diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index ea5fb916a91..00000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,97 +0,0 @@ -# Javascript Node CircleCI 2.0 configuration file -# -# Check https://circleci.com/docs/2.0/language-javascript/ for more details -# - -aliases: - - &environment - docker: - # specify the version you desire here - - image: circleci/node:12.16.1 - resource_class: xlarge - # Specify service dependencies here if necessary - # CircleCI maintains a library of pre-built images - # documented at https://circleci.com/docs/2.0/circleci-images/ - # - image: circleci/mongo:3.4.4 - working_directory: ~/Prebid.js - - - &restore_dep_cache - keys: - - v1-dependencies-{{ checksum "package.json" }} - # fallback to using the latest cache if no exact match is found - - v1-dependencies- - - - &save_dep_cache - paths: - - node_modules - key: v1-dependencies-{{ checksum "package.json" }} - - - &install - name: Install gulp cli - command: sudo npm install -g gulp-cli - - - &run_unit_test - name: BrowserStack testing - command: gulp test --browserstack --nolintfix - - - &run_endtoend_test - name: BrowserStack End to end testing - command: echo "127.0.0.1 test.localhost" | sudo tee -a /etc/hosts && gulp e2e-test --host=test.localhost - - # Download and run BrowserStack local - - &setup_browserstack - name : Download BrowserStack Local binary and start it. - command : | - # Download the browserstack binary file - wget "https://www.browserstack.com/browserstack-local/BrowserStackLocal-linux-x64.zip" - # Unzip it - unzip BrowserStackLocal-linux-x64.zip - # Run the file with user's access key - ./BrowserStackLocal ${BROWSERSTACK_ACCESS_KEY} & - - - &unit_test_steps - - checkout - - restore_cache: *restore_dep_cache - - run: npm install - - save_cache: *save_dep_cache - - run: *install - - run: *setup_browserstack - - run: *run_unit_test - - - &endtoend_test_steps - - checkout - - restore_cache: *restore_dep_cache - - run: npm install - - save_cache: *save_dep_cache - - run: *install - - run: *setup_browserstack - - run: *run_endtoend_test - -version: 2 -jobs: - build: - <<: *environment - steps: *unit_test_steps - - e2etest: - <<: *environment - steps: *endtoend_test_steps - -workflows: - version: 2 - commit: - jobs: - - build - nightly: - triggers: - - schedule: - cron: "0 0 * * *" - filters: - branches: - only: - - master - jobs: - - e2etest - -experimental: - pipelines: true diff --git a/integrationExamples/gpt/adUnitFloors.html b/integrationExamples/gpt/adUnitFloors.html deleted file mode 100644 index bb48a20ef78..00000000000 --- a/integrationExamples/gpt/adUnitFloors.html +++ /dev/null @@ -1,112 +0,0 @@ - - - - - - - - - - - - - - -

Prebid.js Test

-
Div-1
-
- -
- - - - diff --git a/integrationExamples/gpt/adloox.html b/integrationExamples/gpt/adloox.html deleted file mode 100644 index 33f8b9be6a2..00000000000 --- a/integrationExamples/gpt/adloox.html +++ /dev/null @@ -1,211 +0,0 @@ - - - - Prebid Display/Video Merged Auction with Adloox Integration - - - - - - - - -

Prebid Display/Video Merged Auction with Adloox Integration

- -

div-1

-
- -
- -

div-2

-
- -
- -

video-1

-
- - - - diff --git a/integrationExamples/gpt/advanced_size_mapping.html b/integrationExamples/gpt/advanced_size_mapping.html deleted file mode 100644 index 4f1ba085c77..00000000000 --- a/integrationExamples/gpt/advanced_size_mapping.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - - - - - - - - -

Prebid.js Test

-
Div-1
-
- -
- - - diff --git a/integrationExamples/gpt/amp/README.md b/integrationExamples/gpt/amp/README.md deleted file mode 100644 index 1d61fa1f256..00000000000 --- a/integrationExamples/gpt/amp/README.md +++ /dev/null @@ -1,19 +0,0 @@ -##WARNING -The below documented method of deploying prebid on AMP requires remote.html -This is being deprecated on March 29th. A new method the requires Prebid Server -is being developed, see [Prebid Server](http://github.com/prebid/prebid-server). - -## Old method: - -This README provides steps to run amp example page. - -Add following entries to your hosts file - - 127.0.0.1 publisher.com - 127.0.0.1 amp.publisher.com - -Command to run - - gulp serve --https - -Additional documentation can be found at [Prebid AMP](http://prebid.org/dev-docs/how-prebid-on-amp-works.html) diff --git a/integrationExamples/gpt/amp/amp_page.html b/integrationExamples/gpt/amp/amp_page.html deleted file mode 100644 index 2e60e541917..00000000000 --- a/integrationExamples/gpt/amp/amp_page.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - Hello, AMPs - - - - - - - - - - - - -

Welcome to the mobile web

- - - - - - - -
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam aliquam ac orci vitae cursus. - Nulla rutrum egestas felis ut bibendum. Maecenas blandit tellus eu turpis posuere condimentum sit amet eget eros. Donec sollicitudin sit amet enim ut ultricies. Nunc semper enim a dignissim convallis. Vestibulum faucibus eget ante non pellentesque. Maecenas convallis consectetur dolor, non facilisis felis interdum id. Cras ac leo et massa facilisis porttitor ut vitae dolor. Phasellus odio felis, pharetra vel sem vitae, ultricies ornare sapien. In sodales semper ultricies. - -Suspendisse potenti. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Integer tempus rutrum libero, sit amet finibus sapien rutrum sed. Vestibulum accumsan turpis vel est cursus vulputate. Nam id risus ligula. Praesent metus elit, iaculis sit amet egestas id, interdum id nibh. Nullam egestas tempor lorem at consectetur. Fusce sit amet mattis massa, id semper elit. Mauris blandit lectus a orci lobortis malesuada. - -Donec id turpis quam. Morbi fringilla justo nisi, et mattis nibh laoreet non. Aliquam orci eros, tincidunt a feugiat id, gravida ut nisl. Morbi et arcu facilisis, congue mauris ut, ultricies ligula. Vivamus vulputate est non facilisis iaculis. Phasellus quis auctor odio. Nulla facilisi. Sed convallis feugiat erat, sit amet tincidunt justo bibendum ut. Sed maximus justo sit amet pharetra tincidunt. Vivamus laoreet nisi vel est feugiat, sed egestas ante congue. - -Nunc ultricies sodales dolor eget semper. Phasellus ac ligula ac mi fermentum ornare sed et lacus. Curabitur ante enim, maximus ac lacus in, hendrerit mollis enim. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas posuere nisl ac nisl sagittis faucibus. Quisque pellentesque vehicula lectus, ac malesuada dui mollis pulvinar. Nam in lectus placerat eros feugiat dictum ut vel quam. Etiam magna mauris, euismod in felis sodales, interdum ultricies nisl. Nunc elit mi, pellentesque vel est nec, tempus dignissim purus. Praesent pharetra, odio ut cursus dictum, erat felis gravida lorem, at pretium justo dolor quis odio. Mauris tincidunt accumsan mi, gravida condimentum enim vulputate at. Phasellus pretium hendrerit commodo. Quisque blandit rhoncus erat, sed tincidunt dolor rutrum et. - -Nunc nec condimentum mauris, vel porta sem. Donec finibus sapien lacus, quis faucibus neque lobortis non. Nam faucibus nunc odio. Aliquam dolor nisl, placerat sed ipsum quis, facilisis sollicitudin nisi. Nullam sed ultrices enim. Ut sollicitudin mi dignissim, faucibus massa in, pellentesque velit. Donec auctor vel libero in posuere. Ut venenatis odio nec euismod egestas. Nunc posuere pretium sapien finibus sagittis. Nunc volutpat ante eget eleifend consequat. Donec sed quam sit amet quam venenatis pulvinar. Nullam in ex id magna pellentesque tempus. -
- - diff --git a/integrationExamples/gpt/amp/creative.html b/integrationExamples/gpt/amp/creative.html deleted file mode 100644 index 86f669dd6b5..00000000000 --- a/integrationExamples/gpt/amp/creative.html +++ /dev/null @@ -1,38 +0,0 @@ - - - diff --git a/integrationExamples/gpt/amp/gulpfile.js b/integrationExamples/gpt/amp/gulpfile.js deleted file mode 100644 index 30dae86bb0a..00000000000 --- a/integrationExamples/gpt/amp/gulpfile.js +++ /dev/null @@ -1,17 +0,0 @@ -/** Run `gulp serve` to serve files from this directory in development - * Set two different entries in hosts to use x-domain iframes - * AMP requires https - */ - -var gulp = require('gulp'); -var connect = require('gulp-connect'); -var port = 5000; - -gulp.task('serve', function() { - connect.server({ - port: port, - root: './', - livereload: true, - https: true - }); -}); diff --git a/integrationExamples/gpt/amp/remote.html b/integrationExamples/gpt/amp/remote.html deleted file mode 100644 index 785d854766f..00000000000 --- a/integrationExamples/gpt/amp/remote.html +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - - - - - - - -
- -
- - - - diff --git a/integrationExamples/gpt/cmp_files/purposes.json b/integrationExamples/gpt/cmp_files/purposes.json deleted file mode 100644 index 04219e92ce4..00000000000 --- a/integrationExamples/gpt/cmp_files/purposes.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "version": 1, - "purposes": [ - { - "id": 25, - "name": "Custom Purpose 1", - "description": "Here's a description of the first purpose" - }, - { - "id": 26, - "name": "Custom Purpose 2", - "description": "Here's a description of the second purpose" - }, - { - "id": 27, - "name": "Custom Purpose 3", - "description": "Here's a description of the third purpose" - }, - { - "id": 28, - "name": "Custom Purpose 4", - "description": "Here's a description of the fourth purpose" - } - ] -} diff --git a/integrationExamples/gpt/creative_rendering.html b/integrationExamples/gpt/creative_rendering.html deleted file mode 100644 index 04d4736c631..00000000000 --- a/integrationExamples/gpt/creative_rendering.html +++ /dev/null @@ -1,15 +0,0 @@ - - diff --git a/integrationExamples/gpt/gdpr_hello_world.html b/integrationExamples/gpt/gdpr_hello_world.html deleted file mode 100644 index 2d70af8d34f..00000000000 --- a/integrationExamples/gpt/gdpr_hello_world.html +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - -

Prebid.js Test

-
Div-1
-
- -
- - diff --git a/integrationExamples/gpt/haloRtdProvider_example.html b/integrationExamples/gpt/haloRtdProvider_example.html deleted file mode 100644 index 14debbd2698..00000000000 --- a/integrationExamples/gpt/haloRtdProvider_example.html +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - - - - - - - - - - -

Halo RTD Prebid

- -
- -
- -Halo Id: -
-
- -Halo Real-Time Data: -
-
- - diff --git a/integrationExamples/gpt/hello_world.html b/integrationExamples/gpt/hello_world.html deleted file mode 100755 index 47ba5b8f18a..00000000000 --- a/integrationExamples/gpt/hello_world.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - -

Prebid.js Test

-
Div-1
-
- -
- - \ No newline at end of file diff --git a/integrationExamples/gpt/idImportLibrary_example.html b/integrationExamples/gpt/idImportLibrary_example.html deleted file mode 100644 index a3ef3f168c0..00000000000 --- a/integrationExamples/gpt/idImportLibrary_example.html +++ /dev/null @@ -1,351 +0,0 @@ - - - - - - - - - - - - - -Prebid - -

ID Import Library Example

-

Steps before logging in:

- - - - - - - - - - - diff --git a/integrationExamples/gpt/inskin_example.html b/integrationExamples/gpt/inskin_example.html deleted file mode 100644 index 197a5b1ffe1..00000000000 --- a/integrationExamples/gpt/inskin_example.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - - -

Prebid.js Test

-
Div-1
-
- -
- - diff --git a/integrationExamples/gpt/jwplayerRtdProvider_example.html b/integrationExamples/gpt/jwplayerRtdProvider_example.html deleted file mode 100644 index 41c27b70ece..00000000000 --- a/integrationExamples/gpt/jwplayerRtdProvider_example.html +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - - JW Player RTD Provider Example - - - - - - - - -
Div-1
-
- -
- - diff --git a/integrationExamples/gpt/pbjs_video_adUnit.html b/integrationExamples/gpt/pbjs_video_adUnit.html deleted file mode 100644 index 080ca9be142..00000000000 --- a/integrationExamples/gpt/pbjs_video_adUnit.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - Prebid.js video adUnit example - - - - - - - - - - - -
- -
- - - - - diff --git a/integrationExamples/gpt/permutiveRtdProvider_example.html b/integrationExamples/gpt/permutiveRtdProvider_example.html deleted file mode 100644 index a06430bcdfa..00000000000 --- a/integrationExamples/gpt/permutiveRtdProvider_example.html +++ /dev/null @@ -1,232 +0,0 @@ - - - - - - - - - - - -

-

Basic Prebid.js Example

-
Div-1
-
- -
- -
- -
Div-2
-
- -
- - - - diff --git a/integrationExamples/gpt/prebidServer_example.html b/integrationExamples/gpt/prebidServer_example.html deleted file mode 100644 index 37902edd979..00000000000 --- a/integrationExamples/gpt/prebidServer_example.html +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - -

Prebid.js S2S Example

- -
Div-1
-
- -
- - diff --git a/integrationExamples/gpt/prebidServer_native_example.html b/integrationExamples/gpt/prebidServer_native_example.html deleted file mode 100644 index 16c7d38a427..00000000000 --- a/integrationExamples/gpt/prebidServer_native_example.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - - - - - - - - - - - -

Prebid Native

-
-

No response

- -
- -
-
- -
-

No response

- -
- - - - diff --git a/integrationExamples/gpt/proxistore_example.html b/integrationExamples/gpt/proxistore_example.html deleted file mode 100644 index acd95baef2a..00000000000 --- a/integrationExamples/gpt/proxistore_example.html +++ /dev/null @@ -1,118 +0,0 @@ - - - - - - - - - - - - - -

Prebid.js Test

- -
Div-1
- -
- -
- - - \ No newline at end of file diff --git a/integrationExamples/gpt/reconciliationRtdProvider_example.html b/integrationExamples/gpt/reconciliationRtdProvider_example.html deleted file mode 100644 index 4f9b663c22d..00000000000 --- a/integrationExamples/gpt/reconciliationRtdProvider_example.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - Reconciliation RTD Provider Example - - - - - - - - -
Div-1
-
- -
- - diff --git a/integrationExamples/gpt/revcontent_example.html b/integrationExamples/gpt/revcontent_example.html deleted file mode 100644 index d7a44df3014..00000000000 --- a/integrationExamples/gpt/revcontent_example.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - -

Basic Prebid.js Example

-
Div-1
-
- -
- - - \ No newline at end of file diff --git a/integrationExamples/gpt/serverbidServer_example.html b/integrationExamples/gpt/serverbidServer_example.html deleted file mode 100644 index 3d76e963663..00000000000 --- a/integrationExamples/gpt/serverbidServer_example.html +++ /dev/null @@ -1,103 +0,0 @@ - - - - - - - - -

Prebid.js S2S Example

- -
Div-1
-
- -
- - diff --git a/integrationExamples/gpt/sirdataRtdProvider_example.html b/integrationExamples/gpt/sirdataRtdProvider_example.html deleted file mode 100644 index 444c9133905..00000000000 --- a/integrationExamples/gpt/sirdataRtdProvider_example.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - - - - - - - - - - - -
-

-Give consent or make a choice in Europe. Module will add key/value pairs in ad calls. Check out for sd_rtd key in Google Ad call (https://securepubads.g.doubleclick.net/gampad/ads...) and in the payload sent to Xandr to endpoint https://ib.adnxs.com/ut/v3/prebid : tags[0].keywords.key[sd_rtd] should have an array of string as value. This array will mix user segments and/or page categories based on user's choices. -

-
-

Basic Prebid.js Example

-
Div-1
-
- -
- - - \ No newline at end of file diff --git a/integrationExamples/gpt/userId_example.html b/integrationExamples/gpt/userId_example.html deleted file mode 100644 index 6fbdd69aea7..00000000000 --- a/integrationExamples/gpt/userId_example.html +++ /dev/null @@ -1,321 +0,0 @@ - - - - - User ID Modules Example - - - - - - - - - - - - -

User ID Modules Example

- -

Generated EIDs

- -

-
-  

Ad Slot

-
- -
- - - diff --git a/integrationExamples/gpt/x-domain/creative.html b/integrationExamples/gpt/x-domain/creative.html deleted file mode 100644 index fce46bb380f..00000000000 --- a/integrationExamples/gpt/x-domain/creative.html +++ /dev/null @@ -1,71 +0,0 @@ - diff --git a/integrationExamples/longform/basic_w_bidderSettings.html b/integrationExamples/longform/basic_w_bidderSettings.html deleted file mode 100644 index fb87ea5d990..00000000000 --- a/integrationExamples/longform/basic_w_bidderSettings.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - Prebid Freewheel Integration Demo - - - - - - - - - - - - - - - - - - - -

Prebid Freewheel Test Page

-

requireExactDuration = false

-
-
- -
-
-
-
-

- -

-
-
-
- // bids -
-
-
-
-
-

- -

-
-
-
- // bids -
-
-
-
-
-
-
- - - - \ No newline at end of file diff --git a/integrationExamples/longform/basic_w_custom_adserver_translation.html b/integrationExamples/longform/basic_w_custom_adserver_translation.html deleted file mode 100644 index 2dbb89506b5..00000000000 --- a/integrationExamples/longform/basic_w_custom_adserver_translation.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - - Prebid Freewheel Integration Demo - - - - - - - - - - - - - - - - - - - -

Prebid Freewheel Integration Demo

-

custom adserver translation file

-
-
- -
-
-
-
-

- -

-
-
-
- // bids -
-
-
-
-
-

- -

-
-
-
- // bids -
-
-
-
-
-
-
- - - - diff --git a/integrationExamples/longform/basic_w_priceGran.html b/integrationExamples/longform/basic_w_priceGran.html deleted file mode 100644 index 4ea9d5d19be..00000000000 --- a/integrationExamples/longform/basic_w_priceGran.html +++ /dev/null @@ -1,156 +0,0 @@ - - - - - Prebid Freewheel Integration Demo - - - - - - - - - - - - - - - - - - - -

Prebid Freewheel Test Page

-

requireExactDuration = false

-
-
- -
-
-
-
-

- -

-
-
-
- // bids -
-
-
-
-
-

- -

-
-
-
- // bids -
-
-
-
-
-
-
- - - - \ No newline at end of file diff --git a/integrationExamples/longform/basic_w_requireExactDuration.html b/integrationExamples/longform/basic_w_requireExactDuration.html deleted file mode 100644 index 46b91887cfb..00000000000 --- a/integrationExamples/longform/basic_w_requireExactDuration.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - Prebid Freewheel Integration Demo - - - - - - - - - - - - - - - - - - - -

Prebid Freewheel Test Page

-

requireExactDuration = true

-
-
- -
-
-
-
-

- -

-
-
-
- // bids -
-
-
-
-
-

- -

-
-
-
- // bids -
-
-
-
-
-
-
- - - - diff --git a/integrationExamples/longform/basic_wo_brandCategoryExclusion.html b/integrationExamples/longform/basic_wo_brandCategoryExclusion.html deleted file mode 100644 index 47ea4b7f47d..00000000000 --- a/integrationExamples/longform/basic_wo_brandCategoryExclusion.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - Prebid Freewheel Integration Demo - - - - - - - - - - - - - - - - - - - -

Prebid Freewheel Test Page

-

brandCategoryExclusion = false

-
-
- -
-
-
-
-

- -

-
-
-
- // bids -
-
-
-
-
-

- -

-
-
-
- // bids -
-
-
-
-
-
-
- - - - diff --git a/integrationExamples/longform/basic_wo_requireExactDuration.html b/integrationExamples/longform/basic_wo_requireExactDuration.html deleted file mode 100644 index 6dbedbc6d39..00000000000 --- a/integrationExamples/longform/basic_wo_requireExactDuration.html +++ /dev/null @@ -1,134 +0,0 @@ - - - - - Prebid Freewheel Integration Demo - - - - - - - - - - - - - - - - - - - -

Prebid Freewheel Test Page

-

requireExactDuration = false

-
-
- -
-
-
-
-

- -

-
-
-
- // bids -
-
-
-
-
-

- -

-
-
-
- // bids -
-
-
-
-
-
-
- - - - diff --git a/integrationExamples/longform/custom_adserver_translation.json b/integrationExamples/longform/custom_adserver_translation.json deleted file mode 100644 index 377fe9cdeda..00000000000 --- a/integrationExamples/longform/custom_adserver_translation.json +++ /dev/null @@ -1,1180 +0,0 @@ -{ - "mapping":{ - "IAB1-1":{ - "id":404, - "name":"Publishing" - }, - "IAB1-2":{ - "id":392, - "name":"Entertainment" - }, - "IAB1-5":{ - "id":419, - "name":"Filmed Entertainment" - }, - "IAB1-6":{ - "id":392, - "name":"Entertainment" - }, - "IAB1-7":{ - "id":392, - "name":"Entertainment" - }, - "IAB2-1":{ - "id":399, - "name":"Automotive" - }, - "IAB2-2":{ - "id":399, - "name":"Automotive" - }, - "IAB2-3":{ - "id":399, - "name":"Automotive" - }, - "IAB2-4":{ - "id":399, - "name":"Automotive" - }, - "IAB2-5":{ - "id":399, - "name":"Automotive" - }, - "IAB2-6":{ - "id":399, - "name":"Automotive" - }, - "IAB2-7":{ - "id":399, - "name":"Automotive" - }, - "IAB2-8":{ - "id":399, - "name":"Automotive" - }, - "IAB2-9":{ - "id":399, - "name":"Automotive" - }, - "IAB2-10":{ - "id":399, - "name":"Automotive" - }, - "IAB2-11":{ - "id":399, - "name":"Automotive" - }, - "IAB2-12":{ - "id":399, - "name":"Automotive" - }, - "IAB2-13":{ - "id":399, - "name":"Automotive" - }, - "IAB2-14":{ - "id":399, - "name":"Automotive" - }, - "IAB2-15":{ - "id":399, - "name":"Automotive" - }, - "IAB2-16":{ - "id":399, - "name":"Automotive" - }, - "IAB2-17":{ - "id":399, - "name":"Automotive" - }, - "IAB2-18":{ - "id":399, - "name":"Automotive" - }, - "IAB2-19":{ - "id":399, - "name":"Automotive" - }, - "IAB2-20":{ - "id":399, - "name":"Automotive" - }, - "IAB2-21":{ - "id":399, - "name":"Automotive" - }, - "IAB2-22":{ - "id":399, - "name":"Automotive" - }, - "IAB2-23":{ - "id":399, - "name":"Automotive" - }, - "IAB3-1":{ - "id":393, - "name":"Business Services" - }, - "IAB3-2":{ - "id":393, - "name":"Business Services" - }, - "IAB3-3":{ - "id":393, - "name":"Business Services" - }, - "IAB3-4":{ - "id":409, - "name":"Computing Product" - }, - "IAB3-5":{ - "id":393, - "name":"Business Services" - }, - "IAB3-6":{ - "id":393, - "name":"Business Services" - }, - "IAB3-7":{ - "id":398, - "name":"Government/Municipal" - }, - "IAB3-8":{ - "id":393, - "name":"Business Services" - }, - "IAB3-9":{ - "id":393, - "name":"Business Services" - }, - "IAB3-10":{ - "id":393, - "name":"Business Services" - }, - "IAB3-11":{ - "id":393, - "name":"Business Services" - }, - "IAB3-12":{ - "id":393, - "name":"Business Services" - }, - "IAB4-1":{ - "id":393, - "name":"Business Services" - }, - "IAB4-2":{ - "id":405, - "name":"Educational Services" - }, - "IAB4-3":{ - "id":405, - "name":"Educational Services" - }, - "IAB4-4":{ - "id":393, - "name":"Business Services" - }, - "IAB4-5":{ - "id":393, - "name":"Business Services" - }, - "IAB4-6":{ - "id":393, - "name":"Business Services" - }, - "IAB4-7":{ - "id":406, - "name":"Health Care Services" - }, - "IAB4-8":{ - "id":405, - "name":"Educational Services" - }, - "IAB4-9":{ - "id":417, - "name":"Telecommunications" - }, - "IAB4-10":{ - "id":429, - "name":"Military" - }, - "IAB4-11":{ - "id":393, - "name":"Business Services" - }, - "IAB5-1":{ - "id":405, - "name":"Educational Services" - }, - "IAB5-2":{ - "id":405, - "name":"Educational Services" - }, - "IAB5-3":{ - "id":405, - "name":"Educational Services" - }, - "IAB5-4":{ - "id":405, - "name":"Educational Services" - }, - "IAB5-5":{ - "id":405, - "name":"Educational Services" - }, - "IAB5-6":{ - "id":405, - "name":"Educational Services" - }, - "IAB5-7":{ - "id":405, - "name":"Educational Services" - }, - "IAB5-8":{ - "id":405, - "name":"Educational Services" - }, - "IAB5-9":{ - "id":405, - "name":"Educational Services" - }, - "IAB5-10":{ - "id":405, - "name":"Educational Services" - }, - "IAB5-11":{ - "id":405, - "name":"Educational Services" - }, - "IAB5-12":{ - "id":405, - "name":"Educational Services" - }, - "IAB5-13":{ - "id":405, - "name":"Educational Services" - }, - "IAB5-14":{ - "id":405, - "name":"Educational Services" - }, - "IAB5-15":{ - "id":405, - "name":"Educational Services" - }, - "IAB7-1":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-2":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-3":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-4":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-5":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-6":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-7":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-8":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-9":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-10":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-11":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-12":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-13":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-14":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-15":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-16":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-17":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-18":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-19":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-20":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-21":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-22":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-23":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-24":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-25":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-26":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-27":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-28":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-29":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-30":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-31":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-32":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-33":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-34":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-35":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-36":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-37":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-38":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-39":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-40":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-41":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-42":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-43":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-44":{ - "id":406, - "name":"Health Care Services" - }, - "IAB7-45":{ - "id":406, - "name":"Health Care Services" - }, - "IAB8-1":{ - "id":394, - "name":"Food" - }, - "IAB8-2":{ - "id":394, - "name":"Food" - }, - "IAB8-3":{ - "id":394, - "name":"Food" - }, - "IAB8-4":{ - "id":394, - "name":"Food" - }, - "IAB8-5":{ - "id":400, - "name":"Beer/Wine/Liquor" - }, - "IAB8-6":{ - "id":401, - "name":"Beverages" - }, - "IAB8-7":{ - "id":394, - "name":"Food" - }, - "IAB8-8":{ - "id":394, - "name":"Food" - }, - "IAB8-9":{ - "id":407, - "name":"Restaurant/Fast Food" - }, - "IAB8-10":{ - "id":394, - "name":"Food" - }, - "IAB8-11":{ - "id":394, - "name":"Food" - }, - "IAB8-12":{ - "id":394, - "name":"Food" - }, - "IAB8-13":{ - "id":394, - "name":"Food" - }, - "IAB8-14":{ - "id":394, - "name":"Food" - }, - "IAB8-15":{ - "id":394, - "name":"Food" - }, - "IAB8-16":{ - "id":394, - "name":"Food" - }, - "IAB8-17":{ - "id":394, - "name":"Food" - }, - "IAB8-18":{ - "id":400, - "name":"Beer/Wine/Liquor" - }, - "IAB9-1":{ - "id":392, - "name":"Entertainment" - }, - "IAB9-3":{ - "id":418, - "name":"Jewelry" - }, - "IAB9-5":{ - "id":413, - "name":"Gaming" - }, - "IAB9-6":{ - "id":412, - "name":"Household Products" - }, - "IAB9-9":{ - "id":426, - "name":"Tobacco" - }, - "IAB9-11":{ - "id":404, - "name":"Publishing" - }, - "IAB9-15":{ - "id":404, - "name":"Publishing" - }, - "IAB9-16":{ - "id":392, - "name":"Entertainment" - }, - "IAB9-18":{ - "id":393, - "name":"Business Services" - }, - "IAB9-19":{ - "id":418, - "name":"Jewelry" - }, - "IAB9-23":{ - "id":424, - "name":"Photographic Equipment" - }, - "IAB9-24":{ - "id":392, - "name":"Entertainment" - }, - "IAB9-25":{ - "id":392, - "name":"Entertainment" - }, - "IAB9-30":{ - "id":392, - "name":"Entertainment" - }, - "IAB10-1":{ - "id":415, - "name":"Appliances" - }, - "IAB10-5":{ - "id":434, - "name":"Home Furnishings" - }, - "IAB10-6":{ - "id":434, - "name":"Home Furnishings" - }, - "IAB10-7":{ - "id":434, - "name":"Home Furnishings" - }, - "IAB10-8":{ - "id":393, - "name":"Business Services" - }, - "IAB10-9":{ - "id":434, - "name":"Home Furnishings" - }, - "IAB11-1":{ - "id":398, - "name":"Government/Municipal" - }, - "IAB11-2":{ - "id":398, - "name":"Government/Municipal" - }, - "IAB11-3":{ - "id":398, - "name":"Government/Municipal" - }, - "IAB11-4":{ - "id":398, - "name":"Government/Municipal" - }, - "IAB11-5":{ - "id":398, - "name":"Government/Municipal" - }, - "IAB12-1":{ - "id":438, - "name":"News" - }, - "IAB12-2":{ - "id":438, - "name":"News" - }, - "IAB12-3":{ - "id":438, - "name":"News" - }, - "IAB13-1":{ - "id":393, - "name":"Business Services" - }, - "IAB13-2":{ - "id":393, - "name":"Business Services" - }, - "IAB13-3":{ - "id":438, - "name":"News" - }, - "IAB13-4":{ - "id":391, - "name":"Financial Services" - }, - "IAB13-5":{ - "id":393, - "name":"Business Services" - }, - "IAB13-6":{ - "id":436, - "name":"Insurance" - }, - "IAB13-7":{ - "id":393, - "name":"Business Services" - }, - "IAB13-8":{ - "id":393, - "name":"Business Services" - }, - "IAB13-9":{ - "id":393, - "name":"Business Services" - }, - "IAB13-10":{ - "id":393, - "name":"Business Services" - }, - "IAB13-11":{ - "id":393, - "name":"Business Services" - }, - "IAB13-12":{ - "id":393, - "name":"Business Services" - }, - "IAB16-1":{ - "id":423, - "name":"Pet Food/Supplies" - }, - "IAB16-2":{ - "id":423, - "name":"Pet Food/Supplies" - }, - "IAB16-3":{ - "id":423, - "name":"Pet Food/Supplies" - }, - "IAB16-4":{ - "id":423, - "name":"Pet Food/Supplies" - }, - "IAB16-5":{ - "id":423, - "name":"Pet Food/Supplies" - }, - "IAB16-6":{ - "id":423, - "name":"Pet Food/Supplies" - }, - "IAB16-7":{ - "id":423, - "name":"Pet Food/Supplies" - }, - "IAB17-1":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-2":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-3":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-4":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-5":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-6":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-7":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-8":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-9":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-10":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-11":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-12":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-13":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-14":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-15":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-16":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-17":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-18":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-19":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-20":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-21":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-22":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-23":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-24":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-25":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-26":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-27":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-28":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-29":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-30":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-31":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-32":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-33":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-34":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-35":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-36":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-37":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-38":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-39":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-40":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-41":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-42":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-43":{ - "id":425, - "name":"Professional Sports" - }, - "IAB17-44":{ - "id":425, - "name":"Professional Sports" - }, - "IAB18-1":{ - "id":411, - "name":"Cosmetics/Toiletries" - }, - "IAB18-2":{ - "id":397, - "name":"Apparel" - }, - "IAB18-3":{ - "id":397, - "name":"Apparel" - }, - "IAB18-4":{ - "id":418, - "name":"Jewelry" - }, - "IAB18-5":{ - "id":397, - "name":"Apparel" - }, - "IAB18-6":{ - "id":397, - "name":"Apparel" - }, - "IAB19-2":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-3":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-4":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-5":{ - "id":424, - "name":"Photographic Equipment" - }, - "IAB19-6":{ - "id":417, - "name":"Telecommunications" - }, - "IAB19-7":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-8":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-9":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-10":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-11":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-12":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-13":{ - "id":404, - "name":"Publishing" - }, - "IAB19-14":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-15":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-16":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-17":{ - "id":419, - "name":"Filmed Entertainment" - }, - "IAB19-18":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-19":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-20":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-21":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-22":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-23":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-24":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-25":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-26":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-27":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-28":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-29":{ - "id":392, - "name":"Entertainment" - }, - "IAB19-30":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-31":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-32":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-33":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-34":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-35":{ - "id":409, - "name":"Computing Product" - }, - "IAB19-36":{ - "id":409, - "name":"Computing Product" - }, - "IAB20-1":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-2":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-3":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-4":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-5":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-6":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-7":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-8":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-9":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-10":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-11":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-12":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-13":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-14":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-15":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-16":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-17":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-18":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-19":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-20":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-21":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-22":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-23":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-24":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-25":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-26":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB20-27":{ - "id":395, - "name":"Travel/Hotels/Airlines" - }, - "IAB21-1":{ - "id":416, - "name":"Real Estate" - }, - "IAB21-2":{ - "id":416, - "name":"Real Estate" - }, - "IAB21-3":{ - "id":416, - "name":"Real Estate" - }, - "IAB22-1":{ - "id":403, - "name":"Retail Stores/Chains" - }, - "IAB22-2":{ - "id":403, - "name":"Retail Stores/Chains" - }, - "IAB22-3":{ - "id":403, - "name":"Retail Stores/Chains" - } - } -} \ No newline at end of file diff --git a/integrationExamples/longform/longformTestUtils.js b/integrationExamples/longform/longformTestUtils.js deleted file mode 100644 index bfb281e659f..00000000000 --- a/integrationExamples/longform/longformTestUtils.js +++ /dev/null @@ -1,1322 +0,0 @@ -var prebidTestUtils = prebidTestUtils || {}; - -function getIndustry(id) { - var mapping = window.localStorage.getItem('iabToFwMappingkey'); - if (mapping) { - try { - mapping = JSON.parse(mapping); - } catch (error) { - // - } - var industry; - mapping = mapping['mapping']; - for (var v in mapping) { - if (mapping[v]['id'] == id) { - industry = mapping[v]['name']; - break; - } - } - return industry; - } -} - -prebidTestUtils.loadKv = function (targetingArr) { - var div = document.getElementById('collapseThree').children[0]; - var html = ''; - Object.keys(targetingArr).forEach(function(adUnitCode) { - targetingArr[adUnitCode].forEach(function (targeting) { - Object.keys(targeting).forEach(function (key) { - html += '' - }); - }); - }); - html += '
' + key + '' + targeting[key] + '
'; - div.innerHTML = html; -} - -prebidTestUtils.loadBids = function (targetingArr, brandCatExclusion) { - var div = document.getElementById('collapseTwo').children[0]; - var html = ''; - var index = 1; - Object.keys(targetingArr).forEach(function(adUnitCode) { - targetingArr[adUnitCode].forEach(function (targeting) { - Object.keys(targeting).forEach(function (key) { - if (key !== 'hb_cache_id') { - var result = targeting[key].split('_'); - html += ''; - html += ''; - html += ''; - if (brandCatExclusion) { - html += ''; - html += ''; - } else { - html += ''; - html += ''; - } - html += ''; - html += ''; - html += ''; - index++; - } - }); - }); - }); - html += '
#CPMIndustryDurationStatusComm Break #
' + index + '' + result[0] + '' + getIndustry(result[1]) + '' + result[2] + '' + result[1] + '
'; - div.innerHTML = html; -} - -prebidTestUtils.setMockCategories = function () { - const key = 'iabToFwMappingkey'; - const keyPub = 'iabToFwMappingkeyPub'; - const keyBidder = 'appnexus'; - const currTime = new Date().getTime(); - const fwData = { - "mapping": { - "IAB1-1": { - "id": 404, - "name": "Publishing" - }, - "IAB1-2": { - "id": 392, - "name": "Entertainment" - }, - "IAB1-5": { - "id": 419, - "name": "Filmed Entertainment" - }, - "IAB1-6": { - "id": 392, - "name": "Entertainment" - }, - "IAB1-7": { - "id": 392, - "name": "Entertainment" - }, - "IAB2-1": { - "id": 399, - "name": "Automotive" - }, - "IAB2-2": { - "id": 399, - "name": "Automotive" - }, - "IAB2-3": { - "id": 399, - "name": "Automotive" - }, - "IAB2-4": { - "id": 399, - "name": "Automotive" - }, - "IAB2-5": { - "id": 399, - "name": "Automotive" - }, - "IAB2-6": { - "id": 399, - "name": "Automotive" - }, - "IAB2-7": { - "id": 399, - "name": "Automotive" - }, - "IAB2-8": { - "id": 399, - "name": "Automotive" - }, - "IAB2-9": { - "id": 399, - "name": "Automotive" - }, - "IAB2-10": { - "id": 399, - "name": "Automotive" - }, - "IAB2-11": { - "id": 399, - "name": "Automotive" - }, - "IAB2-12": { - "id": 399, - "name": "Automotive" - }, - "IAB2-13": { - "id": 399, - "name": "Automotive" - }, - "IAB2-14": { - "id": 399, - "name": "Automotive" - }, - "IAB2-15": { - "id": 399, - "name": "Automotive" - }, - "IAB2-16": { - "id": 399, - "name": "Automotive" - }, - "IAB2-17": { - "id": 399, - "name": "Automotive" - }, - "IAB2-18": { - "id": 399, - "name": "Automotive" - }, - "IAB2-19": { - "id": 399, - "name": "Automotive" - }, - "IAB2-20": { - "id": 399, - "name": "Automotive" - }, - "IAB2-21": { - "id": 399, - "name": "Automotive" - }, - "IAB2-22": { - "id": 399, - "name": "Automotive" - }, - "IAB2-23": { - "id": 399, - "name": "Automotive" - }, - "IAB3-1": { - "id": 393, - "name": "Business Services" - }, - "IAB3-2": { - "id": 393, - "name": "Business Services" - }, - "IAB3-3": { - "id": 393, - "name": "Business Services" - }, - "IAB3-4": { - "id": 409, - "name": "Computing Product" - }, - "IAB3-5": { - "id": 393, - "name": "Business Services" - }, - "IAB3-6": { - "id": 393, - "name": "Business Services" - }, - "IAB3-7": { - "id": 398, - "name": "Government/Municipal" - }, - "IAB3-8": { - "id": 393, - "name": "Business Services" - }, - "IAB3-9": { - "id": 393, - "name": "Business Services" - }, - "IAB3-10": { - "id": 393, - "name": "Business Services" - }, - "IAB3-11": { - "id": 393, - "name": "Business Services" - }, - "IAB3-12": { - "id": 393, - "name": "Business Services" - }, - "IAB4-1": { - "id": 393, - "name": "Business Services" - }, - "IAB4-2": { - "id": 405, - "name": "Educational Services" - }, - "IAB4-3": { - "id": 405, - "name": "Educational Services" - }, - "IAB4-4": { - "id": 393, - "name": "Business Services" - }, - "IAB4-5": { - "id": 393, - "name": "Business Services" - }, - "IAB4-6": { - "id": 393, - "name": "Business Services" - }, - "IAB4-7": { - "id": 406, - "name": "Health Care Services" - }, - "IAB4-8": { - "id": 405, - "name": "Educational Services" - }, - "IAB4-9": { - "id": 417, - "name": "Telecommunications" - }, - "IAB4-10": { - "id": 429, - "name": "Military" - }, - "IAB4-11": { - "id": 393, - "name": "Business Services" - }, - "IAB5-1": { - "id": 405, - "name": "Educational Services" - }, - "IAB5-2": { - "id": 405, - "name": "Educational Services" - }, - "IAB5-3": { - "id": 405, - "name": "Educational Services" - }, - "IAB5-4": { - "id": 405, - "name": "Educational Services" - }, - "IAB5-5": { - "id": 405, - "name": "Educational Services" - }, - "IAB5-6": { - "id": 405, - "name": "Educational Services" - }, - "IAB5-7": { - "id": 405, - "name": "Educational Services" - }, - "IAB5-8": { - "id": 405, - "name": "Educational Services" - }, - "IAB5-9": { - "id": 405, - "name": "Educational Services" - }, - "IAB5-10": { - "id": 405, - "name": "Educational Services" - }, - "IAB5-11": { - "id": 405, - "name": "Educational Services" - }, - "IAB5-12": { - "id": 405, - "name": "Educational Services" - }, - "IAB5-13": { - "id": 405, - "name": "Educational Services" - }, - "IAB5-14": { - "id": 405, - "name": "Educational Services" - }, - "IAB5-15": { - "id": 405, - "name": "Educational Services" - }, - "IAB7-1": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-2": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-3": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-4": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-5": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-6": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-7": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-8": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-9": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-10": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-11": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-12": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-13": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-14": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-15": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-16": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-17": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-18": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-19": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-20": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-21": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-22": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-23": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-24": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-25": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-26": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-27": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-28": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-29": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-30": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-31": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-32": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-33": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-34": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-35": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-36": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-37": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-38": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-39": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-40": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-41": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-42": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-43": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-44": { - "id": 406, - "name": "Health Care Services" - }, - "IAB7-45": { - "id": 406, - "name": "Health Care Services" - }, - "IAB8-1": { - "id": 394, - "name": "Food" - }, - "IAB8-2": { - "id": 394, - "name": "Food" - }, - "IAB8-3": { - "id": 394, - "name": "Food" - }, - "IAB8-4": { - "id": 394, - "name": "Food" - }, - "IAB8-5": { - "id": 400, - "name": "Beer/Wine/Liquor" - }, - "IAB8-6": { - "id": 401, - "name": "Beverages" - }, - "IAB8-7": { - "id": 394, - "name": "Food" - }, - "IAB8-8": { - "id": 394, - "name": "Food" - }, - "IAB8-9": { - "id": 407, - "name": "Restaurant/Fast Food" - }, - "IAB8-10": { - "id": 394, - "name": "Food" - }, - "IAB8-11": { - "id": 394, - "name": "Food" - }, - "IAB8-12": { - "id": 394, - "name": "Food" - }, - "IAB8-13": { - "id": 394, - "name": "Food" - }, - "IAB8-14": { - "id": 394, - "name": "Food" - }, - "IAB8-15": { - "id": 394, - "name": "Food" - }, - "IAB8-16": { - "id": 394, - "name": "Food" - }, - "IAB8-17": { - "id": 394, - "name": "Food" - }, - "IAB8-18": { - "id": 400, - "name": "Beer/Wine/Liquor" - }, - "IAB9-1": { - "id": 392, - "name": "Entertainment" - }, - "IAB9-3": { - "id": 418, - "name": "Jewelry" - }, - "IAB9-5": { - "id": 413, - "name": "Gaming" - }, - "IAB9-6": { - "id": 412, - "name": "Household Products" - }, - "IAB9-9": { - "id": 426, - "name": "Tobacco" - }, - "IAB9-11": { - "id": 404, - "name": "Publishing" - }, - "IAB9-15": { - "id": 404, - "name": "Publishing" - }, - "IAB9-16": { - "id": 392, - "name": "Entertainment" - }, - "IAB9-18": { - "id": 393, - "name": "Business Services" - }, - "IAB9-19": { - "id": 418, - "name": "Jewelry" - }, - "IAB9-23": { - "id": 424, - "name": "Photographic Equipment" - }, - "IAB9-24": { - "id": 392, - "name": "Entertainment" - }, - "IAB9-25": { - "id": 392, - "name": "Entertainment" - }, - "IAB9-30": { - "id": 392, - "name": "Entertainment" - }, - "IAB10-1": { - "id": 415, - "name": "Appliances" - }, - "IAB10-5": { - "id": 434, - "name": "Home Furnishings" - }, - "IAB10-6": { - "id": 434, - "name": "Home Furnishings" - }, - "IAB10-7": { - "id": 434, - "name": "Home Furnishings" - }, - "IAB10-8": { - "id": 393, - "name": "Business Services" - }, - "IAB10-9": { - "id": 434, - "name": "Home Furnishings" - }, - "IAB11-1": { - "id": 398, - "name": "Government/Municipal" - }, - "IAB11-2": { - "id": 398, - "name": "Government/Municipal" - }, - "IAB11-3": { - "id": 398, - "name": "Government/Municipal" - }, - "IAB11-4": { - "id": 398, - "name": "Government/Municipal" - }, - "IAB11-5": { - "id": 398, - "name": "Government/Municipal" - }, - "IAB12-1": { - "id": 438, - "name": "News" - }, - "IAB12-2": { - "id": 438, - "name": "News" - }, - "IAB12-3": { - "id": 438, - "name": "News" - }, - "IAB13-1": { - "id": 393, - "name": "Business Services" - }, - "IAB13-2": { - "id": 393, - "name": "Business Services" - }, - "IAB13-3": { - "id": 438, - "name": "News" - }, - "IAB13-4": { - "id": 391, - "name": "Financial Services" - }, - "IAB13-5": { - "id": 393, - "name": "Business Services" - }, - "IAB13-6": { - "id": 436, - "name": "Insurance" - }, - "IAB13-7": { - "id": 393, - "name": "Business Services" - }, - "IAB13-8": { - "id": 393, - "name": "Business Services" - }, - "IAB13-9": { - "id": 393, - "name": "Business Services" - }, - "IAB13-10": { - "id": 393, - "name": "Business Services" - }, - "IAB13-11": { - "id": 393, - "name": "Business Services" - }, - "IAB13-12": { - "id": 393, - "name": "Business Services" - }, - "IAB16-1": { - "id": 423, - "name": "Pet Food/Supplies" - }, - "IAB16-2": { - "id": 423, - "name": "Pet Food/Supplies" - }, - "IAB16-3": { - "id": 423, - "name": "Pet Food/Supplies" - }, - "IAB16-4": { - "id": 423, - "name": "Pet Food/Supplies" - }, - "IAB16-5": { - "id": 423, - "name": "Pet Food/Supplies" - }, - "IAB16-6": { - "id": 423, - "name": "Pet Food/Supplies" - }, - "IAB16-7": { - "id": 423, - "name": "Pet Food/Supplies" - }, - "IAB17-1": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-2": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-3": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-4": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-5": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-6": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-7": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-8": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-9": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-10": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-11": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-12": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-13": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-14": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-15": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-16": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-17": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-18": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-19": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-20": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-21": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-22": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-23": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-24": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-25": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-26": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-27": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-28": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-29": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-30": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-31": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-32": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-33": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-34": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-35": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-36": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-37": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-38": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-39": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-40": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-41": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-42": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-43": { - "id": 425, - "name": "Professional Sports" - }, - "IAB17-44": { - "id": 425, - "name": "Professional Sports" - }, - "IAB18-1": { - "id": 411, - "name": "Cosmetics/Toiletries" - }, - "IAB18-2": { - "id": 397, - "name": "Apparel" - }, - "IAB18-3": { - "id": 397, - "name": "Apparel" - }, - "IAB18-4": { - "id": 418, - "name": "Jewelry" - }, - "IAB18-5": { - "id": 397, - "name": "Apparel" - }, - "IAB18-6": { - "id": 397, - "name": "Apparel" - }, - "IAB19-2": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-3": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-4": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-5": { - "id": 424, - "name": "Photographic Equipment" - }, - "IAB19-6": { - "id": 417, - "name": "Telecommunications" - }, - "IAB19-7": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-8": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-9": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-10": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-11": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-12": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-13": { - "id": 404, - "name": "Publishing" - }, - "IAB19-14": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-15": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-16": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-17": { - "id": 419, - "name": "Filmed Entertainment" - }, - "IAB19-18": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-19": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-20": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-21": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-22": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-23": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-24": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-25": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-26": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-27": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-28": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-29": { - "id": 392, - "name": "Entertainment" - }, - "IAB19-30": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-31": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-32": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-33": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-34": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-35": { - "id": 409, - "name": "Computing Product" - }, - "IAB19-36": { - "id": 409, - "name": "Computing Product" - }, - "IAB20-1": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-2": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-3": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-4": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-5": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-6": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-7": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-8": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-9": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-10": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-11": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-12": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-13": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-14": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-15": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-16": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-17": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-18": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-19": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-20": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-21": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-22": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-23": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-24": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-25": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-26": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB20-27": { - "id": 395, - "name": "Travel/Hotels/Airlines" - }, - "IAB21-1": { - "id": 416, - "name": "Real Estate" - }, - "IAB21-2": { - "id": 416, - "name": "Real Estate" - }, - "IAB21-3": { - "id": 416, - "name": "Real Estate" - }, - "IAB22-1": { - "id": 403, - "name": "Retail Stores/Chains" - }, - "IAB22-2": { - "id": 403, - "name": "Retail Stores/Chains" - }, - "IAB22-3": { - "id": 403, - "name": "Retail Stores/Chains" - } - }, - "lastUpdated": currTime - }; - - const appData = { - "lastUpdated": 1588950237532, - "mapping": { - "1": "IAB20-3", - "2": "IAB18-5", - "3": "IAB10-1", - "4": "IAB2-3", - "5": "IAB19-8", - "7": "IAB18-1", - "8": "IAB14-1", - "9": "IAB5-1", - "10": "IAB4-5", - "11": "IAB13-4", - "12": "IAB8-7", - "13": "IAB19-2", - "14": "IAB7-1", - "15": "IAB20-18", - "16": "IAB10-7", - "17": "IAB19-18", - "18": "IAB13-6", - "19": "IAB18-4", - "20": "IAB1-5", - "21": "IAB1-6", - "22": "IAB19-28", - "23": "IAB19-13", - "24": "IAB22-2", - "25": "IAB3-9", - "26": "IAB17-26", - "27": "IAB19-6", - "28": "IAB1-7", - "29": "IAB9-5", - "30": "IAB20-7", - "31": "IAB20-17", - "32": "IAB7-32", - "33": "IAB16-5", - "34": "IAB19-34", - "37": "IAB11-4", - "39": "IAB9-30", - "41": "IAB7-44", - "51": "IAB17-12", - "53": "IAB3-1", - "55": "IAB13-2", - "61": "IAB21-3", - "62": "IAB6-4", - "63": "IAB15-10", - "65": "IAB11-2", - "67": "IAB9-9", - "69": "IAB7-1", - "71": "IAB22-2", - "74": "IAB8-5" - } - }; - - if (!window.localStorage.getItem(key)) { - console.log(key, 'categories not found in localstorage...setting them now...'); - window.localStorage.setItem(key, JSON.stringify(fwData)); - } - - if (!window.localStorage.getItem(keyPub)) { - console.log(keyPub, 'categories not found in localstorage...setting them now...'); - window.localStorage.setItem(keyPub, JSON.stringify(fwData)); - } - - if (!window.localStorage.getItem(keyBidder)) { - console.log(keyBidder, 'categories not found in localstorage...setting them now...'); - window.localStorage.setItem(keyBidder, JSON.stringify(appData)); - } -} \ No newline at end of file diff --git a/integrationExamples/longform/longform_testpages_style.css b/integrationExamples/longform/longform_testpages_style.css deleted file mode 100644 index fe8105edcfa..00000000000 --- a/integrationExamples/longform/longform_testpages_style.css +++ /dev/null @@ -1,34 +0,0 @@ -#videoPlayer { - height: 480px; - width: 100%; - background-color: #000; -} - -.outer { - position: relative; -} - -#skip { - position: absolute; - right: 20px; - bottom: 20px; - display: none; - color: white; - background-color: black; - border: 1px solid gray; -} - -#adCount { - color: white; - position: absolute; - left: 20px; - bottom: 20px; - display: none; -} - -#showad { - color: white; - position: absolute; - left: 20px; - top: 20px; -} \ No newline at end of file diff --git a/integrationExamples/mass/index.html b/integrationExamples/mass/index.html deleted file mode 100644 index 3b034957d13..00000000000 --- a/integrationExamples/mass/index.html +++ /dev/null @@ -1,132 +0,0 @@ - - - - - - - - - - - - - - - -
-

Note: for this example to work, you need access to a bid simulation tool from your MASS enabled Exchange partner.

-
- -
-
- - diff --git a/integrationExamples/postbid/oas/creative.html b/integrationExamples/postbid/oas/creative.html deleted file mode 100644 index 76b16b0fa57..00000000000 --- a/integrationExamples/postbid/oas/creative.html +++ /dev/null @@ -1,69 +0,0 @@ - -
- diff --git a/integrationExamples/postbid/oas/postbid-config.js b/integrationExamples/postbid/oas/postbid-config.js deleted file mode 100644 index f251938bc9c..00000000000 --- a/integrationExamples/postbid/oas/postbid-config.js +++ /dev/null @@ -1,54 +0,0 @@ - - \ No newline at end of file diff --git a/integrationExamples/postbid/oas/postbid.js b/integrationExamples/postbid/oas/postbid.js deleted file mode 100644 index 856f5f36207..00000000000 --- a/integrationExamples/postbid/oas/postbid.js +++ /dev/null @@ -1,135 +0,0 @@ -/* eslint-disable */ -(function(window){ - var postbid = {}; - postbid.que = []; - - var processQue = function(conf) { - for (var i = 0; i < postbid.que.length; i++) { - if (typeof postbid.que[i].called === 'undefined') { - try { - postbid.que[i].call(null, conf); - postbid.que[i].called = true; - } - catch (e) { - - } - } - } - } - - function getIframeContentDoc(iframe) { - var doc; - try { - if (iframe.contentWindow) { - doc = iframe.contentWindow.document; - } else if (iframe.contentDocument.document) { - doc = iframe.contentDocument.document; - } else { - doc = iframe.contentDocument; - } - } catch (e) { - } - return doc; - } - - function createIframe(id) { - var iframe = document.createElement('iframe'); - iframe.id = id; - iframe.width = '100%'; - iframe.height = '100%'; - iframe.frameBorder = "0"; - iframe.marginWidth = "0"; - iframe.marginHeight = "0"; - iframe.scrolling = "no"; - iframe.setAttribute('border', '0'); - iframe.setAttribute('allowtransparency', "true"); - - return iframe; - } - - function loadIframe(iframe, content) { - var iframeDoc = getIframeContentDoc(iframe); - iframeDoc.open('text/html', 'replace'); - iframeDoc.write(content); - iframeDoc.close(); - } - - function loadIeIframe(iframe, content) { - iframe.contentWindow.contents = content; - var base = document.getElementsByTagName('base'); - if(base.length) base[0].target = '_self'; - iframe.src = 'javascript:window["contents"];'; - if(base.length) base[0].target = '_blank'; - } - - function getBrowserType() { - var ua = navigator.userAgent.toLowerCase(); - - var match = /(webkit)[ \/]([\w.]+)/.exec(ua) || - /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || - /(msie) ([\w.]+)/.exec(ua) || - /(trident)(\/\d.0);/.exec(ua) || - (/trident\/7.0;/.test(ua)) ? ['msie'] : false || - ua.indexOf('compatible') < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || []; - - return match[1]; - } - - if (!Array.prototype.find) { - Object.defineProperty(Array.prototype, 'find', { - value: function(predicate) { - if (this == null) { - throw new TypeError('"this" is null or not defined'); - } - var o = Object(this); - var len = o.length >>> 0; - if (typeof predicate !== 'function') { - throw new TypeError('predicate must be a function'); - } - var thisArg = arguments[1]; - var k = 0; - while (k < len) { - var kValue = o[k]; - if (predicate.call(thisArg, kValue, k, o)) { - return kValue; - } - k++; - } - return undefined; - } - }); - } - - postbid.que.push(function(conf) { - var sizes = JSON.parse(conf.adUnitSizes); - var timeout = conf.timeout; - var adUnitCode = conf.adUnitCode; - var adUnitBids = conf.adUnitBids; - var targetId = conf.targetId; - var passbackTagHtml = conf.passbackTagHtml; - - var content = [%%postbid%%]; - content = content.replace(/\[%%targetId%%\]/g, targetId); - content = content.replace(/\[%%adUnitCode%%\]/g, adUnitCode); - content = content.replace(/\[%%timeout%%\]/g, timeout); - content = content.replace(/\[%%adUnitBids%%\]/g, adUnitBids); - content = content.replace(/\[%%passbackTagHtml%%\]/g, passbackTagHtml); - content = content.replace(/\[%%sizes%%\]/g, conf.adUnitSizes); - content = content.replace(/\[%%size0%%\]/g, sizes[0]); - content = content.replace(/\[%%size1%%\]/g, sizes[1]); - - var iframe = createIframe(conf.targetId); - var div = document.getElementById(conf.divId); - div.appendChild(iframe); - var browser = getBrowserType(); - if(browser === 'msie') { - loadIeIframe(iframe, content); - } else { - loadIframe(iframe, content); - } - }); - - window.processQue = processQue; - -})(window); -/* eslint-enable */ diff --git a/integrationExamples/postbid/postbid_prebidServer_example.html b/integrationExamples/postbid/postbid_prebidServer_example.html deleted file mode 100644 index 3af7b010872..00000000000 --- a/integrationExamples/postbid/postbid_prebidServer_example.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - diff --git a/integrationExamples/reviewerTools/index.html b/integrationExamples/reviewerTools/index.html deleted file mode 100755 index 2732cb4fd88..00000000000 --- a/integrationExamples/reviewerTools/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - Prebid Reviewer Tools - - - - -
-
-
-

Reviewer Tools

-

Below are links to the most common tool used by Prebid reviewers. For more info on PR review processes check out the General PR Review Process page on Github.

-

Common

- -

Other Tools

- -

Documentation & Training Material

- -
-
-
- - \ No newline at end of file diff --git a/iqmBidAdapter.js b/iqmBidAdapter.js new file mode 100644 index 00000000000..e3dbec80a7c --- /dev/null +++ b/iqmBidAdapter.js @@ -0,0 +1,290 @@ +import {registerBidder} from './src/adapters/bidderFactory.js'; +import {config} from './src/config.js'; +import * as utils from './src/utils.js'; +import {BANNER, VIDEO} from './src/mediaTypes.js'; +import {INSTREAM} from './src/video.js'; + +const BIDDER_CODE = 'iqm'; +const VERSION = 'v.1.0.0'; +const VIDEO_ORTB_PARAMS = [ + 'mimes', + 'minduration', + 'maxduration', + 'placement', + 'protocols', + 'startdelay' +]; +var ENDPOINT_URL = 'https://pbd.bids.iqm.com'; + +export const spec = { + supportedMediaTypes: [BANNER, VIDEO], + code: BIDDER_CODE, + aliases: ['iqm'], + + /** + * Determines whether or not the given bid request is valid. + * + * @param {BidRequest} bid The bid params to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ + isBidRequestValid: function (bid) { + const banner = utils.deepAccess(bid, 'mediaTypes.banner'); + const videoMediaType = utils.deepAccess(bid, 'mediaTypes.video'); + const context = utils.deepAccess(bid, 'mediaTypes.video.context'); + if ((videoMediaType && context === INSTREAM)) { + const videoBidderParams = utils.deepAccess(bid, 'params.video', {}); + + if (!Array.isArray(videoMediaType.playerSize)) { + return false; + } + + if (!videoMediaType.context) { + return false; + } + + const videoParams = { + ...videoMediaType, + ...videoBidderParams + }; + + if (!Array.isArray(videoParams.mimes) || videoParams.mimes.length === 0) { + return false; + } + + if (!Array.isArray(videoParams.protocols) || videoParams.protocols.length === 0) { + return false; + } + + if ( + typeof videoParams.placement !== 'undefined' && + typeof videoParams.placement === 'number' + ) { + return false; + } + if ( + videoMediaType.context === INSTREAM && + typeof videoParams.startdelay !== 'undefined' && + typeof videoParams.startdelay === 'number' + ) { + return false; + } + + return !!(bid && bid.params && bid.params.publisherId && bid.params.placementId); + } else { + if (banner === 'undefined') { + return false; + } + return !!(bid && bid.params && bid.params.publisherId && bid.params.placementId); + } + }, + /** + * Takes an array of valid bid requests, all of which are guaranteed to have passed the isBidRequestValid() test. + *It prepares a bid request with the required information for the DSP side and sends this request to alloted endpoint + * parameter{validBidRequests, bidderRequest} bidderRequest object is useful because it carries a couple of bid parameters that are global to all the bids. + */ + buildRequests: function (validBidRequests, bidderRequest) { + return validBidRequests.map(bid => { + var finalRequest = {}; + let bidfloor = utils.getBidIdParameter('bidfloor', bid.params); + + const imp = { + id: bid.bidId, + secure: 1, + bidfloor: bidfloor || 0, + displaymanager: 'Prebid.js', + displaymanagerver: VERSION, + + } + if (utils.deepAccess(bid, 'mediaTypes.banner')) { + imp.banner = getSize(bid.sizes); + imp.mediatype = 'banner'; + } else if (utils.deepAccess(bid, 'mediaTypes.video')) { + imp.video = _buildVideoORTB(bid); + imp.mediatype = 'video'; + } + const site = getSite(bid); + let device = getDevice(bid.params); + finalRequest = { + sizes: bid.sizes, + id: bid.bidId, + publisherId: utils.getBidIdParameter('publisherId', bid.params), + placementId: utils.getBidIdParameter('placementId', bid.params), + device: device, + site: site, + imp: imp, + auctionId: bid.auctionId, + adUnitCode: bid.adUnitCode, + bidderRequestId: bid.bidderRequestId, + uuid: bid.bidId, + bidderRequest + } + const request = { + method: 'POST', + url: ENDPOINT_URL, + data: finalRequest, + options: { + withCredentials: false + }, + + } + return request; + }); + }, + /** + * Takes Response from server as input and request. + *It parses the response from server side and generates bidresponses for with required rendering paramteres + * parameter{serverResponse, bidRequest} serverReponse: Response from the server side with ad creative. + */ + interpretResponse: function (serverResponse, bidRequest) { + const bidResponses = []; + serverResponse = serverResponse.body; + if (serverResponse && utils.isArray(serverResponse.seatbid)) { + utils._each(serverResponse.seatbid, function (bidList) { + utils._each(bidList.bid, function (bid) { + const responseCPM = parseFloat(bid.price); + if (responseCPM > 0.0 && bid.impid) { + const bidResponse = { + requestId: bidRequest.data.id, + currency: serverResponse.cur || 'USD', + cpm: responseCPM, + netRevenue: true, + creativeId: bid.crid || '', + adUnitCode: bidRequest.data.adUnitCode, + auctionId: bidRequest.data.auctionId, + mediaType: bidRequest.data.imp.mediatype, + + ttl: bid.ttl || config.getConfig('_bidderTimeout') + }; + + if (bidRequest.data.imp.mediatype === VIDEO) { + bidResponse.width = bid.w || bidRequest.data.imp.video.w; + bidResponse.height = bid.h || bidRequest.data.imp.video.h; + bidResponse.adResponse = { + content: bid.adm, + height: bidRequest.data.imp.video.h, + width: bidRequest.data.imp.video.w + }; + + if (bidRequest.data.imp.video.context === INSTREAM) { + bidResponse.vastUrl = bid.adm; + } + } else if (bidRequest.data.imp.mediatype === BANNER) { + bidResponse.ad = bid.adm; + bidResponse.width = bid.w || bidRequest.data.imp.banner.w; + bidResponse.height = bid.h || bidRequest.data.imp.banner.h; + } + bidResponses.push(bidResponse); + } + }) + }); + } + return bidResponses; + }, + +}; + +let getDevice = function (bidparams) { + const language = navigator.language ? 'language' : 'userLanguage'; + return { + geo: bidparams.geo, + h: screen.height, + w: screen.width, + dnt: _getDNT() ? 1 : 0, + language: navigator[language].split('-')[0], + make: navigator.vendor ? navigator.vendor : '', + ua: navigator.userAgent, + devicetype: _isMobile() ? 1 : _isConnectedTV() ? 3 : 2 + }; +}; + +let _getDNT = function () { + return navigator.doNotTrack === '1' || window.doNotTrack === '1' || navigator.msDoNotTrack === '1' || navigator.doNotTrack === 'yes'; +}; + +let getSize = function (sizes) { + let sizeMap; + if (sizes.length === 2 && typeof sizes[0] === 'number' && typeof sizes[1] === 'number') { + sizeMap = {w: sizes[0], h: sizes[1]}; + } else { + sizeMap = {w: sizes[0][0], h: sizes[0][1]}; + } + return sizeMap; +}; + +function _isMobile() { + return (/(ios|ipod|ipad|iphone|android)/i).test(global.navigator.userAgent); +} + +function _isConnectedTV() { + return (/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(global.navigator.userAgent); +} + +function getSite(bidderRequest) { + let domain = ''; + let page = ''; + let referrer = ''; + const Id = 1; + + const {refererInfo} = bidderRequest; + + if (canAccessTopWindow()) { + const wt = utils.getWindowTop(); + domain = wt.location.hostname; + page = wt.location.href; + referrer = wt.document.referrer || ''; + } else if (refererInfo.reachedTop) { + const url = utils.parseUrl(refererInfo.referer); + domain = url.hostname; + page = refererInfo.referer; + } else if (refererInfo.stack && refererInfo.stack.length && refererInfo.stack[0]) { + const url = utils.parseUrl(refererInfo.stack[0]); + domain = url.hostname; + } + + return { + domain, + page, + Id, + referrer + }; +}; + +function canAccessTopWindow() { + try { + if (utils.getWindowTop().location.href) { + return true; + } + } catch (error) { + return false; + } +} + +function _buildVideoORTB(bidRequest) { + const videoAdUnit = utils.deepAccess(bidRequest, 'mediaTypes.video'); + const videoBidderParams = utils.deepAccess(bidRequest, 'params.video', {}); + const video = {} + + const videoParams = { + ...videoAdUnit, + ...videoBidderParams // Bidder Specific overrides + }; + video.context = 1; + const {w, h} = getSize(videoParams.playerSize[0]); + video.w = w; + video.h = h; + + VIDEO_ORTB_PARAMS.forEach((param) => { + if (videoParams.hasOwnProperty(param)) { + video[param] = videoParams[param]; + } + }); + + video.placement = video.placement || 2; + + video.startdelay = video.startdelay || 0; + video.placement = 1; + video.context = INSTREAM; + + return video; +} +registerBidder(spec); diff --git a/iqmBidAdapter.md b/iqmBidAdapter.md new file mode 100644 index 00000000000..8398a591951 --- /dev/null +++ b/iqmBidAdapter.md @@ -0,0 +1,65 @@ +#Overview + +``` +Module Name: iQM Bidder Adapter +Module Type: Bidder Adapter +Maintainer: hbteam@iqm.com +``` + +# Parameters + +| Name | Scope | Description | Example | +| :------------ | :------- | :------------------------ | :------------------- | +| `publisherId` | required | The Publisher ID from iQM | "df5fd732-c5f3-11e7" | +| `placementId` | required | The Placement ID from iQM | "50cc36fe-c5f4-11e7" | +| `bidfloor` | optional | Bid Floor | 0.50 | + +# Description + +Module that connects to iQM demand sources + +# Test Parameters +``` +var videoAdUnit = { + code: 'video1', + mediaTypes: { + video: { + playerSize: [640,480], + context: 'instream' + } + }, + bids: [{ + bidder: 'iqm', + params: { + publisherId: 'test_publisher_id', + placementId: 23451, + bidfloor: 0.50, + video: { + placement :2, + mimes: ['video/mp4'], + protocols: [2,5], + skipppable: true, + playback_method: ['auto_play_sound_off'] + } + } + }] + + + var adUnits = [{ + code: 'div-gpt-ad-1460505748561-0', + mediaTypes: { + banner: { + sizes: [[844,617]] + } + }, + + bidder: 'iqm', + params: { + publisherId: 'test_publisher_id', + placementId: 23451, + bidfloor: 0.50 + } + }] + + }] +``` diff --git a/iqmBidAdapter_spec.js b/iqmBidAdapter_spec.js new file mode 100644 index 00000000000..d55268fd892 --- /dev/null +++ b/iqmBidAdapter_spec.js @@ -0,0 +1,227 @@ +import { expect } from 'chai'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import * as bidderFactory from 'src/adapters/bidderFactory.js'; +import { spec } from './iqmBidAdapter'; + +const ENDPOINT = 'https://pbd.bids.iqm.com'; + +describe('iqmAdapter', 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 () { + let bid = + { + bidder: 'iqm', + params: { + publisherId: 'df5fd732-c5f3-11e7-abc4-cec278b6b50a', + placementId: 23451, + bidfloor: 0.50 + }, + + 'adUnitCode': 'adunit-code', + 'sizes': [[300, 250]], + 'bidId': '30b31c1838de1e', + 'bidderRequestId': '22edbae2733bf6', + 'auctionId': '1d1a030790a475', + }; + + it('should return false when no bid', function () { + expect(spec.isBidRequestValid()).to.equal(false); + }); + + it('should return true when required params found', function () { + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + it('should return false when it is video and mimes and protcol are not present', function () { + const bid = { + adUnitCode: 'div-gpt-ad-1460505748561-0', + auctionId: 'a0aca162-e3d0-44db-a465-5c96a64fa5fb', + bidId: '2cbdc9b506be33', + bidRequestsCount: 1, + bidder: 'iqm', + bidderRequestId: '185c3a4c7f88ec', + bidderRequestsCount: 1, + bidderWinsCount: 0, + crumbs: {pubcid: 'f56a553d-370d-4cea-b31a-7214a3d8f8e1'}, + mediaTypes: { + video: { + context: 'instream', + playerSize: [ + [ + 640, + 480 + ] + ] + } + }, + params: { + publisherId: 'df5fd732-c5f3-11e7-abc4-cec278b6b50a', + placementId: 23451, + geo: { + country: 'USA' + }, + + bidfloor: 0.50, + video: { + placement: 2, + mimes: null, + protocols: null, + skipppable: true, + playback_method: ['auto_play_sound_off'] + } + }, + src: 'client', + transactionId: 'a57d06fd-cc6d-4a90-87af-c10727998f0b' }; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + it('should return false when required params are not found', function () { + let bid = Object.assign({}, bid); + delete bid.params; + bid.params = { + placementId: 0, + publisherId: null + + }; + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + + describe('buildRequests', function () { + let validBidRequests = [ + {bidder: 'iqm', + params: { + publisherId: 'df5fd732-c5f3-11e7-abc4-cec278b6b50a', + placementId: 23451, + bidfloor: 0.5}, + crumbs: { + pubcid: 'a0f51f64-6d86-41d0-abaf-7ece71404d94'}, + fpd: {'context': {'pbAdSlot': '/19968336/header-bid-tag-0'}}, + mediaTypes: { + banner: { + sizes: [[300, 250]]}}, + adUnitCode: '/19968336/header-bid-tag-0', + transactionId: '56fe8d92-ff6e-4c34-90ad-2f743cd0eae8', + sizes: [[300, 250]], + bidId: '266d810da21904', + bidderRequestId: '13c05d264c7ffe', + auctionId: '565ab569-ab95-40d6-8b42-b9707a92062f', + src: 'client', + bidRequestsCount: 1, + bidderRequestsCount: 1, + bidderWinsCount: 0}]; + + let bidderRequest = {bidderCode: 'iqm', auctionId: '565ab569-ab95-40d6-8b42-b9707a92062f', bidderRequestId: '13c05d264c7ffe', bids: [{bidder: 'iqm', params: {publisherId: 'df5fd732-c5f3-11e7-abc4-cec278b6b50a', placementId: 23451, bidfloor: 0.5}, crumbs: {pubcid: 'a0f51f64-6d86-41d0-abaf-7ece71404d94'}, fpd: {context: {pbAdSlot: '/19968336/header-bid-tag-0'}}, mediaTypes: {banner: {sizes: [[300, 250]]}}, adUnitCode: '/19968336/header-bid-tag-0', transactionId: '56fe8d92-ff6e-4c34-90ad-2f743cd0eae8', sizes: [[300, 250]], bidId: '266d810da21904', bidderRequestId: '13c05d264c7ffe', auctionId: '565ab569-ab95-40d6-8b42-b9707a92062f', src: 'client', bidRequestsCount: 1, bidderRequestsCount: 1, bidderWinsCount: 0}], auctionStart: 1615205942159, timeout: 7000, refererInfo: {referer: 'http://test.localhost:9999/integrationExamples/gpt/hello_world.html', reachedTop: true, isAmp: false, numIframes: 0, stack: ['http://test.localhost:9999/integrationExamples/gpt/hello_world.html'], canonicalUrl: null}, start: 1615205942162}; + + it('should parse out sizes', function () { + let temp = []; + const request = spec.buildRequests(validBidRequests, bidderRequest); + const payload = request[0].data; + + expect(payload.sizes).to.exist; + expect(payload.sizes[0]).to.deep.equal([300, 250]); + }); + + it('should populate the ad_types array on all requests', function () { + // const bidRequest = Object.assign({}, bidRequests[0]); + + const request = spec.buildRequests(validBidRequests, bidderRequest); + const payload = request[0].data; + + expect(payload.imp.mediatype).to.deep.equal('banner'); + }); + it('sends bid request to ENDPOINT via POST', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + expect(request[0].url).to.equal(ENDPOINT); + expect(request[0].method).to.equal('POST'); + }); + it('should attach valid video params to the tag', function () { + let validBidRequests_video = [{bidder: 'iqm', params: {publisherId: 'df5fd732-c5f3-11e7-abc4-cec278b6b50a', placementId: 23451, bidfloor: 0.5, video: {placement: 2, mimes: ['video/mp4'], protocols: [2, 5], skipppable: true, playback_method: ['auto_play_sound_off']}}, crumbs: {pubcid: '09b8f065-9d1b-4a36-bd0c-ea22e2dad807'}, fpd: {context: {pbAdSlot: 'video1'}}, mediaTypes: {video: {playerSize: [[640, 480]], context: 'instream'}}, adUnitCode: 'video1', transactionId: '86795c66-acf9-4dd5-998f-6d5362aaa541', sizes: [[640, 480]], bidId: '28bfb7e2d12897', bidderRequestId: '16e1ce8481bc6d', auctionId: '3140a2ec-d567-4db0-9bbb-eb6fa20ccb71', src: 'client', bidRequestsCount: 1, bidderRequestsCount: 1, bidderWinsCount: 0}]; + let bidderRequest_video = {bidderCode: 'iqm', auctionId: '3140a2ec-d567-4db0-9bbb-eb6fa20ccb71', bidderRequestId: '16e1ce8481bc6d', bids: [{bidder: 'iqm', params: {publisherId: 'df5fd732-c5f3-11e7-abc4-cec278b6b50a', placementId: 23451, bidfloor: 0.5, video: {placement: 2, mimes: ['video/mp4'], protocols: [2, 5], skipppable: true, playback_method: ['auto_play_sound_off']}}, crumbs: {pubcid: '09b8f065-9d1b-4a36-bd0c-ea22e2dad807'}, fpd: {context: {pbAdSlot: 'video1'}}, mediaTypes: {video: {playerSize: [[640, 480]], context: 'instream'}}, adUnitCode: 'video1', transactionId: '86795c66-acf9-4dd5-998f-6d5362aaa541', sizes: [[640, 480]], bidId: '28bfb7e2d12897', bidderRequestId: '16e1ce8481bc6d', auctionId: '3140a2ec-d567-4db0-9bbb-eb6fa20ccb71', src: 'client', bidRequestsCount: 1, bidderRequestsCount: 1, bidderWinsCount: 0}], auctionStart: 1615271191985, timeout: 3000, refererInfo: {referer: 'http://test.localhost:9999/integrationExamples/gpt/pbjs_video_adUnit.html', reachedTop: true, isAmp: false, numIframes: 0, stack: ['http://test.localhost:9999/integrationExamples/gpt/pbjs_video_adUnit.html'], canonicalUrl: null}, start: 1615271191988}; + const request = spec.buildRequests(validBidRequests_video, bidderRequest_video); + const payload = request[0].data; + expect(payload.imp.id).to.exist; + expect(payload.imp.displaymanager).to.exist; + expect(payload.imp.displaymanagerver).to.exist; + + expect(payload.imp.video).to.deep.equal({ + context: 'instream', + w: 640, + h: 480, + mimes: ['video/mp4'], + placement: 1, + protocols: [2, 5], + startdelay: 0 + }); + }); + + it('should add referer info to payload', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + const payload = request[0].data; + + expect(payload.bidderRequest.refererInfo).to.exist; + expect(payload.bidderRequest.refererInfo).to.deep.equal({referer: 'http://test.localhost:9999/integrationExamples/gpt/hello_world.html', reachedTop: true, isAmp: false, numIframes: 0, stack: ['http://test.localhost:9999/integrationExamples/gpt/hello_world.html'], canonicalUrl: null}); + }); + }) + + describe('interpretResponse', function () { + let tempResult = {requestId: '2d9601dd8328f8', currency: 'USD', cpm: 4.5, netRevenue: true, creativeId: 'cr-121004', adUnitCode: 'div-gpt-ad-1460505748561-0', 'auctionId': '22a4f3d8-511f-46ba-91be-53b9949e4b48', mediaType: 'banner', ttl: 3000, ad: "
", width: 844, height: 617}; + let validBidRequests_temp = [ + {bidder: 'iqm', + params: { + publisherId: 'df5fd732-c5f3-11e7-abc4-cec278b6b50a', + placementId: 23451, + bidfloor: 0.5}, + crumbs: { + pubcid: 'a0f51f64-6d86-41d0-abaf-7ece71404d94'}, + fpd: {'context': {'pbAdSlot': '/19968336/header-bid-tag-0'}}, + mediaTypes: { + banner: { + sizes: [[300, 250]]}}, + adUnitCode: '/19968336/header-bid-tag-0', + transactionId: '56fe8d92-ff6e-4c34-90ad-2f743cd0eae8', + sizes: [[300, 250]], + bidId: '266d810da21904', + bidderRequestId: '13c05d264c7ffe', + auctionId: '565ab569-ab95-40d6-8b42-b9707a92062f', + src: 'client', + bidRequestsCount: 1, + bidderRequestsCount: 1, + bidderWinsCount: 0}]; + let bidderRequest = {bidderCode: 'iqm', auctionId: '565ab569-ab95-40d6-8b42-b9707a92062f', bidderRequestId: '13c05d264c7ffe', bids: [{bidder: 'iqm', params: {publisherId: 'df5fd732-c5f3-11e7-abc4-cec278b6b50a', placementId: 23451, bidfloor: 0.5}, crumbs: {pubcid: 'a0f51f64-6d86-41d0-abaf-7ece71404d94'}, fpd: {context: {pbAdSlot: '/19968336/header-bid-tag-0'}}, mediaTypes: {banner: {sizes: [[300, 250]]}}, adUnitCode: '/19968336/header-bid-tag-0', transactionId: '56fe8d92-ff6e-4c34-90ad-2f743cd0eae8', sizes: [[300, 250]], bidId: '266d810da21904', bidderRequestId: '13c05d264c7ffe', auctionId: '565ab569-ab95-40d6-8b42-b9707a92062f', src: 'client', bidRequestsCount: 1, bidderRequestsCount: 1, bidderWinsCount: 0}], auctionStart: 1615205942159, timeout: 7000, refererInfo: {referer: 'http://test.localhost:9999/integrationExamples/gpt/hello_world.html', reachedTop: true, isAmp: false, numIframes: 0, stack: ['http://test.localhost:9999/integrationExamples/gpt/hello_world.html'], canonicalUrl: null}, start: 1615205942162}; + let response = { + + id: '5bdbab92aae961cfbdf7465d', + seatbid: [{bid: [{id: 'bid-5bdbab92aae961cfbdf7465d-5bdbab92aae961cfbdf74653', impid: '5bdbab92aae961cfbdf74653', price: 9.9, nurl: 'https://winn.stage.iqm.com/smaato?raw=w9XViV4dovBHrxujHhBj-l-uWB08CUOMW_oR-EUxZbaWLL0ENzcMlP3CJFEURN6FgRp_HdjAjxTYHR7uG4S6h6dl_vjU_YNABiPd607-iTqxOCl-2cKLo-hhQus4sMw01VIqyqrPmzOTHTwJm4vTjUIoWMPZbARgQvUnBzjRH9xeYS-Bv3kgAW9NSBfgBZeLyT3WJJ_3VKIE_Iurt8OjpA%3D%3D&req_id=5bdbab92aae961cfbdf7465d&ap=${AUCTION_PRICE}', adm: "
", adomain: ['click.iqm.com'], iurl: 'https://d3jme5si7t6llb.cloudfront.net/image/1/404/owVo6mc_1588902031079.png', cid: '169218', crid: 'cr-301435', attr: [], h: 250, w: 250}]}], + bidid: '5bdbab92aae961cfbdf7465d' + }; + + it('should get correct bid response', function () { + let expectedResponse = [ + {requestId: '49ad5f21156efd', currency: 'USD', cpm: 9.9, netRevenue: true, creativeId: 'cr-301435', adUnitCode: '/19968336/header-bid-tag-0', auctionId: '853cddf1-8d13-4482-bd88-f5ef927d5ab3', mediaType: 'banner', ttl: 3000, ad: "
", width: 250, height: 250} + ]; + let temprequest = spec.buildRequests(validBidRequests_temp, bidderRequest); + + let result = spec.interpretResponse({ body: response }, temprequest[0]); + expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); + }); + + let validBidRequests_temp_video = + [{bidder: 'iqm', params: {publisherId: 'df5fd732-c5f3-11e7-abc4-cec278b6b50a', placementId: 23451, bidfloor: 0.5, video: {placement: 2, mimes: ['video/mp4'], protocols: [2, 5], skipppable: true, playback_method: ['auto_play_sound_off']}}, crumbs: {pubcid: 'cd86c3ff-d630-40e6-83ab-420e9e800594'}, fpd: {context: {pbAdSlot: 'video1'}}, mediaTypes: {video: {playerSize: [[640, 480]], context: 'instream'}}, adUnitCode: 'video1', transactionId: '8335b266-7a41-45f9-86a2-92fdc7cf0cd9', sizes: [[640, 480]], bidId: '26274beff25455', bidderRequestId: '17c5d8c3168761', auctionId: '2c592dcf-7dfc-4823-8203-dd1ebab77fe0', src: 'client', bidRequestsCount: 1, bidderRequestsCount: 1, bidderWinsCount: 0}]; + let bidderRequest_video = {bidderCode: 'iqm', auctionId: '3140a2ec-d567-4db0-9bbb-eb6fa20ccb71', bidderRequestId: '16e1ce8481bc6d', bids: [{bidder: 'iqm', params: {publisherId: 'df5fd732-c5f3-11e7-abc4-cec278b6b50a', placementId: 23451, bidfloor: 0.5, video: {placement: 2, mimes: ['video/mp4'], protocols: [2, 5], skipppable: true, playback_method: ['auto_play_sound_off']}}, crumbs: {pubcid: '09b8f065-9d1b-4a36-bd0c-ea22e2dad807'}, fpd: {context: {pbAdSlot: 'video1'}}, mediaTypes: {video: {playerSize: [[640, 480]], context: 'instream'}}, adUnitCode: 'video1', transactionId: '86795c66-acf9-4dd5-998f-6d5362aaa541', sizes: [[640, 480]], bidId: '28bfb7e2d12897', bidderRequestId: '16e1ce8481bc6d', auctionId: '3140a2ec-d567-4db0-9bbb-eb6fa20ccb71', src: 'client', bidRequestsCount: 1, bidderRequestsCount: 1, bidderWinsCount: 0}], auctionStart: 1615271191985, timeout: 3000, refererInfo: {referer: 'http://test.localhost:9999/integrationExamples/gpt/pbjs_video_adUnit.html', reachedTop: true, isAmp: false, numIframes: 0, stack: ['http://test.localhost:9999/integrationExamples/gpt/pbjs_video_adUnit.html'], canonicalUrl: null}, start: 1615271191988}; + + it('handles non-banner media responses', function () { + let response = {id: '2341234', seatbid: [{bid: [{id: 'bid-2341234-1', impid: '1', price: 9, nurl: 'https://frontend.stage.iqm.com/static/vast-01.xml', adm: 'http://cdn.iqm.com/pbd?raw=312730_203cf73dc83fb_2824348636878_pbd', adomain: ['app1.stage.iqm.com'], cid: '168900', crid: 'cr-304503', attr: []}]}], bidid: '2341234'}; + + let temprequest_video = spec.buildRequests(validBidRequests_temp_video, bidderRequest_video); + + let result = spec.interpretResponse({ body: response }, temprequest_video[0]); + expect(result[0]).to.have.property('vastUrl'); + }); + }); +}); diff --git a/modules/.submodules.json b/modules/.submodules.json deleted file mode 100644 index 0a10044a78e..00000000000 --- a/modules/.submodules.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "userId": [ - "unifiedIdSystem", - "pubCommonIdSystem", - "id5IdSystem", - "parrableIdSystem", - "britepoolIdSystem", - "liveIntentIdSystem", - "lotamePanoramaId", - "merkleIdSystem", - "criteoIdSystem", - "netIdSystem", - "identityLinkIdSystem", - "sharedIdSystem", - "intentIqIdSystem", - "zeotapIdPlusIdSystem", - "haloIdSystem", - "quantcastIdSystem", - "deepintentDpesIdSystem", - "nextrollIdSystem", - "idxIdSystem", - "fabrickIdSystem", - "verizonMediaIdSystem", - "pubProvidedIdSystem", - "mwOpenLinkIdSystem", - "tapadIdSystem", - "novatiqIdSystem", - "uid2IdSystem", - "admixerIdSystem", - "dmdIdSystem", - "flocIdSystem" - ], - "adpod": [ - "freeWheelAdserverVideo", - "dfpAdServerVideo" - ], - "rtdModule": [ - "browsiRtdProvider", - "geoedgeRtdProvider", - "haloRtdProvider", - "jwplayerRtdProvider", - "permutiveRtdProvider", - "reconciliationRtdProvider", - "sirdataRtdProvider" - ], - "fpdModule": [ - "enrichmentFpdModule", - "validationFpdModule" - ] -} diff --git a/modules/1ad4goodBidAdapter.js b/modules/1ad4goodBidAdapter.js deleted file mode 100644 index 178f3765587..00000000000 --- a/modules/1ad4goodBidAdapter.js +++ /dev/null @@ -1,399 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import find from 'core-js-pure/features/array/find.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -const BIDDER_CODE = '1ad4good'; -const URL = 'https://hb.1ad4good.org/prebid'; -const VIDEO_TARGETING = ['id', 'mimes', 'minduration', 'maxduration', - 'startdelay', 'skippable', 'playback_method', 'frameworks']; -const USER_PARAMS = ['age', 'externalUid', 'segments', 'gender', 'dnt', 'language']; -const APP_DEVICE_PARAMS = ['geo', 'device_id']; // appid is collected separately -const SOURCE = 'pbjs'; -const MAX_IMPS_PER_REQUEST = 15; - -export const spec = { - code: BIDDER_CODE, - aliases: ['adsforgood', 'ads4good', '1adsforgood'], - supportedMediaTypes: [BANNER, VIDEO], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {object} bid The bid to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - return !!(bid.params.placementId); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server. - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(bidRequests, bidderRequest) { - const tags = bidRequests.map(bidToTag); - const userObjBid = find(bidRequests, hasUserInfo); - let userObj; - if (userObjBid) { - userObj = {}; - Object.keys(userObjBid.params.user) - .filter(param => includes(USER_PARAMS, param)) - .forEach(param => userObj[param] = userObjBid.params.user[param]); - } - - const appDeviceObjBid = find(bidRequests, hasAppDeviceInfo); - let appDeviceObj; - if (appDeviceObjBid && appDeviceObjBid.params && appDeviceObjBid.params.app) { - appDeviceObj = {}; - Object.keys(appDeviceObjBid.params.app) - .filter(param => includes(APP_DEVICE_PARAMS, param)) - .forEach(param => appDeviceObj[param] = appDeviceObjBid.params.app[param]); - } - - const appIdObjBid = find(bidRequests, hasAppId); - let appIdObj; - if (appIdObjBid && appIdObjBid.params && appDeviceObjBid.params.app && appDeviceObjBid.params.app.id) { - appIdObj = { - appid: appIdObjBid.params.app.id - }; - } - - const payload = { - tags: [...tags], - user: userObj, - sdk: { - source: SOURCE, - version: '$prebid.version$' - } - }; - - if (appDeviceObjBid) { - payload.device = appDeviceObj - } - if (appIdObjBid) { - payload.app = appIdObj; - } - - if (bidderRequest && bidderRequest.gdprConsent) { - // note - objects for impbus use underscore instead of camelCase - payload.gdpr_consent = { - consent_string: bidderRequest.gdprConsent.consentString, - consent_required: bidderRequest.gdprConsent.gdprApplies - }; - } - - if (bidderRequest && bidderRequest.refererInfo) { - let refererinfo = { - rd_ref: encodeURIComponent(bidderRequest.refererInfo.referer), - rd_top: bidderRequest.refererInfo.reachedTop, - rd_ifs: bidderRequest.refererInfo.numIframes, - rd_stk: bidderRequest.refererInfo.stack.map((url) => encodeURIComponent(url)).join(',') - } - payload.referrer_detection = refererinfo; - } - - const request = formatRequest(payload, bidderRequest); - return request; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse, {bidderRequest}) { - serverResponse = serverResponse.body; - const bids = []; - if (!serverResponse || serverResponse.error) { - let errorMessage = `in response for ${bidderRequest.bidderCode} adapter`; - if (serverResponse && serverResponse.error) { errorMessage += `: ${serverResponse.error}`; } - utils.logError(errorMessage); - return bids; - } - - if (serverResponse.tags) { - serverResponse.tags.forEach(serverBid => { - const rtbBid = getRtbBid(serverBid); - if (rtbBid) { - if (rtbBid.cpm !== 0 && includes(this.supportedMediaTypes, rtbBid.ad_type)) { - const bid = newBid(serverBid, rtbBid, bidderRequest); - bid.mediaType = parseMediaType(rtbBid); - bids.push(bid); - } - } - }); - } - - return bids; - }, - - transformBidParams: function(params, isOpenRtb) { - params = utils.convertTypes({ - 'placementId': 'number', - 'keywords': utils.transformBidderParamKeywords - }, params); - - if (isOpenRtb) { - params.use_pmt_rule = (typeof params.usePaymentRule === 'boolean') ? params.usePaymentRule : false; - if (params.usePaymentRule) { delete params.usePaymentRule; } - - if (isPopulatedArray(params.keywords)) { - params.keywords.forEach(deleteValues); - } - - Object.keys(params).forEach(paramKey => { - let convertedKey = utils.convertCamelToUnderscore(paramKey); - if (convertedKey !== paramKey) { - params[convertedKey] = params[paramKey]; - delete params[paramKey]; - } - }); - } - - return params; - }, - - /** - * Add element selector to javascript tracker to improve native viewability - * @param {Bid} bid - */ - onBidWon: function(bid) { - } -} - -function isPopulatedArray(arr) { - return !!(utils.isArray(arr) && arr.length > 0); -} - -function deleteValues(keyPairObj) { - if (isPopulatedArray(keyPairObj.value) && keyPairObj.value[0] === '') { - delete keyPairObj.value; - } -} - -function formatRequest(payload, bidderRequest) { - let request = []; - - if (payload.tags.length > MAX_IMPS_PER_REQUEST) { - const clonedPayload = utils.deepClone(payload); - - utils.chunk(payload.tags, MAX_IMPS_PER_REQUEST).forEach(tags => { - clonedPayload.tags = tags; - const payloadString = JSON.stringify(clonedPayload); - request.push({ - method: 'POST', - url: URL, - data: payloadString, - bidderRequest - }); - }); - } else { - const payloadString = JSON.stringify(payload); - request = { - method: 'POST', - url: URL, - data: payloadString, - bidderRequest - }; - } - - return request; -} - -/** - * Unpack the Server's Bid into a Prebid-compatible one. - * @param serverBid - * @param rtbBid - * @param bidderRequest - * @return Bid - */ -function newBid(serverBid, rtbBid, bidderRequest) { - const bidRequest = utils.getBidRequest(serverBid.uuid, [bidderRequest]); - const bid = { - requestId: serverBid.uuid, - cpm: rtbBid.cpm, - creativeId: rtbBid.creative_id, - dealId: rtbBid.deal_id, - currency: 'USD', - netRevenue: true, - ttl: 300, - adUnitCode: bidRequest.adUnitCode, - ads4good: { - buyerMemberId: rtbBid.buyer_member_id, - dealPriority: rtbBid.deal_priority, - dealCode: rtbBid.deal_code - } - }; - - if (rtbBid.advertiser_id) { - bid.meta = Object.assign({}, bid.meta, { advertiserId: rtbBid.advertiser_id }); - } - - if (rtbBid.rtb.video) { - Object.assign(bid, { - width: rtbBid.rtb.video.player_width, - height: rtbBid.rtb.video.player_height, - vastUrl: rtbBid.rtb.video.asset_url, - vastImpUrl: rtbBid.notify_url, - ttl: 3600 - }); - } else { - Object.assign(bid, { - width: rtbBid.rtb.banner.width, - height: rtbBid.rtb.banner.height, - ad: rtbBid.rtb.banner.content - }); - try { - const url = rtbBid.rtb.trackers[0].impression_urls[0]; - const tracker = utils.createTrackPixelHtml(url); - bid.ad += tracker; - } catch (error) { - utils.logError('Error appending tracking pixel', error); - } - } - - return bid; -} - -function bidToTag(bid) { - const tag = {}; - tag.sizes = transformSizes(bid.sizes); - tag.primary_size = tag.sizes[0]; - tag.ad_types = []; - tag.uuid = bid.bidId; - if (bid.params.placementId) { - tag.id = parseInt(bid.params.placementId, 10); - } - if (bid.params.cpm) { - tag.cpm = bid.params.cpm; - } - tag.allow_smaller_sizes = bid.params.allowSmallerSizes || false; - tag.use_pmt_rule = bid.params.usePaymentRule || false - tag.prebid = true; - tag.disable_psa = true; - if (bid.params.reserve) { - tag.reserve = bid.params.reserve; - } - if (bid.params.position) { - tag.position = {'above': 1, 'below': 2}[bid.params.position] || 0; - } - if (bid.params.trafficSourceCode) { - tag.traffic_source_code = bid.params.trafficSourceCode; - } - if (bid.params.privateSizes) { - tag.private_sizes = transformSizes(bid.params.privateSizes); - } - if (bid.params.supplyType) { - tag.supply_type = bid.params.supplyType; - } - if (bid.params.pubClick) { - tag.pubclick = bid.params.pubClick; - } - if (bid.params.extInvCode) { - tag.ext_inv_code = bid.params.extInvCode; - } - if (bid.params.externalImpId) { - tag.external_imp_id = bid.params.externalImpId; - } - if (!utils.isEmpty(bid.params.keywords)) { - let keywords = utils.transformBidderParamKeywords(bid.params.keywords); - - if (keywords.length > 0) { - keywords.forEach(deleteValues); - } - tag.keywords = keywords; - } - - const videoMediaType = utils.deepAccess(bid, `mediaTypes.${VIDEO}`); - const context = utils.deepAccess(bid, 'mediaTypes.video.context'); - - if (bid.mediaType === VIDEO || videoMediaType) { - tag.ad_types.push(VIDEO); - } - - // instream gets vastUrl, outstream gets vastXml - if (bid.mediaType === VIDEO || (videoMediaType && context !== 'outstream')) { - tag.require_asset_url = true; - } - - if (bid.params.video) { - tag.video = {}; - // place any valid video params on the tag - Object.keys(bid.params.video) - .filter(param => includes(VIDEO_TARGETING, param)) - .forEach(param => tag.video[param] = bid.params.video[param]); - } - - if (bid.renderer) { - tag.video = Object.assign({}, tag.video, {custom_renderer_present: true}); - } - - if ( - (utils.isEmpty(bid.mediaType) && utils.isEmpty(bid.mediaTypes)) || - (bid.mediaType === BANNER || (bid.mediaTypes && bid.mediaTypes[BANNER])) - ) { - tag.ad_types.push(BANNER); - } - - return tag; -} - -/* Turn bid request sizes into ut-compatible format */ -function transformSizes(requestSizes) { - let sizes = []; - let sizeObj = {}; - - if (utils.isArray(requestSizes) && requestSizes.length === 2 && - !utils.isArray(requestSizes[0])) { - sizeObj.width = parseInt(requestSizes[0], 10); - sizeObj.height = parseInt(requestSizes[1], 10); - sizes.push(sizeObj); - } else if (typeof requestSizes === 'object') { - for (let i = 0; i < requestSizes.length; i++) { - let size = requestSizes[i]; - sizeObj = {}; - sizeObj.width = parseInt(size[0], 10); - sizeObj.height = parseInt(size[1], 10); - sizes.push(sizeObj); - } - } - - return sizes; -} - -function hasUserInfo(bid) { - return !!bid.params.user; -} - -function hasAppDeviceInfo(bid) { - if (bid.params) { - return !!bid.params.app - } -} - -function hasAppId(bid) { - if (bid.params && bid.params.app) { - return !!bid.params.app.id - } - return !!bid.params.app -} - -function getRtbBid(tag) { - return tag && tag.ads && tag.ads.length && find(tag.ads, ad => ad.rtb); -} - -function parseMediaType(rtbBid) { - const adType = rtbBid.ad_type; - if (adType === VIDEO) { - return VIDEO; - } else { - return BANNER; - } -} - -registerBidder(spec); diff --git a/modules/1ad4goodBidAdapter.md b/modules/1ad4goodBidAdapter.md deleted file mode 100644 index 1e9dfe5e04c..00000000000 --- a/modules/1ad4goodBidAdapter.md +++ /dev/null @@ -1,87 +0,0 @@ -# Overview - -``` -Module Name: 1ad4good Bid Adapter -Module Type: Bidder Adapter -Maintainer: info@1ad4good.org -``` - -# Description - -Connects to 1ad4good exchange for bids. - -1ad4good bid adapter supports Banner and Video (instream). - -# Test Parameters -``` -var adUnits = [ - // Banner adUnit - { - code: 'banner-div', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]] - } - }, - bids: [{ - bidder: '1ad4good', - params: { - placementId: 13144370 - } - }] - }, - // Video instream adUnit - { - code: 'video-instream', - sizes: [[640, 480]], - mediaTypes: { - video: { - playerSize: [[640, 480]], - context: 'instream' - }, - }, - bids: [{ - bidder: '1ad4good', - params: { - placementId: 13232361, - video: { - skippable: true, - playback_methods: ['auto_play_sound_off'] - } - } - }] - }, - - // Banner adUnit in a App Webview - // Only use this for situations where prebid.js is in a webview of an App - // See Prebid Mobile for displaying ads via an SDK - { - code: 'banner-div', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]] - } - } - bids: [{ - bidder: '1ad4good', - params: { - placementId: 13144370, - app: { - id: "B1O2W3M4AN.com.prebid.webview", - geo: { - lat: 40.0964439, - lng: -75.3009142 - }, - device_id: { - idfa: "4D12078D-3246-4DA4-AD5E-7610481E7AE", // Apple advertising identifier - aaid: "38400000-8cf0-11bd-b23e-10b96e40000d", // Android advertising identifier - md5udid: "5756ae9022b2ea1e47d84fead75220c8", // MD5 hash of the ANDROID_ID - sha1udid: "4DFAA92388699AC6539885AEF1719293879985BF", // SHA1 hash of the ANDROID_ID - windowsadid: "750c6be243f1c4b5c9912b95a5742fc5" // Windows advertising identifier - } - } - } - }] - } -]; -``` diff --git a/modules/33acrossBidAdapter.js b/modules/33acrossBidAdapter.js deleted file mode 100644 index 4b8028d97fd..00000000000 --- a/modules/33acrossBidAdapter.js +++ /dev/null @@ -1,654 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { config } from '../src/config.js'; -import * as utils from '../src/utils.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; - -const BIDDER_CODE = '33across'; -const END_POINT = 'https://ssc.33across.com/api/v1/hb'; -const SYNC_ENDPOINT = 'https://ssc-cms.33across.com/ps/?m=xch&rt=html&ru=deb'; - -const CURRENCY = 'USD'; -const GUID_PATTERN = /^[a-zA-Z0-9_-]{22}$/; - -const PRODUCT = { - SIAB: 'siab', - INVIEW: 'inview', - INSTREAM: 'instream' -}; - -const VIDEO_ORTB_PARAMS = [ - 'mimes', - 'minduration', - 'maxduration', - 'placement', - 'protocols', - 'startdelay', - 'skip', - 'skipafter', - 'minbitrate', - 'maxbitrate', - 'delivery', - 'playbackmethod', - 'api', - 'linearity' -]; - -const adapterState = { - uniqueSiteIds: [] -}; - -const NON_MEASURABLE = 'nm'; - -// **************************** VALIDATION *************************** // -function isBidRequestValid(bid) { - return ( - _validateBasic(bid) && - _validateBanner(bid) && - _validateVideo(bid) - ); -} - -function _validateBasic(bid) { - if (bid.bidder !== BIDDER_CODE || typeof bid.params === 'undefined') { - return false; - } - - if (!_validateGUID(bid)) { - return false; - } - - return true; -} - -function _validateGUID(bid) { - const siteID = utils.deepAccess(bid, 'params.siteId', '') || ''; - if (siteID.trim().match(GUID_PATTERN) === null) { - return false; - } - - return true; -} - -function _validateBanner(bid) { - const banner = utils.deepAccess(bid, 'mediaTypes.banner'); - // If there's no banner no need to validate against banner rules - if (banner === undefined) { - return true; - } - - if (!Array.isArray(banner.sizes)) { - return false; - } - - return true; -} - -function _validateVideo(bid) { - const videoAdUnit = utils.deepAccess(bid, 'mediaTypes.video'); - const videoBidderParams = utils.deepAccess(bid, 'params.video', {}); - - // If there's no video no need to validate against video rules - if (videoAdUnit === undefined) { - return true; - } - - if (!Array.isArray(videoAdUnit.playerSize)) { - return false; - } - - if (!videoAdUnit.context) { - return false; - } - - const videoParams = { - ...videoAdUnit, - ...videoBidderParams - }; - - if (!Array.isArray(videoParams.mimes) || videoParams.mimes.length === 0) { - return false; - } - - if (!Array.isArray(videoParams.protocols) || videoParams.protocols.length === 0) { - return false; - } - - // If placement if defined, it must be a number - if ( - typeof videoParams.placement !== 'undefined' && - typeof videoParams.placement !== 'number' - ) { - return false; - } - - // If startdelay is defined it must be a number - if ( - videoAdUnit.context === 'instream' && - typeof videoParams.startdelay !== 'undefined' && - typeof videoParams.startdelay !== 'number' - ) { - return false; - } - - return true; -} - -// **************************** BUILD REQUESTS *************************** // -// NOTE: With regards to gdrp consent data, the server will independently -// infer the gdpr applicability therefore, setting the default value to false -function buildRequests(bidRequests, bidderRequest) { - const gdprConsent = Object.assign({ - consentString: undefined, - gdprApplies: false - }, bidderRequest && bidderRequest.gdprConsent); - - const uspConsent = bidderRequest && bidderRequest.uspConsent; - const pageUrl = (bidderRequest && bidderRequest.refererInfo) ? (bidderRequest.refererInfo.referer) : (undefined); - - adapterState.uniqueSiteIds = bidRequests.map(req => req.params.siteId).filter(utils.uniques); - - return bidRequests.map(bidRequest => _createServerRequest( - { - bidRequest, - gdprConsent, - uspConsent, - pageUrl - }) - ); -} - -// Infer the necessary data from valid bid for a minimal ttxRequest and create HTTP request -// NOTE: At this point, TTX only accepts request for a single impression -function _createServerRequest({bidRequest, gdprConsent = {}, uspConsent, pageUrl}) { - const ttxRequest = {}; - const params = bidRequest.params; - - /* - * Infer data for the request payload - */ - ttxRequest.imp = [{}]; - - if (utils.deepAccess(bidRequest, 'mediaTypes.banner')) { - ttxRequest.imp[0].banner = { - ..._buildBannerORTB(bidRequest) - } - } - - if (utils.deepAccess(bidRequest, 'mediaTypes.video')) { - ttxRequest.imp[0].video = _buildVideoORTB(bidRequest); - } - - ttxRequest.imp[0].ext = { - ttx: { - prod: _getProduct(bidRequest) - } - }; - - ttxRequest.site = { id: params.siteId }; - - if (pageUrl) { - ttxRequest.site.page = pageUrl; - } - - // Go ahead send the bidId in request to 33exchange so it's kept track of in the bid response and - // therefore in ad targetting process - ttxRequest.id = bidRequest.bidId; - - if (gdprConsent.consentString) { - ttxRequest.user = setExtension( - ttxRequest.user, - 'consent', - gdprConsent.consentString - ) - } - - if (Array.isArray(bidRequest.userIdAsEids) && bidRequest.userIdAsEids.length > 0) { - ttxRequest.user = setExtension( - ttxRequest.user, - 'eids', - bidRequest.userIdAsEids - ) - } - - ttxRequest.regs = setExtension( - ttxRequest.regs, - 'gdpr', - Number(gdprConsent.gdprApplies) - ); - - if (uspConsent) { - ttxRequest.regs = setExtension( - ttxRequest.regs, - 'us_privacy', - uspConsent - ) - } - - ttxRequest.ext = { - ttx: { - prebidStartedAt: Date.now(), - caller: [ { - 'name': 'prebidjs', - 'version': '$prebid.version$' - } ] - } - }; - - if (bidRequest.schain) { - ttxRequest.source = setExtension( - ttxRequest.source, - 'schain', - bidRequest.schain - ) - } - - // Finally, set the openRTB 'test' param if this is to be a test bid - if (params.test === 1) { - ttxRequest.test = 1; - } - - /* - * Now construct the full server request - */ - const options = { - contentType: 'text/plain', - withCredentials: true - }; - - // Allow the ability to configure the HB endpoint for testing purposes. - const ttxSettings = config.getConfig('ttxSettings'); - const url = (ttxSettings && ttxSettings.url) || `${END_POINT}?guid=${params.siteId}`; - - // Return the server request - return { - 'method': 'POST', - 'url': url, - 'data': JSON.stringify(ttxRequest), - 'options': options - } -} - -// BUILD REQUESTS: SET EXTENSIONS -function setExtension(obj = {}, key, value) { - return Object.assign({}, obj, { - ext: Object.assign({}, obj.ext, { - [key]: value - }) - }); -} - -// BUILD REQUESTS: SIZE INFERENCE -function _transformSizes(sizes) { - if (utils.isArray(sizes) && sizes.length === 2 && !utils.isArray(sizes[0])) { - return [ _getSize(sizes) ]; - } - - return sizes.map(_getSize); -} - -function _getSize(size) { - return { - w: parseInt(size[0], 10), - h: parseInt(size[1], 10) - } -} - -// BUILD REQUESTS: PRODUCT INFERENCE -function _getProduct(bidRequest) { - const { params, mediaTypes } = bidRequest; - - const { banner, video } = mediaTypes; - - if ((video && !banner) && video.context === 'instream') { - return PRODUCT.INSTREAM; - } - - return (params.productId === PRODUCT.INVIEW) ? (params.productId) : PRODUCT.SIAB; -} - -// BUILD REQUESTS: BANNER -function _buildBannerORTB(bidRequest) { - const bannerAdUnit = utils.deepAccess(bidRequest, 'mediaTypes.banner', {}); - const element = _getAdSlotHTMLElement(bidRequest.adUnitCode); - - const sizes = _transformSizes(bannerAdUnit.sizes); - - let format; - - // We support size based bidfloors so obtain one if there's a rule associated - if (typeof bidRequest.getFloor === 'function') { - format = sizes.map((size) => { - const bidfloors = _getBidFloors(bidRequest, size, BANNER); - - let formatExt; - if (bidfloors) { - formatExt = { - ext: { - ttx: { - bidfloors: [ bidfloors ] - } - } - } - } - - return Object.assign({}, size, formatExt); - }); - } else { - format = sizes; - } - - const minSize = _getMinSize(sizes); - - const viewabilityAmount = _isViewabilityMeasurable(element) - ? _getViewability(element, utils.getWindowTop(), minSize) - : NON_MEASURABLE; - - const ext = contributeViewability(viewabilityAmount); - - return { - format, - ext - } -} - -// BUILD REQUESTS: VIDEO -// eslint-disable-next-line no-unused-vars -function _buildVideoORTB(bidRequest) { - const videoAdUnit = utils.deepAccess(bidRequest, 'mediaTypes.video', {}); - const videoBidderParams = utils.deepAccess(bidRequest, 'params.video', {}); - - const videoParams = { - ...videoAdUnit, - ...videoBidderParams // Bidder Specific overrides - }; - - const video = {} - - const {w, h} = _getSize(videoParams.playerSize[0]); - video.w = w; - video.h = h; - - // Obtain all ORTB params related video from Ad Unit - VIDEO_ORTB_PARAMS.forEach((param) => { - if (videoParams.hasOwnProperty(param)) { - video[param] = videoParams[param]; - } - }); - - const product = _getProduct(bidRequest); - - // Placement Inference Rules: - // - If no placement is defined then default to 2 (In Banner) - // - If product is instream (for instream context) then override placement to 1 - video.placement = video.placement || 2; - - if (product === PRODUCT.INSTREAM) { - video.startdelay = video.startdelay || 0; - video.placement = 1; - }; - - // bidfloors - if (typeof bidRequest.getFloor === 'function') { - const bidfloors = _getBidFloors(bidRequest, {w: video.w, h: video.h}, VIDEO); - - if (bidfloors) { - Object.assign(video, { - ext: { - ttx: { - bidfloors: [ bidfloors ] - } - } - }); - } - } - return video; -} - -// BUILD REQUESTS: BIDFLOORS -function _getBidFloors(bidRequest, size, mediaType) { - const bidFloors = bidRequest.getFloor({ - currency: CURRENCY, - mediaType, - size: [ size.w, size.h ] - }); - - if (!isNaN(bidFloors.floor) && (bidFloors.currency === CURRENCY)) { - return bidFloors.floor; - } -} - -// BUILD REQUESTS: VIEWABILITY -function _isViewabilityMeasurable(element) { - return !_isIframe() && element !== null; -} - -function _getViewability(element, topWin, { w, h } = {}) { - return topWin.document.visibilityState === 'visible' - ? _getPercentInView(element, topWin, { w, h }) - : 0; -} - -function _mapAdUnitPathToElementId(adUnitCode) { - if (utils.isGptPubadsDefined()) { - // eslint-disable-next-line no-undef - const adSlots = googletag.pubads().getSlots(); - const isMatchingAdSlot = utils.isSlotMatchingAdUnitCode(adUnitCode); - - for (let i = 0; i < adSlots.length; i++) { - if (isMatchingAdSlot(adSlots[i])) { - const id = adSlots[i].getSlotElementId(); - - utils.logInfo(`[33Across Adapter] Map ad unit path to HTML element id: '${adUnitCode}' -> ${id}`); - - return id; - } - } - } - - utils.logWarn(`[33Across Adapter] Unable to locate element for ad unit code: '${adUnitCode}'`); - - return null; -} - -function _getAdSlotHTMLElement(adUnitCode) { - return document.getElementById(adUnitCode) || - document.getElementById(_mapAdUnitPathToElementId(adUnitCode)); -} - -function _getMinSize(sizes) { - return sizes.reduce((min, size) => size.h * size.w < min.h * min.w ? size : min); -} - -function _getBoundingBox(element, { w, h } = {}) { - let { width, height, left, top, right, bottom } = element.getBoundingClientRect(); - - if ((width === 0 || height === 0) && w && h) { - width = w; - height = h; - right = left + w; - bottom = top + h; - } - - return { width, height, left, top, right, bottom }; -} - -function _getIntersectionOfRects(rects) { - const bbox = { - left: rects[0].left, - right: rects[0].right, - top: rects[0].top, - bottom: rects[0].bottom - }; - - for (let i = 1; i < rects.length; ++i) { - bbox.left = Math.max(bbox.left, rects[i].left); - bbox.right = Math.min(bbox.right, rects[i].right); - - if (bbox.left >= bbox.right) { - return null; - } - - bbox.top = Math.max(bbox.top, rects[i].top); - bbox.bottom = Math.min(bbox.bottom, rects[i].bottom); - - if (bbox.top >= bbox.bottom) { - return null; - } - } - - bbox.width = bbox.right - bbox.left; - bbox.height = bbox.bottom - bbox.top; - - return bbox; -} - -function _getPercentInView(element, topWin, { w, h } = {}) { - const elementBoundingBox = _getBoundingBox(element, { w, h }); - - // Obtain the intersection of the element and the viewport - const elementInViewBoundingBox = _getIntersectionOfRects([ { - left: 0, - top: 0, - right: topWin.innerWidth, - bottom: topWin.innerHeight - }, elementBoundingBox ]); - - let elementInViewArea, - elementTotalArea; - - if (elementInViewBoundingBox !== null) { - // Some or all of the element is in view - elementInViewArea = elementInViewBoundingBox.width * elementInViewBoundingBox.height; - elementTotalArea = elementBoundingBox.width * elementBoundingBox.height; - - return ((elementInViewArea / elementTotalArea) * 100); - } - - // No overlap between element and the viewport; therefore, the element - // lies completely out of view - return 0; -} - -/** - * Viewability contribution to request.. - */ -function contributeViewability(viewabilityAmount) { - const amount = isNaN(viewabilityAmount) ? viewabilityAmount : Math.round(viewabilityAmount); - - return { - ttx: { - viewability: { - amount - } - } - }; -} - -function _isIframe() { - try { - return utils.getWindowSelf() !== utils.getWindowTop(); - } catch (e) { - return true; - } -} - -// **************************** INTERPRET RESPONSE ******************************** // -// NOTE: At this point, the response from 33exchange will only ever contain one bid -// i.e. the highest bid -function interpretResponse(serverResponse, bidRequest) { - const bidResponses = []; - - // If there are bids, look at the first bid of the first seatbid (see NOTE above for assumption about ttx) - if (serverResponse.body.seatbid.length > 0 && serverResponse.body.seatbid[0].bid.length > 0) { - bidResponses.push(_createBidResponse(serverResponse.body)); - } - - return bidResponses; -} - -// All this assumes that only one bid is ever returned by ttx -function _createBidResponse(response) { - const isADomainPresent = - response.seatbid[0].bid[0].adomain && response.seatbid[0].bid[0].adomain.length; - const bid = { - requestId: response.id, - bidderCode: BIDDER_CODE, - cpm: response.seatbid[0].bid[0].price, - width: response.seatbid[0].bid[0].w, - height: response.seatbid[0].bid[0].h, - ad: response.seatbid[0].bid[0].adm, - ttl: response.seatbid[0].bid[0].ttl || 60, - creativeId: response.seatbid[0].bid[0].crid, - mediaType: utils.deepAccess(response.seatbid[0].bid[0], 'ext.ttx.mediaType', BANNER), - currency: response.cur, - netRevenue: true - } - - if (isADomainPresent) { - bid.meta = { - advertiserDomains: response.seatbid[0].bid[0].adomain - }; - } - - if (bid.mediaType === VIDEO) { - const vastType = utils.deepAccess(response.seatbid[0].bid[0], 'ext.ttx.vastType', 'xml'); - - if (vastType === 'xml') { - bid.vastXml = bid.ad; - } else { - bid.vastUrl = bid.ad; - } - } - - return bid; -} - -// **************************** USER SYNC *************************** // -// Register one sync per unique guid so long as iframe is enable -// Else no syncs -// For logic on how we handle gdpr data see _createSyncs and module's unit tests -// '33acrossBidAdapter#getUserSyncs' -function getUserSyncs(syncOptions, responses, gdprConsent, uspConsent) { - const syncUrls = ( - (syncOptions.iframeEnabled) - ? adapterState.uniqueSiteIds.map((siteId) => _createSync({ gdprConsent, uspConsent, siteId })) - : ([]) - ); - - // Clear adapter state of siteID's since we don't need this info anymore. - adapterState.uniqueSiteIds = []; - - return syncUrls; -} - -// Sync object will always be of type iframe for TTX -function _createSync({ siteId = 'zzz000000000003zzz', gdprConsent = {}, uspConsent }) { - const ttxSettings = config.getConfig('ttxSettings'); - const syncUrl = (ttxSettings && ttxSettings.syncUrl) || SYNC_ENDPOINT; - - const { consentString, gdprApplies } = gdprConsent; - - const sync = { - type: 'iframe', - url: `${syncUrl}&id=${siteId}&gdpr_consent=${encodeURIComponent(consentString)}&us_privacy=${encodeURIComponent(uspConsent)}` - }; - - if (typeof gdprApplies === 'boolean') { - sync.url += `&gdpr=${Number(gdprApplies)}`; - } - - return sync; -} - -export const spec = { - NON_MEASURABLE, - - code: BIDDER_CODE, - supportedMediaTypes: [ BANNER, VIDEO ], - isBidRequestValid, - buildRequests, - interpretResponse, - getUserSyncs, -}; - -registerBidder(spec); diff --git a/modules/33acrossBidAdapter.md b/modules/33acrossBidAdapter.md deleted file mode 100644 index c01c04251e5..00000000000 --- a/modules/33acrossBidAdapter.md +++ /dev/null @@ -1,154 +0,0 @@ -# Overview - -``` -Module Name: 33Across Bid Adapter -Module Type: Bidder Adapter -Maintainer: headerbidding@33across.com -``` - -# Description - -Connects to 33Across's exchange for bids. - -33Across bid adapter supports Banner and Video at present and follows MRA - -# Sample Ad Unit: For Publishers -## Sample Banner only Ad Unit -``` -var adUnits = [ -{ - code: '33across-hb-ad-123456-1', // ad slot HTML element ID - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [728, 90] - ] - } - } - bids: [{ - bidder: '33across', - params: { - siteId: 'sample33xGUID123456789', - productId: 'siab' - } - }] -} -``` - -## Sample Video only Ad Unit: Outstream -``` -var adUnits = [ -{ - code: '33across-hb-ad-123456-1', // ad slot HTML element ID - mediaTypes: { - video: { - playerSize: [300, 250], - context: 'outstream', - placement: 2 - ... // Aditional ORTB video params - } - }, - renderer: { - url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', - render: function (bid) { - adResponse = { - ad: { - video: { - content: bid.vastXml, - player_height: bid.playerHeight, - player_width: bid.playerWidth - } - } - } - // push to render queue because ANOutstreamVideo may not be loaded yet. - bid.renderer.push(() => { - ANOutstreamVideo.renderAd({ - targetId: bid.adUnitCode, // target div id to render video. - adResponse: adResponse - }); - }); - } - }, - bids: [{ - bidder: '33across', - params: { - siteId: 'sample33xGUID123456789', - productId: 'siab' - } - }] -} -``` - -## Sample Multi-Format Ad Unit: Outstream -``` -var adUnits = [ -{ - code: '33across-hb-ad-123456-1', // ad slot HTML element ID - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [728, 90] - ] - }, - video: { - playerSize: [300, 250], - context: 'outstream', - placement: 2 - ... // Aditional ORTB video params - } - }, - renderer: { - url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', - render: function (bid) { - adResponse = { - ad: { - video: { - content: bid.vastXml, - player_height: bid.playerHeight, - player_width: bid.playerWidth - } - } - } - // push to render queue because ANOutstreamVideo may not be loaded yet. - bid.renderer.push(() => { - ANOutstreamVideo.renderAd({ - targetId: bid.adUnitCode, // target div id to render video. - adResponse: adResponse - }); - }); - } - }, - bids: [{ - bidder: '33across', - params: { - siteId: 'sample33xGUID123456789', - productId: 'siab' - } - }] -} -``` - -## Sample Video only Ad Unit: Instream -``` -var adUnits = [ -{ - code: '33across-hb-ad-123456-1', // ad slot HTML element ID - mediaTypes: { - video: { - playerSize: [300, 250], - context: 'intstream', - placement: 1 - ... // Aditional ORTB video params - } - } - bids: [{ - bidder: '33across', - params: { - siteId: 'sample33xGUID123456789', - productId: 'instream' - } - }] -} -``` diff --git a/modules/7xbidBidAdapter.js b/modules/7xbidBidAdapter.js deleted file mode 100644 index b925912a399..00000000000 --- a/modules/7xbidBidAdapter.js +++ /dev/null @@ -1,159 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = '7xbid'; -const BIDDER_ALIAS = '7xb'; -const ENDPOINT_BANNER = '//bidder.7xbid.com/api/v1/prebid/banner'; -const ENDPOINT_NATIVE = '//bidder.7xbid.com/api/v1/prebid/native'; -const COOKIE_SYNC_URL = '//bidder.7xbid.com/api/v1/cookie/gen'; -const SUPPORTED_MEDIA_TYPES = ['banner', 'native']; -const SUPPORTED_CURRENCIES = ['USD', 'JPY']; -const DEFAULT_CURRENCY = 'JPY'; -const NET_REVENUE = true; - -/** - * updated to support prebid 3.0 - remove utils.getTopWindowUrl() - */ - -const _encodeURIComponent = function(a) { - let b = window.encodeURIComponent(a); - b = b.replace(/'/g, '%27'); - return b; -} - -export const _getUrlVars = function(url) { - var hash; - var myJson = {}; - var hashes = url.slice(url.indexOf('?') + 1).split('&'); - for (var i = 0; i < hashes.length; i++) { - hash = hashes[i].split('='); - myJson[hash[0]] = hash[1]; - } - return myJson; -} - -export const spec = { - code: BIDDER_CODE, - aliases: [BIDDER_ALIAS], // short code - supportedMediaTypes: SUPPORTED_MEDIA_TYPES, - isBidRequestValid: function(bid) { - if (!(bid.params.placementId)) { - return false; - } - - if (bid.params.hasOwnProperty('currency') && - SUPPORTED_CURRENCIES.indexOf(bid.params.currency) === -1) { - utils.logInfo('Invalid currency type, we support only JPY and USD!') - return false; - } - - return true; - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests, bidderRequest) { - let serverRequests = []; - var refererInfo; - if (bidderRequest && bidderRequest.refererInfo) { - refererInfo = bidderRequest.refererInfo; - } - validBidRequests.forEach((bid, i) => { - let endpoint = ENDPOINT_BANNER - let data = { - 'placementid': bid.params.placementId, - 'cur': bid.params.hasOwnProperty('currency') ? bid.params.currency : DEFAULT_CURRENCY, - 'ua': navigator.userAgent, - 'loc': utils.deepAccess(bidderRequest, 'refererInfo.referer'), - 'topframe': (window.parent === window.self) ? 1 : 0, - 'sw': screen && screen.width, - 'sh': screen && screen.height, - 'cb': Math.floor(Math.random() * 99999999999), - 'tpaf': 1, - 'cks': 1, - 'requestid': bid.bidId - }; - - if (bid.hasOwnProperty('nativeParams')) { - endpoint = ENDPOINT_NATIVE - data.tkf = 1 // return url tracker - data.ad_track = '1' - data.apiv = '1.1.0' - } - - if (refererInfo && refererInfo.referer) { - data.referer = refererInfo.referer; - } else { - data.referer = ''; - } - - serverRequests.push({ - method: 'GET', - url: endpoint, - data: utils.parseQueryStringParameters(data) - }) - }) - - return serverRequests; - }, - interpretResponse: function(serverResponse, request) { - const data = _getUrlVars(request.data) - const successBid = serverResponse.body || {}; - let bidResponses = []; - if (successBid.hasOwnProperty(data.placementid)) { - let bid = successBid[data.placementid] - let bidResponse = { - requestId: bid.requestid, - cpm: bid.price, - creativeId: bid.creativeId, - currency: bid.cur, - netRevenue: NET_REVENUE, - ttl: 700 - }; - - if (bid.hasOwnProperty('title')) { // it is native ad response - bidResponse.mediaType = 'native' - bidResponse.native = { - title: bid.title, - body: bid.description, - cta: bid.cta, - sponsoredBy: bid.advertiser, - clickUrl: _encodeURIComponent(bid.landingURL), - impressionTrackers: bid.trackings, - } - if (bid.screenshots) { - bidResponse.native.image = { - url: bid.screenshots.url, - height: bid.screenshots.height, - width: bid.screenshots.width, - } - } - if (bid.icon) { - bidResponse.native.icon = { - url: bid.icon.url, - height: bid.icon.height, - width: bid.icon.width, - } - } - } else { - bidResponse.ad = bid.adm - bidResponse.width = bid.width - bidResponse.height = bid.height - } - - bidResponses.push(bidResponse); - } - - return bidResponses; - }, - getUserSyncs: function(syncOptions, serverResponses) { - return [{ - type: 'image', - url: COOKIE_SYNC_URL - }]; - } -} -registerBidder(spec); diff --git a/modules/7xbidBidAdapter.md b/modules/7xbidBidAdapter.md deleted file mode 100644 index 692428332f0..00000000000 --- a/modules/7xbidBidAdapter.md +++ /dev/null @@ -1,59 +0,0 @@ -# Overview - -Module Name: 7xbid Bid Adapter - -Maintainer: 7xbid.com@gmail.com - -# Description - -Module that connects to 7xbid's demand sources - -# Test Parameters -```javascript - var adUnits = [ - { - code: 'test', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]], - } - }, - bids: [ - { - bidder: '7xbid', - params: { - placementId: 1425292, - currency: 'USD' - } - } - ] - }, - { - code: 'test', - mediaTypes: { - native: { - title: { - required: true, - len: 80 - }, - image: { - required: true, - sizes: [150, 50] - }, - sponsoredBy: { - required: true - } - } - }, - bids: [ - { - bidder: '7xbid', - params: { - placementId: 1429695, - currency: 'USD' - } - }, - ], - } - ]; -``` \ No newline at end of file diff --git a/modules/a4gBidAdapter.js b/modules/a4gBidAdapter.js deleted file mode 100644 index 1961dba1f10..00000000000 --- a/modules/a4gBidAdapter.js +++ /dev/null @@ -1,89 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import * as utils from '../src/utils.js'; - -const A4G_BIDDER_CODE = 'a4g'; -const A4G_CURRENCY = 'USD'; -const A4G_DEFAULT_BID_URL = 'https://ads.ad4game.com/v1/bid'; -const A4G_TTL = 120; - -const LOCATION_PARAM_NAME = 'siteurl'; -const ID_PARAM_NAME = 'id'; -const IFRAME_PARAM_NAME = 'if'; -const ZONE_ID_PARAM_NAME = 'zoneId'; -const SIZE_PARAM_NAME = 'size'; - -const ARRAY_PARAM_SEPARATOR = ';'; -const ARRAY_SIZE_SEPARATOR = ','; -const SIZE_SEPARATOR = 'x'; - -export const spec = { - code: A4G_BIDDER_CODE, - isBidRequestValid: function(bid) { - return bid.params && !!bid.params.zoneId; - }, - - buildRequests: function(validBidRequests, bidderRequest) { - let deliveryUrl = ''; - const idParams = []; - const sizeParams = []; - const zoneIds = []; - - utils._each(validBidRequests, function(bid) { - if (!deliveryUrl && typeof bid.params.deliveryUrl === 'string') { - deliveryUrl = bid.params.deliveryUrl; - } - idParams.push(bid.bidId); - let bidSizes = (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) || bid.sizes; - sizeParams.push(bidSizes.map(size => size.join(SIZE_SEPARATOR)).join(ARRAY_SIZE_SEPARATOR)); - zoneIds.push(bid.params.zoneId); - }); - - if (!deliveryUrl) { - deliveryUrl = A4G_DEFAULT_BID_URL; - } - - let data = { - [IFRAME_PARAM_NAME]: 0, - [LOCATION_PARAM_NAME]: (bidderRequest.refererInfo && bidderRequest.refererInfo.referer) ? bidderRequest.refererInfo.referer : window.location.href, - [SIZE_PARAM_NAME]: sizeParams.join(ARRAY_PARAM_SEPARATOR), - [ID_PARAM_NAME]: idParams.join(ARRAY_PARAM_SEPARATOR), - [ZONE_ID_PARAM_NAME]: zoneIds.join(ARRAY_PARAM_SEPARATOR) - }; - - if (bidderRequest && bidderRequest.gdprConsent) { - data.gdpr = { - applies: bidderRequest.gdprConsent.gdprApplies, - consent: bidderRequest.gdprConsent.consentString - }; - } - - return { - method: 'GET', - url: deliveryUrl, - data: data - }; - }, - - interpretResponse: function(serverResponses, request) { - const bidResponses = []; - utils._each(serverResponses.body, function(response) { - if (response.cpm > 0) { - const bidResponse = { - requestId: response.id, - creativeId: response.crid || response.id, - cpm: response.cpm, - width: response.width, - height: response.height, - currency: A4G_CURRENCY, - netRevenue: true, - ttl: A4G_TTL, - ad: response.ad - }; - bidResponses.push(bidResponse); - } - }); - return bidResponses; - } -}; - -registerBidder(spec); diff --git a/modules/a4gBidAdapter.md b/modules/a4gBidAdapter.md deleted file mode 100644 index 70f110724b0..00000000000 --- a/modules/a4gBidAdapter.md +++ /dev/null @@ -1,48 +0,0 @@ -# Overview - -Module Name: Ad4Game Bidder Adapter -Module Type: Bidder Adapter -Maintainer: devops@ad4game.com - -# Description - -Ad4Game Bidder Adapter for Prebid.js. It should be tested on real domain. `localhost` should be rewritten (ex. example.com). - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 250]], // a display size - } - }, - bids: [ - { - bidder: 'a4g', - params: { - zoneId: 59304, - deliveryUrl: 'https://dev01.ad4game.com/v1/bid' - } - } - ] - },{ - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 50]], // a mobile size - } - }, - bids: [ - { - bidder: 'a4g', - params: { - zoneId: 59354, - deliveryUrl: 'https://dev01.ad4game.com/v1/bid' - } - } - ] - } - ]; -``` diff --git a/modules/aardvarkBidAdapter.js b/modules/aardvarkBidAdapter.js deleted file mode 100644 index 0b864286868..00000000000 --- a/modules/aardvarkBidAdapter.js +++ /dev/null @@ -1,262 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'aardvark'; -const DEFAULT_ENDPOINT = 'bidder.rtk.io'; -const SYNC_ENDPOINT = 'sync.rtk.io'; -const AARDVARK_TTL = 300; -const AARDVARK_CURRENCY = 'USD'; - -let hasSynced = false; - -export function resetUserSync() { - hasSynced = false; -} - -export const spec = { - code: BIDDER_CODE, - gvlid: 52, - aliases: ['adsparc', 'safereach'], - - isBidRequestValid: function(bid) { - return ((typeof bid.params.ai === 'string') && !!bid.params.ai.length && - (typeof bid.params.sc === 'string') && !!bid.params.sc.length); - }, - - buildRequests: function(validBidRequests, bidderRequest) { - var auctionCodes = []; - var requests = []; - var requestsMap = {}; - var referer = bidderRequest.refererInfo.referer; - var pageCategories = []; - var tdId = ''; - var width = window.innerWidth; - var height = window.innerHeight; - var schain = ''; - - // This reference to window.top can cause issues when loaded in an iframe if not protected with a try/catch. - try { - var topWin = utils.getWindowTop(); - if (topWin.rtkcategories && Array.isArray(topWin.rtkcategories)) { - pageCategories = topWin.rtkcategories; - } - width = topWin.innerWidth; - height = topWin.innerHeight; - } catch (e) {} - - if (utils.isStr(utils.deepAccess(validBidRequests, '0.userId.tdid'))) { - tdId = validBidRequests[0].userId.tdid; - } - - schain = spec.serializeSupplyChain(utils.deepAccess(validBidRequests, '0.schain')); - - utils._each(validBidRequests, function(b) { - var rMap = requestsMap[b.params.ai]; - if (!rMap) { - rMap = { - shortCodes: [], - payload: { - version: 1, - jsonp: false, - rtkreferer: referer, - w: width, - h: height - }, - endpoint: DEFAULT_ENDPOINT - }; - - if (tdId) { - rMap.payload.tdid = tdId; - } - if (schain) { - rMap.payload.schain = schain; - } - - if (pageCategories && pageCategories.length) { - rMap.payload.categories = pageCategories.slice(0); - } - - if (b.params.categories && b.params.categories.length) { - rMap.payload.categories = rMap.payload.categories || [] - utils._each(b.params.categories, function(cat) { - rMap.payload.categories.push(cat); - }); - } - - if (bidderRequest.gdprConsent) { - rMap.payload.gdpr = false; - if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') { - rMap.payload.gdpr = bidderRequest.gdprConsent.gdprApplies; - } - if (rMap.payload.gdpr) { - rMap.payload.consent = bidderRequest.gdprConsent.consentString; - } - } - - requestsMap[b.params.ai] = rMap; - auctionCodes.push(b.params.ai); - } - - if (bidderRequest.uspConsent) { - rMap.payload.us_privacy = bidderRequest.uspConsent - } - - rMap.shortCodes.push(b.params.sc); - rMap.payload[b.params.sc] = b.bidId; - - if ((typeof b.params.host === 'string') && b.params.host.length && - (b.params.host !== rMap.endpoint)) { - rMap.endpoint = b.params.host; - } - }); - - utils._each(auctionCodes, function(auctionId) { - var req = requestsMap[auctionId]; - requests.push({ - method: 'GET', - url: `https://${req.endpoint}/${auctionId}/${req.shortCodes.join('_')}/aardvark`, - data: req.payload, - bidderRequest - }); - }); - - return requests; - }, - - interpretResponse: function(serverResponse, bidRequest) { - var bidResponses = []; - - if (!Array.isArray(serverResponse.body)) { - serverResponse.body = [serverResponse.body]; - } - - utils._each(serverResponse.body, function(rawBid) { - var cpm = +(rawBid.cpm || 0); - - if (!cpm) { - return; - } - - var bidResponse = { - requestId: rawBid.cid, - cpm: cpm, - width: rawBid.width || 0, - height: rawBid.height || 0, - currency: rawBid.currency ? rawBid.currency : AARDVARK_CURRENCY, - netRevenue: rawBid.netRevenue ? rawBid.netRevenue : true, - ttl: rawBid.ttl ? rawBid.ttl : AARDVARK_TTL, - creativeId: rawBid.creativeId || 0 - }; - - if (rawBid.hasOwnProperty('dealId')) { - bidResponse.dealId = rawBid.dealId - } - - if (rawBid.hasOwnProperty('ex')) { - bidResponse.ex = rawBid.ex; - } - - switch (rawBid.media) { - case 'banner': - bidResponse.ad = rawBid.adm + utils.createTrackPixelHtml(decodeURIComponent(rawBid.nurl)); - break; - - default: - return utils.logError('bad Aardvark response (media)', rawBid); - } - - bidResponses.push(bidResponse); - }); - - return bidResponses; - }, - - getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) { - const syncs = []; - const params = []; - var gdprApplies = false; - if (gdprConsent && (typeof gdprConsent.gdprApplies === 'boolean')) { - gdprApplies = gdprConsent.gdprApplies; - } - - if (!syncOptions.iframeEnabled) { - utils.logWarn('Aardvark: Please enable iframe based user sync.'); - return syncs; - } - - if (hasSynced) { - return syncs; - } - - hasSynced = true; - if (gdprApplies) { - params.push(['g', '1']); - params.push(['c', gdprConsent.consentString]); - } - - if (uspConsent) { - params.push(['us_privacy', uspConsent]); - } - - var queryStr = ''; - if (params.length) { - queryStr = '?' + params.map(p => p[0] + '=' + encodeURIComponent(p[1])).join('&') - } - - syncs.push({ - type: 'iframe', - url: `https://${SYNC_ENDPOINT}/cs${queryStr}` - }); - return syncs; - }, - - /** - * Serializes schain params according to OpenRTB requirements - * @param {Object} supplyChain - * @returns {String} - */ - serializeSupplyChain: function (supplyChain) { - if (!hasValidSupplyChainParams(supplyChain)) { - return ''; - } - - return `${supplyChain.ver},${supplyChain.complete}!${spec.serializeSupplyChainNodes(supplyChain.nodes)}`; - }, - - /** - * Properly sorts schain object params - * @param {Array} nodes - * @returns {String} - */ - serializeSupplyChainNodes: function (nodes) { - const nodePropOrder = ['asi', 'sid', 'hp', 'rid', 'name', 'domain']; - return nodes.map(node => { - return nodePropOrder.map(prop => encodeURIComponent(node[prop] || '')).join(','); - }).join('!'); - }, -}; - -/** - * Make sure the required params are present - * @param {Object} schain - * @param {Bool} - */ -export function hasValidSupplyChainParams(schain) { - if (!schain || !schain.nodes) { - return false; - } - const requiredFields = ['asi', 'sid', 'hp']; - - let isValid = schain.nodes.reduce((status, node) => { - if (!status) { - return status; - } - return requiredFields.every(field => node[field]); - }, true); - if (!isValid) { - utils.logError('Aardvark: required schain params missing'); - } - return isValid; -} - -registerBidder(spec); diff --git a/modules/aardvarkBidAdapter.md b/modules/aardvarkBidAdapter.md deleted file mode 100644 index 9f7a128b6f3..00000000000 --- a/modules/aardvarkBidAdapter.md +++ /dev/null @@ -1,30 +0,0 @@ -# Overview - -**Module Name**: Aardvark Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: chris@rtk.io - -# Description - -Module that connects to a RTK.io Ad Units to fetch bids. - -# Test Parameters -``` - var adUnits = [{ - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - code: 'div-gpt-ad-1460505748561-0', - - bids: [{ - bidder: 'aardvark', - params: { - ai: '0000', - sc: '1234' - } - }] - - }]; -``` diff --git a/modules/ablidaBidAdapter.js b/modules/ablidaBidAdapter.js deleted file mode 100644 index 2400952367f..00000000000 --- a/modules/ablidaBidAdapter.js +++ /dev/null @@ -1,105 +0,0 @@ -import * as utils 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'; - -const BIDDER_CODE = 'ablida'; -const ENDPOINT_URL = 'https://bidder.ablida.net/prebid'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, NATIVE, VIDEO], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return !!(bid.params.placementId); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @return Array Info describing the request to the server. - * @param validBidRequests - * @param bidderRequest - */ - buildRequests: function (validBidRequests, bidderRequest) { - if (validBidRequests.length === 0) { - return []; - } - return validBidRequests.map(bidRequest => { - let sizes = [] - if (bidRequest.mediaTypes && bidRequest.mediaTypes[BANNER] && bidRequest.mediaTypes[BANNER].sizes) { - sizes = bidRequest.mediaTypes[BANNER].sizes; - } else if (bidRequest.mediaTypes[VIDEO] && bidRequest.mediaTypes[VIDEO].playerSize) { - sizes = bidRequest.mediaTypes[VIDEO].playerSize - } - const jaySupported = 'atob' in window && 'currentScript' in document; - const device = getDevice(); - const payload = { - placementId: bidRequest.params.placementId, - sizes: sizes, - bidId: bidRequest.bidId, - categories: bidRequest.params.categories, - referer: bidderRequest.refererInfo.referer, - jaySupported: jaySupported, - device: device, - adapterVersion: 5, - mediaTypes: bidRequest.mediaTypes, - gdprConsent: bidderRequest.gdprConsent - }; - return { - method: 'POST', - url: ENDPOINT_URL, - data: payload - }; - }); - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {ServerResponse} serverResponse A successful response from the server. - * @param bidRequest - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function (serverResponse, bidRequest) { - const bidResponses = []; - const response = serverResponse.body; - - response.forEach(function(bid) { - bid.ttl = config.getConfig('_bidderTimeout'); - bidResponses.push(bid); - }); - return bidResponses; - }, - onBidWon: function (bid) { - if (!bid['nurl']) { return; } - utils.triggerPixel(bid['nurl']); - } -}; - -function getDevice() { - const ua = navigator.userAgent; - const topWindow = window.top; - if ((/(ipad|xoom|sch-i800|playbook|silk|tablet|kindle)|(android(?!.*mobi))/i).test(ua)) { - return 'tablet'; - } - if ((/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(ua)) { - return 'connectedtv'; - } - if ((/Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Windows\sCE|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/i).test(ua)) { - return 'smartphone'; - } - const width = topWindow.innerWidth || topWindow.document.documentElement.clientWidth || topWindow.document.body.clientWidth; - if (width > 320) { - return 'desktop'; - } - return 'other'; -} - -registerBidder(spec); diff --git a/modules/ablidaBidAdapter.md b/modules/ablidaBidAdapter.md deleted file mode 100644 index e0a9f3f9405..00000000000 --- a/modules/ablidaBidAdapter.md +++ /dev/null @@ -1,72 +0,0 @@ -# Overview - -**Module Name**: Ablida Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: d.kuster@ablida.de - -# Description - -Module that connects to Ablida's bidder for bids. - -# Test Parameters -``` - var adUnits = [ - { - code: 'ad-div', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [ - { - bidder: 'ablida', - params: { - placementId: 'mediumrectangle-demo', - categories: ['automotive', 'news-and-politics'] // optional: categories of page - } - } - ] - }, { - code: 'native-ad-div', - mediaTypes: { - native: { - image: { - sendId: true, - required: true - }, - title: { - required: true - }, - body: { - required: true - } - } - }, - bids: [ - { - bidder: 'ablida', - params: { - placementId: 'native-demo' - } - } - ] - }, { - code: 'video-ad', - mediaTypes: { - video: { - playerSize: [[640, 360]], - context: 'instream' - } - }, - bids: [ - { - bidder: 'ablida', - params: { - placementId: 'instream-demo' - } - } - ] - } - ]; -``` diff --git a/modules/adWMGAnalyticsAdapter.js b/modules/adWMGAnalyticsAdapter.js deleted file mode 100644 index 8183187eb73..00000000000 --- a/modules/adWMGAnalyticsAdapter.js +++ /dev/null @@ -1,441 +0,0 @@ -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -import CONSTANTS from '../src/constants.json'; -import { ajax } from '../src/ajax.js'; -const analyticsType = 'endpoint'; -const url = 'https://analytics.wmgroup.us/analytic/collection'; -const { - EVENTS: { - AUCTION_INIT, - AUCTION_END, - BID_REQUESTED, - BID_WON, - BID_TIMEOUT, - NO_BID, - BID_RESPONSE - } -} = CONSTANTS; - -let timestampInit = null; - -let noBidArray = []; -let noBidObject = {}; - -let isBidArray = []; -let isBidObject = {}; - -let bidTimeOutArray = []; -let bidTimeOutObject = {}; - -let bidWonArray = []; -let bidWonObject = {}; - -let initOptions = {}; - -function postAjax(url, data) { - ajax(url, function () {}, data, {contentType: 'application/json', method: 'POST'}); -} - -function handleInitSizes(adUnits) { - return adUnits.map(function (adUnit) { - return adUnit.sizes.toString() || '' - }); -} - -function handleInitTypes(adUnits) { - return adUnits.map(function (adUnit) { - return Object.keys(adUnit.mediaTypes).toString(); - }); -} - -function detectDevice() { - if ( - /ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i.test( - navigator.userAgent.toLowerCase() - ) - ) { - return 'tablet'; - } - if ( - /iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i.test( - navigator.userAgent.toLowerCase() - ) - ) { - return 'mobile'; - } - return 'desktop'; -} - -function detectOsAndBrowser() { - var module = { - options: [], - header: [navigator.platform, navigator.userAgent, navigator.appVersion, navigator.vendor, window.opera], - dataos: [ - { - name: 'Windows Phone', - value: 'Windows Phone', - version: 'OS' - }, - { - name: 'Windows', - value: 'Win', - version: 'NT' - }, - { - name: 'iOS', - value: 'iPhone', - version: 'OS' - }, - { - name: 'iOS', - value: 'iPad', - version: 'OS' - }, - { - name: 'Kindle', - value: 'Silk', - version: 'Silk' - }, - { - name: 'Android', - value: 'Android', - version: 'Android' - }, - { - name: 'PlayBook', - value: 'PlayBook', - version: 'OS' - }, - { - name: 'BlackBerry', - value: 'BlackBerry', - version: '/' - }, - { - name: 'Macintosh', - value: 'Mac', - version: 'OS X' - }, - { - name: 'Linux', - value: 'Linux', - version: 'rv' - }, - { - name: 'Palm', - value: 'Palm', - version: 'PalmOS' - } - ], - databrowser: [ - { - name: 'Yandex Browser', - value: 'YaBrowser', - version: 'YaBrowser' - }, - { - name: 'Opera Mini', - value: 'Opera Mini', - version: 'Opera Mini' - }, - { - name: 'Amigo', - value: 'Amigo', - version: 'Amigo' - }, - { - name: 'Atom', - value: 'Atom', - version: 'Atom' - }, - { - name: 'Opera', - value: 'OPR', - version: 'OPR' - }, - { - name: 'Edge', - value: 'Edge', - version: 'Edge' - }, - { - name: 'Internet Explorer', - value: 'Trident', - version: 'rv' - }, - { - name: 'Chrome', - value: 'Chrome', - version: 'Chrome' - }, - { - name: 'Firefox', - value: 'Firefox', - version: 'Firefox' - }, - { - name: 'Safari', - value: 'Safari', - version: 'Version' - }, - { - name: 'Internet Explorer', - value: 'MSIE', - version: 'MSIE' - }, - { - name: 'Opera', - value: 'Opera', - version: 'Opera' - }, - { - name: 'BlackBerry', - value: 'CLDC', - version: 'CLDC' - }, - { - name: 'Mozilla', - value: 'Mozilla', - version: 'Mozilla' - } - ], - init: function () { - var agent = this.header.join(' '); - var os = this.matchItem(agent, this.dataos); - var browser = this.matchItem(agent, this.databrowser); - - return { - os: os, - browser: browser - }; - }, - - getVersion: function (name, version) { - if (name === 'Windows') { - switch (parseFloat(version).toFixed(1)) { - case '5.0': - return '2000'; - case '5.1': - return 'XP'; - case '5.2': - return 'Server 2003'; - case '6.0': - return 'Vista'; - case '6.1': - return '7'; - case '6.2': - return '8'; - case '6.3': - return '8.1'; - default: - return parseInt(version) || 'other'; - } - } else return parseInt(version) || 'other'; - }, - - matchItem: function (string, data) { - var i = 0; - var j = 0; - var regex, regexv, match, matches, version; - - for (i = 0; i < data.length; i += 1) { - regex = new RegExp(data[i].value, 'i'); - match = regex.test(string); - if (match) { - regexv = new RegExp(data[i].version + '[- /:;]([\\d._]+)', 'i'); - matches = string.match(regexv); - version = ''; - if (matches) { - if (matches[1]) { - matches = matches[1]; - } - } - if (matches) { - matches = matches.split(/[._]+/); - for (j = 0; j < matches.length; j += 1) { - if (j === 0) { - version += matches[j] + '.'; - } else { - version += matches[j]; - } - } - } else { - version = 'other'; - } - return { - name: data[i].name, - version: this.getVersion(data[i].name, version) - }; - } - } - return { - name: 'unknown', - version: 'other' - }; - } - }; - - var e = module.init(); - - var result = {}; - result.os = e.os.name + ' ' + e.os.version; - result.browser = e.browser.name + ' ' + e.browser.version; - return result; -} - -function handleAuctionInit(eventType, args) { - initOptions.c_timeout = args.timeout; - initOptions.ad_unit_size = handleInitSizes(args.adUnits); - initOptions.ad_unit_type = handleInitTypes(args.adUnits); - initOptions.device = detectDevice(); - initOptions.os = detectOsAndBrowser().os; - initOptions.browser = detectOsAndBrowser().browser; - timestampInit = args.timestamp; -} - -function parseBidType(mediaTypes, mediaType) { - if (!mediaTypes) { - return [mediaType]; - } else { - return Object.keys(mediaTypes) || ['']; - } -} - -function parseSizes(sizes, width, height) { - if (sizes !== undefined) { - return sizes.map(s => { - return s.toString(); - }); - } else { - return [`${width},${height}`]; - } -} - -function mapObject({ - bidder, - adUnitCode, - auctionId, - transactionId, - sizes, - size, - mediaTypes, - mediaType, - cpm, - currency, - originalCpm, - originalCurrency, - height, - width -}) { - return { - bidder: bidder, - auction_id: auctionId, - ad_unit_code: adUnitCode, - transaction_id: transactionId || '', - bid_size: size || sizes || (width && height !== undefined) ? parseSizes(sizes, width, height) : [''], - bid_type: mediaType || mediaTypes ? parseBidType(mediaTypes, mediaType) : [''], - time_ms: Date.now() - timestampInit, - cur: originalCurrency !== undefined ? originalCurrency : (currency || ''), - price: cpm !== undefined ? cpm.toString().substring(0, 4) : '', - cur_native: originalCurrency || '', - price_native: originalCpm !== undefined ? originalCpm.toString().substring(0, 4) : '' - }; -} - -function mapUpLevelObject(object, eventType, array) { - Object.assign(object, { - status: eventType || '', - bids: array || [] - }); -} - -function handleEvent(array, object, eventType, args) { - array.push(mapObject(args)); - mapUpLevelObject(object, eventType, array); -} - -function handleNoBid(eventType, args) { - handleEvent(noBidArray, noBidObject, eventType, args); -} - -function handleBidResponse(eventType, args) { - handleEvent(isBidArray, isBidObject, eventType, args); -} - -function handleBidTimeout(eventType, args) { - args.forEach(bid => { - bidTimeOutArray.push(mapObject(bid)); - }); - mapUpLevelObject(bidTimeOutObject, eventType, bidTimeOutArray); -} - -function handleBidWon(eventType, args) { - handleEvent(bidWonArray, bidWonObject, eventType, args); - sendRequest(bidWonObject); -} - -function handleBidRequested(args) {} - -function sendRequest(...objects) { - let obj = { - publisher_id: initOptions.publisher_id.toString() || '', - site: initOptions.site || '', - ad_unit_size: initOptions.ad_unit_size || [''], - ad_unit_type: initOptions.ad_unit_type || [''], - device: initOptions.device || '', - os: initOptions.os || '', - browser: initOptions.browser || '', - c_timeout: initOptions.c_timeout || 0, - events: Object.keys(objects).length ? objects : [] - }; - postAjax(url, JSON.stringify(obj)); -} - -function handleAuctionEnd() { - sendRequest(noBidObject, isBidObject, bidTimeOutObject); -} - -let adWMGAnalyticsAdapter = Object.assign(adapter({ - url, - analyticsType -}), { - track({ - eventType, - args - }) { - switch (eventType) { - case AUCTION_INIT: - handleAuctionInit(eventType, args); - break; - case BID_REQUESTED: - handleBidRequested(args); - break; - case BID_RESPONSE: - handleBidResponse(eventType, args); - break; - case NO_BID: - handleNoBid(eventType, args); - break; - case BID_TIMEOUT: - handleBidTimeout(eventType, args); - break; - case BID_WON: - handleBidWon(eventType, args); - break; - case AUCTION_END: - handleAuctionEnd(); - } - } -}); - -adWMGAnalyticsAdapter.originEnableAnalytics = adWMGAnalyticsAdapter.enableAnalytics; - -adWMGAnalyticsAdapter.enableAnalytics = function (config) { - initOptions = config.options; - adWMGAnalyticsAdapter.originEnableAnalytics(config); -}; -adapterManager.registerAnalyticsAdapter({ - adapter: adWMGAnalyticsAdapter, - code: 'adWMG' -}); -export default adWMGAnalyticsAdapter; diff --git a/modules/adWMGAnalyticsAdapter.md b/modules/adWMGAnalyticsAdapter.md deleted file mode 100644 index 42a1543cf08..00000000000 --- a/modules/adWMGAnalyticsAdapter.md +++ /dev/null @@ -1,23 +0,0 @@ -# Overview -Module Name: adWMG Analytics Adapter - -Module Type: Analytics Adapter - -Maintainer: wbid@adwmg.com - -# Description - -Analytics adapter for adWMG. - -# Test Parameters - -``` -{ - provider: 'adWMG', - options : { - site: 'test.com', - publisher_id: '5abd0543ba45723db49d97ea' - } -} - -``` diff --git a/modules/adWMGBidAdapter.js b/modules/adWMGBidAdapter.js deleted file mode 100644 index 689e7d02124..00000000000 --- a/modules/adWMGBidAdapter.js +++ /dev/null @@ -1,315 +0,0 @@ -'use strict'; - -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { config } from '../src/config.js'; -import { BANNER } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'adWMG'; -const ENDPOINT = 'https://hb.adwmg.com/hb'; -let SYNC_ENDPOINT = 'https://hb.adwmg.com/cphb.html?'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['wmg'], - supportedMediaTypes: [BANNER], - isBidRequestValid: (bid) => { - if (bid.bidder !== BIDDER_CODE) { - return false; - } - - if (!(bid.params.publisherId)) { - return false; - } - - return true; - }, - buildRequests: (validBidRequests, bidderRequest) => { - const timeout = bidderRequest.timeout || 0; - const debug = config.getConfig('debug') || false; - const referrer = bidderRequest.refererInfo.referer; - const locale = window.navigator.language && window.navigator.language.length > 0 ? window.navigator.language.substr(0, 2) : ''; - const domain = config.getConfig('publisherDomain') || (window.location && window.location.host ? window.location.host : ''); - const ua = window.navigator.userAgent.toLowerCase(); - const additional = spec.parseUserAgent(ua); - - return validBidRequests.map(bidRequest => { - const checkFloorValue = (value) => { - if (isNaN(parseFloat(value))) { - return 0; - } else return parseFloat(value); - } - - const adUnit = { - code: bidRequest.adUnitCode, - bids: { - bidder: bidRequest.bidder, - params: { - publisherId: bidRequest.params.publisherId, - IABCategories: bidRequest.params.IABCategories || [], - floorCPM: bidRequest.params.floorCPM ? checkFloorValue(bidRequest.params.floorCPM) : 0 - } - }, - mediaTypes: bidRequest.mediaTypes - }; - - if (bidRequest.hasOwnProperty('sizes') && bidRequest.sizes.length > 0) { - adUnit.sizes = bidRequest.sizes; - } - - const request = { - auctionId: bidRequest.auctionId, - requestId: bidRequest.bidId, - bidRequestsCount: bidRequest.bidRequestsCount, - bidderRequestId: bidRequest.bidderRequestId, - transactionId: bidRequest.transactionId, - referrer: referrer, - timeout: timeout, - adUnit: adUnit, - locale: locale, - domain: domain, - os: additional.os, - osv: additional.osv, - devicetype: additional.devicetype - }; - - if (bidderRequest.gdprConsent) { - request.gdpr = { - applies: bidderRequest.gdprConsent.gdprApplies, - consentString: bidderRequest.gdprConsent.consentString - }; - } - - /* if (bidderRequest.uspConsent) { - request.uspConsent = bidderRequest.uspConsent; - } - */ - if (bidRequest.userId && bidRequest.userId.pubcid) { - request.userId = { - pubcid: bidRequest.userId.pubcid - }; - } - - if (debug) { - request.debug = debug; - } - - return { - method: 'POST', - url: ENDPOINT, - data: JSON.stringify(request) - } - }); - }, - interpretResponse: (serverResponse) => { - const bidResponses = []; - - if (serverResponse.body) { - const response = serverResponse.body; - const bidResponse = { - requestId: response.requestId, - cpm: response.cpm, - width: response.width, - height: response.height, - creativeId: response.creativeId, - currency: response.currency, - netRevenue: response.netRevenue, - ttl: response.ttl, - ad: response.ad, - }; - bidResponses.push(bidResponse); - } - - return bidResponses; - }, - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - if (gdprConsent && SYNC_ENDPOINT.indexOf('gdpr') === -1) { - SYNC_ENDPOINT = utils.tryAppendQueryString(SYNC_ENDPOINT, 'gdpr', (gdprConsent.gdprApplies ? 1 : 0)); - } - - if (gdprConsent && typeof gdprConsent.consentString === 'string' && SYNC_ENDPOINT.indexOf('gdpr_consent') === -1) { - SYNC_ENDPOINT = utils.tryAppendQueryString(SYNC_ENDPOINT, 'gdpr_consent', gdprConsent.consentString); - } - - if (SYNC_ENDPOINT.slice(-1) === '&') { - SYNC_ENDPOINT = SYNC_ENDPOINT.slice(0, -1); - } - - /* if (uspConsent) { - SYNC_ENDPOINT = utils.tryAppendQueryString(SYNC_ENDPOINT, 'us_privacy', uspConsent); - } */ - let syncs = []; - if (syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: SYNC_ENDPOINT - }); - } - return syncs; - }, - parseUserAgent: (ua) => { - function detectDevice() { - if (/ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i - .test(ua.toLowerCase())) { - return 5; - } - if (/iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i - .test(ua.toLowerCase())) { - return 4; - } - if (/smart[-_\s]?tv|hbbtv|appletv|googletv|hdmi|netcast|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b/i - .test(ua.toLowerCase())) { - return 3; - } - return 2; - } - - function detectOs() { - const module = { - options: [], - header: [navigator.platform, ua, navigator.appVersion, navigator.vendor, window.opera], - dataos: [{ - name: 'Windows Phone', - value: 'Windows Phone', - version: 'OS' - }, - { - name: 'Windows', - value: 'Win', - version: 'NT' - }, - { - name: 'iOS', - value: 'iPhone', - version: 'OS' - }, - { - name: 'iOS', - value: 'iPad', - version: 'OS' - }, - { - name: 'Kindle', - value: 'Silk', - version: 'Silk' - }, - { - name: 'Android', - value: 'Android', - version: 'Android' - }, - { - name: 'PlayBook', - value: 'PlayBook', - version: 'OS' - }, - { - name: 'BlackBerry', - value: 'BlackBerry', - version: '/' - }, - { - name: 'Macintosh', - value: 'Mac', - version: 'OS X' - }, - { - name: 'Linux', - value: 'Linux', - version: 'rv' - }, - { - name: 'Palm', - value: 'Palm', - version: 'PalmOS' - } - ], - init: function () { - var agent = this.header.join(' '); - var os = this.matchItem(agent, this.dataos); - return { - os - }; - }, - - getVersion: function (name, version) { - if (name === 'Windows') { - switch (parseFloat(version).toFixed(1)) { - case '5.0': - return '2000'; - case '5.1': - return 'XP'; - case '5.2': - return 'Server 2003'; - case '6.0': - return 'Vista'; - case '6.1': - return '7'; - case '6.2': - return '8'; - case '6.3': - return '8.1'; - default: - return version || 'other'; - } - } else return version || 'other'; - }, - - matchItem: function (string, data) { - var i = 0; - var j = 0; - var regex, regexv, match, matches, version; - - for (i = 0; i < data.length; i += 1) { - regex = new RegExp(data[i].value, 'i'); - match = regex.test(string); - if (match) { - regexv = new RegExp(data[i].version + '[- /:;]([\\d._]+)', 'i'); - matches = string.match(regexv); - version = ''; - if (matches) { - if (matches[1]) { - matches = matches[1]; - } - } - if (matches) { - matches = matches.split(/[._]+/); - for (j = 0; j < matches.length; j += 1) { - if (j === 0) { - version += matches[j] + '.'; - } else { - version += matches[j]; - } - } - } else { - version = 'other'; - } - return { - name: data[i].name, - version: this.getVersion(data[i].name, version) - }; - } - } - return { - name: 'unknown', - version: 'other' - }; - } - }; - - var e = module.init(); - - return { - os: e.os.name || '', - osv: e.os.version || '' - } - } - - return { - devicetype: detectDevice(), - os: detectOs().os, - osv: detectOs().osv - } - } -}; -registerBidder(spec); diff --git a/modules/adWMGBidAdapter.md b/modules/adWMGBidAdapter.md deleted file mode 100644 index ec5541e6168..00000000000 --- a/modules/adWMGBidAdapter.md +++ /dev/null @@ -1,35 +0,0 @@ -# Overview - -``` -Module Name: adWMG Adapter -Module Type: Bidder Adapter -Maintainer: wbid@adwmg.com -``` - -# Description - -Module that connects to adWMG demand sources to fetch bids. Supports 'banner' ad format. - -# Bid Parameters - -| Key | Required | Example | Description | -| --------------- | -------- | -----------------------------| ------------------------------- | -| `publisherId` | yes | `'5cebea3c9eea646c7b623d5e'` | publisher ID from WMG Dashboard | -| `IABCategories` | no | `['IAB1', 'IAB5']` | IAB ad categories for adUnit | -| `floorCPM` | no | `0.5` | Floor price for adUnit | - - -# Test Parameters - -```javascript -var adUnits = [{ - code: 'wmg-test-div', - sizes: [[300, 250]], - bids: [{ - bidder: 'adWMG', - params: { - publisherId: '5cebea3c9eea646c7b623d5e', - IABCategories: ['IAB1', 'IAB5'] - }, - }] -}] \ No newline at end of file diff --git a/modules/adagioAnalyticsAdapter.js b/modules/adagioAnalyticsAdapter.js deleted file mode 100644 index fd7a742d9e7..00000000000 --- a/modules/adagioAnalyticsAdapter.js +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Analytics Adapter for Adagio - */ - -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -import CONSTANTS from '../src/constants.json'; -import * as utils from '../src/utils.js'; - -const emptyUrl = ''; -const analyticsType = 'endpoint'; -const events = Object.keys(CONSTANTS.EVENTS).map(key => CONSTANTS.EVENTS[key]); -const VERSION = '2.0.0'; - -const adagioEnqueue = function adagioEnqueue(action, data) { - utils.getWindowTop().ADAGIO.queue.push({ action, data, ts: Date.now() }); -} - -function canAccessTopWindow() { - try { - if (utils.getWindowTop().location.href) { - return true; - } - } catch (error) { - return false; - } -} - -let adagioAdapter = Object.assign(adapter({ emptyUrl, analyticsType }), { - track: function({ eventType, args }) { - if (typeof args !== 'undefined' && events.indexOf(eventType) !== -1) { - adagioEnqueue('pb-analytics-event', { eventName: eventType, args }); - } - } -}); - -adagioAdapter.originEnableAnalytics = adagioAdapter.enableAnalytics; - -adagioAdapter.enableAnalytics = config => { - if (!canAccessTopWindow()) { - return; - } - - const w = utils.getWindowTop(); - - w.ADAGIO = w.ADAGIO || {}; - w.ADAGIO.queue = w.ADAGIO.queue || []; - w.ADAGIO.versions = w.ADAGIO.versions || {}; - w.ADAGIO.versions.adagioAnalyticsAdapter = VERSION; - - adagioAdapter.originEnableAnalytics(config); -} - -adapterManager.registerAnalyticsAdapter({ - adapter: adagioAdapter, - code: 'adagio' -}); - -export default adagioAdapter; diff --git a/modules/adagioAnalyticsAdapter.md b/modules/adagioAnalyticsAdapter.md deleted file mode 100644 index 312a26ea8da..00000000000 --- a/modules/adagioAnalyticsAdapter.md +++ /dev/null @@ -1,17 +0,0 @@ -# Overview - -Module Name: Adagio Analytics Adapter -Module Type: Analytics Adapter -Maintainer: dev@adagio.io - -# Description - -Analytics adapter for Adagio - -# Test Parameters - -``` -{ - provider: 'adagio' -} -``` diff --git a/modules/adagioBidAdapter.js b/modules/adagioBidAdapter.js deleted file mode 100644 index 66653567dab..00000000000 --- a/modules/adagioBidAdapter.js +++ /dev/null @@ -1,1085 +0,0 @@ -import find from 'core-js-pure/features/array/find.js'; -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { loadExternalScript } from '../src/adloader.js'; -import JSEncrypt from 'jsencrypt/bin/jsencrypt.js'; -import sha256 from 'crypto-js/sha256.js'; -import { getStorageManager } from '../src/storageManager.js'; -import { getRefererInfo } from '../src/refererDetection.js'; -import { createEidsArray } from './userId/eids.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { Renderer } from '../src/Renderer.js'; -import { OUTSTREAM } from '../src/video.js'; - -export const BIDDER_CODE = 'adagio'; -export const LOG_PREFIX = 'Adagio:'; -export const VERSION = '2.10.0'; -export const FEATURES_VERSION = '1'; -export const ENDPOINT = 'https://mp.4dex.io/prebid'; -export const SUPPORTED_MEDIA_TYPES = [BANNER, NATIVE, VIDEO]; -export const ADAGIO_TAG_URL = 'https://script.4dex.io/localstore.js'; -export const ADAGIO_LOCALSTORAGE_KEY = 'adagioScript'; -export const GVLID = 617; -export const storage = getStorageManager(GVLID, 'adagio'); -export const RENDERER_URL = 'https://script.4dex.io/outstream-player.js'; -export const MAX_SESS_DURATION = 30 * 60 * 1000; -export const ADAGIO_PUBKEY = `-----BEGIN PUBLIC KEY----- -MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9el0+OEn6fvEh1RdVHQu4cnT0 -jFSzIbGJJyg3cKqvtE6A0iaz9PkIdJIvSSSNrmJv+lRGKPEyRA/VnzJIieL39Ngl -t0b0lsHN+W4n9kitS/DZ/xnxWK/9vxhv0ZtL1LL/rwR5Mup7rmJbNtDoNBw4TIGj -pV6EP3MTLosuUEpLaQIDAQAB ------END PUBLIC KEY-----`; - -// This provide a whitelist and a basic validation -// of OpenRTB 2.5 options used by the Adagio SSP. -// https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf -export const ORTB_VIDEO_PARAMS = { - 'mimes': (value) => Array.isArray(value) && value.length > 0 && value.every(v => typeof v === 'string'), - 'minduration': (value) => utils.isInteger(value), - 'maxduration': (value) => utils.isInteger(value), - 'protocols': (value) => Array.isArray(value) && value.every(v => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].indexOf(v) !== -1), - 'w': (value) => utils.isInteger(value), - 'h': (value) => utils.isInteger(value), - 'startdelay': (value) => utils.isInteger(value), - 'placement': (value) => Array.isArray(value) && value.every(v => [1, 2, 3, 4, 5].indexOf(v) !== -1), - 'linearity': (value) => [1, 2].indexOf(value) !== -1, - 'skip': (value) => [0, 1].indexOf(value) !== -1, - 'skipmin': (value) => utils.isInteger(value), - 'skipafter': (value) => utils.isInteger(value), - 'sequence': (value) => utils.isInteger(value), - 'battr': (value) => Array.isArray(value) && value.every(v => Array.from({length: 17}, (_, i) => i + 1).indexOf(v) !== -1), - 'maxextended': (value) => utils.isInteger(value), - 'minbitrate': (value) => utils.isInteger(value), - 'maxbitrate': (value) => utils.isInteger(value), - 'boxingallowed': (value) => [0, 1].indexOf(value) !== -1, - 'playbackmethod': (value) => Array.isArray(value) && value.every(v => [1, 2, 3, 4, 5, 6].indexOf(v) !== -1), - '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) -}; - -let currentWindow; - -const EXT_DATA = {} - -export function adagioScriptFromLocalStorageCb(ls) { - try { - if (!ls) { - utils.logWarn(`${LOG_PREFIX} script not found.`); - return; - } - - const hashRgx = /^(\/\/ hash: (.+)\n)(.+\n)$/; - - if (!hashRgx.test(ls)) { - utils.logWarn(`${LOG_PREFIX} no hash found.`); - storage.removeDataFromLocalStorage(ADAGIO_LOCALSTORAGE_KEY); - } else { - const r = ls.match(hashRgx); - const hash = r[2]; - const content = r[3]; - - var jsEncrypt = new JSEncrypt(); - jsEncrypt.setPublicKey(ADAGIO_PUBKEY); - - if (jsEncrypt.verify(content, hash, sha256)) { - utils.logInfo(`${LOG_PREFIX} start script.`); - Function(ls)(); // eslint-disable-line no-new-func - } else { - utils.logWarn(`${LOG_PREFIX} invalid script found.`); - storage.removeDataFromLocalStorage(ADAGIO_LOCALSTORAGE_KEY); - } - } - } catch (err) { - utils.logError(LOG_PREFIX, err); - } -} - -export function getAdagioScript() { - storage.getDataFromLocalStorage(ADAGIO_LOCALSTORAGE_KEY, (ls) => { - internal.adagioScriptFromLocalStorageCb(ls); - }); - - storage.localStorageIsEnabled(isValid => { - if (isValid) { - loadExternalScript(ADAGIO_TAG_URL, BIDDER_CODE); - } else { - // ensure adagio removing for next time. - // It's an antipattern regarding the TCF2 enforcement logic - // but it's the only way to respect the user choice update. - window.localStorage.removeItem(ADAGIO_LOCALSTORAGE_KEY); - // Extra data from external script. - // This key is removed only if localStorage is not accessible. - window.localStorage.removeItem('adagio'); - } - }); -} - -function canAccessTopWindow() { - try { - if (utils.getWindowTop().location.href) { - return true; - } - } catch (error) { - return false; - } -} - -function getCurrentWindow() { - return currentWindow || utils.getWindowSelf(); -} - -function isSafeFrameWindow() { - const ws = utils.getWindowSelf(); - return !!(ws.$sf && ws.$sf.ext); -} - -// Get localStorage "adagio" data to be passed to the request -export function prepareExchange(storageValue) { - const adagioStorage = JSON.parse(storageValue, function(name, value) { - if (!name.startsWith('_') || name === '') { - return value; - } - }); - let random = utils.deepAccess(adagioStorage, 'session.rnd'); - let newSession = false; - - if (internal.isNewSession(adagioStorage)) { - newSession = true; - random = Math.random(); - } - - const data = { - session: { - new: newSession, - rnd: random - } - } - - utils.mergeDeep(EXT_DATA, adagioStorage, data); - - internal.enqueue({ - action: 'session', - ts: Date.now(), - data: EXT_DATA - }); -} - -function initAdagio() { - if (canAccessTopWindow()) { - currentWindow = (canAccessTopWindow()) ? utils.getWindowTop() : utils.getWindowSelf(); - } - - const w = internal.getCurrentWindow(); - - w.ADAGIO = w.ADAGIO || {}; - w.ADAGIO.adUnits = w.ADAGIO.adUnits || {}; - w.ADAGIO.pbjsAdUnits = w.ADAGIO.pbjsAdUnits || []; - w.ADAGIO.queue = w.ADAGIO.queue || []; - w.ADAGIO.versions = w.ADAGIO.versions || {}; - w.ADAGIO.versions.adagioBidderAdapter = VERSION; - w.ADAGIO.isSafeFrameWindow = isSafeFrameWindow(); - - storage.getDataFromLocalStorage('adagio', (storageData) => { - try { - internal.prepareExchange(storageData); - } catch (e) { - utils.logError(LOG_PREFIX, e); - } - }); - - getAdagioScript(); -} - -export const _features = { - getPrintNumber(adUnitCode) { - const adagioAdUnit = internal.getOrAddAdagioAdUnit(adUnitCode); - return adagioAdUnit.printNumber || 1; - }, - - getPageDimensions() { - if (isSafeFrameWindow() || !canAccessTopWindow()) { - return ''; - } - - // the page dimension can be computed on window.top only. - const wt = utils.getWindowTop(); - const body = wt.document.querySelector('body'); - - if (!body) { - return ''; - } - const html = wt.document.documentElement; - const pageWidth = Math.max(body.scrollWidth, body.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth); - const pageHeight = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight); - - return `${pageWidth}x${pageHeight}`; - }, - - getViewPortDimensions() { - if (!isSafeFrameWindow() && !canAccessTopWindow()) { - return ''; - } - - const viewportDims = { w: 0, h: 0 }; - - if (isSafeFrameWindow()) { - const ws = utils.getWindowSelf(); - - if (typeof ws.$sf.ext.geom !== 'function') { - utils.logWarn(`${LOG_PREFIX} cannot use the $sf.ext.geom() safeFrame API method`); - return ''; - } - - const sfGeom = ws.$sf.ext.geom().win; - viewportDims.w = Math.round(sfGeom.w); - viewportDims.h = Math.round(sfGeom.h); - } else { - // window.top based computing - const wt = utils.getWindowTop(); - - if (wt.innerWidth) { - viewportDims.w = wt.innerWidth; - viewportDims.h = wt.innerHeight; - } else { - const d = wt.document; - const body = d.querySelector('body'); - - if (!body) { - return ''; - } - - viewportDims.w = d.querySelector('body').clientWidth; - viewportDims.h = d.querySelector('body').clientHeight; - } - } - - return `${viewportDims.w}x${viewportDims.h}`; - }, - - /** - * domLoading feature is computed on window.top if reachable. - */ - getDomLoadingDuration() { - let domLoadingDuration = -1; - let performance; - - performance = (canAccessTopWindow()) ? utils.getWindowTop().performance : utils.getWindowSelf().performance; - - if (performance && performance.timing && performance.timing.navigationStart > 0) { - const val = performance.timing.domLoading - performance.timing.navigationStart; - if (val > 0) { - domLoadingDuration = val; - } - } - - return domLoadingDuration; - }, - - getSlotPosition(params) { - const { adUnitElementId, postBid } = params; - - if (!adUnitElementId) { - return ''; - } - - if (!isSafeFrameWindow() && !canAccessTopWindow()) { - return ''; - } - - const position = { x: 0, y: 0 }; - - if (isSafeFrameWindow()) { - const ws = utils.getWindowSelf(); - - if (typeof ws.$sf.ext.geom !== 'function') { - utils.logWarn(`${LOG_PREFIX} cannot use the $sf.ext.geom() safeFrame API method`); - return ''; - } - - const sfGeom = ws.$sf.ext.geom().self; - position.x = Math.round(sfGeom.t); - position.y = Math.round(sfGeom.l); - } else if (canAccessTopWindow()) { - // window.top based computing - const wt = utils.getWindowTop(); - const d = wt.document; - - let domElement; - - if (postBid === true) { - const ws = utils.getWindowSelf(); - const currentElement = ws.document.getElementById(adUnitElementId); - domElement = internal.getElementFromTopWindow(currentElement, ws); - } else { - domElement = wt.document.getElementById(adUnitElementId); - } - - if (!domElement) { - return ''; - } - - let box = domElement.getBoundingClientRect(); - - const docEl = d.documentElement; - const body = d.body; - const clientTop = d.clientTop || body.clientTop || 0; - const clientLeft = d.clientLeft || body.clientLeft || 0; - const scrollTop = wt.pageYOffset || docEl.scrollTop || body.scrollTop; - const scrollLeft = wt.pageXOffset || docEl.scrollLeft || body.scrollLeft; - - const elComputedStyle = wt.getComputedStyle(domElement, null); - const elComputedDisplay = elComputedStyle.display || 'block'; - const mustDisplayElement = elComputedDisplay === 'none'; - - if (mustDisplayElement) { - domElement.style = domElement.style || {}; - domElement.style.display = 'block'; - box = domElement.getBoundingClientRect(); - domElement.style.display = elComputedDisplay; - } - position.x = Math.round(box.left + scrollLeft - clientLeft); - position.y = Math.round(box.top + scrollTop - clientTop); - } else { - return ''; - } - - return `${position.x}x${position.y}`; - }, - - getTimestampUTC() { - // timestamp returned in seconds - return Math.floor(new Date().getTime() / 1000) - new Date().getTimezoneOffset() * 60; - }, - - getDevice() { - const ws = utils.getWindowSelf(); - const ua = ws.navigator.userAgent; - - if ((/(tablet|ipad|playbook|silk)|(android(?!.*mobi))/i).test(ua)) { - return 5; // "tablet" - } - if ((/Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/).test(ua)) { - return 4; // "phone" - } - return 2; // personal computers - }, - - getBrowser() { - const ws = utils.getWindowSelf(); - const ua = ws.navigator.userAgent; - const uaLowerCase = ua.toLowerCase(); - return /Edge\/\d./i.test(ua) ? 'edge' : uaLowerCase.indexOf('chrome') > 0 ? 'chrome' : uaLowerCase.indexOf('firefox') > 0 ? 'firefox' : uaLowerCase.indexOf('safari') > 0 ? 'safari' : uaLowerCase.indexOf('opera') > 0 ? 'opera' : uaLowerCase.indexOf('msie') > 0 || ws.MSStream ? 'ie' : 'unknow'; - }, - - getOS() { - const ws = utils.getWindowSelf(); - const ua = ws.navigator.userAgent; - const uaLowerCase = ua.toLowerCase(); - return uaLowerCase.indexOf('linux') > 0 ? 'linux' : uaLowerCase.indexOf('mac') > 0 ? 'mac' : uaLowerCase.indexOf('win') > 0 ? 'windows' : ''; - }, - - getUrl(refererInfo) { - // top has not been reached, it means we are not sure - // to get the proper page url. - if (!refererInfo.reachedTop) { - return; - } - return refererInfo.referer; - }, - - getUrlFromParams(params) { - const { postBidOptions } = params; - if (postBidOptions && postBidOptions.url) { - return postBidOptions.url; - } - } -}; - -function enqueue(ob) { - const w = internal.getCurrentWindow(); - - w.ADAGIO = w.ADAGIO || {}; - w.ADAGIO.queue = w.ADAGIO.queue || []; - w.ADAGIO.queue.push(ob); -}; - -function getOrAddAdagioAdUnit(adUnitCode) { - const w = internal.getCurrentWindow(); - - w.ADAGIO = w.ADAGIO || {}; - - if (w.ADAGIO.adUnits[adUnitCode]) { - return w.ADAGIO.adUnits[adUnitCode]; - } - - return w.ADAGIO.adUnits[adUnitCode] = {}; -}; - -function getPageviewId() { - const w = internal.getCurrentWindow(); - - w.ADAGIO = w.ADAGIO || {}; - w.ADAGIO.pageviewId = w.ADAGIO.pageviewId || utils.generateUUID(); - - return w.ADAGIO.pageviewId; -}; - -function computePrintNumber(adUnitCode) { - let printNumber = 1; - const w = internal.getCurrentWindow(); - - if ( - w.ADAGIO && - w.ADAGIO.adUnits && w.ADAGIO.adUnits[adUnitCode] && - w.ADAGIO.adUnits[adUnitCode].pageviewId === internal.getPageviewId() && - w.ADAGIO.adUnits[adUnitCode].printNumber - ) { - printNumber = parseInt(w.ADAGIO.adUnits[adUnitCode].printNumber, 10) + 1; - } - - return printNumber; -}; - -function getDevice() { - const language = navigator.language ? 'language' : 'userLanguage'; - return { - userAgent: navigator.userAgent, - language: navigator[language], - deviceType: _features.getDevice(), - dnt: utils.getDNT() ? 1 : 0, - geo: {}, - js: 1 - }; -}; - -function getSite(bidderRequest) { - let domain = ''; - let page = ''; - let referrer = ''; - - const { refererInfo } = bidderRequest; - - if (canAccessTopWindow()) { - const wt = utils.getWindowTop(); - domain = wt.location.hostname; - page = wt.location.href; - referrer = wt.document.referrer || ''; - } else if (refererInfo.reachedTop) { - const url = utils.parseUrl(refererInfo.referer); - domain = url.hostname; - page = refererInfo.referer; - } else if (refererInfo.stack && refererInfo.stack.length && refererInfo.stack[0]) { - // important note check if refererInfo.stack[0] is 'thruly' because a `null` value - // will be considered as "localhost" by the parseUrl function. - // As the isBidRequestValid returns false when it does not reach the referer - // this should never called. - const url = utils.parseUrl(refererInfo.stack[0]); - domain = url.hostname; - } - - return { - domain, - page, - referrer - }; -}; - -function getElementFromTopWindow(element, currentWindow) { - try { - if (utils.getWindowTop() === currentWindow) { - if (!element.getAttribute('id')) { - element.setAttribute('id', `adg-${utils.getUniqueIdentifierStr()}`); - } - return element; - } else { - const frame = currentWindow.frameElement; - const frameClientRect = frame.getBoundingClientRect(); - const elementClientRect = element.getBoundingClientRect(); - - if (frameClientRect.width !== elementClientRect.width || frameClientRect.height !== elementClientRect.height) { - return false; - } - - return getElementFromTopWindow(frame, currentWindow.parent); - } - } catch (err) { - utils.logWarn(`${LOG_PREFIX}`, err); - return false; - } -}; - -function autoDetectAdUnitElementId(adUnitCode) { - const autoDetectedAdUnit = utils.getGptSlotInfoForAdUnitCode(adUnitCode); - let adUnitElementId = null; - - if (autoDetectedAdUnit && autoDetectedAdUnit.divId) { - adUnitElementId = autoDetectedAdUnit.divId; - } - - return adUnitElementId; -}; - -function autoDetectEnvironment() { - const device = _features.getDevice(); - let environment; - switch (device) { - case 2: - environment = 'desktop'; - break; - case 4: - environment = 'mobile'; - break; - case 5: - environment = 'tablet'; - break; - }; - return environment; -}; - -function supportIObs() { - const currentWindow = internal.getCurrentWindow(); - return !!(currentWindow && currentWindow.IntersectionObserver && currentWindow.IntersectionObserverEntry && - currentWindow.IntersectionObserverEntry.prototype && 'intersectionRatio' in currentWindow.IntersectionObserverEntry.prototype); -} - -function getFeatures(bidRequest, bidderRequest) { - const { adUnitCode, params } = bidRequest; - const { adUnitElementId } = params; - const { refererInfo } = bidderRequest; - - if (!adUnitElementId) { - utils.logWarn(`${LOG_PREFIX} unable to get params.adUnitElementId. Continue without tiv.`); - } - - const features = { - print_number: _features.getPrintNumber(adUnitCode).toString(), - page_dimensions: _features.getPageDimensions().toString(), - viewport_dimensions: _features.getViewPortDimensions().toString(), - dom_loading: _features.getDomLoadingDuration().toString(), - // layout: features.getLayout().toString(), - adunit_position: _features.getSlotPosition(params).toString(), - user_timestamp: _features.getTimestampUTC().toString(), - device: _features.getDevice().toString(), - url: _features.getUrl(refererInfo) || _features.getUrlFromParams(params) || '', - browser: _features.getBrowser(), - os: _features.getOS() - }; - - Object.keys(features).forEach((prop) => { - if (features[prop] === '') { - delete features[prop]; - } - }); - - const adUnitFeature = {}; - - adUnitFeature[adUnitElementId] = { - features: features, - version: FEATURES_VERSION - }; - - internal.enqueue({ - action: 'features', - ts: Date.now(), - data: adUnitFeature - }); - - return features; -}; - -function isRendererPreferredFromPublisher(bidRequest) { - // renderer defined at adUnit level - const adUnitRenderer = utils.deepAccess(bidRequest, 'renderer'); - const hasValidAdUnitRenderer = !!(adUnitRenderer && adUnitRenderer.url && adUnitRenderer.render); - - // renderer defined at adUnit.mediaTypes level - const mediaTypeRenderer = utils.deepAccess(bidRequest, 'mediaTypes.video.renderer'); - const hasValidMediaTypeRenderer = !!(mediaTypeRenderer && mediaTypeRenderer.url && mediaTypeRenderer.render); - - return !!( - (hasValidAdUnitRenderer && !(adUnitRenderer.backupOnly === true)) || - (hasValidMediaTypeRenderer && !(mediaTypeRenderer.backupOnly === true)) - ); -} - -/** - * - * @param {object} adagioStorage - * @returns {boolean} - */ -function isNewSession(adagioStorage) { - const now = Date.now(); - const { lastActivityTime, vwSmplg } = utils.deepAccess(adagioStorage, 'session', {}); - return ( - !utils.isNumber(lastActivityTime) || - !utils.isNumber(vwSmplg) || - (now - lastActivityTime) > MAX_SESS_DURATION - ) -} - -export const internal = { - enqueue, - getOrAddAdagioAdUnit, - getPageviewId, - computePrintNumber, - getDevice, - getSite, - getElementFromTopWindow, - autoDetectAdUnitElementId, - autoDetectEnvironment, - getFeatures, - getRefererInfo, - adagioScriptFromLocalStorageCb, - getCurrentWindow, - supportIObs, - canAccessTopWindow, - isRendererPreferredFromPublisher, - isNewSession, - prepareExchange -}; - -function _getGdprConsent(bidderRequest) { - if (!utils.deepAccess(bidderRequest, 'gdprConsent')) { - return false; - } - - const { - apiVersion, - gdprApplies, - consentString, - allowAuctionWithoutConsent - } = bidderRequest.gdprConsent; - - const consent = {}; - - if (apiVersion !== undefined) { - consent.apiVersion = apiVersion; - } - - if (consentString !== undefined) { - consent.consentString = consentString; - } - - if (gdprApplies !== undefined) { - consent.consentRequired = (gdprApplies) ? 1 : 0; - } - - if (allowAuctionWithoutConsent !== undefined) { - consent.allowAuctionWithoutConsent = allowAuctionWithoutConsent ? 1 : 0; - } - - return consent; -} - -function _getCoppa() { - return { - required: config.getConfig('coppa') === true ? 1 : 0 - }; -} - -function _getUspConsent(bidderRequest) { - return (utils.deepAccess(bidderRequest, 'uspConsent')) ? { uspConsent: bidderRequest.uspConsent } : false; -} - -function _getSchain(bidRequest) { - if (utils.deepAccess(bidRequest, 'schain')) { - return bidRequest.schain; - } -} - -function _getEids(bidRequest) { - if (utils.deepAccess(bidRequest, 'userId')) { - return createEidsArray(bidRequest.userId); - } -} - -function _buildVideoBidRequest(bidRequest) { - const videoAdUnitParams = utils.deepAccess(bidRequest, 'mediaTypes.video', {}); - const videoBidderParams = utils.deepAccess(bidRequest, 'params.video', {}); - const computedParams = {}; - - // Special case for playerSize. - // Eeach props will be overrided if they are defined in config. - if (Array.isArray(videoAdUnitParams.playerSize)) { - const tempSize = (Array.isArray(videoAdUnitParams.playerSize[0])) ? videoAdUnitParams.playerSize[0] : videoAdUnitParams.playerSize; - computedParams.w = tempSize[0]; - computedParams.h = tempSize[1]; - } - - const videoParams = { - ...computedParams, - ...videoAdUnitParams, - ...videoBidderParams - }; - - if (videoParams.context && videoParams.context === OUTSTREAM) { - bidRequest.mediaTypes.video.playerName = (internal.isRendererPreferredFromPublisher(bidRequest)) ? 'other' : 'adagio'; - - if (bidRequest.mediaTypes.video.playerName === 'other') { - utils.logWarn(`${LOG_PREFIX} renderer.backupOnly has not been set. Adagio recommends to use its own player to get expected behavior.`); - } - } - - // Only whitelisted OpenRTB options need to be validated. - // Other options will still remain in the `mediaTypes.video` object - // sent in the ad-request, but will be ignored by the SSP. - Object.keys(ORTB_VIDEO_PARAMS).forEach(paramName => { - if (videoParams.hasOwnProperty(paramName)) { - if (ORTB_VIDEO_PARAMS[paramName](videoParams[paramName])) { - bidRequest.mediaTypes.video[paramName] = videoParams[paramName]; - } else { - delete bidRequest.mediaTypes.video[paramName]; - utils.logWarn(`${LOG_PREFIX} The OpenRTB video param ${paramName} has been skipped due to misformating. Please refer to OpenRTB 2.5 spec.`); - } - } - }); -} - -function _renderer(bid) { - bid.renderer.push(() => { - if (typeof window.ADAGIO.outstreamPlayer === 'function') { - window.ADAGIO.outstreamPlayer(bid); - } else { - utils.logError(`${LOG_PREFIX} Adagio outstream player is not defined`); - } - }); -} - -function _parseNativeBidResponse(bid) { - if (!bid.admNative || !Array.isArray(bid.admNative.assets)) { - utils.logError(`${LOG_PREFIX} Invalid native response`); - return; - } - - const native = {} - - function addAssetDataValue(data) { - const map = { - 1: 'sponsoredBy', // sponsored - 2: 'body', // desc - 3: 'rating', - 4: 'likes', - 5: 'downloads', - 6: 'price', - 7: 'salePrice', - 8: 'phone', - 9: 'address', - 10: 'body2', // desc2 - 11: 'displayUrl', - 12: 'cta' - } - if (map.hasOwnProperty(data.type) && typeof data.value === 'string') { - native[map[data.type]] = data.value; - } - } - - // assets - bid.admNative.assets.forEach(asset => { - if (asset.title) { - native.title = asset.title.text - } else if (asset.data) { - addAssetDataValue(asset.data) - } else if (asset.img) { - switch (asset.img.type) { - case 1: - native.icon = { - url: asset.img.url, - width: asset.img.w, - height: asset.img.h - }; - break; - default: - native.image = { - url: asset.img.url, - width: asset.img.w, - height: asset.img.h - }; - break; - } - } - }); - - if (bid.admNative.link) { - if (bid.admNative.link.url) { - native.clickUrl = bid.admNative.link.url; - } - if (Array.isArray(bid.admNative.link.clickTrackers)) { - native.clickTrackers = bid.admNative.link.clickTrackers - } - } - - if (Array.isArray(bid.admNative.eventtrackers)) { - native.impressionTrackers = []; - bid.admNative.eventtrackers.forEach(tracker => { - // Only Impression events are supported. Prebid does not support Viewability events yet. - if (tracker.event !== 1) { - return; - } - - // methods: - // 1: image - // 2: js - // note: javascriptTrackers is a string. If there's more than one JS tracker in bid response, the last script will be used. - switch (tracker.method) { - case 1: - native.impressionTrackers.push(tracker.url); - break; - case 2: - native.javascriptTrackers = ``; - break; - } - }); - } else { - native.impressionTrackers = Array.isArray(bid.admNative.imptrackers) ? bid.admNative.imptrackers : []; - if (bid.admNative.jstracker) { - native.javascriptTrackers = bid.admNative.jstracker; - } - } - - if (bid.admNative.privacy) { - native.privacyLink = bid.admNative.privacy; - } - - if (bid.admNative.ext) { - native.ext = {} - - if (bid.admNative.ext.bvw) { - native.ext.adagio_bvw = bid.admNative.ext.bvw; - } - } - - bid.native = native -} - -export const spec = { - code: BIDDER_CODE, - gvlid: GVLID, - supportedMediaTypes: SUPPORTED_MEDIA_TYPES, - - isBidRequestValid(bid) { - const { adUnitCode, auctionId, sizes, bidder, params, mediaTypes } = bid; - if (!params) { - utils.logWarn(`${LOG_PREFIX} the "params" property is missing.`); - return false; - } - - const { organizationId, site } = params; - const adUnitElementId = (params.useAdUnitCodeAsAdUnitElementId === true) - ? adUnitCode - : params.adUnitElementId || internal.autoDetectAdUnitElementId(adUnitCode); - const placement = (params.useAdUnitCodeAsPlacement === true) ? adUnitCode : params.placement; - const environment = params.environment || internal.autoDetectEnvironment(); - const supportIObs = internal.supportIObs(); - - // insure auto-detected params are kept in `bid` object. - bid.params = { - ...params, - adUnitElementId, - environment, - placement, - supportIObs - }; - - const debugData = () => ({ - action: 'pb-dbg', - ts: Date.now(), - data: { - bid - } - }); - - const refererInfo = internal.getRefererInfo(); - - if (!refererInfo.reachedTop) { - utils.logWarn(`${LOG_PREFIX} the main page url is unreachabled.`); - internal.enqueue(debugData()); - - return false; - } else if (!(organizationId && site && placement)) { - utils.logWarn(`${LOG_PREFIX} at least one required param is missing.`); - internal.enqueue(debugData()); - - return false; - } - - const w = internal.getCurrentWindow(); - const pageviewId = internal.getPageviewId(); - const printNumber = internal.computePrintNumber(adUnitCode); - - // Store adUnits config. - // If an adUnitCode has already been stored, it will be replaced. - w.ADAGIO = w.ADAGIO || {}; - w.ADAGIO.pbjsAdUnits = w.ADAGIO.pbjsAdUnits.filter((adUnit) => adUnit.code !== adUnitCode); - w.ADAGIO.pbjsAdUnits.push({ - code: adUnitCode, - mediaTypes: mediaTypes || {}, - sizes: (mediaTypes && mediaTypes.banner && Array.isArray(mediaTypes.banner.sizes)) ? mediaTypes.banner.sizes : sizes, - bids: [{ - bidder, - params: bid.params // use the updated bid.params object with auto-detected params - }], - auctionId, - pageviewId, - printNumber - }); - - // (legacy) Store internal adUnit information - w.ADAGIO.adUnits[adUnitCode] = { - auctionId, - pageviewId, - printNumber, - }; - - return true; - }, - - buildRequests(validBidRequests, bidderRequest) { - const secure = (location.protocol === 'https:') ? 1 : 0; - const device = internal.getDevice(); - const site = internal.getSite(bidderRequest); - const pageviewId = internal.getPageviewId(); - const gdprConsent = _getGdprConsent(bidderRequest) || {}; - const uspConsent = _getUspConsent(bidderRequest) || {}; - const coppa = _getCoppa(); - const schain = _getSchain(validBidRequests[0]); - const eids = _getEids(validBidRequests[0]) || []; - const adUnits = utils._map(validBidRequests, (bidRequest) => { - bidRequest.features = internal.getFeatures(bidRequest, bidderRequest); - - if (utils.deepAccess(bidRequest, 'mediaTypes.video')) { - _buildVideoBidRequest(bidRequest); - } - - return bidRequest; - }); - - // Group ad units by organizationId - const groupedAdUnits = adUnits.reduce((groupedAdUnits, adUnit) => { - adUnit.params.organizationId = adUnit.params.organizationId.toString(); - - groupedAdUnits[adUnit.params.organizationId] = groupedAdUnits[adUnit.params.organizationId] || []; - groupedAdUnits[adUnit.params.organizationId].push(adUnit); - - return groupedAdUnits; - }, {}); - - // Build one request per organizationId - const requests = utils._map(Object.keys(groupedAdUnits), organizationId => { - return { - method: 'POST', - url: ENDPOINT, - data: { - id: utils.generateUUID(), - organizationId: organizationId, - secure: secure, - device: device, - site: site, - pageviewId: pageviewId, - adUnits: groupedAdUnits[organizationId], - data: EXT_DATA, - regs: { - gdpr: gdprConsent, - coppa: coppa, - ccpa: uspConsent - }, - schain: schain, - user: { - eids: eids - }, - prebidVersion: '$prebid.version$', - adapterVersion: VERSION, - featuresVersion: FEATURES_VERSION - }, - options: { - contentType: 'text/plain' - } - }; - }); - - return requests; - }, - - interpretResponse(serverResponse, bidRequest) { - let bidResponses = []; - try { - const response = serverResponse.body; - if (response) { - if (response.data) { - internal.enqueue({ - action: 'ssp-data', - ts: Date.now(), - data: response.data - }); - } - if (response.bids) { - response.bids.forEach(bidObj => { - const bidReq = (find(bidRequest.data.adUnits, bid => bid.bidId === bidObj.requestId)); - - if (bidReq) { - bidObj.meta = utils.deepAccess(bidObj, 'meta', {}); - bidObj.meta.mediaType = bidObj.mediaType; - bidObj.meta.advertiserDomains = (Array.isArray(bidObj.aDomain) && bidObj.aDomain.length) ? bidObj.aDomain : []; - - if (bidObj.mediaType === VIDEO) { - const mediaTypeContext = utils.deepAccess(bidReq, 'mediaTypes.video.context'); - // Adagio SSP returns a `vastXml` only. No `vastUrl` nor `videoCacheKey`. - if (!bidObj.vastUrl && bidObj.vastXml) { - bidObj.vastUrl = 'data:text/xml;charset=utf-8;base64,' + btoa(bidObj.vastXml.replace(/\\"/g, '"')); - } - - if (mediaTypeContext === OUTSTREAM) { - bidObj.renderer = Renderer.install({ - id: bidObj.requestId, - adUnitCode: bidObj.adUnitCode, - url: bidObj.urlRenderer || RENDERER_URL, - config: { - ...utils.deepAccess(bidReq, 'mediaTypes.video'), - ...utils.deepAccess(bidObj, 'outstream', {}) - } - }); - - bidObj.renderer.setRender(_renderer); - } - } - - if (bidObj.mediaType === NATIVE) { - _parseNativeBidResponse(bidObj); - } - - bidObj.site = bidReq.params.site; - bidObj.placement = bidReq.params.placement; - bidObj.pagetype = bidReq.params.pagetype; - bidObj.category = bidReq.params.category; - bidObj.subcategory = bidReq.params.subcategory; - bidObj.environment = bidReq.params.environment; - } - bidResponses.push(bidObj); - }); - } - } - } catch (err) { - utils.logError(err); - } - return bidResponses; - }, - - getUserSyncs(syncOptions, serverResponses) { - if (!serverResponses.length || serverResponses[0].body === '' || !serverResponses[0].body.userSyncs) { - return false; - } - - const syncs = serverResponses[0].body.userSyncs.map(sync => ({ - type: sync.t === 'p' ? 'image' : 'iframe', - url: sync.u - })); - - return syncs; - }, -}; - -initAdagio(); - -registerBidder(spec); diff --git a/modules/adagioBidAdapter.md b/modules/adagioBidAdapter.md deleted file mode 100644 index 46656d88d37..00000000000 --- a/modules/adagioBidAdapter.md +++ /dev/null @@ -1,194 +0,0 @@ -# Overview - -Module Name: Adagio Bid Adapter -Module Type: Adagio Adapter -Maintainer: dev@adagio.io - -## Description - -Connects to Adagio demand source to fetch bids. - -## Test Parameters - -```javascript - var adUnits = [ - { - code: 'dfp_banniere_atf', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - } - }, - bids: [{ - bidder: 'adagio', // Required - params: { - organizationId: '1002', // Required - Organization ID provided by Adagio. - site: 'adagio-io', // Required - Site Name provided by Adagio. - placement: 'in_article', // Required. Refers to the placement of an adunit in a page. Must not contain any information about the type of device. Other example: `mpu_btf'. - adUnitElementId: 'article_outstream', // Required - AdUnit element id. Refers to the adunit id in a page. Usually equals to the adunit code above. - - // The following params are limited to 30 characters, - // and can only contain the following characters: - // - alphanumeric (A-Z+a-z+0-9, case-insensitive) - // - dashes `-` - // - underscores `_` - // Also, each param can have at most 50 unique active values (case-insensitive). - pagetype: 'article', // Highly recommended. The pagetype describes what kind of content will be present in the page. - environment: 'mobile', // Recommended. Environment where the page is displayed. - category: 'sport', // Recommended. Category of the content displayed in the page. - subcategory: 'handball', // Optional. Subcategory of the content displayed in the page. - postBid: false, // Optional. Use it in case of Post-bid integration only. - useAdUnitCodeAsAdUnitElementId: false, // Optional. Use it by-pass adUnitElementId and use the adUnit code as value - useAdUnitCodeAsPlacement: false, // Optional. Use it to by-pass placement and use the adUnit code as value - // Optional debug mode, used to get a bid response with expected cpm. - debug: { - enabled: true, - cpm: 3.00 // default to 1.00 - } - } - }] - }, - { - code: 'article_outstream', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [640, 480], - mimes: ['video/mp4'], - skip: 1 - // Other OpenRTB 2.5 video options… - } - }, - bids: [{ - bidder: 'adagio', // Required - params: { - organizationId: '1002', // Required - Organization ID provided by Adagio. - site: 'adagio-io', // Required - Site Name provided by Adagio. - placement: 'in_article', // Required. Refers to the placement of an adunit in a page. Must not contain any information about the type of device. Other example: `mpu_btf'. - adUnitElementId: 'article_outstream', // Required - AdUnit element id. Refers to the adunit id in a page. Usually equals to the adunit code above. - - // The following params are limited to 30 characters, - // and can only contain the following characters: - // - alphanumeric (A-Z+a-z+0-9, case-insensitive) - // - dashes `-` - // - underscores `_` - // Also, each param can have at most 50 unique active values (case-insensitive). - pagetype: 'article', // Highly recommended. The pagetype describes what kind of content will be present in the page. - environment: 'mobile', // Recommended. Environment where the page is displayed. - category: 'sport', // Recommended. Category of the content displayed in the page. - subcategory: 'handball', // Optional. Subcategory of the content displayed in the page. - postBid: false, // Optional. Use it in case of Post-bid integration only. - useAdUnitCodeAsAdUnitElementId: false, // Optional. Use it by-pass adUnitElementId and use the adUnit code as value - useAdUnitCodeAsPlacement: false, // Optional. Use it to by-pass placement and use the adUnit code as value - video: { - skip: 0 - // OpenRTB 2.5 video options defined here override ones defined in mediaTypes. - }, - // Optional debug mode, used to get a bid response with expected cpm. - debug: { - enabled: true, - cpm: 3.00 // default to 1.00 - } - } - }] - }, - { - code: 'article_native', - mediaTypes: { - native: { - // generic Prebid options - title: { - required: true, - len: 80 - }, - // … - // Custom Adagio data assets - ext: { - adagio_bvw: { - required: false - } - } - } - }, - bids: [{ - bidder: 'adagio', // Required - params: { - organizationId: '1002', // Required - Organization ID provided by Adagio. - site: 'adagio-io', // Required - Site Name provided by Adagio. - placement: 'in_article', // Required. Refers to the placement of an adunit in a page. Must not contain any information about the type of device. Other example: `mpu_btf'. - adUnitElementId: 'article_native', // Required - AdUnit element id. Refers to the adunit id in a page. Usually equals to the adunit code above. - - // The following params are limited to 30 characters, - // and can only contain the following characters: - // - alphanumeric (A-Z+a-z+0-9, case-insensitive) - // - dashes `-` - // - underscores `_` - // Also, each param can have at most 50 unique active values (case-insensitive). - pagetype: 'article', // Highly recommended. The pagetype describes what kind of content will be present in the page. - environment: 'mobile', // Recommended. Environment where the page is displayed. - category: 'sport', // Recommended. Category of the content displayed in the page. - subcategory: 'handball', // Optional. Subcategory of the content displayed in the page. - postBid: false, // Optional. Use it in case of Post-bid integration only. - useAdUnitCodeAsAdUnitElementId: false, // Optional. Use it by-pass adUnitElementId and use the adUnit code as value - useAdUnitCodeAsPlacement: false, // Optional. Use it to by-pass placement and use the adUnit code as value - // Optional OpenRTB Native 1.2 request object. Only `context`, `plcmttype` fields are supported. - native: { - context: 1, - plcmttype: 2 - }, - // Optional debug mode, used to get a bid response with expected cpm. - debug: { - enabled: true, - cpm: 3.00 // default to 1.00 - } - } - }] - } - ]; - - pbjs.addAdUnits(adUnits); - - pbjs.bidderSettings = { - adagio: { - alwaysUseBid: true, - adserverTargeting: [ - { - key: "site", - val: function (bidResponse) { - return bidResponse.site; - } - }, - { - key: "environment", - val: function (bidResponse) { - return bidResponse.environment; - } - }, - { - key: "placement", - val: function (bidResponse) { - return bidResponse.placement; - } - }, - { - key: "pagetype", - val: function (bidResponse) { - return bidResponse.pagetype; - } - }, - { - key: "category", - val: function (bidResponse) { - return bidResponse.category; - } - }, - { - key: "subcategory", - val: function (bidResponse) { - return bidResponse.subcategory; - } - } - ] - } - } -``` diff --git a/modules/adblender.md b/modules/adblender.md deleted file mode 100644 index e70b2a4a8ed..00000000000 --- a/modules/adblender.md +++ /dev/null @@ -1,36 +0,0 @@ -# Overview - -Module Name: AdBlender Bidder Adapter -Module Type: Bidder Adapter -Maintainer: contact@ad-blender.com - -# Description - -Connects to AdBlender demand source to fetch bids. -Banner and Video formats are supported. -Please use ```adblender``` as the bidder code. -#Bidder Config -You can set an alternate endpoint url `pbjs.setBidderConfig` for the bidder `adblender` -``` -pbjs.setBidderConfig({ - bidders: ["adblender"], - config: {"adblender": { "endpoint_url": "https://inv-nets.admixer.net/adblender.1.1.aspx"}} - }) -``` -# Ad Unit Example -``` - var adUnits = [ - { - code: 'desktop-banner-ad-div', - sizes: [[300, 250]], // a display size - bids: [ - { - bidder: "adblender", - params: { - zone: 'fb3d34d0-7a88-4a4a-a5c9-8088cd7845f4' - } - } - ] - } - ]; -``` diff --git a/modules/adbutlerBidAdapter.js b/modules/adbutlerBidAdapter.js deleted file mode 100644 index 10edd8ae3e3..00000000000 --- a/modules/adbutlerBidAdapter.js +++ /dev/null @@ -1,140 +0,0 @@ -'use strict'; - -import * as utils from '../src/utils.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'adbutler'; - -export const spec = { - code: BIDDER_CODE, - pageID: Math.floor(Math.random() * 10e6), - aliases: ['divreach', 'doceree'], - - isBidRequestValid: function (bid) { - return !!(bid.params.accountID && bid.params.zoneID); - }, - - buildRequests: function (validBidRequests) { - let i; - let zoneID; - let bidRequest; - let accountID; - let keyword; - let domain; - let requestURI; - let serverRequests = []; - let zoneCounters = {}; - let extraParams = {}; - - for (i = 0; i < validBidRequests.length; i++) { - bidRequest = validBidRequests[i]; - zoneID = utils.getBidIdParameter('zoneID', bidRequest.params); - accountID = utils.getBidIdParameter('accountID', bidRequest.params); - keyword = utils.getBidIdParameter('keyword', bidRequest.params); - domain = utils.getBidIdParameter('domain', bidRequest.params); - extraParams = utils.getBidIdParameter('extra', bidRequest.params); - - if (!(zoneID in zoneCounters)) { - zoneCounters[zoneID] = 0; - } - - if (typeof domain === 'undefined' || domain.length === 0) { - domain = 'servedbyadbutler.com'; - } - - requestURI = 'https://' + domain + '/adserve/;type=hbr;'; - requestURI += 'ID=' + encodeURIComponent(accountID) + ';'; - requestURI += 'setID=' + encodeURIComponent(zoneID) + ';'; - requestURI += 'pid=' + encodeURIComponent(spec.pageID) + ';'; - requestURI += 'place=' + encodeURIComponent(zoneCounters[zoneID]) + ';'; - - // append the keyword for targeting if one was passed in - if (keyword !== '') { - requestURI += 'kw=' + encodeURIComponent(keyword) + ';'; - } - - for (let key in extraParams) { - if (extraParams.hasOwnProperty(key)) { - let val = encodeURIComponent(extraParams[key]); - requestURI += `${key}=${val};`; - } - } - - zoneCounters[zoneID]++; - serverRequests.push({ - method: 'GET', - url: requestURI, - data: {}, - bidRequest: bidRequest - }); - } - return serverRequests; - }, - - interpretResponse: function (serverResponse, bidRequest) { - const bidObj = bidRequest.bidRequest; - let bidResponses = []; - let bidResponse = {}; - let isCorrectSize = false; - let isCorrectCPM = true; - let CPM; - let minCPM; - let maxCPM; - let width; - let height; - - serverResponse = serverResponse.body; - if (serverResponse && serverResponse.status === 'SUCCESS' && bidObj) { - CPM = serverResponse.cpm; - minCPM = utils.getBidIdParameter('minCPM', bidObj.params); - maxCPM = utils.getBidIdParameter('maxCPM', bidObj.params); - width = parseInt(serverResponse.width); - height = parseInt(serverResponse.height); - - // Ensure response CPM is within the given bounds - if (minCPM !== '' && CPM < parseFloat(minCPM)) { - isCorrectCPM = false; - } - if (maxCPM !== '' && CPM > parseFloat(maxCPM)) { - isCorrectCPM = false; - } - - // Ensure that response ad matches one of the placement sizes. - utils._each(utils.deepAccess(bidObj, 'mediaTypes.banner.sizes', []), function (size) { - if (width === size[0] && height === size[1]) { - isCorrectSize = true; - } - }); - if (isCorrectCPM && isCorrectSize) { - bidResponse.requestId = bidObj.bidId; - bidResponse.bidderCode = bidObj.bidder; - bidResponse.creativeId = serverResponse.placement_id; - bidResponse.cpm = CPM; - bidResponse.width = width; - bidResponse.height = height; - bidResponse.ad = serverResponse.ad_code; - bidResponse.ad += spec.addTrackingPixels(serverResponse.tracking_pixels); - bidResponse.currency = 'USD'; - bidResponse.netRevenue = true; - bidResponse.ttl = config.getConfig('_bidderTimeout'); - bidResponse.referrer = utils.deepAccess(bidObj, 'refererInfo.referer'); - bidResponses.push(bidResponse); - } - } - return bidResponses; - }, - - addTrackingPixels: function (trackingPixels) { - let trackingPixelMarkup = ''; - utils._each(trackingPixels, function (pixelURL) { - let trackingPixel = ''; - - trackingPixelMarkup += trackingPixel; - }); - return trackingPixelMarkup; - } -}; -registerBidder(spec); diff --git a/modules/adbutlerBidAdapter.md b/modules/adbutlerBidAdapter.md deleted file mode 100644 index 1921cc4046e..00000000000 --- a/modules/adbutlerBidAdapter.md +++ /dev/null @@ -1,34 +0,0 @@ -# Overview - -**Module Name**: AdButler Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: dan@sparklit.com - -# Description - -Module that connects to an AdButler zone to fetch bids. - -# Test Parameters -``` - var adUnits = [ - { - code: 'display-div', - sizes: [[300, 250]], // a display size - bids: [ - { - bidder: "adbutler", - params: { - accountID: '167283', - zoneID: '210093', - keyword: 'red', //optional - minCPM: '1.00', //optional - maxCPM: '5.00' //optional - extra: { // optional - foo: "bar" - } - } - } - ] - } - ]; -``` diff --git a/modules/addefendBidAdapter.js b/modules/addefendBidAdapter.js deleted file mode 100644 index 18cafe829b5..00000000000 --- a/modules/addefendBidAdapter.js +++ /dev/null @@ -1,79 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'addefend'; - -export const spec = { - code: BIDDER_CODE, - hostname: 'https://addefend-platform.com', - - getHostname() { - return this.hostname; - }, - isBidRequestValid: function(bid) { - return (bid.sizes !== undefined && bid.bidId !== undefined && bid.params !== undefined && - (bid.params.pageId !== undefined && (typeof bid.params.pageId === 'string')) && - (bid.params.placementId !== undefined && (typeof bid.params.placementId === 'string'))); - }, - buildRequests: function(validBidRequests, bidderRequest) { - let bid = { - v: $$PREBID_GLOBAL$$.version, - auctionId: false, - pageId: false, - gdpr_consent: bidderRequest.gdprConsent && bidderRequest.gdprConsent.consentString ? bidderRequest.gdprConsent.consentString : '', - referer: bidderRequest.refererInfo.referer, - bids: [], - }; - - for (var i = 0; i < validBidRequests.length; i++) { - let vb = validBidRequests[i]; - let o = vb.params; - bid.auctionId = vb.auctionId; - o.bidId = vb.bidId; - o.transactionId = vb.transactionId; - o.sizes = []; - if (o.trafficTypes) { - bid.trafficTypes = o.trafficTypes; - } - delete o.trafficTypes; - - bid.pageId = o.pageId; - delete o.pageId; - - if (vb.sizes && Array.isArray(vb.sizes)) { - for (var j = 0; j < vb.sizes.length; j++) { - let s = vb.sizes[j]; - if (Array.isArray(s) && s.length == 2) { - o.sizes.push(s[0] + 'x' + s[1]); - } - } - } - bid.bids.push(o); - } - return [{ - method: 'POST', - url: this.getHostname() + '/bid', - options: { withCredentials: true }, - data: bid - }]; - }, - interpretResponse: function(serverResponse, request) { - const requiredKeys = ['requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', 'netRevenue', 'currency', 'advertiserDomains']; - const validBidResponses = []; - serverResponse = serverResponse.body; - if (serverResponse && (serverResponse.length > 0)) { - serverResponse.forEach((bid) => { - const bidResponse = {}; - for (const requiredKey of requiredKeys) { - if (!bid.hasOwnProperty(requiredKey)) { - return []; - } - bidResponse[requiredKey] = bid[requiredKey]; - } - validBidResponses.push(bidResponse); - }); - } - return validBidResponses; - } -} - -registerBidder(spec); diff --git a/modules/addefendBidAdapter.md b/modules/addefendBidAdapter.md deleted file mode 100644 index f1ac3ff2c46..00000000000 --- a/modules/addefendBidAdapter.md +++ /dev/null @@ -1,43 +0,0 @@ -# Overview - -``` -Module Name: AdDefend Bid Adapter -Module Type: Bidder Adapter -Maintainer: prebid@addefend.com -``` - -# Description - -Module that connects to AdDefend as a demand source. - -## Parameters -| Param | Description | Optional | Default | -| ------------- | ------------- | ----- | ----- | -| pageId | id assigned to the website in the AdDefend system. (ask AdDefend support) | no | - | -| placementId | id of the placement in the AdDefend system. (ask AdDefend support) | no | - | -| trafficTypes | comma seperated list of the following traffic types:
ADBLOCK - user has a activated adblocker
PM - user has firefox private mode activated
NC - user has not given consent
NONE - user traffic is none of the above, this usually means this is a "normal" user.
| yes | ADBLOCK | - - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[970, 250]], // a display size - } - }, - bids: [ - { - bidder: "addefend", - params: { - pageId: "887", - placementId: "9398", - trafficTypes: "ADBLOCK" - } - } - ] - } - ]; -``` diff --git a/modules/adfBidAdapter.js b/modules/adfBidAdapter.js deleted file mode 100644 index 8b3550e6108..00000000000 --- a/modules/adfBidAdapter.js +++ /dev/null @@ -1,214 +0,0 @@ -// jshint esversion: 6, es3: false, node: true -'use strict'; - -import { - registerBidder -} from '../src/adapters/bidderFactory.js'; -import { - NATIVE -} from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; - -const BIDDER_CODE = 'adf'; -const GVLID = 50; -const BIDDER_ALIAS = [ { code: 'adformOpenRTB', gvlid: GVLID } ]; -const NATIVE_ASSET_IDS = { 0: 'title', 2: 'icon', 3: 'image', 5: 'sponsoredBy', 4: 'body', 1: 'cta' }; -const NATIVE_PARAMS = { - title: { - id: 0, - name: 'title' - }, - icon: { - id: 2, - type: 1, - name: 'img' - }, - image: { - id: 3, - type: 3, - name: 'img' - }, - sponsoredBy: { - id: 5, - name: 'data', - type: 1 - }, - body: { - id: 4, - name: 'data', - type: 2 - }, - cta: { - id: 1, - type: 12, - name: 'data' - } -}; - -export const spec = { - code: BIDDER_CODE, - aliases: BIDDER_ALIAS, - gvlid: GVLID, - supportedMediaTypes: [ NATIVE ], - isBidRequestValid: bid => !!bid.params.mid, - buildRequests: (validBidRequests, bidderRequest) => { - const page = bidderRequest.refererInfo.referer; - const adxDomain = setOnAny(validBidRequests, 'params.adxDomain') || 'adx.adform.net'; - const ua = navigator.userAgent; - const pt = setOnAny(validBidRequests, 'params.pt') || setOnAny(validBidRequests, 'params.priceType') || 'net'; - const tid = validBidRequests[0].transactionId; // ??? check with ssp - const test = setOnAny(validBidRequests, 'params.test'); - const publisher = setOnAny(validBidRequests, 'params.publisher'); - const siteId = setOnAny(validBidRequests, 'params.siteId'); - const currency = config.getConfig('currency.adServerCurrency'); - const cur = currency && [ currency ]; - const eids = setOnAny(validBidRequests, 'userIdAsEids'); - - const imp = validBidRequests.map((bid, id) => { - bid.netRevenue = pt; - const assets = utils._map(bid.nativeParams, (bidParams, key) => { - const props = NATIVE_PARAMS[key]; - const asset = { - required: bidParams.required & 1, - }; - if (props) { - asset.id = props.id; - let wmin, hmin, w, h; - let aRatios = bidParams.aspect_ratios; - - if (aRatios && aRatios[0]) { - aRatios = aRatios[0]; - wmin = aRatios.min_width || 0; - hmin = aRatios.ratio_height * wmin / aRatios.ratio_width | 0; - } - - if (bidParams.sizes) { - const sizes = flatten(bidParams.sizes); - w = sizes[0]; - h = sizes[1]; - } - - asset[props.name] = { - len: bidParams.len, - type: props.type, - wmin, - hmin, - w, - h - }; - - return asset; - } - }).filter(Boolean); - - return { - id: id + 1, - tagid: bid.params.mid, - native: { - request: { - assets - } - } - }; - }); - - const request = { - id: bidderRequest.auctionId, - site: { id: siteId, page, publisher }, - device: { ua }, - source: { tid, fd: 1 }, - ext: { pt }, - cur, - imp - }; - - if (test) { - request.is_debug = !!test; - request.test = 1; - } - if (utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies') !== undefined) { - request.user = { ext: { consent: bidderRequest.gdprConsent.consentString } }; - request.regs = { ext: { gdpr: bidderRequest.gdprConsent.gdprApplies & 1 } }; - } - - if (bidderRequest.uspConsent) { - utils.deepSetValue(request, 'regs.ext.us_privacy', bidderRequest.uspConsent); - } - - if (eids) { - utils.deepSetValue(request, 'user.ext.eids', eids); - } - - return { - method: 'POST', - url: 'https://' + adxDomain + '/adx/openrtb', - data: JSON.stringify(request), - options: { - contentType: 'application/json' - }, - bids: validBidRequests - }; - }, - interpretResponse: function(serverResponse, { bids }) { - if (!serverResponse.body) { - return; - } - const { seatbid, cur } = serverResponse.body; - - const bidResponses = flatten(seatbid.map(seat => seat.bid)).reduce((result, bid) => { - result[bid.impid - 1] = bid; - return result; - }, []); - - return bids.map((bid, id) => { - const bidResponse = bidResponses[id]; - if (bidResponse) { - return { - requestId: bid.bidId, - cpm: bidResponse.price, - creativeId: bidResponse.crid, - ttl: 360, - netRevenue: bid.netRevenue === 'net', - currency: cur, - mediaType: NATIVE, - native: parseNative(bidResponse) - }; - } - }).filter(Boolean); - } -}; - -registerBidder(spec); - -function parseNative(bid) { - const { assets, link, imptrackers, jstracker } = bid.native; - const result = { - clickUrl: link.url, - clickTrackers: link.clicktrackers || undefined, - impressionTrackers: imptrackers || undefined, - javascriptTrackers: jstracker ? [ jstracker ] : undefined - }; - assets.forEach(asset => { - const kind = NATIVE_ASSET_IDS[asset.id]; - const content = kind && asset[NATIVE_PARAMS[kind].name]; - if (content) { - result[kind] = content.text || content.value || { url: content.url, width: content.w, height: content.h }; - } - }); - - return result; -} - -function setOnAny(collection, key) { - for (let i = 0, result; i < collection.length; i++) { - result = utils.deepAccess(collection[i], key); - if (result) { - return result; - } - } -} - -function flatten(arr) { - return [].concat(...arr); -} diff --git a/modules/adfBidAdapter.md b/modules/adfBidAdapter.md deleted file mode 100644 index 190aa91ea57..00000000000 --- a/modules/adfBidAdapter.md +++ /dev/null @@ -1,59 +0,0 @@ -# Overview - -Module Name: Adf Adapter -Module Type: Bidder Adapter -Maintainer: Scope.FL.Scripts@adform.com - -# Description - -Module that connects to Adform demand sources to fetch bids. -Only native format is supported. Using OpenRTB standard. Previous adapter name - adformOpenRTB. - -# Test Parameters -``` - var adUnits = [ - code: '/19968336/prebid_native_example_1', - sizes: [ - [360, 360] - ], - mediaTypes: { - native: { - image: { - required: false, - sizes: [100, 50] - }, - title: { - required: false, - len: 140 - }, - sponsoredBy: { - required: false - }, - clickUrl: { - required: false - }, - body: { - required: false - }, - icon: { - required: false, - sizes: [50, 50] - } - } - }, - bids: [{ - bidder: 'adf', - params: { - mid: 606169, // required - adxDomain: 'adx.adform.net', // optional - siteId: '23455', // optional - priceType: 'gross' // optional, default is 'net' - publisher: { // optional block - id: "2706", - name: "Publishers Name", - domain: "publisher.com" - } - } - }] - ]; -``` diff --git a/modules/adfinityBidAdapter.js b/modules/adfinityBidAdapter.js deleted file mode 100644 index ebf1198fba2..00000000000 --- a/modules/adfinityBidAdapter.js +++ /dev/null @@ -1,125 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; - -const BIDDER_CODE = 'adfinity'; -const AD_URL = 'https://stat.adfinity.pro/?c=o&m=multi'; -const SYNC_URL = 'https://stat.adfinity.pro/?c=o&m=cookie' - -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl); - case NATIVE: - const n = bid.native - return Boolean(n) && Boolean(n.title) && Boolean(n.body) && Boolean(n.image) && Boolean(n.impression_trackers); - default: - return false; - } -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO, NATIVE], - /** - * Determines whether or not the given bid request is valid. - * - * @param {object} bid The bid to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && bid.params && !isNaN(bid.params.placement_id)); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests A non-empty list of valid bid requests that should be sent to the Server. - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: (validBidRequests, bidderRequest) => { - let winTop = window; - let location; - try { - location = new URL(bidderRequest.refererInfo.referer) - winTop = window.top; - } catch (e) { - location = winTop.location; - utils.logMessage(e); - }; - let placements = []; - let request = { - 'deviceWidth': winTop.screen.width, - 'deviceHeight': winTop.screen.height, - 'language': (navigator && navigator.language) ? navigator.language : '', - 'secure': 1, - 'host': location.host, - 'page': location.pathname, - 'placements': placements - }; - - if (bidderRequest) { - if (bidderRequest.gdprConsent) { - request.gdpr_consent = bidderRequest.gdprConsent.consentString || 'ALL' - request.gdpr_require = bidderRequest.gdprConsent.gdprApplies ? 1 : 0 - } - } - - for (let i = 0; i < validBidRequests.length; i++) { - let bid = validBidRequests[i]; - let traff = bid.params.traffic || BANNER - let placement = { - placementId: bid.params.placement_id, - bidId: bid.bidId, - sizes: bid.mediaTypes[traff].sizes, - traffic: traff - }; - if (bid.schain) { - placement.schain = bid.schain; - } - placements.push(placement); - } - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: (serverResponse) => { - let response = []; - try { - serverResponse = serverResponse.body; - for (let i = 0; i < serverResponse.length; i++) { - let resItem = serverResponse[i]; - if (isBidResponseValid(resItem)) { - response.push(resItem); - } - } - } catch (e) { - utils.logMessage(e); - }; - return response; - }, - - getUserSyncs: () => { - return [{ - type: 'image', - url: SYNC_URL - }]; - } -}; - -registerBidder(spec); diff --git a/modules/adfinityBidAdapter.md b/modules/adfinityBidAdapter.md deleted file mode 100644 index f67d4fddfe7..00000000000 --- a/modules/adfinityBidAdapter.md +++ /dev/null @@ -1,67 +0,0 @@ -# Overview - -``` -Module Name: Adfinity Bidder Adapter -Module Type: Bidder Adapter -Maintainer: adfinity_prebid@i.ua -``` - -# Description - -Module that connects to Adfinity demand sources - -# Test Parameters -``` - var adUnits = [ - { - code: 'placementid_0', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]] - } - }, - bids: [{ - bidder: 'adfinity', - params: { - placement_id: 0, - traffic: 'banner' - } - } - ] - }, - { - code: 'placementid_0', - mediaTypes: { - native: { - - } - }, - bids: [ - { - bidder: 'adfinity', - params: { - placement_id: 0, - traffic: 'native' - } - } - ] - }, - { - code: 'placementid_0', - mediaTypes: { - video: { - sizes: [[300, 250], [300,600]] - } - }, - bids: [ - { - bidder: 'adfinity', - params: { - placement_id: 0, - traffic: 'video' - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/adformBidAdapter.js b/modules/adformBidAdapter.js deleted file mode 100644 index 3d0ed0fba79..00000000000 --- a/modules/adformBidAdapter.js +++ /dev/null @@ -1,213 +0,0 @@ -'use strict'; - -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 * as utils from '../src/utils.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -const OUTSTREAM_RENDERER_URL = 'https://s2.adform.net/banners/scripts/video/outstream/render.js'; - -const BIDDER_CODE = 'adform'; -const GVLID = 50; -export const spec = { - code: BIDDER_CODE, - gvlid: GVLID, - supportedMediaTypes: [ BANNER, VIDEO ], - isBidRequestValid: function (bid) { - return !!(bid.params.mid); - }, - buildRequests: function (validBidRequests, bidderRequest) { - var i, l, j, k, bid, _key, _value, reqParams, netRevenue, gdprObject; - const currency = config.getConfig('currency.adServerCurrency'); - const eids = getEncodedEIDs(utils.deepAccess(validBidRequests, '0.userIdAsEids')); - - var request = []; - var globalParams = [ [ 'adxDomain', 'adx.adform.net' ], [ 'fd', 1 ], [ 'url', null ], [ 'tid', null ], [ 'eids', eids ] ]; - const targetingParams = { mkv: [], mkw: [], msw: [] }; - - var bids = JSON.parse(JSON.stringify(validBidRequests)); - var bidder = (bids[0] && bids[0].bidder) || BIDDER_CODE; - - // set common targeting options as query params - if (bids.length > 1) { - for (let key in targetingParams) { - if (targetingParams.hasOwnProperty(key)) { - const collection = bids.map(bid => ((bid.params[key] && bid.params[key].split(',')) || [])); - targetingParams[key] = collection.reduce(intersects); - if (targetingParams[key].length) { - bids.forEach((bid, index) => { - bid.params[key] = collection[index].filter(item => !includes(targetingParams[key], item)); - }); - } - } - } - } - - for (i = 0, l = bids.length; i < l; i++) { - bid = bids[i]; - if ((bid.params.priceType === 'net') || (bid.params.pt === 'net')) { - netRevenue = 'net'; - } - - for (j = 0, k = globalParams.length; j < k; j++) { - _key = globalParams[j][0]; - _value = bid[_key] || bid.params[_key]; - if (_value) { - bid[_key] = bid.params[_key] = null; - globalParams[j][1] = _value; - } - } - reqParams = bid.params; - reqParams.transactionId = bid.transactionId; - reqParams.rcur = reqParams.rcur || currency; - request.push(formRequestUrl(reqParams)); - } - - request.unshift('https://' + globalParams[0][1] + '/adx/?rp=4'); - netRevenue = netRevenue || 'gross'; - request.push('pt=' + netRevenue); - request.push('stid=' + validBidRequests[0].auctionId); - - const gdprApplies = utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies'); - const consentString = utils.deepAccess(bidderRequest, 'gdprConsent.consentString'); - if (gdprApplies !== undefined) { - gdprObject = { - gdpr: gdprApplies, - gdpr_consent: consentString - }; - request.push('gdpr=' + (gdprApplies & 1)); - request.push('gdpr_consent=' + consentString); - } - - if (bidderRequest && bidderRequest.uspConsent) { - request.push('us_privacy=' + bidderRequest.uspConsent); - } - - for (let key in targetingParams) { - if (targetingParams.hasOwnProperty(key)) { - globalParams.push([ key, targetingParams[key].join(',') ]); - } - } - - for (i = 1, l = globalParams.length; i < l; i++) { - _key = globalParams[i][0]; - _value = globalParams[i][1]; - if (_value) { - request.push(_key + '=' + encodeURIComponent(_value)); - } - } - - return { - method: 'GET', - url: request.join('&'), - bids: validBidRequests, - netRevenue: netRevenue, - bidder, - gdpr: gdprObject - }; - - function formRequestUrl(reqData) { - var key; - var url = []; - - for (key in reqData) { - if (reqData.hasOwnProperty(key) && reqData[key]) { url.push(key, '=', reqData[key], '&'); } - } - - return encodeURIComponent(btoa(url.join('').slice(0, -1))); - } - - function getEncodedEIDs(eids) { - if (utils.isArray(eids) && eids.length > 0) { - const parsed = parseEIDs(eids); - return btoa(JSON.stringify(parsed)); - } - } - - function parseEIDs(eids) { - return eids.reduce((result, eid) => { - const source = eid.source; - result[source] = result[source] || {}; - - eid.uids.forEach(value => { - const id = value.id + ''; - result[source][id] = result[source][id] || []; - result[source][id].push(value.atype); - }); - - return result; - }, {}); - } - - function intersects(col1, col2) { - return col1.filter(item => includes(col2, item)); - } - }, - interpretResponse: function (serverResponse, bidRequest) { - const VALID_RESPONSES = { - banner: 1, - vast_content: 1, - vast_url: 1 - }; - var bidObject, response, bid, type; - var bidRespones = []; - var bids = bidRequest.bids; - var responses = serverResponse.body; - for (var i = 0; i < responses.length; i++) { - response = responses[i]; - type = response.response === 'banner' ? BANNER : VIDEO; - bid = bids[i]; - if (VALID_RESPONSES[response.response] && (verifySize(response, utils.getAdUnitSizes(bid)) || type === VIDEO)) { - bidObject = { - requestId: bid.bidId, - cpm: response.win_bid, - width: response.width, - height: response.height, - creativeId: bid.bidId, - dealId: response.deal_id, - currency: response.win_cur, - netRevenue: bidRequest.netRevenue !== 'gross', - ttl: 360, - meta: { advertiserDomains: response && response.adomain ? response.adomain : [] }, - ad: response.banner, - bidderCode: bidRequest.bidder, - transactionId: bid.transactionId, - vastUrl: response.vast_url, - vastXml: response.vast_content, - mediaType: type - }; - - if (!bid.renderer && type === VIDEO && utils.deepAccess(bid, 'mediaTypes.video.context') === 'outstream') { - bidObject.renderer = Renderer.install({id: bid.bidId, url: OUTSTREAM_RENDERER_URL}); - bidObject.renderer.setRender(renderer); - } - - if (bidRequest.gdpr) { - bidObject.gdpr = bidRequest.gdpr.gdpr; - bidObject.gdpr_consent = bidRequest.gdpr.gdpr_consent; - } - bidRespones.push(bidObject); - } - } - return bidRespones; - - function renderer(bid) { - bid.renderer.push(() => { - window.Adform.renderOutstream(bid); - }); - } - - function verifySize(adItem, validSizes) { - for (var j = 0, k = validSizes.length; j < k; j++) { - if (adItem.width == validSizes[j][0] && - adItem.height == validSizes[j][1]) { - return true; - } - } - return false; - } - } -}; -registerBidder(spec); diff --git a/modules/adformBidAdapter.md b/modules/adformBidAdapter.md deleted file mode 100644 index 10ebec37e08..00000000000 --- a/modules/adformBidAdapter.md +++ /dev/null @@ -1,30 +0,0 @@ -# Overview - -Module Name: Adform Bidder Adapter -Module Type: Bidder Adapter -Maintainer: Scope.FL.Scripts@adform.com - -# Description - -Module that connects to Adform demand sources to fetch bids. -Banner and video formats are supported. - -# Test Parameters -``` - var adUnits = [ - { - code: 'div-gpt-ad-1460505748561-0', - sizes: [[300, 250], [250, 300], [300, 600], [600, 300]], // a display size - bids: [ - { - bidder: "adform", - params: { - adxDomain: 'adx.adform.net', //optional - mid: '292063', - priceType: 'net' // default is 'gross' - } - } - ] - }, - ]; -``` diff --git a/modules/adgenerationBidAdapter.js b/modules/adgenerationBidAdapter.js deleted file mode 100644 index 7f92ab483f6..00000000000 --- a/modules/adgenerationBidAdapter.js +++ /dev/null @@ -1,236 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -const ADG_BIDDER_CODE = 'adgeneration'; - -export const spec = { - code: ADG_BIDDER_CODE, - aliases: ['adg'], // short code - supportedMediaTypes: [BANNER, NATIVE], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return !!(bid.params.id); - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - const ADGENE_PREBID_VERSION = '1.0.1'; - let serverRequests = []; - for (let i = 0, len = validBidRequests.length; i < len; i++) { - const validReq = validBidRequests[i]; - const DEBUG_URL = 'https://api-test.scaleout.jp/adsv/v1'; - const URL = 'https://d.socdm.com/adsv/v1'; - const url = validReq.params.debug ? DEBUG_URL : URL; - let data = ``; - data = utils.tryAppendQueryString(data, 'posall', 'SSPLOC'); - const id = utils.getBidIdParameter('id', validReq.params); - data = utils.tryAppendQueryString(data, 'id', id); - data = utils.tryAppendQueryString(data, 'sdktype', '0'); - data = utils.tryAppendQueryString(data, 'hb', 'true'); - data = utils.tryAppendQueryString(data, 't', 'json3'); - data = utils.tryAppendQueryString(data, 'transactionid', validReq.transactionId); - data = utils.tryAppendQueryString(data, 'sizes', getSizes(validReq)); - data = utils.tryAppendQueryString(data, 'currency', getCurrencyType()); - data = utils.tryAppendQueryString(data, 'pbver', '$prebid.version$'); - data = utils.tryAppendQueryString(data, 'sdkname', 'prebidjs'); - data = utils.tryAppendQueryString(data, 'adapterver', ADGENE_PREBID_VERSION); - // native以外にvideo等の対応が入った場合は要修正 - if (!validReq.mediaTypes || !validReq.mediaTypes.native) { - data = utils.tryAppendQueryString(data, 'imark', '1'); - } - data = utils.tryAppendQueryString(data, 'tp', bidderRequest.refererInfo.referer); - // remove the trailing "&" - if (data.lastIndexOf('&') === data.length - 1) { - data = data.substring(0, data.length - 1); - } - serverRequests.push({ - method: 'GET', - url: url, - data: data, - bidRequest: validBidRequests[i] - }); - } - return serverRequests; - }, - /** - * Unpack the response from the server into a list of bids. - * - * @param {ServerResponse} serverResponse A successful response from the server. - * @param {BidRequest} bidRequests - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function (serverResponse, bidRequests) { - const body = serverResponse.body; - if (!body.results || body.results.length < 1) { - return []; - } - const bidRequest = bidRequests.bidRequest; - const bidResponse = { - requestId: bidRequest.bidId, - cpm: body.cpm || 0, - width: body.w ? body.w : 1, - height: body.h ? body.h : 1, - creativeId: body.creativeid || '', - dealId: body.dealid || '', - currency: getCurrencyType(), - netRevenue: true, - ttl: body.ttl || 10, - }; - if (isNative(body)) { - bidResponse.native = createNativeAd(body); - bidResponse.mediaType = NATIVE; - } else { - // banner - bidResponse.ad = createAd(body, bidRequest); - } - return [bidResponse]; - }, - - /** - * Register the user sync pixels which should be dropped after the auction. - * - * @param {SyncOptions} syncOptions Which user syncs are allowed? - * @param {ServerResponse[]} serverResponses List of server's responses. - * @return {UserSync[]} The user syncs which should be dropped. - */ - getUserSyncs: function (syncOptions, serverResponses) { - const syncs = []; - return syncs; - } -}; - -function createAd(body, bidRequest) { - let ad = body.ad; - if (body.vastxml && body.vastxml.length > 0) { - ad = `
${createAPVTag()}${insertVASTMethod(bidRequest.bidId, body.vastxml)}`; - } - ad = appendChildToBody(ad, body.beacon); - if (removeWrapper(ad)) return removeWrapper(ad); - return ad; -} - -function isNative(body) { - if (!body) return false; - return body.native_ad && body.native_ad.assets.length > 0; -} - -function createNativeAd(body) { - let native = {}; - if (body.native_ad && body.native_ad.assets.length > 0) { - const assets = body.native_ad.assets; - for (let i = 0, len = assets.length; i < len; i++) { - switch (assets[i].id) { - case 1: - native.title = assets[i].title.text; - break; - case 2: - native.image = { - url: assets[i].img.url, - height: assets[i].img.h, - width: assets[i].img.w, - }; - break; - case 3: - native.icon = { - url: assets[i].img.url, - height: assets[i].img.h, - width: assets[i].img.w, - }; - break; - case 4: - native.sponsoredBy = assets[i].data.value; - break; - case 5: - native.body = assets[i].data.value; - break; - case 6: - native.cta = assets[i].data.value; - break; - case 502: - native.privacyLink = encodeURIComponent(assets[i].data.value); - break; - } - } - native.clickUrl = body.native_ad.link.url; - native.clickTrackers = body.native_ad.link.clicktrackers || []; - native.impressionTrackers = body.native_ad.imptrackers || []; - if (body.beaconurl && body.beaconurl != '') { - native.impressionTrackers.push(body.beaconurl) - } - } - return native; -} - -function appendChildToBody(ad, data) { - return ad.replace(/<\/\s?body>/, `${data}`); -} - -function createAPVTag() { - const APVURL = 'https://cdn.apvdr.com/js/VideoAd.min.js'; - let apvScript = document.createElement('script'); - apvScript.type = 'text/javascript'; - apvScript.id = 'apv'; - apvScript.src = APVURL; - return apvScript.outerHTML; -} - -function insertVASTMethod(targetId, vastXml) { - let apvVideoAdParam = { - s: targetId - }; - let script = document.createElement(`script`); - script.type = 'text/javascript'; - script.innerHTML = `(function(){ new APV.VideoAd(${JSON.stringify(apvVideoAdParam)}).load('${vastXml.replace(/\r?\n/g, '')}'); })();`; - return script.outerHTML; -} - -/** - * - * @param ad - */ -function removeWrapper(ad) { - const bodyIndex = ad.indexOf(''); - const lastBodyIndex = ad.lastIndexOf(''); - if (bodyIndex === -1 || lastBodyIndex === -1) return false; - return ad.substr(bodyIndex, lastBodyIndex).replace('', '').replace('', ''); -} - -/** - * request - * @param validReq request - * @returns {?string} 300x250,320x50... - */ -function getSizes(validReq) { - const sizes = validReq.sizes; - if (!sizes || sizes.length < 1) return null; - let sizesStr = ''; - for (const i in sizes) { - const size = sizes[i]; - if (size.length !== 2) return null; - sizesStr += `${size[0]}x${size[1]},`; - } - if (sizesStr || sizesStr.lastIndexOf(',') === sizesStr.length - 1) { - sizesStr = sizesStr.substring(0, sizesStr.length - 1); - } - return sizesStr; -} - -/** - * @return {?string} USD or JPY - */ -function getCurrencyType() { - if (config.getConfig('currency.adServerCurrency') && config.getConfig('currency.adServerCurrency').toUpperCase() === 'USD') return 'USD'; - return 'JPY'; -} - -registerBidder(spec); diff --git a/modules/adgenerationBidAdapter.md b/modules/adgenerationBidAdapter.md deleted file mode 100644 index 7f66732ff38..00000000000 --- a/modules/adgenerationBidAdapter.md +++ /dev/null @@ -1,75 +0,0 @@ -# Overview - -``` -Module Name: AdGeneration Bid Adapter -Module Type: Bidder Adapter -Maintainer: ssp-ope@supership.jp -``` - -# Description - -Connects to AdGeneration exchange for bids. - -AdGeneration bid adapter supports Banner and Native. - -# Test Parameters -``` -var adUnits = [ - // Banner adUnit - { - code: 'banner-div', // banner - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [ - { - bidder: 'adg', - params: { - id: '58278', // banner - } - }, - ] - }, - // Native adUnit - { - code: 'native-div', - sizes: [[1,1]], - mediaTypes: { - native: { - image: { - required: true - }, - title: { - required: true, - len: 80 - }, - sponsoredBy: { - required: true - }, - clickUrl: { - required: true - }, - body: { - required: true - }, - icon: { - required: true - }, - privacyLink: { - required: true - }, - }, - }, - bids: [ - { - bidder: 'adg', - params: { - id: '58279', //native - } - }, - ] - }, -]; -``` diff --git a/modules/adglareBidAdapter.js b/modules/adglareBidAdapter.js deleted file mode 100644 index d66a38482ec..00000000000 --- a/modules/adglareBidAdapter.js +++ /dev/null @@ -1,90 +0,0 @@ -'use strict'; - -import {registerBidder} from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'adglare'; - -export const spec = { - code: BIDDER_CODE, - isBidRequestValid: function (bid) { - let p = bid.params; - if (typeof p.domain === 'string' && !!p.domain.length && p.zID && !isNaN(p.zID) && p.type == 'banner') return true; - return false; - }, - buildRequests: function (validBidRequests, bidderRequest) { - let i; - let j; - let bidRequest; - let zID; - let domain; - let keywords; - let url; - let type; - let availscreen = window.innerWidth + 'x' + window.innerHeight; - let pixelRatio = window.devicePixelRatio || 1; - let screen = (pixelRatio * window.screen.width) + 'x' + (pixelRatio * window.screen.height); - let sizes = []; - let serverRequests = []; - let timeout = bidderRequest.timeout || 0; - let referer = bidderRequest.refererInfo.referer || ''; - let reachedtop = bidderRequest.refererInfo.reachedTop || ''; - for (i = 0; i < validBidRequests.length; i++) { - bidRequest = validBidRequests[i]; - zID = bidRequest.params.zID; - domain = bidRequest.params.domain; - keywords = bidRequest.params.keywords || ''; - type = bidRequest.params.type; - - // Build ad unit sizes - if (bidRequest.mediaTypes && bidRequest.mediaTypes[type]) { - for (j in bidRequest.mediaTypes[type].sizes) { - sizes.push(bidRequest.mediaTypes[type].sizes[j].join('x')); - } - } - - // Build URL - url = 'https://' + domain + '/?' + encodeURIComponent(zID) + '&pbjs&pbjs_version=1'; - url += '&pbjs_type=' + encodeURIComponent(type); - url += '&pbjs_timeout=' + encodeURIComponent(timeout); - url += '&pbjs_reachedtop=' + encodeURIComponent(reachedtop); - url += '&sizes=' + encodeURIComponent(sizes.join(',')); - url += '&screen=' + encodeURIComponent(screen); - url += '&availscreen=' + encodeURIComponent(availscreen); - url += '&referer=' + encodeURIComponent(referer); - if (keywords !== '') { - url += '&keywords=' + encodeURIComponent(keywords); - } - - // Push server request - serverRequests.push({ - method: 'GET', - url: url, - data: {}, - bidRequest: bidRequest - }); - } - return serverRequests; - }, - interpretResponse: function (serverResponse, request) { - const bidObj = request.bidRequest; - let bidResponses = []; - let bidResponse = {}; - serverResponse = serverResponse.body; - - if (serverResponse && serverResponse.status == 'OK' && bidObj) { - bidResponse.requestId = bidObj.bidId; - bidResponse.bidderCode = bidObj.bidder; - bidResponse.cpm = serverResponse.cpm; - bidResponse.width = serverResponse.width; - bidResponse.height = serverResponse.height; - bidResponse.ad = serverResponse.adhtml; - bidResponse.ttl = serverResponse.ttl; - bidResponse.creativeId = serverResponse.crID; - bidResponse.netRevenue = true; - bidResponse.currency = serverResponse.currency; - bidResponses.push(bidResponse); - } - return bidResponses; - }, -}; -registerBidder(spec); diff --git a/modules/adglareBidAdapter.md b/modules/adglareBidAdapter.md deleted file mode 100644 index 845564473c7..00000000000 --- a/modules/adglareBidAdapter.md +++ /dev/null @@ -1,36 +0,0 @@ -# Overview - -``` -Module Name: AdGlare Ad Server Adapter -Module Type: Bidder Adapter -Maintainer: prebid@adglare.com -``` - -# Description - -Adapter that connects to your AdGlare Ad Server. -Including support for your white label ad serving domain. - -# Test Parameters -``` - var adUnits = [ - { - code: 'your-div-id', - mediaTypes: { - banner: { - sizes: [[300,250], [728,90]], - } - }, - bids: [ - { - bidder: 'adglare', - params: { - domain: 'try.engine.adglare.net', - zID: '475579334', - type: 'banner' - } - } - ] - } - ]; -``` diff --git a/modules/adhashBidAdapter.js b/modules/adhashBidAdapter.js deleted file mode 100644 index b30f9cebbc1..00000000000 --- a/modules/adhashBidAdapter.js +++ /dev/null @@ -1,102 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import { BANNER } from '../src/mediaTypes.js'; - -const VERSION = '1.0'; - -export const spec = { - code: 'adhash', - url: 'https://bidder.adhash.org/rtb?version=' + VERSION + '&prebid=true', - supportedMediaTypes: [ BANNER ], - - isBidRequestValid: (bid) => { - try { - const { publisherId, platformURL } = bid.params; - return ( - includes(Object.keys(bid.mediaTypes), BANNER) && - typeof publisherId === 'string' && - publisherId.length === 42 && - typeof platformURL === 'string' && - platformURL.length >= 13 - ); - } catch (error) { - return false; - } - }, - - buildRequests: (validBidRequests, bidderRequest) => { - const { gdprConsent } = bidderRequest; - const { url } = spec; - const bidRequests = []; - let referrer = ''; - if (bidderRequest && bidderRequest.refererInfo) { - referrer = bidderRequest.refererInfo.referer; - } - for (var i = 0; i < validBidRequests.length; i++) { - var index = Math.floor(Math.random() * validBidRequests[i].sizes.length); - var size = validBidRequests[i].sizes[index].join('x'); - bidRequests.push({ - method: 'POST', - url: url, - bidRequest: validBidRequests[i], - data: { - timezone: new Date().getTimezoneOffset() / 60, - location: referrer, - publisherId: validBidRequests[i].params.publisherId, - size: { - screenWidth: window.screen.width, - screenHeight: window.screen.height - }, - navigator: { - platform: window.navigator.platform, - language: window.navigator.language, - userAgent: window.navigator.userAgent - }, - creatives: [{ - size: size, - position: validBidRequests[i].adUnitCode - }], - blockedCreatives: [], - currentTimestamp: new Date().getTime(), - recentAds: [], - GDPR: gdprConsent - }, - options: { - withCredentials: false, - crossOrigin: true - }, - }); - } - return bidRequests; - }, - - interpretResponse: (serverResponse, request) => { - const responseBody = serverResponse ? serverResponse.body : {}; - - if (!responseBody.creatives || responseBody.creatives.length === 0) { - return []; - } - - const publisherURL = JSON.stringify(request.bidRequest.params.platformURL); - const oneTimeId = request.bidRequest.adUnitCode + Math.random().toFixed(16).replace('0.', '.'); - const bidderResponse = JSON.stringify({ responseText: JSON.stringify(responseBody) }); - const requestData = JSON.stringify(request.data); - - return [{ - requestId: request.bidRequest.bidId, - cpm: responseBody.creatives[0].costEUR, - ad: - `
- - `, - width: request.bidRequest.sizes[0][0], - height: request.bidRequest.sizes[0][1], - creativeId: request.bidRequest.adUnitCode, - netRevenue: true, - currency: 'EUR', - ttl: 60 - }]; - } -}; - -registerBidder(spec); diff --git a/modules/adhashBidAdapter.md b/modules/adhashBidAdapter.md deleted file mode 100644 index c1093e0ccd7..00000000000 --- a/modules/adhashBidAdapter.md +++ /dev/null @@ -1,43 +0,0 @@ -# Overview - -``` -Module Name: AdHash Bidder Adapter -Module Type: Bidder Adapter -Maintainer: damyan@adhash.org -``` - -# Description - -Here is what you need for Prebid integration with AdHash: -1. Register with AdHash. -2. Once registered and approved, you will receive a Publisher ID and Platform URL. -3. Use the Publisher ID and Platform URL as parameters in params. - -Please note that a number of AdHash functionalities are not supported in the Prebid.js integration: -* Cookie-less frequency and recency capping; -* Audience segments; -* Price floors and passback tags, as they are not needed in the Prebid.js setup; -* Reservation for direct deals only, as bids are evaluated based on their price. - -# Test Parameters -``` - var adUnits = [ - { - code: '/19968336/header-bid-tag-1', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [ - { - bidder: 'adhash', - params: { - publisherId: '0x1234567890123456789012345678901234567890', - platformURL: 'https://adhash.org/p/struma/' - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/adheseBidAdapter.js b/modules/adheseBidAdapter.js deleted file mode 100644 index b9dbae529ba..00000000000 --- a/modules/adheseBidAdapter.js +++ /dev/null @@ -1,233 +0,0 @@ -'use strict'; - -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'adhese'; -const GVLID = 553; -const USER_SYNC_BASE_URL = 'https://user-sync.adhese.com/iframe/user_sync.html'; - -export const spec = { - code: BIDDER_CODE, - gvlid: GVLID, - supportedMediaTypes: [BANNER, VIDEO], - - isBidRequestValid: function(bid) { - return !!(bid.params.account && bid.params.location && (bid.params.format || bid.mediaTypes.banner.sizes)); - }, - - buildRequests: function(validBidRequests, bidderRequest) { - if (validBidRequests.length === 0) { - return null; - } - const { gdprConsent, refererInfo } = bidderRequest; - - const gdprParams = (gdprConsent && gdprConsent.consentString) ? { xt: [gdprConsent.consentString] } : {}; - const refererParams = (refererInfo && refererInfo.referer) ? { xf: [base64urlEncode(refererInfo.referer)] } : {}; - const commonParams = { ...gdprParams, ...refererParams }; - - const slots = validBidRequests.map(bid => ({ - slotname: bidToSlotName(bid), - parameters: cleanTargets(bid.params.data) - })); - - const payload = { - slots: slots, - parameters: commonParams, - vastContentAsUrl: true, - user: { - ext: { - eids: getEids(validBidRequests), - } - } - }; - - const account = getAccount(validBidRequests); - const uri = 'https://ads-' + account + '.adhese.com/json'; - - return { - method: 'POST', - url: uri, - data: JSON.stringify(payload), - bids: validBidRequests, - options: { - contentType: 'application/json' - } - }; - }, - - interpretResponse: function(serverResponse, request) { - const serverAds = serverResponse.body.reduce(function(map, ad) { - map[ad.slotName] = ad; - return map; - }, {}); - - serverResponse.account = getAccount(request.bids); - - return request.bids - .map(bid => ({ - bid: bid, - ad: serverAds[bidToSlotName(bid)] - })) - .filter(item => item.ad) - .map(item => adResponse(item.bid, item.ad)); - }, - - getUserSyncs: function(syncOptions, serverResponses, gdprConsent) { - if (syncOptions.iframeEnabled && serverResponses.length > 0) { - const account = serverResponses[0].account; - if (account) { - let syncurl = USER_SYNC_BASE_URL + '?account=' + account; - if (gdprConsent) { - syncurl += '&gdpr=' + (gdprConsent.gdprApplies ? 1 : 0); - syncurl += '&consentString=' + encodeURIComponent(gdprConsent.consentString || ''); - } - return [{type: 'iframe', url: syncurl}]; - } - } - return []; - } -}; - -function adResponse(bid, ad) { - const price = getPrice(ad); - const adDetails = getAdDetails(ad); - const markup = getAdMarkup(ad); - - const bidResponse = getbaseAdResponse({ - requestId: bid.bidId, - mediaType: ad.extension.mediaType, - cpm: Number(price.amount), - currency: price.currency, - width: Number(ad.width), - height: Number(ad.height), - creativeId: adDetails.creativeId, - dealId: adDetails.dealId, - adhese: { - originData: adDetails.originData, - origin: adDetails.origin, - originInstance: adDetails.originInstance - } - }); - - if (bidResponse.mediaType === VIDEO) { - if (ad.cachedBodyUrl) { - bidResponse.vastUrl = ad.cachedBodyUrl - } else { - bidResponse.vastXml = markup; - } - } else { - const counter = ad.impressionCounter ? "" : ''; - bidResponse.ad = markup + counter; - } - return bidResponse; -} - -function cleanTargets(target) { - const targets = {}; - if (target) { - Object.keys(target).forEach(function (key) { - const val = target[key]; - const dirtyValues = Array.isArray(val) ? val : [val]; - const values = dirtyValues.filter(v => v === 0 || v); - if (values.length > 0) { - if (targets[key]) { - const distinctValues = values.filter(v => targets[key].indexOf(v) < 0); - targets[key].push.apply(targets[key], distinctValues); - } else { - targets[key] = values; - } - } - }); - } - return targets; -} - -function bidToSlotName(bid) { - if (bid.params.format) { - return bid.params.location + '-' + bid.params.format; - } - - var sizes = bid.mediaTypes.banner.sizes; - sizes.sort(); - var format = sizes.map(size => size[0] + 'x' + size[1]).join('_'); - - if (format.length > 0) { - return bid.params.location + '-' + format; - } else { - return bid.params.location; - } -} - -function getAccount(validBidRequests) { - return validBidRequests[0].params.account; -} - -function getEids(validBidRequests) { - if (validBidRequests[0] && validBidRequests[0].userIdAsEids) { - return validBidRequests[0].userIdAsEids; - } -} - -function getbaseAdResponse(response) { - return Object.assign({ netRevenue: true, ttl: 360 }, response); -} - -function isAdheseAd(ad) { - return !ad.origin || ad.origin === 'JERLICIA'; -} - -function getAdMarkup(ad) { - if (!isAdheseAd(ad) || (ad.ext === 'js' && ad.body !== undefined && ad.body !== '' && ad.body.match(/ { - if (!config.options.pubId) { - utils.logError('PubId is not defined. Analytics won\'t work'); - return; - } - analyticsAdapter.context = { - host: config.options.host || DEFAULT_HOST, - pubId: config.options.pubId, - requestTemplate: buildRequestTemplate(config.options.pubId), - queue: new ExpiringQueue(sendAll, config.options.queueTimeout || DEFAULT_QUEUE_TIMEOUT) - }; - analyticsAdapter.originEnableAnalytics(config); -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: analyticsAdapter, - code: 'adkernelAdn', - gvlid: GVLID -}); - -export default analyticsAdapter; - -function sendAll() { - let events = analyticsAdapter.context.queue.popAll(); - if (events.length !== 0) { - let req = Object.assign({}, analyticsAdapter.context.requestTemplate, {hb_ev: events}); - analyticsAdapter.ajaxCall(JSON.stringify(req)); - } -} - -analyticsAdapter.ajaxCall = function ajaxCall(data) { - ajax(`https://${analyticsAdapter.context.host}/hb-analytics`, () => { - }, data); -}; - -function trackAuctionInit() { - analyticsAdapter.context.auctionTimeStart = Date.now(); - const event = createHbEvent(undefined, ADK_HB_EVENTS.AUCTION_INIT); - return [event]; -} - -function trackBidRequest(args) { - return args.bids.map(bid => - createHbEvent(args.bidderCode, ADK_HB_EVENTS.BID_REQUEST, bid.adUnitCode)); -} - -function trackBidResponse(args) { - const event = createHbEvent(args.bidderCode, ADK_HB_EVENTS.BID_RESPONSE, - args.adUnitCode, args.cpm, args.timeToRespond / 1000); - return [event]; -} - -function trackBidWon(args) { - const event = createHbEvent(args.bidderCode, ADK_HB_EVENTS.BID_WON, args.adUnitCode, args.cpm); - return [event]; -} - -function trackAuctionEnd(args) { - const event = createHbEvent(undefined, ADK_HB_EVENTS.AUCTION_END, undefined, - undefined, (Date.now() - analyticsAdapter.context.auctionTimeStart) / 1000); - return [event]; -} - -function trackBidTimeout(args) { - return args.map(bidderName => createHbEvent(bidderName, ADK_HB_EVENTS.TIMEOUT)); -} - -function createHbEvent(adapter, event, tagid = undefined, value = 0, time = 0) { - let ev = {event: event}; - if (adapter) { - ev.adapter = adapter - } - if (tagid) { - ev.tagid = tagid; - } - if (value) { - ev.val = value; - } - if (time) { - ev.time = time; - } - return ev; -} - -const UTM_TAGS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', - 'utm_c1', 'utm_c2', 'utm_c3', 'utm_c4', 'utm_c5']; -const ADKERNEL_PREBID_KEY = 'adk_dpt_analytics'; -const DIRECT = '(direct)'; -const REFERRAL = '(referral)'; -const ORGANIC = '(organic)'; - -export let storage = { - getItem: (name) => { - return storageObj.getDataFromLocalStorage(name); - }, - setItem: (name, value) => { - storageObj.setDataInLocalStorage(name, value); - } -}; - -export function getUmtSource(pageUrl, referrer) { - let prevUtm = getPreviousTrafficSource(); - let currUtm = getCurrentTrafficSource(pageUrl, referrer); - let [updated, actual] = chooseActualUtm(prevUtm, currUtm); - if (updated) { - storeUtm(actual); - } - return actual; - - function getPreviousTrafficSource() { - let val = storage.getItem(ADKERNEL_PREBID_KEY); - if (!val) { - return getDirect(); - } - return JSON.parse(val); - } - - function getCurrentTrafficSource(pageUrl, referrer) { - var source = getUTM(pageUrl); - if (source) { - return source; - } - if (referrer) { - let se = getSearchEngine(referrer); - if (se) { - return asUtm(se, ORGANIC, ORGANIC); - } - let parsedUrl = utils.parseUrl(pageUrl); - let [refHost, refPath] = getReferrer(referrer); - if (refHost && refHost !== parsedUrl.hostname) { - return asUtm(refHost, REFERRAL, REFERRAL, '', refPath); - } - } - return getDirect(); - } - - function getSearchEngine(pageUrl) { - let engines = { - 'google': /^https?\:\/\/(?:www\.)?(?:google\.(?:com?\.)?(?:com|cat|[a-z]{2})|g.cn)\//i, - 'yandex': /^https?\:\/\/(?:www\.)?ya(?:ndex\.(?:com|net)?\.?(?:asia|mobi|org|[a-z]{2})?|\.ru)\//i, - 'bing': /^https?\:\/\/(?:www\.)?bing\.com\//i, - 'duckduckgo': /^https?\:\/\/(?:www\.)?duckduckgo\.com\//i, - 'ask': /^https?\:\/\/(?:www\.)?ask\.com\//i, - 'yahoo': /^https?\:\/\/(?:[-a-z]+\.)?(?:search\.)?yahoo\.com\//i - }; - - for (let engine in engines) { - if (engines.hasOwnProperty(engine) && engines[engine].test(pageUrl)) { - return engine; - } - } - } - - function getReferrer(referrer) { - let ref = utils.parseUrl(referrer); - return [ref.hostname, ref.pathname]; - } - - function getUTM(pageUrl) { - let urlParameters = utils.parseUrl(pageUrl).search; - if (!urlParameters['utm_campaign'] || !urlParameters['utm_source']) { - return; - } - let utmArgs = []; - utils._each(UTM_TAGS, (utmTagName) => { - let utmValue = urlParameters[utmTagName] || ''; - utmArgs.push(utmValue); - }); - return asUtm.apply(this, utmArgs); - } - - function getDirect() { - return asUtm(DIRECT, DIRECT, DIRECT); - } - - function storeUtm(utm) { - let val = JSON.stringify(utm); - storage.setItem(ADKERNEL_PREBID_KEY, val); - } - - function asUtm(source, medium, campaign, term = '', content = '', c1 = '', c2 = '', c3 = '', c4 = '', c5 = '') { - let result = { - source: source, - medium: medium, - campaign: campaign - }; - if (term) { - result.term = term; - } - if (content) { - result.content = content; - } - if (c1) { - result.c1 = c1; - } - if (c2) { - result.c2 = c2; - } - if (c3) { - result.c3 = c3; - } - if (c4) { - result.c4 = c4; - } - if (c5) { - result.c5 = c5; - } - return result; - } - - function chooseActualUtm(prev, curr) { - if (ord(prev) < ord(curr)) { - return [true, curr]; - } else if (ord(prev) > ord(curr)) { - return [false, prev]; - } else { - if (prev.campaign === REFERRAL && prev.content !== curr.content) { - return [true, curr]; - } else if (prev.campaign === ORGANIC && prev.source !== curr.source) { - return [true, curr]; - } else if (isCampaignTraffic(prev) && (prev.campaign !== curr.campaign || prev.source !== curr.source)) { - return [true, curr]; - } - } - return [false, prev]; - } - - function ord(utm) { - switch (utm.campaign) { - case DIRECT: - return 0; - case ORGANIC: - return 1; - case REFERRAL: - return 2; - default: - return 3; - } - } - - function isCampaignTraffic(utm) { - return [DIRECT, REFERRAL, ORGANIC].indexOf(utm.campaign) === -1; - } -} - -/** - * Expiring queue implementation. Fires callback on elapsed timeout since last update or creation. - * @param callback - * @param ttl - * @constructor - */ -export function ExpiringQueue(callback, ttl) { - let queue = []; - let timeoutId; - - this.push = (event) => { - if (event instanceof Array) { - queue.push.apply(queue, event); - } else { - queue.push(event); - } - reset(); - }; - - this.popAll = () => { - let result = queue; - queue = []; - reset(); - return result; - }; - - /** - * For test/debug purposes only - * @return {Array} - */ - this.peekAll = () => { - return queue; - }; - - this.init = reset; - - function reset() { - if (timeoutId) { - clearTimeout(timeoutId); - } - timeoutId = setTimeout(() => { - if (queue.length) { - callback(); - } - }, ttl); - } -} - -function getNavigationInfo() { - try { - return getLocationAndReferrer(self.top); - } catch (e) { - return getLocationAndReferrer(self); - } -} - -function getLocationAndReferrer(win) { - return { - ref: win.document.referrer, - loc: win.location - }; -} - -function initPrivacy(template, requests) { - let consent = requests[0].gdprConsent; - if (consent && consent.gdprApplies) { - template.user.gdpr = ~~consent.gdprApplies; - } - if (consent && consent.consentString) { - template.user.gdpr_consent = consent.consentString; - } - if (requests[0].uspConsent) { - template.user.us_privacy = requests[0].uspConsent; - } - if (config.getConfig('coppa')) { - template.user.coppa = 1; - } -} diff --git a/modules/adkernelAdnAnalyticsAdapter.md b/modules/adkernelAdnAnalyticsAdapter.md deleted file mode 100644 index 94219e5ec8d..00000000000 --- a/modules/adkernelAdnAnalyticsAdapter.md +++ /dev/null @@ -1,22 +0,0 @@ -# Overview -Module Name: Adkernel ADN Analytics Adapter - -Module Type: Analytics Adapter - -Maintainer: denis@adkernel.com - -# Description - -Analytics adapter for Adkernel Ad Delivery Network. Contact contact@adkernel.com for information. - -# Test Parameters - -``` -{ - provider: 'adkernelAdn', - options : { - pubId : 50357, //id provided by adkernel - host: 'dsp-staging.adkernel.com' //optional host for validation purposes - } -} -``` diff --git a/modules/adkernelAdnBidAdapter.js b/modules/adkernelAdnBidAdapter.js deleted file mode 100644 index 0de750c773f..00000000000 --- a/modules/adkernelAdnBidAdapter.js +++ /dev/null @@ -1,207 +0,0 @@ -import * as utils 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 DEFAULT_ADKERNEL_DSP_DOMAIN = 'tag.adkernel.com'; -const DEFAULT_MIMES = ['video/mp4', 'video/webm', 'application/x-shockwave-flash', 'application/javascript']; -const DEFAULT_PROTOCOLS = [2, 3, 5, 6]; -const DEFAULT_APIS = [1, 2]; -const GVLID = 14; - -function isRtbDebugEnabled(refInfo) { - return refInfo.referer.indexOf('adk_debug=true') !== -1; -} - -function buildImp(bidRequest) { - let imp = { - id: bidRequest.bidId, - tagid: bidRequest.adUnitCode - }; - let mediaType; - let bannerReq = utils.deepAccess(bidRequest, `mediaTypes.banner`); - let videoReq = utils.deepAccess(bidRequest, `mediaTypes.video`); - if (bannerReq) { - let sizes = canonicalizeSizesArray(bannerReq.sizes); - imp.banner = { - format: utils.parseSizesInput(sizes) - }; - mediaType = BANNER; - } else if (videoReq) { - let size = canonicalizeSizesArray(videoReq.playerSize)[0]; - imp.video = { - w: size[0], - h: size[1], - mimes: videoReq.mimes || DEFAULT_MIMES, - protocols: videoReq.protocols || DEFAULT_PROTOCOLS, - api: videoReq.api || DEFAULT_APIS - }; - mediaType = VIDEO; - } - let bidFloor = getBidFloor(bidRequest, mediaType, '*'); - if (bidFloor) { - imp.bidfloor = bidFloor; - } - return imp; -} - -/** - * Convert input array of sizes to canonical form Array[Array[Number]] - * @param sizes - * @return Array[Array[Number]] - */ -function canonicalizeSizesArray(sizes) { - if (sizes.length === 2 && !utils.isArray(sizes[0])) { - return [sizes]; - } - return sizes; -} - -function buildRequestParams(tags, bidderRequest) { - let {auctionId, gdprConsent, uspConsent, transactionId, refererInfo} = bidderRequest; - let req = { - id: auctionId, - tid: transactionId, - site: buildSite(refererInfo), - imp: tags - }; - if (gdprConsent) { - if (gdprConsent.gdprApplies !== undefined) { - utils.deepSetValue(req, 'user.gdpr', ~~gdprConsent.gdprApplies); - } - if (gdprConsent.consentString !== undefined) { - utils.deepSetValue(req, 'user.consent', gdprConsent.consentString); - } - } - if (uspConsent) { - utils.deepSetValue(req, 'user.us_privacy', uspConsent); - } - if (config.getConfig('coppa')) { - utils.deepSetValue(req, 'user.coppa', 1); - } - return req; -} - -function buildSite(refInfo) { - let loc = utils.parseUrl(refInfo.referer); - let result = { - page: `${loc.protocol}://${loc.hostname}${loc.pathname}`, - secure: ~~(loc.protocol === 'https') - }; - if (self === top && document.referrer) { - result.ref = document.referrer; - } - let keywords = document.getElementsByTagName('meta')['keywords']; - if (keywords && keywords.content) { - result.keywords = keywords.content; - } - return result; -} - -function buildBid(tag) { - let bid = { - requestId: tag.impid, - bidderCode: spec.code, - cpm: tag.bid, - width: tag.w, - height: tag.h, - creativeId: tag.crid, - currency: 'USD', - ttl: 720, - netRevenue: true - }; - if (tag.tag) { - bid.ad = tag.tag; - bid.mediaType = BANNER; - } else if (tag.vast_url) { - bid.vastUrl = tag.vast_url; - bid.mediaType = VIDEO; - } - return bid; -} - -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}); - if (typeof floorInfo === 'object' && floorInfo.currency === 'USD' && !isNaN(parseFloat(floorInfo.floor))) { - floor = parseFloat(floorInfo.floor); - } - } - return floor; -} - -export const spec = { - code: 'adkernelAdn', - gvlid: GVLID, - supportedMediaTypes: [BANNER, VIDEO], - aliases: ['engagesimply'], - - isBidRequestValid: function(bidRequest) { - return 'params' in bidRequest && - (typeof bidRequest.params.host === 'undefined' || typeof bidRequest.params.host === 'string') && - typeof bidRequest.params.pubId === 'number' && - 'mediaTypes' in bidRequest && - ('banner' in bidRequest.mediaTypes || 'video' in bidRequest.mediaTypes); - }, - - buildRequests: function(bidRequests, bidderRequest) { - let dispatch = bidRequests.map(buildImp) - .reduce((acc, curr, index) => { - let bidRequest = bidRequests[index]; - let pubId = bidRequest.params.pubId; - let host = bidRequest.params.host || DEFAULT_ADKERNEL_DSP_DOMAIN; - acc[host] = acc[host] || {}; - acc[host][pubId] = acc[host][pubId] || []; - acc[host][pubId].push(curr); - return acc; - }, {}); - - let requests = []; - Object.keys(dispatch).forEach(host => { - Object.keys(dispatch[host]).forEach(pubId => { - let request = buildRequestParams(dispatch[host][pubId], bidderRequest); - requests.push({ - method: 'POST', - url: `https://${host}/tag?account=${pubId}&pb=1${isRtbDebugEnabled(bidderRequest.refererInfo) ? '&debug=1' : ''}`, - data: JSON.stringify(request) - }) - }); - }); - return requests; - }, - - interpretResponse: function(serverResponse) { - let response = serverResponse.body; - if (!response.tags) { - return []; - } - if (response.debug) { - utils.logInfo(`ADKERNEL DEBUG:\n${response.debug}`); - } - return response.tags.map(buildBid); - }, - - getUserSyncs: function(syncOptions, serverResponses) { - if (!serverResponses || serverResponses.length === 0) { - return []; - } - if (syncOptions.iframeEnabled) { - return buildSyncs(serverResponses, 'syncpages', 'iframe'); - } else if (syncOptions.pixelEnabled) { - return buildSyncs(serverResponses, 'syncpixels', 'image'); - } else { - return []; - } - } -}; - -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})); -} - -registerBidder(spec); diff --git a/modules/adkernelAdnBidAdapter.md b/modules/adkernelAdnBidAdapter.md deleted file mode 100644 index c536ee1438c..00000000000 --- a/modules/adkernelAdnBidAdapter.md +++ /dev/null @@ -1,50 +0,0 @@ -# Overview - -``` -Module Name: AdKernel ADN Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid-dev@adkernel.com -``` - -# Description - -Connects to AdKernel Ad Delivery Network -Banner and video formats are supported. - - -# Test Parameters -``` -var adUnits = [{ - code: 'banner-ad-div', - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [300, 200] // banner sizes - ], - } - }, - bids: [{ - bidder: 'adkernelAdn', - params: { - pubId: 50357, - host: 'dsp-staging.adkernel.com' - } - }] -}, { - code: 'video-ad-player', - mediaTypes: { - video: { - context: 'instream', // or 'outstream' - playerSize: [640, 480] // video player size - } - }, - bids: [{ - bidder: 'adkernelAdn', - params: { - pubId: 50357, - host: 'dsp-staging.adkernel.com' - } - }] -}]; -``` diff --git a/modules/adkernelBidAdapter.js b/modules/adkernelBidAdapter.js deleted file mode 100644 index e4b04a27d42..00000000000 --- a/modules/adkernelBidAdapter.js +++ /dev/null @@ -1,495 +0,0 @@ -import * as utils from '../src/utils.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import find from 'core-js-pure/features/array/find.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import {config} from '../src/config.js'; - -/* - * In case you're AdKernel whitelable platform's client who needs branded adapter to - * work with Adkernel platform - DO NOT COPY THIS ADAPTER UNDER NEW NAME - * - * Please contact prebid@adkernel.com and we'll add your adapter as an alias. - */ - -const VIDEO_TARGETING = Object.freeze(['mimes', 'minduration', 'maxduration', 'protocols', - 'startdelay', 'linearity', 'boxingallowed', 'playbackmethod', 'delivery', - 'pos', 'api', 'ext']); -const VERSION = '1.6'; -const SYNC_IFRAME = 1; -const SYNC_IMAGE = 2; -const SYNC_TYPES = Object.freeze({ - 1: 'iframe', - 2: 'image' -}); -const GVLID = 14; - -const NATIVE_MODEL = [ - {name: 'title', assetType: 'title'}, - {name: 'icon', assetType: 'img', type: 1}, - {name: 'image', assetType: 'img', type: 3}, - {name: 'body', assetType: 'data', type: 2}, - {name: 'body2', assetType: 'data', type: 10}, - {name: 'sponsoredBy', assetType: 'data', type: 1}, - {name: 'phone', assetType: 'data', type: 8}, - {name: 'address', assetType: 'data', type: 9}, - {name: 'price', assetType: 'data', type: 6}, - {name: 'salePrice', assetType: 'data', type: 7}, - {name: 'cta', assetType: 'data', type: 12}, - {name: 'rating', assetType: 'data', type: 3}, - {name: 'downloads', assetType: 'data', type: 5}, - {name: 'likes', assetType: 'data', type: 4}, - {name: 'displayUrl', assetType: 'data', type: 11} -]; - -const NATIVE_INDEX = NATIVE_MODEL.reduce((acc, val, idx) => { - acc[val.name] = {id: idx, ...val}; - return acc; -}, {}); - -/** - * Adapter for requesting bids from AdKernel white-label display platform - */ -export const spec = { - code: 'adkernel', - gvlid: GVLID, - aliases: [ - {code: 'headbidding'}, - {code: 'adsolut'}, - {code: 'oftmediahb'}, - {code: 'audiencemedia'}, - {code: 'waardex_ak'}, - {code: 'roqoon'}, - {code: 'andbeyond'}, - {code: 'adbite'}, - {code: 'houseofpubs'}, - {code: 'torchad'}, - {code: 'stringads'}, - {code: 'bcm'}, - {code: 'engageadx'}, - {code: 'converge_digital', gvlid: 248}, - {code: 'adomega'} - ], - supportedMediaTypes: [BANNER, VIDEO, NATIVE], - - /** - * Validates bid request for adunit - * @param bidRequest {BidRequest} - * @returns {boolean} - */ - isBidRequestValid: function (bidRequest) { - return 'params' in bidRequest && - typeof bidRequest.params.host !== 'undefined' && - 'zoneId' in bidRequest.params && - !isNaN(Number(bidRequest.params.zoneId)) && - bidRequest.params.zoneId > 0 && - bidRequest.mediaTypes && - (bidRequest.mediaTypes.banner || bidRequest.mediaTypes.video || (bidRequest.mediaTypes.native && validateNativeAdUnit(bidRequest.mediaTypes.native))); - }, - - /** - * Builds http request for each unique combination of adkernel host/zone - * @param bidRequests {BidRequest[]} - * @param bidderRequest {BidderRequest} - * @returns {ServerRequest[]} - */ - buildRequests: function (bidRequests, bidderRequest) { - let impDispatch = dispatchImps(bidRequests, bidderRequest.refererInfo); - let requests = []; - let schain = bidRequests[0].schain; - Object.keys(impDispatch).forEach(host => { - Object.keys(impDispatch[host]).forEach(zoneId => { - const request = buildRtbRequest(impDispatch[host][zoneId], bidderRequest, schain); - requests.push({ - method: 'POST', - url: `https://${host}/hb?zone=${zoneId}&v=${VERSION}`, - data: JSON.stringify(request) - }); - }); - }); - return requests; - }, - - /** - * Parse response from adkernel backend - * @param serverResponse {ServerResponse} - * @param serverRequest {ServerRequest} - * @returns {Bid[]} - */ - interpretResponse: function (serverResponse, serverRequest) { - let response = serverResponse.body; - if (!response.seatbid) { - return []; - } - - let rtbRequest = JSON.parse(serverRequest.data); - let rtbBids = response.seatbid - .map(seatbid => seatbid.bid) - .reduce((a, b) => a.concat(b), []); - - return rtbBids.map(rtbBid => { - let imp = find(rtbRequest.imp, imp => imp.id === rtbBid.impid); - let prBid = { - requestId: rtbBid.impid, - cpm: rtbBid.price, - creativeId: rtbBid.crid, - currency: response.cur || 'USD', - ttl: 360, - netRevenue: true - }; - if ('banner' in imp) { - prBid.mediaType = BANNER; - prBid.width = rtbBid.w; - prBid.height = rtbBid.h; - prBid.ad = formatAdMarkup(rtbBid); - } else if ('video' in imp) { - prBid.mediaType = VIDEO; - prBid.vastUrl = rtbBid.nurl; - prBid.width = imp.video.w; - prBid.height = imp.video.h; - } else if ('native' in imp) { - prBid.mediaType = NATIVE; - prBid.native = buildNativeAd(JSON.parse(rtbBid.adm)); - } - if (utils.isStr(rtbBid.dealid)) { - prBid.dealId = rtbBid.dealid; - } - if (utils.isArray(rtbBid.adomain)) { - utils.deepSetValue(prBid, 'meta.advertiserDomains', rtbBid.adomain); - } - if (utils.isArray(rtbBid.cat)) { - utils.deepSetValue(prBid, 'meta.secondaryCatIds', rtbBid.cat); - } - if (utils.isPlainObject(rtbBid.ext)) { - if (utils.isNumber(rtbBid.ext.advertiser_id)) { - utils.deepSetValue(prBid, 'meta.advertiserId', rtbBid.ext.advertiser_id); - } - if (utils.isStr(rtbBid.ext.advertiser_name)) { - utils.deepSetValue(prBid, 'meta.advertiserName', rtbBid.ext.advertiser_name); - } - if (utils.isStr(rtbBid.ext.agency_name)) { - utils.deepSetValue(prBid, 'meta.agencyName', rtbBid.ext.agency_name); - } - } - - return prBid; - }); - }, - - /** - * Extracts user-syncs information from server response - * @param syncOptions {SyncOptions} - * @param serverResponses {ServerResponse[]} - * @returns {UserSync[]} - */ - getUserSyncs: function (syncOptions, serverResponses) { - if (!serverResponses || serverResponses.length === 0 || (!syncOptions.iframeEnabled && !syncOptions.pixelEnabled)) { - return []; - } - 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})); - } -}; - -registerBidder(spec); - -/** - * Dispatch impressions by ad network host and zone - * @param bidRequests {BidRequest[]} - * @param refererInfo {refererInfo} - */ -function dispatchImps(bidRequests, refererInfo) { - let secure = (refererInfo && refererInfo.referer.indexOf('https:') === 0); - return bidRequests.map(bidRequest => buildImp(bidRequest, secure)) - .reduce((acc, curr, index) => { - let bidRequest = bidRequests[index]; - let {zoneId, host} = bidRequest.params; - acc[host] = acc[host] || {}; - acc[host][zoneId] = acc[host][zoneId] || []; - acc[host][zoneId].push(curr); - return acc; - }, {}); -} - -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}); - if (typeof floorInfo === 'object' && floorInfo.currency === 'USD' && !isNaN(parseFloat(floorInfo.floor))) { - floor = parseFloat(floorInfo.floor); - } - } - return floor; -} - -/** - * Builds rtb imp object for single adunit - * @param bidRequest {BidRequest} - * @param secure {boolean} - */ -function buildImp(bidRequest, secure) { - const imp = { - 'id': bidRequest.bidId, - 'tagid': bidRequest.adUnitCode - }; - var mediaType; - var sizes = []; - - if (utils.deepAccess(bidRequest, 'mediaTypes.banner')) { - sizes = utils.getAdUnitSizes(bidRequest); - imp.banner = { - format: sizes.map(wh => utils.parseGPTSingleSizeArrayToRtbSize(wh)), - topframe: 0 - }; - mediaType = BANNER; - } else if (utils.deepAccess(bidRequest, 'mediaTypes.video')) { - let video = utils.deepAccess(bidRequest, 'mediaTypes.video'); - imp.video = {}; - if (video.playerSize) { - sizes = video.playerSize[0]; - imp.video = Object.assign(imp.video, utils.parseGPTSingleSizeArrayToRtbSize(sizes) || {}); - } - if (bidRequest.params.video) { - Object.keys(bidRequest.params.video) - .filter(key => includes(VIDEO_TARGETING, key)) - .forEach(key => imp.video[key] = bidRequest.params.video[key]); - } - mediaType = VIDEO; - } else if (utils.deepAccess(bidRequest, 'mediaTypes.native')) { - let nativeRequest = buildNativeRequest(bidRequest.mediaTypes.native); - imp.native = { - ver: '1.1', - request: JSON.stringify(nativeRequest) - }; - mediaType = NATIVE; - } else { - throw new Error('Unsupported bid received'); - } - let floor = getBidFloor(bidRequest, mediaType, sizes); - if (floor) { - imp.bidfloor = floor; - } - if (secure) { - imp.secure = 1; - } - return imp; -} - -/** - * Builds native request from native adunit - */ -function buildNativeRequest(nativeReq) { - let request = {ver: '1.1', assets: []}; - for (let k of Object.keys(nativeReq)) { - let v = nativeReq[k]; - let desc = NATIVE_INDEX[k]; - if (desc === undefined) { - continue; - } - let assetRoot = { - id: desc.id, - required: ~~v.required, - }; - if (desc.assetType === 'img') { - assetRoot[desc.assetType] = buildImageAsset(desc, v); - } else if (desc.assetType === 'data') { - assetRoot.data = utils.cleanObj({type: desc.type, len: v.len}); - } else if (desc.assetType === 'title') { - assetRoot.title = {len: v.len || 90}; - } else { - return; - } - request.assets.push(assetRoot); - } - return request; -} - -/** - * Builds image asset request - */ -function buildImageAsset(desc, val) { - let img = { - type: desc.type - }; - if (val.sizes) { - [img.w, img.h] = val.sizes; - } else if (val.aspect_ratios) { - img.wmin = val.aspect_ratios[0].min_width; - img.hmin = val.aspect_ratios[0].min_height; - } - return utils.cleanObj(img); -} - -/** - * Checks if configuration allows specified sync method - * @param syncRule {Object} - * @param bidderCode {string} - * @returns {boolean} - */ -function isSyncMethodAllowed(syncRule, bidderCode) { - if (!syncRule) { - return false; - } - let bidders = utils.isArray(syncRule.bidders) ? syncRule.bidders : [bidderCode]; - let rule = syncRule.filter === 'include'; - return utils.contains(bidders, bidderCode) === rule; -} - -/** - * Get preferred user-sync method based on publisher configuration - * @param bidderCode {string} - * @returns {number|undefined} - */ -function getAllowedSyncMethod(bidderCode) { - if (!config.getConfig('userSync.syncEnabled')) { - return; - } - let filterConfig = config.getConfig('userSync.filterSettings'); - if (isSyncMethodAllowed(filterConfig.all, bidderCode) || isSyncMethodAllowed(filterConfig.iframe, bidderCode)) { - return SYNC_IFRAME; - } else if (isSyncMethodAllowed(filterConfig.image, bidderCode)) { - return SYNC_IMAGE; - } -} - -/** - * Builds complete rtb request - * @param imps {Object} Collection of rtb impressions - * @param bidderRequest {BidderRequest} - * @param schain {Object=} Supply chain config - * @return {Object} Complete rtb request - */ -function buildRtbRequest(imps, bidderRequest, schain) { - let {bidderCode, gdprConsent, auctionId, refererInfo, timeout, uspConsent} = bidderRequest; - let coppa = config.getConfig('coppa'); - let req = { - 'id': auctionId, - 'imp': imps, - 'site': createSite(refererInfo), - 'at': 1, - 'device': { - 'ip': 'caller', - 'ipv6': 'caller', - 'ua': 'caller', - 'js': 1, - 'language': getLanguage() - }, - 'tmax': parseInt(timeout) - }; - if (utils.getDNT()) { - req.device.dnt = 1; - } - if (gdprConsent) { - if (gdprConsent.gdprApplies !== undefined) { - utils.deepSetValue(req, 'regs.ext.gdpr', ~~gdprConsent.gdprApplies); - } - if (gdprConsent.consentString !== undefined) { - utils.deepSetValue(req, 'user.ext.consent', gdprConsent.consentString); - } - } - if (uspConsent) { - utils.deepSetValue(req, 'regs.ext.us_privacy', uspConsent); - } - if (coppa) { - utils.deepSetValue(req, 'regs.coppa', 1); - } - let syncMethod = getAllowedSyncMethod(bidderCode); - if (syncMethod) { - utils.deepSetValue(req, 'ext.adk_usersync', syncMethod); - } - if (schain) { - utils.deepSetValue(req, 'source.ext.schain', schain); - } - return req; -} - -/** - * Get browser language - * @returns {String} - */ -function getLanguage() { - const language = navigator.language ? 'language' : 'userLanguage'; - return navigator[language].split('-')[0]; -} - -/** - * Creates site description object - */ -function createSite(refInfo) { - let url = utils.parseUrl(refInfo.referer); - let site = { - 'domain': url.hostname, - 'page': `${url.protocol}://${url.hostname}${url.pathname}` - }; - if (self === top && document.referrer) { - site.ref = document.referrer; - } - let keywords = document.getElementsByTagName('meta')['keywords']; - if (keywords && keywords.content) { - site.keywords = keywords.content; - } - return site; -} - -/** - * Format creative with optional nurl call - * @param bid rtb Bid object - */ -function formatAdMarkup(bid) { - let adm = bid.adm; - if ('nurl' in bid) { - adm += utils.createTrackPixelHtml(`${bid.nurl}&px=1`); - } - return adm; -} - -/** - * Basic validates to comply with platform requirements - */ -function validateNativeAdUnit(adUnit) { - return validateNativeImageSize(adUnit.image) && validateNativeImageSize(adUnit.icon) && - !utils.deepAccess(adUnit, 'privacyLink.required') && // not supported yet - !utils.deepAccess(adUnit, 'privacyIcon.required'); // not supported yet -} - -/** - * Validates image asset size definition - */ -function validateNativeImageSize(img) { - if (!img) { - return true; - } - if (img.sizes) { - return utils.isArrayOfNums(img.sizes, 2); - } - if (utils.isArray(img.aspect_ratios)) { - return img.aspect_ratios.length > 0 && img.aspect_ratios[0].min_height && img.aspect_ratios[0].min_width; - } - return true; -} - -/** - * Creates native ad for native 1.1 response - */ -function buildNativeAd(nativeResp) { - const {assets, link, imptrackers, jstracker, privacy} = nativeResp.native; - let nativeAd = { - clickUrl: link.url, - impressionTrackers: imptrackers, - javascriptTrackers: jstracker ? [jstracker] : undefined, - privacyLink: privacy, - }; - utils._each(assets, asset => { - let assetName = NATIVE_MODEL[asset.id].name; - let assetType = NATIVE_MODEL[asset.id].assetType; - nativeAd[assetName] = asset[assetType].text || asset[assetType].value || utils.cleanObj({ - url: asset[assetType].url, - width: asset[assetType].w, - height: asset[assetType].h - }); - }); - return utils.cleanObj(nativeAd); -} diff --git a/modules/adkernelBidAdapter.md b/modules/adkernelBidAdapter.md deleted file mode 100644 index b3854d721ad..00000000000 --- a/modules/adkernelBidAdapter.md +++ /dev/null @@ -1,79 +0,0 @@ -# Overview - -``` -Module Name: AdKernel Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid-dev@adkernel.com -``` - -# Description - -Connects to AdKernel whitelabel platform. -Banner, video and native formats are supported. - - -# Test Parameters -``` -var adUnits = [{ - code: 'banner-ad-div', - mediaTypes: { - banner: { - sizes: [[300, 250]], // banner size - } - }, - bids: [{ - bidder: 'adkernel', - params: { - zoneId: '30164', //required parameter - host: 'cpm.metaadserving.com' //required parameter - } - }] -}, { - code: 'video-ad-player', - mediaTypes: { - video: { - context: 'instream', // or 'outstream' - playerSize: [640, 480] // video player size - } - }, - bids: [{ - bidder: 'adkernel', - params: { - zoneId: '30164', //required parameter - host: 'cpm.metaadserving.com' //required parameter - } - }] -}, { - code: 'native-ad', - mediaTypes: { - native: { - title: { - required: true - }, - body: { - required: true - }, - icon: { - required: true, - size: [64, 64] - }, - sponsoredBy: { - required: true - }, - clickUrl: { - required: true - }, - displayUrl: { - required: false - } - } - }, - bids: [{ - bidder: 'adkernel', - params: { - host: 'cpm.metaadserving.com', - zoneId: 30164 - } - }] -}]; -``` diff --git a/modules/adliveBidAdapter.js b/modules/adliveBidAdapter.js deleted file mode 100644 index 4c703628c4d..00000000000 --- a/modules/adliveBidAdapter.js +++ /dev/null @@ -1,69 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'adlive'; -const ENDPOINT_URL = 'https://api.publishers.adlive.io/get?pbjs=1'; - -const CURRENCY = 'USD'; -const TIME_TO_LIVE = 360; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - - isBidRequestValid: function(bid) { - return !!(bid.params.hashes && utils.isArray(bid.params.hashes)); - }, - - buildRequests: function(validBidRequests) { - let requests = []; - - utils._each(validBidRequests, function(bid) { - requests.push({ - method: 'POST', - url: ENDPOINT_URL, - options: { - contentType: 'application/json', - withCredentials: true - }, - data: JSON.stringify({ - transaction_id: bid.bidId, - hashes: utils.getBidIdParameter('hashes', bid.params) - }), - bidId: bid.bidId - }); - }); - - return requests; - }, - - interpretResponse: function(serverResponse, bidRequest) { - try { - const response = serverResponse.body; - const bidResponses = []; - - utils._each(response, function(bidResponse) { - if (!bidResponse.is_passback) { - bidResponses.push({ - requestId: bidRequest.bidId, - cpm: bidResponse.price, - width: bidResponse.size[0], - height: bidResponse.size[1], - creativeId: bidResponse.hash, - currency: CURRENCY, - netRevenue: false, - ttl: TIME_TO_LIVE, - ad: bidResponse.content - }); - } - }); - - return bidResponses; - } catch (err) { - utils.logError(err); - return []; - } - } -}; -registerBidder(spec); diff --git a/modules/adliveBidAdapter.md b/modules/adliveBidAdapter.md deleted file mode 100644 index 4fc6a112e82..00000000000 --- a/modules/adliveBidAdapter.md +++ /dev/null @@ -1,28 +0,0 @@ -# Overview -``` -Module Name: Adlive Bid Adapter -Module Type: Bidder Adapter -Maintainer: traffic@adlive.io -``` - -# Description -Module that connects to Adlive's server for bids. -Currently module supports only banner mediaType. - -# Test Parameters -``` - var adUnits = [{ - code: '/test/div', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [{ - bidder: 'adlive', - params: { - hashes: ['1e100887dd614b0909bf6c49ba7f69fdd1360437'] - } - }] - }]; -``` \ No newline at end of file diff --git a/modules/adlooxAnalyticsAdapter.js b/modules/adlooxAnalyticsAdapter.js deleted file mode 100644 index 3e92ae34004..00000000000 --- a/modules/adlooxAnalyticsAdapter.js +++ /dev/null @@ -1,288 +0,0 @@ -/** - * This module provides [Adloox]{@link https://www.adloox.com/} Analytics - * The module will inject Adloox's verification JS tag alongside slot at bidWin - * @module modules/adlooxAnalyticsAdapter - */ - -import adapterManager from '../src/adapterManager.js'; -import adapter from '../src/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.json'; -import find from 'core-js-pure/features/array/find.js'; -import * as utils from '../src/utils.js'; - -const MODULE = 'adlooxAnalyticsAdapter'; - -const URL_JS = 'https://j.adlooxtracking.com/ads/js/tfav_adl_%%clientid%%.js'; - -const ADLOOX_VENDOR_ID = 93; - -const ADLOOX_MEDIATYPE = { - DISPLAY: 2, - VIDEO: 6 -}; - -const MACRO = {}; -MACRO['client'] = function(b, c) { - return c.client; -}; -MACRO['clientid'] = function(b, c) { - return c.clientid; -}; -MACRO['tagid'] = function(b, c) { - return c.tagid; -}; -MACRO['platformid'] = function(b, c) { - return c.platformid; -}; -MACRO['targetelt'] = function(b, c) { - return c.toselector(b); -}; -MACRO['creatype'] = function(b, c) { - return b.mediaType == 'video' ? ADLOOX_MEDIATYPE.VIDEO : ADLOOX_MEDIATYPE.DISPLAY; -}; -MACRO['pbAdSlot'] = function(b, c) { - const adUnit = find(auctionManager.getAdUnits(), a => b.adUnitCode === a.code); - return utils.deepAccess(adUnit, 'fpd.context.pbAdSlot') || utils.getGptSlotInfoForAdUnitCode(b.adUnitCode).gptSlot || b.adUnitCode; -}; - -const PARAMS_DEFAULT = { - 'id1': function(b) { return b.adUnitCode }, - 'id2': '%%pbAdSlot%%', - 'id3': function(b) { return b.bidder }, - 'id4': function(b) { return b.adId }, - 'id5': function(b) { return b.dealId }, - 'id6': function(b) { return b.creativeId }, - 'id7': function(b) { return b.size }, - 'id11': '$ADLOOX_WEBSITE' -}; - -const NOOP = function() {}; - -let analyticsAdapter = Object.assign(adapter({ analyticsType: 'endpoint' }), { - track({ eventType, args }) { - if (!analyticsAdapter[`handle_${eventType}`]) return; - - utils.logInfo(MODULE, 'track', eventType, args); - - analyticsAdapter[`handle_${eventType}`](args); - } -}); - -analyticsAdapter.context = null; - -analyticsAdapter.originEnableAnalytics = analyticsAdapter.enableAnalytics; -analyticsAdapter.enableAnalytics = function(config) { - analyticsAdapter.context = null; - - utils.logInfo(MODULE, 'config', config); - - if (!utils.isPlainObject(config.options)) { - utils.logError(MODULE, 'missing options'); - return; - } - if (!(config.options.js === undefined || utils.isStr(config.options.js))) { - utils.logError(MODULE, 'invalid js options value'); - return; - } - if (!(config.options.toselector === undefined || utils.isFn(config.options.toselector))) { - utils.logError(MODULE, 'invalid toselector options value'); - return; - } - if (!utils.isStr(config.options.client)) { - utils.logError(MODULE, 'invalid client options value'); - return; - } - if (!utils.isNumber(config.options.clientid)) { - utils.logError(MODULE, 'invalid clientid options value'); - return; - } - if (!utils.isNumber(config.options.tagid)) { - utils.logError(MODULE, 'invalid tagid options value'); - return; - } - if (!utils.isNumber(config.options.platformid)) { - utils.logError(MODULE, 'invalid platformid options value'); - return; - } - if (!(config.options.params === undefined || utils.isPlainObject(config.options.params))) { - utils.logError(MODULE, 'invalid params options value'); - return; - } - - analyticsAdapter.context = { - js: config.options.js || URL_JS, - toselector: config.options.toselector || function(bid) { - let code = utils.getGptSlotInfoForAdUnitCode(bid.adUnitCode).divId || bid.adUnitCode; - // https://mathiasbynens.be/notes/css-escapes - code = code.replace(/^\d/, '\\3$& '); - return `#${code}` - }, - client: config.options.client, - clientid: config.options.clientid, - tagid: config.options.tagid, - platformid: config.options.platformid, - params: [] - }; - - config.options.params = utils.mergeDeep({}, PARAMS_DEFAULT, config.options.params || {}); - Object - .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].forEach(v => analyticsAdapter.context.params.push([ k, v ])); - }); - - Object.keys(COMMAND_QUEUE).forEach(commandProcess); - - analyticsAdapter.originEnableAnalytics(config); -} - -analyticsAdapter.originDisableAnalytics = analyticsAdapter.disableAnalytics; -analyticsAdapter.disableAnalytics = function() { - analyticsAdapter.context = null; - - analyticsAdapter.originDisableAnalytics(); -} - -analyticsAdapter.url = function(url, args, bid) { - // utils.formatQS outputs PHP encoded querystrings... (╯°□°)╯ ┻━┻ - function a2qs(a) { - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent - function fixedEncodeURIComponent(str) { - return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { - return '%' + c.charCodeAt(0).toString(16); - }); - } - - const args = []; - let n = a.length; - while (n-- > 0) { - if (!(a[n][1] === undefined || a[n][1] === null || a[n][1] === false)) { - args.unshift(fixedEncodeURIComponent(a[n][0]) + (a[n][1] !== true ? ('=' + fixedEncodeURIComponent(a[n][1])) : '')); - } - } - - return args.join('&'); - } - - const macros = (str) => { - return str.replace(/%%([a-z]+)%%/gi, (match, p1) => MACRO[p1] ? MACRO[p1](bid, analyticsAdapter.context) : match); - }; - - url = macros(url); - args = args || []; - - let n = args.length; - while (n-- > 0) { - if (utils.isFn(args[n][1])) { - try { - args[n][1] = args[n][1](bid); - } catch (_) { - utils.logError(MODULE, 'macro', args[n][0], _.message); - args[n][1] = `ERROR: ${_.message}`; - } - } - if (utils.isStr(args[n][1])) { - args[n][1] = macros(args[n][1]); - } - } - - return url + a2qs(args); -} - -analyticsAdapter[`handle_${EVENTS.AUCTION_END}`] = function(auctionDetails) { - if (!(auctionDetails.auctionStatus == AUCTION_COMPLETED && auctionDetails.bidsReceived.length > 0)) return; - analyticsAdapter[`handle_${EVENTS.AUCTION_END}`] = NOOP; - - utils.logMessage(MODULE, 'preloading verification JS'); - - const uri = utils.parseUrl(analyticsAdapter.url(`${analyticsAdapter.context.js}#`)); - - const link = document.createElement('link'); - link.setAttribute('href', `${uri.protocol}://${uri.host}${uri.pathname}`); - link.setAttribute('rel', 'preload'); - link.setAttribute('as', 'script'); - utils.insertElement(link); -} - -analyticsAdapter[`handle_${EVENTS.BID_WON}`] = function(bid) { - const sl = analyticsAdapter.context.toselector(bid); - let el; - try { - el = document.querySelector(sl); - } catch (_) { } - if (!el) { - utils.logWarn(MODULE, `unable to find ad unit code '${bid.adUnitCode}' slot using selector '${sl}' (use options.toselector to change), ignoring`); - return; - } - - utils.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%%' ] - ]); - - loadExternalScript(analyticsAdapter.url(`${analyticsAdapter.context.js}#`, params, bid), 'adloox'); -} - -adapterManager.registerAnalyticsAdapter({ - adapter: analyticsAdapter, - code: 'adloox', - gvlid: ADLOOX_VENDOR_ID -}); - -export default analyticsAdapter; - -// src/events.js does not support custom events or handle races... (╯°□°)╯ ┻━┻ -const COMMAND_QUEUE = {}; -export const COMMAND = { - CONFIG: 'config', - URL: 'url', - TRACK: 'track' -}; -export function command(cmd, data, callback0) { - const cid = utils.getUniqueIdentifierStr(); - const callback = function() { - delete COMMAND_QUEUE[cid]; - if (callback0) callback0.apply(null, arguments); - }; - COMMAND_QUEUE[cid] = { cmd, data, callback }; - if (analyticsAdapter.context) commandProcess(cid); -} -function commandProcess(cid) { - const { cmd, data, callback } = COMMAND_QUEUE[cid]; - - utils.logInfo(MODULE, 'command', cmd, data); - - switch (cmd) { - case COMMAND.CONFIG: - const response = { - client: analyticsAdapter.context.client, - clientid: analyticsAdapter.context.clientid, - tagid: analyticsAdapter.context.tagid, - platformid: analyticsAdapter.context.platformid - }; - callback(response); - break; - case COMMAND.URL: - if (data.ids) data.args = data.args.concat(analyticsAdapter.context.params.filter(p => /^id([1-9]|10)$/.test(p[0]))); // not >10 - callback(analyticsAdapter.url(data.url, data.args, data.bid)); - break; - case COMMAND.TRACK: - analyticsAdapter.track(data); - callback(); // drain queue - break; - default: - utils.logWarn(MODULE, 'command unknown', cmd); - // do not callback as arguments are unknown and to aid debugging - } -} diff --git a/modules/adlooxAnalyticsAdapter.md b/modules/adlooxAnalyticsAdapter.md deleted file mode 100644 index 0ca67f937f6..00000000000 --- a/modules/adlooxAnalyticsAdapter.md +++ /dev/null @@ -1,146 +0,0 @@ -# Overview - - Module Name: Adloox Analytics Adapter - Module Type: Analytics Adapter - Maintainer: technique@adloox.com - -# Description - -Analytics adapter for adloox.com. Contact adops@adloox.com for information. - -This module can be used to track: - - * Display - * Native - * Video (see below for further instructions) - -The adapter adds an HTML ``; - trackedAd += tracker; - }); - } - - return trackedAd; -} - -function getScreenParams() { - return `${window.screen.width}x${window.screen.height}@${window.devicePixelRatio}`; -} - -function getBids(bids) { - const bidArr = bids.map(bid => { - const bidId = bid.bidId; - - let mediaType = ''; - const mediaTypes = Object.keys(bid.mediaTypes) - switch (mediaTypes[0]) { - case 'video': - mediaType = 'v'; - break; - - case 'native': - mediaType = 'n'; - break; - - case 'audio': - mediaType = 'a'; - break; - - default: - mediaType = 'b'; - break; - } - - let adUnitCode = `,c=${bid.adUnitCode}`; - if (bid.params.code) { - adUnitCode = `,c=${encodeURIComponent(bid.params.code)}`; - } - if (bid.params.adunitId) { - adUnitCode = `,u=${encodeURIComponent(bid.params.adunitId)}`; - } - - return `${bidId}:t=${mediaType},s=${serializeSizes(bid.sizes)}${adUnitCode}`; - }); - - return bidArr.join(';'); -}; - -function getEndpointsGroups(bidRequests) { - let endpoints = []; - const getEndpoint = bid => { - const publisherId = bid.params.publisherId || config.getConfig('apstream.publisherId'); - const isTestConfig = bid.params.test || config.getConfig('apstream.test'); - - if (isTestConfig) { - return `https://mock-bapi.userreport.com/v2/${publisherId}/bid`; - } - - if (bid.params.endpoint) { - return `${bid.params.endpoint}${publisherId}/bid`; - } - - return `https://bapi.userreport.com/v2/${publisherId}/bid`; - } - bidRequests.forEach(bid => { - const endpoint = getEndpoint(bid); - const exist = endpoints.filter(item => item.endpoint.indexOf(endpoint) > -1)[0]; - if (exist) { - exist.bids.push(bid); - } else { - endpoints.push({ - endpoint: endpoint, - bids: [bid] - }); - } - }); - - return endpoints; -} - -function isBidRequestValid(bid) { - const publisherId = config.getConfig('apstream.publisherId'); - const isPublisherIdExist = !!(publisherId || bid.params.publisherId); - const isOneMediaType = Object.keys(bid.mediaTypes).length === 1; - - return isPublisherIdExist && isOneMediaType; -} - -function buildRequests(bidRequests, bidderRequest) { - const data = { - med: encodeURIComponent(window.location.href), - auid: bidderRequest.auctionId, - ref: document.referrer, - dnt: utils.getDNT() ? 1 : 0, - sr: getScreenParams() - }; - - const consentData = getRawConsentString(bidderRequest.gdprConsent); - data.iab_consent = consentData; - - const options = { - withCredentials: true - }; - - const isConsent = getIabConsentString(bidderRequest); - const noDsu = config.getConfig('apstream.noDsu'); - if (!isConsent || noDsu) { - data.dsu = ''; - } else { - data.dsu = dsuModule.readOrCreateDsu(); - } - - if (!isConsent || isConsent === 'disabled') { - options.withCredentials = false; - } - - const endpoints = getEndpointsGroups(bidRequests); - const serverRequests = endpoints.map(item => ({ - method: 'GET', - url: item.endpoint, - data: { - ...data, - bids: getBids(item.bids), - rnd: Math.random() - }, - options: options - })); - - return serverRequests; -} - -function interpretResponse(serverResponse) { - let bidResponses = serverResponse && serverResponse.body; - - if (!bidResponses || !bidResponses.length) { - return []; - } - - return bidResponses.map(x => ({ - requestId: x.bidId, - cpm: x.bidDetails.cpm, - width: x.bidDetails.width, - height: x.bidDetails.height, - creativeId: x.bidDetails.creativeId, - currency: x.bidDetails.currency || 'USD', - netRevenue: x.bidDetails.netRevenue, - dealId: x.bidDetails.dealId, - ad: injectPixels(x.bidDetails.ad, x.bidDetails.noticeUrls, x.bidDetails.impressionScripts), - ttl: x.bidDetails.ttl, - })); -} - -export const spec = { - code: CONSTANTS.BIDDER_CODE, - gvlid: CONSTANTS.GVLID, - isBidRequestValid: isBidRequestValid, - buildRequests: buildRequests, - interpretResponse: interpretResponse -} - -registerBidder(spec); diff --git a/modules/apstreamBidAdapter.md b/modules/apstreamBidAdapter.md deleted file mode 100644 index 6b87b33489a..00000000000 --- a/modules/apstreamBidAdapter.md +++ /dev/null @@ -1,111 +0,0 @@ -# Overview - -``` -Module Name: AP Stream Bidder Adapter -Module Type: Bidder Adapter -Maintainer: tech@audienceproject.com -gdpr_supported: true -tcf2_supported: true -``` - -# Description - -Module that connects to AP Stream source - -# Inherit from prebid.js -``` - var adUnits = [ - { - code: '/19968336/header-bid-tag-1', - mediaTypes: { // mandatory and should be only one - banner: { - sizes: [[920,180], [920, 130]] - } - }, - bids: [{ - bidder: 'apstream', - params: { - publisherId: STREAM_PIBLISHER_ID // mandatory - } - }] - } - ]; -``` - -# Explicit ad-unit code -``` - var website = null; - switch (location.hostname) { - case "site1.com": - website = "S1"; - break; - case "site2.com": - website = "S2"; - break; - } - - var adUnits = [ - { - code: '/19968336/header-bid-tag-1', - mediaTypes: { // mandatory and should be only one - banner: { - sizes: [[920,180], [920, 130]] - } - }, - bids: [{ - bidder: 'apstream', - params: { - publisherId: STREAM_PIBLISHER_ID, // mandatory - code: website + '_Leaderboard' - } - }] - } - ]; -``` - -# Explicit ad-unit ID -``` - var adUnits = [ - { - code: '/19968336/header-bid-tag-1', - mediaTypes: { // mandatory and should be only one - banner: { - sizes: [[920,180], [920, 130]] - } - }, - bids: [{ - bidder: 'apstream', - params: { - publisherId: STREAM_PIBLISHER_ID, // mandatory - adunitId: 1234 - } - }] - } - ]; -``` - -# DSU - -To disable DSU use config option: - -``` - pbjs.setConfig({ - apstream: { - noDsu: true - } - }); -``` - -To set `test` and `publisherId` parameters globally use config options (it can be overrided if set in specific bid): - -``` -pbjs.setBidderConfig({ - bidders: ["apstream"], - config: { - appstream: { - publisherId: '1234 - test: true - } - } -}); -``` diff --git a/modules/arteebeeBidAdapter.md b/modules/arteebeeBidAdapter.md deleted file mode 100644 index 4c178d722b1..00000000000 --- a/modules/arteebeeBidAdapter.md +++ /dev/null @@ -1,32 +0,0 @@ -# Overview - -``` -Module Name: Arteebee Bidder Adapter -Module Type: Bidder Adapter -Maintainer: jeffyecn@gmail.com -``` - -# Description - -Module that connects to Arteebee's demand source - -# Test Parameters -``` - var adUnits = [ - { - code: 'banner-ad-div', - sizes: [[300, 250]], - bids: [ - { - bidder: 'arteebee', - params: { - ssp: 'mock', - pub: 'prebidtest', - source: 'prebidtest', - test: true - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/astraoneBidAdapter.js b/modules/astraoneBidAdapter.js deleted file mode 100644 index 2fec3892d27..00000000000 --- a/modules/astraoneBidAdapter.js +++ /dev/null @@ -1,137 +0,0 @@ -import * as utils from '../src/utils.js' -import { registerBidder } from '../src/adapters/bidderFactory.js' -import { BANNER } from '../src/mediaTypes.js' - -const BIDDER_CODE = 'astraone'; -const SSP_ENDPOINT = 'https://ssp.astraone.io/auction/prebid'; -const TTL = 60; - -function buildBidRequests(validBidRequests) { - return utils._map(validBidRequests, function(validBidRequest) { - const params = validBidRequest.params; - const bidRequest = { - bidId: validBidRequest.bidId, - transactionId: validBidRequest.transactionId, - sizes: validBidRequest.sizes, - placement: params.placement, - placeId: params.placeId, - imageUrl: params.imageUrl - }; - - return bidRequest; - }) -} - -function buildBid(bidData) { - const bid = { - requestId: bidData.bidId, - cpm: bidData.price, - width: bidData.width, - height: bidData.height, - creativeId: bidData.content.seanceId, - currency: bidData.currency, - netRevenue: true, - meta: { - mediaType: BANNER, - }, - ttl: TTL, - content: bidData.content - }; - - bid.ad = wrapAd(bid, bidData); - - return bid; -} - -function getMediaTypeFromBid(bid) { - return bid.mediaTypes && Object.keys(bid.mediaTypes)[0] -} - -function wrapAd(bid, bidData) { - return ` - - - - - - - - -
- - - `; -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid(bid) { - return ( - getMediaTypeFromBid(bid) === BANNER && - !!bid.params.placeId && - !!bid.params.imageUrl && - !!bid.params.placement && - (bid.params.placement === 'inImage') - ); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests(validBidRequests, bidderRequest) { - const payload = { - url: bidderRequest.refererInfo.referer, - cmp: !!bidderRequest.gdprConsent, - bidRequests: buildBidRequests(validBidRequests) - }; - - if (payload.cmp) { - const gdprApplies = bidderRequest.gdprConsent.gdprApplies; - if (gdprApplies !== undefined) payload['ga'] = gdprApplies; - payload['cs'] = bidderRequest.gdprConsent.consentString; - } - - const payloadString = JSON.stringify(payload); - return { - method: 'POST', - url: SSP_ENDPOINT, - data: payloadString, - options: { - contentType: 'application/json' - } - } - }, - - /** - * Unpack the 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. - */ - interpretResponse: function(serverResponse) { - const bids = serverResponse.body && serverResponse.body.bids; - - return Array.isArray(bids) ? bids.map(bid => buildBid(bid)) : [] - } - -} -registerBidder(spec); diff --git a/modules/astraoneBidAdapter.md b/modules/astraoneBidAdapter.md deleted file mode 100644 index e090cfe1e54..00000000000 --- a/modules/astraoneBidAdapter.md +++ /dev/null @@ -1,202 +0,0 @@ -# Overview - - -**Module Name**: AstraOne Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: prebid@astraone.io - -# Description - -You can use this adapter to get a bid from AstraOne. -Please reach out to your AstraOne account team before using this plugin to get placeId. -The code below returns a demo ad. - -About us: https://astraone.io - -# Test Parameters -```js -var adUnits = [{ - code: 'test-div', - mediaTypes: { - banner: { - sizes: [1, 1], - } - }, - bids: [{ - bidder: "astraone", - params: { - placement: "inImage", - placeId: "5f477bf94d506ebe2c4240f3", - imageUrl: "https://creative.astraone.io/files/default_image-1-600x400.jpg" - } - }] -}]; -``` - -# Example page - -```html - - - - - Prebid.js Banner Example - - - - - - -

Prebid.js InImage Banner Test

- -
- - -
- - - -``` -# Example page with GPT - -```html - - - - - Prebid.js Banner gpt Example - - - - - - -

Prebid.js InImage Banner gpt Test

- -
- - - -
- - -``` diff --git a/modules/atomxBidAdapter.js b/modules/atomxBidAdapter.js deleted file mode 100644 index e9f15218c4c..00000000000 --- a/modules/atomxBidAdapter.js +++ /dev/null @@ -1,107 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'atomx'; - -function getDomain() { - var domain = ''; - - try { - if ((domain === '') && (window.top == window)) { - domain = window.location.href; - } - - if ((domain === '') && (window.top == window.parent)) { - domain = document.referrer; - } - - if (domain == '') { - var atomxt = 'atomxtest'; - - // It should be impossible to change the window.location.ancestorOrigins. - window.location.ancestorOrigins[0] = atomxt; - if (window.location.ancestorOrigins[0] != atomxt) { - var ancestorOrigins = window.location.ancestorOrigins; - - // If the length is 0 we are a javascript tag running in the main domain. - // But window.top != window or window.location.hostname is empty. - if (ancestorOrigins.length == 0) { - // This browser is so fucked up, just return an empty string. - return ''; - } - - // ancestorOrigins is an array where [0] is our own window.location - // and [length-1] is the top window.location. - domain = ancestorOrigins[ancestorOrigins.length - 1]; - } - } - } catch (unused) { - } - - if (domain === '') { - domain = document.referrer; - } - - if (domain === '') { - domain = window.location.href; - } - - return domain.substr(0, 512); -} - -export const spec = { - code: BIDDER_CODE, - - isBidRequestValid: function(bid) { - return bid.params && (!!bid.params.id); - }, - - buildRequests: function(validBidRequests) { - return validBidRequests.map(bidRequest => { - return { - method: 'GET', - url: 'https://p.ato.mx/placement', - data: { - v: 12, - id: bidRequest.params.id, - size: utils.parseSizesInput(bidRequest.sizes)[0], - prebid: bidRequest.bidId, - b: 0, - h: '7t3y9', - type: 'javascript', - screen: window.screen.width + 'x' + window.screen.height + 'x' + window.screen.colorDepth, - timezone: new Date().getTimezoneOffset(), - domain: getDomain(), - r: document.referrer.substr(0, 512), - }, - }; - }); - }, - - interpretResponse: function (serverResponse, bidRequest) { - const body = serverResponse.body; - const res = { - requestId: body.code, - cpm: body.cpm * 1000, - width: body.width, - height: body.height, - creativeId: body.creative_id, - currency: 'USD', - netRevenue: true, - ttl: 60, - }; - - if (body.adm) { - res.ad = body.adm; - } else { - res.adUrl = body.url; - } - - return [res]; - }, - - getUserSyncs: function(syncOptions, serverResponses) { - return []; - }, -}; -registerBidder(spec); diff --git a/modules/atomxBidAdapter.md b/modules/atomxBidAdapter.md deleted file mode 100644 index 7f32b12fdfe..00000000000 --- a/modules/atomxBidAdapter.md +++ /dev/null @@ -1,25 +0,0 @@ -# Overview -Module Name: Atomx Bidder Adapter Module -Type: Bidder Adapter -Maintainer: erik@atomx.com - -# Description -Atomx Bidder Adapter for Prebid.js. - -# Test Parameters -``` -var adUnits = [ -{ - code: 'test-div', - sizes: [[300, 250]], - bids: [ - { - bidder: 'atomx', - params: { - id: 4025860, - } - } - ] -} -]; -``` diff --git a/modules/atsAnalyticsAdapter.js b/modules/atsAnalyticsAdapter.js deleted file mode 100644 index 31e46dead89..00000000000 --- a/modules/atsAnalyticsAdapter.js +++ /dev/null @@ -1,374 +0,0 @@ -import adapter from '../src/AnalyticsAdapter.js'; -import CONSTANTS from '../src/constants.json'; -import adaptermanager from '../src/adapterManager.js'; -import * as utils from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; -import {getStorageManager} from '../src/storageManager.js'; - -export const storage = getStorageManager(); - -/** - * Analytics adapter for - https://liveramp.com - * Maintainer - prebid@liveramp.com - */ - -const analyticsType = 'endpoint'; -// dev endpoints -// const preflightUrl = 'https://analytics-check.publishersite.xyz/check/'; -// export const analyticsUrl = 'https://analyticsv2.publishersite.xyz'; - -const preflightUrl = 'https://check.analytics.rlcdn.com/check/'; -export const analyticsUrl = 'https://analytics.rlcdn.com'; - -let handlerRequest = []; -let handlerResponse = []; - -let atsAnalyticsAdapterVersion = 1; - -let browsersList = [ - /* Googlebot */ - { - test: /googlebot/i, - name: 'Googlebot' - }, - - /* Opera < 13.0 */ - { - test: /opera/i, - name: 'Opera', - }, - - /* Opera > 13.0 */ - { - test: /opr\/|opios/i, - name: 'Opera' - }, - { - test: /SamsungBrowser/i, - name: 'Samsung Internet for Android', - }, - { - test: /Whale/i, - name: 'NAVER Whale Browser', - }, - { - test: /MZBrowser/i, - name: 'MZ Browser' - }, - { - test: /focus/i, - name: 'Focus', - }, - { - test: /swing/i, - name: 'Swing', - }, - { - test: /coast/i, - name: 'Opera Coast', - }, - { - test: /opt\/\d+(?:.?_?\d+)+/i, - name: 'Opera Touch', - }, - { - test: /yabrowser/i, - name: 'Yandex Browser', - }, - { - test: /ucbrowser/i, - name: 'UC Browser', - }, - { - test: /Maxthon|mxios/i, - name: 'Maxthon', - }, - { - test: /epiphany/i, - name: 'Epiphany', - }, - { - test: /puffin/i, - name: 'Puffin', - }, - { - test: /sleipnir/i, - name: 'Sleipnir', - }, - { - test: /k-meleon/i, - name: 'K-Meleon', - }, - { - test: /micromessenger/i, - name: 'WeChat', - }, - { - test: /qqbrowser/i, - name: (/qqbrowserlite/i).test(window.navigator.userAgent) ? 'QQ Browser Lite' : 'QQ Browser', - }, - { - test: /msie|trident/i, - name: 'Internet Explorer', - }, - { - test: /\sedg\//i, - name: 'Microsoft Edge', - }, - { - test: /edg([ea]|ios)/i, - name: 'Microsoft Edge', - }, - { - test: /vivaldi/i, - name: 'Vivaldi', - }, - { - test: /seamonkey/i, - name: 'SeaMonkey', - }, - { - test: /sailfish/i, - name: 'Sailfish', - }, - { - test: /silk/i, - name: 'Amazon Silk', - }, - { - test: /phantom/i, - name: 'PhantomJS', - }, - { - test: /slimerjs/i, - name: 'SlimerJS', - }, - { - test: /blackberry|\bbb\d+/i, - name: 'BlackBerry', - }, - { - test: /(web|hpw)[o0]s/i, - name: 'WebOS Browser', - }, - { - test: /bada/i, - name: 'Bada', - }, - { - test: /tizen/i, - name: 'Tizen', - }, - { - test: /qupzilla/i, - name: 'QupZilla', - }, - { - test: /firefox|iceweasel|fxios/i, - name: 'Firefox', - }, - { - test: /electron/i, - name: 'Electron', - }, - { - test: /MiuiBrowser/i, - name: 'Miui', - }, - { - test: /chromium/i, - name: 'Chromium', - }, - { - test: /chrome|crios|crmo/i, - name: 'Chrome', - }, - { - test: /GSA/i, - name: 'Google Search', - }, - - /* Android Browser */ - { - test: /android/i, - name: 'Android Browser', - }, - - /* PlayStation 4 */ - { - test: /playstation 4/i, - name: 'PlayStation 4', - }, - - /* Safari */ - { - test: /safari|applewebkit/i, - name: 'Safari', - }, -]; - -function setSamplingCookie(samplRate) { - let now = new Date(); - now.setTime(now.getTime() + 3600000); - storage.setCookie('_lr_sampling_rate', samplRate, now.toUTCString()); -} - -let listOfSupportedBrowsers = ['Safari', 'Chrome', 'Firefox', 'Microsoft Edge']; - -function bidRequestedHandler(args) { - let envelopeSourceCookieValue = storage.getCookie('_lr_env_src_ats'); - let envelopeSource = envelopeSourceCookieValue === 'true'; - let requests; - requests = args.bids.map(function(bid) { - return { - envelope_source: envelopeSource, - has_envelope: bid.userId ? !!bid.userId.idl_env : false, - bidder: bid.bidder, - bid_id: bid.bidId, - auction_id: args.auctionId, - user_browser: parseBrowser(), - user_platform: navigator.platform, - auction_start: new Date(args.auctionStart).toJSON(), - domain: window.location.hostname, - pid: atsAnalyticsAdapter.context.pid, - adapter_version: atsAnalyticsAdapterVersion - }; - }); - return requests; -} - -function bidResponseHandler(args) { - return { - bid_id: args.requestId, - response_time_stamp: new Date(args.responseTimestamp).toJSON(), - currency: args.currency, - cpm: args.cpm, - net_revenue: args.netRevenue - }; -} - -export function parseBrowser() { - let ua = atsAnalyticsAdapter.getUserAgent(); - try { - let result = browsersList.filter(function(obj) { - return obj.test.test(ua); - }); - let browserName = result && result.length ? result[0].name : ''; - return (listOfSupportedBrowsers.indexOf(browserName) >= 0) ? browserName : 'Unknown'; - } catch (err) { - utils.logError('ATS Analytics - Error while checking user browser!', err); - } -} - -function sendDataToAnalytic () { - // send data to ats analytic endpoint - try { - let dataToSend = {'Data': atsAnalyticsAdapter.context.events}; - let strJSON = JSON.stringify(dataToSend); - utils.logInfo('ATS Analytics - tried to send analytics data!'); - ajax(analyticsUrl, function () { - }, strJSON, {method: 'POST', contentType: 'application/json'}); - } catch (err) { - utils.logError('ATS Analytics - request encounter an error: ', err); - } -} - -// preflight request, to check did publisher have permission to send data to analytics endpoint -function preflightRequest (envelopeSourceCookieValue) { - ajax(preflightUrl + atsAnalyticsAdapter.context.pid, function (data) { - let samplingRateObject = JSON.parse(data); - utils.logInfo('ATS Analytics - Sampling Rate: ', samplingRateObject); - let samplingRate = samplingRateObject['samplingRate']; - setSamplingCookie(samplingRate); - let samplingRateNumber = Number(samplingRate); - if (data && samplingRate && atsAnalyticsAdapter.shouldFireRequest(samplingRateNumber) && envelopeSourceCookieValue != null) { - sendDataToAnalytic(); - } - }, undefined, { method: 'GET', crossOrigin: true }); -} - -function callHandler(evtype, args) { - if (evtype === CONSTANTS.EVENTS.BID_REQUESTED) { - handlerRequest = handlerRequest.concat(bidRequestedHandler(args)); - } else if (evtype === CONSTANTS.EVENTS.BID_RESPONSE) { - handlerResponse.push(bidResponseHandler(args)); - } - if (evtype === CONSTANTS.EVENTS.AUCTION_END) { - if (handlerRequest.length) { - let events = []; - if (handlerResponse.length) { - events = handlerRequest.filter(request => handlerResponse.filter(function(response) { - if (request.bid_id === response.bid_id) { - Object.assign(request, response); - } - })); - } else { - events = handlerRequest; - } - atsAnalyticsAdapter.context.events = events; - } - } -} - -let atsAnalyticsAdapter = Object.assign(adapter( - { - analyticsType - }), -{ - track({eventType, args}) { - if (typeof args !== 'undefined') { - callHandler(eventType, args); - } - if (eventType === CONSTANTS.EVENTS.AUCTION_END) { - let envelopeSourceCookieValue = storage.getCookie('_lr_env_src_ats'); - try { - utils.logInfo('ATS Analytics - preflight request!'); - let samplingRateCookie = storage.getCookie('_lr_sampling_rate'); - if (!samplingRateCookie) { - preflightRequest(envelopeSourceCookieValue); - } else { - if (atsAnalyticsAdapter.shouldFireRequest(parseInt(samplingRateCookie)) && envelopeSourceCookieValue != null) { - sendDataToAnalytic(); - } - } - } catch (err) { - utils.logError('ATS Analytics - preflight request encounter an error: ', err); - } - } - } -}); - -// save the base class function -atsAnalyticsAdapter.originEnableAnalytics = atsAnalyticsAdapter.enableAnalytics; - -// add check to not fire request every time, but instead to send 1/10 events -atsAnalyticsAdapter.shouldFireRequest = function (samplingRate) { - let shouldFireRequestValue = (Math.floor((Math.random() * samplingRate + 1)) === samplingRate); - utils.logInfo('ATS Analytics - Should Fire Request: ', shouldFireRequestValue); - return shouldFireRequestValue; -}; - -atsAnalyticsAdapter.getUserAgent = function () { - return window.navigator.userAgent; -}; -// override enableAnalytics so we can get access to the config passed in from the page -atsAnalyticsAdapter.enableAnalytics = function (config) { - if (!config.options.pid) { - utils.logError('ATS Analytics - Publisher ID (pid) option is not defined. Analytics won\'t work'); - return; - } - atsAnalyticsAdapter.context = { - events: [], - pid: config.options.pid - }; - let initOptions = config.options; - atsAnalyticsAdapter.originEnableAnalytics(initOptions); // call the base class function -}; - -adaptermanager.registerAnalyticsAdapter({ - adapter: atsAnalyticsAdapter, - code: 'atsAnalytics', - gvlid: 97 -}); - -export default atsAnalyticsAdapter; diff --git a/modules/atsAnalyticsAdapter.md b/modules/atsAnalyticsAdapter.md deleted file mode 100644 index 7c634f39ae2..00000000000 --- a/modules/atsAnalyticsAdapter.md +++ /dev/null @@ -1,22 +0,0 @@ -# Overview - -``` -Module Name: Ats Analytics Adapter -Module Type: Analytics Adapter -Maintainer: marko.matic@liveramp.com -``` - -# Description - -Analytics adapter for Authenticated Traffic Solution(ATS), provided by LiveRamp. - -# Test Parameters - -``` -{ - provider: 'atsAnalytics', - options: { - pid: '999', // publisher ID - } -} -``` diff --git a/modules/audiencerunBidAdapter.js b/modules/audiencerunBidAdapter.js deleted file mode 100644 index b90471ee21a..00000000000 --- a/modules/audiencerunBidAdapter.js +++ /dev/null @@ -1,142 +0,0 @@ -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'audiencerun'; -const ENDPOINT_URL = 'https://d.audiencerun.com/prebid'; - -export const spec = { - version: '1.0.0', - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {object} bid The bid to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - let isValid = true; - if (!utils.deepAccess(bid, 'params.zoneId')) { - utils.logError('AudienceRun zoneId parameter is required. Bid aborted.'); - isValid = false; - } - return isValid; - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server. - * @param {*} bidderRequest - * @return {ServerRequest} Info describing the request to the server. - */ - buildRequests: function(bidRequests, bidderRequest) { - const bids = bidRequests.map(bid => { - const sizes = utils.deepAccess(bid, 'mediaTypes.banner.sizes', []); - return { - zoneId: utils.getValue(bid.params, 'zoneId'), - sizes: sizes.map(size => ({ - w: size[0], - h: size[1] - })), - bidfloor: bid.params.bidfloor || 0.0, - bidId: bid.bidId, - bidderRequestId: utils.getBidIdParameter('bidderRequestId', bid), - adUnitCode: utils.getBidIdParameter('adUnitCode', bid), - auctionId: utils.getBidIdParameter('auctionId', bid), - transactionId: utils.getBidIdParameter('transactionId', bid) - }; - }); - - const payload = { - libVersion: this.version, - referer: bidderRequest.refererInfo ? bidderRequest.refererInfo.referer || null : null, - currencyCode: config.getConfig('currency.adServerCurrency'), - timeout: config.getConfig('bidderTimeout'), - bids - }; - - if (bidderRequest && bidderRequest.gdprConsent) { - payload.gdpr = { - consent: bidderRequest.gdprConsent.consentString, - applies: bidderRequest.gdprConsent.gdprApplies - }; - } else { - payload.gdpr = { - consent: '' - } - } - - return { - method: 'POST', - url: ENDPOINT_URL, - data: JSON.stringify(payload), - options: { - withCredentials: true - } - }; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function (serverResponse, bidRequest) { - const bids = []; - utils._each(serverResponse.body.bid, function (bidObject) { - if (!bidObject.cpm || bidObject.cpm === null || !bidObject.adm) { - return; - } - - const bid = {}; - - bid.ad = bidObject.adm; - bid.mediaType = BANNER; - - // Common properties - bid.requestId = bidObject.bidId; - bid.adId = bidObject.zoneId; - bid.cpm = parseFloat(bidObject.cpm); - bid.creativeId = bidObject.crid; - bid.currency = bidObject.currency ? bidObject.currency.toUpperCase() : 'USD'; - - bid.height = bidObject.h; - bid.width = bidObject.w; - bid.netRevenue = bidObject.isNet ? bidObject.isNet : false; - bid.ttl = 300; - - bids.push(bid); - }); - return bids; - }, - - /** - * Register the user sync pixels which should be dropped after the auction. - * - * @param {SyncOptions} syncOptions Which user syncs are allowed? - * @param {ServerResponse[]} serverResponses List of server's responses. - * @return {UserSync[]} The user syncs which should be dropped. - */ - getUserSyncs: function(syncOptions, serverResponses) { - if (!serverResponses || !serverResponses.length) return []; - - const syncs = []; - serverResponses.forEach(response => { - response.body.bid.forEach(bidObject => { - syncs.push({ - type: 'iframe', - url: bidObject.syncUrl - }); - }); - }); - - return syncs; - } -}; - -registerBidder(spec); diff --git a/modules/audiencerunBidAdapter.md b/modules/audiencerunBidAdapter.md deleted file mode 100644 index 3704922fdd5..00000000000 --- a/modules/audiencerunBidAdapter.md +++ /dev/null @@ -1,48 +0,0 @@ -# Overview - -**Module Name**: AudienceRun Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: prebid@audiencerun.com - -# Description - -Module that connects to AudienceRun demand sources - -Use `audiencerun` as bidder. - -`zoneId` is required and must be 10 alphanumeric characters. - -## AdUnits configuration example -``` - var adUnits = [{ - code: 'ad-slot-300x600', - mediaTypes: { - banner: { - sizes: [ - [300, 600] - ], - } - }, - bids: [{ - bidder: 'audiencerun', - params: { - zoneId: 'xtov2mgij0' - } - }] - },{ - code: 'ad-slot-728x90', - mediaTypes: { - banner: { - sizes: [ - [728, 90] - ], - } - }, - bids: [{ - bidder: 'audiencerun', - params: { - zoneId: 'u4q6z6u97b' - } - }] - }]; -``` diff --git a/modules/automatadBidAdapter.js b/modules/automatadBidAdapter.js deleted file mode 100644 index 415c52ba6d3..00000000000 --- a/modules/automatadBidAdapter.js +++ /dev/null @@ -1,131 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js' -import * as utils from '../src/utils.js' -import {BANNER} from '../src/mediaTypes.js' -import {ajax} from '../src/ajax.js' - -const BIDDER = 'automatad' - -const ENDPOINT_URL = 'https://rtb2.automatad.com/ortb2' - -const DEFAULT_BID_TTL = 30 -const DEFAULT_CURRENCY = 'USD' -const DEFAULT_NET_REVENUE = true - -export const spec = { - code: BIDDER, - aliases: ['atd'], - supportedMediaTypes: [BANNER], - - isBidRequestValid: function (bid) { - // will receive request bid. check if have necessary params for bidding - return (bid && bid.hasOwnProperty('params') && bid.params.hasOwnProperty('siteId') && bid.params.hasOwnProperty('placementId') && bid.hasOwnProperty('mediaTypes') && bid.mediaTypes.hasOwnProperty('banner')) - }, - - buildRequests: function (validBidRequests, bidderRequest) { - if (!validBidRequests || !bidderRequest) { - return - } - - const siteId = validBidRequests[0].params.siteId - - const impressions = validBidRequests.map(bidRequest => { - return { - id: bidRequest.bidId, - adUnitCode: bidRequest.adUnitCode, - placement: bidRequest.params.placementId, - banner: { - format: bidRequest.sizes.map(sizeArr => ({ - w: sizeArr[0], - h: sizeArr[1], - })) - }, - } - }) - - // params from bid request - const openrtbRequest = { - id: validBidRequests[0].auctionId, - imp: impressions, - site: { - id: siteId, - domain: window.location.hostname, - page: window.location.href, - ref: bidderRequest.refererInfo ? bidderRequest.refererInfo.referer || null : null, - }, - } - - const payloadString = JSON.stringify(openrtbRequest) - return { - method: 'POST', - url: ENDPOINT_URL + '/resp', - data: payloadString, - options: { - contentType: 'application/json', - withCredentials: false, - crossOrigin: true, - }, - } - }, - - interpretResponse: function (serverResponse, request) { - const bidResponses = [] - const response = (serverResponse || {}).body - - if (response && response.seatbid && response.seatbid[0].bid && response.seatbid[0].bid.length) { - response.seatbid.forEach(bidObj => { - bidObj.bid.forEach(bid => { - bidResponses.push({ - requestId: bid.impid, - cpm: bid.price, - ad: bid.adm, - meta: { - advertiserDomains: bid.adomain - }, - currency: DEFAULT_CURRENCY, - ttl: DEFAULT_BID_TTL, - creativeId: bid.crid, - width: bid.w, - height: bid.h, - netRevenue: DEFAULT_NET_REVENUE, - nurl: bid.nurl, - }) - }) - }) - } else { - utils.logInfo('automatad :: no valid responses to interpret') - } - - return bidResponses - }, - getUserSyncs: function(syncOptions, serverResponse) { - return [{ - type: 'iframe', - url: 'https://rtb2.automatad.com/ortb2/async_usersync' - }] - }, - onBidWon: function(bid) { - if (!bid.nurl) { return } - const winCpm = (bid.hasOwnProperty('originalCpm')) ? bid.originalCpm : bid.cpm - const winCurr = (bid.hasOwnProperty('originalCurrency') && bid.hasOwnProperty('originalCpm')) ? bid.originalCurrency : bid.currency - const winUrl = bid.nurl.replace( - /\$\{AUCTION_PRICE\}/, - winCpm - ).replace( - /\$\{AUCTION_IMP_ID\}/, - bid.requestId - ).replace( - /\$\{AUCTION_CURRENCY\}/, - winCurr - ).replace( - /\$\{AUCTION_ID\}/, - bid.auctionId - ) - spec.ajaxCall(winUrl, null) - return true - }, - ajaxCall: function(endpoint, data) { - ajax(endpoint, data) - }, - -} -registerBidder(spec) diff --git a/modules/automatadBidAdapter.md b/modules/automatadBidAdapter.md deleted file mode 100644 index 56a4b53c067..00000000000 --- a/modules/automatadBidAdapter.md +++ /dev/null @@ -1,34 +0,0 @@ -# Overview - -``` -Module Name: Automatad Bid Adapter -Module Type: Bidder Adapter -Maintainer: tech@automatad.com -``` - -# Description - -Connects to automatad exchange for bids. - -automatad bid adapter supports Banner ads. - -# Test Parameters -``` -var adUnits = [ - { - code: 'banner-ad-div', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]] - } - }, - bids: [{ - bidder: 'automatad', - params: { - siteId: 'someValue', - placementId: 'someValue' - } - }] - } -]; -``` diff --git a/modules/avocetBidAdapter.js b/modules/avocetBidAdapter.js deleted file mode 100644 index 1283bb865d4..00000000000 --- a/modules/avocetBidAdapter.js +++ /dev/null @@ -1,141 +0,0 @@ -import { config } from '../src/config.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'avct'; -const DEFAULT_BASE_URL = 'https://ads.avct.cloud'; -const DEFAULT_PREBID_PATH = '/prebid'; - -function getPrebidURL() { - let host = config.getConfig('avct.baseUrl'); - if (host && typeof host === 'string') { - return `${host}${getPrebidPath()}`; - } - return `${DEFAULT_BASE_URL}${getPrebidPath()}`; -} - -function getPrebidPath() { - let prebidPath = config.getConfig('avct.prebidPath'); - if (prebidPath && typeof prebidPath === 'string') { - return prebidPath; - } - return DEFAULT_PREBID_PATH; -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid with params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return ( - !!bid.params && - !!bid.params.placement && - typeof bid.params.placement === 'string' && - bid.params.placement.length === 24 - ); - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (bidRequests, bidderRequest) { - // Get currency from config - const currency = config.getConfig('currency.adServerCurrency'); - - // Publisher domain from config - const publisherDomain = config.getConfig('publisherDomain'); - - // First-party data from config - const fpd = config.getLegacyFpd(config.getConfig('ortb2')); - - // GDPR status and TCF consent string - let tcfConsentString; - let gdprApplies = false; - if (bidderRequest.gdprConsent) { - tcfConsentString = bidderRequest.gdprConsent.consentString; - gdprApplies = !!bidderRequest.gdprConsent.gdprApplies; - } - - // US privacy string - let usPrivacyString; - if (bidderRequest.uspConsent) { - usPrivacyString = bidderRequest.uspConsent; - } - - // Supply chain - let schain; - if (bidderRequest.schain) { - schain = bidderRequest.schain; - } - - // ID5 identifier - let id5id; - if (bidRequests[0].userId && bidRequests[0].userId.id5id && bidRequests[0].userId.id5id.uid) { - id5id = bidRequests[0].userId.id5id.uid; - } - - // Build the avocet ext object - const ext = { - currency, - tcfConsentString, - gdprApplies, - usPrivacyString, - schain, - publisherDomain, - fpd, - id5id, - }; - - // Extract properties from bidderRequest - const { - auctionId, - auctionStart, - bidderCode, - bidderRequestId, - refererInfo, - timeout, - } = bidderRequest; - - // Construct payload - const payload = JSON.stringify({ - auctionId, - auctionStart, - bidderCode, - bidderRequestId, - refererInfo, - timeout, - bids: bidRequests, - ext, - }); - - return { - method: 'POST', - url: getPrebidURL(), - data: payload, - }; - }, - interpretResponse: function (serverResponse, bidRequest) { - if ( - !serverResponse || - !serverResponse.body || - typeof serverResponse.body !== 'object' - ) { - return []; - } - if (Array.isArray(serverResponse.body)) { - return serverResponse.body; - } - if (Array.isArray(serverResponse.body.responses)) { - return serverResponse.body.responses; - } - return []; - }, -}; -registerBidder(spec); diff --git a/modules/avocetBidAdapter.md b/modules/avocetBidAdapter.md deleted file mode 100644 index 95cb29303f2..00000000000 --- a/modules/avocetBidAdapter.md +++ /dev/null @@ -1,40 +0,0 @@ -# Overview - -``` -Module Name: Avocet Bidder Adapter -Module Type: Bidder Adapter -Maintainer: developers@avocet.io -``` - -# Description - -Module that connects to the Avocet advertising platform. - -# Parameters - -| Name | Scope | Description | Example | -| :------------ | :------- | :---------------------------------- | :------------------------- | -| `placement` | required | A Placement ID from Avocet. | "5ebd27607781b9af3ccc3332" | - - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 250]], // a display size - } - }, - bids: [ - { - bidder: "avct", - params: { - placement: "5ebd27607781b9af3ccc3332" - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/axonixBidAdapter.js b/modules/axonixBidAdapter.js deleted file mode 100644 index daaac27e6a4..00000000000 --- a/modules/axonixBidAdapter.js +++ /dev/null @@ -1,185 +0,0 @@ -import { registerBidder } 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 { ajax } from '../src/ajax.js'; - -const BIDDER_CODE = 'axonix'; -const BIDDER_VERSION = '1.0.2'; - -const CURRENCY = 'USD'; -const DEFAULT_REGION = 'us-east-1'; - -function getBidFloor(bidRequest) { - let floorInfo = {}; - - if (typeof bidRequest.getFloor === 'function') { - floorInfo = bidRequest.getFloor({ - currency: CURRENCY, - mediaType: '*', - size: '*' - }); - } - - return floorInfo.floor || 0; -} - -function getPageUrl(bidRequest, bidderRequest) { - let pageUrl = config.getConfig('pageUrl'); - - if (bidRequest.params.referrer) { - pageUrl = bidRequest.params.referrer; - } else if (!pageUrl) { - pageUrl = bidderRequest.refererInfo.referer; - } - - return bidRequest.params.secure ? pageUrl.replace(/^http:/i, 'https:') : pageUrl; -} - -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 getURL(params, path) { - let { supplyId, region, endpoint } = params; - let url; - - if (endpoint) { - url = endpoint; - } else if (region) { - url = `https://openrtb-${region}.axonix.com/supply/${path}/${supplyId}`; - } else { - url = `https://openrtb-${DEFAULT_REGION}.axonix.com/supply/${path}/${supplyId}` - } - - return url; -} - -export const spec = { - code: BIDDER_CODE, - version: BIDDER_VERSION, - supportedMediaTypes: [BANNER, VIDEO], - - isBidRequestValid: function(bid) { - // video bid request validation - if (bid.hasOwnProperty('mediaTypes') && bid.mediaTypes.hasOwnProperty(VIDEO)) { - if (!bid.mediaTypes[VIDEO].hasOwnProperty('mimes') || - !utils.isArray(bid.mediaTypes[VIDEO].mimes) || - bid.mediaTypes[VIDEO].mimes.length === 0) { - utils.logError('mimes are mandatory for video bid request. Ad Unit: ', JSON.stringify(bid)); - - return false; - } - } - - return !!(bid.params && bid.params.supplyId); - }, - - buildRequests: function(validBidRequests, bidderRequest) { - // device.connectiontype - let connection = window.navigator && (window.navigator.connection || window.navigator.mozConnection || window.navigator.webkitConnection) - let connectionType = 'unknown'; - let effectiveType = ''; - - if (connection) { - if (connection.type) { - connectionType = connection.type; - } - - if (connection.effectiveType) { - effectiveType = connection.effectiveType; - } - } - - const requests = validBidRequests.map(validBidRequest => { - // app/site - let app; - let site; - - if (typeof config.getConfig('app') === 'object') { - app = config.getConfig('app'); - } else { - site = { - page: getPageUrl(validBidRequest, bidderRequest) - } - } - - const data = { - app, - site, - validBidRequest, - connectionType, - effectiveType, - devicetype: isMobile() ? 1 : isConnectedTV() ? 3 : 2, - bidfloor: getBidFloor(validBidRequest), - dnt: (navigator.doNotTrack === 'yes' || navigator.doNotTrack === '1' || navigator.msDoNotTrack === '1') ? 1 : 0, - language: navigator.language, - prebidVersion: '$prebid.version$', - screenHeight: screen.height, - screenWidth: screen.width, - tmax: config.getConfig('bidderTimeout'), - ua: navigator.userAgent, - }; - - return { - method: 'POST', - url: getURL(validBidRequest.params, 'prebid'), - options: { - withCredentials: false, - contentType: 'application/json' - }, - data - }; - }); - - return requests; - }, - - interpretResponse: function(serverResponse) { - const response = serverResponse ? serverResponse.body : []; - - if (!utils.isArray(response)) { - return []; - } - - const responses = []; - - for (const resp of response) { - if (resp.requestId) { - responses.push(Object.assign(resp, { - ttl: config.getConfig('_bidderTimeout') - })); - } - } - - return responses; - }, - - onTimeout: function(timeoutData) { - const params = utils.deepAccess(timeoutData, '0.params.0'); - - if (!utils.isEmpty(params)) { - ajax(getURL(params, 'prebid/timeout'), null, timeoutData[0], { - method: 'POST', - options: { - withCredentials: false, - contentType: 'application/json' - } - }); - } - }, - - onBidWon: function(bid) { - const { nurl } = bid || {}; - - if (bid.nurl) { - utils.triggerPixel(utils.replaceAuctionPrice(nurl, bid.cpm)); - }; - } -} - -registerBidder(spec); diff --git a/modules/axonixBidAdapter.md b/modules/axonixBidAdapter.md deleted file mode 100644 index 7a4606d5502..00000000000 --- a/modules/axonixBidAdapter.md +++ /dev/null @@ -1,140 +0,0 @@ -# Overview - -``` -Module Name : Axonix Bidder Adapter -Module Type : Bidder Adapter -Maintainer : support+prebid@axonix.com -``` - -# Description - -Module that connects to Axonix's exchange for bids. - -# Parameters - -| Name | Scope | Description | Example | -| :------------ | :------- | :---------------------------------------------- | :------------------------------------- | -| `supplyId` | required | Supply UUID | `"2c426f78-bb18-4a16-abf4-62c6cd0ee8de"` | -| `region` | optional | Cloud region | `"us-east-1"` | -| `endpoint` | optional | Supply custom endpoint | `"https://open-rtb.axonix.com/custom"` | -| `instl` | optional | Set to 1 if using interstitial (default: 0) | `1` | - -# Test Parameters - -## Banner - -```javascript -var bannerAdUnit = { - code: 'test-banner', - mediaTypes: { - banner: { - sizes: [[120, 600], [300, 250], [320, 50], [468, 60], [728, 90]] - } - }, - bids: [{ - bidder: 'axonix', - params: { - supplyId: 'abc', - region: 'def', - endpoint: 'url' - } - }] -}; -``` - -## Video - -```javascript -var videoAdUnit = { - code: 'test-video', - mediaTypes: { - video: { - protocols: [1, 2, 3, 4, 5, 6, 7, 8] - } - }, - bids: [{ - bidder: 'axonix', - params: { - supplyId: 'abc', - region: 'def', - endpoint: 'url' - } - }] -}; -``` - -## Native - -```javascript -var nativeAdUnit = { - code: 'test-native', - mediaTypes: { - native: { - - } - }, - bids: [{ - bidder: 'axonix', - params: { - supplyId: 'abc', - region: 'def', - endpoint: 'url' - } - }] -}; -``` - -## Multiformat - -```javascript -var adUnits = [ -{ - code: 'test-banner', - mediaTypes: { - banner: { - sizes: [[120, 600], [300, 250], [320, 50], [468, 60], [728, 90]] - } - }, - bids: [{ - bidder: 'axonix', - params: { - supplyId: 'abc', - region: 'def', - endpoint: 'url' - } - }] -}, -{ - code: 'test-video', - mediaTypes: { - video: { - protocols: [1, 2, 3, 4, 5, 6, 7, 8] - } - }, - bids: [{ - bidder: 'axonix', - params: { - supplyId: 'abc', - region: 'def', - endpoint: 'url' - } - }] -}, -{ - code: 'test-native', - mediaTypes: { - native: { - - } - }, - bids: [{ - bidder: 'axonix', - params: { - supplyId: 'abc', - region: 'def', - endpoint: 'url' - } - }] -} -]; -``` diff --git a/modules/beachfrontBidAdapter.js b/modules/beachfrontBidAdapter.js deleted file mode 100644 index 7466b3d6a68..00000000000 --- a/modules/beachfrontBidAdapter.js +++ /dev/null @@ -1,441 +0,0 @@ -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { Renderer } from '../src/Renderer.js'; -import { VIDEO, BANNER } from '../src/mediaTypes.js'; -import find from 'core-js-pure/features/array/find.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -const ADAPTER_VERSION = '1.15'; -const ADAPTER_NAME = 'BFIO_PREBID'; -const OUTSTREAM = 'outstream'; - -export const VIDEO_ENDPOINT = 'https://reachms.bfmio.com/bid.json?exchange_id='; -export const BANNER_ENDPOINT = 'https://display.bfmio.com/prebid_display'; -export const OUTSTREAM_SRC = 'https://player-cdn.beachfrontmedia.com/playerapi/loader/outstream.js'; - -export const VIDEO_TARGETING = ['mimes', 'playbackmethod', 'maxduration', 'placement', 'skip', 'skipmin', 'skipafter']; -export const DEFAULT_MIMES = ['video/mp4', 'application/javascript']; - -export const SUPPORTED_USER_IDS = [ - { key: 'tdid', source: 'adserver.org', rtiPartner: 'TDID', queryParam: 'tdid' }, - { key: 'idl_env', source: 'liveramp.com', rtiPartner: 'idl', queryParam: 'idl' }, - { key: 'uid2.id', source: 'uidapi.com', rtiPartner: 'UID2', queryParam: 'uid2' } -]; - -let appId = ''; - -export const spec = { - code: 'beachfront', - supportedMediaTypes: [ VIDEO, BANNER ], - - isBidRequestValid(bid) { - return !!(isVideoBidValid(bid) || isBannerBidValid(bid)); - }, - - buildRequests(bids, bidderRequest) { - let requests = []; - let videoBids = bids.filter(bid => isVideoBidValid(bid)); - let bannerBids = bids.filter(bid => isBannerBidValid(bid)); - videoBids.forEach(bid => { - appId = getVideoBidParam(bid, 'appId'); - requests.push({ - method: 'POST', - url: VIDEO_ENDPOINT + appId, - data: createVideoRequestData(bid, bidderRequest), - bidRequest: bid - }); - }); - if (bannerBids.length) { - appId = getBannerBidParam(bannerBids[0], 'appId'); - requests.push({ - method: 'POST', - url: BANNER_ENDPOINT, - data: createBannerRequestData(bannerBids, bidderRequest), - bidRequest: bannerBids - }); - } - return requests; - }, - - interpretResponse(response, { bidRequest }) { - response = response.body; - - if (isVideoBid(bidRequest)) { - if (!response || !response.bidPrice) { - utils.logWarn(`No valid video bids from ${spec.code} bidder`); - return []; - } - let sizes = getVideoSizes(bidRequest); - let firstSize = getFirstSize(sizes); - let context = utils.deepAccess(bidRequest, 'mediaTypes.video.context'); - let responseType = getVideoBidParam(bidRequest, 'responseType') || 'both'; - let bidResponse = { - requestId: bidRequest.bidId, - bidderCode: spec.code, - cpm: response.bidPrice, - width: firstSize.w, - height: firstSize.h, - creativeId: response.crid || response.cmpId, - renderer: context === OUTSTREAM ? createRenderer(bidRequest) : null, - mediaType: VIDEO, - currency: 'USD', - netRevenue: true, - ttl: 300 - }; - - if (responseType === 'nurl' || responseType === 'both') { - bidResponse.vastUrl = response.url; - } - - if (responseType === 'adm' || responseType === 'both') { - bidResponse.vastXml = response.vast; - } - - return bidResponse; - } else { - if (!response || !response.length) { - utils.logWarn(`No valid banner bids from ${spec.code} bidder`); - return []; - } - return response - .filter(bid => bid.adm) - .map((bid) => { - let request = find(bidRequest, req => req.adUnitCode === bid.slot); - return { - requestId: request.bidId, - bidderCode: spec.code, - ad: bid.adm, - creativeId: bid.crid, - cpm: bid.price, - width: bid.w, - height: bid.h, - mediaType: BANNER, - currency: 'USD', - netRevenue: true, - ttl: 300 - }; - }); - } - }, - - getUserSyncs(syncOptions, serverResponses = [], gdprConsent = {}, uspConsent = '') { - let syncs = []; - let { gdprApplies, consentString = '' } = gdprConsent; - let bannerResponse = find(serverResponses, (res) => utils.isArray(res.body)); - - if (bannerResponse) { - if (syncOptions.iframeEnabled) { - bannerResponse.body - .filter(bid => bid.sync) - .forEach(bid => { - syncs.push({ - type: 'iframe', - url: bid.sync - }); - }); - } - } else if (syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: `https://sync.bfmio.com/sync_iframe?ifg=1&id=${appId}&gdpr=${gdprApplies ? 1 : 0}&gc=${consentString}&gce=1&us_privacy=${uspConsent}` - }); - } else if (syncOptions.pixelEnabled) { - syncs.push({ - type: 'image', - url: `https://sync.bfmio.com/syncb?pid=144&id=${appId}&gdpr=${gdprApplies ? 1 : 0}&gc=${consentString}&gce=1&us_privacy=${uspConsent}` - }); - } - - return syncs; - } -}; - -function createRenderer(bidRequest) { - const renderer = Renderer.install({ - id: bidRequest.bidId, - url: OUTSTREAM_SRC, - loaded: false - }); - - renderer.setRender(bid => { - bid.renderer.push(() => { - window.Beachfront.Player(bid.adUnitCode, { - adTagUrl: bid.vastUrl, - width: bid.width, - height: bid.height, - expandInView: getPlayerBidParam(bidRequest, 'expandInView', false), - collapseOnComplete: getPlayerBidParam(bidRequest, 'collapseOnComplete', true), - progressColor: getPlayerBidParam(bidRequest, 'progressColor'), - adPosterColor: getPlayerBidParam(bidRequest, 'adPosterColor') - }); - }); - }); - - return renderer; -} - -function getFirstSize(sizes) { - return (sizes && sizes.length) ? sizes[0] : { w: undefined, h: undefined }; -} - -function parseSizes(sizes) { - return utils.parseSizesInput(sizes).map(size => { - let [ width, height ] = size.split('x'); - return { - w: parseInt(width, 10) || undefined, - h: parseInt(height, 10) || undefined - }; - }); -} - -function getVideoSizes(bid) { - return parseSizes(utils.deepAccess(bid, 'mediaTypes.video.playerSize') || bid.sizes); -} - -function getBannerSizes(bid) { - return parseSizes(utils.deepAccess(bid, 'mediaTypes.banner.sizes') || bid.sizes); -} - -function getOsVersion() { - let clientStrings = [ - { s: 'Android', r: /Android/ }, - { s: 'iOS', r: /(iPhone|iPad|iPod)/ }, - { s: 'Mac OS X', r: /Mac OS X/ }, - { s: 'Mac OS', r: /(MacPPC|MacIntel|Mac_PowerPC|Macintosh)/ }, - { s: 'Linux', r: /(Linux|X11)/ }, - { s: 'Windows 10', r: /(Windows 10.0|Windows NT 10.0)/ }, - { s: 'Windows 8.1', r: /(Windows 8.1|Windows NT 6.3)/ }, - { s: 'Windows 8', r: /(Windows 8|Windows NT 6.2)/ }, - { s: 'Windows 7', r: /(Windows 7|Windows NT 6.1)/ }, - { s: 'Windows Vista', r: /Windows NT 6.0/ }, - { s: 'Windows Server 2003', r: /Windows NT 5.2/ }, - { s: 'Windows XP', r: /(Windows NT 5.1|Windows XP)/ }, - { s: 'UNIX', r: /UNIX/ }, - { s: 'Search Bot', r: /(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/ } - ]; - let cs = find(clientStrings, cs => cs.r.test(navigator.userAgent)); - return cs ? cs.s : 'unknown'; -} - -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 getDoNotTrack() { - return navigator.doNotTrack === '1' || window.doNotTrack === '1' || navigator.msDoNoTrack === '1' || navigator.doNotTrack === 'yes'; -} - -function isVideoBid(bid) { - return utils.deepAccess(bid, 'mediaTypes.video'); -} - -function isBannerBid(bid) { - return utils.deepAccess(bid, 'mediaTypes.banner') || !isVideoBid(bid); -} - -function getVideoBidParam(bid, key) { - return utils.deepAccess(bid, 'params.video.' + key) || utils.deepAccess(bid, 'params.' + key); -} - -function getBannerBidParam(bid, key) { - return utils.deepAccess(bid, 'params.banner.' + key) || utils.deepAccess(bid, 'params.' + key); -} - -function getPlayerBidParam(bid, key, defaultValue) { - let param = utils.deepAccess(bid, 'params.player.' + key); - return param === undefined ? defaultValue : param; -} - -function isVideoBidValid(bid) { - return isVideoBid(bid) && getVideoBidParam(bid, 'appId') && getVideoBidParam(bid, 'bidfloor'); -} - -function isBannerBidValid(bid) { - return isBannerBid(bid) && getBannerBidParam(bid, 'appId') && getBannerBidParam(bid, 'bidfloor'); -} - -function getTopWindowLocation(bidderRequest) { - let url = bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer; - return utils.parseUrl(config.getConfig('pageUrl') || url, { decodeSearchAsString: true }); -} - -function getTopWindowReferrer() { - try { - return window.top.document.referrer; - } catch (e) { - return ''; - } -} - -function getEids(bid) { - return SUPPORTED_USER_IDS - .map(getUserId(bid)) - .filter(x => x); -} - -function getUserId(bid) { - return ({ key, source, rtiPartner }) => { - let id = utils.deepAccess(bid, `userId.${key}`); - return id ? formatEid(id, source, rtiPartner) : null; - }; -} - -function formatEid(id, source, rtiPartner) { - return { - source, - uids: [{ - id, - ext: { rtiPartner } - }] - }; -} - -function getVideoTargetingParams(bid) { - const result = {}; - const excludeProps = ['playerSize', 'context', 'w', 'h']; - Object.keys(Object(bid.mediaTypes.video)) - .filter(key => !includes(excludeProps, key)) - .forEach(key => { - result[ key ] = bid.mediaTypes.video[ key ]; - }); - Object.keys(Object(bid.params.video)) - .filter(key => includes(VIDEO_TARGETING, key)) - .forEach(key => { - result[ key ] = bid.params.video[ key ]; - }); - return result; -} - -function createVideoRequestData(bid, bidderRequest) { - let sizes = getVideoSizes(bid); - let firstSize = getFirstSize(sizes); - let video = getVideoTargetingParams(bid); - let appId = getVideoBidParam(bid, 'appId'); - let bidfloor = getVideoBidParam(bid, 'bidfloor'); - let tagid = getVideoBidParam(bid, 'tagid'); - let topLocation = getTopWindowLocation(bidderRequest); - let eids = getEids(bid); - let payload = { - isPrebid: true, - appId: appId, - domain: document.location.hostname, - id: utils.getUniqueIdentifierStr(), - imp: [{ - video: Object.assign({ - w: firstSize.w, - h: firstSize.h, - mimes: DEFAULT_MIMES - }, video), - bidfloor: bidfloor, - tagid: tagid, - secure: topLocation.protocol.indexOf('https') === 0 ? 1 : 0, - displaymanager: ADAPTER_NAME, - displaymanagerver: ADAPTER_VERSION - }], - site: { - page: topLocation.href, - domain: topLocation.hostname - }, - device: { - ua: navigator.userAgent, - language: navigator.language, - devicetype: isMobile() ? 1 : isConnectedTV() ? 3 : 2, - dnt: getDoNotTrack() ? 1 : 0, - js: 1, - geo: {} - }, - regs: { - ext: {} - }, - source: { - ext: {} - }, - user: { - ext: {} - }, - cur: ['USD'] - }; - - if (bidderRequest && bidderRequest.uspConsent) { - payload.regs.ext.us_privacy = bidderRequest.uspConsent; - } - - if (bidderRequest && bidderRequest.gdprConsent) { - let { gdprApplies, consentString } = bidderRequest.gdprConsent; - payload.regs.ext.gdpr = gdprApplies ? 1 : 0; - payload.user.ext.consent = consentString; - } - - if (bid.schain) { - payload.source.ext.schain = bid.schain; - } - - if (eids.length > 0) { - payload.user.ext.eids = eids; - } - - let connection = navigator.connection || navigator.webkitConnection; - if (connection && connection.effectiveType) { - payload.device.connectiontype = connection.effectiveType; - } - - return payload; -} - -function createBannerRequestData(bids, bidderRequest) { - let topLocation = getTopWindowLocation(bidderRequest); - let topReferrer = getTopWindowReferrer(); - let slots = bids.map(bid => { - return { - slot: bid.adUnitCode, - id: getBannerBidParam(bid, 'appId'), - bidfloor: getBannerBidParam(bid, 'bidfloor'), - tagid: getBannerBidParam(bid, 'tagid'), - sizes: getBannerSizes(bid) - }; - }); - let payload = { - slots: slots, - page: topLocation.href, - domain: topLocation.hostname, - search: topLocation.search, - secure: topLocation.protocol.indexOf('https') === 0 ? 1 : 0, - referrer: topReferrer, - ua: navigator.userAgent, - deviceOs: getOsVersion(), - isMobile: isMobile() ? 1 : 0, - dnt: getDoNotTrack() ? 1 : 0, - adapterVersion: ADAPTER_VERSION, - adapterName: ADAPTER_NAME - }; - - if (bidderRequest && bidderRequest.uspConsent) { - payload.usPrivacy = bidderRequest.uspConsent; - } - - if (bidderRequest && bidderRequest.gdprConsent) { - let { gdprApplies, consentString } = bidderRequest.gdprConsent; - payload.gdpr = gdprApplies ? 1 : 0; - payload.gdprConsent = consentString; - } - - if (bids[0] && bids[0].schain) { - payload.schain = bids[0].schain; - } - - SUPPORTED_USER_IDS.forEach(({ key, queryParam }) => { - let id = utils.deepAccess(bids, `0.userId.${key}`) - if (id) { - payload[queryParam] = id; - } - }); - - return payload; -} - -registerBidder(spec); diff --git a/modules/beachfrontBidAdapter.md b/modules/beachfrontBidAdapter.md deleted file mode 100644 index 9de415f8fc5..00000000000 --- a/modules/beachfrontBidAdapter.md +++ /dev/null @@ -1,119 +0,0 @@ -# Overview - -Module Name: Beachfront Bid Adapter - -Module Type: Bidder Adapter - -Maintainer: prebid@beachfront.com - -# Description - -Module that connects to Beachfront's demand sources - -# Test Parameters -```javascript - var adUnits = [ - { - code: 'test-video', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 360], - mimes: ['video/mp4', 'application/javascript'] - } - }, - bids: [ - { - bidder: 'beachfront', - params: { - bidfloor: 0.01, - appId: '11bc5dd5-7421-4dd8-c926-40fa653bec76' - } - } - ] - }, { - code: 'test-banner', - mediaTypes: { - banner: { - sizes: [300, 250] - } - }, - bids: [ - { - bidder: 'beachfront', - params: { - bidfloor: 0.01, - appId: '3b16770b-17af-4d22-daff-9606bdf2c9c3' - } - } - ] - } - ]; -``` - -# Multi-Format Ad Unit Example -```javascript - var adUnits = [ - { - code: 'test-video-banner', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [640, 360], - mimes: ['video/mp4', 'application/javascript'] - }, - banner: { - sizes: [300, 250] - } - }, - bids: [ - { - bidder: 'beachfront', - params: { - video: { - bidfloor: 0.01, - appId: '11bc5dd5-7421-4dd8-c926-40fa653bec76', - }, - banner: { - bidfloor: 0.01, - appId: '3b16770b-17af-4d22-daff-9606bdf2c9c3' - } - } - } - ] - } - ]; -``` - -# Outstream Player Params Example -```javascript - var adUnits = [ - { - code: 'test-video-outstream', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [ 640, 360 ], - mimes: ['video/mp4', 'application/javascript'] - } - }, - bids: [ - { - bidder: 'beachfront', - params: { - video: { - bidfloor: 0.01, - appId: '11bc5dd5-7421-4dd8-c926-40fa653bec76' - }, - player: { - progressColor: '#50A8FA', - adPosterColor: '#FFF', - expandInView: false, - collapseOnComplete: true - } - } - } - ] - } - ]; -``` diff --git a/modules/betweenBidAdapter.js b/modules/betweenBidAdapter.js deleted file mode 100644 index f6360332368..00000000000 --- a/modules/betweenBidAdapter.js +++ /dev/null @@ -1,212 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { getAdUnitSizes, parseSizesInput, deepAccess } from '../src/utils.js'; -import { getRefererInfo } from '../src/refererDetection.js'; - -const BIDDER_CODE = 'between'; -const ENDPOINT = 'https://ads.betweendigital.com/adjson?t=prebid'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['btw'], - supportedMediaTypes: ['banner'], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - return Boolean(bid.params.s); - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests, bidderRequest) { - let requests = []; - const gdprConsent = bidderRequest && bidderRequest.gdprConsent; - const refInfo = getRefererInfo(); - - validBidRequests.forEach(i => { - let params = { - sizes: parseSizesInput(getAdUnitSizes(i)), - jst: 'hb', - ord: Math.random() * 10000000000000000, - tz: getTz(), - fl: getFl(), - rr: getRr(), - shid: getSharedId(i)('id'), - shid3: getSharedId(i)('third'), - s: i.params.s, - bidid: i.bidId, - transactionid: i.transactionId, - auctionid: i.auctionId - }; - if (i.params.itu !== undefined) { - params.itu = i.params.itu; - } - if (i.params.cur !== undefined) { - params.cur = i.params.cur; - } - if (i.params.subid !== undefined) { - params.subid = i.params.subid; - } - if (i.params.click3rd !== undefined) { - params.click3rd = i.params.click3rd; - } - if (i.params.pubdata !== undefined) { - for (let key in i.params.pubdata) { - params['pubside_macro[' + key + ']'] = encodeURIComponent(i.params.pubdata[key]); - } - } - - if (i.schain) { - params.schain = encodeToBase64WebSafe(JSON.stringify(i.schain)); - } - - if (refInfo && refInfo.referer) params.ref = refInfo.referer; - - if (gdprConsent) { - if (typeof gdprConsent.gdprApplies !== 'undefined') { - params.gdprApplies = !!gdprConsent.gdprApplies; - } - if (typeof gdprConsent.consentString !== 'undefined') { - params.consentString = gdprConsent.consentString; - } - } - - requests.push({data: params}) - }) - return { - method: 'POST', - url: ENDPOINT, - data: JSON.stringify(requests) - } - // return requests; - }, - /** - * Unpack the 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. - */ - interpretResponse: function(serverResponse, bidRequest) { - const bidResponses = []; - for (var i = 0; i < serverResponse.body.length; i++) { - let bidResponse = { - requestId: serverResponse.body[i].bidid, - cpm: serverResponse.body[i].cpm || 0, - width: serverResponse.body[i].w, - height: serverResponse.body[i].h, - ttl: serverResponse.body[i].ttl, - creativeId: serverResponse.body[i].creativeid, - currency: serverResponse.body[i].currency || 'RUB', - netRevenue: serverResponse.body[i].netRevenue || true, - ad: serverResponse.body[i].ad - }; - bidResponses.push(bidResponse); - } - return bidResponses; - }, - - /** - * Register the user sync pixels which should be dropped after the auction. - * - * @param {SyncOptions} syncOptions Which user syncs are allowed? - * @param {ServerResponse[]} serverResponses List of server's responses. - * @return {UserSync[]} The user syncs which should be dropped. - */ - getUserSyncs: function(syncOptions, serverResponses) { - let syncs = [] - /* console.log(syncOptions,serverResponses) - if (syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: 'https://acdn.adnxs.com/dmp/async_usersync.html' - }); - } - if (syncOptions.pixelEnabled && serverResponses.length > 0) { - syncs.push({ - type: 'image', - url: serverResponses[0].body.userSync.url - }); - } */ - - // syncs.push({ - // type: 'iframe', - // url: 'https://acdn.adnxs.com/dmp/async_usersync.html' - // }); - syncs.push({ - type: 'iframe', - url: 'https://ads.betweendigital.com/sspmatch-iframe' - }); - return syncs; - } -} - -function getSharedId(bid) { - const id = deepAccess(bid, 'userId.sharedid.id'); - const third = deepAccess(bid, 'userId.sharedid.third'); - return function(kind) { - if (kind === 'id') return id || ''; - return third || ''; - } -} - -function getRr() { - try { - var td = top.document; - var rr = td.referrer; - } catch (err) { return false } - - if (typeof rr != 'undefined' && rr.length > 0) { - return encodeURIComponent(rr); - } else if (typeof rr != 'undefined' && rr == '') { - return 'direct'; - } -} - -function getFl() { - if (navigator.plugins !== undefined && navigator.plugins !== null) { - if (navigator.plugins['Shockwave Flash'] !== undefined && navigator.plugins['Shockwave Flash'] !== null && typeof navigator.plugins['Shockwave Flash'] === 'object') { - var description = navigator.plugins['Shockwave Flash'].description; - if (description && !(navigator.mimeTypes !== undefined && navigator.mimeTypes['application/x-shockwave-flash'] && !navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin)) { - description = description.replace(/^.*\s+(\S+\s+\S+$)/, '$1').replace(/^(.*)\..*$/, '$1'); - - return parseInt(description, 10); - } - } - } - - return 0; -} - -function getTz() { - return new Date().getTimezoneOffset(); -} - -function encodeToBase64WebSafe(string) { - return btoa(string).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, ''); -} - -/* -function get_pubdata(adds) { - if (adds !== undefined && adds.pubdata !== undefined) { - let index = 0; - let url = ''; - for(var key in adds.pubdata) { - if (index == 0) { - url = url + encodeURIComponent('pubside_macro[' + key + ']') + '=' + encodeURIComponent(adds.pubdata[key]); - index++; - } else { - url = url + '&' + encodeURIComponent('pubside_macro[' + key + ']') + '=' + encodeURIComponent(adds.pubdata[key]); - } - } - return url; - } -} -*/ - -registerBidder(spec); diff --git a/modules/betweenBidAdapter.md b/modules/betweenBidAdapter.md deleted file mode 100644 index 4371a8709d8..00000000000 --- a/modules/betweenBidAdapter.md +++ /dev/null @@ -1,154 +0,0 @@ -# Overview - -Module Name: Between Bidder Adapter -Module Type: Bidder Adapter -Maintainer: info@betweendigital.com - -# Description - -You can use this adapter to get a bid from betweendigital. - -About us : [betweenx.com](https://betweenx.com) - -More detailed instructions you can be found on [this page](https://cdn.betweendigital.com/prebid_instructions/index.html) . - -# Test Parameters - -> The parameters are used as an example: -> s: 3649326 — Between section id; code: ad_slot — id of an iframe element showing prebid ads - -```javascript -var adUnits = [ - { - code: "ad_slot", - mediaTypes: { - banner: { - sizes: [[240, 400]], - }, - }, - bids: [ - { - bidder: "between", - params: { - s: 3649326, - }, - }, - ], - }, -]; -``` - -### Multisizes - -If you specify several sizes in the AdUnits settings in the **mediaTypes.banner.sizes** field, our SSP server will hold an auction with each size and respond with a bid with the maximum CPM. - -For example, your ad-slot supports three sizes: 970x250, 728x90 and 468x60. Then the AdUnits code will look like this: - -```javascript -var adUnits = [{ - code: 'ad-slot', - mediaTypes: { - banner: { - sizes: [[970, 250], [728, 90], [468, 60]] - } - }, - bids: [ - { - bidder: 'between', - params: { - s: BETWEEN_SECTION_ID, - } - } -] -}]; -``` - -### Currency - -You can choose in which currency the SSP server will send cpm: 'RUB', 'USD' or 'EUR'. Default is 'RUB'. To do this, in the params field of our adapter you need to add the cur field, which takes one of the values: 'RUB', 'USD' or 'EUR'. - -For example, you want CPM to be sent in dollars. Then the code of our adapter settings will look like this: - -```javascript -{ - bidder: 'between', - params: { - s: BETWEEN_SECTION_ID, - cur: 'USD' - } -} -``` - -### GDPR - -Also, we support GDPR. To find out how to use GDPR in Prebid you can visit [this page](http://prebid.org/dev-docs/modules/consentManagement.html) - - -# Example page - -```html - - - - - - - - - -

Prebid.js BetweenBidAdapter Test

- - - -``` diff --git a/modules/bidViewability.js b/modules/bidViewability.js deleted file mode 100644 index c3b72cda8d4..00000000000 --- a/modules/bidViewability.js +++ /dev/null @@ -1,97 +0,0 @@ -// This module, when included, will trigger a BID_VIEWABLE event which can be consumed by Bidders and Analytics adapters -// 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 * as events from '../src/events.js'; -import { EVENTS } from '../src/constants.json'; -import { logWarn, isFn, triggerPixel } from '../src/utils.js'; -import { getGlobal } from '../src/prebidGlobal.js'; -import adapterManager, { gdprDataHandler, uspDataHandler } from '../src/adapterManager.js'; -import find from 'core-js-pure/features/array/find.js'; - -const MODULE_NAME = 'bidViewability'; -const CONFIG_ENABLED = 'enabled'; -const CONFIG_FIRE_PIXELS = 'firePixels'; -const CONFIG_CUSTOM_MATCH = 'customMatchFunction'; -const BID_VURL_ARRAY = 'vurls'; -const GPT_IMPRESSION_VIEWABLE_EVENT = 'impressionViewable'; - -export let isBidAdUnitCodeMatchingSlot = (bid, slot) => { - return (slot.getAdUnitPath() === bid.adUnitCode || slot.getSlotElementId() === bid.adUnitCode); -} - -export let getMatchingWinningBidForGPTSlot = (globalModuleConfig, slot) => { - return find(getGlobal().getAllWinningBids(), - // supports custom match function from config - bid => isFn(globalModuleConfig[CONFIG_CUSTOM_MATCH]) - ? globalModuleConfig[CONFIG_CUSTOM_MATCH](bid, slot) - : isBidAdUnitCodeMatchingSlot(bid, slot) - ) || null; -}; - -export let fireViewabilityPixels = (globalModuleConfig, bid) => { - if (globalModuleConfig[CONFIG_FIRE_PIXELS] === true && bid.hasOwnProperty(BID_VURL_ARRAY)) { - let queryParams = {}; - - const gdprConsent = gdprDataHandler.getConsentData(); - if (gdprConsent) { - if (typeof gdprConsent.gdprApplies === 'boolean') { queryParams.gdpr = Number(gdprConsent.gdprApplies); } - if (gdprConsent.consentString) { queryParams.gdpr_consent = gdprConsent.consentString; } - if (gdprConsent.addtlConsent) { queryParams.addtl_consent = gdprConsent.addtlConsent; } - } - - const uspConsent = uspDataHandler.getConsentData(); - if (uspConsent) { queryParams.us_privacy = uspConsent; } - - bid[BID_VURL_ARRAY].forEach(url => { - // add '?' if not present in URL - if (Object.keys(queryParams).length > 0 && url.indexOf('?') === -1) { - url += '?'; - } - // append all query params, `&key=urlEncoded(value)` - url += Object.keys(queryParams).reduce((prev, key) => prev += `&${key}=${encodeURIComponent(queryParams[key])}`, ''); - triggerPixel(url) - }); - } -}; - -export let logWinningBidNotFound = (slot) => { - logWarn(`bid details could not be found for ${slot.getSlotElementId()}, probable reasons: a non-prebid bid is served OR check the prebid.AdUnit.code to GPT.AdSlot relation.`); -}; - -export let impressionViewableHandler = (globalModuleConfig, slot, event) => { - let respectiveBid = getMatchingWinningBidForGPTSlot(globalModuleConfig, slot); - if (respectiveBid === null) { - logWinningBidNotFound(slot); - } else { - // if config is enabled AND VURL array is present then execute each pixel - fireViewabilityPixels(globalModuleConfig, respectiveBid); - // trigger respective bidder's onBidViewable handler - adapterManager.callBidViewableBidder(respectiveBid.bidder, respectiveBid); - // emit the BID_VIEWABLE event with bid details, this event can be consumed by bidders and analytics pixels - events.emit(EVENTS.BID_VIEWABLE, respectiveBid); - } -}; - -export let init = () => { - events.on(EVENTS.AUCTION_INIT, () => { - // read the config for the module - const globalModuleConfig = config.getConfig(MODULE_NAME) || {}; - // do nothing if module-config.enabled is not set to true - // this way we are adding a way for bidders to know (using pbjs.getConfig('bidViewability').enabled === true) whether this module is added in build and is enabled - if (globalModuleConfig[CONFIG_ENABLED] !== true) { - return; - } - // add the GPT event listener - window.googletag = window.googletag || {}; - window.googletag.cmd = window.googletag.cmd || []; - window.googletag.cmd.push(() => { - window.googletag.pubads().addEventListener(GPT_IMPRESSION_VIEWABLE_EVENT, function(event) { - impressionViewableHandler(globalModuleConfig, event.slot, event); - }); - }); - }); -} - -init() diff --git a/modules/bidViewability.md b/modules/bidViewability.md deleted file mode 100644 index 78a1539fb1a..00000000000 --- a/modules/bidViewability.md +++ /dev/null @@ -1,49 +0,0 @@ -# Overview - -Module Name: bidViewability - -Purpose: Track when a bid is viewable - -Maintainer: harshad.mane@pubmatic.com - -# Description -- This module, when included, will trigger a BID_VIEWABLE event which can be consumed by Analytics adapters, bidders will need to implement `onBidViewable` method to capture this event -- Bidderes can check if this module is part of the final build and whether it is enabled or not by accessing ```pbjs.getConfig('bidViewability')``` -- GPT API is used to find when a bid is viewable, https://developers.google.com/publisher-tag/reference#googletag.events.impressionviewableevent . This event is fired when an impression becomes viewable, according to the Active View criteria. -Refer: https://support.google.com/admanager/answer/4524488 -- The module does not work with adserver other than GAM with GPT integration -- Logic used to find a matching pbjs-bid for a GPT slot is ``` (slot.getAdUnitPath() === bid.adUnitCode || slot.getSlotElementId() === bid.adUnitCode) ``` this logic can be changed by using param ```customMatchFunction``` -- When a rendered PBJS bid is viewable the module will trigger BID_VIEWABLE event, which can be consumed by bidders and analytics adapters -- For the viewable bid if ```bid.vurls type array``` param is and module config ``` firePixels: true ``` is set then the URLs mentioned in bid.vurls will be executed. Please note that GDPR and USP related parameters will be added to the given URLs - -# Params -- enabled [required] [type: boolean, default: false], when set to true, the module will emit BID_VIEWABLE when applicable -- firePixels [optional] [type: boolean], when set to true, will fire the urls mentioned in bid.vurls which should be array of urls -- customMatchFunction [optional] [type: function(bid, slot)], when passed this function will be used to `find` the matching winning bid for the GPT slot. Default value is ` (bid, slot) => (slot.getAdUnitPath() === bid.adUnitCode || slot.getSlotElementId() === bid.adUnitCode) ` - -# Example of consuming BID_VIEWABLE event -``` - pbjs.onEvent('bidViewable', function(bid){ - console.log('got bid details in bidViewable event', bid); - }); - -``` - -# Example of using config -``` - pbjs.setConfig({ - bidViewability: { - enabled: true, - firePixels: true, - customMatchFunction: function(bid, slot){ - console.log('using custom match function....'); - return bid.adUnitCode === slot.getAdUnitPath(); - } - } - }); -``` - -# Please Note: -- Doesn't seems to work with Instream Video, https://docs.prebid.org/dev-docs/examples/instream-banner-mix.html as GPT's impressionViewable event is not triggered for instream-video-creative -- Works with Banner, Outsteam, Native creatives - diff --git a/modules/bidfluenceBidAdapter.js b/modules/bidfluenceBidAdapter.js deleted file mode 100644 index f8a1f9ac92f..00000000000 --- a/modules/bidfluenceBidAdapter.js +++ /dev/null @@ -1,131 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const storage = getStorageManager(); -const BIDDER_CODE = 'bidfluence'; - -function stdTimezoneOffset(t) { - const jan = new Date(t.getFullYear(), 0, 1); - const jul = new Date(t.getFullYear(), 6, 1); - return Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset()); -} -function dst(t) { - return t.getTimezoneOffset() < stdTimezoneOffset(t); -} -function getBdfTz(d) { - let tz = d.getTimezoneOffset(); - if (dst(d)) { - tz += 60; - } - return tz.toString(); -} -function getUTCDate() { - var m = new Date(); - var dateString = m.getUTCFullYear() + '/' + - ('0' + (m.getUTCMonth() + 1)).slice(-2) + '/' + - ('0' + m.getUTCDate()).slice(-2) + ' ' + - ('0' + m.getUTCHours()).slice(-2) + ':' + - ('0' + m.getUTCMinutes()).slice(-2) + ':' + - ('0' + m.getUTCSeconds()).slice(-2); - - return dateString; -} - -export const spec = { - code: BIDDER_CODE, - isBidRequestValid: function (bid) { - return !!bid.params.placementId || !!bid.params.publisherId; - }, - - buildRequests: function (validBidRequests, bidderRequest) { - const body = document.getElementsByTagName('body')[0]; - const refInfo = bidderRequest.refererInfo; - const gdpr = bidderRequest.gdprConsent; - const vpW = Math.max(window.innerWidth || body.clientWidth || 0) + 2; - const vpH = Math.max(window.innerHeight || body.clientHeight || 0) + 2; - const sr = screen.height > screen.width ? screen.height + 'x' + screen.width + 'x' + screen.colorDepth : screen.width + 'x' + screen.height + 'x' + screen.colorDepth; - - var payload = { - v: '2.0', - azr: true, - ck: storage.cookiesAreEnabled(), - re: refInfo ? refInfo.referer : '', - st: refInfo ? refInfo.stack : [], - tz: getBdfTz(new Date()), - sr: sr, - tm: bidderRequest.timeout, - vp: vpW + 'x' + vpH, - sdt: getUTCDate(), - top: refInfo ? refInfo.reachedTop : false, - gdpr: gdpr ? gdpr.gdprApplies : false, - gdprc: gdpr ? gdpr.consentString : '', - bids: [] - }; - - utils._each(validBidRequests, function (bidRequest) { - var params = bidRequest.params; - var sizes = utils.parseSizesInput(bidRequest.sizes)[0]; - var width = sizes.split('x')[0]; - var height = sizes.split('x')[1]; - - var currentBidPayload = { - bid: bidRequest.bidId, - tid: params.placementId, - pid: params.publisherId, - rp: params.reservePrice || 0, - w: width, - h: height - }; - - payload.bids.push(currentBidPayload); - }); - - const payloadString = JSON.stringify(payload); - return { - method: 'POST', - url: `https://bdf${payload.bids[0].pid}.bidfluence.com/Prebid`, - data: payloadString, - options: { contentType: 'text/plain' } - }; - }, - - interpretResponse: function (serverResponse, bidRequest) { - const bidResponses = []; - const response = serverResponse.body; - - utils._each(response.Bids, function (currentResponse) { - var cpm = currentResponse.Cpm || 0; - - if (cpm > 0) { - const bidResponse = { - requestId: currentResponse.BidId, - cpm: cpm, - width: currentResponse.Width, - height: currentResponse.Height, - creativeId: currentResponse.CreativeId, - ad: currentResponse.Ad, - currency: 'USD', - netRevenue: true, - ttl: 360 - }; - bidResponses.push(bidResponse); - } - }); - - return bidResponses; - }, - - getUserSyncs: function (serverResponses) { - if (serverResponses.userSyncs) { - const syncs = serverResponses.UserSyncs.map((sync) => { - return { - type: sync.Type === 'ifr' ? 'iframe' : 'image', - url: sync.Url - }; - }); - return syncs; - } - } -}; -registerBidder(spec); diff --git a/modules/bidfluenceBidAdapter.md b/modules/bidfluenceBidAdapter.md deleted file mode 100644 index 34dbb3d3a1c..00000000000 --- a/modules/bidfluenceBidAdapter.md +++ /dev/null @@ -1,31 +0,0 @@ -# Overview - -``` -Module Name: Bidfluence Adapter -Module Type: Bidder Adapter -Maintainer: integrations@bidfluence.com -prebid_1_0_supported : true -gdpr_supported: true -``` - -# Description - -Bidfluence adapter for prebid. - -# Test Parameters - -``` -var adUnits = [ - { - code: 'test-prebid', - sizes: [[300, 250]], - bids: [{ - bidder: 'bidfluence', - params: { - placementId: '1000', - publisherId: '1000' - } - }] - } -] -``` diff --git a/modules/bidglassBidAdapter.js b/modules/bidglassBidAdapter.js deleted file mode 100644 index 44f5cdf4384..00000000000 --- a/modules/bidglassBidAdapter.js +++ /dev/null @@ -1,149 +0,0 @@ -import * as utils from '../src/utils.js'; -// import {config} from 'src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'bidglass'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['bg'], // short code - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - return !!(bid.params.adUnitId && !isNaN(parseFloat(bid.params.adUnitId)) && isFinite(bid.params.adUnitId)); - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests, bidderRequest) { - /* - Sample array entry for validBidRequests[]: - [{ - "bidder": "bidglass", - "bidId": "51ef8751f9aead", - "params": { - "adUnitId": 11, - ... - }, - "adUnitCode": "div-gpt-ad-1460505748561-0", - "transactionId": "d7b773de-ceaa-484d-89ca-d9f51b8d61ec", - "sizes": [[320,50],[300,250],[300,600]], - "bidderRequestId": "418b37f85e772c", - "auctionId": "18fd8b8b0bd757", - "bidRequestsCount": 1 - }] - */ - - let imps = []; - let getReferer = function() { - return window === window.top ? window.location.href : window.parent === window.top ? document.referrer : null; - }; - let getOrigins = function() { - var ori = [window.location.protocol + '//' + window.location.hostname]; - - if (window.location.ancestorOrigins) { - for (var i = 0; i < window.location.ancestorOrigins.length; i++) { - ori.push(window.location.ancestorOrigins[i]); - } - } else if (window !== window.top) { - // Derive the parent origin - var parts = document.referrer.split('/'); - - ori.push(parts[0] + '//' + parts[2]); - - if (window.parent !== window.top) { - // Additional unknown origins exist - ori.push('null'); - } - } - - return ori; - }; - - let bidglass = window['bidglass']; - - utils._each(validBidRequests, function(bid) { - bid.sizes = ((utils.isArray(bid.sizes) && utils.isArray(bid.sizes[0])) ? bid.sizes : [bid.sizes]); - bid.sizes = bid.sizes.filter(size => utils.isArray(size)); - - var adUnitId = utils.getBidIdParameter('adUnitId', bid.params); - var options = utils.deepClone(bid.params); - - delete options.adUnitId; - - // Merge externally set targeting params - if (typeof bidglass === 'object' && bidglass.getTargeting) { - let targeting = bidglass.getTargeting(adUnitId, options.targeting); - - if (targeting && Object.keys(targeting).length > 0) options.targeting = targeting; - } - - // Stuff to send: [bid id, sizes, adUnitId, options] - imps.push({ - bidId: bid.bidId, - sizes: bid.sizes, - adUnitId: adUnitId, - options: options - }); - }); - - // Stuff to send: page URL - const bidReq = { - reqId: utils.getUniqueIdentifierStr(), - imps: imps, - ref: getReferer(), - ori: getOrigins() - }; - - let url = 'https://bid.glass/ad/hb.php?' + - `src=$$REPO_AND_VERSION$$`; - - return { - method: 'POST', - url: url, - data: JSON.stringify(bidReq), - options: { - contentType: 'text/plain', - withCredentials: false - } - } - }, - - /** - * Unpack the 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. - */ - interpretResponse: function(serverResponse) { - const bidResponses = []; - - utils._each(serverResponse.body.bidResponses, function(bid) { - bidResponses.push({ - requestId: bid.requestId, - cpm: parseFloat(bid.cpm), - width: parseInt(bid.width, 10), - height: parseInt(bid.height, 10), - creativeId: bid.creativeId, - dealId: bid.dealId || null, - currency: bid.currency || 'USD', - mediaType: bid.mediaType || 'banner', - netRevenue: true, - ttl: bid.ttl || 10, - ad: bid.ad - }); - }); - - return bidResponses; - } - -} - -registerBidder(spec); diff --git a/modules/bidglassBidAdapter.md b/modules/bidglassBidAdapter.md deleted file mode 100644 index 5384a095314..00000000000 --- a/modules/bidglassBidAdapter.md +++ /dev/null @@ -1,34 +0,0 @@ -# Overview - -``` -Module Name: Bid Glass Bid Adapter -Module Type: Bidder Adapter -Maintainer: dliebner@gmail.com -``` - -# Description - -Connects to Bid Glass and allows bids on ad units to compete within prebid. - -# Sample Ad Unit: For Publishers -``` -var adUnits = [{ - code: 'bg-test-rectangle', - sizes: [[300, 250]], - bids: [{ - bidder: 'bidglass', - params: { - adUnitId: '-1' - } - }] -},{ - code: 'bg-test-leaderboard', - sizes: [[728, 90]], - bids: [{ - bidder: 'bidglass', - params: { - adUnitId: '-1' - } - }] -}] -``` \ No newline at end of file diff --git a/modules/bidlabBidAdapter.js b/modules/bidlabBidAdapter.js deleted file mode 100644 index 8f501505a6d..00000000000 --- a/modules/bidlabBidAdapter.js +++ /dev/null @@ -1,112 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; - -const BIDDER_CODE = 'bidlab'; -const AD_URL = 'https://service.bidlab.ai/?c=o&m=multi'; -const URL_SYNC = 'https://service.bidlab.ai/?c=o&m=sync'; -const NO_SYNC = true; - -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency) { - return false; - } - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl); - case NATIVE: - return Boolean(bid.native && bid.native.title && bid.native.image && bid.native.impressionTrackers); - default: - return false; - } -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO, NATIVE], - noSync: NO_SYNC, - - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && bid.params && !isNaN(parseInt(bid.params.placementId))); - }, - - buildRequests: (validBidRequests = [], bidderRequest) => { - let winTop = window; - let location; - try { - location = new URL(bidderRequest.refererInfo.referer) - winTop = window.top; - } catch (e) { - location = winTop.location; - utils.logMessage(e); - }; - let placements = []; - let request = { - 'deviceWidth': winTop.screen.width, - 'deviceHeight': winTop.screen.height, - 'language': (navigator && navigator.language) ? navigator.language.split('-')[0] : '', - 'secure': 1, - 'host': location.host, - 'page': location.pathname, - 'placements': placements - }; - request.language.indexOf('-') != -1 && (request.language = request.language.split('-')[0]) - if (bidderRequest) { - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - if (bidderRequest.gdprConsent) { - request.gdpr = bidderRequest.gdprConsent - } - } - const len = validBidRequests.length; - - for (let i = 0; i < len; i++) { - let bid = validBidRequests[i]; - let traff = bid.params.traffic || BANNER - - placements.push({ - placementId: bid.params.placementId, - bidId: bid.bidId, - sizes: bid.mediaTypes && bid.mediaTypes[traff] && bid.mediaTypes[traff].sizes ? bid.mediaTypes[traff].sizes : [], - traffic: traff - }); - if (bid.schain) { - placements.schain = bid.schain; - } - } - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses) => { - if (NO_SYNC) { - return false - } else { - return [{ - type: 'image', - url: URL_SYNC - }]; - } - } - -}; - -registerBidder(spec); diff --git a/modules/bidlabBidAdapter.md b/modules/bidlabBidAdapter.md deleted file mode 100644 index 3e5fe3128ed..00000000000 --- a/modules/bidlabBidAdapter.md +++ /dev/null @@ -1,53 +0,0 @@ -# Overview - -``` -Module Name: bidlab Bidder Adapter -Module Type: bidlab Bidder Adapter -``` - -# Description - -Module that connects to bidlab demand sources - -# Test Parameters -``` - var adUnits = [ - // Will return static test banner - { - code: 'placementId_0', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [ - { - bidder: 'bidlab', - params: { - placementId: 0, - traffic: 'banner' - } - } - ] - }, - // Will return test vast xml. All video params are stored under placement in publishers UI - { - code: 'placementId_0', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'instream' - } - }, - bids: [ - { - bidder: 'bidlab', - params: { - placementId: 0, - traffic: 'video' - } - } - ] - } - ]; -``` diff --git a/modules/bidphysicsBidAdapter.js b/modules/bidphysicsBidAdapter.js deleted file mode 100644 index b6b5690ede5..00000000000 --- a/modules/bidphysicsBidAdapter.js +++ /dev/null @@ -1,134 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import * as utils from '../src/utils.js'; -import {BANNER} from '../src/mediaTypes.js'; - -const ENDPOINT_URL = 'https://exchange.bidphysics.com/auction'; - -const DEFAULT_BID_TTL = 30; -const DEFAULT_CURRENCY = 'USD'; -const DEFAULT_NET_REVENUE = true; - -export const spec = { - code: 'bidphysics', - aliases: ['yieldlift'], - supportedMediaTypes: [BANNER], - - isBidRequestValid: function (bid) { - return (!!bid.params.unitId && typeof bid.params.unitId === 'string') || - (!!bid.params.networkId && typeof bid.params.networkId === 'string') || - (!!bid.params.publisherId && typeof bid.params.publisherId === 'string'); - }, - - buildRequests: function (validBidRequests, bidderRequest) { - if (!validBidRequests || !bidderRequest) { - return; - } - const publisherId = validBidRequests[0].params.publisherId; - const networkId = validBidRequests[0].params.networkId; - const impressions = validBidRequests.map(bidRequest => ({ - id: bidRequest.bidId, - banner: { - format: bidRequest.sizes.map(sizeArr => ({ - w: sizeArr[0], - h: sizeArr[1] - })) - }, - ext: { - bidphysics: { - unitId: bidRequest.params.unitId - } - } - })); - - const openrtbRequest = { - id: bidderRequest.auctionId, - imp: impressions, - site: { - domain: window.location.hostname, - page: window.location.href, - ref: bidderRequest.refererInfo ? bidderRequest.refererInfo.referer || null : null - }, - ext: { - bidphysics: { - publisherId: publisherId, - networkId: networkId, - } - } - }; - - // apply gdpr - if (bidderRequest.gdprConsent) { - openrtbRequest.regs = {ext: {gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0}}; - openrtbRequest.user = {ext: {consent: bidderRequest.gdprConsent.consentString}}; - } - - const payloadString = JSON.stringify(openrtbRequest); - return { - method: 'POST', - url: ENDPOINT_URL, - data: payloadString, - }; - }, - - interpretResponse: function (serverResponse, request) { - const bidResponses = []; - const response = (serverResponse || {}).body; - // response is always one seat (bidphysics) with (optional) bids for each impression - if (response && response.seatbid && response.seatbid.length === 1 && response.seatbid[0].bid && response.seatbid[0].bid.length) { - response.seatbid[0].bid.forEach(bid => { - bidResponses.push({ - requestId: bid.impid, - cpm: bid.price, - width: bid.w, - height: bid.h, - ad: bid.adm, - ttl: DEFAULT_BID_TTL, - creativeId: bid.crid, - netRevenue: DEFAULT_NET_REVENUE, - currency: DEFAULT_CURRENCY, - }) - }) - } else { - utils.logInfo('bidphysics.interpretResponse :: no valid responses to interpret'); - } - return bidResponses; - }, - getUserSyncs: function (syncOptions, serverResponses) { - utils.logInfo('bidphysics.getUserSyncs', 'syncOptions', syncOptions, 'serverResponses', serverResponses); - let syncs = []; - - if (!syncOptions.iframeEnabled && !syncOptions.pixelEnabled) { - return syncs; - } - - serverResponses.forEach(resp => { - const userSync = utils.deepAccess(resp, 'body.ext.usersync'); - if (userSync) { - let syncDetails = []; - Object.keys(userSync).forEach(key => { - const value = userSync[key]; - if (value.syncs && value.syncs.length) { - syncDetails = syncDetails.concat(value.syncs); - } - }); - syncDetails.forEach(syncDetails => { - syncs.push({ - type: syncDetails.type === 'iframe' ? 'iframe' : 'image', - url: syncDetails.url - }); - }); - - if (!syncOptions.iframeEnabled) { - syncs = syncs.filter(s => s.type !== 'iframe') - } - if (!syncOptions.pixelEnabled) { - syncs = syncs.filter(s => s.type !== 'image') - } - } - }); - utils.logInfo('bidphysics.getUserSyncs result=%o', syncs); - return syncs; - }, - -}; -registerBidder(spec); diff --git a/modules/bidphysicsBidAdapter.md b/modules/bidphysicsBidAdapter.md deleted file mode 100644 index d7d8b355027..00000000000 --- a/modules/bidphysicsBidAdapter.md +++ /dev/null @@ -1,33 +0,0 @@ -# Overview - -``` -Module Name: BidPhysics Bid Adapter -Module Type: Bidder Adapter -Maintainer: info@bidphysics.com -``` - -# Description - -Connects to BidPhysics exchange for bids. - -BidPhysics bid adapter supports Banner ads. - -# Test Parameters -``` -var adUnits = [ - { - code: 'banner-ad-div', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]] - } - }, - bids: [{ - bidder: 'bidphysics', - params: { - unitId: 'bidphysics-test' - } - }] - } -]; -``` diff --git a/modules/bizzclickBidAdapter.js b/modules/bizzclickBidAdapter.js deleted file mode 100644 index 2af9a7afed2..00000000000 --- a/modules/bizzclickBidAdapter.js +++ /dev/null @@ -1,326 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; -import {config} from '../src/config.js'; - -const BIDDER_CODE = 'bizzclick'; -const ACCOUNTID_MACROS = '[account_id]'; -const URL_ENDPOINT = `https://us-e-node1.bizzclick.com/bid?rtb_seat_id=prebidjs&secret_key=${ACCOUNTID_MACROS}`; -const NATIVE_ASSET_IDS = { 0: 'title', 2: 'icon', 3: 'image', 5: 'sponsoredBy', 4: 'body', 1: 'cta' }; -const NATIVE_PARAMS = { - title: { - id: 0, - name: 'title' - }, - icon: { - id: 2, - type: 1, - name: 'img' - }, - image: { - id: 3, - type: 3, - name: 'img' - }, - sponsoredBy: { - id: 5, - name: 'data', - type: 1 - }, - body: { - id: 4, - name: 'data', - type: 2 - }, - cta: { - id: 1, - type: 12, - name: 'data' - } -}; -const NATIVE_VERSION = '1.2'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO, NATIVE], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {object} bid The bid to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: (bid) => { - return Boolean(bid.params.accountId) && Boolean(bid.params.placementId) - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests A non-empty list of valid bid requests that should be sent to the Server. - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: (validBidRequests, bidderRequest) => { - if (validBidRequests && validBidRequests.length === 0) return [] - let accuontId = validBidRequests[0].params.accountId; - const endpointURL = URL_ENDPOINT.replace(ACCOUNTID_MACROS, accuontId); - - let winTop = window; - let location; - try { - location = new URL(bidderRequest.refererInfo.referer) - winTop = window.top; - } catch (e) { - location = winTop.location; - utils.logMessage(e); - }; - - let bids = []; - for (let bidRequest of validBidRequests) { - let impObject = prepareImpObject(bidRequest); - let data = { - id: bidRequest.bidId, - test: config.getConfig('debug') ? 1 : 0, - at: 1, - cur: ['USD'], - device: { - w: winTop.screen.width, - h: winTop.screen.height, - dnt: utils.getDNT() ? 1 : 0, - language: (navigator && navigator.language) ? navigator.language.indexOf('-') != -1 ? navigator.language.split('-')[0] : navigator.language : '', - }, - site: { - page: location.pathname, - host: location.host - }, - source: { - tid: bidRequest.transactionId - }, - regs: { - coppa: config.getConfig('coppa') === true ? 1 : 0, - ext: {} - }, - user: { - ext: {} - }, - tmax: bidRequest.timeout, - imp: [impObject], - }; - if (bidRequest) { - if (bidRequest.gdprConsent && bidRequest.gdprConsent.gdprApplies) { - utils.deepSetValue(data, 'regs.ext.gdpr', bidRequest.gdprConsent.gdprApplies ? 1 : 0); - utils.deepSetValue(data, 'user.ext.consent', bidRequest.gdprConsent.consentString); - } - - if (bidRequest.uspConsent !== undefined) { - utils.deepSetValue(data, 'regs.ext.us_privacy', bidRequest.uspConsent); - } - } - bids.push(data) - } - return { - method: 'POST', - url: endpointURL, - data: bids - }; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: (serverResponse) => { - if (!serverResponse || !serverResponse.body) return [] - let bizzclickResponse = serverResponse.body; - - let bids = []; - for (let response of bizzclickResponse) { - let mediaType = response.seatbid[0].bid[0].ext && response.seatbid[0].bid[0].ext.mediaType ? response.seatbid[0].bid[0].ext.mediaType : BANNER; - - let bid = { - requestId: response.id, - cpm: response.seatbid[0].bid[0].price, - width: response.seatbid[0].bid[0].w, - height: response.seatbid[0].bid[0].h, - ttl: response.ttl || 1200, - currency: response.cur || 'USD', - netRevenue: true, - creativeId: response.seatbid[0].bid[0].crid, - dealId: response.seatbid[0].bid[0].dealid, - mediaType: mediaType - }; - - switch (mediaType) { - case VIDEO: - bid.vastXml = response.seatbid[0].bid[0].adm - bid.vastUrl = response.seatbid[0].bid[0].ext.vastUrl - break - case NATIVE: - bid.native = parseNative(response.seatbid[0].bid[0].adm) - break - default: - bid.ad = response.seatbid[0].bid[0].adm - } - - bids.push(bid); - } - - return bids; - }, -}; - -/** - * Determine type of request - * - * @param bidRequest - * @param type - * @returns {boolean} - */ -const checkRequestType = (bidRequest, type) => { - return (typeof utils.deepAccess(bidRequest, `mediaTypes.${type}`) !== 'undefined'); -} - -const parseNative = admObject => { - const { assets, link, imptrackers, jstracker } = admObject.native; - const result = { - clickUrl: link.url, - clickTrackers: link.clicktrackers || undefined, - impressionTrackers: imptrackers || undefined, - javascriptTrackers: jstracker ? [ jstracker ] : undefined - }; - assets.forEach(asset => { - const kind = NATIVE_ASSET_IDS[asset.id]; - const content = kind && asset[NATIVE_PARAMS[kind].name]; - if (content) { - result[kind] = content.text || content.value || { url: content.url, width: content.w, height: content.h }; - } - }); - - return result; -} - -const prepareImpObject = (bidRequest) => { - let impObject = { - id: bidRequest.transactionId, - secure: 1, - ext: { - placementId: bidRequest.params.placementId - } - }; - if (checkRequestType(bidRequest, BANNER)) { - impObject.banner = addBannerParameters(bidRequest); - } - if (checkRequestType(bidRequest, VIDEO)) { - impObject.video = addVideoParameters(bidRequest); - } - if (checkRequestType(bidRequest, NATIVE)) { - impObject.native = { - ver: NATIVE_VERSION, - request: addNativeParameters(bidRequest) - }; - } - return impObject -}; - -const addNativeParameters = bidRequest => { - let impObject = { - id: bidRequest.transactionId, - ver: NATIVE_VERSION, - }; - - const assets = utils._map(bidRequest.mediaTypes.native, (bidParams, key) => { - const props = NATIVE_PARAMS[key]; - const asset = { - required: bidParams.required & 1, - }; - if (props) { - asset.id = props.id; - let wmin, hmin; - let aRatios = bidParams.aspect_ratios; - - if (aRatios && aRatios[0]) { - aRatios = aRatios[0]; - wmin = aRatios.min_width || 0; - hmin = aRatios.ratio_height * wmin / aRatios.ratio_width | 0; - } - - if (bidParams.sizes) { - const sizes = flatten(bidParams.sizes); - wmin = sizes[0]; - hmin = sizes[1]; - } - - asset[props.name] = {} - - if (bidParams.len) asset[props.name]['len'] = bidParams.len; - if (props.type) asset[props.name]['type'] = props.type; - if (wmin) asset[props.name]['wmin'] = wmin; - if (hmin) asset[props.name]['hmin'] = hmin; - - return asset; - } - }).filter(Boolean); - - impObject.assets = assets; - return impObject -} - -const addBannerParameters = (bidRequest) => { - let bannerObject = {}; - const size = parseSizes(bidRequest, 'banner'); - bannerObject.w = size[0]; - bannerObject.h = size[1]; - return bannerObject; -}; - -const parseSizes = (bid, mediaType) => { - let mediaTypes = bid.mediaTypes; - if (mediaType === 'video') { - let size = []; - if (mediaTypes.video && mediaTypes.video.w && mediaTypes.video.h) { - size = [ - mediaTypes.video.w, - mediaTypes.video.h - ]; - } else if (Array.isArray(utils.deepAccess(bid, 'mediaTypes.video.playerSize')) && bid.mediaTypes.video.playerSize.length === 1) { - size = bid.mediaTypes.video.playerSize[0]; - } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0 && Array.isArray(bid.sizes[0]) && bid.sizes[0].length > 1) { - size = bid.sizes[0]; - } - return size; - } - let sizes = []; - if (Array.isArray(mediaTypes.banner.sizes)) { - sizes = mediaTypes.banner.sizes[0]; - } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) { - sizes = bid.sizes - } else { - utils.logWarn('no sizes are setup or found'); - } - - return sizes -} - -const addVideoParameters = (bidRequest) => { - let videoObj = {}; - let supportParamsList = ['mimes', 'minduration', 'maxduration', 'protocols', 'startdelay', 'placement', 'skip', 'skipafter', 'minbitrate', 'maxbitrate', 'delivery', 'playbackmethod', 'api', 'linearity'] - - for (let param of supportParamsList) { - if (bidRequest.mediaTypes.video[param] !== undefined) { - videoObj[param] = bidRequest.mediaTypes.video[param]; - } - } - - const size = parseSizes(bidRequest, 'video'); - videoObj.w = size[0]; - videoObj.h = size[1]; - return videoObj; -} - -const flatten = arr => { - return [].concat(...arr); -} - -registerBidder(spec); diff --git a/modules/bizzclickBidAdapter.md b/modules/bizzclickBidAdapter.md deleted file mode 100644 index 6fc1bebf546..00000000000 --- a/modules/bizzclickBidAdapter.md +++ /dev/null @@ -1,104 +0,0 @@ -# Overview - -``` -Module Name: BizzClick SSP Bidder Adapter -Module Type: Bidder Adapter -Maintainer: support@bizzclick.com -``` - -# Description - -Module that connects to BizzClick SSP demand sources - -# Test Parameters -``` - var adUnits = [{ - code: 'placementId', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]] - } - }, - bids: [{ - bidder: 'bizzclick', - params: { - placementId: 'hash', - accountId: 'accountId' - } - }] - }, - { - code: 'native_example', - // sizes: [[1, 1]], - mediaTypes: { - native: { - title: { - required: true, - len: 800 - }, - image: { - required: true, - len: 80 - }, - sponsoredBy: { - required: true - }, - clickUrl: { - required: true - }, - privacyLink: { - required: false - }, - body: { - required: true - }, - icon: { - required: true, - sizes: [50, 50] - } - } - - }, - bids: [ { - bidder: 'bizzclick', - params: { - placementId: 'hash', - accountId: 'accountId' - } - }] - }, - { - code: 'video1', - sizes: [640,480], - mediaTypes: { video: { - minduration:0, - maxduration:999, - boxingallowed:1, - skip:0, - mimes:[ - 'application/javascript', - 'video/mp4' - ], - w:1920, - h:1080, - protocols:[ - 2 - ], - linearity:1, - api:[ - 1, - 2 - ] - } }, - bids: [ - { - bidder: 'bizzclick', - params: { - placementId: 'hash', - accountId: 'accountId' - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/bluebillywigBidAdapter.js b/modules/bluebillywigBidAdapter.js deleted file mode 100644 index cac993b0f8c..00000000000 --- a/modules/bluebillywigBidAdapter.js +++ /dev/null @@ -1,375 +0,0 @@ -import * as utils from '../src/utils.js'; -import find from 'core-js-pure/features/array/find.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { VIDEO } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; -import { Renderer } from '../src/Renderer.js'; -import { createEidsArray } from './userId/eids.js'; - -const DEV_MODE = window.location.search.match(/bbpbs_debug=true/); - -// Blue Billywig Constants -const BB_CONSTANTS = { - BIDDER_CODE: 'bluebillywig', - AUCTION_URL: '$$URL_STARTpbs.bluebillywig.com/openrtb2/auction?pub=$$PUBLICATION', - SYNC_URL: '$$URL_STARTpbs.bluebillywig.com/static/cookie-sync.html?pub=$$PUBLICATION', - RENDERER_URL: 'https://$$PUBLICATION.bbvms.com/r/$$RENDERER.js', - DEFAULT_TIMEOUT: 5000, - DEFAULT_TTL: 300, - DEFAULT_WIDTH: 768, - DEFAULT_HEIGHT: 432, - DEFAULT_NET_REVENUE: true, - VIDEO_PARAMS: ['mimes', 'minduration', 'maxduration', 'protocols', 'w', 'h', 'startdelay', 'placement', 'linearity', 'skip', 'skipmin', - 'skipafter', 'sequence', 'battr', 'maxextended', 'minbitrate', 'maxbitrate', 'boxingallowed', 'playbackmethod', 'playbackend', 'delivery', 'pos', 'companionad', - 'api', 'companiontype', 'ext'] -}; - -// Aliasing -const getConfig = config.getConfig; - -// Helper Functions -const BB_HELPERS = { - addSiteAppDevice: function(request, pageUrl) { - if (typeof getConfig('app') === 'object') request.app = getConfig('app'); - else { - request.site = {}; - if (typeof getConfig('site') === 'object') request.site = getConfig('site'); - if (pageUrl) request.site.page = pageUrl; - } - - if (typeof getConfig('device') === 'object') request.device = getConfig('device'); - if (!request.device) request.device = {}; - if (!request.device.w) request.device.w = window.innerWidth; - if (!request.device.h) request.device.h = window.innerHeight; - }, - addSchain: function(request, validBidRequests) { - const schain = utils.deepAccess(validBidRequests, '0.schain'); - if (schain) request.source.ext = { schain: schain }; - }, - addCurrency: function(request) { - const adServerCur = getConfig('currency.adServerCurrency'); - if (adServerCur && typeof adServerCur === 'string') request.cur = [adServerCur]; - else if (Array.isArray(adServerCur) && adServerCur.length) request.cur = [adServerCur[0]]; - }, - addUserIds: function(request, validBidRequests) { - const bidUserId = utils.deepAccess(validBidRequests, '0.userId'); - const eids = createEidsArray(bidUserId); - - if (eids.length) { - utils.deepSetValue(request, 'user.ext.eids', eids); - } - }, - substituteUrl: function (url, publication, renderer) { - return url.replace('$$URL_START', (DEV_MODE) ? 'https://dev.' : 'https://').replace('$$PUBLICATION', publication).replace('$$RENDERER', renderer); - }, - getAuctionUrl: function(publication) { - return BB_HELPERS.substituteUrl(BB_CONSTANTS.AUCTION_URL, publication); - }, - getSyncUrl: function(publication) { - return BB_HELPERS.substituteUrl(BB_CONSTANTS.SYNC_URL, publication); - }, - getRendererUrl: function(publication, renderer) { - return BB_HELPERS.substituteUrl(BB_CONSTANTS.RENDERER_URL, publication, renderer); - }, - transformVideoParams: function(videoParams, videoParamsExt) { - videoParams = utils.deepClone(videoParams); - - let playerSize = videoParams.playerSize || [BB_CONSTANTS.DEFAULT_WIDTH, BB_CONSTANTS.DEFAULT_HEIGHT]; - if (Array.isArray(playerSize[0])) playerSize = playerSize[0]; - - videoParams.w = playerSize[0]; - videoParams.h = playerSize[1]; - videoParams.placement = 3; - - if (videoParamsExt) videoParams = Object.assign(videoParams, videoParamsExt); - - const videoParamsProperties = Object.keys(videoParams); - - videoParamsProperties.forEach(property => { - if (BB_CONSTANTS.VIDEO_PARAMS.indexOf(property) === -1) delete videoParams[property]; - }); - - return videoParams; - }, - transformRTBToPrebidProps: function(bid, serverResponse) { - const bidObject = { - cpm: bid.price, - currency: serverResponse.cur, - netRevenue: BB_CONSTANTS.DEFAULT_NET_REVENUE, - bidId: bid.impid, - requestId: bid.impid, - creativeId: bid.crid, - mediaType: VIDEO, - width: bid.w || BB_CONSTANTS.DEFAULT_WIDTH, - height: bid.h || BB_CONSTANTS.DEFAULT_HEIGHT, - ttl: BB_CONSTANTS.DEFAULT_TTL - }; - - const extPrebidTargeting = utils.deepAccess(bid, 'ext.prebid.targeting'); - const extPrebidCache = utils.deepAccess(bid, 'ext.prebid.cache'); - - if (extPrebidCache && typeof extPrebidCache.vastXml === 'object' && extPrebidCache.vastXml.cacheId && extPrebidCache.vastXml.url) { - bidObject.videoCacheKey = extPrebidCache.vastXml.cacheId; - bidObject.vastUrl = extPrebidCache.vastXml.url; - } else if (extPrebidTargeting && extPrebidTargeting.hb_uuid && extPrebidTargeting.hb_cache_host && extPrebidTargeting.hb_cache_path) { - bidObject.videoCacheKey = extPrebidTargeting.hb_uuid; - bidObject.vastUrl = `https://${extPrebidTargeting.hb_cache_host}${extPrebidTargeting.hb_cache_path}?uuid=${extPrebidTargeting.hb_uuid}`; - } - if (bid.adm) { - bidObject.ad = bid.adm; - bidObject.vastXml = bid.adm; - } - if (!bidObject.vastUrl && bid.nurl && !bid.adm) { // ad markup is on win notice url, and adm is ommited according to OpenRTB 2.5 - bidObject.vastUrl = bid.nurl; - } - - return bidObject; - }, -}; - -// Renderer Functions -const BB_RENDERER = { - bootstrapPlayer: function(bid) { - const config = { - code: bid.adUnitCode, - }; - - if (bid.vastXml) config.vastXml = bid.vastXml; - else if (bid.vastUrl) config.vastUrl = bid.vastUrl; - - if (!bid.vastXml && !bid.vastUrl) { - utils.logWarn(`${BB_CONSTANTS.BIDDER_CODE}: No vastXml or vastUrl on bid, bailing...`); - return; - } - - if (!(window.bluebillywig && window.bluebillywig.renderers)) { - utils.logWarn(`${BB_CONSTANTS.BIDDER_CODE}: renderer code failed to initialize...`); - return; - } - - const rendererId = BB_RENDERER.getRendererId(bid.publicationName, bid.rendererCode); - const ele = document.getElementById(bid.adUnitCode); // NB convention - const renderer = find(window.bluebillywig.renderers, r => r._id === rendererId); - - if (renderer) renderer.bootstrap(config, ele, bid.rendererSettings || {}); - else utils.logWarn(`${BB_CONSTANTS.BIDDER_CODE}: Couldn't find a renderer with ${rendererId}`); - }, - newRenderer: function(rendererUrl, adUnitCode) { - const renderer = Renderer.install({ - url: rendererUrl, - loaded: false, - adUnitCode - }); - - try { - renderer.setRender(BB_RENDERER.outstreamRender); - } catch (err) { - utils.logWarn(`${BB_CONSTANTS.BIDDER_CODE}: Error tying to setRender on renderer`, err); - } - - return renderer; - }, - outstreamRender: function(bid) { - bid.renderer.push(function() { BB_RENDERER.bootstrapPlayer(bid) }); - }, - getRendererId: function(pub, renderer) { - return `${pub}-${renderer}`; // NB convention! - } -}; - -// Spec Functions -// These functions are used to construct the core spec for the adapter -export const spec = { - code: BB_CONSTANTS.BIDDER_CODE, - supportedMediaTypes: [VIDEO], - syncStore: { bidders: [], }, - isBidRequestValid(bid) { - const publicationNameRegex = /^\w+\.?\w+$/; - const rendererRegex = /^[\w+_]+$/; - - if (!bid.params) { - utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: no params set on bid. Rejecting bid: `, bid); - return false; - } - - if (!bid.params.hasOwnProperty('publicationName') || typeof bid.params.publicationName !== 'string') { - utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: no publicationName specified in bid params, or it's not a string. Rejecting bid: `, bid); - return false; - } else if (!publicationNameRegex.test(bid.params.publicationName)) { - utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: publicationName must be in format 'publication' or 'publication.environment'. Rejecting bid: `, bid); - return false; - } - - if ((!bid.params.hasOwnProperty('rendererCode') || typeof bid.params.rendererCode !== 'string')) { - utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: no rendererCode was specified in bid params. Rejecting bid: `, bid); - return false; - } else if (!rendererRegex.test(bid.params.rendererCode)) { - utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: rendererCode must be alphanumeric, including underscores. Rejecting bid: `, bid); - return false; - } - - if (!bid.params.accountId) { - utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: no accountId specified in bid params. Rejecting bid: `, bid); - return false; - } - - if (bid.params.hasOwnProperty('connections')) { - if (!Array.isArray(bid.params.connections)) { - utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: connections is not of type array. Rejecting bid: `, bid); - return false; - } else { - for (let i = 0; i < bid.params.connections.length; i++) { - if (!bid.params.hasOwnProperty(bid.params.connections[i])) { - utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: connection specified in params.connections, but not configured in params. Rejecting bid: `, bid); - return false; - } - } - } - } else { - utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: no connections specified in bid. Rejecting bid: `, bid); - return false; - } - - if (bid.params.hasOwnProperty('video') && (bid.params.video === null || typeof bid.params.video !== 'object')) { - utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: params.video must be of type object. Rejecting bid: `, bid); - return false; - } - - if (bid.params.hasOwnProperty('rendererSettings') && (bid.params.rendererSettings === null || typeof bid.params.rendererSettings !== 'object')) { - utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: params.rendererSettings must be of type object. Rejecting bid: `, bid); - return false; - } - - if (bid.hasOwnProperty('mediaTypes') && bid.mediaTypes.hasOwnProperty(VIDEO)) { - if (!bid.mediaTypes[VIDEO].hasOwnProperty('context')) { - utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: no context specified in bid. Rejecting bid: `, bid); - return false; - } - - if (bid.mediaTypes[VIDEO].context !== 'outstream') { - utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: video.context is invalid, must be "outstream". Rejecting bid: `, bid); - return false; - } - } else { - utils.logError(`${BB_CONSTANTS.BIDDER_CODE}: mediaTypes or mediaTypes.video is not specified. Rejecting bid: `, bid); - return false; - } - - return true; - }, - buildRequests(validBidRequests, bidderRequest) { - const imps = []; - - validBidRequests.forEach(validBidRequest => { - if (!this.syncStore.publicationName) this.syncStore.publicationName = validBidRequest.params.publicationName; - if (!this.syncStore.accountId) this.syncStore.accountId = validBidRequest.params.accountId; - - const ext = validBidRequest.params.connections.reduce((extBuilder, connection) => { - extBuilder[connection] = validBidRequest.params[connection]; - - if (this.syncStore.bidders.indexOf(connection) === -1) this.syncStore.bidders.push(connection); - - return extBuilder; - }, {}); - - const videoParams = BB_HELPERS.transformVideoParams(utils.deepAccess(validBidRequest, 'mediaTypes.video'), utils.deepAccess(validBidRequest, 'params.video')); - imps.push({ id: validBidRequest.bidId, ext, secure: window.location.protocol === 'https' ? 1 : 0, video: videoParams }); - }); - - const request = { - id: bidderRequest.auctionId, - source: {tid: bidderRequest.auctionId}, - tmax: BB_CONSTANTS.DEFAULT_TIMEOUT, - imp: imps, - test: DEV_MODE ? 1 : 0, - ext: { - prebid: { - targeting: { includewinners: true, includebidderkeys: false } - } - } - }; - - // handle privacy settings for GDPR/CCPA/COPPA - if (bidderRequest.gdprConsent) { - let gdprApplies = 0; - if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') gdprApplies = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; - utils.deepSetValue(request, 'regs.ext.gdpr', gdprApplies); - utils.deepSetValue(request, 'user.ext.consent', bidderRequest.gdprConsent.consentString); - } - - if (bidderRequest.uspConsent) { - utils.deepSetValue(request, 'regs.ext.us_privacy', bidderRequest.uspConsent); - this.syncStore.uspConsent = bidderRequest.uspConsent; - } - - if (getConfig('coppa') == true) utils.deepSetValue(request, 'regs.coppa', 1); - - // Enrich the request with any external data we may have - BB_HELPERS.addSiteAppDevice(request, bidderRequest.refererInfo && bidderRequest.refererInfo.referer); - BB_HELPERS.addSchain(request, validBidRequests); - BB_HELPERS.addCurrency(request); - BB_HELPERS.addUserIds(request, validBidRequests); - - return { - method: 'POST', - url: BB_HELPERS.getAuctionUrl(validBidRequests[0].params.publicationName), - data: JSON.stringify(request), - bidderRequest: bidderRequest - }; - }, - interpretResponse(serverResponse, request) { - serverResponse = serverResponse.body || {}; - - if (!serverResponse.hasOwnProperty('seatbid') || !Array.isArray(serverResponse.seatbid)) { - return []; - } - - const bids = []; - - serverResponse.seatbid.forEach(seatbid => { - if (!seatbid.bid || !Array.isArray(seatbid.bid)) return; - seatbid.bid.forEach(bid => { - bid = BB_HELPERS.transformRTBToPrebidProps(bid, serverResponse); - - const bidParams = find(request.bidderRequest.bids, bidderRequestBid => bidderRequestBid.bidId === bid.bidId).params; - bid.publicationName = bidParams.publicationName; - bid.rendererCode = bidParams.rendererCode; - bid.accountId = bidParams.accountId; - bid.rendererSettings = bidParams.rendererSettings; - - const rendererUrl = BB_HELPERS.getRendererUrl(bid.publicationName, bid.rendererCode); - bid.renderer = BB_RENDERER.newRenderer(rendererUrl, bid.adUnitCode); - - bids.push(bid); - }); - }); - - return bids; - }, - getUserSyncs(syncOptions, serverResponses, gdpr) { - if (!syncOptions.iframeEnabled) return []; - - const queryString = []; - - if (gdpr.gdprApplies) queryString.push(`gdpr=${gdpr.gdprApplies ? 1 : 0}`); - if (gdpr.gdprApplies && gdpr.consentString) queryString.push(`gdpr_consent=${gdpr.consentString}`); - - if (this.syncStore.uspConsent) queryString.push(`usp_consent=${this.syncStore.uspConsent}`); - - queryString.push(`accountId=${this.syncStore.accountId}`); - queryString.push(`bidders=${btoa(JSON.stringify(this.syncStore.bidders))}`); - queryString.push(`cb=${Date.now()}-${Math.random().toString().replace('.', '')}`); - - if (DEV_MODE) queryString.push('bbpbs_debug=true'); - - // NB syncUrl by default starts with ?pub=$$PUBLICATION - const syncUrl = `${BB_HELPERS.getSyncUrl(this.syncStore.publicationName)}&${queryString.join('&')}`; - - return [{ - type: 'iframe', - url: syncUrl - }]; - } -}; - -registerBidder(spec); diff --git a/modules/bluebillywigBidAdapter.md b/modules/bluebillywigBidAdapter.md deleted file mode 100644 index 7879697baf5..00000000000 --- a/modules/bluebillywigBidAdapter.md +++ /dev/null @@ -1,38 +0,0 @@ -# Overview - -``` -Module Name: Blue Billywig Adapter -Module Type: Bidder Adapter -Maintainer: dev+prebid@bluebillywig.com -``` - -# Description - -Prebid Blue Billywig Bidder Adapter - -# Test Parameters - -``` - const adUnits = [{ - code: 'ad-unit', - sizes: [[[768,432],[640,480],[640,360]]], - mediaTypes: { - video: { - playerSize: [768, 432], - context: 'outstream', - mimes: ['video/mp4'], - protocols: [ 2,3,5,6] - } - }, - bids: [{ - bidder: 'bluebillywig', - params: { - publicationName: "bbprebid", - rendererCode: "renderer", - accountId: 642, - connections: [ 'bluebillywig' ], - bluebillywig: {} - } - }] - }]; -``` diff --git a/modules/boldwinBidAdapter.js b/modules/boldwinBidAdapter.js deleted file mode 100644 index 04f4085ba24..00000000000 --- a/modules/boldwinBidAdapter.js +++ /dev/null @@ -1,110 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; - -const BIDDER_CODE = 'boldwin'; -const AD_URL = 'https://ssp.videowalldirect.com/?c=o&m=multi'; -const SYNC_URL = 'https://cs.videowalldirect.com/?c=o&m=cookie' - -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency) { - return false; - } - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl); - case NATIVE: - return Boolean(bid.native && bid.native.title && bid.native.image && bid.native.impressionTrackers); - default: - return false; - } -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO, NATIVE], - - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && bid.params && !isNaN(parseInt(bid.params.placementId))); - }, - - buildRequests: (validBidRequests = [], bidderRequest) => { - let winTop = window; - let location; - try { - location = new URL(bidderRequest.refererInfo.referer) - winTop = window.top; - } catch (e) { - location = winTop.location; - utils.logMessage(e); - }; - let placements = []; - let request = { - 'deviceWidth': winTop.screen.width, - 'deviceHeight': winTop.screen.height, - 'language': (navigator && navigator.language) ? navigator.language.split('-')[0] : '', - 'secure': 1, - 'host': location.host, - 'page': location.pathname, - 'placements': placements - }; - if (bidderRequest) { - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - if (bidderRequest.gdprConsent) { - request.gdpr = bidderRequest.gdprConsent - } - } - const len = validBidRequests.length; - - for (let i = 0; i < len; i++) { - let bid = validBidRequests[i]; - let sizes - if (bid.mediaTypes) { - if (bid.mediaTypes[BANNER] && bid.mediaTypes[BANNER].sizes) { - sizes = bid.mediaTypes[BANNER].sizes - } else if (bid.mediaTypes[VIDEO] && bid.mediaTypes[VIDEO].playerSize) { - sizes = bid.mediaTypes[VIDEO].playerSize - } - } - placements.push({ - placementId: bid.params.placementId, - bidId: bid.bidId, - sizes: sizes || [], - wPlayer: sizes ? sizes[0] : 0, - hPlayer: sizes ? sizes[1] : 0, - traffic: bid.params.traffic || BANNER, - schain: bid.schain || {} - }); - } - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: () => { - return [{ - type: 'image', - url: SYNC_URL - }]; - } -}; - -registerBidder(spec); diff --git a/modules/boldwinBidAdapter.md b/modules/boldwinBidAdapter.md deleted file mode 100644 index 4bf272c4de3..00000000000 --- a/modules/boldwinBidAdapter.md +++ /dev/null @@ -1,53 +0,0 @@ -# Overview - -``` -Module Name: boldwin Bidder Adapter -Module Type: boldwin Bidder Adapter -``` - -# Description - -Module that connects to boldwin demand sources - -# Test Parameters -``` - var adUnits = [ - // Will return static test banner - { - code: 'placementId_0', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [ - { - bidder: 'boldwin', - params: { - placementId: 0, - traffic: 'banner' - } - } - ] - }, - // Will return test vast xml. All video params are stored under placement in publishers UI - { - code: 'placementId_0', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'instream' - } - }, - bids: [ - { - bidder: 'boldwin', - params: { - placementId: 0, - traffic: 'video' - } - } - ] - } - ]; -``` diff --git a/modules/brainyBidAdapter.md b/modules/brainyBidAdapter.md deleted file mode 100644 index 0f8308f6cc3..00000000000 --- a/modules/brainyBidAdapter.md +++ /dev/null @@ -1,31 +0,0 @@ -# Overview - -``` -Module Name: brainy Bid Adapter -Module Type: Bidder Adapter -Maintainer: support@mg.brainy-inc.co.jp -``` - -# Description -This module connects to brainy's demand sources. It supports display, and rich media formats. -brainy will provide ``accountID`` and ``slotID`` that are specific to your ad type. -Please reach out to ``support@mg.brainy-inc.co.jp`` to set up an brainy account and above ids. -Use bidder code ```brainy``` for all brainy traffic. - - -# Test Parameters - -``` - var adUnits = [{ - code: 'test-div', - sizes: [[300, 250], - bids: [{ - bidder: 'brainy', - params: { - accountID: "3481", - slotID: "5569" - } - }] - } - ]; -``` diff --git a/modules/bridgewellBidAdapter.js b/modules/bridgewellBidAdapter.js deleted file mode 100644 index 58c4e907328..00000000000 --- a/modules/bridgewellBidAdapter.js +++ /dev/null @@ -1,293 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE } from '../src/mediaTypes.js'; -import find from 'core-js-pure/features/array/find.js'; - -const BIDDER_CODE = 'bridgewell'; -const REQUEST_ENDPOINT = 'https://prebid.scupio.com/recweb/prebid.aspx?cb=' + Math.random(); -const BIDDER_VERSION = '0.0.3'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, NATIVE], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - let valid = false; - if (bid && bid.params) { - if ((bid.params.cid) && (typeof bid.params.cid === 'number')) { - valid = true; - } else if (bid.params.ChannelID) { - valid = true; - } - } - return valid; - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - const adUnits = []; - utils._each(validBidRequests, function (bid) { - if (bid.params.cid) { - adUnits.push({ - cid: bid.params.cid, - adUnitCode: bid.adUnitCode, - requestId: bid.bidId, - mediaTypes: bid.mediaTypes || { - banner: { - sizes: bid.sizes - } - } - }); - } else { - adUnits.push({ - ChannelID: bid.params.ChannelID, - adUnitCode: bid.adUnitCode, - requestId: bid.bidId, - mediaTypes: bid.mediaTypes || { - banner: { - sizes: bid.sizes - } - } - }); - } - }); - - let topUrl = ''; - if (bidderRequest && bidderRequest.refererInfo) { - topUrl = bidderRequest.refererInfo.referer; - } - - return { - method: 'POST', - url: REQUEST_ENDPOINT, - data: { - version: { - prebid: '$prebid.version$', - bridgewell: BIDDER_VERSION - }, - inIframe: utils.inIframe(), - url: topUrl, - referrer: getTopWindowReferrer(), - adUnits: adUnits, - refererInfo: bidderRequest.refererInfo, - }, - validBidRequests: validBidRequests - }; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @param {*} bidRequest - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function (serverResponse, bidRequest) { - const bidResponses = []; - - // map responses to requests - utils._each(bidRequest.validBidRequests, function (req) { - const bidResponse = {}; - - if (!serverResponse.body) { - return; - } - - let matchedResponse = find(serverResponse.body, function (res) { - let valid = false; - - if (res && !res.consumed) { - let mediaTypes = req.mediaTypes; - let adUnitCode = req.adUnitCode; - if (res.adUnitCode) { - return res.adUnitCode === adUnitCode; - } else if (res.width && res.height && mediaTypes) { - if (mediaTypes.native) { // dont care native sizes - valid = true; - } else if (mediaTypes.banner) { - if (mediaTypes.banner.sizes) { - let width = res.width; - let height = res.height; - let sizes = mediaTypes.banner.sizes; - // check response size validation - if (typeof sizes[0] === 'number') { // for foramt Array[Number] check - valid = width === sizes[0] && height === sizes[1]; - } else { // for format Array[Array[Number]] check - valid = !!find(sizes, function (size) { - return (width === size[0] && height === size[1]); - }); - } - } - } - } - } - - return valid; - }); - - if (matchedResponse) { - matchedResponse.consumed = true; - - // check required parameters - if (typeof matchedResponse.cpm !== 'number') { - return; - } else if (typeof matchedResponse.netRevenue !== 'boolean') { - return; - } else if (typeof matchedResponse.currency !== 'string') { - return; - } else if (typeof matchedResponse.mediaType !== 'string') { - return; - } - - bidResponse.requestId = req.bidId; - bidResponse.cpm = matchedResponse.cpm; - bidResponse.width = matchedResponse.width; - bidResponse.height = matchedResponse.height; - bidResponse.ttl = matchedResponse.ttl; - bidResponse.creativeId = matchedResponse.id; - bidResponse.netRevenue = matchedResponse.netRevenue; - bidResponse.currency = matchedResponse.currency; - bidResponse.mediaType = matchedResponse.mediaType; - - if (matchedResponse.adomain) { - utils.deepSetValue(bidResponse, 'meta.advertiserDomains', Array.isArray(matchedResponse.adomain) ? matchedResponse.adomain : [matchedResponse.adomain]); - } - - // check required parameters by matchedResponse.mediaType - switch (matchedResponse.mediaType) { - case BANNER: - // check banner required parameters - if (typeof matchedResponse.ad !== 'string') { - return; - } - - bidResponse.ad = matchedResponse.ad; - break; - case NATIVE: - // check native required parameters - if (!matchedResponse.native) { - return; - } - - let reqNativeLayout = req.mediaTypes.native; - let resNative = matchedResponse.native; - - // check title - let title = reqNativeLayout.title; - if (title && title.required) { - if (typeof resNative.title !== 'string') { - return; - } else if (title.len && title.len < resNative.title.length) { - return; - } - } - - // check body - let body = reqNativeLayout.body; - if (body && body.required) { - if (typeof resNative.body !== 'string') { - return; - } - } - - // check image - let image = reqNativeLayout.image; - if (image && image.required) { - if (resNative.image) { - if (typeof resNative.image.url !== 'string') { // check image url - return; - } else { - if (resNative.image.width !== image.sizes[0] || resNative.image.height !== image.sizes[1]) { // check image sizes - return; - } - } - } else { - return; - } - } - - // check sponsoredBy - let sponsoredBy = reqNativeLayout.sponsoredBy; - if (sponsoredBy && sponsoredBy.required) { - if (typeof resNative.sponsoredBy !== 'string') { - return; - } - } - - // check icon - let icon = reqNativeLayout.icon; - if (icon && icon.required) { - if (resNative.icon) { - if (typeof resNative.icon.url !== 'string') { // check icon url - return; - } else { - if (resNative.icon.width !== icon.sizes[0] || resNative.icon.height !== icon.sizes[0]) { // check image sizes - return; - } - } - } else { - return; - } - } - - // check clickUrl - if (typeof resNative.clickUrl !== 'string') { - return; - } - - // check clickTracker - let clickTrackers = resNative.clickTrackers; - if (clickTrackers) { - if (clickTrackers.length === 0) { - return; - } - } else { - return; - } - - // check impressionTrackers - let impressionTrackers = resNative.impressionTrackers; - if (impressionTrackers) { - if (impressionTrackers.length === 0) { - return; - } - } else { - return; - } - - bidResponse.native = matchedResponse.native; - - break; - - default: // response mediaType is not supported - return; - } - - bidResponses.push(bidResponse); - } - }); - - return bidResponses; - } -}; - -function getTopWindowReferrer() { - try { - return window.top.document.referrer; - } catch (e) { - return ''; - } -} - -registerBidder(spec); diff --git a/modules/bridgewellBidAdapter.md b/modules/bridgewellBidAdapter.md deleted file mode 100644 index 97e11f6eaf9..00000000000 --- a/modules/bridgewellBidAdapter.md +++ /dev/null @@ -1,77 +0,0 @@ -# Overview - -Module Name: Bridgewell Bidder Adapter -Module Type: Bidder Adapter -Maintainer: scupio@bridgewell.com - -# Description - -Module that connects to Bridgewell demand source to fetch bids. - -# Test Parameters -``` - var adUnits = [{ - code: 'test-div', - mediaTypes: { - banner: { - sizes: [300, 250] - } - }, - bids: [{ - bidder: 'bridgewell', - params: { - cid: 12345 - } - }] - }, { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [728, 90] - } - }, - bids: [{ - bidder: 'bridgewell', - params: { - cid: 56789 - } - }] - }, { - code: 'test-div', - sizes: [1, 1], - mediaTypes: { - native: { - title: { - required: true, - len: 80 - }, - body: { - required: true - }, - image: { - required: true, - sizes: [150, 50] - }, - icon: { - required: false, - sizes: [50, 50] - }, - clickUrl: { - required: true - }, - cta: { - required: false - }, - sponsoredBy: { - required: false - } - } - }, - bids: [{ - bidder: 'bridgewell', - params: { - cid: 2394 - } - }] - }]; -``` diff --git a/modules/brightMountainMediaBidAdapter.js b/modules/brightMountainMediaBidAdapter.js deleted file mode 100644 index 5539004bdcd..00000000000 --- a/modules/brightMountainMediaBidAdapter.js +++ /dev/null @@ -1,129 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; - -const BIDDER_CODE = 'bmtm'; -const AD_URL = 'https://one.elitebidder.com/api/hb'; -const SYNC_URL = 'https://console.brightmountainmedia.com:8443/cookieSync'; - -const videoExt = [ - 'video/x-ms-wmv', - 'video/x-flv', - 'video/mp4', - 'video/3gpp', - 'application/x-mpegURL', - 'video/quicktime', - 'video/x-msvideo', - 'application/x-shockwave-flash', - 'application/javascript' -]; - -export const spec = { - code: BIDDER_CODE, - aliases: ['brightmountainmedia'], - supportedMediaTypes: [BANNER, VIDEO], - - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && bid.params && bid.params.placement_id); - }, - - buildRequests: (validBidRequests, bidderRequest) => { - let winTop = window; - let location; - try { - location = new URL(bidderRequest.refererInfo.referer) - winTop = window.top; - } catch (e) { - location = winTop.location; - utils.logMessage(e); - }; - let placements = []; - let request = { - 'deviceWidth': winTop.screen.width, - 'deviceHeight': winTop.screen.height, - 'language': (navigator && navigator.language) ? navigator.language : '', - 'secure': 1, - 'host': location.host, - 'page': location.pathname, - 'placements': placements - }; - if (bidderRequest) { - if (bidderRequest.gdprConsent) { - request.gdpr_consent = bidderRequest.gdprConsent.consentString || 'ALL' - request.gdpr_require = bidderRequest.gdprConsent.gdprApplies ? 1 : 0 - } - } - for (let i = 0; i < validBidRequests.length; i++) { - let bid = validBidRequests[i]; - let placement = { - placementId: bid.params.placement_id, - bidId: bid.bidId, - }; - - if (bid.mediaTypes.hasOwnProperty(BANNER)) { - placement['traffic'] = BANNER; - if (bid.mediaTypes.banner.sizes) { - placement['sizes'] = bid.mediaTypes.banner.sizes; - } - } - - if (bid.mediaTypes.hasOwnProperty(VIDEO)) { - placement['traffic'] = VIDEO; - if (bid.mediaTypes.video.context) { - placement['context'] = bid.mediaTypes.video.context; - } - if (bid.mediaTypes.video.playerSize) { - placement['sizes'] = bid.mediaTypes.video.playerSize; - } - if (bid.mediaTypes.video.mimes && Array.isArray(bid.mediaTypes.video.mimes)) { - placement['mimes'] = bid.mediaTypes.video.mimes; - } else { - placement['mimes'] = videoExt; - } - if (bid.mediaTypes.video.skip != undefined) { - placement['skip'] = bid.mediaTypes.video.skip; - } - if (bid.mediaTypes.video.playbackmethod && Array.isArray(bid.mediaTypes.video.playbackmethod)) { - placement['playbackmethod'] = bid.mediaTypes.video.playbackmethod; - } - } - if (bid.schain) { - placement.schain = bid.schain; - } - placements.push(placement); - } - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let bidResponse = []; - const response = serverResponse.body; - if (response && Array.isArray(response) && response.length > 0) { - for (let i = 0; i < response.length; i++) { - if (response[i].cpm > 0) { - if (response[i].mediaType && response[i].mediaType === 'video') { - response[i].vastXml = response[i].ad; - } - bidResponse.push(response[i]); - } - } - } - return bidResponse; - }, - - getUserSyncs: (syncOptions) => { - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: SYNC_URL - }]; - } - }, - -}; - -registerBidder(spec); diff --git a/modules/brightMountainMediaBidAdapter.md b/modules/brightMountainMediaBidAdapter.md deleted file mode 100644 index 97cebe5b633..00000000000 --- a/modules/brightMountainMediaBidAdapter.md +++ /dev/null @@ -1,111 +0,0 @@ -# Overview - -``` -Module Name: Bright Mountain Media Bidder Adapter -Module Type: Bidder Adapter -Maintainer: dev@brightmountainmedia.com -``` - -# Description - -Connects to Bright Mountain Media exchange for bids. - -Bright Mountain Media bid adapter currently supports Banner and Video. - -# Sample Ad Unit: For Publishers - -## Sample Banner only Ad Unit - -``` -var adUnits = [ - { - code: 'postbid_iframe', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [ - { - "bidder": "bmtm", - "params": { - "placement_id": 1 - } - } - ] - } - ]; -``` - -## Sample Video only Ad Unit: Outstream - -``` -var adUnits = [ - { - code: 'postbid_iframe_video', - mediaTypes: { - video: { - playerSize: [[640, 480]], - context: 'outstream' - ... // Additional ORTB video params - } - }, - bids: [ - { - bidder: "bmtm", - params: { - placement_id: 1 - } - } - ], - renderer: { - url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', - render: function (bid) { - adResponse = { - ad: { - video: { - content: bid.vastXml, - player_height: bid.height, - player_width: bid.width - } - } - } - // push to render queue because ANOutstreamVideo may not be loaded yet. - bid.renderer.push(() => { - ANOutstreamVideo.renderAd({ - targetId: bid.adUnitCode, - adResponse: adResponse - }); - }); - } - } - } -]; - -``` - -## Sample Video only Ad Unit: Instream - -``` -var adUnits = [ - { - code: 'postbid_iframe_video', - mediaTypes: { - video: { - playerSize: [[640, 480]], - context: 'instream' - ... // Additional ORTB video params - }, - }, - bids: [ - { - bidder: "bmtm", - params: { - placement_id: 1 - } - } - ] - } -]; - -``` diff --git a/modules/brightcomBidAdapter.js b/modules/brightcomBidAdapter.js deleted file mode 100644 index 2aad211b186..00000000000 --- a/modules/brightcomBidAdapter.js +++ /dev/null @@ -1,251 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; - -const BIDDER_CODE = 'brightcom'; -const URL = 'https://brightcombid.marphezis.com/hb'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - isBidRequestValid, - buildRequests, - interpretResponse, - getUserSyncs -}; - -function buildRequests(bidReqs, bidderRequest) { - try { - let referrer = ''; - if (bidderRequest && bidderRequest.refererInfo) { - referrer = bidderRequest.refererInfo.referer; - } - const brightcomImps = []; - const publisherId = utils.getBidIdParameter('publisherId', bidReqs[0].params); - utils._each(bidReqs, function (bid) { - let bidSizes = (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) || bid.sizes; - bidSizes = ((utils.isArray(bidSizes) && utils.isArray(bidSizes[0])) ? bidSizes : [bidSizes]); - bidSizes = bidSizes.filter(size => utils.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, utils.getWindowTop(), minSize) - : 'na'; - const viewabilityAmountRounded = isNaN(viewabilityAmount) ? viewabilityAmount : Math.round(viewabilityAmount); - - const imp = { - id: bid.bidId, - banner: { - format: processedSizes, - ext: { - viewability: viewabilityAmountRounded - } - }, - tagid: String(bid.adUnitCode) - }; - const bidFloor = utils.getBidIdParameter('bidFloor', bid.params); - if (bidFloor) { - imp.bidfloor = bidFloor; - } - brightcomImps.push(imp); - }); - const brightcomBidReq = { - id: utils.getUniqueIdentifierStr(), - imp: brightcomImps, - site: { - domain: utils.parseUrl(referrer).host, - page: referrer, - publisher: { - id: publisherId - } - }, - device: { - devicetype: _getDeviceType(), - w: screen.width, - h: screen.height - }, - tmax: config.getConfig('bidderTimeout') - }; - - if (bidderRequest && bidderRequest.gdprConsent) { - utils.deepSetValue(brightcomBidReq, 'regs.ext.gdpr', +bidderRequest.gdprConsent.gdprApplies); - utils.deepSetValue(brightcomBidReq, 'user.ext.consent', bidderRequest.gdprConsent.consentString); - } - - return { - method: 'POST', - url: URL, - data: JSON.stringify(brightcomBidReq), - options: {contentType: 'text/plain', withCredentials: false} - }; - } catch (e) { - utils.logError(e, {bidReqs, bidderRequest}); - } -} - -function isBidRequestValid(bid) { - if (bid.bidder !== BIDDER_CODE || typeof bid.params === 'undefined') { - return false; - } - - if (typeof bid.params.publisherId === 'undefined') { - return false; - } - - return true; -} - -function interpretResponse(serverResponse) { - if (!serverResponse.body || typeof serverResponse.body != 'object') { - utils.logWarn('Brightcom server returned empty/non-json response: ' + JSON.stringify(serverResponse.body)); - return []; - } - const { body: {id, seatbid} } = serverResponse; - try { - const brightcomBidResponses = []; - if (id && - seatbid && - seatbid.length > 0 && - seatbid[0].bid && - seatbid[0].bid.length > 0) { - seatbid[0].bid.map(brightcomBid => { - brightcomBidResponses.push({ - requestId: brightcomBid.impid, - cpm: parseFloat(brightcomBid.price), - width: parseInt(brightcomBid.w), - height: parseInt(brightcomBid.h), - creativeId: brightcomBid.crid || brightcomBid.id, - currency: 'USD', - netRevenue: true, - mediaType: BANNER, - ad: _getAdMarkup(brightcomBid), - ttl: 60 - }); - }); - } - return brightcomBidResponses; - } catch (e) { - utils.logError(e, {id, seatbid}); - } -} - -// Don't do user sync for now -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 += utils.createTrackPixelHtml(bid.nurl); - } - return adm; -} - -function _isViewabilityMeasurable(element) { - return !_isIframe() && element !== null; -} - -function _getViewability(element, topWin, { w, h } = {}) { - return utils.getWindowTop().document.visibilityState === 'visible' - ? _getPercentInView(element, topWin, { w, h }) - : 0; -} - -function _isIframe() { - try { - return utils.getWindowSelf() !== utils.getWindowTop(); - } catch (e) { - return true; - } -} - -function _getMinSize(sizes) { - return sizes.reduce((min, size) => size.h * size.w < min.h * min.w ? size : min); -} - -function _getBoundingBox(element, { w, h } = {}) { - let { width, height, left, top, right, bottom } = element.getBoundingClientRect(); - - if ((width === 0 || height === 0) && w && h) { - width = w; - height = h; - right = left + w; - bottom = top + h; - } - - return { width, height, left, top, right, bottom }; -} - -function _getIntersectionOfRects(rects) { - const bbox = { - left: rects[0].left, - right: rects[0].right, - top: rects[0].top, - bottom: rects[0].bottom - }; - - for (let i = 1; i < rects.length; ++i) { - bbox.left = Math.max(bbox.left, rects[i].left); - bbox.right = Math.min(bbox.right, rects[i].right); - - if (bbox.left >= bbox.right) { - return null; - } - - bbox.top = Math.max(bbox.top, rects[i].top); - bbox.bottom = Math.min(bbox.bottom, rects[i].bottom); - - if (bbox.top >= bbox.bottom) { - return null; - } - } - - bbox.width = bbox.right - bbox.left; - bbox.height = bbox.bottom - bbox.top; - - return bbox; -} - -function _getPercentInView(element, topWin, { w, h } = {}) { - const elementBoundingBox = _getBoundingBox(element, { w, h }); - - // Obtain the intersection of the element and the viewport - const elementInViewBoundingBox = _getIntersectionOfRects([ { - left: 0, - top: 0, - right: topWin.innerWidth, - bottom: topWin.innerHeight - }, elementBoundingBox ]); - - let elementInViewArea, elementTotalArea; - - if (elementInViewBoundingBox !== null) { - // Some or all of the element is in view - elementInViewArea = elementInViewBoundingBox.width * elementInViewBoundingBox.height; - elementTotalArea = elementBoundingBox.width * elementBoundingBox.height; - - return ((elementInViewArea / elementTotalArea) * 100); - } - - // No overlap between element and the viewport; therefore, the element - // lies completely out of view - return 0; -} - -registerBidder(spec); diff --git a/modules/brightcomBidAdapter.md b/modules/brightcomBidAdapter.md deleted file mode 100644 index 9f9aa0e5dd7..00000000000 --- a/modules/brightcomBidAdapter.md +++ /dev/null @@ -1,46 +0,0 @@ -# Overview - -``` -Module Name: Brightcom Bid Adapter -Module Type: Bidder Adapter -Maintainer: vladislavy@brightcom.com -``` - -# Description - -Brightcom's adapter integration to the Prebid library. - -# Test Parameters - -``` -var adUnits = [ - { - code: 'test-leaderboard', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - }, - bids: [{ - bidder: 'brightcom', - params: { - publisherId: 2141020, - bidFloor: 0.01 - } - }] - }, { - code: 'test-banner', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [{ - bidder: 'brightcom', - params: { - publisherId: 2141020 - } - }] - } -] -``` diff --git a/modules/britepoolIdSystem.js b/modules/britepoolIdSystem.js deleted file mode 100644 index 3bf416957d2..00000000000 --- a/modules/britepoolIdSystem.js +++ /dev/null @@ -1,142 +0,0 @@ -/** - * This module adds BritePoolId to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/britepoolIdSystem - * @requires module:modules/userId - */ - -import * as utils from '../src/utils.js' -import {ajax} from '../src/ajax.js'; -import {submodule} from '../src/hook.js'; -const PIXEL = 'https://px.britepool.com/new?partner_id=t'; - -/** @type {Submodule} */ -export const britepoolIdSubmodule = { - /** - * Used to link submodule with config - * @type {string} - */ - name: 'britepoolId', - /** - * Decode the stored id value for passing to bid requests - * @function - * @param {string} value - * @returns {{britepoolid:string}} - */ - decode(value) { - return (value && typeof value['primaryBPID'] === 'string') ? { 'britepoolid': value['primaryBPID'] } : null; - }, - /** - * Performs action to obtain id and return a value in the callback's response argument - * @function - * @param {SubmoduleConfig} [submoduleConfig] - * @param {ConsentData|undefined} consentData - * @returns {function(callback:function)} - */ - getId(submoduleConfig, consentData) { - const submoduleConfigParams = (submoduleConfig && submoduleConfig.params) || {}; - const { params, headers, url, getter, errors } = britepoolIdSubmodule.createParams(submoduleConfigParams, consentData); - let getterResponse = null; - if (typeof getter === 'function') { - getterResponse = getter(params); - // First let's rule out that the response is not a function - if (typeof getterResponse !== 'function') { - // Optimization to return value from getter - return { - id: britepoolIdSubmodule.normalizeValue(getterResponse) - }; - } - } - if (utils.isEmpty(params)) { - utils.triggerPixel(PIXEL); - } - // Return for async operation - return { - callback: function(callback) { - if (errors.length > 0) { - errors.forEach(error => utils.logError(error)); - callback(); - return; - } - if (getterResponse) { - // Resolve the getter function response - try { - getterResponse(function(response) { - callback(britepoolIdSubmodule.normalizeValue(response)); - }); - } catch (error) { - if (error !== '') utils.logError(error); - callback(); - } - } else { - ajax(url, { - success: response => { - const responseObj = britepoolIdSubmodule.normalizeValue(response); - callback(responseObj ? { primaryBPID: responseObj.primaryBPID } : null); - }, - error: error => { - if (error !== '') utils.logError(error); - callback(); - } - }, JSON.stringify(params), { customHeaders: headers, contentType: 'application/json', method: 'POST', withCredentials: true }); - } - } - } - }, - /** - * Helper method to create params for our API call - * @param {SubmoduleParams} [submoduleConfigParams] - * @param {ConsentData|undefined} consentData - * @returns {object} Object with parsed out params - */ - createParams(submoduleConfigParams, consentData) { - const hasGdprData = consentData && typeof consentData.gdprApplies === 'boolean' && consentData.gdprApplies; - const gdprConsentString = hasGdprData ? consentData.consentString : undefined; - let errors = []; - const headers = {}; - const dynamicVars = typeof britepool_pubparams !== 'undefined' ? britepool_pubparams : {}; // eslint-disable-line camelcase, no-undef - let params = Object.assign({}, submoduleConfigParams, dynamicVars); - if (params.getter) { - // Custom getter will not require other params - if (typeof params.getter !== 'function') { - errors.push(`userIdTargeting - britepoolId submodule requires getter to be a function`); - return { errors }; - } - } else { - if (params.api_key) { - // Add x-api-key into the header - headers['x-api-key'] = params.api_key; - } - } - const url = params.url || `https://api.britepool.com/v1/britepool/id${gdprConsentString ? '?gdprString=' + encodeURIComponent(gdprConsentString) : ''}`; - const getter = params.getter; - delete params.api_key; - delete params.url; - delete params.getter; - return { - params, - headers, - url, - getter, - errors - }; - }, - /** - * Helper method to normalize a JSON value - */ - normalizeValue(value) { - let valueObj = null; - if (typeof value === 'object') { - valueObj = value; - } else if (typeof value === 'string') { - try { - valueObj = JSON.parse(value); - } catch (error) { - utils.logError(error); - } - } - return valueObj; - } -}; - -submodule('userId', britepoolIdSubmodule); diff --git a/modules/britepoolIdSystem.md b/modules/britepoolIdSystem.md deleted file mode 100644 index 72edbe2324b..00000000000 --- a/modules/britepoolIdSystem.md +++ /dev/null @@ -1,42 +0,0 @@ -## BritePool User ID Submodule - -BritePool User ID Module. For assistance setting up your module please contact us at [prebid@britepool.com](prebid@britepool.com). - -### Prebid Params - -Individual params may be set for the BritePool User ID Submodule. -``` -pbjs.setConfig({ - userSync: { - userIds: [{ - name: 'britepoolId', - storage: { - name: 'britepoolid', - type: 'cookie', - expires: 30 - }, - params: { - url: 'https://sandbox-api.britepool.com/v1/britepool/id', // optional - api_key: '3fdbe297-3690-4f5c-9e11-ee9186a6d77c', // provided by britepool - hash: '31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66', // example hash identifier (sha256) - ssid: '221aa074-57fc-453b-81f0-6c74f628cd5c' // example identifier - } - }] - } -}); -``` -## Parameter Descriptions for the `usersync` Configuration Section -The below parameters apply only to the BritePool User ID Module integration. - -| Param under usersync.userIds[] | Scope | Type | Description | Example | -| --- | --- | --- | --- | --- | -| name | Required | String | ID value for the BritePool module - `"britepoolId"` | `"britepoolId"` | -| params | Required | Object | Details for BritePool initialization. | | -| params.api_key | Required | String |BritePool API Key provided by BritePool | "3fdbe297-3690-4f5c-9e11-ee9186a6d77c" | -| params.url | Optional | String |BritePool API url | "https://sandbox-api.britepool.com/v1/britepool/id" | -| params.identifier | Required | String | Where identifier in the params object is the key name. At least one identifier is required. Available Identifiers `aaid` `dtid` `idfa` `ilid` `luid` `mmid` `msid` `mwid` `rida` `ssid` `hash` | `params.ssid` `params.aaid` | -| storage | Required | Object | The publisher must specify the local storage in which to store the results of the call to get the user ID. This can be either cookie or HTML5 storage. | | -| storage.type | Required | String | This is where the results of the user ID will be stored. The recommended method is `localStorage` by specifying `html5`. | `"html5"` | -| storage.name | Required | String | The name of the cookie or html5 local storage where the user ID will be stored. | `"britepoolid"` | -| storage.expires | Optional | Integer | How long (in days) the user ID information will be stored. | `365` | -| value | Optional | Object | Used only if the page has a separate mechanism for storing the BritePool ID. The value is an object containing the values to be sent to the adapters. In this scenario, no URL is called and nothing is added to local storage | `{"primaryBPID": "eb33b0cb-8d35-4722-b9c0-1a31d4064888"}` | diff --git a/modules/browsiRtdProvider.js b/modules/browsiRtdProvider.js deleted file mode 100644 index 4ee338e94cc..00000000000 --- a/modules/browsiRtdProvider.js +++ /dev/null @@ -1,270 +0,0 @@ -/** - * This module adds browsi provider to the eal time data module - * The {@link module:modules/realTimeData} module is required - * The module will fetch predictions from browsi server - * The module will place browsi bootstrap script on page - * @module modules/browsiProvider - * @requires module:modules/realTimeData - */ - -/** - * @typedef {Object} ModuleParams - * @property {string} siteKey - * @property {string} pubKey - * @property {string} url - * @property {?string} keyName - */ - -import * as utils from '../src/utils.js'; -import {submodule} from '../src/hook.js'; -import {ajaxBuilder} from '../src/ajax.js'; -import {loadExternalScript} from '../src/adloader.js'; -import {getStorageManager} from '../src/storageManager.js'; -import find from 'core-js-pure/features/array/find.js'; - -const storage = getStorageManager(); - -/** @type {ModuleParams} */ -let _moduleParams = {}; -/** @type {null|Object} */ -let _predictionsData = null; -/** @type {string} */ -const DEF_KEYNAME = 'browsiViewability'; - -/** - * add browsi script to page - * @param {Object} data - */ -export function addBrowsiTag(data) { - let script = loadExternalScript(data.u, 'browsi'); - script.async = true; - script.setAttribute('data-sitekey', _moduleParams.siteKey); - script.setAttribute('data-pubkey', _moduleParams.pubKey); - script.setAttribute('prebidbpt', 'true'); - script.setAttribute('id', 'browsi-tag'); - script.setAttribute('src', data.u); - script.prebidData = utils.deepClone(data); - if (_moduleParams.keyName) { - script.prebidData.kn = _moduleParams.keyName; - } - return script; -} - -/** - * collect required data from page - * send data to browsi server to get predictions - */ -export function collectData() { - const win = window.top; - const doc = win.document; - let browsiData = null; - try { - browsiData = storage.getDataFromLocalStorage('__brtd'); - } catch (e) { - utils.logError('unable to parse __brtd'); - } - - let predictorData = { - ...{ - sk: _moduleParams.siteKey, - sw: (win.screen && win.screen.width) || -1, - sh: (win.screen && win.screen.height) || -1, - url: `${doc.location.protocol}//${doc.location.host}${doc.location.pathname}`, - }, - ...(browsiData ? {us: browsiData} : {us: '{}'}), - ...(document.referrer ? {r: document.referrer} : {}), - ...(document.title ? {at: document.title} : {}) - }; - getPredictionsFromServer(`//${_moduleParams.url}/prebid?${toUrlParams(predictorData)}`); -} - -export function setData(data) { - _predictionsData = data; -} - -function sendDataToModule(adUnitsCodes) { - try { - const _predictions = (_predictionsData && _predictionsData.p) || {}; - return adUnitsCodes.reduce((rp, adUnitCode) => { - if (!adUnitCode) { - return rp - } - const adSlot = getSlotByCode(adUnitCode); - const identifier = adSlot ? getMacroId(_predictionsData['pmd'], adSlot) : adUnitCode; - const predictionData = _predictions[identifier]; - rp[adUnitCode] = getKVObject(-1, _predictionsData['kn']); - if (!predictionData) { - return rp - } - if (predictionData.p) { - if (!isIdMatchingAdUnit(adSlot, predictionData.w)) { - return rp; - } - rp[adUnitCode] = getKVObject(predictionData.p, _predictionsData.kn); - } - return rp; - }, {}); - } catch (e) { - return {}; - } -} - -/** - * get all slots on page - * @return {Object[]} slot GoogleTag slots - */ -function getAllSlots() { - return utils.isGptPubadsDefined() && window.googletag.pubads().getSlots(); -} -/** - * get prediction and return valid object for key value set - * @param {number} p - * @param {string?} keyName - * @return {Object} key:value - */ -function getKVObject(p, keyName) { - const prValue = p < 0 ? 'NA' : (Math.floor(p * 10) / 10).toFixed(2); - let prObject = {}; - prObject[((_moduleParams['keyName'] || keyName || DEF_KEYNAME).toString())] = prValue.toString(); - return prObject; -} -/** - * check if placement id matches one of given ad units - * @param {Object} slot google slot - * @param {string[]} whitelist ad units - * @return {boolean} - */ -export function isIdMatchingAdUnit(slot, whitelist) { - if (!whitelist || !whitelist.length || !slot) { - return true; - } - const slotAdUnits = slot.getAdUnitPath(); - return whitelist.indexOf(slotAdUnits) !== -1; -} - -/** - * get GPT slot by placement id - * @param {string} code placement id - * @return {?Object} - */ -function getSlotByCode(code) { - const slots = getAllSlots(); - if (!slots || !slots.length) { - return null; - } - return find(slots, s => s.getSlotElementId() === code || s.getAdUnitPath() === code) || null; -} - -/** - * generate id according to macro script - * @param {Object} macro replacement macro - * @param {Object} slot google slot - * @return {?Object} - */ -export function getMacroId(macro, slot) { - if (macro) { - try { - const macroResult = evaluate(macro, slot.getSlotElementId(), slot.getAdUnitPath(), (match, p1) => { - return (p1 && slot.getTargeting(p1).join('_')) || 'NA'; - }); - return macroResult; - } catch (e) { - utils.logError(`failed to evaluate: ${macro}`); - } - } - return slot.getSlotElementId(); -} - -function evaluate(macro, divId, adUnit, replacer) { - let macroResult = macro.p - .replace(/['"]+/g, '') - .replace(//g, divId); - - if (adUnit) { - macroResult = macroResult.replace(//g, adUnit); - } - if (replacer) { - macroResult = macroResult.replace(//g, replacer); - } - if (macro.s) { - macroResult = macroResult.substring(macro.s.s, macro.s.e); - } - return macroResult; -} -/** - * XMLHttpRequest to get data form browsi server - * @param {string} url server url with query params - */ -function getPredictionsFromServer(url) { - let ajax = ajaxBuilder(); - - ajax(url, - { - success: function (response, req) { - if (req.status === 200) { - try { - const data = JSON.parse(response); - if (data && data.p && data.kn) { - setData({p: data.p, kn: data.kn, pmd: data.pmd}); - } else { - setData({}); - } - addBrowsiTag(data); - } catch (err) { - utils.logError('unable to parse data'); - setData({}) - } - } else if (req.status === 204) { - // unrecognized site key - setData({}); - } - }, - error: function () { - setData({}); - utils.logError('unable to get prediction data'); - } - } - ); -} - -/** - * serialize object and return query params string - * @param {Object} data - * @return {string} - */ -function toUrlParams(data) { - return Object.keys(data) - .map(key => key + '=' + encodeURIComponent(data[key])) - .join('&'); -} - -/** @type {RtdSubmodule} */ -export const browsiSubmodule = { - /** - * used to link submodule with realTimeData - * @type {string} - */ - name: 'browsi', - /** - * get data and send back to realTimeData module - * @function - * @param {string[]} adUnitsCodes - */ - getTargetingData: sendDataToModule, - init: init, -}; - -function init(moduleConfig) { - _moduleParams = moduleConfig.params; - if (_moduleParams && _moduleParams.siteKey && _moduleParams.pubKey && _moduleParams.url) { - collectData(); - } else { - utils.logError('missing params for Browsi provider'); - } - return true; -} - -function registerSubModule() { - submodule('realTimeData', browsiSubmodule); -} -registerSubModule(); diff --git a/modules/browsiRtdProvider.md b/modules/browsiRtdProvider.md deleted file mode 100644 index 9eed4b2b2d4..00000000000 --- a/modules/browsiRtdProvider.md +++ /dev/null @@ -1,55 +0,0 @@ -# Overview - -The Browsi RTD module provides viewability predictions for ad slots on the page. -To use this module, you’ll need to work with [Browsi](https://gobrowsi.com/) to get an account and receive instructions on how to set up your pages and ad server. - -# Configurations - -Compile the Browsi RTD Provider into your Prebid build: - -`gulp build --modules=browsiRtdProvider` - - -Configuration example for using RTD module with `browsi` provider -```javascript - pbjs.setConfig({ - "realTimeData": { - "auctionDelay": 1000, - dataProviders:[{ - "name": "browsi", - "waitForIt": "true" - "params": { - "url": "yield-manager.browsiprod.com", - "siteKey": "browsidemo", - "pubKey": "browsidemo" - "keyName":"bv" - } - }] - } - }); -``` - -#Params - -Contact Browsi to get required params - -| param name | type |Scope | Description | -| :------------ | :------------ | :------- | :------- | -| url | string | required | Browsi server URL | -| siteKey | string | required | Site key | -| pubKey | string | required | Publisher key | -| keyName | string | optional | Ad unit targeting key | - - -#Output -`getTargetingData` function will return expected viewability prediction in the following structure: -```json -{ - "adUnitCode":{ - "browsiViewability":"0.6" - }, - "adUnitCode2":{ - "browsiViewability":"0.9" - } -} -``` diff --git a/modules/bucksenseBidAdapter.js b/modules/bucksenseBidAdapter.js deleted file mode 100644 index 46d0dfe3590..00000000000 --- a/modules/bucksenseBidAdapter.js +++ /dev/null @@ -1,128 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; - -const WHO = 'BKSHBID-005'; -const BIDDER_CODE = 'bucksense'; -const URL = 'https://prebid.bksn.se/prebidjs/'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {object} bid The bid to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - utils.logInfo(WHO + ' isBidRequestValid() - INPUT bid:', bid); - if (bid.bidder !== BIDDER_CODE || typeof bid.params === 'undefined') { - return false; - } - if (typeof bid.params.placementId === 'undefined') { - return false; - } - return true; - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests A non-empty list of valid bid requests that should be sent to the Server. - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - utils.logInfo(WHO + ' buildRequests() - INPUT validBidRequests:', validBidRequests, 'INPUT bidderRequest:', bidderRequest); - let requests = []; - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - var bid = validBidRequests[i]; - var params = {}; - for (var key in bid.params) { - if (bid.params.hasOwnProperty(key)) { - params[key] = encodeURI(bid.params[key]); - } - } - delete bid.params; - var sizes = bid.sizes; - delete bid.sizes; - var sendData = { - 'pub_id': location.host, - 'pl_id': '' + params.placementId, - 'secure': (location.protocol === 'https:') ? 1 : 0, - 'href': encodeURI(location.href), - 'bid_id': bid.bidId, - 'params': params, - 'sizes': sizes, - '_bid': bidderRequest - }; - requests.push({ - method: 'POST', - url: URL, - data: sendData - }); - } - utils.logInfo(WHO + ' buildRequests() - requests:', requests); - return requests; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function (serverResponse, request) { - utils.logInfo(WHO + ' interpretResponse() - INPUT serverResponse:', serverResponse, 'INPUT request:', request); - - const bidResponses = []; - if (serverResponse.body) { - var oResponse = serverResponse.body; - - var sRequestID = oResponse.requestId || ''; - var nCPM = oResponse.cpm || 0; - var nWidth = oResponse.width || 0; - var nHeight = oResponse.height || 0; - var nTTL = oResponse.ttl || 0; - var sCreativeID = oResponse.creativeId || 0; - var sCurrency = oResponse.currency || 'USD'; - var bNetRevenue = oResponse.netRevenue || true; - var sAd = oResponse.ad || ''; - var sAdomains = oResponse.adomains || []; - - if (request && sRequestID.length == 0) { - utils.logInfo(WHO + ' interpretResponse() - use RequestID from Placments'); - sRequestID = request.data.bid_id || ''; - } - - if (request && request.data.params.hasOwnProperty('testcpm')) { - utils.logInfo(WHO + ' interpretResponse() - use Test CPM '); - nCPM = request.data.params.testcpm; - } - - let bidResponse = { - requestId: sRequestID, - cpm: nCPM, - width: nWidth, - height: nHeight, - ttl: nTTL, - creativeId: sCreativeID, - currency: sCurrency, - netRevenue: bNetRevenue, - ad: sAd, - meta: { - advertiserDomains: sAdomains - } - }; - bidResponses.push(bidResponse); - } else { - utils.logInfo(WHO + ' interpretResponse() - serverResponse not valid'); - } - utils.logInfo(WHO + ' interpretResponse() - return', bidResponses); - return bidResponses; - }, - -}; -registerBidder(spec); diff --git a/modules/bucksenseBidAdapter.md b/modules/bucksenseBidAdapter.md deleted file mode 100644 index a240a2c31d8..00000000000 --- a/modules/bucksenseBidAdapter.md +++ /dev/null @@ -1,38 +0,0 @@ -# Overview - -``` -Module Name: Bucksense Bidder Adapter -Module Type: Bidder Adapter -Maintainer: stefano.dechicchis@bucksense.com -``` - -# Description - -Use `bucksense` as bidder. - -`placementId` is required, use the Placement ID received by Bucksense. - - -Module that connects to Example's demand sources - -## AdUnits configuration example -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [ - { - bidder: "bucksense", - params: { - placementId : 1000 - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/buzzoolaBidAdapter.js b/modules/buzzoolaBidAdapter.js deleted file mode 100644 index f87607657c3..00000000000 --- a/modules/buzzoolaBidAdapter.js +++ /dev/null @@ -1,108 +0,0 @@ -import * as utils 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 {OUTSTREAM} from '../src/video.js'; - -const BIDDER_CODE = 'buzzoola'; -const ENDPOINT = 'https://exchange.buzzoola.com/ssp/prebidjs'; -const RENDERER_SRC = 'https://tube.buzzoola.com/new/build/buzzlibrary.js'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['buzzoolaAdapter'], - supportedMediaTypes: [BANNER, VIDEO], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return {boolean} True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - let types = bid.mediaTypes; - return !!(bid && bid.mediaTypes && (types.banner || types.video) && bid.params && bid.params.placementId); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests an array of bids - * @param bidderRequest - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - return { - url: ENDPOINT, - method: 'POST', - data: bidderRequest, - } - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {ServerResponse} serverResponse A successful response from the server. - * @param bidderRequest - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function ({body}, {data}) { - let requestBids = {}; - let response; - - try { - response = JSON.parse(body); - } catch (ex) { - response = body; - } - - if (!Array.isArray(response)) response = []; - - data.bids.forEach(bid => requestBids[bid.bidId] = bid); - - return response.map(bid => { - let requestBid = requestBids[bid.requestId]; - let context = utils.deepAccess(requestBid, 'mediaTypes.video.context'); - let validBid = utils.deepClone(bid); - - if (validBid.mediaType === VIDEO && context === OUTSTREAM) { - let renderer = Renderer.install({ - id: validBid.requestId, - url: RENDERER_SRC, - loaded: false - }); - - renderer.setRender(setOutstreamRenderer); - validBid.renderer = renderer - } - - return validBid; - }); - } -}; - -/** - * Initialize Buzzoola Outstream player - * - * @param bid - */ -function setOutstreamRenderer(bid) { - let adData = JSON.parse(bid.ad); - let unitSettings = utils.deepAccess(adData, 'placement.unit_settings'); - let extendedSettings = { - width: '' + bid.width, - height: '' + bid.height, - container_height: '' + bid.height - }; - - adData.placement = Object.assign({}, adData.placement); - adData.placement.unit_settings = Object.assign({}, unitSettings, extendedSettings); - - bid.renderer.push(() => { - window.Buzzoola.Core.install(document.querySelector(`#${bid.adUnitCode}`), { - data: adData - }); - }); -} - -registerBidder(spec); diff --git a/modules/buzzoolaBidAdapter.md b/modules/buzzoolaBidAdapter.md deleted file mode 100644 index aec3eda6c58..00000000000 --- a/modules/buzzoolaBidAdapter.md +++ /dev/null @@ -1,72 +0,0 @@ -# Overview - -``` -Module Name: Buzzoola Bid Adapter -Module Type: Bidder Adapter -Maintainer: devteam@buzzoola.com -``` - -# Description - -Connects to Buzzoola exchange for bids. - -Buzzoola bid adapter supports Banner and Video (instream and outstream). - -# Test Parameters -``` -var adUnits = [ - // Banner adUnit - { - code: 'banner-div', - mediaTypes: { - banner: { - sizes: [[240, 400], [300, 600]], - } - }, - bids: [{ - bidder: 'buzzoola', - params: { - placementId: 417846 - } - }] - }, - // Video instream adUnit - { - code: 'video-instream', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 380], - mimes: ['video/mp4'], - minduration: 1, - maxduration: 2, - } - }, - bids: [{ - bidder: 'buzzoola', - params: { - placementId: 417845 - } - }] - }, - // Video outstream adUnit - { - code: 'video-outstream', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [640, 380], - mimes: ['video/mp4'], - minduration: 1, - maxduration: 2, - } - }, - bids: [{ - bidder: 'buzzoola', - params: { - placementId: 417845 - } - }] - } -]; -``` diff --git a/modules/byplayBidAdapter.js b/modules/byplayBidAdapter.js deleted file mode 100644 index 6133cdfa647..00000000000 --- a/modules/byplayBidAdapter.js +++ /dev/null @@ -1,67 +0,0 @@ -import { config } from '../src/config.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { Renderer } from '../src/Renderer.js'; -import { VIDEO } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'byplay'; -const ENDPOINT_URL = 'https://prebid.byplay.net/bidder'; -const VIDEO_PLAYER_URL = 'https://cdn.byplay.net/prebid-byplay-v2.js'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [VIDEO], - isBidRequestValid: (bid) => { - return !!bid.params.sectionId; - }, - buildRequests: function(validBidRequests) { - return validBidRequests.map(req => { - const payload = { - requestId: req.bidId, - sectionId: req.params.sectionId, - ...(req.params.env ? { env: req.params.env } : {}) - }; - - return { - method: 'POST', - url: ENDPOINT_URL, - data: JSON.stringify(payload), - options: { - withCredentials: false - } - }; - }); - }, - interpretResponse: (serverResponse, bidderRequest) => { - const response = serverResponse.body; - const data = JSON.parse(bidderRequest.data); - const bidResponse = { - requestId: data.requestId, - cpm: response.cpm, - width: response.width, - height: response.height, - creativeId: response.creativeId || '0', - ttl: config.getConfig('_bidderTimeout'), - currency: 'JPY', - netRevenue: response.netRevenue, - mediaType: VIDEO, - vastXml: response.vastXml, - renderer: createRenderer() - }; - - return [bidResponse]; - } -}; - -function createRenderer() { - const renderer = Renderer.install({ url: VIDEO_PLAYER_URL }); - - renderer.setRender(bid => { - bid.renderer.push(() => { - window.adtagRender(bid); - }); - }); - - return renderer; -} - -registerBidder(spec); diff --git a/modules/byplayBidAdapter.md b/modules/byplayBidAdapter.md deleted file mode 100644 index 67fb9c40d35..00000000000 --- a/modules/byplayBidAdapter.md +++ /dev/null @@ -1,37 +0,0 @@ -# Overview - -``` -Module Name: ByPlay Bidder Adapter -Module Type: Bidder Adapter -Maintainer: byplayers@tsumikiinc.com -``` - -# Description - -Connects to ByPlay exchange for bids. - -ByPlay bid adapter supports Video. - -# Test Parameters -``` - const adUnits = [ - { - code: 'byplay-ad', - mediaTypes: { - video: { - playerSize: [400, 225], - context: 'outstream' - } - }, - bids: [ - { - bidder: 'byplay', - params: { - sectionId: '7986', - env: 'dev' - } - } - ] - } - ]; -``` diff --git a/modules/c1xBidAdapter.js b/modules/c1xBidAdapter.js deleted file mode 100644 index 8e1f1487ba7..00000000000 --- a/modules/c1xBidAdapter.js +++ /dev/null @@ -1,178 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import * as utils from '../src/utils.js'; -import { userSync } from '../src/userSync.js'; - -const BIDDER_CODE = 'c1x'; -const URL = 'https://ht.c1exchange.com/ht'; -const PIXEL_ENDPOINT = 'https://px.c1exchange.com/pubpixel/'; -const LOG_MSG = { - invalidBid: 'C1X: [ERROR] bidder returns an invalid bid', - noSite: 'C1X: [ERROR] no site id supplied', - noBid: 'C1X: [INFO] creating a NO bid for Adunit: ', - bidWin: 'C1X: [INFO] creating a bid for Adunit: ' -}; - -/** - * Adapter for requesting bids from C1X header tag server. - * v3.1 (c) C1X Inc., 2018 - */ - -export const c1xAdapter = { - code: BIDDER_CODE, - - // check the bids sent to c1x bidder - isBidRequestValid: function(bid) { - const siteId = bid.params.siteId || ''; - if (!siteId) { - utils.logError(LOG_MSG.noSite); - } - return !!(bid.adUnitCode && siteId); - }, - - buildRequests: function(bidRequests, bidderRequest) { - let payload = {}; - let tagObj = {}; - let pixelUrl = ''; - const adunits = bidRequests.length; - const rnd = new Date().getTime(); - const c1xTags = bidRequests.map(bidToTag); - const bidIdTags = bidRequests.map(bidToShortTag); // include only adUnitCode and bidId from request obj - - // flattened tags in a tag object - tagObj = c1xTags.reduce((current, next) => Object.assign(current, next)); - const pixelId = tagObj.pixelId; - - payload = { - adunits: adunits.toString(), - rnd: rnd.toString(), - response: 'json', - compress: 'gzip' - } - - // for GDPR support - if (bidderRequest && bidderRequest.gdprConsent) { - payload['consent_string'] = bidderRequest.gdprConsent.consentString; - payload['consent_required'] = (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') ? bidderRequest.gdprConsent.gdprApplies.toString() : 'true' - ; - } - - if (pixelId) { - pixelUrl = PIXEL_ENDPOINT + pixelId; - if (payload.consent_required) { - pixelUrl += '&gdpr=' + (bidderRequest.gdprConsent.gdprApplies ? 1 : 0); - pixelUrl += '&consent=' + encodeURIComponent(bidderRequest.gdprConsent.consentString || ''); - } - userSync.registerSync('image', BIDDER_CODE, pixelUrl); - } - - Object.assign(payload, tagObj); - - let payloadString = stringifyPayload(payload); - // ServerRequest object - return { - method: 'GET', - url: URL, - data: payloadString, - bids: bidIdTags - }; - }, - - interpretResponse: function(serverResponse, requests) { - serverResponse = serverResponse.body; - requests = requests.bids || []; - const currency = 'USD'; - const bidResponses = []; - let netRevenue = false; - - if (!serverResponse || serverResponse.error) { - let errorMessage = serverResponse.error; - utils.logError(LOG_MSG.invalidBid + errorMessage); - return bidResponses; - } else { - serverResponse.forEach(bid => { - if (bid.bid) { - if (bid.bidType === 'NET_BID') { - netRevenue = !netRevenue; - } - const curBid = { - width: bid.width, - height: bid.height, - cpm: bid.cpm, - ad: bid.ad, - creativeId: bid.crid, - currency: currency, - ttl: 300, - netRevenue: netRevenue - }; - - for (let i = 0; i < requests.length; i++) { - if (bid.adId === requests[i].adUnitCode) { - curBid.requestId = requests[i].bidId; - } - } - utils.logInfo(LOG_MSG.bidWin + bid.adId + ' size: ' + curBid.width + 'x' + curBid.height); - bidResponses.push(curBid); - } else { - // no bid - utils.logInfo(LOG_MSG.noBid + bid.adId); - } - }); - } - - return bidResponses; - } -} - -function bidToTag(bid, index) { - const tag = {}; - const adIndex = 'a' + (index + 1).toString(); // ad unit id for c1x - const sizeKey = adIndex + 's'; - const priceKey = adIndex + 'p'; - // TODO: Multiple Floor Prices - - const sizesArr = bid.sizes; - const floorPriceMap = bid.params.floorPriceMap || ''; - tag['site'] = bid.params.siteId || ''; - - // prevent pixelId becoming undefined when publishers don't fill this param in ad units they have on the same page - if (bid.params.pixelId) { - tag['pixelId'] = bid.params.pixelId - } - - tag[adIndex] = bid.adUnitCode; - tag[sizeKey] = sizesArr.reduce((prev, current) => prev + (prev === '' ? '' : ',') + current.join('x'), ''); - - const newSizeArr = tag[sizeKey].split(','); - if (floorPriceMap) { - newSizeArr.forEach(size => { - if (size in floorPriceMap) { - tag[priceKey] = floorPriceMap[size].toString(); - } // we only accept one cpm price in floorPriceMap - }); - } - if (bid.params.pageurl) { - tag['pageurl'] = bid.params.pageurl; - } - - return tag; -} - -function bidToShortTag(bid) { - const tag = {}; - tag.adUnitCode = bid.adUnitCode; - tag.bidId = bid.bidId; - - return tag; -} - -function stringifyPayload(payload) { - let payloadString = ''; - payloadString = JSON.stringify(payload).replace(/":"|","|{"|"}/g, (foundChar) => { - if (foundChar == '":"') return '='; - else if (foundChar == '","') return '&'; - else return ''; - }); - return payloadString; -} - -registerBidder(c1xAdapter); diff --git a/modules/c1xBidAdapter.md b/modules/c1xBidAdapter.md deleted file mode 100644 index 83a4ff1ea81..00000000000 --- a/modules/c1xBidAdapter.md +++ /dev/null @@ -1,32 +0,0 @@ -# Overview - -Module Name: C1X Bidder Adapter -Module Type: Bidder Adapter -Maintainer: cathy@c1exchange.com - -# Description - -Module that connects to C1X's demand sources - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - sizes: [[300, 600], [300, 250]], - bids: [ - { - bidder: 'c1x', - params: { - siteId: '9999', - pixelId: '12345', - floorPriceMap: { - '300x250': 0.20, - '300x600': 0.30 - }, //optional - } - } - ] - }, - ]; -``` \ No newline at end of file diff --git a/modules/categoryTranslation.js b/modules/categoryTranslation.js deleted file mode 100644 index 9a9289fcd73..00000000000 --- a/modules/categoryTranslation.js +++ /dev/null @@ -1,103 +0,0 @@ -/** - * This module translates iab category to freewheel industry using translation mapping file - * Publisher can set translation file by using setConfig method - * - * Example: - * config.setConfig({ - * 'brandCategoryTranslation': { - * 'translationFile': 'http://sample.com' - * } - * }); - * 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 { setupBeforeHookFnOnce, hook } from '../src/hook.js'; -import { ajax } from '../src/ajax.js'; -import { timestamp, logError } from '../src/utils.js'; -import { addBidResponse } from '../src/auction.js'; -import { getCoreStorageManager } from '../src/storageManager.js'; - -export const storage = getCoreStorageManager('categoryTranslation'); -const DEFAULT_TRANSLATION_FILE_URL = 'https://cdn.jsdelivr.net/gh/prebid/category-mapping-file@1/freewheel-mapping.json'; -const DEFAULT_IAB_TO_FW_MAPPING_KEY = 'iabToFwMappingkey'; -const DEFAULT_IAB_TO_FW_MAPPING_KEY_PUB = 'iabToFwMappingkeyPub'; -const refreshInDays = 1; - -export const registerAdserver = hook('async', function(adServer) { - let url; - if (adServer === 'freewheel') { - url = DEFAULT_TRANSLATION_FILE_URL; - initTranslation(url, DEFAULT_IAB_TO_FW_MAPPING_KEY); - } -}, 'registerAdserver'); -registerAdserver(); - -export function getAdserverCategoryHook(fn, adUnitCode, bid) { - if (!bid) { - return fn.call(this, adUnitCode); // if no bid, call original and let it display warnings - } - - if (!config.getConfig('adpod.brandCategoryExclusion')) { - return fn.call(this, adUnitCode, bid); - } - - let localStorageKey = (config.getConfig('brandCategoryTranslation.translationFile')) ? DEFAULT_IAB_TO_FW_MAPPING_KEY_PUB : DEFAULT_IAB_TO_FW_MAPPING_KEY; - - if (bid.meta && !bid.meta.adServerCatId) { - let mapping = storage.getDataFromLocalStorage(localStorageKey); - if (mapping) { - try { - mapping = JSON.parse(mapping); - } catch (error) { - logError('Failed to parse translation mapping file'); - } - if (bid.meta.primaryCatId && mapping['mapping'] && mapping['mapping'][bid.meta.primaryCatId]) { - bid.meta.adServerCatId = mapping['mapping'][bid.meta.primaryCatId]['id']; - } else { - // This bid will be automatically ignored by adpod module as adServerCatId was not found - bid.meta.adServerCatId = undefined; - } - } else { - logError('Translation mapping data not found in local storage'); - } - } - fn.call(this, adUnitCode, bid); -} - -export function initTranslation(url, localStorageKey) { - setupBeforeHookFnOnce(addBidResponse, getAdserverCategoryHook, 50); - let mappingData = storage.getDataFromLocalStorage(localStorageKey); - try { - mappingData = mappingData ? JSON.parse(mappingData) : undefined; - if (!mappingData || timestamp() > mappingData.lastUpdated + refreshInDays * 24 * 60 * 60 * 1000) { - ajax(url, - { - success: (response) => { - try { - response = JSON.parse(response); - response['lastUpdated'] = timestamp(); - storage.setDataInLocalStorage(localStorageKey, JSON.stringify(response)); - } catch (error) { - logError('Failed to parse translation mapping file'); - } - }, - error: () => { - logError('Failed to load brand category translation file.') - } - }, - ); - } - } catch (error) { - logError('Failed to parse translation mapping file'); - } -} - -function setConfig(config) { - if (config.translationFile) { - // if publisher has defined the translation file, preload that file here - initTranslation(config.translationFile, DEFAULT_IAB_TO_FW_MAPPING_KEY_PUB); - } -} - -config.getConfig('brandCategoryTranslation', config => setConfig(config.brandCategoryTranslation)); diff --git a/modules/ccxBidAdapter.js b/modules/ccxBidAdapter.js deleted file mode 100644 index 37b6fdc3e98..00000000000 --- a/modules/ccxBidAdapter.js +++ /dev/null @@ -1,240 +0,0 @@ -import * as utils from '../src/utils.js' -import { registerBidder } from '../src/adapters/bidderFactory.js' -import { config } from '../src/config.js' -import { getStorageManager } from '../src/storageManager.js'; - -const storage = getStorageManager(); -const BIDDER_CODE = 'ccx' -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'] -const SUPPORTED_VIDEO_PLAYBACK_METHODS = [1, 2, 3, 4] - -function _getDeviceObj () { - let device = {} - device.w = screen.width - device.y = screen.height - device.ua = navigator.userAgent - return device -} - -function _getSiteObj (bidderRequest) { - let site = {} - let url = config.getConfig('pageUrl') || utils.deepAccess(window, 'location.href'); - if (url.length > 0) { - url = url.split('?')[0] - } - site.page = url - - return site -} - -function _validateSizes (sizeObj, type) { - if (!utils.isArray(sizeObj) || typeof sizeObj[0] === 'undefined') { - return false - } - - if (type === 'video' && (!utils.isArray(sizeObj[0]) || sizeObj[0].length !== 2)) { - return false - } - - let result = true - - if (type === 'banner') { - utils._each(sizeObj, function (size) { - if (!utils.isArray(size) || (size.length !== 2)) { - result = false - } - }) - return result - } - - if (type === 'old') { - if (!utils.isArray(sizeObj[0]) && sizeObj.length !== 2) { - result = false - } else if (utils.isArray(sizeObj[0])) { - utils._each(sizeObj, function (size) { - if (!utils.isArray(size) || (size.length !== 2)) { - result = false - } - }) - } - return result; - } - - return true -} - -function _buildBid (bid) { - let placement = {} - placement.id = bid.bidId - placement.secure = 1 - - let sizes = utils.deepAccess(bid, 'mediaTypes.banner.sizes') || utils.deepAccess(bid, 'mediaTypes.video.playerSize') || utils.deepAccess(bid, 'sizes') - - if (utils.deepAccess(bid, 'mediaTypes.banner') || utils.deepAccess(bid, 'mediaType') === 'banner' || (!utils.deepAccess(bid, 'mediaTypes.video') && !utils.deepAccess(bid, 'mediaType'))) { - placement.banner = {'format': []} - if (utils.isArray(sizes[0])) { - utils._each(sizes, function (size) { - placement.banner.format.push({'w': size[0], 'h': size[1]}) - }) - } else { - placement.banner.format.push({'w': sizes[0], 'h': sizes[1]}) - } - } else if (utils.deepAccess(bid, 'mediaTypes.video') || utils.deepAccess(bid, 'mediaType') === 'video') { - placement.video = {} - - if (typeof sizes !== 'undefined') { - if (utils.isArray(sizes[0])) { - placement.video.w = sizes[0][0] - placement.video.h = sizes[0][1] - } else { - placement.video.w = sizes[0] - placement.video.h = sizes[1] - } - } - - placement.video.protocols = utils.deepAccess(bid, 'params.video.protocols') || SUPPORTED_VIDEO_PROTOCOLS - placement.video.mimes = utils.deepAccess(bid, 'params.video.mimes') || SUPPORTED_VIDEO_MIMES - placement.video.playbackmethod = utils.deepAccess(bid, 'params.video.playbackmethod') || SUPPORTED_VIDEO_PLAYBACK_METHODS - placement.video.skip = utils.deepAccess(bid, 'params.video.skip') || 0 - if (placement.video.skip === 1 && utils.deepAccess(bid, 'params.video.skipafter')) { - placement.video.skipafter = utils.deepAccess(bid, 'params.video.skipafter') - } - } - - placement.ext = {'pid': bid.params.placementId} - - return placement -} - -function _buildResponse (bid, currency, ttl) { - let resp = { - requestId: bid.impid, - cpm: bid.price, - width: bid.w, - height: bid.h, - creativeId: bid.crid, - netRevenue: false, - ttl: ttl, - currency: currency - } - - resp.meta = {}; - if (bid.adomain && bid.adomain.length > 0) { - resp.meta.advertiserDomains = bid.adomain; - } - - if (bid.ext.type === 'video') { - resp.vastXml = bid.adm - } else { - resp.ad = bid.adm - } - - if (utils.deepAccess(bid, 'dealid')) { - resp.dealId = bid.dealid - } - - return resp -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: ['banner', 'video'], - - isBidRequestValid: function (bid) { - if (!utils.deepAccess(bid, 'params.placementId')) { - utils.logWarn('placementId param is reqeuired.') - return false - } - if (utils.deepAccess(bid, 'mediaTypes.banner.sizes')) { - let isValid = _validateSizes(bid.mediaTypes.banner.sizes, 'banner') - if (!isValid) { - utils.logWarn('Bid sizes are invalid.') - } - return isValid - } else if (utils.deepAccess(bid, 'mediaTypes.video.playerSize')) { - let isValid = _validateSizes(bid.mediaTypes.video.playerSize, 'video') - if (!isValid) { - utils.logWarn('Bid sizes are invalid.') - } - return isValid - } else if (utils.deepAccess(bid, 'sizes')) { - let isValid = _validateSizes(bid.sizes, 'old') - if (!isValid) { - utils.logWarn('Bid sizes are invalid.') - } - return isValid - } else { - utils.logWarn('Bid sizes are required.') - return false - } - }, - buildRequests: function (validBidRequests, bidderRequest) { - // check if validBidRequests is not empty - if (validBidRequests.length > 0) { - let requestBody = {} - requestBody.imp = [] - requestBody.site = _getSiteObj(bidderRequest) - requestBody.device = _getDeviceObj() - requestBody.id = bidderRequest.bids[0].auctionId - requestBody.ext = {'ce': (storage.cookiesAreEnabled() ? 1 : 0)} - - // Attaching GDPR Consent Params - if (bidderRequest && bidderRequest.gdprConsent) { - requestBody.user = { - ext: { - consent: bidderRequest.gdprConsent.consentString - } - }; - - requestBody.regs = { - ext: { - gdpr: (bidderRequest.gdprConsent.gdprApplies ? 1 : 0) - } - }; - } - - utils._each(validBidRequests, function (bid) { - requestBody.imp.push(_buildBid(bid)) - }) - // Return the server request - return { - 'method': 'POST', - 'url': BID_URL, - 'data': JSON.stringify(requestBody) - } - } - }, - interpretResponse: function (serverResponse, request) { - const bidResponses = [] - - // response is not empty (HTTP 204) - if (!utils.isEmpty(serverResponse.body)) { - utils._each(serverResponse.body.seatbid, function (seatbid) { - utils._each(seatbid.bid, function (bid) { - bidResponses.push(_buildResponse(bid, serverResponse.body.cur, serverResponse.body.ext.ttl)) - }) - }) - } - - return bidResponses - }, - getUserSyncs: function (syncOptions, serverResponses) { - const syncs = [] - - if (utils.deepAccess(serverResponses[0], 'body.ext.usersync') && !utils.isEmpty(serverResponses[0].body.ext.usersync)) { - utils._each(serverResponses[0].body.ext.usersync, function (match) { - if ((syncOptions.iframeEnabled && match.type === 'iframe') || (syncOptions.pixelEnabled && match.type === 'image')) { - syncs.push({ - type: match.type, - url: match.url - }) - } - }) - } - - return syncs - } -} -registerBidder(spec) diff --git a/modules/ccxBidAdapter.md b/modules/ccxBidAdapter.md deleted file mode 100644 index 740457dd099..00000000000 --- a/modules/ccxBidAdapter.md +++ /dev/null @@ -1,98 +0,0 @@ -# Overview - -Module Name: Clickonometrics Bidder Adapter -Module Type: Bidder Adapter -Maintainer: it@clickonometrics.pl - -# Description - -Module that connects to Clickonometrics's demand sources - -# Test Parameters - - var adUnits = [ - { - code: 'test-banner', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [ - { - bidder: "ccx", - params: { - placementId: 3286844 - } - } - ] - }, - { - code: 'test-video', - mediaTypes: { - video: { - playerSize: [1920, 1080] - - } - }, - bids: [ - { - bidder: "ccx", - params: { - placementId: 3287742, - //following options are not required, default values will be used. Uncomment if you want to use custom values - /*video: { - //check OpenRTB documentation for following options description - protocols: [2, 3, 5, 6], //default - mimes: ["video/mp4", "video/x-flv"], //default - playbackmethod: [1, 2, 3, 4], //default - skip: 1, //default 0 - skipafter: 5 //delete this key if skip = 0 - }*/ - } - } - ] - } - - ]; - -# Pre 1.0 Support - - var adUnits = [ - { - code: 'test-banner', - mediaType: 'banner', - sizes: [300, 250], - bids: [ - { - bidder: "ccx", - params: { - placementId: 3286844 - } - } - ] - }, - { - code: 'test-video', - mediaType: 'video', - sizes: [1920, 1080] - bids: [ - { - bidder: "ccx", - params: { - placementId: 3287742, - //following options are not required, default values will be used. Uncomment if you want to use custom values - /*video: { - //check OpenRTB documentation for following options description - protocols: [2, 3, 5, 6], //default - mimes: ["video/mp4", "video/x-flv"], //default - playbackmethod: [1, 2, 3, 4], //default - skip: 1, //default 0 - skipafter: 5 //delete this key if skip = 0 - }*/ - } - } - ] - } - - ]; \ No newline at end of file diff --git a/modules/cedatoBidAdapter.js b/modules/cedatoBidAdapter.js deleted file mode 100644 index ab381698f01..00000000000 --- a/modules/cedatoBidAdapter.js +++ /dev/null @@ -1,229 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const storage = getStorageManager(); - -const BIDDER_CODE = 'cedato'; -const BID_URL = 'https://h.cedatoplayer.com/hb'; -const SYNC_URL = 'https://h.cedatoplayer.com/hb_usync'; -const TTL = 10000; -const CURRENCY = 'USD'; -const NET_REVENUE = true; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - - isBidRequestValid: function(bid) { - return !!( - bid && - bid.params && - bid.params.player_id && - utils.checkCookieSupport() && - storage.cookiesAreEnabled() - ); - }, - - buildRequests: function(bidRequests, bidderRequest) { - const site = { domain: document.domain }; - const device = { ua: navigator.userAgent, w: screen.width, h: screen.height }; - const currency = CURRENCY; - const tmax = bidderRequest.timeout; - const auctionId = bidderRequest.auctionId; - const auctionStart = bidderRequest.auctionStart; - const bidderRequestId = bidderRequest.bidderRequestId; - - const imp = bidRequests.map(req => { - const banner = getMediaType(req, 'banner'); - const video = getMediaType(req, 'video'); - const params = req.params; - const bidId = req.bidId; - const adUnitCode = req.adUnitCode; - const bidRequestsCount = req.bidRequestsCount; - const bidderWinsCount = req.bidderWinsCount; - const transactionId = req.transactionId; - - return { - bidId, - banner, - video, - adUnitCode, - bidRequestsCount, - bidderWinsCount, - transactionId, - params - }; - }); - - const payload = { - version: '$prebid.version$', - site, - device, - imp, - currency, - tmax, - auctionId, - auctionStart, - bidderRequestId - }; - - if (bidderRequest) { - payload.referer_info = bidderRequest.refererInfo; - payload.us_privacy = bidderRequest.uspConsent; - - if (bidderRequest.gdprConsent) { - payload.gdpr_consent = { - consent_string: bidderRequest.gdprConsent.consentString, - consent_required: bidderRequest.gdprConsent.gdprApplies - }; - } - } - - return formatRequest(payload, bidderRequest); - }, - - interpretResponse: function(resp, {bidderRequest}) { - resp = resp.body; - const bids = []; - - if (!resp) { - return bids; - } - - resp.seatbid[0].bid.map(serverBid => { - const bid = newBid(serverBid, bidderRequest); - bid.currency = resp.cur; - bids.push(bid); - }); - - return bids; - }, - - getUserSyncs: function(syncOptions, resps, gdprConsent, uspConsent) { - const syncs = []; - if (syncOptions.iframeEnabled) { - syncs.push(getSync('iframe', gdprConsent, uspConsent)); - } else if (syncOptions.pixelEnabled) { - syncs.push(getSync('image', gdprConsent, uspConsent)); - } - return syncs; - } -} - -function getMediaType(req, type) { - const { mediaTypes } = req; - - if (!mediaTypes) { - return; - } - - switch (type) { - case 'banner': - if (mediaTypes.banner) { - const { sizes } = mediaTypes.banner; - return { - format: getFormats(sizes) - }; - } - break; - - case 'video': - if (mediaTypes.video) { - const { playerSize, context } = mediaTypes.video; - return { - context: context, - format: getFormats(playerSize) - }; - } - } -} - -function newBid(serverBid, bidderRequest) { - const bidRequest = utils.getBidRequest(serverBid.uuid, [bidderRequest]); - - const cpm = serverBid.price; - const requestId = serverBid.uuid; - const width = serverBid.w; - const height = serverBid.h; - const creativeId = serverBid.crid; - const dealId = serverBid.dealid; - const mediaType = serverBid.media_type; - const netRevenue = NET_REVENUE; - const ttl = TTL; - - const bid = { - cpm, - requestId, - width, - height, - mediaType, - creativeId, - dealId, - netRevenue, - ttl, - }; - - if (mediaType == 'video') { - const videoContext = utils.deepAccess(bidRequest, 'mediaTypes.video.context'); - - if (videoContext == 'instream') { - bid.vastUrl = serverBid.vast_url; - bid.vastImpUrl = serverBid.notify_url; - } - } else { - bid.ad = serverBid.adm; - } - - return bid; -} - -function formatRequest(payload, bidderRequest) { - const payloadByUrl = {}; - const requests = []; - - payload.imp.forEach(imp => { - const url = imp.params.bid_url || BID_URL; - if (!payloadByUrl[url]) { - payloadByUrl[url] = { - ...payload, - imp: [] - }; - } - payloadByUrl[url].imp.push(imp); - }); - - for (const url in payloadByUrl) { - requests.push({ - url, - method: 'POST', - data: JSON.stringify(payloadByUrl[url]), - bidderRequest - }); - } - - return requests; -} - -const getSync = (type, gdprConsent, uspConsent = '') => { - const syncUrl = SYNC_URL; - let params = '?type=' + type + '&us_privacy=' + uspConsent; - if (gdprConsent && typeof gdprConsent.consentString === 'string') { - if (typeof gdprConsent.gdprApplies === 'boolean') { - params += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - params += `&gdpr_consent=${gdprConsent.consentString}`; - } - } - return { - type: type, - url: syncUrl + params, - }; -} - -const getFormats = arr => arr.map((s) => { - return { w: s[0], h: s[1] }; -}); - -registerBidder(spec); diff --git a/modules/cedatoBidAdapter.md b/modules/cedatoBidAdapter.md deleted file mode 100644 index 088f8a4baef..00000000000 --- a/modules/cedatoBidAdapter.md +++ /dev/null @@ -1,53 +0,0 @@ -# Overview - -``` -Module Name: Cedato Bidder Adapter -Module Type: Bidder Adapter -Maintainer: alexk@cedato.com -``` - -# Description - -Connects to Cedato Bidder. -Player ID must be replaced. You can approach your Cedato account manager to get one. - -# Test Parameters -``` -var adUnits = [ - // Banner - { - code: 'div-gpt-ad-1460505748561-0', - mediaTypes: { - banner: { - // You can choose one of them - sizes: [ - [300, 250], - [300, 600], - [240, 400], - [728, 90], - ] - } - }, - bids: [ - { - bidder: "cedato", - params: { - player_id: 1450133326, - } - } - ] - } -]; - -pbjs.que.push(() => { - pbjs.setConfig({ - userSync: { - syncEnabled: true, - enabledBidders: ['cedato'], - pixelEnabled: true, - syncsPerBidder: 200, - syncDelay: 100, - }, - }); -}); -``` diff --git a/modules/cleanmedianetBidAdapter.js b/modules/cleanmedianetBidAdapter.js deleted file mode 100644 index 80e4f13e7d4..00000000000 --- a/modules/cleanmedianetBidAdapter.js +++ /dev/null @@ -1,316 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; -import {Renderer} from '../src/Renderer.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -export const helper = { - getTopWindowDomain: function (url) { - const domainStart = url.indexOf('://') + '://'.length; - return url.substring(domainStart, url.indexOf('/', domainStart) < 0 ? url.length : url.indexOf('/', domainStart)); - }, - startsWith: function (str, search) { - return str.substr(0, search.length) === search; - }, - getMediaType: function (bid) { - if (bid.ext) { - if (bid.ext.media_type) { - return bid.ext.media_type.toLowerCase(); - } else if (bid.ext.vast_url) { - return VIDEO; - } else { - return BANNER; - } - } - return BANNER; - } -}; - -export const spec = { - code: 'cleanmedianet', - aliases: [], - supportedMediaTypes: [BANNER, VIDEO], - - isBidRequestValid: function (bid) { - return ( - !!bid.params.supplyPartnerId && - typeof bid.params.supplyPartnerId === 'string' && - (typeof bid.params.bidfloor === 'undefined' || - typeof bid.params.bidfloor === 'number') && - (typeof bid.params['adpos'] === 'undefined' || - typeof bid.params['adpos'] === 'number') && - (typeof bid.params['protocols'] === 'undefined' || - Array.isArray(bid.params['protocols'])) && - (typeof bid.params.instl === 'undefined' || - bid.params.instl === 0 || - bid.params.instl === 1) - ); - }, - - buildRequests: function (validBidRequests, bidderRequest) { - return validBidRequests.map(bidRequest => { - const { - adUnitCode, - auctionId, - mediaTypes, - params, - sizes, - transactionId - } = bidRequest; - const baseEndpoint = 'https://bidder.cleanmediaads.com'; - const rtbEndpoint = - `${baseEndpoint}/r/${ - params.supplyPartnerId - }/bidr?rformat=open_rtb&reqformat=rtb_json&bidder=prebid` + - (params.query ? '&' + params.query : ''); - let url = - config.getConfig('pageUrl') || bidderRequest.refererInfo.referer; - - const rtbBidRequest = { - id: auctionId, - site: { - domain: helper.getTopWindowDomain(url), - page: url, - ref: bidderRequest.refererInfo.referer - }, - device: { - ua: navigator.userAgent, - dnt: utils.getDNT() ? 1 : 0, - h: screen.height, - w: screen.width, - language: navigator.language - }, - imp: [], - ext: {}, - user: { - ext: {} - } - }; - - if ( - bidderRequest.gdprConsent && - bidderRequest.gdprConsent.consentString && - bidderRequest.gdprConsent.gdprApplies - ) { - rtbBidRequest.ext.gdpr_consent = { - consent_string: bidderRequest.gdprConsent.consentString, - consent_required: bidderRequest.gdprConsent.gdprApplies - }; - rtbBidRequest.regs = { - ext: { - gdpr: bidderRequest.gdprConsent.gdprApplies === true ? 1 : 0 - } - }; - rtbBidRequest.user = { - ext: { - consent: bidderRequest.gdprConsent.consentString - } - } - } - - const imp = { - id: transactionId, - instl: params.instl === 1 ? 1 : 0, - tagid: adUnitCode, - bidfloor: params.bidfloor || 0, - bidfloorcur: 'USD', - secure: 1 - }; - - const hasFavoredMediaType = - params.favoredMediaType && - includes(this.supportedMediaTypes, params.favoredMediaType); - - if (!mediaTypes || mediaTypes.banner) { - if (!hasFavoredMediaType || params.favoredMediaType === BANNER) { - const bannerImp = Object.assign({}, imp, { - banner: { - w: sizes.length ? sizes[0][0] : 300, - h: sizes.length ? sizes[0][1] : 250, - pos: params.pos || 0, - topframe: utils.inIframe() ? 0 : 1 - } - }); - rtbBidRequest.imp.push(bannerImp); - } - } - - if (mediaTypes && mediaTypes.video) { - if (!hasFavoredMediaType || params.favoredMediaType === VIDEO) { - let videoImp = { - video: { - protocols: params.protocols || [1, 2, 3, 4, 5, 6], - pos: params.pos || 0, - ext: {context: mediaTypes.video.context} - } - }; - - let playerSize = mediaTypes.video.playerSize || sizes; - if (utils.isArray(playerSize[0])) { - videoImp.video.w = playerSize[0][0]; - videoImp.video.h = playerSize[0][1]; - } else if (utils.isNumber(playerSize[0])) { - videoImp.video.w = playerSize[0]; - videoImp.video.h = playerSize[1]; - } else { - videoImp.video.w = 300; - videoImp.video.h = 250; - } - - videoImp = Object.assign({}, imp, videoImp); - rtbBidRequest.imp.push(videoImp); - } - } - - if (rtbBidRequest.imp.length === 0) { - return; - } - - return { - method: 'POST', - url: rtbEndpoint, - data: rtbBidRequest, - bidRequest - }; - }); - }, - - interpretResponse: function (serverResponse, bidRequest) { - const response = serverResponse && serverResponse.body; - if (!response) { - utils.logError('empty response'); - return []; - } - - const bids = response.seatbid.reduce( - (acc, seatBid) => acc.concat(seatBid.bid), - [] - ); - let outBids = []; - - bids.forEach(bid => { - const outBid = { - requestId: bidRequest.bidRequest.bidId, - cpm: bid.price, - width: bid.w, - height: bid.h, - ttl: 360, - creativeId: bid.crid || bid.adid, - netRevenue: true, - currency: bid.cur || response.cur, - mediaType: helper.getMediaType(bid) - }; - - if ( - utils.deepAccess( - bidRequest.bidRequest, - 'mediaTypes.' + outBid.mediaType - ) - ) { - if (outBid.mediaType === BANNER) { - outBids.push(Object.assign({}, outBid, {ad: bid.adm})); - } else if (outBid.mediaType === VIDEO) { - const context = utils.deepAccess( - bidRequest.bidRequest, - 'mediaTypes.video.context' - ); - outBids.push( - Object.assign({}, outBid, { - vastUrl: bid.ext.vast_url, - vastXml: bid.adm, - renderer: - context === 'outstream' - ? newRenderer(bidRequest.bidRequest, bid) - : undefined - }) - ); - } - } - }); - return outBids; - }, - - getUserSyncs: function (syncOptions, serverResponses, gdprConsent) { - const syncs = []; - const gdprApplies = - gdprConsent && typeof gdprConsent.gdprApplies === 'boolean' - ? gdprConsent.gdprApplies - : false; - const suffix = gdprApplies - ? 'gc=' + encodeURIComponent(gdprConsent.consentString) - : 'gc=missing'; - serverResponses.forEach(resp => { - if (resp.body) { - const bidResponse = resp.body; - if (bidResponse.ext && Array.isArray(bidResponse.ext['utrk'])) { - bidResponse.ext['utrk'].forEach(pixel => { - const url = - pixel.url + - (pixel.url.indexOf('?') > 0 ? '&' + suffix : '?' + suffix); - return syncs.push({type: pixel.type, url}); - }); - } - if (Array.isArray(bidResponse.seatbid)) { - bidResponse.seatbid.forEach(seatBid => { - if (Array.isArray(seatBid.bid)) { - seatBid.bid.forEach(bid => { - if (bid.ext && Array.isArray(bid.ext['utrk'])) { - bid.ext['utrk'].forEach(pixel => { - const url = - pixel.url + - (pixel.url.indexOf('?') > 0 - ? '&' + suffix - : '?' + suffix); - return syncs.push({type: pixel.type, url}); - }); - } - }); - } - }); - } - } - }); - return syncs; - } -}; - -function newRenderer(bidRequest, bid, rendererOptions = {}) { - const renderer = Renderer.install({ - url: - (bidRequest.params && bidRequest.params.rendererUrl) || - (bid.ext && bid.ext.renderer_url) || - 'https://s.wlplayer.com/video/latest/renderer.js', - config: rendererOptions, - loaded: false - }); - try { - renderer.setRender(renderOutstream); - } catch (err) { - utils.logWarn('Prebid Error calling setRender on renderer', err); - } - return renderer; -} - -function renderOutstream(bid) { - bid.renderer.push(() => { - const unitId = bid.adUnitCode + '/' + bid.adId; - window['GamoshiPlayer'].renderAd({ - id: unitId, - debug: window.location.href.indexOf('pbjsDebug') >= 0, - placement: document.getElementById(bid.adUnitCode), - width: bid.width, - height: bid.height, - events: { - ALL_ADS_COMPLETED: () => - window.setTimeout(() => { - window['GamoshiPlayer'].removeAd(unitId); - }, 300) - }, - vastUrl: bid.vastUrl, - vastXml: bid.vastXml - }); - }); -} - -registerBidder(spec); diff --git a/modules/cleanmedianetBidAdapter.md b/modules/cleanmedianetBidAdapter.md deleted file mode 100644 index f2bc8feb0f0..00000000000 --- a/modules/cleanmedianetBidAdapter.md +++ /dev/null @@ -1,66 +0,0 @@ -# Overview - -``` -Module Name: Clean Media Net Adapter -Module Type: Bidder Adapter -Maintainer: dev@cleanmedia.net -``` - -# Description - -Connects to Clean Media Net's Programmatic advertising platform as a service. - -Clean Media bid adapter supports Banner & Video (Instream and Outstream). -The *only* required parameter (in the `params` section) is the `supplyPartnerId` parameter. - -# Test Parameters -``` -var adUnits = [ - // Banner adUnit - { - code: 'banner-div', - sizes: [[300, 250]], - bids: [{ - bidder: 'cleanmedianet', - params: { - // ID of the supply partner you created in the Clean Media Net dashboard - supplyPartnerId: '1253', - // OPTIONAL: custom bid floor - bidfloor: 0.01, - // OPTIONAL: if you know the ad position on the page, specify it here - // (this corresponds to "Ad Position" in OpenRTB 2.3, section 5.4) - //adpos: 1, - // OPTIONAL: whether this is an interstitial placement (0 or 1) - // (see "instl" property in "Imp" object in the OpenRTB 2.3, section 3.2.2) - //instl: 0 - } - }] - }, - // Video outstream adUnit - { - code: 'video-outstream', - sizes: [[300, 250]], - mediaTypes: { - video: { - context: 'outstream', - playerSize: [300, 250] - } - }, - bids: [ { - bidder: 'cleanmedianet', - params: { - // ID of the supply partner you created in the dashboard - supplyPartnerId: '1254', - // OPTIONAL: custom bid floor - bidfloor: 0.01, - // OPTIONAL: if you know the ad position on the page, specify it here - // (this corresponds to "Ad Position" in OpenRTB 2.3, section 5.4) - //adpos: 1, - // OPTIONAL: whether this is an interstitial placement (0 or 1) - // (see "instl" property in "Imp" object in the OpenRTB 2.3, section 3.2.2) - //instl: 0 - } - }] - } -]; -``` diff --git a/modules/clickforceBidAdapter.js b/modules/clickforceBidAdapter.js deleted file mode 100644 index 20408fe9177..00000000000 --- a/modules/clickforceBidAdapter.js +++ /dev/null @@ -1,126 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE} from '../src/mediaTypes.js'; -const BIDDER_CODE = 'clickforce'; -const ENDPOINT_URL = 'https://ad.holmesmind.com/adserver/prebid.json?cb=' + new Date().getTime() + '&hb=1&ver=1.21'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, NATIVE], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - return bid && bid.params && !!bid.params.zone; - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests) { - const bidParams = []; - utils._each(validBidRequests, function(bid) { - bidParams.push({ - z: bid.params.zone, - bidId: bid.bidId - }); - }); - return { - method: 'POST', - url: ENDPOINT_URL, - data: bidParams, - validBidRequests: validBidRequests - }; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @param {*} bidRequest - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse, bidRequest) { - const cfResponses = []; - const bidRequestList = []; - - if (typeof bidRequest != 'undefined') { - utils._each(bidRequest.validBidRequests, function(req) { - bidRequestList[req.bidId] = req; - }); - } - - utils._each(serverResponse.body, function(response) { - if (response.requestId != null) { - // native ad size - if (response.width == 3) { - cfResponses.push({ - requestId: response.requestId, - cpm: response.cpm, - width: response.width, - height: response.height, - creativeId: response.creativeId, - currency: response.currency, - netRevenue: response.netRevenue, - ttl: response.ttl, - native: { - title: response.tag.content.title, - body: response.tag.content.content, - image: { - url: response.tag.content.image, - height: 900, - width: 1600 - }, - icon: { - url: response.tag.content.icon, - height: 900, - width: 900 - }, - clickUrl: response.tag.cu, - cta: response.tag.content.button_text, - sponsoredBy: response.tag.content.advertiser, - impressionTrackers: response.tag.iu, - }, - mediaType: 'native', - }); - } else { - // display ad - cfResponses.push({ - requestId: response.requestId, - cpm: response.cpm, - width: response.width, - height: response.height, - creativeId: response.creativeId, - currency: response.currency, - netRevenue: response.netRevenue, - ttl: response.ttl, - ad: response.tag, - mediaType: 'banner', - }); - } - } - }); - return cfResponses; - }, - getUserSyncs: function(syncOptions, serverResponses) { - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: 'https://cdn.holmesmind.com/js/capmapping.htm' - }] - } else if (syncOptions.pixelEnabled) { - return [{ - type: 'image', - url: 'https://c.holmesmind.com/cm' - }] - } - } -}; - -registerBidder(spec); diff --git a/modules/clickforceBidAdapter.md b/modules/clickforceBidAdapter.md deleted file mode 100644 index 07fe9475881..00000000000 --- a/modules/clickforceBidAdapter.md +++ /dev/null @@ -1,80 +0,0 @@ -# Overview - -``` -Module Name: CLICKFORCE Bid Adapter -Module Type: Bidder Adapter -Maintainer: danis@clickforce.com.tw -``` - -# Description - -You can use this adapter to get a bid from clickforce. - -About us : http://www.clickforce.com.tw/en/ - -It requires adapters to start bidding and no extra setting is needed. If you'd like to apply for placements, please contact: - -joey@clickforce.com.tw (MR. Joey) - -# Test Parameters (Display ad) -``` - var adUnits = [{ - code: 'banner-ad-div', - sizes: [[300, 250]], - bids: [{ - bidder: "clickforce", - params: { - zone: "6682", - } - }] - }]; -``` -# Test Parameters (Native ad) -``` - var adUnits = [{ - code: 'banner-ad-div', - sizes: [[300, 250]], - mediaTypes: { - native: { - title: { - required: true, - }, - body: { - required: true - }, - image: { - required: true, - }, - icon: { - required: false, - }, - clickUrl: { - required: true - }, - cta: { - required: true - }, - sponsoredBy: { - required: true - } - } - }, - bids: [{ - bidder: "clickforce", - params: { - zone: "6878", - } - }] - }]; -``` - -### Configuration - -CLICKFORCE recommend the UserSync configuration below. It's can be optimize the CPM for the request. -```javascript -pbjs.setConfig({ - userSync: { - iframeEnabled: true, - syncDelay: 1000 -}}); -``` \ No newline at end of file diff --git a/modules/clicktripzBidAdapter.js b/modules/clicktripzBidAdapter.js deleted file mode 100644 index 2149cbe4527..00000000000 --- a/modules/clicktripzBidAdapter.js +++ /dev/null @@ -1,67 +0,0 @@ -import {logError, _each} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'clicktripz'; -const ENDPOINT_URL = 'https://www.clicktripz.com/x/prebid/v1'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['ctz'], // short code - - isBidRequestValid: function (bid) { - if (bid && bid.params && bid.params.placementId && bid.params.siteId) { - return true; - } - - return false; - }, - - buildRequests: function (validBidRequests) { - let bidRequests = []; - - _each(validBidRequests, function (bid) { - bidRequests.push({ - bidId: bid.bidId, - placementId: bid.params.placementId, - siteId: bid.params.siteId, - sizes: bid.sizes.map(function (size) { - return size.join('x') - }) - }); - }); - return { - method: 'POST', - url: ENDPOINT_URL, - data: bidRequests - }; - }, - - interpretResponse: function (serverResponse) { - let bidResponses = []; - - if (serverResponse && serverResponse.body) { - _each(serverResponse.body, function (bid) { - if (bid.errors) { - logError(bid.errors); - return; - } - - const size = bid.size.split('x'); - bidResponses.push({ - requestId: bid.bidId, - cpm: bid.cpm, - width: size[0], - height: size[1], - creativeId: bid.creativeId, - currency: bid.currency, - netRevenue: bid.netRevenue, - ttl: bid.ttl, - adUrl: bid.adUrl - }); - }); - } - return bidResponses; - } -}; - -registerBidder(spec); diff --git a/modules/clicktripzBidAdapter.md b/modules/clicktripzBidAdapter.md deleted file mode 100644 index 1de1e26f37a..00000000000 --- a/modules/clicktripzBidAdapter.md +++ /dev/null @@ -1,35 +0,0 @@ -# Overview - -``` -Module Name: Clicktripz Bidder Adapter -Module Type: Bidder Adapter -Maintainer: integration-support@clicktripz.com -``` - -# Description -Our module makes it easy to integrate Clicktripz demand sources into your website. - -Supported Ad Fortmats: -* Banner - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]], - } - }, - bids: [ - { - bidder: "clicktripz", - params: { - placementId: '4312c63f', - siteId: 'prebid', - } - } - ] - } - ]; diff --git a/modules/cointrafficBidAdapter.js b/modules/cointrafficBidAdapter.js deleted file mode 100644 index 43f5cc01ccf..00000000000 --- a/modules/cointrafficBidAdapter.js +++ /dev/null @@ -1,97 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js' -import { config } from '../src/config.js' - -const BIDDER_CODE = 'cointraffic'; -const ENDPOINT_URL = 'https://appspb.cointraffic.io/pb/tmp'; -const DEFAULT_CURRENCY = 'EUR'; -const ALLOWED_CURRENCIES = [ - 'EUR', 'USD', 'JPY', 'BGN', 'CZK', 'DKK', 'GBP', 'HUF', 'PLN', 'RON', 'SEK', 'CHF', 'ISK', 'NOK', 'HRK', 'RUB', 'TRY', - 'AUD', 'BRL', 'CAD', 'CNY', 'HKD', 'IDR', 'ILS', 'INR', 'KRW', 'MXN', 'MYR', 'NZD', 'PHP', 'SGD', 'THB', 'ZAR', -]; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return !!(bid.params.placementId); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param validBidRequests - * @param bidderRequest - * @return Array Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - return validBidRequests.map(bidRequest => { - const sizes = utils.parseSizesInput(bidRequest.params.size || bidRequest.sizes); - const currency = - config.getConfig(`currency.bidderCurrencyDefault.${BIDDER_CODE}`) || - config.getConfig('currency.adServerCurrency') || - DEFAULT_CURRENCY; - - if (ALLOWED_CURRENCIES.indexOf(currency) === -1) { - utils.logError('Currency is not supported - ' + currency); - return; - } - - const payload = { - placementId: bidRequest.params.placementId, - currency: currency, - sizes: sizes, - bidId: bidRequest.bidId, - referer: bidderRequest.refererInfo.referer, - }; - - return { - method: 'POST', - url: ENDPOINT_URL, - data: payload - }; - }); - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {ServerResponse} serverResponse A successful response from the server. - * @param bidRequest - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function (serverResponse, bidRequest) { - const bidResponses = []; - const response = serverResponse.body; - - if (utils.isEmpty(response)) { - return bidResponses; - } - - const bidResponse = { - requestId: response.requestId, - cpm: response.cpm, - currency: response.currency, - netRevenue: response.netRevenue, - width: response.width, - height: response.height, - creativeId: response.creativeId, - ttl: response.ttl, - ad: response.ad - }; - - bidResponses.push(bidResponse); - - return bidResponses; - } -}; - -registerBidder(spec); diff --git a/modules/cointrafficBidAdapter.md b/modules/cointrafficBidAdapter.md deleted file mode 100644 index fcbcad1cad7..00000000000 --- a/modules/cointrafficBidAdapter.md +++ /dev/null @@ -1,31 +0,0 @@ -# Overview - -``` -Module Name: Cointraffic Bidder Adapter -Module Type: Cointraffic Adapter -Maintainer: tech@cointraffic.io -``` - -# Description -The Cointraffic client module makes it easy to implement Cointraffic directly into your website. To get started, simply replace the ``placementId`` with your assigned tracker key. This is dependent on the size required by your account dashboard. -We support response in different currencies. Supported currencies listed [here](https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/index.en.html). - -For additional information on this module, please contact us at ``support@cointraffic.io``. - -# Test Parameters -``` - var adUnits = [{ - code: 'test-ad-div', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [{ - bidder: 'cointraffic', - params: { - placementId: 'testPlacementId' - } - }] - }]; -``` diff --git a/modules/coinzillaBidAdapter.js b/modules/coinzillaBidAdapter.js deleted file mode 100644 index 240a3f1fcde..00000000000 --- a/modules/coinzillaBidAdapter.js +++ /dev/null @@ -1,89 +0,0 @@ -import * as utils from '../src/utils.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'coinzilla'; -const ENDPOINT_URL = 'https://request.czilladx.com/serve/request.php'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['czlla'], // short code - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return !!(bid.params.placementId); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @return Array Info describing the request to the server. - * @param validBidRequests - * @param bidderRequest - */ - buildRequests: function (validBidRequests, bidderRequest) { - if (validBidRequests.length === 0) { - return []; - } - return validBidRequests.map(bidRequest => { - const sizes = utils.parseSizesInput(bidRequest.params.size || bidRequest.sizes)[0]; - const width = sizes.split('x')[0]; - const height = sizes.split('x')[1]; - const payload = { - placementId: bidRequest.params.placementId, - width: width, - height: height, - bidId: bidRequest.bidId, - referer: bidderRequest.refererInfo.referer, - }; - return { - method: 'POST', - url: ENDPOINT_URL, - data: payload - }; - }); - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {ServerResponse} serverResponse A successful response from the server. - * @param bidRequest - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function (serverResponse, bidRequest) { - const bidResponses = []; - const response = serverResponse.body; - const creativeId = response.creativeId || 0; - const width = response.width || 0; - const height = response.height || 0; - const cpm = response.cpm || 0; - if (width !== 0 && height !== 0 && cpm !== 0 && creativeId !== 0) { - const dealId = response.dealid || ''; - const currency = response.currency || 'EUR'; - const netRevenue = (response.netRevenue === undefined) ? true : response.netRevenue; - const referrer = bidRequest.data.referer; - const bidResponse = { - requestId: response.requestId, - cpm: cpm, - width: response.width, - height: response.height, - creativeId: creativeId, - dealId: dealId, - currency: currency, - netRevenue: netRevenue, - ttl: config.getConfig('_bidderTimeout'), - referrer: referrer, - ad: response.ad - }; - bidResponses.push(bidResponse); - } - return bidResponses; - }, -}; -registerBidder(spec); diff --git a/modules/coinzillaBidAdapter.md b/modules/coinzillaBidAdapter.md deleted file mode 100644 index c7da4efb1a4..00000000000 --- a/modules/coinzillaBidAdapter.md +++ /dev/null @@ -1,24 +0,0 @@ -# Overview - -``` -Module Name: Coinzilla Bidder Adapter -Module Type: Coinzilla Adapter -Maintainer: technical@sevio.com -``` - -# Description - -Our module helps you have an easier time implementing Coinzilla on your website. All you have to do is replace the ``placementId`` with your zoneID, depending on the required size in your account dashboard. If you need additional information please contact us at ``publishers@coinzilla.com``. -# Test Parameters -``` - var adUnits = [{ - code: 'test-ad-div', - sizes: [[300, 250]], - bids: [{ - bidder: 'coinzilla', - params: { - placementId: 'testPlacementId' - } - }] - }]; -``` \ No newline at end of file diff --git a/modules/collectcentBidAdapter.js b/modules/collectcentBidAdapter.js deleted file mode 100644 index add3e06430d..00000000000 --- a/modules/collectcentBidAdapter.js +++ /dev/null @@ -1,93 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; - -const BIDDER_CODE = 'collectcent'; -const URL_MULTI = 'https://publishers.motionspots.com/?c=o&m=multi'; -const URL_SYNC = 'https://publishers.motionspots.com/?c=o&m=cookie'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO, NATIVE], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {object} bid The bid to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && - bid.params && - !isNaN(bid.params.placementId) && - spec.supportedMediaTypes.indexOf(bid.params.traffic) !== -1 - ); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests A non-empty list of valid bid requests that should be sent to the Server. - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: (validBidRequests, bidderRequest) => { - let winTop; - try { - winTop = window.top; - } catch (e) { - utils.logMessage(e); - winTop = window; - }; - - const placements = []; - const location = bidderRequest ? new URL(bidderRequest.refererInfo.referer) : winTop.location; - const request = { - 'secure': (location.protocol === 'https:') ? 1 : 0, - 'deviceWidth': winTop.screen.width, - 'deviceHeight': winTop.screen.height, - 'host': location.host, - 'page': location.pathname, - 'placements': placements - }; - - for (let i = 0; i < validBidRequests.length; i++) { - const bid = validBidRequests[i]; - const params = bid.params; - placements.push({ - placementId: params.placementId, - bidId: bid.bidId, - sizes: bid.sizes, - traffic: params.traffic - }); - } - return { - method: 'POST', - url: URL_MULTI, - data: request - }; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: (serverResponse) => { - try { - serverResponse = serverResponse.body; - } catch (e) { - utils.logMessage(e); - }; - return serverResponse; - }, - - getUserSyncs: () => { - return [{ - type: 'image', - url: URL_SYNC - }]; - } -}; - -registerBidder(spec); diff --git a/modules/collectcentBidAdapter.md b/modules/collectcentBidAdapter.md deleted file mode 100644 index 938bdc420cd..00000000000 --- a/modules/collectcentBidAdapter.md +++ /dev/null @@ -1,27 +0,0 @@ -# Overview - -``` -Module Name: Collectcent SSP Bidder Adapter -Module Type: Bidder Adapter -Maintainer: dev.collectcent@gmail.com -``` - -# Description - -Module that connects to Collectcent SSP demand sources - -# Test Parameters -``` - var adUnits = [{ - code: 'placementCode', - sizes: [[300, 250]], - bids: [{ - bidder: 'collectcent', - params: { - placementId: 0, - traffic: 'banner' - } - }] - } - ]; -``` diff --git a/modules/colombiaBidAdapter.js b/modules/colombiaBidAdapter.js deleted file mode 100644 index 55109dbaab2..00000000000 --- a/modules/colombiaBidAdapter.js +++ /dev/null @@ -1,82 +0,0 @@ -import * as utils from '../src/utils.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'; -const HOST_NAME = document.location.protocol + '//' + window.location.host; - -export const spec = { - code: BIDDER_CODE, - aliases: ['clmb'], - supportedMediaTypes: [BANNER], - isBidRequestValid: function(bid) { - return !!(bid.params.placementId); - }, - buildRequests: function(validBidRequests, bidderRequest) { - return validBidRequests.map(bidRequest => { - const params = bidRequest.params; - const sizes = utils.parseSizesInput(bidRequest.sizes)[0]; - const width = sizes.split('x')[0]; - const height = sizes.split('x')[1]; - const placementId = params.placementId; - const cb = Math.floor(Math.random() * 99999999999); - const bidId = bidRequest.bidId; - const referrer = (bidderRequest && bidderRequest.refererInfo) ? bidderRequest.refererInfo.referer : ''; - const payload = { - v: 'hb1', - p: placementId, - w: width, - h: height, - cb: cb, - r: referrer, - uid: bidId, - t: 'i', - d: HOST_NAME, - }; - return { - method: 'POST', - url: ENDPOINT_URL, - data: payload, - } - }); - }, - interpretResponse: function(serverResponse, bidRequest) { - const bidResponses = []; - const response = serverResponse.body; - const crid = response.creativeId || 0; - const width = response.width || 0; - const height = response.height || 0; - let cpm = response.cpm || 0; - if (width == 300 && height == 250) { - cpm = cpm * 0.2; - } - if (width == 320 && height == 50) { - cpm = cpm * 0.55; - } - if (cpm <= 0) { - return bidResponses; - } - if (width !== 0 && height !== 0 && cpm !== 0 && crid !== 0) { - const dealId = response.dealid || ''; - const currency = response.currency || 'USD'; - const netRevenue = (response.netRevenue === undefined) ? true : response.netRevenue; - const bidResponse = { - requestId: bidRequest.data.uid, - cpm: cpm, - width: response.width, - height: response.height, - creativeId: crid, - dealId: dealId, - currency: currency, - netRevenue: netRevenue, - ttl: config.getConfig('_bidderTimeout'), - referrer: bidRequest.data.r, - ad: response.ad - }; - bidResponses.push(bidResponse); - } - return bidResponses; - } -} -registerBidder(spec); diff --git a/modules/colombiaBidAdapter.md b/modules/colombiaBidAdapter.md deleted file mode 100644 index c754e49771d..00000000000 --- a/modules/colombiaBidAdapter.md +++ /dev/null @@ -1,31 +0,0 @@ -# Overview - -``` -Module Name: COLOMBIA Bidder Adapter -Module Type: Bidder Adapter -Maintainer: colombiaonline@timesinteret.in -``` - -# Description - -Connect to COLOMBIA for bids. - -COLOMBIA adapter requires setup and approval from the COLOMBIA team. Please reach out to your account team or colombiaonline@timesinteret.in for more information. - -# Test Parameters -``` - var adUnits = [{ - code: 'test-ad-div', - mediaTypes: { - banner: { - sizes: [[300, 250],[728,90],[320,50]] - } - }, - bids: [{ - bidder: 'colombia', - params: { - placementId: '307466' - } - }] - }]; -``` diff --git a/modules/colossussspBidAdapter.js b/modules/colossussspBidAdapter.js deleted file mode 100644 index 1afb343566d..00000000000 --- a/modules/colossussspBidAdapter.js +++ /dev/null @@ -1,156 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; - -const BIDDER_CODE = 'colossusssp'; -const G_URL = 'https://colossusssp.com/?c=o&m=multi'; -const G_URL_SYNC = 'https://colossusssp.com/?c=o&m=cookie'; - -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl); - case NATIVE: - return Boolean(bid.native); - default: - return false; - } -} - -function getUserId(eids, id, source, uidExt) { - if (id) { - var uid = { id }; - if (uidExt) { - uid.ext = uidExt; - } - eids.push({ - source, - uids: [ uid ] - }); - } -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO, NATIVE], - /** - * Determines whether or not the given bid request is valid. - * - * @param {object} bid The bid to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && bid.params && !isNaN(bid.params.placement_id)); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests A non-empty list of valid bid requests that should be sent to the Server. - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: (validBidRequests, bidderRequest) => { - const winTop = utils.getWindowTop(); - const location = winTop.location; - let placements = []; - let request = { - 'deviceWidth': winTop.screen.width, - 'deviceHeight': winTop.screen.height, - 'language': (navigator && navigator.language) ? navigator.language : '', - 'secure': location.protocol === 'https:' ? 1 : 0, - 'host': location.host, - 'page': location.pathname, - 'placements': placements, - }; - - if (bidderRequest) { - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - if (bidderRequest.gdprConsent) { - request.gdpr_consent = bidderRequest.gdprConsent.consentString || 'ALL' - request.gdpr_require = bidderRequest.gdprConsent.gdprApplies ? 1 : 0 - } - } - - for (let i = 0; i < validBidRequests.length; i++) { - let bid = validBidRequests[i]; - let traff = bid.params.traffic || BANNER - let placement = { - placementId: bid.params.placement_id, - bidId: bid.bidId, - sizes: bid.mediaTypes[traff].sizes, - traffic: traff, - eids: [], - floor: {} - }; - if (typeof bid.getFloor === 'function') { - let tmpFloor = {}; - for (let size of placement.sizes) { - tmpFloor = bid.getFloor({ - currency: 'USD', - mediaType: traff, - size: size - }); - if (tmpFloor) { - placement.floor[`${size[0]}x${size[1]}`] = tmpFloor.floor; - } - } - } - if (bid.schain) { - placement.schain = bid.schain; - } - if (bid.userId) { - getUserId(placement.eids, bid.userId.britepoolid, 'britepool.com'); - getUserId(placement.eids, bid.userId.idl_env, 'identityLink'); - getUserId(placement.eids, bid.userId.id5id, 'id5-sync.com') - getUserId(placement.eids, bid.userId.tdid, 'adserver.org', { - rtiPartner: 'TDID' - }); - } - placements.push(placement); - } - return { - method: 'POST', - url: G_URL, - data: request - }; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: (serverResponse) => { - let response = []; - try { - serverResponse = serverResponse.body; - for (let i = 0; i < serverResponse.length; i++) { - let resItem = serverResponse[i]; - if (isBidResponseValid(resItem)) { - response.push(resItem); - } - } - } catch (e) { - utils.logMessage(e); - }; - return response; - }, - - getUserSyncs: () => { - return [{ - type: 'image', - url: G_URL_SYNC - }]; - } -}; - -registerBidder(spec); diff --git a/modules/colossussspBidAdapter.md b/modules/colossussspBidAdapter.md deleted file mode 100644 index d95080546c2..00000000000 --- a/modules/colossussspBidAdapter.md +++ /dev/null @@ -1,31 +0,0 @@ -# Overview - -``` -Module Name: Colossus SSP Bidder Adapter -Module Type: Bidder Adapter -Maintainer: support@colossusmediallc.com -``` - -# Description - -Module that connects to Colossus SSP demand sources - -# Test Parameters -``` - var adUnits = [{ - code: 'placementid_0', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]] - } - }, - bids: [{ - bidder: 'colossusssp', - params: { - placement_id: 0, - traffic: 'banner' - } - }] - } - ]; -``` diff --git a/modules/concertAnalyticsAdapter.js b/modules/concertAnalyticsAdapter.js deleted file mode 100644 index a81d07e63b5..00000000000 --- a/modules/concertAnalyticsAdapter.js +++ /dev/null @@ -1,120 +0,0 @@ -import {ajax} from '../src/ajax.js'; -import adapter from '../src/AnalyticsAdapter.js'; -import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager.js'; -import * as utils from '../src/utils.js'; - -const analyticsType = 'endpoint'; - -// We only want to send about 1% of events for sampling purposes -const SAMPLE_RATE_PERCENTAGE = 1 / 100; -const pageIncludedInSample = sampleAnalytics(); - -const url = 'https://bids.concert.io/analytics'; - -const { - EVENTS: { - BID_RESPONSE, - BID_WON, - AUCTION_END - } -} = CONSTANTS; - -let queue = []; - -let concertAnalytics = Object.assign(adapter({url, analyticsType}), { - track({ eventType, args }) { - switch (eventType) { - case BID_RESPONSE: - if (args.bidder !== 'concert') break; - queue.push(mapBidEvent(eventType, args)); - break; - - case BID_WON: - if (args.bidder !== 'concert') break; - queue.push(mapBidEvent(eventType, args)); - break; - - case AUCTION_END: - // Set a delay, as BID_WON events will come after AUCTION_END events - setTimeout(() => sendEvents(), 3000); - break; - - default: - break; - } - } -}); - -function mapBidEvent(eventType, args) { - const { adId, auctionId, cpm, creativeId, width, height, timeToRespond } = args; - const [gamCreativeId, concertRequestId] = getConcertRequestId(creativeId); - - const payload = { - event: eventType, - concert_rid: concertRequestId, - adId, - auctionId, - creativeId: gamCreativeId, - position: args.adUnitCode, - url: window.location.href, - cpm, - width, - height, - timeToRespond - } - - return payload; -} - -/** - * In order to pass back the concert_rid from CBS, it is tucked into the `creativeId` - * slot in the bid response and combined with a pipe `|`. This method splits the creative ID - * and the concert_rid. - * - * @param {string} creativeId - */ -function getConcertRequestId(creativeId) { - if (!creativeId || creativeId.indexOf('|') < 0) return [null, null]; - - return creativeId.split('|'); -} - -function sampleAnalytics() { - return Math.random() <= SAMPLE_RATE_PERCENTAGE; -} - -function sendEvents() { - concertAnalytics.eventsStorage = queue; - - if (!queue.length) return; - - if (!pageIncludedInSample) { - utils.logMessage('Page not included in sample for Concert Analytics'); - return; - } - - try { - const body = JSON.stringify(queue); - ajax(url, () => queue = [], body, { - contentType: 'application/json', - method: 'POST' - }); - } catch (err) { utils.logMessage('Concert Analytics error') } -} - -// save the base class function -concertAnalytics.originEnableAnalytics = concertAnalytics.enableAnalytics; -concertAnalytics.eventsStorage = []; - -// override enableAnalytics so we can get access to the config passed in from the page -concertAnalytics.enableAnalytics = function (config) { - concertAnalytics.originEnableAnalytics(config); -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: concertAnalytics, - code: 'concert' -}); - -export default concertAnalytics; diff --git a/modules/concertAnalyticsAdapter.md b/modules/concertAnalyticsAdapter.md deleted file mode 100644 index 7c9b6d22703..00000000000 --- a/modules/concertAnalyticsAdapter.md +++ /dev/null @@ -1,11 +0,0 @@ -# Overview - -``` -Module Name: Concert Analytics Adapter -Module Type: Analytics Adapter -Maintainer: support@concert.io -``` - -# Description - -Analytics adapter for concert. \ No newline at end of file diff --git a/modules/concertBidAdapter.js b/modules/concertBidAdapter.js deleted file mode 100644 index 60634151aba..00000000000 --- a/modules/concertBidAdapter.js +++ /dev/null @@ -1,212 +0,0 @@ - -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { getStorageManager } from '../src/storageManager.js' - -const BIDDER_CODE = 'concert'; -const CONCERT_ENDPOINT = 'https://bids.concert.io'; -const USER_SYNC_URL = 'https://cdn.concert.io/lib/bids/sync.html'; - -export const spec = { - code: BIDDER_CODE, - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - if (!bid.params.partnerId) { - utils.logWarn('Missing partnerId bid parameter'); - return false; - } - - return true; - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @param {bidderRequest} - - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests, bidderRequest) { - utils.logMessage(validBidRequests); - utils.logMessage(bidderRequest); - let payload = { - meta: { - prebidVersion: '$prebid.version$', - pageUrl: bidderRequest.refererInfo.referer, - screen: [window.screen.width, window.screen.height].join('x'), - debug: utils.debugTurnedOn(), - uid: getUid(bidderRequest), - optedOut: hasOptedOutOfPersonalization(), - adapterVersion: '1.1.1', - uspConsent: bidderRequest.uspConsent, - gdprConsent: bidderRequest.gdprConsent - } - } - - payload.slots = validBidRequests.map(bidRequest => { - let slot = { - name: bidRequest.adUnitCode, - bidId: bidRequest.bidId, - transactionId: bidRequest.transactionId, - sizes: bidRequest.params.sizes || bidRequest.sizes, - partnerId: bidRequest.params.partnerId, - slotType: bidRequest.params.slotType, - adSlot: bidRequest.params.slot || bidRequest.adUnitCode, - placementId: bidRequest.params.placementId || '', - site: bidRequest.params.site || bidderRequest.refererInfo.referer - } - - return slot; - }); - - utils.logMessage(payload); - - return { - method: 'POST', - url: `${CONCERT_ENDPOINT}/bids/prebid`, - data: JSON.stringify(payload) - } - }, - /** - * Unpack the 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. - */ - interpretResponse: function(serverResponse, bidRequest) { - utils.logMessage(serverResponse); - utils.logMessage(bidRequest); - - const serverBody = serverResponse.body; - - if (!serverBody || typeof serverBody !== 'object') { - return []; - } - - let bidResponses = []; - - bidResponses = serverBody.bids.map(bid => { - return { - requestId: bid.bidId, - cpm: bid.cpm, - width: bid.width, - height: bid.height, - ad: bid.ad, - ttl: bid.ttl, - meta: { advertiserDomains: bid && bid.adomain ? bid.adomain : [] }, - creativeId: bid.creativeId, - netRevenue: bid.netRevenue, - currency: bid.currency - } - }); - - if (utils.debugTurnedOn() && serverBody.debug) { - utils.logMessage(`CONCERT`, serverBody.debug); - } - - utils.logMessage(bidResponses); - return bidResponses; - }, - - /** - * Register the user sync pixels which should be dropped after the auction. - * - * @param {SyncOptions} syncOptions Which user syncs are allowed? - * @param {ServerResponse[]} serverResponses List of server's responses. - * @param {gdprConsent} object GDPR consent object. - * @param {uspConsent} string US Privacy String. - * @return {UserSync[]} The user syncs which should be dropped. - */ - getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) { - const syncs = [] - if (syncOptions.iframeEnabled && !hasOptedOutOfPersonalization()) { - let params = []; - - if (gdprConsent && (typeof gdprConsent.gdprApplies === 'boolean')) { - params.push(`gdpr_applies=${gdprConsent.gdprApplies ? '1' : '0'}`); - } - if (gdprConsent && (typeof gdprConsent.consentString === 'string')) { - params.push(`gdpr_consent=${gdprConsent.consentString}`); - } - if (uspConsent && (typeof uspConsent === 'string')) { - params.push(`usp_consent=${uspConsent}`); - } - - syncs.push({ - type: 'iframe', - url: USER_SYNC_URL + (params.length > 0 ? `?${params.join('&')}` : '') - }); - } - return syncs; - }, - - /** - * Register bidder specific code, which will execute if bidder timed out after an auction - * @param {data} Containing timeout specific data - */ - onTimeout: function(data) { - utils.logMessage('concert bidder timed out'); - utils.logMessage(data); - }, - - /** - * Register bidder specific code, which will execute if a bid from this bidder won the auction - * @param {Bid} The bid that won the auction - */ - onBidWon: function(bid) { - utils.logMessage('concert bidder won bid'); - utils.logMessage(bid); - } - -} - -registerBidder(spec); - -const storage = getStorageManager(); - -/** - * Check or generate a UID for the current user. - */ -function getUid(bidderRequest) { - if (hasOptedOutOfPersonalization() || !consentAllowsPpid(bidderRequest)) { - return false; - } - - const CONCERT_UID_KEY = 'c_uid'; - - let uid = storage.getDataFromLocalStorage(CONCERT_UID_KEY); - - if (!uid) { - uid = utils.generateUUID(); - storage.setDataInLocalStorage(CONCERT_UID_KEY, uid); - } - - return uid; -} - -/** - * Whether the user has opted out of personalization. - */ -function hasOptedOutOfPersonalization() { - const CONCERT_NO_PERSONALIZATION_KEY = 'c_nap'; - - return storage.getDataFromLocalStorage(CONCERT_NO_PERSONALIZATION_KEY) === 'true'; -} - -/** - * Whether the privacy consent strings allow personalization. - * - * @param {BidderRequest} bidderRequest Object which contains any data consent signals - */ -function consentAllowsPpid(bidderRequest) { - /* NOTE: We cannot easily test GDPR consent, without the - * `consent-string` npm module; so will have to rely on that - * happening on the bid-server. */ - return !(bidderRequest.uspConsent === 'string' && - bidderRequest.uspConsent.toUpperCase().substring(0, 2) === '1YY') -} diff --git a/modules/concertBidAdapter.md b/modules/concertBidAdapter.md deleted file mode 100644 index d8736082e5c..00000000000 --- a/modules/concertBidAdapter.md +++ /dev/null @@ -1,37 +0,0 @@ -# Overview - -``` -Module Name: Concert Bid Adapter -Module Type: Bidder Adapter -Maintainer: support@concert.io -``` - -# Description - -Module that connects to Concert demand sources - -# Test Paramters -``` - var adUnits = [ - { - code: 'desktop_leaderboard_variable', - mediaTypes: { - banner: { - sizes: [[1030, 590]] - } - } - bids: [ - { - bidder: "concert", - params: { - partnerId: 'test_partner', - site: 'site_name', - placementId: 1234567, - slot: 'slot_name', - sizes: [[1030, 590]] - } - } - ] - } - ]; -``` diff --git a/modules/connectadBidAdapter.js b/modules/connectadBidAdapter.js deleted file mode 100644 index 4fa2a56a004..00000000000 --- a/modules/connectadBidAdapter.js +++ /dev/null @@ -1,264 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js' -import {config} from '../src/config.js'; -import {createEidsArray} from './userId/eids.js'; - -const BIDDER_CODE = 'connectad'; -const BIDDER_CODE_ALIAS = 'connectadrealtime'; -const ENDPOINT_URL = 'https://i.connectad.io/api/v2'; -const SUPPORTED_MEDIA_TYPES = [BANNER]; - -export const spec = { - code: BIDDER_CODE, - gvlid: 138, - aliases: [ BIDDER_CODE_ALIAS ], - supportedMediaTypes: SUPPORTED_MEDIA_TYPES, - - isBidRequestValid: function(bid) { - return !!(bid.params.networkId && bid.params.siteId); - }, - - buildRequests: function(validBidRequests, bidderRequest) { - let ret = { - method: 'POST', - url: '', - data: '', - bidRequest: [] - }; - - if (validBidRequests.length < 1) { - return ret; - } - - const data = Object.assign({ - placements: [], - time: Date.now(), - user: {}, - url: (bidderRequest.refererInfo && bidderRequest.refererInfo.referer) ? bidderRequest.refererInfo.referer : window.location.href, - referrer: window.document.referrer, - referrer_info: bidderRequest.refererInfo, - screensize: getScreenSize(), - dnt: (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0, - language: navigator.language, - ua: navigator.userAgent, - pversion: '$prebid.version$' - }); - - // coppa compliance - if (config.getConfig('coppa') === true) { - utils.deepSetValue(data, 'user.coppa', 1); - } - - // adding schain object - if (validBidRequests[0].schain) { - utils.deepSetValue(data, 'source.ext.schain', validBidRequests[0].schain); - } - - // Attaching GDPR Consent Params - if (bidderRequest.gdprConsent) { - let gdprApplies; - if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') { - gdprApplies = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; - } - utils.deepSetValue(data, 'user.ext.gdpr', gdprApplies); - utils.deepSetValue(data, 'user.ext.consent', bidderRequest.gdprConsent.consentString); - } - - // CCPA - if (bidderRequest.uspConsent) { - utils.deepSetValue(data, 'user.ext.us_privacy', bidderRequest.uspConsent); - } - - // EIDS Support - if (validBidRequests[0].userId) { - utils.deepSetValue(data, 'user.ext.eids', createEidsArray(validBidRequests[0].userId)); - } - - validBidRequests.map(bid => { - const placement = Object.assign({ - id: bid.transactionId, - divName: bid.bidId, - pisze: bid.mediaTypes.banner.sizes[0] || bid.sizes[0], - sizes: bid.mediaTypes.banner.sizes, - adTypes: getSize(bid.mediaTypes.banner.sizes || bid.sizes), - bidfloor: getBidFloor(bid), - siteId: bid.params.siteId, - networkId: bid.params.networkId - }); - - if (placement.networkId && placement.siteId) { - data.placements.push(placement); - } - }); - - ret.data = JSON.stringify(data); - ret.bidRequest = validBidRequests; - ret.url = ENDPOINT_URL; - - return ret; - }, - - interpretResponse: function(serverResponse, bidRequest, bidderRequest) { - let bid; - let bids; - let bidId; - let bidObj; - let bidResponses = []; - - bids = bidRequest.bidRequest; - - serverResponse = (serverResponse || {}).body; - for (let i = 0; i < bids.length; i++) { - bid = {}; - bidObj = bids[i]; - bidId = bidObj.bidId; - - if (serverResponse) { - const decision = serverResponse.decisions && serverResponse.decisions[bidId]; - const price = decision && decision.pricing && decision.pricing.clearPrice; - - if (decision && price) { - bid.requestId = bidId; - bid.cpm = price; - bid.width = decision.width; - bid.height = decision.height; - bid.dealid = decision.dealid || null; - bid.ad = retrieveAd(decision); - bid.currency = 'USD'; - bid.creativeId = decision.adId; - bid.ttl = 360; - bid.netRevenue = true; - bidResponses.push(bid); - } - } - } - - return bidResponses; - }, - - transformBidParams: function (params, isOpenRtb) { - return utils.convertTypes({ - 'siteId': 'number', - 'networkId': 'number' - }, params); - }, - - getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) { - let syncEndpoint = 'https://cdn.connectad.io/connectmyusers.php?'; - - if (gdprConsent) { - syncEndpoint = utils.tryAppendQueryString(syncEndpoint, 'gdpr', (gdprConsent.gdprApplies ? 1 : 0)); - } - - if (gdprConsent && typeof gdprConsent.consentString === 'string') { - syncEndpoint = utils.tryAppendQueryString(syncEndpoint, 'gdpr_consent', gdprConsent.consentString); - } - - if (uspConsent) { - syncEndpoint = utils.tryAppendQueryString(syncEndpoint, 'us_privacy', uspConsent); - } - - if (config.getConfig('coppa') === true) { - syncEndpoint = utils.tryAppendQueryString(syncEndpoint, 'coppa', 1); - } - - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: syncEndpoint - }]; - } else { - utils.logWarn('Bidder ConnectAd: Please activate iFrame Sync'); - } - } -}; - -const sizeMap = [ - null, - '120x90', - '200x200', - '468x60', - '728x90', - '300x250', - '160x600', - '120x600', - '300x100', - '180x150', - '336x280', - '240x400', - '234x60', - '88x31', - '120x60', - '120x240', - '125x125', - '220x250', - '250x250', - '250x90', - '0x0', - '200x90', - '300x50', - '320x50', - '320x480', - '185x185', - '620x45', - '300x125', - '800x250', - '980x120', - '980x150', - '320x150', - '300x300', - '200x600', - '320x500', - '320x320' -]; - -sizeMap[77] = '970x90'; -sizeMap[123] = '970x250'; -sizeMap[43] = '300x600'; -sizeMap[286] = '970x66'; -sizeMap[3230] = '970x280'; -sizeMap[429] = '486x60'; -sizeMap[374] = '700x500'; -sizeMap[934] = '300x1050'; -sizeMap[1578] = '320x100'; -sizeMap[331] = '320x250'; -sizeMap[3301] = '320x267'; -sizeMap[2730] = '728x250'; - -function getBidFloor(bidRequest) { - let floorInfo = {}; - - if (typeof bidRequest.getFloor === 'function') { - floorInfo = bidRequest.getFloor({ - currency: 'USD', - mediaType: 'banner', - size: '*' - }); - } - - let floor = floorInfo.floor || bidRequest.params.bidfloor || bidRequest.params.floorprice || 0; - - return floor; -} - -function getSize(sizes) { - const result = []; - sizes.forEach(function(size) { - const index = sizeMap.indexOf(size[0] + 'x' + size[1]); - if (index >= 0) { - result.push(index); - } - }); - return result; -} - -function retrieveAd(decision) { - return decision.contents && decision.contents[0] && decision.contents[0].body; -} - -function getScreenSize() { - return [window.screen.width, window.screen.height].join('x'); -} - -registerBidder(spec); diff --git a/modules/connectadBidAdapter.md b/modules/connectadBidAdapter.md deleted file mode 100644 index e63494e1add..00000000000 --- a/modules/connectadBidAdapter.md +++ /dev/null @@ -1,46 +0,0 @@ -# Overview - -``` -Module Name: ConnectAd PreBid Adapter -Module Type: Bidder Adapter -Maintainer: support@connectad.io -``` - -# Description - -ConnectAd bid adapter supports only Banner at present. Video and Mobile will follow Q2/2020 - -# Sample Ad Unit: For Publishers -``` -var adUnits = [ -{ - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]] - } - }, - bids: [{ - bidder: 'connectad', - params: { - siteId: 123456, - networkId: 123456, - bidfloor: 0.20 // Optional: Requested Bidfloor - } - }] -} - -# ## Configuration -ConnectAd recommends the UserSync configuration below otherwise we will not be able to performe user syncs. - -```javascript -pbjs.setConfig({ - userSync: { - filterSettings: { - iframe: { - bidders: ['connectad'], - filter: 'include' - } - } - } -}); \ No newline at end of file diff --git a/modules/consentManagement.js b/modules/consentManagement.js deleted file mode 100644 index 6a13e73b8a2..00000000000 --- a/modules/consentManagement.js +++ /dev/null @@ -1,519 +0,0 @@ -/** - * This module adds GDPR consentManagement support to prebid.js. It interacts with - * supported CMPs (Consent Management Platforms) to grab the user's consent information - * and make it available for any GDPR supported adapters to read/pass this information to - * their system. - */ -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; -import { gdprDataHandler } from '../src/adapterManager.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import strIncludes from 'core-js-pure/features/string/includes.js'; - -const DEFAULT_CMP = 'iab'; -const DEFAULT_CONSENT_TIMEOUT = 10000; -const DEFAULT_ALLOW_AUCTION_WO_CONSENT = true; - -export const allowAuction = { - value: DEFAULT_ALLOW_AUCTION_WO_CONSENT, - definedInConfig: false -} -export let userCMP; -export let consentTimeout; -export let gdprScope; -export let staticConsentData; - -let cmpVersion = 0; -let consentData; -let addedConsentHook = false; - -// add new CMPs here, with their dedicated lookup function -const cmpCallMap = { - 'iab': lookupIabConsent, - 'static': lookupStaticConsentData -}; - -/** - * This function reads the consent string from the config to obtain the consent information of the user. - * @param {function(string)} cmpSuccess acts as a success callback when the value is read from config; pass along consentObject (string) from CMP - * @param {function(string)} cmpError acts as an error callback while interacting with the config string; pass along an error message (string) - * @param {object} hookConfig contains module related variables (see comment in requestBidsHook function) - */ -function lookupStaticConsentData(cmpSuccess, cmpError, hookConfig) { - cmpSuccess(staticConsentData, hookConfig); -} - -/** - * This function handles interacting with an IAB compliant CMP to obtain the consent information of the user. - * Given the async nature of the CMP's API, we pass in acting success/error callback functions to exit this function - * based on the appropriate result. - * @param {function(string)} cmpSuccess acts as a success callback when CMP returns a value; pass along consentObject (string) from CMP - * @param {function(string)} cmpError acts as an error callback while interacting with CMP; pass along an error message (string) - * @param {object} hookConfig contains module related variables (see comment in requestBidsHook function) - */ -function lookupIabConsent(cmpSuccess, cmpError, hookConfig) { - function findCMP() { - let f = window; - let cmpFrame; - let cmpFunction; - while (!cmpFrame) { - try { - if (typeof f.__tcfapi === 'function' || typeof f.__cmp === 'function') { - if (typeof f.__tcfapi === 'function') { - cmpVersion = 2; - cmpFunction = f.__tcfapi; - } else { - cmpVersion = 1; - cmpFunction = f.__cmp; - } - cmpFrame = f; - break; - } - } catch (e) { } - - // need separate try/catch blocks due to the exception errors thrown when trying to check for a frame that doesn't exist in 3rd party env - try { - if (f.frames['__tcfapiLocator']) { - cmpVersion = 2; - cmpFrame = f; - break; - } - } catch (e) { } - - try { - if (f.frames['__cmpLocator']) { - cmpVersion = 1; - cmpFrame = f; - break; - } - } catch (e) { } - - if (f === window.top) break; - f = f.parent; - } - return { - cmpFrame, - cmpFunction - }; - } - - function v2CmpResponseCallback(tcfData, success) { - utils.logInfo('Received a response from CMP', tcfData); - if (success) { - if (tcfData.gdprApplies === false || tcfData.eventStatus === 'tcloaded' || tcfData.eventStatus === 'useractioncomplete') { - cmpSuccess(tcfData, hookConfig); - } - } else { - cmpError('CMP unable to register callback function. Please check CMP setup.', hookConfig); - } - } - - function handleV1CmpResponseCallbacks() { - const cmpResponse = {}; - - function afterEach() { - if (cmpResponse.getConsentData && cmpResponse.getVendorConsents) { - utils.logInfo('Received all requested responses from CMP', cmpResponse); - cmpSuccess(cmpResponse, hookConfig); - } - } - - return { - consentDataCallback: function (consentResponse) { - cmpResponse.getConsentData = consentResponse; - afterEach(); - }, - vendorConsentsCallback: function (consentResponse) { - cmpResponse.getVendorConsents = consentResponse; - afterEach(); - } - } - } - - let v1CallbackHandler = handleV1CmpResponseCallbacks(); - let cmpCallbacks = {}; - let { cmpFrame, cmpFunction } = findCMP(); - - if (!cmpFrame) { - return cmpError('CMP not found.', hookConfig); - } - // to collect the consent information from the user, we perform two calls to the CMP in parallel: - // first to collect the user's consent choices represented in an encoded string (via getConsentData) - // second to collect the user's full unparsed consent information (via getVendorConsents) - - // the following code also determines where the CMP is located and uses the proper workflow to communicate with it: - // check to see if CMP is found on the same window level as prebid and call it directly if so - // check to see if prebid is in a safeframe (with CMP support) - // else assume prebid may be inside an iframe and use the IAB CMP locator code to see if CMP's located in a higher parent window. this works in cross domain iframes - // if the CMP is not found, the iframe function will call the cmpError exit callback to abort the rest of the CMP workflow - - if (utils.isFn(cmpFunction)) { - utils.logInfo('Detected CMP API is directly accessible, calling it now...'); - if (cmpVersion === 1) { - cmpFunction('getConsentData', null, v1CallbackHandler.consentDataCallback); - cmpFunction('getVendorConsents', null, v1CallbackHandler.vendorConsentsCallback); - } else if (cmpVersion === 2) { - cmpFunction('addEventListener', cmpVersion, v2CmpResponseCallback); - } - } else if (cmpVersion === 1 && inASafeFrame() && typeof window.$sf.ext.cmp === 'function') { - // this safeframe workflow is only supported with TCF v1 spec; the v2 recommends to use the iframe postMessage route instead (even if you are in a safeframe). - utils.logInfo('Detected Prebid.js is encased in a SafeFrame and CMP is registered, calling it now...'); - callCmpWhileInSafeFrame('getConsentData', v1CallbackHandler.consentDataCallback); - callCmpWhileInSafeFrame('getVendorConsents', v1CallbackHandler.vendorConsentsCallback); - } else { - utils.logInfo('Detected CMP is outside the current iframe where Prebid.js is located, calling it now...'); - if (cmpVersion === 1) { - callCmpWhileInIframe('getConsentData', cmpFrame, v1CallbackHandler.consentDataCallback); - callCmpWhileInIframe('getVendorConsents', cmpFrame, v1CallbackHandler.vendorConsentsCallback); - } else if (cmpVersion === 2) { - callCmpWhileInIframe('addEventListener', cmpFrame, v2CmpResponseCallback); - } - } - - function inASafeFrame() { - return !!(window.$sf && window.$sf.ext); - } - - function callCmpWhileInSafeFrame(commandName, callback) { - function sfCallback(msgName, data) { - if (msgName === 'cmpReturn') { - let responseObj = (commandName === 'getConsentData') ? data.vendorConsentData : data.vendorConsents; - callback(responseObj); - } - } - - // find sizes from adUnits object - let adUnits = hookConfig.adUnits; - let width = 1; - let height = 1; - if (Array.isArray(adUnits) && adUnits.length > 0) { - let sizes = utils.getAdUnitSizes(adUnits[0]); - width = sizes[0][0]; - height = sizes[0][1]; - } - - window.$sf.ext.register(width, height, sfCallback); - window.$sf.ext.cmp(commandName); - } - - function callCmpWhileInIframe(commandName, cmpFrame, moduleCallback) { - let apiName = (cmpVersion === 2) ? '__tcfapi' : '__cmp'; - - let callName = `${apiName}Call`; - - /* Setup up a __cmp function to do the postMessage and stash the callback. - This function behaves (from the caller's perspective identicially to the in-frame __cmp call */ - if (cmpVersion === 2) { - window[apiName] = function (cmd, cmpVersion, callback, arg) { - let callId = Math.random() + ''; - let msg = { - [callName]: { - command: cmd, - version: cmpVersion, - parameter: arg, - callId: callId - } - }; - - cmpCallbacks[callId] = callback; - cmpFrame.postMessage(msg, '*'); - } - - /** when we get the return message, call the stashed callback */ - window.addEventListener('message', readPostMessageResponse, false); - - // call CMP - window[apiName](commandName, cmpVersion, moduleCallback); - } else { - window[apiName] = function (cmd, arg, callback) { - let callId = Math.random() + ''; - let msg = { - [callName]: { - command: cmd, - parameter: arg, - callId: callId - } - }; - - cmpCallbacks[callId] = callback; - cmpFrame.postMessage(msg, '*'); - } - - /** when we get the return message, call the stashed callback */ - window.addEventListener('message', readPostMessageResponse, false); - - // call CMP - window[apiName](commandName, undefined, moduleCallback); - } - - function readPostMessageResponse(event) { - let cmpDataPkgName = `${apiName}Return`; - let json = (typeof event.data === 'string' && strIncludes(event.data, cmpDataPkgName)) ? JSON.parse(event.data) : event.data; - if (json[cmpDataPkgName] && json[cmpDataPkgName].callId) { - let payload = json[cmpDataPkgName]; - // TODO - clean up this logic (move listeners?); we have duplicate messages responses because 2 eventlisteners are active from the 2 cmp requests running in parallel - if (typeof cmpCallbacks[payload.callId] !== 'undefined') { - cmpCallbacks[payload.callId](payload.returnValue, payload.success); - } - } - } - } -} - -/** - * If consentManagement module is enabled (ie included in setConfig), this hook function will attempt to fetch the - * user's encoded consent string from the supported CMP. Once obtained, the module will store this - * data as part of a gdprConsent object which gets transferred to adapterManager's gdprDataHandler object. - * This information is later added into the bidRequest object for any supported adapters to read/pass along to their system. - * @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.js - */ -export function requestBidsHook(fn, reqBidsConfigObj) { - // preserves all module related variables for the current auction instance (used primiarily for concurrent auctions) - const hookConfig = { - context: this, - args: [reqBidsConfigObj], - nextFn: fn, - adUnits: reqBidsConfigObj.adUnits || $$PREBID_GLOBAL$$.adUnits, - bidsBackHandler: reqBidsConfigObj.bidsBackHandler, - haveExited: false, - timer: null - }; - - // in case we already have consent (eg during bid refresh) - if (consentData) { - utils.logInfo('User consent information already known. Pulling internally stored information...'); - return exitModule(null, hookConfig); - } - - if (!includes(Object.keys(cmpCallMap), userCMP)) { - utils.logWarn(`CMP framework (${userCMP}) is not a supported framework. Aborting consentManagement module and resuming auction.`); - return hookConfig.nextFn.apply(hookConfig.context, hookConfig.args); - } - - cmpCallMap[userCMP].call(this, processCmpData, cmpFailed, hookConfig); - - // only let this code run if module is still active (ie if the callbacks used by CMPs haven't already finished) - if (!hookConfig.haveExited) { - if (consentTimeout === 0) { - processCmpData(undefined, hookConfig); - } else { - hookConfig.timer = setTimeout(cmpTimedOut.bind(null, hookConfig), consentTimeout); - } - } -} - -/** - * This function checks the consent data provided by CMP to ensure it's in an expected state. - * If it's bad, we exit the module depending on config settings. - * If it's good, then we store the value and exits the module. - * @param {object} consentObject required; object returned by CMP that contains user's consent choices - * @param {object} hookConfig contains module related variables (see comment in requestBidsHook function) - */ -function processCmpData(consentObject, hookConfig) { - function checkV1Data(consentObject) { - let gdprApplies = consentObject && consentObject.getConsentData && consentObject.getConsentData.gdprApplies; - return !!( - (typeof gdprApplies !== 'boolean') || - (gdprApplies === true && - !(utils.isStr(consentObject.getConsentData.consentData) && - utils.isPlainObject(consentObject.getVendorConsents) && - Object.keys(consentObject.getVendorConsents).length > 1 - ) - ) - ); - } - - function checkV2Data() { - // if CMP does not respond with a gdprApplies boolean, use defaultGdprScope (gdprScope) - let gdprApplies = consentObject && typeof consentObject.gdprApplies === 'boolean' ? consentObject.gdprApplies : gdprScope; - let tcString = consentObject && consentObject.tcString; - return !!( - (typeof gdprApplies !== 'boolean') || - (gdprApplies === true && !utils.isStr(tcString)) - ); - } - - // do extra things for static config - if (userCMP === 'static') { - cmpVersion = (consentObject.getConsentData) ? 1 : (consentObject.getTCData) ? 2 : 0; - // remove extra layer in static v2 data object so it matches normal v2 CMP object for processing step - if (cmpVersion === 2) { - consentObject = consentObject.getTCData; - } - } - - // determine which set of checks to run based on cmpVersion - let checkFn = (cmpVersion === 1) ? checkV1Data : (cmpVersion === 2) ? checkV2Data : null; - - // Raise deprecation warning if 'allowAuctionWithoutConsent' is used with TCF 2. - if (allowAuction.definedInConfig && cmpVersion === 2) { - utils.logWarn(`'allowAuctionWithoutConsent' ignored for TCF 2`); - } else if (!allowAuction.definedInConfig && cmpVersion === 1) { - utils.logInfo(`'allowAuctionWithoutConsent' using system default: (${DEFAULT_ALLOW_AUCTION_WO_CONSENT}).`); - } - - if (utils.isFn(checkFn)) { - if (checkFn(consentObject)) { - cmpFailed(`CMP returned unexpected value during lookup process.`, hookConfig, consentObject); - } else { - clearTimeout(hookConfig.timer); - storeConsentData(consentObject); - exitModule(null, hookConfig); - } - } else { - cmpFailed('Unable to derive CMP version to process data. Consent object does not conform to TCF v1 or v2 specs.', hookConfig, consentObject); - } -} - -/** - * General timeout callback when interacting with CMP takes too long. - */ -function cmpTimedOut(hookConfig) { - cmpFailed('CMP workflow exceeded timeout threshold.', hookConfig); -} - -/** - * This function contains the controlled steps to perform when there's a problem with CMP. - * @param {string} errMsg required; should be a short descriptive message for why the failure/issue happened. - * @param {object} hookConfig contains module related variables (see comment in requestBidsHook function) - * @param {object} extraArgs contains additional data that's passed along in the error/warning messages for easier debugging -*/ -function cmpFailed(errMsg, hookConfig, extraArgs) { - clearTimeout(hookConfig.timer); - - // still set the consentData to undefined when there is a problem as per config options - if (allowAuction.value && cmpVersion === 1) { - storeConsentData(undefined); - } - exitModule(errMsg, hookConfig, extraArgs); -} - -/** - * Stores CMP data locally in module and then invokes gdprDataHandler.setConsentData() to make information available in adaptermanager.js for later in the auction - * @param {object} cmpConsentObject required; an object representing user's consent choices (can be undefined in certain use-cases for this function only) - */ -function storeConsentData(cmpConsentObject) { - if (cmpVersion === 1) { - consentData = { - consentString: (cmpConsentObject) ? cmpConsentObject.getConsentData.consentData : undefined, - vendorData: (cmpConsentObject) ? cmpConsentObject.getVendorConsents : undefined, - gdprApplies: (cmpConsentObject) ? cmpConsentObject.getConsentData.gdprApplies : gdprScope - }; - } else { - consentData = { - consentString: (cmpConsentObject) ? cmpConsentObject.tcString : undefined, - vendorData: (cmpConsentObject) || undefined, - gdprApplies: cmpConsentObject && typeof cmpConsentObject.gdprApplies === 'boolean' ? cmpConsentObject.gdprApplies : gdprScope - }; - if (cmpConsentObject && cmpConsentObject.addtlConsent && utils.isStr(cmpConsentObject.addtlConsent)) { - consentData.addtlConsent = cmpConsentObject.addtlConsent; - }; - } - consentData.apiVersion = cmpVersion; - gdprDataHandler.setConsentData(consentData); -} - -/** - * This function handles the exit logic for the module. - * While there are several paths in the module's logic to call this function, we only allow 1 of the 3 potential exits to happen before suppressing others. - * - * We prevent multiple exits to avoid conflicting messages in the console depending on certain scenarios. - * One scenario could be auction was canceled due to timeout with CMP being reached. - * While the timeout is the accepted exit and runs first, the CMP's callback still tries to process the user's data (which normally leads to a good exit). - * In this case, the good exit will be suppressed since we already decided to cancel the auction. - * - * Three exit paths are: - * 1. good exit where auction runs (CMP data is processed normally). - * 2. bad exit but auction still continues (warning message is logged, CMP data is undefined and still passed along). - * 3. bad exit with auction canceled (error message is logged). - * @param {string} errMsg optional; only to be used when there was a 'bad' exit. String is a descriptive message for the failure/issue encountered. - * @param {object} hookConfig contains module related variables (see comment in requestBidsHook function) - * @param {object} extraArgs contains additional data that's passed along in the error/warning messages for easier debugging - */ -function exitModule(errMsg, hookConfig, extraArgs) { - if (hookConfig.haveExited === false) { - hookConfig.haveExited = true; - - let context = hookConfig.context; - let args = hookConfig.args; - let nextFn = hookConfig.nextFn; - - if (errMsg) { - if (allowAuction.value && cmpVersion === 1) { - utils.logWarn(errMsg + ` 'allowAuctionWithoutConsent' activated.`, extraArgs); - nextFn.apply(context, args); - } else { - utils.logError(errMsg + ' Canceling auction as per consentManagement config.', extraArgs); - if (typeof hookConfig.bidsBackHandler === 'function') { - hookConfig.bidsBackHandler(); - } else { - utils.logError('Error executing bidsBackHandler'); - } - } - } else { - nextFn.apply(context, args); - } - } -} - -/** - * Simply resets the module's consentData variable back to undefined, mainly for testing purposes - */ -export function resetConsentData() { - consentData = undefined; - userCMP = undefined; - cmpVersion = 0; - gdprDataHandler.setConsentData(null); -} - -/** - * A configuration function that initializes some module variables, as well as add a hook into the requestBids function - * @param {{cmp:string, timeout:number, allowAuctionWithoutConsent:boolean, defaultGdprScope:boolean}} config required; consentManagement module config settings; cmp (string), timeout (int), allowAuctionWithoutConsent (boolean) - */ -export function setConsentConfig(config) { - // if `config.gdpr` or `config.usp` exist, assume new config format. - // else for backward compatability, just use `config` - config = config && (config.gdpr || config.usp ? config.gdpr : config); - if (!config || typeof config !== 'object') { - utils.logWarn('consentManagement config not defined, exiting consent manager'); - return; - } - if (utils.isStr(config.cmpApi)) { - userCMP = config.cmpApi; - } else { - userCMP = DEFAULT_CMP; - utils.logInfo(`consentManagement config did not specify cmp. Using system default setting (${DEFAULT_CMP}).`); - } - - if (utils.isNumber(config.timeout)) { - consentTimeout = config.timeout; - } else { - consentTimeout = DEFAULT_CONSENT_TIMEOUT; - utils.logInfo(`consentManagement config did not specify timeout. Using system default setting (${DEFAULT_CONSENT_TIMEOUT}).`); - } - - if (typeof config.allowAuctionWithoutConsent === 'boolean') { - allowAuction.value = config.allowAuctionWithoutConsent; - allowAuction.definedInConfig = true; - } - - // if true, then gdprApplies should be set to true - gdprScope = config.defaultGdprScope === true; - - utils.logInfo('consentManagement module has been activated...'); - - if (userCMP === 'static') { - if (utils.isPlainObject(config.consentData)) { - staticConsentData = config.consentData; - consentTimeout = 0; - } else { - utils.logError(`consentManagement config with cmpApi: 'static' did not specify consentData. No consents will be available to adapters.`); - } - } - if (!addedConsentHook) { - $$PREBID_GLOBAL$$.requestBids.before(requestBidsHook, 50); - } - addedConsentHook = true; -} -config.getConfig('consentManagement', config => setConsentConfig(config.consentManagement)); diff --git a/modules/consentManagementUsp.js b/modules/consentManagementUsp.js deleted file mode 100644 index cba9c2758d0..00000000000 --- a/modules/consentManagementUsp.js +++ /dev/null @@ -1,332 +0,0 @@ -/** - * This module adds USPAPI (CCPA) consentManagement support to prebid.js. It - * interacts with supported USP Consent APIs to grab the user's consent - * information and make it available for any USP (CCPA) supported adapters to - * read/pass this information to their system. - */ -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; -import { uspDataHandler } from '../src/adapterManager.js'; - -const DEFAULT_CONSENT_API = 'iab'; -const DEFAULT_CONSENT_TIMEOUT = 50; -const USPAPI_VERSION = 1; - -export let consentAPI; -export let consentTimeout; -export let staticConsentData; - -let consentData; -let addedConsentHook = false; - -// consent APIs -const uspCallMap = { - 'iab': lookupUspConsent, - 'static': lookupStaticConsentData -}; - -/** - * This function reads the consent string from the config to obtain the consent information of the user. - * @param {function(string)} cmpSuccess acts as a success callback when the value is read from config; pass along consentObject (string) from CMP - * @param {function(string)} cmpError acts as an error callback while interacting with the config string; pass along an error message (string) - * @param {object} hookConfig contains module related variables (see comment in requestBidsHook function) - */ -function lookupStaticConsentData(cmpSuccess, cmpError, hookConfig) { - cmpSuccess(staticConsentData, hookConfig); -} - -/** - * This function handles interacting with an USP compliant consent manager to obtain the consent information of the user. - * 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. - * @param {function(string)} uspSuccess acts as a success callback when USPAPI returns a value; pass along consentObject (string) from USPAPI - * @param {function(string)} uspError acts as an error callback while interacting with USPAPI; pass along an error message (string) - * @param {object} hookConfig contains module related variables (see comment in requestBidsHook function) - */ -function lookupUspConsent(uspSuccess, uspError, hookConfig) { - function findUsp() { - let f = window; - let uspapiFrame; - let uspapiFunction; - - while (!uspapiFrame) { - try { - if (typeof f.__uspapi === 'function') { - uspapiFunction = f.__uspapi; - uspapiFrame = f; - break; - } - } catch (e) {} - - try { - if (f.frames['__uspapiLocator']) { - uspapiFrame = f; - break; - } - } catch (e) {} - if (f === window.top) break; - f = f.parent; - } - return { - uspapiFrame, - uspapiFunction, - }; - } - - function handleUspApiResponseCallbacks() { - const uspResponse = {}; - - function afterEach() { - if (uspResponse.usPrivacy) { - uspSuccess(uspResponse, hookConfig); - } else { - uspError('Unable to get USP consent string.', hookConfig); - } - } - - return { - consentDataCallback: (consentResponse, success) => { - if (success && consentResponse.uspString) { - uspResponse.usPrivacy = consentResponse.uspString; - } - afterEach(); - }, - }; - } - - let callbackHandler = handleUspApiResponseCallbacks(); - let uspapiCallbacks = {}; - - let { uspapiFrame, uspapiFunction } = findUsp(); - - if (!uspapiFrame) { - return uspError('USP CMP not found.', hookConfig); - } - - // to collect the consent information from the user, we perform a call to USPAPI - // to collect the user's consent choices represented as a string (via getUSPData) - - // the following code also determines where the USPAPI is located and uses the proper workflow to communicate with it: - // - use the USPAPI locator code to see if USP's located in the current window or an ancestor window. - // - else assume prebid is in an iframe, and use the locator to see if the CMP is located in a higher parent window. This works in cross domain iframes. - // - if USPAPI is not found, the iframe function will call the uspError exit callback to abort the rest of the USPAPI workflow - - if (utils.isFn(uspapiFunction)) { - utils.logInfo('Detected USP CMP is directly accessible, calling it now...'); - uspapiFunction( - 'getUSPData', - USPAPI_VERSION, - callbackHandler.consentDataCallback - ); - } else { - utils.logInfo( - 'Detected USP CMP is outside the current iframe where Prebid.js is located, calling it now...' - ); - callUspApiWhileInIframe( - 'getUSPData', - uspapiFrame, - callbackHandler.consentDataCallback - ); - } - - function callUspApiWhileInIframe(commandName, uspapiFrame, moduleCallback) { - /* Setup up a __uspapi function to do the postMessage and stash the callback. - This function behaves, from the caller's perspective, identicially to the in-frame __uspapi call (although it is not synchronous) */ - window.__uspapi = function (cmd, ver, callback) { - let callId = Math.random() + ''; - let msg = { - __uspapiCall: { - command: cmd, - version: ver, - callId: callId, - }, - }; - - uspapiCallbacks[callId] = callback; - uspapiFrame.postMessage(msg, '*'); - }; - - /** when we get the return message, call the stashed callback */ - window.addEventListener('message', readPostMessageResponse, false); - - // call uspapi - window.__uspapi(commandName, USPAPI_VERSION, moduleCallback); - - function readPostMessageResponse(event) { - const res = event && event.data && event.data.__uspapiReturn; - if (res && res.callId) { - if (typeof uspapiCallbacks[res.callId] !== 'undefined') { - uspapiCallbacks[res.callId](res.returnValue, res.success); - delete uspapiCallbacks[res.callId]; - } - } - } - } -} - -/** - * If consentManagementUSP module is enabled (ie included in setConfig), this hook function will attempt to fetch the - * user's encoded consent string from the supported USPAPI. Once obtained, the module will store this - * data as part of a uspConsent object which gets transferred to adapterManager's uspDataHandler object. - * This information is later added into the bidRequest object for any supported adapters to read/pass along to their system. - * @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.js - */ -export function requestBidsHook(fn, reqBidsConfigObj) { - // preserves all module related variables for the current auction instance (used primiarily for concurrent auctions) - const hookConfig = { - context: this, - args: [reqBidsConfigObj], - nextFn: fn, - adUnits: reqBidsConfigObj.adUnits || $$PREBID_GLOBAL$$.adUnits, - bidsBackHandler: reqBidsConfigObj.bidsBackHandler, - haveExited: false, - timer: null - }; - - if (!uspCallMap[consentAPI]) { - utils.logWarn(`USP framework (${consentAPI}) is not a supported framework. Aborting consentManagement module and resuming auction.`); - return hookConfig.nextFn.apply(hookConfig.context, hookConfig.args); - } - - uspCallMap[consentAPI].call(this, processUspData, uspapiFailed, hookConfig); - - // only let this code run if module is still active (ie if the callbacks used by USPs haven't already finished) - if (!hookConfig.haveExited) { - if (consentTimeout === 0) { - processUspData(undefined, hookConfig); - } else { - hookConfig.timer = setTimeout(uspapiTimeout.bind(null, hookConfig), consentTimeout); - } - } -} - -/** - * This function checks the consent data provided by USPAPI to ensure it's in an expected state. - * If it's bad, we exit the module depending on config settings. - * If it's good, then we store the value and exits the module. - * @param {object} consentObject required; object returned by USPAPI that contains user's consent choices - * @param {object} hookConfig contains module related variables (see comment in requestBidsHook function) - */ -function processUspData(consentObject, hookConfig) { - const valid = !!(consentObject && consentObject.usPrivacy); - if (!valid) { - uspapiFailed(`USPAPI returned unexpected value during lookup process.`, hookConfig, consentObject); - return; - } - - clearTimeout(hookConfig.timer); - storeUspConsentData(consentObject); - exitModule(null, hookConfig); -} - -/** - * General timeout callback when interacting with USPAPI takes too long. - */ -function uspapiTimeout(hookConfig) { - uspapiFailed('USPAPI workflow exceeded timeout threshold.', hookConfig); -} - -/** - * This function contains the controlled steps to perform when there's a problem with USPAPI. - * @param {string} errMsg required; should be a short descriptive message for why the failure/issue happened. - * @param {object} hookConfig contains module related variables (see comment in requestBidsHook function) - * @param {object} extraArgs contains additional data that's passed along in the error/warning messages for easier debugging -*/ -function uspapiFailed(errMsg, hookConfig, extraArgs) { - clearTimeout(hookConfig.timer); - - exitModule(errMsg, hookConfig, extraArgs); -} - -/** - * Stores USP data locally in module and then invokes uspDataHandler.setConsentData() to make information available in adaptermanger.js for later in the auction - * @param {object} cmpConsentObject required; an object representing user's consent choices (can be undefined in certain use-cases for this function only) - */ -function storeUspConsentData(consentObject) { - if (consentObject && consentObject.usPrivacy) { - consentData = consentObject.usPrivacy; - uspDataHandler.setConsentData(consentData); - } -} - -/** - * This function handles the exit logic for the module. - * There are a couple paths in the module's logic to call this function and we only allow 1 of the 2 potential exits to happen before suppressing others. - * - * We prevent multiple exits to avoid conflicting messages in the console depending on certain scenarios. - * One scenario could be auction was canceled due to timeout with USPAPI being reached. - * While the timeout is the accepted exit and runs first, the USP's callback still tries to process the user's data (which normally leads to a good exit). - * In this case, the good exit will be suppressed since we already decided to cancel the auction. - * - * Three exit paths are: - * 1. good exit where auction runs (USPAPI data is processed normally). - * 2. bad exit but auction still continues (warning message is logged, USPAPI data is undefined and still passed along). - * @param {string} errMsg optional; only to be used when there was a 'bad' exit. String is a descriptive message for the failure/issue encountered. - * @param {object} hookConfig contains module related variables (see comment in requestBidsHook function) - * @param {object} extraArgs contains additional data that's passed along in the error/warning messages for easier debugging - */ -function exitModule(errMsg, hookConfig, extraArgs) { - if (hookConfig.haveExited === false) { - hookConfig.haveExited = true; - - let context = hookConfig.context; - let args = hookConfig.args; - let nextFn = hookConfig.nextFn; - - if (errMsg) { - utils.logWarn(errMsg + ' Resuming auction without consent data as per consentManagement config.', extraArgs); - } - nextFn.apply(context, args); - } -} - -/** - * Simply resets the module's consentData variable back to undefined, mainly for testing purposes - */ -export function resetConsentData() { - consentData = undefined; - consentAPI = undefined; - uspDataHandler.setConsentData(null); -} - -/** - * A configuration function that initializes some module variables, as well as add a hook into the requestBids function - * @param {object} config required; consentManagementUSP module config settings; usp (string), timeout (int), allowAuctionWithoutConsent (boolean) - */ -export function setConsentConfig(config) { - config = config && config.usp; - if (!config || typeof config !== 'object') { - utils.logWarn('consentManagement.usp config not defined, exiting usp consent manager'); - return; - } - if (utils.isStr(config.cmpApi)) { - consentAPI = config.cmpApi; - } else { - consentAPI = DEFAULT_CONSENT_API; - utils.logInfo(`consentManagement.usp config did not specify cmpApi. Using system default setting (${DEFAULT_CONSENT_API}).`); - } - - if (utils.isNumber(config.timeout)) { - consentTimeout = config.timeout; - } else { - consentTimeout = DEFAULT_CONSENT_TIMEOUT; - utils.logInfo(`consentManagement.usp config did not specify timeout. Using system default setting (${DEFAULT_CONSENT_TIMEOUT}).`); - } - - utils.logInfo('USPAPI consentManagement module has been activated...'); - - if (consentAPI === 'static') { - if (utils.isPlainObject(config.consentData) && utils.isPlainObject(config.consentData.getUSPData)) { - if (config.consentData.getUSPData.uspString) staticConsentData = { usPrivacy: config.consentData.getUSPData.uspString }; - consentTimeout = 0; - } else { - utils.logError(`consentManagement config with cmpApi: 'static' did not specify consentData. No consents will be available to adapters.`); - } - } - if (!addedConsentHook) { - $$PREBID_GLOBAL$$.requestBids.before(requestBidsHook, 50); - } - addedConsentHook = true; -} -config.getConfig('consentManagement', config => setConsentConfig(config.consentManagement)); diff --git a/modules/consumableBidAdapter.js b/modules/consumableBidAdapter.js deleted file mode 100644 index 8eb56f7d0c2..00000000000 --- a/modules/consumableBidAdapter.js +++ /dev/null @@ -1,214 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'consumable'; - -const BASE_URI = 'https://e.serverbid.com/api/v2' - -let siteId = 0; -let bidder = 'consumable'; - -export const spec = { - code: BIDDER_CODE, - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - return !!(bid.params.networkId && bid.params.siteId && bid.params.unitId && bid.params.unitName); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - - buildRequests: function(validBidRequests, bidderRequest) { - let ret = { - method: 'POST', - url: '', - data: '', - bidRequest: [] - }; - - if (validBidRequests.length < 1) { - return ret; - } - - // These variables are used in creating the user sync URL. - siteId = validBidRequests[0].params.siteId; - bidder = validBidRequests[0].bidder; - - const data = Object.assign({ - placements: [], - time: Date.now(), - url: bidderRequest.refererInfo.referer, - referrer: document.referrer, - source: [{ - 'name': 'prebidjs', - 'version': '$prebid.version$' - }] - }, validBidRequests[0].params); - - if (bidderRequest && bidderRequest.gdprConsent) { - data.gdpr = { - consent: bidderRequest.gdprConsent.consentString, - applies: (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') ? bidderRequest.gdprConsent.gdprApplies : true - }; - } - - if (bidderRequest && bidderRequest.uspConsent) { - data.ccpa = bidderRequest.uspConsent; - } - - validBidRequests.map(bid => { - const sizes = (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) || bid.sizes || []; - const placement = Object.assign({ - divName: bid.bidId, - adTypes: bid.adTypes || getSize(sizes) - }, bid.params); - - if (placement.networkId && placement.siteId && placement.unitId && placement.unitName) { - data.placements.push(placement); - } - }); - - ret.data = JSON.stringify(data); - ret.bidRequest = validBidRequests; - ret.bidderRequest = bidderRequest; - ret.url = BASE_URI; - - return ret; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse, bidRequest) { - let bid; - let bids; - let bidId; - let bidObj; - let bidResponses = []; - - bids = bidRequest.bidRequest; - - serverResponse = (serverResponse || {}).body; - for (let i = 0; i < bids.length; i++) { - bid = {}; - bidObj = bids[i]; - bidId = bidObj.bidId; - - if (serverResponse) { - const decision = serverResponse.decisions && serverResponse.decisions[bidId]; - const price = decision && decision.pricing && decision.pricing.clearPrice; - - if (decision && price) { - bid.requestId = bidId; - bid.cpm = price; - bid.width = decision.width; - bid.height = decision.height; - bid.unitId = bidObj.params.unitId; - bid.unitName = bidObj.params.unitName; - bid.ad = retrieveAd(decision, bid.unitId, bid.unitName); - bid.currency = 'USD'; - bid.creativeId = decision.adId; - bid.ttl = 30; - bid.netRevenue = true; - bid.referrer = bidRequest.bidderRequest.refererInfo.referer; - - bidResponses.push(bid); - } - } - } - - return bidResponses; - }, - - getUserSyncs: function(syncOptions, serverResponses) { - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: 'https://sync.serverbid.com/ss/' + siteId + '.html' - }]; - } - - if (syncOptions.pixelEnabled && serverResponses.length > 0) { - return serverResponses[0].body.pixels; - } else { - utils.logWarn(bidder + ': Please enable iframe based user syncing.'); - } - } -}; - -const sizeMap = [ - null, - '120x90', - '120x90', - '468x60', - '728x90', - '300x250', - '160x600', - '120x600', - '300x100', - '180x150', - '336x280', - '240x400', - '234x60', - '88x31', - '120x60', - '120x240', - '125x125', - '220x250', - '250x250', - '250x90', - '0x0', - '200x90', - '300x50', - '320x50', - '320x480', - '185x185', - '620x45', - '300x125', - '800x250' -]; - -sizeMap[77] = '970x90'; -sizeMap[123] = '970x250'; -sizeMap[43] = '300x600'; -sizeMap[286] = '970x66'; -sizeMap[3230] = '970x280'; -sizeMap[429] = '486x60'; -sizeMap[374] = '700x500'; -sizeMap[934] = '300x1050'; -sizeMap[1578] = '320x100'; -sizeMap[331] = '320x250'; -sizeMap[3301] = '320x267'; -sizeMap[2730] = '728x250'; - -function getSize(sizes) { - const result = []; - sizes.forEach(function(size) { - const index = sizeMap.indexOf(size[0] + 'x' + size[1]); - if (index >= 0) { - result.push(index); - } - }); - return result; -} - -function retrieveAd(decision, unitId, unitName) { - let ad = decision.contents && decision.contents[0] && decision.contents[0].body + utils.createTrackPixelHtml(decision.impressionUrl); - - return ad; -} - -registerBidder(spec); diff --git a/modules/consumableBidAdapter.md b/modules/consumableBidAdapter.md deleted file mode 100644 index 2189494ebd4..00000000000 --- a/modules/consumableBidAdapter.md +++ /dev/null @@ -1,48 +0,0 @@ -# Overview - -Module Name: Consumable Bid Adapter - -Module Type: Consumable Adapter - -Maintainer: naffis@consumable.com - -# Description - -Module that connects to Consumable's demand sources - -# Test Parameters -```javascript - var adUnits = [ - { - code: 'test-ad-1', - sizes: [[300, 250]], - bids: [ - { - bidder: 'consumable', - params: { - networkId: '9969', - siteId: '980639', - unitId: '123456', - unitName: 'cnsmbl-unit' - } - } - ] - }, - { - code: 'test-ad-2', - sizes: [[300, 250]], - bids: [ - { - bidder: 'consumable', - params: { - networkId: '9969', - siteId: '980639', - unitId: '123456', - unitName: 'cnsmbl-unit', - zoneIds: [178503] - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/contentigniteBidAdapter.md b/modules/contentigniteBidAdapter.md deleted file mode 100644 index 1f3a543b621..00000000000 --- a/modules/contentigniteBidAdapter.md +++ /dev/null @@ -1,30 +0,0 @@ -# Overview - -``` -Module Name: Content Ignite Bidder Adapter -Module Type: Bidder Adapter -Maintainer: jamie@contentignite.com -``` - -# Description - -Module that connects to Content Ignites bidder application. - -# Test Parameters - -``` - var adUnits = [{ - code: 'display-div', - sizes: [[728, 90]], // a display size - bids: [{ - bidder: "contentignite", - params: { - accountID: '168237', - zoneID: '299680', - keyword: 'business', //optional - minCPM: '0.10', //optional - maxCPM: '1.00' //optional - } - }] - }]; -``` diff --git a/modules/convergeBidAdapter.js b/modules/convergeBidAdapter.js deleted file mode 100644 index bea3b6cb1ab..00000000000 --- a/modules/convergeBidAdapter.js +++ /dev/null @@ -1,313 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { Renderer } from '../src/Renderer.js'; -import { VIDEO, BANNER } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'converge'; -const ENDPOINT_URL = 'https://tech.convergd.com/hb'; -const TIME_TO_LIVE = 360; -const SYNC_URL = 'https://tech.convergd.com/push_sync'; -const RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js'; - -let hasSynced = false; - -const LOG_ERROR_MESS = { - noAuid: 'Bid from response has no auid parameter - ', - noAdm: 'Bid from response has no adm parameter - ', - noBid: 'Array of bid objects is empty', - noPlacementCode: "Can't find in requested bids the bid with auid - ", - emptyUids: 'Uids should be not empty', - emptySeatbid: 'Seatbid array from response has empty item', - emptyResponse: 'Response is empty', - hasEmptySeatbidArray: 'Response has empty seatbid array', - hasNoArrayOfBids: 'Seatbid from response has no array of bid objects - ' -}; -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [ BANNER, VIDEO ], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - return !!bid.params.uid; - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests - an array of bids - * @param {bidderRequest} bidderRequest - bidder request object - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests, bidderRequest) { - const auids = []; - const bidsMap = {}; - const slotsMapByUid = {}; - const sizeMap = {}; - const bids = validBidRequests || []; - let priceType = 'net'; - let pageKeywords; - let reqId; - - bids.forEach(bid => { - if (bid.params.priceType === 'gross') { - priceType = 'gross'; - } - reqId = bid.bidderRequestId; - const {params: {uid}, adUnitCode} = bid; - auids.push(uid); - const sizesId = utils.parseSizesInput(bid.sizes); - - if (!pageKeywords && !utils.isEmpty(bid.params.keywords)) { - const keywords = utils.transformBidderParamKeywords(bid.params.keywords); - - if (keywords.length > 0) { - keywords.forEach(deleteValues); - } - pageKeywords = keywords; - } - - if (!slotsMapByUid[uid]) { - slotsMapByUid[uid] = {}; - } - const slotsMap = slotsMapByUid[uid]; - if (!slotsMap[adUnitCode]) { - slotsMap[adUnitCode] = {adUnitCode, bids: [bid], parents: []}; - } else { - slotsMap[adUnitCode].bids.push(bid); - } - const slot = slotsMap[adUnitCode]; - - sizesId.forEach((sizeId) => { - sizeMap[sizeId] = true; - if (!bidsMap[uid]) { - bidsMap[uid] = {}; - } - - if (!bidsMap[uid][sizeId]) { - bidsMap[uid][sizeId] = [slot]; - } else { - bidsMap[uid][sizeId].push(slot); - } - slot.parents.push({parent: bidsMap[uid], key: sizeId, uid}); - }); - }); - - const payload = { - pt: priceType, - auids: auids.join(','), - sizes: utils.getKeys(sizeMap).join(','), - r: reqId, - wrapperType: 'Prebid_js', - wrapperVersion: '$prebid.version$' - }; - - if (pageKeywords) { - payload.keywords = JSON.stringify(pageKeywords); - } - - if (bidderRequest) { - if (bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { - payload.u = bidderRequest.refererInfo.referer; - } - if (bidderRequest.timeout) { - payload.wtimeout = bidderRequest.timeout; - } - if (bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.consentString) { - payload.gdpr_consent = bidderRequest.gdprConsent.consentString; - } - payload.gdpr_applies = - (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') - ? Number(bidderRequest.gdprConsent.gdprApplies) : 1; - } - if (bidderRequest.uspConsent) { - payload.us_privacy = bidderRequest.uspConsent; - } - } - - return { - method: 'GET', - url: ENDPOINT_URL, - data: utils.parseQueryStringParameters(payload).replace(/\&$/, ''), - bidsMap: bidsMap, - }; - }, - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @param {*} bidRequest - * @param {Renderer} RendererConst - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse, bidRequest, RendererConst = Renderer) { - serverResponse = serverResponse && serverResponse.body; - const bidResponses = []; - const bidsMap = bidRequest.bidsMap; - const priceType = bidRequest.data.pt; - - let errorMessage; - - if (!serverResponse) errorMessage = LOG_ERROR_MESS.emptyResponse; - else if (serverResponse.seatbid && !serverResponse.seatbid.length) { - errorMessage = LOG_ERROR_MESS.hasEmptySeatbidArray; - } - - if (!errorMessage && serverResponse.seatbid) { - serverResponse.seatbid.forEach(respItem => { - _addBidResponse(_getBidFromResponse(respItem), bidsMap, priceType, bidResponses, RendererConst); - }); - } - if (errorMessage) utils.logError(errorMessage); - return bidResponses; - }, - getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent) { - if (!hasSynced && syncOptions.pixelEnabled) { - let params = ''; - - if (gdprConsent && typeof gdprConsent.consentString === 'string') { - if (typeof gdprConsent.gdprApplies === 'boolean') { - params += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - params += `&gdpr_consent=${gdprConsent.consentString}`; - } - } - if (uspConsent) { - params += `&us_privacy=${uspConsent}`; - } - - hasSynced = true; - return { - type: 'image', - url: SYNC_URL + params - }; - } - } -}; - -function isPopulatedArray(arr) { - return !!(utils.isArray(arr) && arr.length > 0); -} - -function deleteValues(keyPairObj) { - if (isPopulatedArray(keyPairObj.value) && keyPairObj.value[0] === '') { - delete keyPairObj.value; - } -} - -function _getBidFromResponse(respItem) { - if (!respItem) { - utils.logError(LOG_ERROR_MESS.emptySeatbid); - } else if (!respItem.bid) { - utils.logError(LOG_ERROR_MESS.hasNoArrayOfBids + JSON.stringify(respItem)); - } else if (!respItem.bid[0]) { - utils.logError(LOG_ERROR_MESS.noBid); - } - return respItem && respItem.bid && respItem.bid[0]; -} - -function _addBidResponse(serverBid, bidsMap, priceType, bidResponses, RendererConst) { - if (!serverBid) return; - let errorMessage; - if (!serverBid.auid) errorMessage = LOG_ERROR_MESS.noAuid + JSON.stringify(serverBid); - if (!serverBid.adm) errorMessage = LOG_ERROR_MESS.noAdm + JSON.stringify(serverBid); - else { - const awaitingBids = bidsMap[serverBid.auid]; - if (awaitingBids) { - const sizeId = `${serverBid.w}x${serverBid.h}`; - if (awaitingBids[sizeId]) { - const slot = awaitingBids[sizeId][0]; - - const bid = slot.bids.shift(); - const bidResponse = { - requestId: bid.bidId, // bid.bidderRequestId, - bidderCode: spec.code, - cpm: serverBid.price, - width: serverBid.w, - height: serverBid.h, - creativeId: serverBid.auid, // bid.bidId, - currency: 'EUR', - netRevenue: priceType !== 'gross', - ttl: TIME_TO_LIVE, - dealId: serverBid.dealid - }; - if (serverBid.content_type === 'video' || (!serverBid.content_type && bid.mediaTypes && bid.mediaTypes.video)) { - bidResponse.vastXml = serverBid.adm; - bidResponse.mediaType = VIDEO; - bidResponse.adResponse = { - content: bidResponse.vastXml - }; - if (!bid.renderer && (!bid.mediaTypes || !bid.mediaTypes.video || bid.mediaTypes.video.context === 'outstream')) { - bidResponse.renderer = createRenderer(bidResponse, { - id: bid.bidId, - url: RENDERER_URL - }, RendererConst); - } - } else { - bidResponse.ad = serverBid.adm; - bidResponse.mediaType = BANNER; - } - - bidResponses.push(bidResponse); - - if (!slot.bids.length) { - slot.parents.forEach(({parent, key, uid}) => { - const index = parent[key].indexOf(slot); - if (index > -1) { - parent[key].splice(index, 1); - } - if (!parent[key].length) { - delete parent[key]; - if (!utils.getKeys(parent).length) { - delete bidsMap[uid]; - } - } - }); - } - } - } else { - errorMessage = LOG_ERROR_MESS.noPlacementCode + serverBid.auid; - } - } - if (errorMessage) { - utils.logError(errorMessage); - } -} - -function outstreamRender (bid) { - bid.renderer.push(() => { - window.ANOutstreamVideo.renderAd({ - targetId: bid.adUnitCode, - adResponse: bid.adResponse - }); - }); -} - -function createRenderer (bid, rendererParams, RendererConst) { - const rendererInst = RendererConst.install({ - id: rendererParams.id, - url: rendererParams.url, - loaded: false - }); - - try { - rendererInst.setRender(outstreamRender); - } catch (err) { - utils.logWarn('Prebid Error calling setRender on renderer', err); - } - - return rendererInst; -} - -export function resetUserSync() { - hasSynced = false; -} - -export function getSyncUrl() { - return SYNC_URL; -} - -registerBidder(spec); diff --git a/modules/convergeBidAdapter.md b/modules/convergeBidAdapter.md deleted file mode 100644 index ab916a8b3b6..00000000000 --- a/modules/convergeBidAdapter.md +++ /dev/null @@ -1,57 +0,0 @@ -# Overview - -Module Name: Converge Bidder Adapter -Module Type: Bidder Adapter -Maintainer: support@converge-digital.com - -# Description - -Module that connects to Converge demand source to fetch bids. -Converge Bid Adapter supports Banner and Video (instream and outstream). - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - sizes: [[300, 250]], - bids: [ - { - bidder: "converge", - params: { - uid: '59', - priceType: 'gross' // by default is 'net' - } - } - ] - },{ - code: 'test-div', - sizes: [[728, 90]], - bids: [ - { - bidder: "converge", - params: { - uid: 1, - priceType: 'gross', - keywords: { - brandsafety: ['disaster'], - topic: ['stress', 'fear'] - } - } - } - ] - },{ - code: 'test-div', - sizes: [[640, 360]], - mediaTypes: { video: {} }, - bids: [ - { - bidder: "converge", - params: { - uid: 60 - } - } - ] - } - ]; -``` diff --git a/modules/conversantBidAdapter.js b/modules/conversantBidAdapter.js deleted file mode 100644 index 806f276fb72..00000000000 --- a/modules/conversantBidAdapter.js +++ /dev/null @@ -1,381 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const GVLID = 24; -export const storage = getStorageManager(GVLID); - -const BIDDER_CODE = 'conversant'; -const URL = 'https://web.hb.ad.cpe.dotomi.com/cvx/client/hb/ortb/25'; - -export const spec = { - code: BIDDER_CODE, - gvlid: GVLID, - aliases: ['cnvr'], // short code - supportedMediaTypes: [BANNER, VIDEO], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid - The bid params to validate. - * @return {boolean} True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - if (!bid || !bid.params) { - utils.logWarn(BIDDER_CODE + ': Missing bid parameters'); - return false; - } - - if (!utils.isStr(bid.params.site_id)) { - utils.logWarn(BIDDER_CODE + ': site_id must be specified as a string'); - return false; - } - - if (isVideoRequest(bid)) { - const mimes = bid.params.mimes || utils.deepAccess(bid, 'mediaTypes.video.mimes'); - if (!mimes) { - // Give a warning but let it pass - utils.logWarn(BIDDER_CODE + ': mimes should be specified for videos'); - } else if (!utils.isArray(mimes) || !mimes.every(s => utils.isStr(s))) { - utils.logWarn(BIDDER_CODE + ': mimes must be an array of strings'); - return false; - } - } - - return true; - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests - an array of bids - * @param bidderRequest - * @return {ServerRequest} Info describing the request to the server. - */ - buildRequests: function(validBidRequests, bidderRequest) { - const page = (bidderRequest && bidderRequest.refererInfo) ? bidderRequest.refererInfo.referer : ''; - let siteId = ''; - let requestId = ''; - let pubcid = null; - let pubcidName = '_pubcid'; - let bidurl = URL; - - const conversantImps = validBidRequests.map(function(bid) { - const bidfloor = utils.getBidIdParameter('bidfloor', bid.params); - - siteId = utils.getBidIdParameter('site_id', bid.params) || siteId; - pubcidName = utils.getBidIdParameter('pubcid_name', bid.params) || pubcidName; - - requestId = bid.auctionId; - - const imp = { - id: bid.bidId, - secure: 1, - bidfloor: bidfloor || 0, - displaymanager: 'Prebid.js', - displaymanagerver: '$prebid.version$' - }; - - copyOptProperty(bid.params.tag_id, imp, 'tagid'); - - if (isVideoRequest(bid)) { - const videoData = utils.deepAccess(bid, 'mediaTypes.video') || {}; - const format = convertSizes(videoData.playerSize || bid.sizes); - const video = {}; - - if (format && format[0]) { - copyOptProperty(format[0].w, video, 'w'); - copyOptProperty(format[0].h, video, 'h'); - } - - copyOptProperty(bid.params.position, video, 'pos'); - copyOptProperty(bid.params.mimes || videoData.mimes, video, 'mimes'); - copyOptProperty(bid.params.maxduration || videoData.maxduration, video, 'maxduration'); - copyOptProperty(bid.params.protocols || videoData.protocols, video, 'protocols'); - copyOptProperty(bid.params.api || videoData.api, video, 'api'); - - imp.video = video; - } else { - const bannerData = utils.deepAccess(bid, 'mediaTypes.banner') || {}; - const format = convertSizes(bannerData.sizes || bid.sizes); - const banner = {format: format}; - - copyOptProperty(bid.params.position, banner, 'pos'); - - imp.banner = banner; - } - - if (bid.userId && bid.userId.pubcid) { - pubcid = bid.userId.pubcid; - } else if (bid.crumbs && bid.crumbs.pubcid) { - pubcid = bid.crumbs.pubcid; - } - if (bid.params.white_label_url) { - bidurl = bid.params.white_label_url; - } - - return imp; - }); - - const payload = { - id: requestId, - imp: conversantImps, - site: { - id: siteId, - mobile: document.querySelector('meta[name="viewport"][content*="width=device-width"]') !== null ? 1 : 0, - page: page - }, - device: getDevice(), - at: 1 - }; - - let userExt = {}; - - if (bidderRequest) { - // Add GDPR flag and consent string - if (bidderRequest.gdprConsent) { - userExt.consent = bidderRequest.gdprConsent.consentString; - - if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') { - utils.deepSetValue(payload, 'regs.ext.gdpr', bidderRequest.gdprConsent.gdprApplies ? 1 : 0); - } - } - - if (bidderRequest.uspConsent) { - utils.deepSetValue(payload, 'regs.ext.us_privacy', bidderRequest.uspConsent); - } - } - - if (!pubcid) { - pubcid = readStoredValue(pubcidName); - } - - // Add common id if available - if (pubcid) { - userExt.fpc = pubcid; - } - - // Add Eids if available - const eids = collectEids(validBidRequests); - if (eids.length > 0) { - userExt.eids = eids; - } - - // Only add the user object if it's not empty - if (!utils.isEmpty(userExt)) { - payload.user = {ext: userExt}; - } - - return { - method: 'POST', - url: bidurl, - data: payload, - }; - }, - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @param bidRequest - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse, bidRequest) { - const bidResponses = []; - const requestMap = {}; - serverResponse = serverResponse.body; - - if (bidRequest && bidRequest.data && bidRequest.data.imp) { - utils._each(bidRequest.data.imp, imp => requestMap[imp.id] = imp); - } - - if (serverResponse && utils.isArray(serverResponse.seatbid)) { - utils._each(serverResponse.seatbid, function(bidList) { - utils._each(bidList.bid, function(conversantBid) { - const responseCPM = parseFloat(conversantBid.price); - if (responseCPM > 0.0 && conversantBid.impid) { - const responseAd = conversantBid.adm || ''; - const responseNurl = conversantBid.nurl || ''; - const request = requestMap[conversantBid.impid]; - - const bid = { - requestId: conversantBid.impid, - currency: serverResponse.cur || 'USD', - cpm: responseCPM, - creativeId: conversantBid.crid || '', - ttl: 300, - netRevenue: true - }; - bid.meta = {}; - if (conversantBid.adomain && conversantBid.adomain.length > 0) { - bid.meta.advertiserDomains = conversantBid.adomain; - } - - if (request.video) { - if (responseAd.charAt(0) === '<') { - bid.vastXml = responseAd; - } else { - bid.vastUrl = responseAd; - } - - bid.mediaType = 'video'; - bid.width = request.video.w; - bid.height = request.video.h; - } else { - bid.ad = responseAd + ''; - bid.width = conversantBid.w; - bid.height = conversantBid.h; - } - - bidResponses.push(bid); - } - }) - }); - } - - return bidResponses; - }, - - /** - * Covert bid param types for S2S - * @param {Object} params bid params - * @param {Boolean} isOpenRtb boolean to check openrtb2 protocol - * @return {Object} params bid params - */ - transformBidParams: function(params, isOpenRtb) { - return utils.convertTypes({ - 'site_id': 'string', - 'secure': 'number', - 'mobile': 'number' - }, params); - } -}; - -/** - * Determine do-not-track state - * - * @returns {boolean} - */ -function getDNT() { - return navigator.doNotTrack === '1' || window.doNotTrack === '1' || navigator.msDoNoTrack === '1' || navigator.doNotTrack === 'yes'; -} - -/** - * Return openrtb device object that includes ua, width, and height. - * - * @returns {Device} Openrtb device object - */ -function getDevice() { - const language = navigator.language ? 'language' : 'userLanguage'; - return { - h: screen.height, - w: screen.width, - dnt: getDNT() ? 1 : 0, - language: navigator[language].split('-')[0], - make: navigator.vendor ? navigator.vendor : '', - ua: navigator.userAgent - }; -} - -/** - * Convert arrays of widths and heights to an array of objects with w and h properties. - * - * [[300, 250], [300, 600]] => [{w: 300, h: 250}, {w: 300, h: 600}] - * - * @param {Array.>} bidSizes - arrays of widths and heights - * @returns {object[]} Array of objects with w and h - */ -function convertSizes(bidSizes) { - let format; - if (Array.isArray(bidSizes)) { - if (bidSizes.length === 2 && typeof bidSizes[0] === 'number' && typeof bidSizes[1] === 'number') { - format = [{w: bidSizes[0], h: bidSizes[1]}]; - } else { - format = utils._map(bidSizes, d => { return {w: d[0], h: d[1]}; }); - } - } - - return format; -} - -/** - * Check if it's a video bid request - * - * @param {BidRequest} bid - Bid request generated from ad slots - * @returns {boolean} True if it's a video bid - */ -function isVideoRequest(bid) { - return bid.mediaType === 'video' || !!utils.deepAccess(bid, 'mediaTypes.video'); -} - -/** - * Copy property if exists from src to dst - * - * @param {object} src - source object - * @param {object} dst - destination object - * @param {string} dstName - destination property name - */ -function copyOptProperty(src, dst, dstName) { - if (src) { - dst[dstName] = src; - } -} - -/** - * Collect IDs from validBidRequests and store them as an extended id array - * @param bidRequests valid bid requests - */ -function collectEids(bidRequests) { - const request = bidRequests[0]; // bidRequests have the same userId object - const eids = []; - if (utils.isArray(request.userIdAsEids) && request.userIdAsEids.length > 0) { - // later following white-list can be converted to block-list if needed - const requiredSourceValues = { - 'adserver.org': 1, - 'liveramp.com': 1, - 'criteo.com': 1, - 'id5-sync.com': 1, - 'parrable.com': 1, - 'liveintent.com': 1 - }; - request.userIdAsEids.forEach(function(eid) { - if (requiredSourceValues.hasOwnProperty(eid.source)) { - eids.push(eid); - } - }); - } - return eids; -} - -/** - * Look for a stored value from both cookie and local storage and return the first value found. - * @param key Key for the search - * @return {string} Stored value - */ -function readStoredValue(key) { - let storedValue; - try { - // check cookies first - storedValue = storage.getCookie(key); - - if (!storedValue) { - // check expiration time before reading local storage - const storedValueExp = storage.getDataFromLocalStorage(`${key}_exp`); - if (storedValueExp === '' || (storedValueExp && (new Date(storedValueExp)).getTime() - Date.now() > 0)) { - storedValue = storage.getDataFromLocalStorage(key); - storedValue = storedValue ? decodeURIComponent(storedValue) : storedValue; - } - } - - // deserialize JSON if needed - if (utils.isStr(storedValue) && storedValue.charAt(0) === '{') { - storedValue = JSON.parse(storedValue); - } - } catch (e) { - utils.logError(e); - } - - return storedValue; -} - -registerBidder(spec); diff --git a/modules/conversantBidAdapter.md b/modules/conversantBidAdapter.md deleted file mode 100644 index 07d9abf918b..00000000000 --- a/modules/conversantBidAdapter.md +++ /dev/null @@ -1,46 +0,0 @@ -# Overview - -- Module Name: Conversant Bidder Adapter -- Module Type: Bidder Adapter -- Maintainer: mediapsr@conversantmedia.com - -# Description - -Module that connects to Conversant's demand sources. Supports banners and videos. - -# Test Parameters -``` -var adUnits = [ - { - code: 'banner-test-div', - mediaTypes: { - banner: { - sizes: [[300, 250],[300,600]] - } - }, - bids: [{ - bidder: "conversant", - params: { - site_id: '108060' - } - }] - },{ - code: 'video-test-div', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480], - api: [2], - protocols: [1, 2], - mimes: ['video/mp4'] - } - }, - bids: [{ - bidder: "conversant", - params: { - site_id: '108060', - white_label_url: 'https://web.hb.ad.cpe.dotomi.com/s2s/header/24' - } - }] - }]; -``` diff --git a/modules/cosmosBidAdapter.js b/modules/cosmosBidAdapter.js deleted file mode 100644 index 73ee5c223b3..00000000000 --- a/modules/cosmosBidAdapter.js +++ /dev/null @@ -1,392 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; - -const BIDDER_CODE = 'cosmos'; -const BID_ENDPOINT = 'https://bid.cosmoshq.com/openrtb2/bids'; -const USER_SYNC_ENDPOINT = 'https://sync.cosmoshq.com/js/v1/usersync.html'; -const HTTP_POST = 'POST'; -const LOG_PREFIX = 'COSMOS: '; -const DEFAULT_CURRENCY = 'USD'; -const HTTPS = 'https:'; -const MEDIA_TYPES = 'mediaTypes'; -const MIMES = 'mimes'; -const DEFAULT_NET_REVENUE = false; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - - /** - * generate UUID - **/ - _createUUID: function () { - return ('' + new Date().getTime()); - }, - - /** - * copy object if not null - **/ - _copyObject: function (src, dst) { - if (src) { - // copy complete object - Object.keys(src).forEach(param => dst[param] = src[param]); - } - }, - - /** - * parse object - **/ - _parse: function (rawPayload) { - try { - if (rawPayload) { - return JSON.parse(rawPayload); - } - } catch (ex) { - utils.logError(LOG_PREFIX, 'Exception: ', ex); - } - return null; - }, - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - **/ - isBidRequestValid: function (bid) { - if (!bid || !bid.params) { - utils.logError(LOG_PREFIX, 'nil/empty bid object'); - return false; - } - - if (!utils.isEmpty(bid.params.publisherId) || - !utils.isNumber(bid.params.publisherId)) { - utils.logError(LOG_PREFIX, 'publisherId is mandatory and must be numeric. Ad Unit: ', JSON.stringify(bid)); - return false; - } - // video bid request validation - if (bid.hasOwnProperty(MEDIA_TYPES) && bid.mediaTypes.hasOwnProperty(VIDEO)) { - if (!bid.mediaTypes.video.hasOwnProperty(MIMES) || - !utils.isArray(bid.mediaTypes.video.mimes) || - bid.mediaTypes.video.mimes.length === 0) { - utils.logError(LOG_PREFIX, 'mimes are mandatory for video bid request. Ad Unit: ', JSON.stringify(bid)); - return false; - } - } - - return true; - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - **/ - buildRequests: function (validBidRequests, bidderRequest) { - if (validBidRequests.length === 0) { - return []; - } - - var refererInfo; - if (bidderRequest && bidderRequest.refererInfo) { - refererInfo = bidderRequest.refererInfo; - } - - let clonedBidRequests = utils.deepClone(validBidRequests); - return clonedBidRequests.map(bidRequest => { - const oRequest = spec._createRequest(bidRequest, refererInfo); - if (oRequest) { - spec._setGDPRParams(bidderRequest, oRequest); - return { - method: HTTP_POST, - url: BID_ENDPOINT, - data: JSON.stringify(oRequest) - }; - } - }); - }, - - /** - * Unpack the 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. - **/ - interpretResponse: function (serverResponse, request) { - let response = serverResponse.body; - var bidResponses = []; - try { - if (response.seatbid) { - var currency = response.cur ? response.cur : DEFAULT_CURRENCY; - response.seatbid.forEach(seatbid => { - var bids = seatbid.bid ? seatbid.bid : []; - bids.forEach(bid => { - var bidResponse = { - requestId: bid.impid, - cpm: (parseFloat(bid.price) || 0).toFixed(2), - width: bid.w, - height: bid.h, - creativeId: bid.crid, - currency: currency, - netRevenue: DEFAULT_NET_REVENUE, - ttl: 300 - }; - if (bid.dealid) { - bidResponse.dealId = bid.dealid; - } - - var req = spec._parse(request.data); - if (req.imp && req.imp.length > 0) { - req.imp.forEach(impr => { - if (impr.id === bid.impid) { - if (impr.banner) { - bidResponse.ad = bid.adm; - bidResponse.mediaType = BANNER; - } else { - bidResponse.width = bid.hasOwnProperty('w') ? bid.w : impr.video.w; - bidResponse.height = bid.hasOwnProperty('h') ? bid.h : impr.video.h; - bidResponse.vastXml = bid.adm; - bidResponse.mediaType = VIDEO; - } - } - }); - } - bidResponses.push(bidResponse); - }); - }); - } - } catch (ex) { - utils.logError(LOG_PREFIX, 'Exception: ', ex); - } - return bidResponses; - }, - - /** - * Register the user sync pixels which should be dropped after the auction. - * @param {SyncOptions} syncOptions Which user syncs are allowed? - * @param {ServerResponse[]} serverResponses List of server's responses. - * @return {UserSync[]} The user syncs which should be dropped. - **/ - getUserSyncs: function (syncOptions, serverResponses) { - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: USER_SYNC_ENDPOINT - }]; - } else { - utils.logWarn(LOG_PREFIX + 'Please enable iframe based user sync.'); - } - }, - - /** - * create IAB standard OpenRTB bid request - **/ - _createRequest: function (bidRequests, refererInfo) { - var oRequest = {}; - try { - oRequest = { - id: spec._createUUID(), - imp: spec._createImpressions(bidRequests), - user: {}, - ext: {} - }; - var site = spec._createSite(bidRequests, refererInfo); - var app = spec._createApp(bidRequests); - var device = spec._createDevice(bidRequests); - if (app) { - oRequest.app = app; - } - if (site) { - oRequest.site = site; - } - if (device) { - oRequest.device = device; - } - } catch (ex) { - utils.logError(LOG_PREFIX, 'Exception: ', ex); - oRequest = null; - } - return oRequest; - }, - - /** - * create impression array objects - **/ - _createImpressions: function (request) { - var impressions = []; - var impression = spec._creatImpression(request); - if (impression) { - impressions.push(impression); - } - return impressions; - }, - - /** - * create impression (single) object - **/ - _creatImpression: function (request) { - if (!request.hasOwnProperty(MEDIA_TYPES)) { - return undefined; - } - - var params = request && request.params ? request.params : null; - var impression = { - id: request.bidId ? request.bidId : spec._createUUID(), - secure: window.location.protocol === HTTPS ? 1 : 0, - bidfloorcur: request.params.currency ? request.params.currency : DEFAULT_CURRENCY - }; - if (params.bidFloor) { - impression.bidfloor = params.bidFloor; - } - - if (params.tagId) { - impression.tagid = params.tagId.toString(); - } - - var banner; - var video; - var mediaType; - for (mediaType in request.mediaTypes) { - switch (mediaType) { - case BANNER: - banner = spec._createBanner(request); - if (banner) { - impression.banner = banner; - } - break; - case VIDEO: - video = spec._createVideo(request); - if (video) { - impression.video = video; - } - break; - } - } - - return impression.hasOwnProperty(BANNER) || - impression.hasOwnProperty(VIDEO) ? impression : undefined; - }, - - /** - * create the banner object - **/ - _createBanner: function (request) { - if (utils.deepAccess(request, 'mediaTypes.banner')) { - var banner = {}; - var sizes = request.mediaTypes.banner.sizes; - if (sizes && utils.isArray(sizes) && sizes.length > 0) { - var format = []; - banner.w = sizes[0][0]; - banner.h = sizes[0][1]; - sizes.forEach(size => { - format.push({ - w: size[0], - h: size[1] - }); - }); - banner.format = format; - } - - spec._copyObject(request.mediaTypes.banner, banner); - spec._copyObject(request.params.banner, banner); - return banner; - } - return undefined; - }, - - /** - * create video object - **/ - _createVideo: function (request) { - if (utils.deepAccess(request, 'mediaTypes.video')) { - var video = {}; - var sizes = request.mediaTypes.video.playerSize; - if (sizes && utils.isArray(sizes) && sizes.length > 1) { - video.w = sizes[0]; - video.h = sizes[1]; - } - spec._copyObject(request.mediaTypes.video, video); - spec._copyObject(request.params.video, video); - return video; - } - return undefined; - }, - - /** - * create site object - **/ - _createSite: function (request, refererInfo) { - var rSite = request.params.site; - if (rSite || !request.params.app) { - var site = {}; - spec._copyObject(rSite, site); - - if (refererInfo) { - if (refererInfo.referer) { - site.ref = encodeURIComponent(refererInfo.referer); - } - if (utils.isArray(refererInfo.stack) && refererInfo.stack.length > 0) { - site.page = encodeURIComponent(refererInfo.stack[0]); - let anchrTag = document.createElement('a'); - anchrTag.href = site.page; - site.domain = anchrTag.hostname; - } - } - - // override publisher object - site.publisher = { - id: request.params.publisherId.toString() - }; - return site; - } - return undefined; - }, - - /** - * create app object - **/ - _createApp: function (request) { - var rApp = request.params.app; - if (rApp) { - var app = {}; - spec._copyObject(rApp, app); - // override publisher object - app.publisher = { - id: request.params.publisherId.toString() - }; - return app; - } - return undefined; - }, - - /** - * create device obejct - **/ - _createDevice: function (request) { - var device = {}; - var rDevice = request.params.device; - spec._copyObject(rDevice, device); - device.dnt = utils.getDNT() ? 1 : 0; - device.ua = navigator.userAgent; - device.language = (navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage); - device.w = (window.screen.width || window.innerWidth); - device.h = (window.screen.height || window.innerHeigh); - return device; - }, - - /** - * set GDPR parameters - **/ - _setGDPRParams: function (bidderRequest, oRequest) { - if (!bidderRequest || !bidderRequest.gdprConsent) { - return; - } - - oRequest.regs = { ext: { gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0 } }; - oRequest.user = { ext: { consent: bidderRequest.gdprConsent.consentString } }; - }, - -} -registerBidder(spec); diff --git a/modules/cosmosBidAdapter.md b/modules/cosmosBidAdapter.md deleted file mode 100644 index 187a19ba17a..00000000000 --- a/modules/cosmosBidAdapter.md +++ /dev/null @@ -1,80 +0,0 @@ -# Overview - -``` -Module Name: Cosmos Bid Adapter -Module Type: Bidder Adapter -Maintainer: dev@cosmoshq.com -``` - -# Description - -Module that connects to Cosmos server for bids. -Supported Ad Fortmats: -* Banner -* Video - -# Configuration -## Following configuration required for enabling user sync. -```javascript -pbjs.setConfig({ - userSync: { - iframeEnabled: true, - enabledBidders: ['cosmos'], - syncDelay: 6000 - }}); -``` -## For Video ads, enable prebid cache -```javascript -pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } -}); -``` - -# Test Parameters -``` - var adUnits = [ - // Banner adUnit - { - code: 'banner-div', - mediaTypes: { - banner: { //supported as per the openRTB spec - sizes: [[300, 250]] // required - } - }, - bids: [ - { - bidder: "cosmos", - params: { - publisherId: 1001, // required - tagId: 1 // optional - } - } - ] - }, - // Video adUnit - { - code: 'video-div', - mediaTypes: { - video: { // supported as per the openRTB spec - sizes: [[300, 50]], // required - mimes : ['video/mp4', 'application/javascript'], // required - context: 'instream' // optional - } - }, - bids: [ - { - bidder: "cosmos", - params: { - publisherId: 1001, // required - tagId: 1, // optional - video: { // supported as per the openRTB spec - - } - } - } - ] - } - ]; -``` diff --git a/modules/cpmstarBidAdapter.js b/modules/cpmstarBidAdapter.js deleted file mode 100644 index 61ccc0e786b..00000000000 --- a/modules/cpmstarBidAdapter.js +++ /dev/null @@ -1,180 +0,0 @@ - -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { VIDEO, BANNER } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; - -const BIDDER_CODE = 'cpmstar'; - -const ENDPOINT_DEV = 'https://dev.server.cpmstar.com/view.aspx'; -const ENDPOINT_STAGING = 'https://staging.server.cpmstar.com/view.aspx'; -const ENDPOINT_PRODUCTION = 'https://server.cpmstar.com/view.aspx'; - -const DEFAULT_TTL = 300; -const DEFAULT_CURRENCY = 'USD'; - -function fixedEncodeURIComponent(str) { - return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { - return '%' + c.charCodeAt(0).toString(16); - }); -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - pageID: Math.floor(Math.random() * 10e6), - - getMediaType: function (bidRequest) { - if (bidRequest == null) return BANNER; - return !utils.deepAccess(bidRequest, 'mediaTypes.video') ? BANNER : VIDEO; - }, - - getPlayerSize: function (bidRequest) { - var playerSize = utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize'); - if (playerSize == null) return [640, 440]; - if (playerSize[0] != null) playerSize = playerSize[0]; - if (playerSize == null || playerSize[0] == null || playerSize[1] == null) return [640, 440]; - return playerSize; - }, - - isBidRequestValid: function (bid) { - return ((typeof bid.params.placementId === 'string') && !!bid.params.placementId.length) || (typeof bid.params.placementId === 'number'); - }, - - buildRequests: function (validBidRequests, bidderRequest) { - var requests = []; - // This reference to window.top can cause issues when loaded in an iframe if not protected with a try/catch. - - for (var i = 0; i < validBidRequests.length; i++) { - var bidRequest = validBidRequests[i]; - var referer = encodeURIComponent(bidderRequest.refererInfo.referer); - var e = utils.getBidIdParameter('endpoint', bidRequest.params); - var ENDPOINT = e == 'dev' ? ENDPOINT_DEV : e == 'staging' ? ENDPOINT_STAGING : ENDPOINT_PRODUCTION; - var mediaType = spec.getMediaType(bidRequest); - var playerSize = spec.getPlayerSize(bidRequest); - var videoArgs = '&fv=0' + (playerSize ? ('&w=' + playerSize[0] + '&h=' + playerSize[1]) : ''); - var url = ENDPOINT + '?media=' + mediaType + (mediaType == VIDEO ? videoArgs : '') + - '&json=c_b&mv=1&poolid=' + utils.getBidIdParameter('placementId', bidRequest.params) + - '&reachedTop=' + encodeURIComponent(bidderRequest.refererInfo.reachedTop) + - '&requestid=' + bidRequest.bidId + - '&referer=' + encodeURIComponent(referer); - - if (bidRequest.schain && bidRequest.schain.nodes) { - var schain = bidRequest.schain; - var schainString = ''; - schainString += schain.ver + ',' + schain.complete; - for (var i2 = 0; i2 < schain.nodes.length; i2++) { - var node = schain.nodes[i2]; - schainString += '!' + - fixedEncodeURIComponent(node.asi || '') + ',' + - fixedEncodeURIComponent(node.sid || '') + ',' + - fixedEncodeURIComponent(node.hp || '') + ',' + - fixedEncodeURIComponent(node.rid || '') + ',' + - fixedEncodeURIComponent(node.name || '') + ',' + - fixedEncodeURIComponent(node.domain || ''); - } - url += '&schain=' + schainString - } - - if (bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.consentString != null) { - url += '&gdpr_consent=' + bidderRequest.gdprConsent.consentString; - } - if (bidderRequest.gdprConsent.gdprApplies != null) { - url += '&gdpr=' + (bidderRequest.gdprConsent.gdprApplies ? 1 : 0); - } - } - - if (bidderRequest.uspConsent != null) { - url += '&us_privacy=' + bidderRequest.uspConsent; - } - - if (config.getConfig('coppa')) { - url += '&tfcd=' + (config.getConfig('coppa') ? 1 : 0); - } - - requests.push({ - method: 'GET', - url: url, - bidRequest: bidRequest, - }); - } - - return requests; - }, - - interpretResponse: function (serverResponse, request) { - var bidRequest = request.bidRequest; - var mediaType = spec.getMediaType(bidRequest); - - var bidResponses = []; - - if (!Array.isArray(serverResponse.body)) { - serverResponse.body = [serverResponse.body]; - } - - for (var i = 0; i < serverResponse.body.length; i++) { - var raw = serverResponse.body[i]; - var rawBid = raw.creatives[0]; - if (!rawBid) { - utils.logWarn('cpmstarBidAdapter: server response failed check'); - return; - } - var cpm = (parseFloat(rawBid.cpm) || 0); - - if (!cpm) { - utils.logWarn('cpmstarBidAdapter: server response failed check. Missing cpm') - return; - } - - var bidResponse = { - requestId: rawBid.requestid, - cpm: cpm, - width: rawBid.width || 0, - height: rawBid.height || 0, - currency: rawBid.currency ? rawBid.currency : DEFAULT_CURRENCY, - netRevenue: rawBid.netRevenue ? rawBid.netRevenue : true, - ttl: rawBid.ttl ? rawBid.ttl : DEFAULT_TTL, - creativeId: rawBid.creativeid || 0, - }; - - if (rawBid.hasOwnProperty('dealId')) { - bidResponse.dealId = rawBid.dealId - } - - if (mediaType == BANNER && rawBid.code) { - bidResponse.ad = rawBid.code + (rawBid.px_cr ? "\n" : ''); - } else if (mediaType == VIDEO && rawBid.creativemacros && rawBid.creativemacros.HTML5VID_VASTSTRING) { - var playerSize = spec.getPlayerSize(bidRequest); - if (playerSize != null) { - bidResponse.width = playerSize[0]; - bidResponse.height = playerSize[1]; - } - bidResponse.mediaType = VIDEO; - bidResponse.vastXml = rawBid.creativemacros.HTML5VID_VASTSTRING; - } else { - return utils.logError('bad response', rawBid); - } - - bidResponses.push(bidResponse); - } - - return bidResponses; - }, - - getUserSyncs: function (syncOptions, serverResponses) { - const syncs = []; - if (serverResponses.length == 0 || !serverResponses[0].body) return syncs; - var usersyncs = serverResponses[0].body[0].syncs; - if (!usersyncs || usersyncs.length < 0) return syncs; - for (var i = 0; i < usersyncs.length; i++) { - var us = usersyncs[i]; - if ((us.type === 'image' && syncOptions.pixelEnabled) || (us.type == 'iframe' && syncOptions.iframeEnabled)) { - syncs.push(us); - } - } - return syncs; - } - -}; -registerBidder(spec); diff --git a/modules/cpmstarBidAdapter.md b/modules/cpmstarBidAdapter.md deleted file mode 100755 index c227f19bfaf..00000000000 --- a/modules/cpmstarBidAdapter.md +++ /dev/null @@ -1,53 +0,0 @@ -# Overview - -``` -Module Name: Cpmstar Bidder Adapter -Module Type: Bidder Adapter -Maintainer: josh@cpmstar.com -gdpr_supported: true -usp_supported: true -coppa_supported: true -``` - -# Description - -Module that connects to Cpmstar's demand sources - -# Test Parameters -``` -var adUnits = [ - { - code: 'banner-ad-div', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [ - { - bidder: 'cpmstar', - params: { - placementId: 81006 - } - }, - ] - }, - { - code: 'video-ad-div', - mediaTypes: { - video: { - context: 'instream', - sizes: [[640, 480]] - } - }, - bids:[ - { - bidder: 'cpmstar', - params: { - placementId: 81007 - } - } - ] - } -]; -``` \ No newline at end of file diff --git a/modules/craftBidAdapter.js b/modules/craftBidAdapter.js deleted file mode 100644 index 0124f96a107..00000000000 --- a/modules/craftBidAdapter.js +++ /dev/null @@ -1,239 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import { auctionManager } from '../src/auctionManager.js'; -import find from 'core-js-pure/features/array/find.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const BIDDER_CODE = 'craft'; -const URL_BASE = 'https://gacraft.jp/prebid-v3'; -const TTL = 360; -const storage = getStorageManager(); - -export const spec = { - code: BIDDER_CODE, - aliases: ['craft'], - supportedMediaTypes: [BANNER], - - isBidRequestValid: function(bid) { - return !!bid.params.sitekey && !!bid.params.placementId && !isAmp(); - }, - - buildRequests: function(bidRequests, bidderRequest) { - const tags = bidRequests.map(bidToTag); - const schain = bidRequests[0].schain; - const payload = { - tags: [...tags], - ua: navigator.userAgent, - sdk: { - version: '$prebid.version$' - }, - schain: schain - }; - if (bidderRequest && bidderRequest.gdprConsent) { - payload.gdpr_consent = { - consent_string: bidderRequest.gdprConsent.consentString, - consent_required: bidderRequest.gdprConsent.gdprApplies - }; - } - if (bidderRequest && bidderRequest.uspConsent) { - payload.us_privacy = bidderRequest.uspConsent; - } - if (bidderRequest && bidderRequest.refererInfo) { - let refererinfo = { - rd_ref: bidderRequest.refererInfo.referer, - rd_top: bidderRequest.refererInfo.reachedTop, - rd_ifs: bidderRequest.refererInfo.numIframes, - }; - if (bidderRequest.refererInfo.stack) { - refererinfo.rd_stk = bidderRequest.refererInfo.stack.join(','); - } - payload.referrer_detection = refererinfo; - } - const request = formatRequest(payload, bidderRequest); - return request; - }, - - interpretResponse: function(serverResponse, {bidderRequest}) { - try { - serverResponse = serverResponse.body; - const bids = []; - if (!serverResponse) { - return []; - } - if (serverResponse.error) { - let errorMessage = `in response for ${bidderRequest.bidderCode} adapter`; - if (serverResponse.error) { - errorMessage += `: ${serverResponse.error}`; - } - utils.logError(errorMessage); - return bids; - } - if (serverResponse.tags) { - serverResponse.tags.forEach(serverBid => { - const rtbBid = getRtbBid(serverBid); - if (rtbBid) { - if (rtbBid.cpm !== 0 && includes(this.supportedMediaTypes, rtbBid.ad_type)) { - const bid = newBid(serverBid, rtbBid, bidderRequest); - bid.mediaType = parseMediaType(rtbBid); - bids.push(bid); - } - } - }); - } - return bids; - } catch (e) { - return []; - } - }, - - transformBidParams: function(params, isOpenRtb) { - params = utils.convertTypes({ - 'sitekey': 'string', - 'placementId': 'string', - 'keywords': utils.transformBidderParamKeywords - }, params); - if (isOpenRtb) { - if (isPopulatedArray(params.keywords)) { - params.keywords.forEach(deleteValues); - } - Object.keys(params).forEach(paramKey => { - let convertedKey = utils.convertCamelToUnderscore(paramKey); - if (convertedKey !== paramKey) { - params[convertedKey] = params[paramKey]; - delete params[paramKey]; - } - }); - } - return params; - }, - - onBidWon: function(bid) { - var xhr = new XMLHttpRequest(); - xhr.open('POST', bid._prebidWon); - xhr.send(); - } -}; - -function isPopulatedArray(arr) { - return !!(utils.isArray(arr) && arr.length > 0); -} - -function deleteValues(keyPairObj) { - if (isPopulatedArray(keyPairObj.value) && keyPairObj.value[0] === '') { - delete keyPairObj.value; - } -} - -function hasPurpose1Consent(bidderRequest) { - let result = true; - if (bidderRequest && bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.gdprApplies && bidderRequest.gdprConsent.apiVersion === 2) { - result = !!(utils.deepAccess(bidderRequest.gdprConsent, 'vendorData.purpose.consents.1') === true); - } - } - return result; -} - -function formatRequest(payload, bidderRequest) { - let options = {}; - if (!hasPurpose1Consent(bidderRequest)) { - options = { - withCredentials: false - }; - } - - const payloadString = JSON.stringify(payload); - return { - method: 'POST', - url: `${URL_BASE}/${payload.tags[0].sitekey}`, - data: payloadString, - bidderRequest, - options - }; -} - -function newBid(serverBid, rtbBid, bidderRequest) { - const bidRequest = utils.getBidRequest(serverBid.uuid, [bidderRequest]); - const bid = { - requestId: serverBid.uuid, - cpm: rtbBid.cpm, - currency: 'JPY', - width: rtbBid.rtb.banner.width, - height: rtbBid.rtb.banner.height, - ad: rtbBid.rtb.banner.content, - ttl: TTL, - creativeId: rtbBid.creative_id, - netRevenue: false, // ??? - dealId: rtbBid.deal_id, - meta: null, - _adUnitCode: bidRequest.adUnitCode, - _bidKey: serverBid.bid_key, - _prebidWon: serverBid.won_url, - }; - return bid; -} - -function bidToTag(bid) { - const tag = {}; - for (var k in bid.params) { - tag[k] = bid.params[k]; - } - try { - if (storage.hasLocalStorage()) { - tag.uid = JSON.parse(storage.getDataFromLocalStorage(`${bid.params.sitekey}_uid`)); - } - } catch (e) { - } - tag.sizes = bid.sizes; - tag.primary_size = tag.sizes[0]; - tag.ad_types = []; - tag.uuid = bid.bidId; - if (!utils.isEmpty(bid.params.keywords)) { - let keywords = utils.transformBidderParamKeywords(bid.params.keywords); - if (keywords.length > 0) { - keywords.forEach(deleteValues); - } - tag.keywords = keywords; - } - let adUnit = find(auctionManager.getAdUnits(), au => bid.transactionId === au.transactionId); - if (adUnit && adUnit.mediaTypes && adUnit.mediaTypes.banner) { - tag.ad_types.push(BANNER); - } - - if (tag.ad_types.length === 0) { - delete tag.ad_types; - } - - return tag; -} - -function getRtbBid(tag) { - return tag && tag.ads && tag.ads.length && find(tag.ads, ad => ad.rtb); -} - -function parseMediaType(rtbBid) { - const adType = rtbBid.ad_type; - if (adType === VIDEO) { - return VIDEO; - } else if (adType === NATIVE) { - return NATIVE; - } else { - return BANNER; - } -} - -function isAmp() { - try { - const ampContext = window.context || window.parent.context; - if (ampContext && ampContext.pageViewId) { - return ampContext; - } - return false; - } catch (e) { - return false; - } -} - -registerBidder(spec); diff --git a/modules/craftBidAdapter.md b/modules/craftBidAdapter.md deleted file mode 100644 index d1a8daeab73..00000000000 --- a/modules/craftBidAdapter.md +++ /dev/null @@ -1,35 +0,0 @@ -# Overview - -``` -Module Name: Craft Bid Adapter -Module Type: Bidder Adapter -Maintainer: system@gacraft.jp -``` - -# Description - -Connects to craft exchange for bids. - -Craft bid adapter supports Banner. - -# Test Parameters -``` -var adUnits = [ - // Banner adUnit - { - code: '/21998384947/prebid-example', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [{ - bidder: 'craft', - params: { - sitekey: 'craft-prebid-example', - placementId: '1234abcd' - } - }] - } -]; -``` diff --git a/modules/criteoBidAdapter.js b/modules/criteoBidAdapter.js deleted file mode 100644 index 41cbb0670c8..00000000000 --- a/modules/criteoBidAdapter.js +++ /dev/null @@ -1,490 +0,0 @@ -import {loadExternalScript} from '../src/adloader.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; -import find from 'core-js-pure/features/array/find.js'; -import { verify } from 'criteo-direct-rsa-validate/build/verify.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const GVLID = 91; -export const ADAPTER_VERSION = 33; -const BIDDER_CODE = 'criteo'; -const CDB_ENDPOINT = 'https://bidder.criteo.com/cdb'; -const PROFILE_ID_INLINE = 207; -export const PROFILE_ID_PUBLISHERTAG = 185; -const storage = getStorageManager(GVLID); -const LOG_PREFIX = 'Criteo: '; - -// Unminified source code can be found in: https://github.com/Prebid-org/prebid-js-external-js-criteo/blob/master/dist/prod.js -const PUBLISHER_TAG_URL = 'https://static.criteo.net/js/ld/publishertag.prebid.js'; - -const FAST_BID_PUBKEY_E = 65537; -const FAST_BID_PUBKEY_N = 'ztQYwCE5BU7T9CDM5he6rKoabstXRmkzx54zFPZkWbK530dwtLBDeaWBMxHBUT55CYyboR/EZ4efghPi3CoNGfGWezpjko9P6p2EwGArtHEeS4slhu/SpSIFMjG6fdrpRoNuIAMhq1Z+Pr/+HOd1pThFKeGFr2/NhtAg+TXAzaU='; - -/** @type {BidderSpec} */ -export const spec = { - code: BIDDER_CODE, - gvlid: GVLID, - supportedMediaTypes: [ BANNER, VIDEO, NATIVE ], - - /** f - * @param {object} bid - * @return {boolean} - */ - isBidRequestValid: (bid) => { - // either one of zoneId or networkId should be set - if (!(bid && bid.params && (bid.params.zoneId || bid.params.networkId))) { - return false; - } - - // video media types requires some mandatory params - if (hasVideoMediaType(bid)) { - if (!hasValidVideoMediaType(bid)) { - return false; - } - } - - return true; - }, - - /** - * @param {BidRequest[]} bidRequests - * @param {*} bidderRequest - * @return {ServerRequest} - */ - buildRequests: (bidRequests, bidderRequest) => { - let url; - let data; - let fpd = config.getLegacyFpd(config.getConfig('ortb2')) || {}; - - Object.assign(bidderRequest, { - publisherExt: fpd.context, - userExt: fpd.user, - ceh: config.getConfig('criteo.ceh') - }); - - // If publisher tag not already loaded try to get it from fast bid - if (!publisherTagAvailable()) { - window.Criteo = window.Criteo || {}; - window.Criteo.usePrebidEvents = false; - - tryGetCriteoFastBid(); - - // Reload the PublisherTag after the timeout to ensure FastBid is up-to-date and tracking done properly - setTimeout(() => { - loadExternalScript(PUBLISHER_TAG_URL, BIDDER_CODE); - }, bidderRequest.timeout); - } - - if (publisherTagAvailable()) { - // eslint-disable-next-line no-undef - const adapter = new Criteo.PubTag.Adapters.Prebid(PROFILE_ID_PUBLISHERTAG, ADAPTER_VERSION, bidRequests, bidderRequest, '$prebid.version$'); - url = adapter.buildCdbUrl(); - data = adapter.buildCdbRequest(); - } else { - const context = buildContext(bidRequests, bidderRequest); - url = buildCdbUrl(context); - data = buildCdbRequest(context, bidRequests, bidderRequest); - } - - if (data) { - return { method: 'POST', url, data, bidRequests }; - } - }, - - /** - * @param {*} response - * @param {ServerRequest} request - * @return {Bid[]} - */ - interpretResponse: (response, request) => { - const body = response.body || response; - - if (publisherTagAvailable()) { - // eslint-disable-next-line no-undef - const adapter = Criteo.PubTag.Adapters.Prebid.GetAdapter(request); - if (adapter) { - return adapter.interpretResponse(body, request); - } - } - - const bids = []; - - if (body && body.slots && utils.isArray(body.slots)) { - body.slots.forEach(slot => { - const bidRequest = find(request.bidRequests, b => b.adUnitCode === slot.impid && (!b.params.zoneId || parseInt(b.params.zoneId) === slot.zoneid)); - const bidId = bidRequest.bidId; - const bid = { - requestId: bidId, - adId: slot.bidId || utils.getUniqueIdentifierStr(), - cpm: slot.cpm, - currency: slot.currency, - netRevenue: true, - ttl: slot.ttl || 60, - creativeId: bidId, - width: slot.width, - height: slot.height, - dealId: slot.dealCode, - }; - if (slot.native) { - if (bidRequest.params.nativeCallback) { - bid.ad = createNativeAd(bidId, slot.native, bidRequest.params.nativeCallback); - } else { - bid.native = createPrebidNativeAd(slot.native); - bid.mediaType = NATIVE; - } - } else if (slot.video) { - bid.vastUrl = slot.displayurl; - bid.mediaType = VIDEO; - } else { - bid.ad = slot.creative; - } - bids.push(bid); - }); - } - - return bids; - }, - - /** - * @param {TimedOutBid} timeoutData - */ - onTimeout: (timeoutData) => { - if (publisherTagAvailable() && Array.isArray(timeoutData)) { - var auctionsIds = []; - timeoutData.forEach((bid) => { - if (auctionsIds.indexOf(bid.auctionId) === -1) { - auctionsIds.push(bid.auctionId); - // eslint-disable-next-line no-undef - const adapter = Criteo.PubTag.Adapters.Prebid.GetAdapter(bid.auctionId); - adapter.handleBidTimeout(); - } - }); - } - }, - - /** - * @param {Bid} bid - */ - onBidWon: (bid) => { - if (publisherTagAvailable() && bid) { - // eslint-disable-next-line no-undef - const adapter = Criteo.PubTag.Adapters.Prebid.GetAdapter(bid.auctionId); - adapter.handleBidWon(bid); - } - }, - - /** - * @param {Bid} bid - */ - onSetTargeting: (bid) => { - if (publisherTagAvailable()) { - // eslint-disable-next-line no-undef - const adapter = Criteo.PubTag.Adapters.Prebid.GetAdapter(bid.auctionId); - adapter.handleSetTargeting(bid); - } - }, -}; - -/** - * @return {boolean} - */ -function publisherTagAvailable() { - // eslint-disable-next-line no-undef - return typeof Criteo !== 'undefined' && Criteo.PubTag && Criteo.PubTag.Adapters && Criteo.PubTag.Adapters.Prebid; -} - -/** - * @param {BidRequest[]} bidRequests - * @param bidderRequest - */ -function buildContext(bidRequests, bidderRequest) { - let referrer = ''; - if (bidderRequest && bidderRequest.refererInfo) { - referrer = bidderRequest.refererInfo.referer; - } - const queryString = utils.parseUrl(referrer).search; - - const context = { - url: referrer, - debug: queryString['pbt_debug'] === '1', - noLog: queryString['pbt_nolog'] === '1', - amp: false, - }; - - bidRequests.forEach(bidRequest => { - if (bidRequest.params.integrationMode === 'amp') { - context.amp = true; - } - }); - - return context; -} - -/** - * @param {CriteoContext} context - * @return {string} - */ -function buildCdbUrl(context) { - let url = CDB_ENDPOINT; - url += '?profileId=' + PROFILE_ID_INLINE; - url += '&av=' + String(ADAPTER_VERSION); - url += '&wv=' + encodeURIComponent('$prebid.version$'); - url += '&cb=' + String(Math.floor(Math.random() * 99999999999)); - - if (context.amp) { - url += '&im=1'; - } - if (context.debug) { - url += '&debug=1'; - } - if (context.noLog) { - url += '&nolog=1'; - } - - return url; -} - -function checkNativeSendId(bidRequest) { - return !(bidRequest.nativeParams && - ( - (bidRequest.nativeParams.image && ((bidRequest.nativeParams.image.sendId !== true || bidRequest.nativeParams.image.sendTargetingKeys === true))) || - (bidRequest.nativeParams.icon && ((bidRequest.nativeParams.icon.sendId !== true || bidRequest.nativeParams.icon.sendTargetingKeys === true))) || - (bidRequest.nativeParams.clickUrl && ((bidRequest.nativeParams.clickUrl.sendId !== true || bidRequest.nativeParams.clickUrl.sendTargetingKeys === true))) || - (bidRequest.nativeParams.displayUrl && ((bidRequest.nativeParams.displayUrl.sendId !== true || bidRequest.nativeParams.displayUrl.sendTargetingKeys === true))) || - (bidRequest.nativeParams.privacyLink && ((bidRequest.nativeParams.privacyLink.sendId !== true || bidRequest.nativeParams.privacyLink.sendTargetingKeys === true))) || - (bidRequest.nativeParams.privacyIcon && ((bidRequest.nativeParams.privacyIcon.sendId !== true || bidRequest.nativeParams.privacyIcon.sendTargetingKeys === true))) - )); -} - -/** - * @param {CriteoContext} context - * @param {BidRequest[]} bidRequests - * @param bidderRequest - * @return {*} - */ -function buildCdbRequest(context, bidRequests, bidderRequest) { - let networkId; - const request = { - publisher: { - url: context.url, - ext: bidderRequest.publisherExt - }, - slots: bidRequests.map(bidRequest => { - networkId = bidRequest.params.networkId || networkId; - const slot = { - impid: bidRequest.adUnitCode, - transactionid: bidRequest.transactionId, - auctionId: bidRequest.auctionId, - }; - if (bidRequest.params.zoneId) { - slot.zoneid = bidRequest.params.zoneId; - } - if (utils.deepAccess(bidRequest, 'ortb2Imp.ext')) { - slot.ext = bidRequest.ortb2Imp.ext; - } - if (bidRequest.params.ext) { - slot.ext = Object.assign({}, slot.ext, bidRequest.params.ext); - } - if (bidRequest.params.publisherSubId) { - slot.publishersubid = bidRequest.params.publisherSubId; - } - if (bidRequest.params.nativeCallback || utils.deepAccess(bidRequest, `mediaTypes.${NATIVE}`)) { - slot.native = true; - if (!checkNativeSendId(bidRequest)) { - utils.logWarn(LOG_PREFIX + 'all native assets containing URL should be sent as placeholders with sendId(icon, image, clickUrl, displayUrl, privacyLink, privacyIcon)'); - } - slot.sizes = parseSizes(retrieveBannerSizes(bidRequest), parseNativeSize); - } else { - slot.sizes = parseSizes(retrieveBannerSizes(bidRequest), parseSize); - } - if (hasVideoMediaType(bidRequest)) { - const video = { - playersizes: parseSizes(utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize'), parseSize), - mimes: bidRequest.mediaTypes.video.mimes, - protocols: bidRequest.mediaTypes.video.protocols, - maxduration: bidRequest.mediaTypes.video.maxduration, - api: bidRequest.mediaTypes.video.api - }; - - video.skip = bidRequest.params.video.skip; - video.placement = bidRequest.params.video.placement; - video.minduration = bidRequest.params.video.minduration; - video.playbackmethod = bidRequest.params.video.playbackmethod; - video.startdelay = bidRequest.params.video.startdelay; - - slot.video = video; - } - return slot; - }), - }; - if (networkId) { - request.publisher.networkid = networkId; - } - request.user = { - ext: bidderRequest.userExt - }; - if (bidderRequest && bidderRequest.ceh) { - request.user.ceh = bidderRequest.ceh; - } - if (bidderRequest && bidderRequest.gdprConsent) { - request.gdprConsent = {}; - if (typeof bidderRequest.gdprConsent.gdprApplies !== 'undefined') { - request.gdprConsent.gdprApplies = !!(bidderRequest.gdprConsent.gdprApplies); - } - request.gdprConsent.version = bidderRequest.gdprConsent.apiVersion; - if (typeof bidderRequest.gdprConsent.consentString !== 'undefined') { - request.gdprConsent.consentData = bidderRequest.gdprConsent.consentString; - } - } - if (bidderRequest && bidderRequest.uspConsent) { - request.user.uspIab = bidderRequest.uspConsent; - } - return request; -} - -function retrieveBannerSizes(bidRequest) { - return utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes') || bidRequest.sizes; -} - -function parseSizes(sizes, parser) { - if (Array.isArray(sizes[0])) { // is there several sizes ? (ie. [[728,90],[200,300]]) - return sizes.map(size => parser(size)); - } - return [parser(sizes)]; // or a single one ? (ie. [728,90]) -} - -function parseSize(size) { - return size[0] + 'x' + size[1]; -} - -function parseNativeSize(size) { - if (size[0] === undefined && size[1] === undefined) { - return '2x2'; - } - return size[0] + 'x' + size[1]; -} - -function hasVideoMediaType(bidRequest) { - if (utils.deepAccess(bidRequest, 'params.video') === undefined) { - return false; - } - return utils.deepAccess(bidRequest, 'mediaTypes.video') !== undefined; -} - -function hasValidVideoMediaType(bidRequest) { - let isValid = true; - - var requiredMediaTypesParams = ['mimes', 'playerSize', 'maxduration', 'protocols', 'api']; - - requiredMediaTypesParams.forEach(function(param) { - if (utils.deepAccess(bidRequest, 'mediaTypes.video.' + param) === undefined) { - isValid = false; - utils.logError('Criteo Bid Adapter: mediaTypes.video.' + param + ' is required'); - } - }); - - var requiredParams = ['skip', 'placement', 'playbackmethod']; - - requiredParams.forEach(function(param) { - if (utils.deepAccess(bidRequest, 'params.video.' + param) === undefined) { - isValid = false; - utils.logError('Criteo Bid Adapter: params.video.' + param + ' is required'); - } - }); - - if (isValid) { - // We do not support long form for now, also we have to check that context & placement are consistent - if (bidRequest.mediaTypes.video.context == 'instream' && bidRequest.params.video.placement === 1) { - return true; - } else if (bidRequest.mediaTypes.video.context == 'outstream' && bidRequest.params.video.placement !== 1) { - return true; - } - } - - return false; -} - -/** - * Create prebid compatible native ad with native payload - * @param {*} payload - * @returns prebid native ad assets - */ -function createPrebidNativeAd(payload) { - return { - sendTargetingKeys: false, // no key is added to KV by default - title: payload.products[0].title, - body: payload.products[0].description, - sponsoredBy: payload.advertiser.description, - icon: payload.advertiser.logo, - image: payload.products[0].image, - clickUrl: payload.products[0].click_url, - privacyLink: payload.privacy.optout_click_url, - privacyIcon: payload.privacy.optout_image_url, - cta: payload.products[0].call_to_action, - price: payload.products[0].price, - impressionTrackers: payload.impression_pixels.map(pix => pix.url) - }; -} - -/** - * @param {string} id - * @param {*} payload - * @param {*} callback - * @return {string} - */ -function createNativeAd(id, payload, callback) { - // Store the callback and payload in a global object to be later accessed from the creative - var slotsName = 'criteo_prebid_native_slots'; - window[slotsName] = window[slotsName] || {}; - window[slotsName][id] = { callback, payload }; - - // The creative is in an iframe so we have to get the callback and payload - // from the parent window (doesn't work with safeframes) - return ` -`; -} - -export function tryGetCriteoFastBid() { - try { - const fastBidStorageKey = 'criteo_fast_bid'; - const hashPrefix = '// Hash: '; - const fastBidFromStorage = storage.getDataFromLocalStorage(fastBidStorageKey); - - if (fastBidFromStorage !== null) { - // The value stored must contain the file's encrypted hash as first line - const firstLineEndPosition = fastBidFromStorage.indexOf('\n'); - const firstLine = fastBidFromStorage.substr(0, firstLineEndPosition).trim(); - - if (firstLine.substr(0, hashPrefix.length) !== hashPrefix) { - utils.logWarn('No hash found in FastBid'); - storage.removeDataFromLocalStorage(fastBidStorageKey); - } else { - // Remove the hash part from the locally stored value - const publisherTagHash = firstLine.substr(hashPrefix.length); - const publisherTag = fastBidFromStorage.substr(firstLineEndPosition + 1); - - if (verify(publisherTag, publisherTagHash, FAST_BID_PUBKEY_N, FAST_BID_PUBKEY_E)) { - utils.logInfo('Using Criteo FastBid'); - eval(publisherTag); // eslint-disable-line no-eval - } else { - utils.logWarn('Invalid Criteo FastBid found'); - storage.removeDataFromLocalStorage(fastBidStorageKey); - } - } - } - } catch (e) { - // Unable to get fast bid - } -} - -registerBidder(spec); diff --git a/modules/criteoBidAdapter.md b/modules/criteoBidAdapter.md deleted file mode 100644 index 68599f05434..00000000000 --- a/modules/criteoBidAdapter.md +++ /dev/null @@ -1,37 +0,0 @@ -# Overview - -Module Name: Criteo Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid@criteo.com - -# Description - -Module that connects to Criteo's demand sources. - -# Test Parameters -``` - var adUnits = [ - { - code: 'banner-ad-div', - sizes: [[300, 250], [728, 90]], - bids: [ - { - bidder: 'criteo', - params: { - zoneId: 497747 - } - } - ] - } - ]; -``` - -# Additional Config (Optional) -Set the "ceh" property to provides the user's hashed email if available -``` - pbjs.setConfig({ - criteo: { - ceh: 'hashed mail' - } - }); -``` \ No newline at end of file diff --git a/modules/criteoIdSystem.js b/modules/criteoIdSystem.js deleted file mode 100644 index ac26d34d529..00000000000 --- a/modules/criteoIdSystem.js +++ /dev/null @@ -1,141 +0,0 @@ -/** - * This module adds Criteo Real Time User Sync to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/criteoIdSystem - * @requires module:modules/userId - */ - -import * as utils from '../src/utils.js' -import * as ajax from '../src/ajax.js' -import { getRefererInfo } from '../src/refererDetection.js' -import { submodule } from '../src/hook.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const gvlid = 91; -const bidderCode = 'criteo'; -export const storage = getStorageManager(gvlid, bidderCode); - -const bididStorageKey = 'cto_bidid'; -const bundleStorageKey = 'cto_bundle'; -const cookiesMaxAge = 13 * 30 * 24 * 60 * 60 * 1000; - -const pastDateString = new Date(0).toString(); -const expirationString = new Date(utils.timestamp() + cookiesMaxAge).toString(); - -function extractProtocolHost (url, returnOnlyHost = false) { - const parsedUrl = utils.parseUrl(url, {noDecodeWholeURL: true}) - return returnOnlyHost - ? `${parsedUrl.hostname}` - : `${parsedUrl.protocol}://${parsedUrl.hostname}${parsedUrl.port ? ':' + parsedUrl.port : ''}/`; -} - -function getFromAllStorages(key) { - return storage.getCookie(key) || storage.getDataFromLocalStorage(key); -} - -function saveOnAllStorages(key, value) { - if (key && value) { - storage.setCookie(key, value, expirationString); - storage.setDataInLocalStorage(key, value); - } -} - -function deleteFromAllStorages(key) { - storage.setCookie(key, '', pastDateString); - storage.removeDataFromLocalStorage(key); -} - -function getCriteoDataFromAllStorages() { - return { - bundle: getFromAllStorages(bundleStorageKey), - bidId: getFromAllStorages(bididStorageKey), - } -} - -function buildCriteoUsersyncUrl(topUrl, domain, bundle, areCookiesWriteable, isLocalStorageWritable, isPublishertagPresent, gdprString) { - const url = 'https://gum.criteo.com/sid/json?origin=prebid' + - `${topUrl ? '&topUrl=' + encodeURIComponent(topUrl) : ''}` + - `${domain ? '&domain=' + encodeURIComponent(domain) : ''}` + - `${bundle ? '&bundle=' + encodeURIComponent(bundle) : ''}` + - `${gdprString ? '&gdprString=' + encodeURIComponent(gdprString) : ''}` + - `${areCookiesWriteable ? '&cw=1' : ''}` + - `${isPublishertagPresent ? '&pbt=1' : ''}` + - `${isLocalStorageWritable ? '&lsw=1' : ''}`; - - return url; -} - -function callCriteoUserSync(parsedCriteoData, gdprString) { - const cw = storage.cookiesAreEnabled(); - const lsw = storage.localStorageIsEnabled(); - const topUrl = extractProtocolHost(getRefererInfo().referer); - const domain = extractProtocolHost(document.location.href, true); - const isPublishertagPresent = typeof criteo_pubtag !== 'undefined'; // eslint-disable-line camelcase - - const url = buildCriteoUsersyncUrl( - topUrl, - domain, - parsedCriteoData.bundle, - cw, - lsw, - isPublishertagPresent, - gdprString - ); - - ajax.ajaxBuilder()( - url, - response => { - const jsonResponse = JSON.parse(response); - if (jsonResponse.bidId) { - saveOnAllStorages(bididStorageKey, jsonResponse.bidId); - } else { - deleteFromAllStorages(bididStorageKey); - } - - if (jsonResponse.acwsUrl) { - const urlsToCall = typeof jsonResponse.acwsUrl === 'string' ? [jsonResponse.acwsUrl] : jsonResponse.acwsUrl; - urlsToCall.forEach(url => utils.triggerPixel(url)); - } else if (jsonResponse.bundle) { - saveOnAllStorages(bundleStorageKey, jsonResponse.bundle); - } - }, - undefined, - { method: 'GET', contentType: 'application/json', withCredentials: true } - ); -} - -/** @type {Submodule} */ -export const criteoIdSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: bidderCode, - gvlid: gvlid, - /** - * decode the stored id value for passing to bid requests - * @function - * @returns {{criteoId: string} | undefined} - */ - decode(bidId) { - return bidId; - }, - /** - * get the Criteo Id from local storages and initiate a new user sync - * @function - * @param {SubmoduleConfig} [config] - * @param {ConsentData} [consentData] - * @returns {{id: {criteoId: string} | undefined}}} - */ - getId(config, consentData) { - const hasGdprData = consentData && typeof consentData.gdprApplies === 'boolean' && consentData.gdprApplies; - const gdprConsentString = hasGdprData ? consentData.consentString : undefined; - - let localData = getCriteoDataFromAllStorages(); - callCriteoUserSync(localData, gdprConsentString); - - return { id: localData.bidId ? { criteoId: localData.bidId } : undefined } - } -}; - -submodule('userId', criteoIdSubmodule); diff --git a/modules/currency.js b/modules/currency.js deleted file mode 100644 index 0464d9b5cdb..00000000000 --- a/modules/currency.js +++ /dev/null @@ -1,299 +0,0 @@ -import { getGlobal } from '../src/prebidGlobal.js'; -import { createBid } from '../src/bidfactory.js'; -import { STATUS } from '../src/constants.json'; -import { ajax } from '../src/ajax.js'; -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; -import { getHook } from '../src/hook.js'; - -const DEFAULT_CURRENCY_RATE_URL = 'https://cdn.jsdelivr.net/gh/prebid/currency-file@1/latest.json?date=$$TODAY$$'; -const CURRENCY_RATE_PRECISION = 4; - -var bidResponseQueue = []; -var conversionCache = {}; -var currencyRatesLoaded = false; -var needToCallForCurrencyFile = true; -var adServerCurrency = 'USD'; - -export var currencySupportEnabled = false; -export var currencyRates = {}; -var bidderCurrencyDefault = {}; -var defaultRates; - -/** - * Configuration function for currency - * @param {string} [config.adServerCurrency = 'USD'] - * ISO 4217 3-letter currency code that represents the target currency. (e.g. 'EUR'). If this value is present, - * the currency conversion feature is activated. - * @param {number} [config.granularityMultiplier = 1] - * A decimal value representing how mcuh to scale the price granularity calculations. - * @param {object} config.bidderCurrencyDefault - * An optional argument to specify bid currencies for bid adapters. This option is provided for the transitional phase - * before every bid adapter will specify its own bid currency. If the adapter specifies a bid currency, this value is - * ignored for that bidder. - * - * example: - * { - * rubicon: 'USD' - * } - * @param {string} [config.conversionRateFile = 'URL pointing to conversion file'] - * Optional path to a file containing currency conversion data. Prebid.org hosts a file that is used as the default, - * if not specified. - * @param {object} [config.rates] - * This optional argument allows you to specify the rates with a JSON object, subverting the need for a external - * config.conversionRateFile parameter. If this argument is specified, the conversion rate file will not be loaded. - * - * example: - * { - * 'GBP': { 'CNY': 8.8282, 'JPY': 141.7, 'USD': 1.2824 }, - * 'USD': { 'CNY': 6.8842, 'GBP': 0.7798, 'JPY': 110.49 } - * } - * @param {object} [config.defaultRates] - * This optional currency rates definition follows the same format as config.rates, however it is only utilized if - * there is an error loading the config.conversionRateFile. - */ -export function setConfig(config) { - let url = DEFAULT_CURRENCY_RATE_URL; - - if (typeof config.rates === 'object') { - currencyRates.conversions = config.rates; - currencyRatesLoaded = true; - needToCallForCurrencyFile = false; // don't call if rates are already specified - } - - if (typeof config.defaultRates === 'object') { - defaultRates = config.defaultRates; - - // set up the default rates to be used if the rate file doesn't get loaded in time - currencyRates.conversions = defaultRates; - currencyRatesLoaded = true; - } - - if (typeof config.adServerCurrency === 'string') { - utils.logInfo('enabling currency support', arguments); - - adServerCurrency = config.adServerCurrency; - if (config.conversionRateFile) { - utils.logInfo('currency using override conversionRateFile:', config.conversionRateFile); - url = config.conversionRateFile; - } - - // see if the url contains a date macro - // this is a workaround to the fact that jsdelivr doesn't currently support setting a 24-hour HTTP cache header - // So this is an approach to let the browser cache a copy of the file each day - // We should remove the macro once the CDN support a day-level HTTP cache setting - const macroLocation = url.indexOf('$$TODAY$$'); - if (macroLocation !== -1) { - // get the date to resolve the macro - const d = new Date(); - let month = `${d.getMonth() + 1}`; - let day = `${d.getDate()}`; - if (month.length < 2) month = `0${month}`; - if (day.length < 2) day = `0${day}`; - const todaysDate = `${d.getFullYear()}${month}${day}`; - - // replace $$TODAY$$ with todaysDate - url = `${url.substring(0, macroLocation)}${todaysDate}${url.substring(macroLocation + 9, url.length)}`; - } - - initCurrency(url); - } else { - // currency support is disabled, setting defaults - utils.logInfo('disabling currency support'); - resetCurrency(); - } - if (typeof config.bidderCurrencyDefault === 'object') { - bidderCurrencyDefault = config.bidderCurrencyDefault; - } -} -config.getConfig('currency', config => setConfig(config.currency)); - -function errorSettingsRates(msg) { - if (defaultRates) { - utils.logWarn(msg); - utils.logWarn('Currency failed loading rates, falling back to currency.defaultRates'); - } else { - utils.logError(msg); - } -} - -function initCurrency(url) { - conversionCache = {}; - currencySupportEnabled = true; - - utils.logInfo('Installing addBidResponse decorator for currency module', arguments); - - // Adding conversion function to prebid global for external module and on page use - getGlobal().convertCurrency = (cpm, fromCurrency, toCurrency) => parseFloat(cpm) * getCurrencyConversion(fromCurrency, toCurrency); - getHook('addBidResponse').before(addBidResponseHook, 100); - - // call for the file if we haven't already - if (needToCallForCurrencyFile) { - needToCallForCurrencyFile = false; - ajax(url, - { - success: function (response) { - try { - currencyRates = JSON.parse(response); - utils.logInfo('currencyRates set to ' + JSON.stringify(currencyRates)); - currencyRatesLoaded = true; - processBidResponseQueue(); - } catch (e) { - errorSettingsRates('Failed to parse currencyRates response: ' + response); - } - }, - error: errorSettingsRates - } - ); - } -} - -function resetCurrency() { - utils.logInfo('Uninstalling addBidResponse decorator for currency module', arguments); - - getHook('addBidResponse').getHooks({hook: addBidResponseHook}).remove(); - delete getGlobal().convertCurrency; - - adServerCurrency = 'USD'; - conversionCache = {}; - currencySupportEnabled = false; - currencyRatesLoaded = false; - needToCallForCurrencyFile = true; - currencyRates = {}; - bidderCurrencyDefault = {}; -} - -export function addBidResponseHook(fn, adUnitCode, bid) { - if (!bid) { - return fn.call(this, adUnitCode); // if no bid, call original and let it display warnings - } - - let bidder = bid.bidderCode || bid.bidder; - if (bidderCurrencyDefault[bidder]) { - let currencyDefault = bidderCurrencyDefault[bidder]; - if (bid.currency && currencyDefault !== bid.currency) { - utils.logWarn(`Currency default '${bidder}: ${currencyDefault}' ignored. adapter specified '${bid.currency}'`); - } else { - bid.currency = currencyDefault; - } - } - - // default to USD if currency not set - if (!bid.currency) { - utils.logWarn('Currency not specified on bid. Defaulted to "USD"'); - bid.currency = 'USD'; - } - - // used for analytics - bid.getCpmInNewCurrency = function(toCurrency) { - return (parseFloat(this.cpm) * getCurrencyConversion(this.currency, toCurrency)).toFixed(3); - }; - - // execute immediately if the bid is already in the desired currency - if (bid.currency === adServerCurrency) { - return fn.call(this, adUnitCode, bid); - } - - bidResponseQueue.push(wrapFunction(fn, this, [adUnitCode, bid])); - if (!currencySupportEnabled || currencyRatesLoaded) { - processBidResponseQueue(); - } -} - -function processBidResponseQueue() { - while (bidResponseQueue.length > 0) { - (bidResponseQueue.shift())(); - } -} - -function wrapFunction(fn, context, params) { - return function() { - let bid = params[1]; - if (bid !== undefined && 'currency' in bid && 'cpm' in bid) { - let fromCurrency = bid.currency; - try { - let conversion = getCurrencyConversion(fromCurrency); - if (conversion !== 1) { - bid.cpm = (parseFloat(bid.cpm) * conversion).toFixed(4); - bid.currency = adServerCurrency; - } - } catch (e) { - utils.logWarn('Returning NO_BID, getCurrencyConversion threw error: ', e); - params[1] = createBid(STATUS.NO_BID, { - bidder: bid.bidderCode || bid.bidder, - bidId: bid.requestId - }); - } - } - return fn.apply(context, params); - }; -} - -function getCurrencyConversion(fromCurrency, toCurrency = adServerCurrency) { - var conversionRate = null; - var rates; - let cacheKey = `${fromCurrency}->${toCurrency}`; - if (cacheKey in conversionCache) { - conversionRate = conversionCache[cacheKey]; - utils.logMessage('Using conversionCache value ' + conversionRate + ' for ' + cacheKey); - } else if (currencySupportEnabled === false) { - if (fromCurrency === 'USD') { - conversionRate = 1; - } else { - throw new Error('Prebid currency support has not been enabled and fromCurrency is not USD'); - } - } else if (fromCurrency === toCurrency) { - conversionRate = 1; - } else { - if (fromCurrency in currencyRates.conversions) { - // using direct conversion rate from fromCurrency to toCurrency - rates = currencyRates.conversions[fromCurrency]; - if (!(toCurrency in rates)) { - // bid should fail, currency is not supported - throw new Error('Specified adServerCurrency in config \'' + toCurrency + '\' not found in the currency rates file'); - } - conversionRate = rates[toCurrency]; - utils.logInfo('getCurrencyConversion using direct ' + fromCurrency + ' to ' + toCurrency + ' conversionRate ' + conversionRate); - } else if (toCurrency in currencyRates.conversions) { - // using reciprocal of conversion rate from toCurrency to fromCurrency - rates = currencyRates.conversions[toCurrency]; - if (!(fromCurrency in rates)) { - // bid should fail, currency is not supported - throw new Error('Specified fromCurrency \'' + fromCurrency + '\' not found in the currency rates file'); - } - conversionRate = roundFloat(1 / rates[fromCurrency], CURRENCY_RATE_PRECISION); - utils.logInfo('getCurrencyConversion using reciprocal ' + fromCurrency + ' to ' + toCurrency + ' conversionRate ' + conversionRate); - } else { - // first defined currency base used as intermediary - var anyBaseCurrency = Object.keys(currencyRates.conversions)[0]; - - if (!(fromCurrency in currencyRates.conversions[anyBaseCurrency])) { - // bid should fail, currency is not supported - throw new Error('Specified fromCurrency \'' + fromCurrency + '\' not found in the currency rates file'); - } - var toIntermediateConversionRate = 1 / currencyRates.conversions[anyBaseCurrency][fromCurrency]; - - if (!(toCurrency in currencyRates.conversions[anyBaseCurrency])) { - // bid should fail, currency is not supported - throw new Error('Specified adServerCurrency in config \'' + toCurrency + '\' not found in the currency rates file'); - } - var fromIntermediateConversionRate = currencyRates.conversions[anyBaseCurrency][toCurrency]; - - conversionRate = roundFloat(toIntermediateConversionRate * fromIntermediateConversionRate, CURRENCY_RATE_PRECISION); - utils.logInfo('getCurrencyConversion using intermediate ' + fromCurrency + ' thru ' + anyBaseCurrency + ' to ' + toCurrency + ' conversionRate ' + conversionRate); - } - } - if (!(cacheKey in conversionCache)) { - utils.logMessage('Adding conversionCache value ' + conversionRate + ' for ' + cacheKey); - conversionCache[cacheKey] = conversionRate; - } - return conversionRate; -} - -function roundFloat(num, dec) { - var d = 1; - for (let i = 0; i < dec; i++) { - d += '0'; - } - return Math.round(num * d) / d; -} diff --git a/modules/dailyhuntBidAdapter.js b/modules/dailyhuntBidAdapter.js deleted file mode 100644 index 1018417300a..00000000000 --- a/modules/dailyhuntBidAdapter.js +++ /dev/null @@ -1,395 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import * as mediaTypes from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; -import { ajax } from '../src/ajax.js'; -import find from 'core-js-pure/features/array/find.js'; -import { OUTSTREAM, INSTREAM } from '../src/video.js'; - -const BIDDER_CODE = 'dailyhunt'; -const BIDDER_ALIAS = 'dh'; -const SUPPORTED_MEDIA_TYPES = [mediaTypes.BANNER, mediaTypes.NATIVE, mediaTypes.VIDEO]; - -const PROD_PREBID_ENDPOINT_URL = 'https://pbs.dailyhunt.in/openrtb2/auction?partner='; -const PROD_PREBID_TEST_ENDPOINT_URL = 'https://qa-pbs-van.dailyhunt.in/openrtb2/auction?partner='; - -const ORTB_NATIVE_TYPE_MAPPING = { - img: { - '3': 'image', - '1': 'icon' - }, - data: { - '1': 'sponsoredBy', - '2': 'body', - '3': 'rating', - '4': 'likes', - '5': 'downloads', - '6': 'price', - '7': 'salePrice', - '8': 'phone', - '9': 'address', - '10': 'body2', - '11': 'displayUrl', - '12': 'cta' - } -} - -const ORTB_NATIVE_PARAMS = { - title: { - id: 0, - name: 'title' - }, - icon: { - id: 1, - type: 1, - name: 'img' - }, - image: { - id: 2, - type: 3, - name: 'img' - }, - sponsoredBy: { - id: 3, - name: 'data', - type: 1 - }, - body: { - id: 4, - name: 'data', - type: 2 - }, - cta: { - id: 5, - type: 12, - name: 'data' - }, - body2: { - id: 4, - name: 'data', - type: 10 - }, -}; - -// Encode URI. -const _encodeURIComponent = function (a) { - let b = window.encodeURIComponent(a); - b = b.replace(/'/g, '%27'); - return b; -} - -// Extract key from collections. -const extractKeyInfo = (collection, key) => { - for (let i = 0, result; i < collection.length; i++) { - result = utils.deepAccess(collection[i].params, key); - if (result) { - return result; - } - } - return undefined -} - -// Flattern Array. -const flatten = (arr) => { - return [].concat(...arr); -} - -const createOrtbRequest = (validBidRequests, bidderRequest) => { - let device = createOrtbDeviceObj(validBidRequests); - let user = createOrtbUserObj(validBidRequests) - let site = createOrtbSiteObj(validBidRequests, bidderRequest.refererInfo.referer) - return { - id: bidderRequest.auctionId, - imp: [], - site, - device, - user, - }; -} - -const createOrtbDeviceObj = (validBidRequests) => { - let device = { ...extractKeyInfo(validBidRequests, `device`) }; - device.ua = navigator.userAgent; - return device; -} - -const createOrtbUserObj = (validBidRequests) => ({ ...extractKeyInfo(validBidRequests, `user`) }) - -const createOrtbSiteObj = (validBidRequests, page) => { - let site = { ...extractKeyInfo(validBidRequests, `site`), page }; - let publisher = createOrtbPublisherObj(validBidRequests); - if (publisher) { - site.publisher = publisher - } - return site -} - -const createOrtbPublisherObj = (validBidRequests) => ({ ...extractKeyInfo(validBidRequests, `publisher`) }) - -const createOrtbImpObj = (bid) => { - let params = bid.params - let testMode = !!bid.params.test_mode - - // Validate Banner Request. - let bannerObj = utils.deepAccess(bid.mediaTypes, `banner`); - let nativeObj = utils.deepAccess(bid.mediaTypes, `native`); - let videoObj = utils.deepAccess(bid.mediaTypes, `video`); - - let imp = { - id: bid.bidId, - bidfloor: params.bidfloor ? params.bidfloor : 0, - ext: { - dailyhunt: { - placement_id: params.placement_id, - publisher_id: params.publisher_id, - partner: params.partner_name - } - } - }; - - // Test Mode Campaign. - if (testMode) { - imp.ext.test_mode = testMode; - } - - if (bannerObj) { - imp.banner = { - ...createOrtbImpBannerObj(bid, bannerObj) - } - } else if (nativeObj) { - imp.native = { - ...createOrtbImpNativeObj(bid, nativeObj) - } - } else if (videoObj) { - imp.video = { - ...createOrtbImpVideoObj(bid, videoObj) - } - } - return imp; -} - -const createOrtbImpBannerObj = (bid, bannerObj) => { - let format = []; - bannerObj.sizes.forEach(size => format.push({ w: size[0], h: size[1] })) - - return { - id: 'banner-' + bid.bidId, - format - } -} - -const createOrtbImpNativeObj = (bid, nativeObj) => { - const assets = utils._map(bid.nativeParams, (bidParams, key) => { - const props = ORTB_NATIVE_PARAMS[key]; - const asset = { - required: bidParams.required & 1, - }; - if (props) { - let h = 0; - let w = 0; - - asset.id = props.id; - - if (bidParams.sizes) { - const sizes = flatten(bidParams.sizes); - w = sizes[0]; - h = sizes[1]; - } - - asset[props.name] = { - len: bidParams.len ? bidParams.len : 20, - type: props.type, - w, - h - }; - - return asset; - } - }).filter(Boolean); - let request = { - assets, - ver: '1,0' - } - return { request: JSON.stringify(request) }; -} - -const createOrtbImpVideoObj = (bid, videoObj) => { - let obj = {}; - let params = bid.params - if (!utils.isEmpty(bid.params.video)) { - obj = { - ...params.video, - } - } else { - obj = { - mimes: ['video/mp4'], - }; - } - obj.ext = { - ...videoObj, - } - return obj; -} - -const createServerRequest = (ortbRequest, validBidRequests, isTestMode = 'false') => ({ - method: 'POST', - url: isTestMode === 'true' ? PROD_PREBID_TEST_ENDPOINT_URL + validBidRequests[0].params.partner_name : PROD_PREBID_ENDPOINT_URL + validBidRequests[0].params.partner_name, - data: JSON.stringify(ortbRequest), - options: { - contentType: 'application/json', - withCredentials: true - }, - bids: validBidRequests -}) - -const createPrebidBannerBid = (bid, bidResponse) => ({ - requestId: bid.bidId, - cpm: bidResponse.price.toFixed(2), - creativeId: bidResponse.crid, - width: bidResponse.w, - height: bidResponse.h, - ttl: 360, - netRevenue: bid.netRevenue === 'net', - currency: 'USD', - ad: bidResponse.adm, - mediaType: 'banner', - winUrl: bidResponse.nurl -}) - -const createPrebidNativeBid = (bid, bidResponse) => ({ - requestId: bid.bidId, - cpm: bidResponse.price.toFixed(2), - creativeId: bidResponse.crid, - currency: 'USD', - ttl: 360, - netRevenue: bid.netRevenue === 'net', - native: parseNative(bidResponse), - mediaType: 'native', - winUrl: bidResponse.nurl, - width: bidResponse.w, - height: bidResponse.h, -}) - -const parseNative = (bid) => { - let adm = JSON.parse(bid.adm) - const { assets, link, imptrackers, jstracker } = adm.native; - const result = { - clickUrl: _encodeURIComponent(link.url), - clickTrackers: link.clicktrackers || [], - impressionTrackers: imptrackers || [], - javascriptTrackers: jstracker ? [ jstracker ] : [] - }; - assets.forEach(asset => { - if (!utils.isEmpty(asset.title)) { - result.title = asset.title.text - } else if (!utils.isEmpty(asset.img)) { - result[ORTB_NATIVE_TYPE_MAPPING.img[asset.img.type]] = { - url: asset.img.url, - height: asset.img.h, - width: asset.img.w - } - } else if (!utils.isEmpty(asset.data)) { - result[ORTB_NATIVE_TYPE_MAPPING.data[asset.data.type]] = asset.data.value - } - }); - - return result; -} - -const createPrebidVideoBid = (bid, bidResponse) => { - let videoBid = { - requestId: bid.bidId, - cpm: bidResponse.price.toFixed(2), - creativeId: bidResponse.crid, - width: bidResponse.w, - height: bidResponse.h, - ttl: 360, - netRevenue: bid.netRevenue === 'net', - currency: 'USD', - mediaType: 'video', - winUrl: bidResponse.nurl, - }; - - let videoContext = bid.mediaTypes.video.context; - switch (videoContext) { - case OUTSTREAM: - videoBid.vastXml = bidResponse.adm; - break; - case INSTREAM: - videoBid.videoCacheKey = bidResponse.ext.bidder.cacheKey; - videoBid.vastUrl = bidResponse.ext.bidder.vastUrl; - break; - } - return videoBid; -} - -const getQueryVariable = (variable) => { - let query = window.location.search.substring(1); - let vars = query.split('&'); - for (var i = 0; i < vars.length; i++) { - let pair = vars[i].split('='); - if (decodeURIComponent(pair[0]) == variable) { - return decodeURIComponent(pair[1]); - } - } - return false; -} - -export const spec = { - code: BIDDER_CODE, - - aliases: [BIDDER_ALIAS], - - supportedMediaTypes: SUPPORTED_MEDIA_TYPES, - - isBidRequestValid: bid => !!bid.params.placement_id && !!bid.params.publisher_id && !!bid.params.partner_name, - - buildRequests: function (validBidRequests, bidderRequest) { - let serverRequests = []; - - // ORTB Request. - let ortbReq = createOrtbRequest(validBidRequests, bidderRequest); - - validBidRequests.forEach((bid) => { - let imp = createOrtbImpObj(bid) - ortbReq.imp.push(imp); - }); - - serverRequests.push({ ...createServerRequest(ortbReq, validBidRequests, getQueryVariable('dh_test')) }); - - return serverRequests; - }, - - interpretResponse: function (serverResponse, request) { - const { seatbid } = serverResponse.body; - let bids = request.bids; - let prebidResponse = []; - - let seatBids = seatbid[0].bid; - - seatBids.forEach(ortbResponseBid => { - let bidId = ortbResponseBid.impid; - let actualBid = find(bids, (bid) => bid.bidId === bidId); - let bidMediaType = ortbResponseBid.ext.prebid.type - switch (bidMediaType) { - case mediaTypes.BANNER: - prebidResponse.push(createPrebidBannerBid(actualBid, ortbResponseBid)); - break; - case mediaTypes.NATIVE: - prebidResponse.push(createPrebidNativeBid(actualBid, ortbResponseBid)); - break; - case mediaTypes.VIDEO: - prebidResponse.push(createPrebidVideoBid(actualBid, ortbResponseBid)); - break; - } - }) - return prebidResponse; - }, - - onBidWon: function(bid) { - ajax(bid.winUrl, null, null, { - method: 'GET' - }) - } -} - -registerBidder(spec); diff --git a/modules/dailyhuntBidAdapter.md b/modules/dailyhuntBidAdapter.md deleted file mode 100644 index acfd20a4de0..00000000000 --- a/modules/dailyhuntBidAdapter.md +++ /dev/null @@ -1,101 +0,0 @@ -# Overview - -``` -Module Name: Dailyhunt Bid Adapter -Module Type: Bidder Adapter -Maintainer: Dailyhunt -``` - -# Description - -Connects to dailyhunt for bids. - -Dailyhunt bid adapter supports Banner, Native and Video. - -# Test Parameters -``` - var adUnits = [ - { - code: '/83414793/prebid_test_display', - sizes: [[300, 250], [320, 50]], - mediaTypes: { - banner : { - sizes: [[300, 250], [320, 50]], - } - }, - bids: [ - { - bidder: 'dailyhunt', - params: { - placement_id: 1, - publisher_id: 1, - partner_name: 'dailyhunt', - device: { - ip: "182.23.143.212" - } - } - } - ] - }, - { - code: '/83414793/prebid_test_native', - sizes: [[300, 250]], - mediaTypes: { - native: { - title: { - required: true - }, - body: { - required: true - }, - image: { - required: true - }, - cta: { - required: true - } - } - }, - bids: [ - { - bidder: 'dailyhunt', - params: { - placement_id: 1, - publisher_id: 1, - partner_name: 'dailyhunt', - device: { - ip: "182.23.143.212" - } - } - } - ] - }, - { - code: '/83414793/prebid_test_video', - mediaTypes: { - video: { - playerSize: [1280, 720], - context: 'instream' - } - }, - bids: [ - { - bidder: 'dailyhunt', - params: { - placement_id: 1, - publisher_id: 1, - partner_name: 'dailyhunt', - device: { - ip: "182.23.143.212" - }, - video: { - mimes: [ - 'video/mp4' - ] - } - } - } - ] - } - ]; -``` diff --git a/modules/danmarketBidAdapter.md b/modules/danmarketBidAdapter.md deleted file mode 100644 index 8ddc83d2cf6..00000000000 --- a/modules/danmarketBidAdapter.md +++ /dev/null @@ -1,40 +0,0 @@ -# Overview - -Module Name: Dentsu Aegis Network Marketplace Bidder Adapter -Module Type: Bidder Adapter -Maintainer: niels@baarsma.net - -# Description - -Module that connects to DAN Marketplace demand source to fetch bids. - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - sizes: [[300, 250]], - bids: [ - { - bidder: "danmarket", - params: { - uid: '4', - priceType: 'gross' // by default is 'net' - } - } - ] - },{ - code: 'test-div', - sizes: [[728, 90]], - bids: [ - { - bidder: "danmarket", - params: { - uid: 5, - priceType: 'gross' - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/datablocksAnalyticsAdapter.js b/modules/datablocksAnalyticsAdapter.js deleted file mode 100644 index 5e977155284..00000000000 --- a/modules/datablocksAnalyticsAdapter.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Analytics Adapter for Datablocks - */ - -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; - -var datablocksAdapter = adapter({ - global: 'datablocksAnalytics', - handler: 'on', - analyticsType: 'bundle' -}); - -adapterManager.registerAnalyticsAdapter({ - adapter: datablocksAdapter, - code: 'datablocks' -}); - -export default datablocksAdapter; diff --git a/modules/datablocksAnalyticsAdapter.md b/modules/datablocksAnalyticsAdapter.md deleted file mode 100644 index 07f65da6e2c..00000000000 --- a/modules/datablocksAnalyticsAdapter.md +++ /dev/null @@ -1,23 +0,0 @@ -# Overview - -Module Name: Datablocks Analytics Adapter -Module Type: Datablocks Adapter -Maintainer: support@datablocks.net - -# Description - -Analytics adapter for Datablocks.net. Contact support@datablocks.net for information. - -# Test Parameters - -``` -{ - provider: 'datablocks', - options: { - publisherId: 12345, - sourceId: 12356, - host: 'prebid.datablocks.net' - - } -} -``` \ No newline at end of file diff --git a/modules/datablocksBidAdapter.js b/modules/datablocksBidAdapter.js deleted file mode 100644 index b00a3eae659..00000000000 --- a/modules/datablocksBidAdapter.js +++ /dev/null @@ -1,330 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -const NATIVE_MAP = { - 'body': 2, - 'body2': 10, - 'price': 6, - 'displayUrl': 11, - 'cta': 12 -}; -const NATIVE_IMAGE = [{ - id: 1, - required: 1, - title: { - len: 140 - } -}, { - id: 2, - required: 1, - img: { type: 3 } -}, { - id: 3, - required: 1, - data: { - type: 11 - } -}, { - id: 4, - required: 0, - data: { - type: 2 - } -}, { - id: 5, - required: 0, - img: { type: 1 } -}, { - id: 6, - required: 0, - data: { - type: 12 - } -}]; - -const VIDEO_PARAMS = ['mimes', 'minduration', 'maxduration', 'protocols', 'w', 'h', 'startdelay', - 'placement', 'linearity', 'skip', 'skipmin', 'skipafter', 'sequence', 'battr', 'maxextended', - 'minbitrate', 'maxbitrate', 'boxingallowed', 'playbackmethod', 'playbackend', 'delivery', - 'pos', 'companionad', 'api', 'companiontype', 'ext']; - -export const spec = { - supportedMediaTypes: [BANNER, NATIVE, VIDEO], - code: 'datablocks', - isBidRequestValid: function(bid) { - return !!(bid.params.host && bid.params.sourceId && - bid.mediaTypes && (bid.mediaTypes.banner || bid.mediaTypes.native || bid.mediaTypes.video)); - }, - buildRequests: function(validBidRequests, bidderRequest) { - if (!validBidRequests.length) { return []; } - - let imps = {}; - let site = {}; - let device = {}; - let refurl = utils.parseUrl(bidderRequest.referrer); - let requests = []; - - validBidRequests.forEach(bidRequest => { - let imp = { - id: bidRequest.bidId, - tagid: bidRequest.adUnitCode, - secure: window.location.protocol == 'https:' - } - - if (utils.deepAccess(bidRequest, `mediaTypes.banner`)) { - let sizes = bidRequest.mediaTypes.banner.sizes; - if (sizes.length == 1) { - imp.banner = { - w: sizes[0][0], - h: sizes[0][1] - } - } else if (sizes.length > 1) { - imp.banner = { - format: sizes.map(size => ({ w: size[0], h: size[1] })) - }; - } else { - return; - } - } else if (utils.deepAccess(bidRequest, 'mediaTypes.native')) { - let nativeImp = bidRequest.mediaTypes.native; - - if (nativeImp.type) { - let nativeAssets = []; - switch (nativeImp.type) { - case 'image': - nativeAssets = NATIVE_IMAGE; - break; - default: - return; - } - imp.native = JSON.stringify({ assets: nativeAssets }); - } else { - let nativeAssets = []; - let nativeKeys = Object.keys(nativeImp); - nativeKeys.forEach((nativeKey, index) => { - let required = !!nativeImp[nativeKey].required; - let assetId = index + 1; - switch (nativeKey) { - case 'title': - nativeAssets.push({ - id: assetId, - required: required, - title: { - len: nativeImp[nativeKey].len || 140 - } - }); - break; - case 'body': // desc - case 'body2': // desc2 - case 'price': - case 'display_url': - let data = { - id: assetId, - required: required, - data: { - type: NATIVE_MAP[nativeKey] - } - } - if (nativeImp[nativeKey].data && nativeImp[nativeKey].data.len) { data.data.len = nativeImp[nativeKey].data.len; } - - nativeAssets.push(data); - break; - case 'image': - if (nativeImp[nativeKey].sizes && nativeImp[nativeKey].sizes.length) { - nativeAssets.push({ - id: assetId, - required: required, - image: { - type: 3, - w: nativeImp[nativeKey].sizes[0], - h: nativeImp[nativeKey].sizes[1] - } - }) - } - } - }); - imp.native = { - request: JSON.stringify({native: {assets: nativeAssets}}) - }; - } - } else if (utils.deepAccess(bidRequest, 'mediaTypes.video')) { - let video = bidRequest.mediaTypes.video; - let sizes = video.playerSize || bidRequest.sizes || []; - if (sizes.length && Array.isArray(sizes[0])) { - imp.video = { - w: sizes[0][0], - h: sizes[0][1] - }; - } else if (sizes.length == 2 && !Array.isArray(sizes[0])) { - imp.video = { - w: sizes[0], - h: sizes[1] - }; - } else { - return; - } - - if (video.durationRangeSec) { - if (Array.isArray(video.durationRangeSec)) { - if (video.durationRangeSec.length == 1) { - imp.video.maxduration = video.durationRangeSec[0]; - } else if (video.durationRangeSec.length == 2) { - imp.video.minduration = video.durationRangeSec[0]; - imp.video.maxduration = video.durationRangeSec[1]; - } - } else { - imp.video.maxduration = video.durationRangeSec; - } - } - - if (bidRequest.params.video) { - Object.keys(bidRequest.params.video).forEach(k => { - if (VIDEO_PARAMS.indexOf(k) > -1) { - imp.video[k] = bidRequest.params.video[k]; - } - }) - } - } - let host = bidRequest.params.host; - let sourceId = bidRequest.params.sourceId; - imps[host] = imps[host] || {}; - let hostImp = imps[host][sourceId] = imps[host][sourceId] || { imps: [] }; - hostImp.imps.push(imp); - hostImp.subid = hostImp.imps.subid || bidRequest.params.subid || 'blank'; - hostImp.path = 'search'; - hostImp.idParam = 'sid'; - hostImp.protocol = '//'; - }); - - // Generate Site obj - site.domain = refurl.hostname; - site.page = refurl.protocol + '://' + refurl.hostname + refurl.pathname; - if (self === top && document.referrer) { - site.ref = document.referrer; - } - let keywords = document.getElementsByTagName('meta')['keywords']; - if (keywords && keywords.content) { - site.keywords = keywords.content; - } - - // Generate Device obj. - device.ip = 'peer'; - device.ua = window.navigator.userAgent; - device.js = 1; - device.language = ((navigator.language || navigator.userLanguage || '').split('-'))[0] || 'en'; - - RtbRequest(device, site, imps).forEach(formatted => { - requests.push({ - method: 'POST', - url: formatted.url, - data: formatted.body, - options: { - withCredentials: false - } - }) - }); - return requests; - - function RtbRequest(device, site, imps) { - let collection = []; - Object.keys(imps).forEach(host => { - let sourceIds = imps[host]; - Object.keys(sourceIds).forEach(sourceId => { - let impObj = sourceIds[sourceId]; - collection.push({ - url: `https://${host}/${impObj.path}/?${impObj.idParam}=${sourceId}`, - body: { - id: bidderRequest.auctionId, - imp: impObj.imps, - site: Object.assign({ id: impObj.subid || 'blank' }, site), - device: Object.assign({}, device) - } - }) - }) - }) - - return collection; - } - }, - interpretResponse: function(serverResponse, bidRequest) { - if (!serverResponse || !serverResponse.body || !serverResponse.body.seatbid) { - return []; - } - let body = serverResponse.body; - - let bids = body.seatbid - .map(seatbid => seatbid.bid) - .reduce((memo, bid) => memo.concat(bid), []); - let req = bidRequest.data; - let reqImps = req.imp; - - return bids.map(rtbBid => { - let imp; - for (let i in reqImps) { - let testImp = reqImps[i] - if (testImp.id == rtbBid.impid) { - imp = testImp; - break; - } - } - let br = { - requestId: rtbBid.impid, - cpm: rtbBid.price, - creativeId: rtbBid.crid, - currency: rtbBid.currency || 'USD', - netRevenue: true, - ttl: 360 - }; - if (!imp) { - return br; - } else if (imp.banner) { - br.mediaType = BANNER; - br.width = rtbBid.w; - br.height = rtbBid.h; - br.ad = rtbBid.adm; - } else if (imp.native) { - br.mediaType = NATIVE; - - let reverseNativeMap = {}; - let nativeKeys = Object.keys(NATIVE_MAP); - nativeKeys.forEach(k => { - reverseNativeMap[NATIVE_MAP[k]] = k; - }); - - let idMap = {}; - let nativeReq = JSON.parse(imp.native.request); - if (nativeReq.native && nativeReq.native.assets) { - nativeReq.native.assets.forEach(asset => { - if (asset.data) { idMap[asset.id] = reverseNativeMap[asset.data.type]; } - }) - } - - const nativeResponse = JSON.parse(rtbBid.adm); - const { assets, link, imptrackers, jstrackers } = nativeResponse.native; - const result = { - clickUrl: link.url, - clickTrackers: link.clicktrackers || undefined, - impressionTrackers: imptrackers || undefined, - javascriptTrackers: jstrackers ? [jstrackers] : undefined - }; - assets.forEach(asset => { - if (asset.title) { - result.title = asset.title.text; - } else if (asset.img) { - result.image = asset.img.url; - } else if (idMap[asset.id]) { - result[idMap[asset.id]] = asset.data.value; - } - }) - br.native = result; - } else if (imp.video) { - br.mediaType = VIDEO; - br.width = rtbBid.w; - br.height = rtbBid.h; - if (rtbBid.adm) { br.vastXml = rtbBid.adm; } else if (rtbBid.nurl) { br.vastUrl = rtbBid.nurl; } - } - return br; - }); - } - -}; -registerBidder(spec); diff --git a/modules/datablocksBidAdapter.md b/modules/datablocksBidAdapter.md deleted file mode 100644 index e30cd361974..00000000000 --- a/modules/datablocksBidAdapter.md +++ /dev/null @@ -1,73 +0,0 @@ -# Overview - -``` -Module Name: Datablocks Bidder Adapter -Module Type: Bidder Adapter -Maintainer: support@datablocks.net -``` - -# Description - -Connects to Datablocks Version 5 Platform -Banner Native and Video - - -# Test Parameters -``` - var adUnits = [ - { - code: 'banner-div', - sizes: [[300, 250]], - mediaTypes:{ - banner: { - sizes: [300,250] - } - }, - bids: [ - { - bidder: 'datablocks', - params: { - sourceId: 12345, - host: 'prebid.datablocks.net' - } - } - ] - }, { - code: 'native-div', - mediaTypes : { - native: { - title:{required:true}, - body:{required:true} - } - }, - bids: [ - { - bidder: 'datablocks', - params: { - sourceId: 12345, - host: 'prebid.datablocks.net' - } - }, { - code: 'video-div', - mediaTypes : { - video: { - playerSize:[500,400], - durationRangeSec:[15,30], - context: "linear" - } - }, - bids: [ - { - bidder: 'datablocks', - params: { - sourceId: 12345, - host: 'prebid.datablocks.net', - video: { - mimes:["video/flv"] - } - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/decenteradsBidAdapter.js b/modules/decenteradsBidAdapter.js deleted file mode 100644 index 823a59a3768..00000000000 --- a/modules/decenteradsBidAdapter.js +++ /dev/null @@ -1,90 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js' -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js' -import * as utils from '../src/utils.js' - -const BIDDER_CODE = 'decenterads' -const URL = 'https://supply.decenterads.com/?c=o&m=multi' -const URL_SYNC = 'https://supply.decenterads.com/?c=o&m=cookie' - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO, NATIVE], - - isBidRequestValid: function (opts) { - return Boolean(opts.bidId && opts.params && !isNaN(opts.params.placementId)) - }, - - buildRequests: function (validBidRequests) { - validBidRequests = validBidRequests || [] - let winTop = window - try { - window.top.location.toString() - winTop = window.top - } catch (e) { utils.logMessage(e) } - - const location = utils.getWindowLocation() - const placements = [] - - for (let i = 0; i < validBidRequests.length; i++) { - const p = validBidRequests[i] - - placements.push({ - placementId: p.params.placementId, - bidId: p.bidId, - traffic: p.params.traffic || BANNER - }) - } - - return { - method: 'POST', - url: URL, - data: { - deviceWidth: winTop.screen.width, - deviceHeight: winTop.screen.height, - language: (navigator && navigator.language) ? navigator.language : '', - secure: +(location.protocol === 'https:'), - host: location.hostname, - page: location.pathname, - placements: placements - } - } - }, - - interpretResponse: function (opts) { - const body = opts.body - const response = [] - - for (let i = 0; i < body.length; i++) { - const item = body[i] - if (isBidResponseValid(item)) { - delete item.mediaType - response.push(item) - } - } - - return response - }, - - getUserSyncs: function (syncOptions, serverResponses) { - return [{ type: 'image', url: URL_SYNC }] - } -} - -registerBidder(spec) - -function isBidResponseValid (bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency) { - return false - } - switch (bid['mediaType']) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad) - case VIDEO: - return Boolean(bid.vastUrl) - case NATIVE: - return Boolean(bid.title && bid.image && bid.impressionTrackers) - default: - return false - } -} diff --git a/modules/decenteradsBidAdapter.md b/modules/decenteradsBidAdapter.md deleted file mode 100644 index 04260a9da58..00000000000 --- a/modules/decenteradsBidAdapter.md +++ /dev/null @@ -1,27 +0,0 @@ -# Overview - -``` -Module Name: DecenterAds Bidder Adapter -Module Type: Bidder Adapter -Maintainer: publishers@decenterads.com -``` - -# Description - -Module that connects to DecenterAds' demand sources - -# Test Parameters -``` - var adUnits = [{ - code: 'placementId_0', - sizes: [[300, 250]], - bids: [{ - bidder: 'decenterads', - params: { - placementId: 0, - traffic: 'banner' - } - }] - } - ]; -``` diff --git a/modules/deepintentBidAdapter.js b/modules/deepintentBidAdapter.js deleted file mode 100644 index a6a6cac6570..00000000000 --- a/modules/deepintentBidAdapter.js +++ /dev/null @@ -1,193 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; -const BIDDER_CODE = 'deepintent'; -const BIDDER_ENDPOINT = 'https://prebid.deepintent.com/prebid'; -const USER_SYNC_URL = 'https://cdn.deepintent.com/syncpixel.html'; -const DI_M_V = '1.0.0'; -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - aliases: [], - - // tagId is mandatory param - isBidRequestValid: bid => { - let valid = false; - if (bid && bid.params && bid.params.tagId) { - if (typeof bid.params.tagId === 'string' || bid.params.tagId instanceof String) { - valid = true; - } - } - return valid; - }, - interpretResponse: function(bidResponse, request) { - let responses = []; - if (bidResponse && bidResponse.body) { - let bids = bidResponse.body.seatbid && bidResponse.body.seatbid[0] ? bidResponse.body.seatbid[0].bid : []; - responses = bids.map(bid => formatResponse(bid)) - } - return responses; - }, - buildRequests: function (validBidRequests, bidderRequest) { - var user = validBidRequests.map(bid => buildUser(bid)); - clean(user); - const openRtbBidRequest = { - id: utils.generateUUID(), - at: 1, - imp: validBidRequests.map(bid => buildImpression(bid)), - site: buildSite(bidderRequest), - device: buildDevice(), - user: user && user.length === 1 ? user[0] : {} - }; - - if (bidderRequest && bidderRequest.uspConsent) { - utils.deepSetValue(openRtbBidRequest, 'regs.ext.us_privacy', bidderRequest.uspConsent); - } - - if (bidderRequest && bidderRequest.gdprConsent) { - utils.deepSetValue(openRtbBidRequest, 'user.ext.consent', bidderRequest.gdprConsent.consentString); - utils.deepSetValue(openRtbBidRequest, 'regs.ext.gdpr', (bidderRequest.gdprConsent.gdprApplies ? 1 : 0)); - } - - injectEids(openRtbBidRequest, validBidRequests); - - return { - method: 'POST', - url: BIDDER_ENDPOINT, - data: JSON.stringify(openRtbBidRequest), - options: { - contentType: 'application/json' - } - }; - }, - /** - * Register User Sync. - */ - getUserSyncs: syncOptions => { - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: USER_SYNC_URL - }]; - } - } - -}; -function clean(obj) { - for (let propName in obj) { - if (obj[propName] === null || obj[propName] === undefined) { - delete obj[propName]; - } - } -} - -function formatResponse(bid) { - return { - requestId: bid && bid.impid ? bid.impid : undefined, - cpm: bid && bid.price ? bid.price : 0.0, - width: bid && bid.w ? bid.w : 0, - height: bid && bid.h ? bid.h : 0, - ad: bid && bid.adm ? bid.adm : '', - meta: { - advertiserDomains: bid && bid.adomain ? bid.adomain : [] - }, - creativeId: bid && bid.crid ? bid.crid : undefined, - netRevenue: false, - currency: bid && bid.cur ? bid.cur : 'USD', - ttl: 300, - dealId: bid && bid.dealId ? bid.dealId : undefined - } -} - -function buildImpression(bid) { - return { - id: bid.bidId, - tagid: bid.params.tagId || '', - secure: window.location.protocol === 'https' ? 1 : 0, - banner: buildBanner(bid), - displaymanager: 'di_prebid', - displaymanagerver: DI_M_V, - ext: buildCustomParams(bid) - }; -} -function buildCustomParams(bid) { - if (bid.params && bid.params.custom) { - return { - deepintent: bid.params.custom - - } - } else { - return {} - } -} -function buildUser(bid) { - if (bid && bid.params && bid.params.user) { - return { - id: bid.params.user.id && typeof bid.params.user.id == 'string' ? bid.params.user.id : undefined, - buyeruid: bid.params.user.buyeruid && typeof bid.params.user.buyeruid == 'string' ? bid.params.user.buyeruid : undefined, - yob: bid.params.user.yob && typeof bid.params.user.yob == 'number' ? bid.params.user.yob : null, - gender: bid.params.user.gender && typeof bid.params.user.gender == 'string' ? bid.params.user.gender : undefined, - keywords: bid.params.user.keywords && typeof bid.params.user.keywords == 'string' ? bid.params.user.keywords : undefined, - customdata: bid.params.user.customdata && typeof bid.params.user.customdata == 'string' ? bid.params.user.customdata : undefined - } - } -} - -function injectEids(openRtbBidRequest, validBidRequests) { - const bidUserIdAsEids = utils.deepAccess(validBidRequests, '0.userIdAsEids'); - if (utils.isArray(bidUserIdAsEids) && bidUserIdAsEids.length > 0) { - utils.deepSetValue(openRtbBidRequest, 'user.eids', bidUserIdAsEids); - } -} - -function buildBanner(bid) { - if (utils.deepAccess(bid, 'mediaTypes.banner')) { - // Get Sizes from MediaTypes Object, Will always take first size, will be overrided by params for exact w,h - if (utils.deepAccess(bid, 'mediaTypes.banner.sizes') && !bid.params.height && !bid.params.width) { - let sizes = utils.deepAccess(bid, 'mediaTypes.banner.sizes'); - if (utils.isArray(sizes) && sizes.length > 0) { - return { - h: sizes[0][1], - w: sizes[0][0], - pos: bid && bid.params && bid.params.pos ? bid.params.pos : 0 - } - } - } else { - return { - h: bid.params.height, - w: bid.params.width, - pos: bid && bid.params && bid.params.pos ? bid.params.pos : 0 - } - } - } -} - -function buildSite(bidderRequest) { - let site = {}; - if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { - site.page = bidderRequest.refererInfo.referer; - site.domain = getDomain(bidderRequest.refererInfo.referer); - } - return site; -} - -function getDomain(referer) { - if (referer) { - let domainA = document.createElement('a'); - domainA.href = referer; - return domainA.hostname; - } -} - -function buildDevice() { - return { - ua: navigator.userAgent, - js: 1, - dnt: (navigator.doNotTrack == 'yes' || navigator.doNotTrack === '1') ? 1 : 0, - h: screen.height, - w: screen.width, - language: navigator.language - } -} - -registerBidder(spec); diff --git a/modules/deepintentBidAdapter.md b/modules/deepintentBidAdapter.md deleted file mode 100644 index 79a6a1679e2..00000000000 --- a/modules/deepintentBidAdapter.md +++ /dev/null @@ -1,54 +0,0 @@ -# Overview - -``` -Module Name: Deepintent Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid@deepintent.com -``` - -# Description - -Deepintent currently supports the BANNER type ads through prebid js - -Module that connects to Deepintent's demand sources. - -# Banner Test Request -``` - var adUnits = [ - { - code: 'di_adUnit1', - mediaTypes: { - banner: { - sizes: [[300, 250]], // a display size, only first one will be picked up since multiple ad sizes are not supported yet - } - } - bids: [ - { - bidder: 'deepintent', - params: { - tagId: '1300', // Required parameter - w: 300, // Width and Height here will override sizes in mediatype - h: 250, - pos: 1, - custom: { // Custom parameters in form of key value pairs - user_min_age: 18 - } - } - } - ] - } - ]; -``` - -###Recommended User Sync Configuration - -```javascript -pbjs.setConfig({ - userSync: { - iframeEnabled: true, - enabledBidders: ['deepintent'], - syncDelay: 3000 - }}); - - -``` diff --git a/modules/deepintentDpesIdSystem.js b/modules/deepintentDpesIdSystem.js deleted file mode 100644 index 375c8c07ed1..00000000000 --- a/modules/deepintentDpesIdSystem.js +++ /dev/null @@ -1,45 +0,0 @@ -/** - * This module adds DPES to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/deepintentDpesSystem - * @requires module:modules/userId - */ - -import { submodule } from '../src/hook.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const MODULE_NAME = 'deepintentId'; -export const storage = getStorageManager(null, MODULE_NAME); - -/** @type {Submodule} */ -export const deepintentDpesSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: MODULE_NAME, - /** - * decode the stored id value for passing to bid requests - * @function - * @param {{value:string}} value - * @returns {{deepintentId:Object}} - */ - decode(value, config) { - return value ? { 'deepintentId': value } : undefined; - }, - - /** - * performs action to obtain id and return a value in the callback's response argument - * @function - * @param {SubmoduleConfig} config - * @param {ConsentData|undefined} consentData - * @param {Object} cacheIdObj - existing id, if any - * @return {{id: string | undefined} | undefined} - */ - getId(config, consentData, cacheIdObj) { - return cacheIdObj; - } - -}; - -submodule('userId', deepintentDpesSubmodule); diff --git a/modules/deepintentDpesIdSystem.md b/modules/deepintentDpesIdSystem.md deleted file mode 100644 index 2af0fe7446e..00000000000 --- a/modules/deepintentDpesIdSystem.md +++ /dev/null @@ -1,43 +0,0 @@ -# Deepintent DPES ID - -The Deepintent Id is a shared, healthcare identifier which helps publisher in absence of the 3rd Party cookie matching. This lets publishers set and bid with healthcare identity . Deepintent lets users protect their privacy through advertising value chain, where Healthcare identity when setting the identity takes in consideration of users choices, as well as when passing identity on the cookie itself privacy consent strings are checked. The healthcare identity when set is not stored on Deepintent's servers but is stored on users browsers itself. User can still opt out of the ads by https://option.deepintent.com/adchoices. - -## Deepintent DPES ID Registration - -The Deepintent DPES ID is free to use, but requires a simple registration with Deepintent. Please reach to prebid@deepintent.com to get started. -Once publisher registers with deepintents platform for healthcare identity Deepintent provides the Tag code to be placed on the page, this tag code works to capture and store information as per publishers and users agreement. DPES User ID module uses this stored id and passes it on the deepintent prebid adapter. - - -## Deepintent DPES ID Configuration - -First, make sure to add the Deepintent submodule to your Prebid.js package with: - -``` -gulp build --modules=deepintentDpesIdSystem,userId -``` - -The following configuration parameters are available: - -```javascript -pbjs.setConfig({ - userSync: { - userIds: [{ - name: 'deepintentId', - storage: { - type: 'cookie', - name: '_dpes_id', - expires: 90 // storage lasts for 90 days, optional if storage type is html5 - } - }], - auctionDelay: 50 // 50ms maximum auction delay, applies to all userId modules - } -}); -``` - -| Param under userSync.userIds[] | Scope | Type | Description | Example | -| --- | --- | --- | --- | --- | -| name | Required | String | The name of this module: `"deepintentId"` | `"deepintentId"` | -| storage | Required | Object | Storage settings for how the User Id module will cache the Deepintent ID locally | | -| storage.type | Required | String | This is where the results of the user ID will be stored. Deepintent`"html5"` or `"cookie"`. | `"html5"` | -| storage.name | Required | String | The name of the local storage where the user ID will be stored. | `"_dpes_id"` | -| storage.expires | Optional | Integer | How long (in days) the user ID information will be stored. Deepintent recommends `90`. | `90` | \ No newline at end of file diff --git a/modules/dfpAdServerVideo.js b/modules/dfpAdServerVideo.js deleted file mode 100644 index 22c904b604c..00000000000 --- a/modules/dfpAdServerVideo.js +++ /dev/null @@ -1,293 +0,0 @@ -/** - * This module adds [DFP support]{@link https://www.doubleclickbygoogle.com/} for Video to Prebid. - */ - -import { registerVideoSupport } from '../src/adServerManager.js'; -import { targeting } from '../src/targeting.js'; -import { deepAccess, isEmpty, logError, parseSizesInput, formatQS, parseUrl, buildUrl } from '../src/utils.js'; -import { config } from '../src/config.js'; -import { getHook, submodule } from '../src/hook.js'; -import { auctionManager } from '../src/auctionManager.js'; -import { gdprDataHandler, uspDataHandler } from '../src/adapterManager.js'; -import events from '../src/events.js'; -import CONSTANTS from '../src/constants.json'; - -/** - * @typedef {Object} DfpVideoParams - * - * This object contains the params needed to form a URL which hits the - * [DFP API]{@link https://support.google.com/dfp_premium/answer/1068325?hl=en}. - * - * All params (except iu, mentioned below) should be considered optional. This module will choose reasonable - * defaults for all of the other required params. - * - * The cust_params property, if present, must be an object. It will be merged with the rest of the - * standard Prebid targeting params (hb_adid, hb_bidder, etc). - * - * @param {string} iu This param *must* be included, in order for us to create a valid request. - * @param [string] description_url This field is required if you want Ad Exchange to bid on our ad unit... - * but otherwise optional - */ - -/** - * @typedef {Object} DfpVideoOptions - * - * @param {Object} adUnit The adUnit which this bid is supposed to help fill. - * @param [Object] bid The bid which should be considered alongside the rest of the adserver's demand. - * If this isn't defined, then we'll use the winning bid for the adUnit. - * - * @param {DfpVideoParams} [params] Query params which should be set on the DFP request. - * These will override this module's defaults whenever they conflict. - * @param {string} [url] video adserver url - */ - -/** Safe defaults which work on pretty much all video calls. */ -const defaultParamConstants = { - env: 'vp', - gdfp_req: 1, - output: 'vast', - unviewed_position_start: 1, -}; - -export const adpodUtils = {}; - -/** - * Merge all the bid data and publisher-supplied options into a single URL, and then return it. - * - * @see [The DFP API]{@link https://support.google.com/dfp_premium/answer/1068325?hl=en#env} for details. - * - * @param {DfpVideoOptions} options Options which should be used to construct the URL. - * - * @return {string} A URL which calls DFP, letting options.bid - * (or the auction's winning bid for this adUnit, if undefined) compete alongside the rest of the - * demand in DFP. - */ -export function buildDfpVideoUrl(options) { - if (!options.params && !options.url) { - logError(`A params object or a url is required to use $$PREBID_GLOBAL$$.adServers.dfp.buildVideoUrl`); - return; - } - - const adUnit = options.adUnit; - const bid = options.bid || targeting.getWinningBids(adUnit.code)[0]; - - let urlComponents = {}; - - 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}); - - if (isEmpty(options.params)) { - return buildUrlFromAdserverUrlComponents(urlComponents, bid, options); - } - } - - const derivedParams = { - correlator: Date.now(), - sz: parseSizesInput(deepAccess(adUnit, 'mediaTypes.video.playerSize')).join('|'), - url: encodeURIComponent(location.href), - }; - const encodedCustomParams = getCustParams(bid, options); - - const queryParams = Object.assign({}, - defaultParamConstants, - urlComponents.search, - derivedParams, - options.params, - { cust_params: encodedCustomParams } - ); - - const descriptionUrl = getDescriptionUrl(bid, options, 'params'); - if (descriptionUrl) { queryParams.description_url = descriptionUrl; } - - const gdprConsent = gdprDataHandler.getConsentData(); - if (gdprConsent) { - if (typeof gdprConsent.gdprApplies === 'boolean') { queryParams.gdpr = Number(gdprConsent.gdprApplies); } - if (gdprConsent.consentString) { queryParams.gdpr_consent = gdprConsent.consentString; } - if (gdprConsent.addtlConsent) { queryParams.addtl_consent = gdprConsent.addtlConsent; } - } - - const uspConsent = uspDataHandler.getConsentData(); - if (uspConsent) { queryParams.us_privacy = uspConsent; } - - return buildUrl({ - protocol: 'https', - host: 'securepubads.g.doubleclick.net', - pathname: '/gampad/ads', - search: queryParams - }); -} - -export function notifyTranslationModule(fn) { - fn.call(this, 'dfp'); -} - -getHook('registerAdserver').before(notifyTranslationModule); - -/** - * @typedef {Object} DfpAdpodOptions - * - * @param {string} code Ad Unit code - * @param {Object} params Query params which should be set on the DFP request. - * These will override this module's defaults whenever they conflict. - * @param {function} callback Callback function to execute when master tag is ready - */ - -/** - * Creates master tag url for long-form - * @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} = {}) { - if (!params || !callback) { - logError(`A params object and a callback is required to use pbjs.adServers.dfp.buildAdpodVideoUrl`); - return; - } - - const derivedParams = { - correlator: Date.now(), - sz: getSizeForAdUnit(code), - url: encodeURIComponent(location.href), - }; - - function getSizeForAdUnit(code) { - let adUnit = auctionManager.getAdUnits() - .filter((adUnit) => adUnit.code === code) - let sizes = deepAccess(adUnit[0], 'mediaTypes.video.playerSize'); - return parseSizesInput(sizes).join('|'); - } - - adpodUtils.getTargeting({ - 'codes': [code], - 'callback': createMasterTag - }); - - function createMasterTag(err, targeting) { - if (err) { - callback(err, null); - return; - } - - let initialValue = { - [adpodUtils.TARGETING_KEY_PB_CAT_DUR]: undefined, - [adpodUtils.TARGETING_KEY_CACHE_ID]: undefined - } - let customParams = {}; - if (targeting[code]) { - customParams = targeting[code].reduce((acc, curValue) => { - if (Object.keys(curValue)[0] === adpodUtils.TARGETING_KEY_PB_CAT_DUR) { - acc[adpodUtils.TARGETING_KEY_PB_CAT_DUR] = (typeof acc[adpodUtils.TARGETING_KEY_PB_CAT_DUR] !== 'undefined') ? acc[adpodUtils.TARGETING_KEY_PB_CAT_DUR] + ',' + curValue[adpodUtils.TARGETING_KEY_PB_CAT_DUR] : curValue[adpodUtils.TARGETING_KEY_PB_CAT_DUR]; - } else if (Object.keys(curValue)[0] === adpodUtils.TARGETING_KEY_CACHE_ID) { - acc[adpodUtils.TARGETING_KEY_CACHE_ID] = curValue[adpodUtils.TARGETING_KEY_CACHE_ID] - } - return acc; - }, initialValue); - } - - let encodedCustomParams = encodeURIComponent(formatQS(customParams)); - - const queryParams = Object.assign({}, - defaultParamConstants, - derivedParams, - params, - { cust_params: encodedCustomParams } - ); - - const gdprConsent = gdprDataHandler.getConsentData(); - if (gdprConsent) { - if (typeof gdprConsent.gdprApplies === 'boolean') { queryParams.gdpr = Number(gdprConsent.gdprApplies); } - if (gdprConsent.consentString) { queryParams.gdpr_consent = gdprConsent.consentString; } - if (gdprConsent.addtlConsent) { queryParams.addtl_consent = gdprConsent.addtlConsent; } - } - - const uspConsent = uspDataHandler.getConsentData(); - if (uspConsent) { queryParams.us_privacy = uspConsent; } - - const masterTag = buildUrl({ - protocol: 'https', - host: 'securepubads.g.doubleclick.net', - pathname: '/gampad/ads', - search: queryParams - }); - - callback(null, masterTag); - } -} - -/** - * Builds a video url from a base dfp video url and a winning bid, appending - * Prebid-specific key-values. - * @param {Object} components base video adserver url parsed into components object - * @param {AdapterBidResponse} bid winning bid object to append parameters from - * @param {Object} options Options which should be used to construct the URL (used for custom params). - * @return {string} video url - */ -function buildUrlFromAdserverUrlComponents(components, bid, options) { - const descriptionUrl = getDescriptionUrl(bid, components, 'search'); - if (descriptionUrl) { components.search.description_url = descriptionUrl; } - - const encodedCustomParams = getCustParams(bid, options); - components.search.cust_params = (components.search.cust_params) ? components.search.cust_params + '%26' + encodedCustomParams : encodedCustomParams; - - return buildUrl(components); -} - -/** - * Returns the encoded vast url if it exists on a bid object, only if prebid-cache - * is disabled, and description_url is not already set on a given input - * @param {AdapterBidResponse} bid object to check for vast url - * @param {Object} components the object to check that description_url is NOT set on - * @param {string} prop the property of components that would contain description_url - * @return {string | undefined} The encoded vast url if it exists, or undefined - */ -function getDescriptionUrl(bid, components, prop) { - if (config.getConfig('cache.url')) { return; } - - if (!deepAccess(components, `${prop}.description_url`)) { - const vastUrl = bid && bid.vastUrl; - if (vastUrl) { return encodeURIComponent(vastUrl); } - } else { - logError(`input cannnot contain description_url`); - } -} - -/** - * Returns the encoded `cust_params` from the bid.adserverTargeting and adds the `hb_uuid`, and `hb_cache_id`. Optionally the options.params.cust_params - * @param {AdapterBidResponse} bid - * @param {Object} options this is the options passed in from the `buildDfpVideoUrl` function - * @return {Object} Encoded key value pairs for cust_params - */ -function getCustParams(bid, options) { - const adserverTargeting = (bid && bid.adserverTargeting) || {}; - - let allTargetingData = {}; - const adUnit = options && options.adUnit; - if (adUnit) { - let allTargeting = targeting.getAllTargeting(adUnit.code); - allTargetingData = (allTargeting) ? allTargeting[adUnit.code] : {}; - } - - const prebidTargetingSet = Object.assign({}, - // Why are we adding standard keys here ? Refer https://github.com/prebid/Prebid.js/issues/3664 - { hb_uuid: bid && bid.videoCacheKey }, - // hb_uuid will be deprecated and replaced by hb_cache_id - { hb_cache_id: bid && bid.videoCacheKey }, - allTargetingData, - adserverTargeting, - ); - events.emit(CONSTANTS.EVENTS.SET_TARGETING, {[adUnit.code]: prebidTargetingSet}); - - // merge the prebid + publisher targeting sets - const publisherTargetingSet = deepAccess(options, 'params.cust_params'); - const targetingSet = Object.assign({}, prebidTargetingSet, publisherTargetingSet); - return encodeURIComponent(formatQS(targetingSet)); -} - -registerVideoSupport('dfp', { - buildVideoUrl: buildDfpVideoUrl, - buildAdpodVideoUrl: buildAdpodVideoUrl, - getAdpodTargeting: (args) => adpodUtils.getTargeting(args) -}); - -submodule('adpod', adpodUtils); diff --git a/modules/dgadsBidAdapter.md b/modules/dgadsBidAdapter.md deleted file mode 100644 index b1544007a43..00000000000 --- a/modules/dgadsBidAdapter.md +++ /dev/null @@ -1,65 +0,0 @@ -# Overview - -``` -Module Name: Digital Garage Ads Platform Bidder Adapter -Module Type: Bidder Adapter -Maintainer:dgads-support@garage.co.jp -``` - -# Description - -Connect to Digital Garage Ads Platform for bids. -This adapter supports Banner and Native. - -# Test Parameters -``` - var adUnits = [ - // Banner - { - code: 'banner-div', - sizes: [[300, 250]], - bids: [{ - bidder: 'dgads', - mediaTypes: 'banner', - params: { - location_id: '1', - site_id: '1' - } - }] - }, - // Native - { - code: 'native-div', - sizes: [[300, 250]], - mediaTypes: { - native: { - title: { - required: true, - len: 25 - }, - body: { - required: true, - len: 140 - }, - sponsoredBy: { - required: true, - len: 40 - }, - image: { - required: true - }, - clickUrl: { - required: true - }, - } - }, - bids: [{ - bidder: 'dgads', - params: { - location_id: '10', - site_id: '1' - } - }] - }, - ]; -``` diff --git a/modules/districtmDMXBidAdapter.js b/modules/districtmDMXBidAdapter.js deleted file mode 100644 index ec0a0a2f2e6..00000000000 --- a/modules/districtmDMXBidAdapter.js +++ /dev/null @@ -1,434 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { config } from '../src/config.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'districtmDMX'; - -const DMXURI = 'https://dmx.districtm.io/b/v1'; - -const GVLID = 144; -const VIDEO_MAPPING = { - playback_method: { - 'auto_play_sound_on': 1, - 'auto_play_sound_off': 2, - 'click_to_play': 3, - 'mouse_over': 4, - 'viewport_sound_on': 5, - 'viewport_sound_off': 6 - } -}; -export const spec = { - code: BIDDER_CODE, - gvlid: GVLID, - aliases: ['dmx'], - supportedFormat: [BANNER, VIDEO], - supportedMediaTypes: [VIDEO, BANNER], - isBidRequestValid(bid) { - return !!(bid.params.memberid); - }, - interpretResponse(response, bidRequest) { - response = response.body || {}; - if (response.seatbid) { - if (utils.isArray(response.seatbid)) { - const { seatbid } = response; - let winners = seatbid.reduce((bid, ads) => { - let ad = ads.bid.reduce(function (oBid, nBid) { - if (oBid.price < nBid.price) { - const bid = matchRequest(nBid.impid, bidRequest); - const { width, height } = defaultSize(bid); - nBid.cpm = parseFloat(nBid.price).toFixed(2); - nBid.bidId = nBid.impid; - nBid.requestId = nBid.impid; - nBid.width = nBid.w || width; - nBid.height = nBid.h || height; - nBid.ttl = 300; - nBid.mediaType = bid.mediaTypes && bid.mediaTypes.video ? 'video' : 'banner'; - if (nBid.mediaType === 'video') { - nBid.vastXml = cleanVast(nBid.adm, nBid.nurl); - nBid.ttl = 3600; - } - if (nBid.dealid) { - nBid.dealId = nBid.dealid; - } - nBid.uuid = nBid.bidId; - nBid.ad = nBid.adm; - nBid.netRevenue = true; - nBid.creativeId = nBid.crid; - nBid.currency = 'USD'; - nBid.meta = nBid.meta || {}; - if (nBid.adomain && nBid.adomain.length > 0) { - nBid.meta.advertiserDomains = nBid.adomain; - } - return nBid; - } else { - oBid.cpm = oBid.price; - return oBid; - } - }, { price: 0 }); - if (ad.adm) { - bid.push(ad) - } - return bid; - }, []) - let winnersClean = winners.filter(w => { - if (w.bidId) { - return true; - } - return false; - }); - return winnersClean; - } else { - return []; - } - } else { - return []; - } - }, - buildRequests(bidRequest, bidderRequest) { - let timeout = config.getConfig('bidderTimeout'); - let schain = null; - let dmxRequest = { - id: utils.generateUUID(), - cur: ['USD'], - tmax: (timeout - 300), - test: this.test() || 0, - site: { - publisher: { id: String(bidRequest[0].params.memberid) || null } - } - } - - try { - let params = config.getConfig('dmx'); - dmxRequest.user = params.user || {}; - let site = params.site || {}; - dmxRequest.site = { ...dmxRequest.site, ...site } - } catch (e) { - - } - - let eids = []; - if (bidRequest[0] && bidRequest[0].userId) { - bindUserId(eids, utils.deepAccess(bidRequest[0], `userId.idl_env`), 'liveramp.com', 1); - bindUserId(eids, utils.deepAccess(bidRequest[0], `userId.id5id.uid`), 'id5-sync.com', 1); - bindUserId(eids, utils.deepAccess(bidRequest[0], `userId.pubcid`), 'pubcid.org', 1); - bindUserId(eids, utils.deepAccess(bidRequest[0], `userId.tdid`), 'adserver.org', 1); - bindUserId(eids, utils.deepAccess(bidRequest[0], `userId.criteoId`), 'criteo.com', 1); - bindUserId(eids, utils.deepAccess(bidRequest[0], `userId.britepoolid`), 'britepool.com', 1); - bindUserId(eids, utils.deepAccess(bidRequest[0], `userId.lipb.lipbid`), 'liveintent.com', 1); - bindUserId(eids, utils.deepAccess(bidRequest[0], `userId.intentiqid`), 'intentiq.com', 1); - bindUserId(eids, utils.deepAccess(bidRequest[0], `userId.lotamePanoramaId`), 'lotame.com', 1); - bindUserId(eids, utils.deepAccess(bidRequest[0], `userId.parrableId`), 'parrable.com', 1); - bindUserId(eids, utils.deepAccess(bidRequest[0], `userId.netId`), 'netid.de', 1); - bindUserId(eids, utils.deepAccess(bidRequest[0], `userId.sharedid`), 'sharedid.org', 1); - dmxRequest.user = dmxRequest.user || {}; - dmxRequest.user.ext = dmxRequest.user.ext || {}; - dmxRequest.user.ext.eids = eids; - } - if (!dmxRequest.test) { - delete dmxRequest.test; - } - if (bidderRequest.gdprConsent) { - dmxRequest.regs = {}; - dmxRequest.regs.ext = {}; - dmxRequest.regs.ext.gdpr = bidderRequest.gdprConsent.gdprApplies === true ? 1 : 0; - - if (bidderRequest.gdprConsent.gdprApplies === true) { - dmxRequest.user = {}; - dmxRequest.user.ext = {}; - dmxRequest.user.ext.consent = bidderRequest.gdprConsent.consentString; - } - } - dmxRequest.regs = dmxRequest.regs || {}; - dmxRequest.regs.coppa = config.getConfig('coppa') === true ? 1 : 0; - if (bidderRequest && bidderRequest.uspConsent) { - dmxRequest.regs = dmxRequest.regs || {}; - dmxRequest.regs.ext = dmxRequest.regs.ext || {}; - dmxRequest.regs.ext.us_privacy = bidderRequest.uspConsent; - } - try { - schain = bidRequest[0].schain; - dmxRequest.source = {}; - dmxRequest.source.ext = {}; - dmxRequest.source.ext.schain = schain || {} - } catch (e) { } - let tosendtags = bidRequest.map(dmx => { - var obj = {}; - obj.id = dmx.bidId; - obj.tagid = String(dmx.params.dmxid || dmx.adUnitCode); - obj.secure = 1; - obj.bidfloor = getFloor(dmx); - if (dmx.mediaTypes && dmx.mediaTypes.video) { - obj.video = { - topframe: 1, - skip: dmx.mediaTypes.video.skip || 0, - linearity: dmx.mediaTypes.video.linearity || 1, - minduration: dmx.mediaTypes.video.minduration || 5, - maxduration: dmx.mediaTypes.video.maxduration || 60, - playbackmethod: dmx.mediaTypes.video.playbackmethod || [2], - api: getApi(dmx.mediaTypes.video), - mimes: dmx.mediaTypes.video.mimes || ['video/mp4'], - protocols: getProtocols(dmx.mediaTypes.video), - h: dmx.mediaTypes.video.playerSize[0][1], - w: dmx.mediaTypes.video.playerSize[0][0] - }; - } else { - obj.banner = { - topframe: 1, - w: cleanSizes(dmx.sizes, 'w'), - h: cleanSizes(dmx.sizes, 'h'), - format: cleanSizes(dmx.sizes).map(s => { - return { w: s[0], h: s[1] }; - }).filter(obj => typeof obj.w === 'number' && typeof obj.h === 'number') - }; - } - return obj; - }); - - if (tosendtags.length <= 5) { - dmxRequest.imp = tosendtags; - return { - method: 'POST', - url: DMXURI, - data: JSON.stringify(dmxRequest), - bidderRequest - } - } else { - return upto5(tosendtags, dmxRequest, bidderRequest, DMXURI); - } - }, - test() { - return window.location.href.indexOf('dmTest=true') !== -1 ? 1 : 0; - }, - getUserSyncs(optionsType, serverResponses, gdprConsent, uspConsent) { - let query = []; - let url = 'https://cdn.districtm.io/ids/index.html' - if (gdprConsent && gdprConsent.gdprApplies && typeof gdprConsent.consentString === 'string') { - query.push(['gdpr', gdprConsent.consentString]) - } - if (uspConsent) { - query.push(['ccpa', uspConsent]) - } - if (query.length > 0) { - url += '?' + query.map(q => q.join('=')).join('&') - } - if (optionsType.iframeEnabled) { - return [{ - type: 'iframe', - url: url - }]; - } - } -} - -export function getFloor(bid) { - let floor = null; - if (typeof bid.getFloor === 'function') { - const floorInfo = bid.getFloor({ - currency: 'USD', - mediaType: bid.mediaTypes.video ? 'video' : 'banner', - size: bid.sizes.map(size => { - return { - w: size[0], - h: size[1] - } - }) - }); - if (typeof floorInfo === 'object' && - floorInfo.currency === 'USD' && !isNaN(parseFloat(floorInfo.floor))) { - floor = parseFloat(floorInfo.floor); - } - } - return floor !== null ? floor : bid.params.floor; -} - -export function cleanSizes(sizes, value) { - const supportedSize = [ - { - size: [300, 250], - s: 100 - }, - { - size: [728, 90], - s: 95 - }, - { - size: [320, 50], - s: 90 - }, - { - size: [160, 600], - s: 88 - }, - { - size: [300, 600], - s: 85 - }, - { - size: [300, 50], - s: 80 - }, - { - size: [970, 250], - s: 75 - }, - { - size: [970, 90], - s: 60 - }, - ]; - let newArray = shuffle(sizes, supportedSize); - switch (value) { - case 'w': - return newArray[0][0] || 0; - case 'h': - return newArray[0][1] || 0; - case 'size': - return newArray; - default: - return newArray; - } -} - -export function shuffle(sizes, list) { - let removeSizes = sizes.filter(size => { - return list.map(l => `${l.size[0]}x${l.size[1]}`).indexOf(`${size[0]}x${size[1]}`) === -1 - }) - let reOrder = sizes.reduce((results, current) => { - if (results.length === 0) { - results.push(current); - return results; - } - results.push(current); - results = list.filter(l => results.map(r => `${r[0]}x${r[1]}`).indexOf(`${l.size[0]}x${l.size[1]}`) !== -1); - results = results.sort(function (a, b) { - return b.s - a.s; - }) - return results.map(r => r.size); - }, []) - return removeDuplicate([...reOrder, ...removeSizes]); -} - -export function removeDuplicate(arrayValue) { - return arrayValue.filter((elem, index) => { - return arrayValue.map(e => `${e[0]}x${e[1]}`).indexOf(`${elem[0]}x${elem[1]}`) === index - }) -} - -export function upto5(allimps, dmxRequest, bidderRequest, DMXURI) { - let start = 0; - let step = 5; - let req = []; - while (allimps.length !== 0) { - if (allimps.length >= 5) { - req.push(allimps.splice(start, step)) - } else { - req.push(allimps.splice(start, allimps.length)) - } - } - return req.map(r => { - dmxRequest.imp = r; - return { - method: 'POST', - url: DMXURI, - data: JSON.stringify(dmxRequest), - bidderRequest - } - }) -} - -/** - * Function matchRequest(id: string, BidRequest: object) - * @param id - * @type string - * @param bidRequest - * @type Object - * @returns Object - * - */ -export function matchRequest(id, bidRequest) { - const { bids } = bidRequest.bidderRequest; - const [returnValue] = bids.filter(bid => bid.bidId === id); - return returnValue; -} -export function checkDeepArray(Arr) { - if (Array.isArray(Arr)) { - if (Array.isArray(Arr[0])) { - return Arr[0]; - } else { - return Arr; - } - } else { - return Arr; - } -} -export function defaultSize(thebidObj) { - const { sizes } = thebidObj; - const returnObject = {}; - returnObject.width = checkDeepArray(sizes)[0]; - returnObject.height = checkDeepArray(sizes)[1]; - return returnObject; -} - -export function bindUserId(eids, value, source, atype) { - if (utils.isStr(value) && Array.isArray(eids)) { - eids.push({ - source, - uids: [ - { - id: value, - atype - } - ] - }) - } -} - -export function getApi({ api }) { - let defaultValue = [2]; - if (api && Array.isArray(api) && api.length > 0) { - return api - } else { - return defaultValue; - } -} -export function getPlaybackmethod(playback) { - if (Array.isArray(playback) && playback.length > 0) { - return playback.map(label => { - return VIDEO_MAPPING.playback_method[label] - }) - } - return [2] -} - -export function getProtocols({ protocols }) { - let defaultValue = [2, 3, 5, 6, 7, 8]; - if (protocols && Array.isArray(protocols) && protocols.length > 0) { - return protocols; - } else { - return defaultValue; - } -} - -export function cleanVast(str, nurl) { - try { - const toberemove = /]*?src\s*=\s*['\"]([^'\"]*?)['\"][^>]*?>/ - const [img, url] = str.match(toberemove) - str = str.replace(toberemove, '') - if (img) { - if (url) { - const insrt = `` - str = str.replace('', `${insrt}`) - } - } - return str; - } catch (e) { - if (!nurl) { - return str - } - const insrt = `` - str = str.replace('', `${insrt}`) - return str - } -} -registerBidder(spec); diff --git a/modules/districtmDmxBidAdapter.md b/modules/districtmDmxBidAdapter.md deleted file mode 100644 index 5d5dd2affe6..00000000000 --- a/modules/districtmDmxBidAdapter.md +++ /dev/null @@ -1,203 +0,0 @@ -``` -Module Name: district m Bid Adapter -Module Type: Bidder Adapter -Maintainer: Steve Alliance (steve@districtm.net) -``` - -# Overview - -The `districtmDmxAdapter` module allows publishers to include DMX Exchange demand using Prebid 1.0+. - -## Attributes - -* Single Request -* Multi-Size Support -* GDPR Compliant -* CCPA Compliant -* COPPA Compliant -* Bids returned in **NET** - - ## Media Types - -* Banner -* Video -## Bidder Parameters - -| Key | Scope | Type | Description -| --- | --- | --- | --- -| `dmxid` | Mandatory | Integer | Unique identifier of the placement, dmxid can be obtained in the district m Boost platform. -| `memberid` | Mandatory | Integer | Unique identifier for your account, memberid can be obtained in the district m Boost platform. -| `floor` | Optional | float | Most placement can have floor set in our platform, but this can now be set on the request too. - -# Ad Unit Configuration Example - -```javascript - var adUnits = [{ - code: 'div-gpt-ad-1460505748561-0', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]], - } - }, - bids: [{ - bidder: 'districtmDMX', - params: { - dmxid: 100001, - memberid: 100003 - } - }] - }]; -``` - -# Ad Unit Configuration Example for video request - -```javascript - var videoAdUnit = { - code: 'video1', - sizes: [640,480], - mediaTypes: { video: {context: 'instream', //or 'outstream' - playerSize: [[640, 480]], - skipppable: true, - minduration: 5, - maxduration: 45, - playback_method: ['auto_play_sound_off', 'viewport_sound_off'], - mimes: ["application/javascript", - "video/mp4"], - - } }, - bids: [ - { - bidder: 'districtmDMX', - params: { - dmxid: '100001', - memberid: '100003', - } - } - - ] - }; -``` - - -# Ad Unit Configuration when COPPA is needed - - -# Quick Start Guide - -###### 1. Including the `districtmDmxAdapter` in your build process. - -Add the adapter as an argument to gulp build. - -``` -gulp build --modules=districtmDmxAdapter,ixBidAdapter,appnexusBidAdapter -``` - -*Adding `"districtmDmxAdapter"` as an entry in a JSON file with your bidders is also acceptable.* - -``` -[ - "districtmDmxAdapter", - "ixBidAdapter", - "appnexusBidAdapter" -] -``` - -*Proceed to build with the JSON file.* - -``` -gulp build --modules=bidderModules.json -``` - -###### 2. Configure the ad unit object - -Once Prebid is ready you may use the below example to create the adUnits object and begin building the configuration. - -```javascript -var adUnits = [{ - code: 'div-gpt-ad-1460505748561-0', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600], [728, 90]], - } - }, - bids: [] - } -]; -``` - -###### 3. Add the bidder - -Our demand and adapter supports multiple sizes per placement, as such a single dmxid may be used for all sizes of a single domain. - -```javascript - var adUnits = [{ - code: 'div-gpt-ad-1460505748561-0', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600], [728, 90]], - } - }, - bids: [{ - bidder: 'districtmDMX', - params: { - dmxid: 100001, - memberid: 100003 - } - }] - }]; -``` - -Our bidder only supports instream context at the moment and we strongly like to put the media types and setting in the ad unit settings. -If no value is set the default value will be applied. - -```javascript - var videoAdUnit = { - code: 'video1', - sizes: [640,480], - mediaTypes: { video: {context: 'instream', //or 'outstream' - playerSize: [[640, 480]], - skipppable: true, - minduration: 5, - maxduration: 45, - playback_method: ['auto_play_sound_off', 'viewport_sound_off'], - mimes: ["application/javascript", - "video/mp4"], - - } }, - bids: [ - { - bidder: 'districtmDMX', - params: { - dmxid: '250258', - memberid: '100600', - } - } - ] - }; -``` - -###### 4. Implementation Checking - -Once the bidder is live in your Prebid configuration you may confirm it is making requests to our end point by looking for requests to `https://dmx.districtm.io/b/v1`. - - -###### 5. Setting first party data - -```code -pbjs.setConfig({ - dmx: { - user: { - 'gender': 'M', - 'yob': 1992, - // keywords example - 'keywords': 'automotive,dodge,engine,car' - - }, - site: { - cat: ['IAB-12'], - pagecat: ['IAB-14'], - sectioncat: ['IAB-24'] - } - } -}); -``` diff --git a/modules/divreachBidAdapter.md b/modules/divreachBidAdapter.md deleted file mode 100644 index 643845782b8..00000000000 --- a/modules/divreachBidAdapter.md +++ /dev/null @@ -1,30 +0,0 @@ -# Overview - -Module Name: DivReach Bidder Adapter -Module Type: Bidder Adapter -Maintainer: Zeke@divreach.com - -# Description - -Connects to DivReach demand source to fetch bids. -Please use ```divreach``` as the bidder code. - -# Test Parameters -``` - var adUnits = [ - { - code: 'desktop-banner-ad-div', - sizes: [[300, 250]], - bids: [ - { - bidder: "divreach", - params: { - accountID: '167283', - zoneID: '335105', - domain: 'ad.divreach.com', - } - } - ] - }, - ]; -``` diff --git a/modules/djaxBidAdapter.js b/modules/djaxBidAdapter.js deleted file mode 100644 index ffaf61a3f15..00000000000 --- a/modules/djaxBidAdapter.js +++ /dev/null @@ -1,129 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { config } from '../src/config.js'; -import * as utils from '../src/utils.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import { ajax } from '../src/ajax.js'; -import {Renderer} from '../src/Renderer.js'; - -const SUPPORTED_AD_TYPES = [BANNER, VIDEO]; -const BIDDER_CODE = 'djax'; -const DOMAIN = 'https://demo.reviveadservermod.com/headerbidding_adminshare/'; -const RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js'; - -function isBidRequestValid(bid) { - return (typeof bid.params !== 'undefined' && parseInt(utils.getValue(bid.params, 'publisherId')) > 0); -} - -function buildRequests(validBidRequests) { - return { - method: 'POST', - url: DOMAIN + 'www/admin/plugins/Prebid/getAd.php', - options: { - withCredentials: false, - crossOrigin: true - }, - data: validBidRequests, - }; -} - -function interpretResponse(serverResponse, request) { - const response = serverResponse.body; - const bidResponses = []; - var bidRequestResponses = []; - - utils._each(response, function(bidAd) { - bidAd.adResponse = { - content: bidAd.vastXml, - height: bidAd.height, - width: bidAd.width - }; - bidAd.ttl = config.getConfig('_bidderTimeout') - bidAd.renderer = bidAd.context === 'outstream' ? createRenderer(bidAd, { - id: bidAd.adUnitCode, - url: RENDERER_URL - }, bidAd.adUnitCode) : undefined; - bidResponses.push(bidAd); - }); - - bidRequestResponses.push({ - function: 'saveResponses', - request: request, - response: bidResponses - }); - sendResponseToServer(bidRequestResponses); - return bidResponses; -} - -function outstreamRender(bidAd) { - bidAd.renderer.push(() => { - window.ANOutstreamVideo.renderAd({ - sizes: [bidAd.width, bidAd.height], - width: bidAd.width, - height: bidAd.height, - targetId: bidAd.adUnitCode, - adResponse: bidAd.adResponse, - rendererOptions: { - showVolume: false, - allowFullscreen: false - } - }); - }); -} - -function createRenderer(bidAd, rendererParams, adUnitCode) { - const renderer = Renderer.install({ - id: rendererParams.id, - url: rendererParams.url, - loaded: false, - config: {'player_height': bidAd.height, 'player_width': bidAd.width}, - adUnitCode - }); - try { - renderer.setRender(outstreamRender); - } catch (err) { - utils.logWarn('Prebid Error calling setRender on renderer', err); - } - return renderer; -} - -function onBidWon(bid) { - let wonBids = []; - wonBids.push(bid); - wonBids[0].function = 'onBidWon'; - sendResponseToServer(wonBids); -} - -function onTimeout(details) { - details.unshift({ 'function': 'onTimeout' }); - sendResponseToServer(details); -} - -function sendResponseToServer(data) { - ajax(DOMAIN + 'www/admin/plugins/Prebid/tracking/track.php', null, JSON.stringify(data), { - withCredentials: false, - method: 'POST', - crossOrigin: true - }); -} - -function getUserSyncs(syncOptions) { - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: DOMAIN + 'www/admin/plugins/Prebid/userSync.php' - }]; - } -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: SUPPORTED_AD_TYPES, - isBidRequestValid, - buildRequests, - interpretResponse, - getUserSyncs, - onBidWon, - onTimeout -}; - -registerBidder(spec); diff --git a/modules/djaxBidAdapter.md b/modules/djaxBidAdapter.md deleted file mode 100644 index d597eb59b58..00000000000 --- a/modules/djaxBidAdapter.md +++ /dev/null @@ -1,50 +0,0 @@ -# Overview - -``` -Module Name: djax Bid Adapter -Module Type: Bidder Adapter -Maintainer : support@djaxtech.com -``` - -# Description - -Connects to Djax Ad Server for bids. - -djax bid adapter supports Banner and Video. - -# Test Parameters -``` - var adUnits = [ - //bannner object - { - code: 'banner-ad-slot', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]], - } - }, - bids: [{ - bidder: 'djax', - params: { - publisherId: 2 - } - }] - - }, - //video object - { - code: 'video-ad-slot', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480], - }, - }, - bids: [{ - bidder: "djax", - params: { - publisherId: 2 - } - }] - }]; -``` \ No newline at end of file diff --git a/modules/dmdIdSystem.js b/modules/dmdIdSystem.js deleted file mode 100644 index 7cf7b9fac95..00000000000 --- a/modules/dmdIdSystem.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * This module adds dmdId to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/dmdIdSystem - * @requires module:modules/userId - */ - -import * as utils from '../src/utils.js'; -import { submodule } from '../src/hook.js'; - -/** @type {Submodule} */ -export const dmdIdSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: 'dmdId', - - /** - * decode the stored id value for passing to bid requests - * @function decode - * @param {(Object|string)} value - * @returns {(Object|undefined)} - */ - decode(value) { - return value && typeof value === 'string' - ? { 'dmdId': value } - : undefined; - }, - - /** - * performs action to obtain id and return a value in the callback's response argument - * @function getId - * @param {SubmoduleConfig} [config] - * @param {ConsentData} - * @param {Object} cacheIdObj - existing id, if any consentData] - * @returns {IdResponse|undefined} - */ - getId(config, consentData, cacheIdObj) { - try { - const configParams = (config && config.params) || {}; - if ( - !configParams || - !configParams.api_key || - typeof configParams.api_key !== 'string' - ) { - utils.logError('dmd submodule requires an api_key.'); - return; - } else { - return cacheIdObj; - } - } catch (e) { - utils.logError(`dmdIdSystem encountered an error`, e); - } - }, -}; - -submodule('userId', dmdIdSubmodule); diff --git a/modules/dmdIdSystem.md b/modules/dmdIdSystem.md deleted file mode 100644 index f2a5b76ade7..00000000000 --- a/modules/dmdIdSystem.md +++ /dev/null @@ -1,26 +0,0 @@ -pbjs.setConfig({ - userSync: { - userIds: [{ - name: 'dmdId', - storage: { - name: 'dmd-dgid', - type: 'cookie', - expires: 30 - }, - params: { - api_key: '3fdbe297-3690-4f5c-9e11-ee9186a6d77c', // provided by DMD - } - }] - } -}); - -#### DMD ID Configuration - -{: .table .table-bordered .table-striped } -| Param under userSync.userIds[] | Scope | Type | Description | Example | -| --- | --- | --- | --- | --- | -| name | Required | String | The name of Module | `"dmdId"` | -| storage | Required | Object | | -| storage.name | Required | String | `dmd-dgid` | -| params | Required | Object | Container of all module params. | | -| params.api_key | Required | String | This is your `api_key` as provided by DMD Marketing Corp. | `3fdbe297-3690-4f5c-9e11-ee9186a6d77c` | \ No newline at end of file diff --git a/modules/docereeBidAdapter.js b/modules/docereeBidAdapter.js deleted file mode 100644 index f9f3e1bcc70..00000000000 --- a/modules/docereeBidAdapter.js +++ /dev/null @@ -1,65 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { config } from '../src/config.js'; -import { BANNER } from '../src/mediaTypes.js'; -const BIDDER_CODE = 'doceree'; -const END_POINT = 'https://bidder.doceree.com' - -export const spec = { - code: BIDDER_CODE, - url: '', - supportedMediaTypes: [ BANNER ], - - isBidRequestValid: (bid) => { - const { placementId } = bid.params; - return !!placementId - }, - buildRequests: (validBidRequests) => { - const serverRequests = []; - const { data } = config.getConfig('doceree.user') - const { page, domain, token } = config.getConfig('doceree.context') - const encodedUserInfo = window.btoa(encodeURIComponent(JSON.stringify(data))) - - validBidRequests.forEach(function(validBidRequest) { - const { publisherUrl, placementId } = validBidRequest.params; - const url = publisherUrl || page - let queryString = ''; - queryString = utils.tryAppendQueryString(queryString, 'id', placementId); - queryString = utils.tryAppendQueryString(queryString, 'publisherDomain', domain); - queryString = utils.tryAppendQueryString(queryString, 'pubRequestedURL', encodeURIComponent(url)); - queryString = utils.tryAppendQueryString(queryString, 'loggedInUser', encodedUserInfo); - queryString = utils.tryAppendQueryString(queryString, 'currentUrl', url); - queryString = utils.tryAppendQueryString(queryString, 'prebidjs', true); - queryString = utils.tryAppendQueryString(queryString, 'token', token); - queryString = utils.tryAppendQueryString(queryString, 'requestId', validBidRequest.bidId); - - serverRequests.push({ - method: 'GET', - url: END_POINT + '/v1/adrequest?' + queryString - }) - }) - return serverRequests; - }, - interpretResponse: (serverResponse, request) => { - const responseJson = serverResponse ? serverResponse.body : {}; - const placementId = responseJson.DIVID; - const bidResponse = { - ad: responseJson.sourceHTML, - width: Number(responseJson.width), - height: Number(responseJson.height), - requestId: responseJson.guid, - netRevenue: true, - ttl: 30, - cpm: responseJson.cpmBid, - currency: responseJson.currency, - mediaType: 'banner', - creativeId: placementId, - meta: { - advertiserDomains: [responseJson.advertiserDomain] - } - }; - return [bidResponse]; - } -}; - -registerBidder(spec); diff --git a/modules/docereeBidAdapter.md b/modules/docereeBidAdapter.md deleted file mode 100644 index d977e11f40a..00000000000 --- a/modules/docereeBidAdapter.md +++ /dev/null @@ -1,33 +0,0 @@ -# Overview - -``` -Module Name: Doceree Bidder Adapter -Module Type: Bidder Adapter -Maintainer: sourbh.gupta@doceree.com -``` - - -Connects to Doceree demand source to fetch bids. -Please use ```doceree``` as the bidder code. - - -# Test Parameters -``` -var adUnits = [ - { - code: 'doceree', - sizes: [ - [300, 250] - ], - bids: [ - { - bidder: "doceree", - params: { - placementId: 'DOC_7jm9j5eqkl0xvc5w', //required - publisherUrl: document.URL || window.location.href, //optional - } - } - ] - } -]; -``` diff --git a/modules/dspxBidAdapter.js b/modules/dspxBidAdapter.js deleted file mode 100644 index dd49a744225..00000000000 --- a/modules/dspxBidAdapter.js +++ /dev/null @@ -1,191 +0,0 @@ -import * as utils from '../src/utils.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'dspx'; -const ENDPOINT_URL = 'https://buyer.dspx.tv/request/'; -const ENDPOINT_URL_DEV = 'https://dcbuyer.dspx.tv/request/'; -const DEFAULT_VAST_FORMAT = 'vast2'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['dspx'], - supportedMediaTypes: [BANNER, VIDEO], - isBidRequestValid: function(bid) { - return !!(bid.params.placement); - }, - buildRequests: function(validBidRequests, bidderRequest) { - return validBidRequests.map(bidRequest => { - const params = bidRequest.params; - - const videoData = utils.deepAccess(bidRequest, 'mediaTypes.video') || {}; - const sizes = utils.parseSizesInput(videoData.playerSize || bidRequest.sizes)[0]; - const [width, height] = sizes.split('x'); - - const placementId = params.placement; - const rnd = Math.floor(Math.random() * 99999999999); - const referrer = bidderRequest.refererInfo.referer; - const bidId = bidRequest.bidId; - const isDev = params.devMode || false; - - let endpoint = isDev ? ENDPOINT_URL_DEV : ENDPOINT_URL; - let payload = {}; - - if (isVideoRequest(bidRequest)) { - let vastFormat = params.vastFormat || DEFAULT_VAST_FORMAT; - payload = { - _f: vastFormat, - alternative: 'prebid_js', - inventory_item_id: placementId, - srw: width, - srh: height, - idt: 100, - rnd: rnd, - ref: referrer, - bid_id: bidId, - }; - } else { - payload = { - _f: 'html', - alternative: 'prebid_js', - inventory_item_id: placementId, - srw: width, - srh: height, - idt: 100, - rnd: rnd, - ref: referrer, - bid_id: bidId, - }; - } - - if (params.pfilter !== undefined) { - payload.pfilter = params.pfilter; - } - - if (bidderRequest && bidderRequest.gdprConsent) { - if (payload.pfilter !== undefined) { - if (!payload.pfilter.gdpr_consent) { - payload.pfilter.gdpr_consent = bidderRequest.gdprConsent.consentString; - payload.pfilter.gdpr = bidderRequest.gdprConsent.gdprApplies; - } - } else { - payload.pfilter = { - 'gdpr_consent': bidderRequest.gdprConsent.consentString, - 'gdpr': bidderRequest.gdprConsent.gdprApplies - }; - } - } - - if (params.bcat !== undefined) { - payload.bcat = params.bcat; - } - if (params.dvt !== undefined) { - payload.dvt = params.dvt; - } - if (isDev) { - payload.prebidDevMode = 1; - } - return { - method: 'GET', - url: endpoint, - data: objectToQueryString(payload), - } - }); - }, - interpretResponse: function(serverResponse, bidRequest) { - const bidResponses = []; - const response = serverResponse.body; - const crid = response.crid || 0; - const cpm = response.cpm / 1000000 || 0; - if (cpm !== 0 && crid !== 0) { - const dealId = response.dealid || ''; - const currency = response.currency || 'EUR'; - const netRevenue = (response.netRevenue === undefined) ? true : response.netRevenue; - const bidResponse = { - requestId: response.bid_id, - cpm: cpm, - width: response.width, - height: response.height, - creativeId: crid, - dealId: dealId, - currency: currency, - netRevenue: netRevenue, - type: response.type, - ttl: config.getConfig('_bidderTimeout') - }; - if (response.vastXml) { - bidResponse.vastXml = response.vastXml; - bidResponse.mediaType = 'video'; - } else { - bidResponse.ad = response.adTag; - } - bidResponses.push(bidResponse); - } - return bidResponses; - }, - getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) { - if (!serverResponses || serverResponses.length === 0) { - return []; - } - - const syncs = [] - - let gdprParams = ''; - if (gdprConsent) { - if ('gdprApplies' in gdprConsent && typeof gdprConsent.gdprApplies === 'boolean') { - gdprParams = `gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - gdprParams = `gdpr_consent=${gdprConsent.consentString}`; - } - } - - if (syncOptions.iframeEnabled) { - serverResponses[0].body.userSync.iframeUrl.forEach((url) => syncs.push({ - type: 'iframe', - url: appendToUrl(url, gdprParams) - })); - } - if (syncOptions.pixelEnabled && serverResponses.length > 0) { - serverResponses[0].body.userSync.imageUrl.forEach((url) => syncs.push({ - type: 'image', - url: appendToUrl(url, gdprParams) - })); - } - return syncs; - } -} - -function appendToUrl(url, what) { - if (!what) { - return url; - } - return url + (url.indexOf('?') !== -1 ? '&' : '?') + what; -} - -function objectToQueryString(obj, prefix) { - let str = []; - let p; - for (p in obj) { - if (obj.hasOwnProperty(p)) { - let k = prefix ? prefix + '[' + p + ']' : p; - let v = obj[p]; - str.push((v !== null && typeof v === 'object') - ? objectToQueryString(v, k) - : encodeURIComponent(k) + '=' + encodeURIComponent(v)); - } - } - return str.join('&'); -} - -/** - * Check if it's a video bid request - * - * @param {BidRequest} bid - Bid request generated from ad slots - * @returns {boolean} True if it's a video bid - */ -function isVideoRequest(bid) { - return bid.mediaType === 'video' || !!utils.deepAccess(bid, 'mediaTypes.video'); -} - -registerBidder(spec); diff --git a/modules/dspxBidAdapter.md b/modules/dspxBidAdapter.md deleted file mode 100644 index 8733aff698c..00000000000 --- a/modules/dspxBidAdapter.md +++ /dev/null @@ -1,65 +0,0 @@ -# Overview - -``` -Module Name: DSPx Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid@dspx.tv -``` - -# Description - -DSPx adapter for Prebid. - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [300, 600], - ] - } - }, - bids: [ - { - bidder: "dspx", - params: { - placement: '101', // [required] info available from your contact with DSPx team - /* - bcat: "IAB2,IAB4", // [optional] list of blocked advertiser categories (IAB), comma separated - */ - /* - pfilter: { // [optional] - // [optional] only required if a deal is negotiated - deals: [ // [optional] - "123-4567-d58a7f9a-..."// DEAL_ID from DSPx contact - ], - private_auction: 1 // [optional] 0 - no, 1 - yes - // usually managed on DSPx side - floorprice: 1000000 // input min_cpm_micros, CPM in EUR * 1000000 - }, - */ - } - } - ] - }, - { - code: 'video1', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'instream' - } - }, - bids: [{ - bidder: 'dspx', - params: { - placement: '106' - } - }] - } - ]; -``` diff --git a/modules/e_volutionBidAdapter.js b/modules/e_volutionBidAdapter.js deleted file mode 100644 index 9fc7035db32..00000000000 --- a/modules/e_volutionBidAdapter.js +++ /dev/null @@ -1,111 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; - -const BIDDER_CODE = 'e_volution'; -const AD_URL = 'https://service.e-volution.ai/?c=o&m=multi'; -const URL_SYNC = 'https://service.e-volution.ai/?c=o&m=sync'; -const NO_SYNC = true; - -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency) { - return false; - } - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl); - case NATIVE: - return Boolean(bid.native && bid.native.title && bid.native.image && bid.native.impressionTrackers); - default: - return false; - } -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO, NATIVE], - noSync: NO_SYNC, - - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && bid.params && !isNaN(parseInt(bid.params.placementId))); - }, - - buildRequests: (validBidRequests = [], bidderRequest) => { - let winTop = window; - let location; - try { - location = new URL(bidderRequest.refererInfo.referer) - winTop = window.top; - } catch (e) { - location = winTop.location; - utils.logMessage(e); - }; - let placements = []; - let request = { - 'deviceWidth': winTop.screen.width, - 'deviceHeight': winTop.screen.height, - 'language': (navigator && navigator.language) ? navigator.language.split('-')[0] : '', - 'secure': 1, - 'host': location.host, - 'page': location.pathname, - 'placements': placements - }; - if (bidderRequest) { - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - if (bidderRequest.gdprConsent) { - request.gdpr = bidderRequest.gdprConsent - } - } - const len = validBidRequests.length; - - for (let i = 0; i < len; i++) { - let bid = validBidRequests[i]; - let traff = bid.params.traffic || BANNER - - placements.push({ - placementId: bid.params.placementId, - bidId: bid.bidId, - sizes: bid.mediaTypes && bid.mediaTypes[traff] && bid.mediaTypes[traff].sizes ? bid.mediaTypes[traff].sizes : [], - traffic: traff - }); - if (bid.schain) { - placements.schain = bid.schain; - } - } - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - response.push(resItem); - } - } - return response; - }, - - getUserSyncs: (syncOptions, serverResponses) => { - if (NO_SYNC) { - return false - } else { - return [{ - type: 'image', - url: URL_SYNC - }]; - } - } - -}; - -registerBidder(spec); diff --git a/modules/e_volutionBidAdapter.md b/modules/e_volutionBidAdapter.md deleted file mode 100644 index ff5b2860e05..00000000000 --- a/modules/e_volutionBidAdapter.md +++ /dev/null @@ -1,53 +0,0 @@ -# Overview - -``` -Module Name: e_volution Bidder Adapter -Module Type: Bidder Adapter -``` - -# Description - -Module that connects to e-volution-tech demand sources - -# Test Parameters -``` - var adUnits = [ - // Will return static test banner - { - code: 'placementId_0', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [ - { - bidder: 'e_volution', - params: { - placementId: 0, - traffic: 'banner' - } - } - ] - }, - // Will return test vast xml. All video params are stored under placement in publishers UI - { - code: 'placementId_0', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'instream' - } - }, - bids: [ - { - bidder: 'e_volution', - params: { - placementId: 0, - traffic: 'video' - } - } - ] - } - ]; -``` diff --git a/modules/ebdrBidAdapter.js b/modules/ebdrBidAdapter.js deleted file mode 100644 index c30c10d8a90..00000000000 --- a/modules/ebdrBidAdapter.js +++ /dev/null @@ -1,151 +0,0 @@ -import * as utils from '../src/utils.js'; -import { VIDEO, BANNER } from '../src/mediaTypes.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -const BIDDER_CODE = 'ebdr'; -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [ BANNER, VIDEO ], - isBidRequestValid: function(bid) { - return !!(bid && bid.params && bid.params.zoneid); - }, - buildRequests: function(bids) { - const rtbServerDomain = 'dsp.bnmla.com'; - let domain = window.location.host; - let page = window.location.pathname + location.search + location.hash; - let ebdrImps = []; - const ebdrReq = {}; - let ebdrParams = {}; - let zoneid = ''; - let requestId = ''; - bids.forEach(bid => { - utils.logInfo('Log bid', bid); - let bidFloor = utils.getBidIdParameter('bidfloor', bid.params); - let whArr = getWidthAndHeight(bid); - let _mediaTypes = (bid.mediaTypes && bid.mediaTypes.video) ? VIDEO : BANNER; - zoneid = utils.getBidIdParameter('zoneid', bid.params); - requestId = bid.bidderRequestId; - ebdrImps.push({ - id: bid.bidId, - [_mediaTypes]: { - w: whArr[0], - h: whArr[1] - }, - bidfloor: bidFloor - }) - ebdrReq[bid.bidId] = {mediaTypes: _mediaTypes, - w: whArr[0], - h: whArr[1] - }; - ebdrParams['latitude'] = utils.getBidIdParameter('latitude', bid.params); - ebdrParams['longitude'] = utils.getBidIdParameter('longitude', bid.params); - ebdrParams['ifa'] = (utils.getBidIdParameter('IDFA', bid.params).length > utils.getBidIdParameter('ADID', bid.params).length) ? utils.getBidIdParameter('IDFA', bid.params) : utils.getBidIdParameter('ADID', bid.params); - }); - let ebdrBidReq = { - id: requestId, - imp: ebdrImps, - site: { - domain: domain, - page: page - }, - device: { - geo: { - lat: ebdrParams.latitude, - log: ebdrParams.longitude - }, - ifa: ebdrParams.ifa - } - }; - return { - method: 'GET', - url: 'https://' + rtbServerDomain + '/hb?' + '&zoneid=' + zoneid + '&br=' + encodeURIComponent(JSON.stringify(ebdrBidReq)), - bids: ebdrReq - }; - }, - interpretResponse: function(serverResponse, bidRequest) { - utils.logInfo('Log serverResponse', serverResponse); - utils.logInfo('Log bidRequest', bidRequest); - let ebdrResponseImps = []; - const ebdrResponseObj = serverResponse.body; - if (!ebdrResponseObj || !ebdrResponseObj.seatbid || ebdrResponseObj.seatbid.length === 0 || !ebdrResponseObj.seatbid[0].bid || ebdrResponseObj.seatbid[0].bid.length === 0) { - return []; - } - ebdrResponseObj.seatbid[0].bid.forEach(ebdrBid => { - let responseCPM; - responseCPM = parseFloat(ebdrBid.price); - let adm; - let type; - let _mediaTypes; - let vastURL; - if (bidRequest.bids[ebdrBid.id].mediaTypes == BANNER) { - adm = decodeURIComponent(ebdrBid.adm) - type = 'ad'; - _mediaTypes = BANNER; - } else { - adm = ebdrBid.adm - type = 'vastXml' - _mediaTypes = VIDEO; - if (ebdrBid.nurl) { - vastURL = ebdrBid.nurl; - } - } - let response = { - requestId: ebdrBid.id, - [type]: adm, - mediaType: _mediaTypes, - creativeId: ebdrBid.crid, - cpm: responseCPM, - width: ebdrBid.w, - height: ebdrBid.h, - currency: 'USD', - netRevenue: true, - ttl: 3600 } - if (vastURL) { - response.vastUrl = vastURL; - } - ebdrResponseImps.push(response); - }); - return ebdrResponseImps; - }, - getUserSyncs: function(syncOptions, serverResponses) { - const syncs = [] - if (syncOptions.pixelEnabled) { - const ebdrResponseObj = serverResponses.body; - if (!ebdrResponseObj || !ebdrResponseObj.seatbid || ebdrResponseObj.seatbid.length === 0 || !ebdrResponseObj.seatbid[0].bid || ebdrResponseObj.seatbid[0].bid.length === 0) { - return []; - } - ebdrResponseObj.seatbid[0].bid.forEach(ebdrBid => { - if (ebdrBid.iurl && ebdrBid.iurl.length > 0) { - syncs.push({ - type: 'image', - url: ebdrBid.iurl - }); - } - }); - } - return syncs; - } -} -function getWidthAndHeight(bid) { - let adW = null; - let adH = null; - // Handing old bidder only has size object - if (bid.sizes && bid.sizes.length) { - let sizeArrayLength = bid.sizes.length; - if (sizeArrayLength === 2 && typeof bid.sizes[0] === 'number' && typeof bid.sizes[1] === 'number') { - adW = bid.sizes[0]; - adH = bid.sizes[1]; - } - } - let _mediaTypes = bid.mediaTypes && bid.mediaTypes.video ? VIDEO : BANNER; - if (bid.mediaTypes && bid.mediaTypes[_mediaTypes]) { - if (_mediaTypes == BANNER && bid.mediaTypes[_mediaTypes].sizes && bid.mediaTypes[_mediaTypes].sizes[0] && bid.mediaTypes[_mediaTypes].sizes[0].length === 2) { - adW = bid.mediaTypes[_mediaTypes].sizes[0][0]; - adH = bid.mediaTypes[_mediaTypes].sizes[0][1]; - } else if (_mediaTypes == VIDEO && bid.mediaTypes[_mediaTypes].playerSize && bid.mediaTypes[_mediaTypes].playerSize.length === 2) { - adW = bid.mediaTypes[_mediaTypes].playerSize[0]; - adH = bid.mediaTypes[_mediaTypes].playerSize[1]; - } - } - return [adW, adH]; -} -registerBidder(spec); diff --git a/modules/ebdrBidAdapter.md b/modules/ebdrBidAdapter.md deleted file mode 100644 index 64483797b25..00000000000 --- a/modules/ebdrBidAdapter.md +++ /dev/null @@ -1,53 +0,0 @@ -# Overview - -``` -Module Name: EngageBDR Bid Adapter -Module Type: Bidder Adapter -Maintainer: tech@engagebdr.com -``` - -# Description - -Adapter that connects to EngageBDR's demand sources. - -# Test Parameters -``` - var adUnits = [{ - code: 'div-gpt-ad-1460505748561-0', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]], - } - }, - bids: [{ - bidder: 'ebdr', - params: { - zoneid: '99999', - bidfloor: '1.00', - IDFA:'xxx-xxx', - ADID:'xxx-xxx', - latitude:'34.089811', - longitude:'-118.392805' - } - }] - },{ - code: 'test-video', - mediaTypes: { - video: { - context: 'instream', - playerSize: [300, 250] - } - }, - bids: [{ - bidder: 'ebdr', - params: { - zoneid: '99998', - bidfloor: '1.00', - IDFA:'xxx-xxx', - ADID:'xxx-xxx', - latitude:'34.089811', - longitude:'-118.392805' - } - }] - }]; -``` diff --git a/modules/edgequeryxBidAdapter.js b/modules/edgequeryxBidAdapter.js deleted file mode 100644 index ee50946ee18..00000000000 --- a/modules/edgequeryxBidAdapter.js +++ /dev/null @@ -1,98 +0,0 @@ -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'edgequeryx'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['eqx'], // short code - supportedMediaTypes: [BANNER, VIDEO], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return !!(bid.params && bid.params.accountId && bid.params.widgetId); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests an array of bids - * @param {BidderRequest} bidderRequest bidder request object - * @return {ServerRequest[]} Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - // use bidderRequest.bids[] to get bidder-dependent request info - // if your bidder supports multiple currencies, use config.getConfig(currency) - // to find which one the ad server needs - - // pull requested transaction ID from bidderRequest.bids[].transactionId - return validBidRequests.map(bid => { - // Common bid request attributes for banner, outstream and instream. - let payload = { - accountId: bid.params.accountId, - widgetId: bid.params.widgetId, - currencyCode: 'EUR', - tagId: bid.adUnitCode, - transactionId: bid.transactionId, - timeout: config.getConfig('bidderTimeout'), - bidId: bid.bidId, - prebidVersion: '$prebid.version$' - }; - - const bannerMediaType = utils.deepAccess(bid, 'mediaTypes.banner'); - payload.sizes = bannerMediaType.sizes.map(size => ({ - w: size[0], - h: size[1] - })); - - var payloadString = JSON.stringify(payload); - - return { - method: 'POST', - url: (bid.params.domain !== undefined ? bid.params.domain : 'https://deep.edgequery.io') + '/prebid/x', - data: payloadString, - }; - }); - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @param {*} bidRequestString - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function (serverResponse, bidRequestString) { - const bidResponses = []; - let response = serverResponse.body; - try { - if (response) { - let bidResponse = { - requestId: response.requestId, - cpm: response.cpm, - currency: response.currency, - width: response.width, - height: response.height, - ad: response.ad, - ttl: response.ttl, - creativeId: response.creativeId, - netRevenue: response.netRevenue - }; - - bidResponses.push(bidResponse); - } - } catch (error) { - utils.logError('Error while parsing Edge Query X response', error); - } - return bidResponses; - } - -}; - -registerBidder(spec); diff --git a/modules/edgequeryxBidAdapter.md b/modules/edgequeryxBidAdapter.md deleted file mode 100644 index 265120dfaba..00000000000 --- a/modules/edgequeryxBidAdapter.md +++ /dev/null @@ -1,39 +0,0 @@ -# Overview - -``` -Module Name: Edge Query X Bidder Adapter -Module Type: Bidder Adapter -Maintainer: contact@edgequery.com -``` - -# Description - -Connect to Edge Query X for bids. - -The Edge Query X adapter requires setup and approval from the Edge Query team. -Please reach out to your Technical account manager for more information. - -# Test Parameters - -## Web -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[1, 1]] - } - }, - bids: [ - { - bidder: "edgequeryx", - params: { - accountId: "test", - widgetId: "test" - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/emoteevBidAdapter.js b/modules/emoteevBidAdapter.js deleted file mode 100644 index e0f88725d8a..00000000000 --- a/modules/emoteevBidAdapter.js +++ /dev/null @@ -1,525 +0,0 @@ -/** - * This file contains Emoteev bid adpater. - * - * It is organised as follows: - * - Constants values; - * - Spec API functions, which should be pristine pure; - * - Ancillary functions, which should be as pure as possible; - * - Adapter API, where unpure side-effects happen. - * - * The code style is « functional core, imperative shell ». - * - * @link https://www.emoteev.io - * @file This files defines the spec of EmoteevBidAdapter. - * @author Emoteev Engineering . - */ - -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import { - triggerPixel, - getUniqueIdentifierStr, - contains, - deepAccess, - isArray, - isInteger, - getParameterByName, - buildUrl -} from '../src/utils.js'; -import {config} from '../src/config.js'; -import { getStorageManager } from '../src/storageManager.js'; - -export const storage = getStorageManager(); - -export const BIDDER_CODE = 'emoteev'; - -/** - * Version number of the adapter API. - */ -export const ADAPTER_VERSION = '1.35.0'; - -export const DOMAIN = 'prebid.emoteev.xyz'; -export const DOMAIN_STAGING = 'prebid-staging.emoteev.xyz'; -export const DOMAIN_DEVELOPMENT = 'localhost:3000'; - -/** - * Path of Emoteev endpoint for events. - */ -export const EVENTS_PATH = '/api/ad_event.json'; - -/** - * Path of Emoteev bidder. - */ -export const BIDDER_PATH = '/api/prebid/bid'; -export const USER_SYNC_IFRAME_PATH = '/api/prebid/sync-iframe'; -export const USER_SYNC_IMAGE_PATH = '/api/prebid/sync-image'; - -export const PRODUCTION = 'production'; -export const STAGING = 'staging'; -export const DEVELOPMENT = 'development'; -export const DEFAULT_ENV = PRODUCTION; - -export const ON_ADAPTER_CALLED = 'on_adapter_called'; -export const ON_BID_WON = 'on_bid_won'; -export const ON_BIDDER_TIMEOUT = 'on_bidder_timeout'; - -export const IN_CONTENT = 'content'; -export const FOOTER = 'footer'; -export const OVERLAY = 'overlay'; -export const WALLPAPER = 'wallpaper'; - -/** - * Vendor ID assigned to Emoteev from the Global Vendor & CMP List. - * - * See https://vendorlist.consensu.org/vendorinfo.json for more information. - * @type {number} - */ -export const VENDOR_ID = 15; - -/** - * Pure function. See http://prebid.org/dev-docs/bidder-adaptor.html#valid-build-requests-array for detailed semantic. - * - * @param {AdUnit.bidRequest} bidRequest - * @returns {boolean} Is this bidRequest valid? - */ -export const isBidRequestValid = (bidRequest) => { - return !!( - bidRequest && - bidRequest.params && - deepAccess(bidRequest, 'params.adSpaceId') && - validateContext(deepAccess(bidRequest, 'params.context')) && - validateExternalId(deepAccess(bidRequest, 'params.externalId')) && - bidRequest.bidder === BIDDER_CODE && - validateSizes(deepAccess(bidRequest, 'mediaTypes.banner.sizes'))); -}; - -/** - * Pure function. See http://prebid.org/dev-docs/bidder-adaptor.html#serverrequest-objects for detailed semantic. - * - * @param {string} env Emoteev environment parameter - * @param {boolean} debug Pbjs debug parameter. - * @param {string} currency See http://prebid.org/dev-docs/modules/currency.html for detailed semantic. - * @param {Array} validBidRequests Takes an array of bid requests, which are guaranteed to have passed the isBidRequestValid() test. - * @param bidderRequest General context for a bidder request being constructed - * @returns {ServerRequest} - */ -export const buildRequests = (env, debug, currency, validBidRequests, bidderRequest) => { - return { - method: 'POST', - url: bidderUrl(env), - data: JSON.stringify(requestsPayload(debug, currency, validBidRequests, bidderRequest)) // Keys with undefined values will be filtered out. - }; -}; - -/** - * Pure function. See http://prebid.org/dev-docs/bidder-adaptor.html#interpreting-the-response for detailed semantic. - * - * @param {Array} serverResponse.body The body of the server response is an array of bid objects. - * @returns {Array} - */ -export const interpretResponse = (serverResponse) => serverResponse.body; - -/** - * Pure function. See http://prebid.org/dev-docs/bidder-adaptor.html#registering-on-set-targeting for detailed semantic. - * - * @param {string} env Emoteev environment parameter. - * @param {BidRequest} bidRequest - * @returns {UrlObject} - */ -export function onAdapterCalled(env, bidRequest) { - return { - protocol: 'https', - hostname: domain(env), - pathname: EVENTS_PATH, - search: { - eventName: ON_ADAPTER_CALLED, - pubcId: deepAccess(bidRequest, 'crumbs.pubcid'), - bidId: bidRequest.bidId, - adSpaceId: deepAccess(bidRequest, 'params.adSpaceId'), - cache_buster: getUniqueIdentifierStr() - } - }; -} - -/** - * Pure function. See http://prebid.org/dev-docs/bidder-adaptor.html#registering-on-bid-won for detailed semantic. - * - * @param {string} env Emoteev environment parameter. - * @param {string} pubcId Publisher common id. See http://prebid.org/dev-docs/modules/pubCommonId.html for detailed semantic. - * @param bidObject - * @returns {UrlObject} - */ -export const onBidWon = (env, pubcId, bidObject) => { - const bidId = bidObject.requestId; - return { - protocol: 'https', - hostname: domain(env), - pathname: EVENTS_PATH, - search: { - eventName: ON_BID_WON, - pubcId, - bidId, - cache_buster: getUniqueIdentifierStr() - } - }; -}; - -/** - * Pure function. See http://prebid.org/dev-docs/bidder-adaptor.html#registering-on-timeout for detailed semantic. - * - * @param {string} env Emoteev environment parameter. - * @param {BidRequest} bidRequest - * @returns {UrlObject} - */ -export const onTimeout = (env, bidRequest) => { - return { - protocol: 'https', - hostname: domain(env), - pathname: EVENTS_PATH, - search: { - eventName: ON_BIDDER_TIMEOUT, - pubcId: deepAccess(bidRequest, 'crumbs.pubcid'), - bidId: bidRequest.bidId, - adSpaceId: deepAccess(bidRequest, 'params.adSpaceId'), - timeout: bidRequest.timeout, - cache_buster: getUniqueIdentifierStr() - } - } -}; - -/** - * Pure function. See http://prebid.org/dev-docs/bidder-adaptor.html#registering-user-syncs for detailed semantic. - * - * @param {string} env Emoteev environment parameter - * @param {SyncOptions} syncOptions - * @returns userSyncs - */ -export const getUserSyncs = (env, syncOptions) => { - let syncs = []; - if (syncOptions.pixelEnabled) { - syncs.push({ - type: 'image', - url: userSyncImageUrl(env), - }); - } - if (syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: userSyncIframeUrl(env), - }); - } - return syncs; -}; - -/** - * Pure function. - * - * @param {string} env Emoteev environment parameter - * @returns {string} The domain for network calls to Emoteev. - */ -export const domain = (env) => { - switch (env) { - case DEVELOPMENT: - return DOMAIN_DEVELOPMENT; - case STAGING: - return DOMAIN_STAGING; - default: - return DOMAIN; - } -}; - -/** - * Pure function. - * - * @param {string} env Emoteev environment parameter - * @returns {string} The full URL which events is sent to. - */ -export const eventsUrl = env => buildUrl({ - protocol: (env === DEVELOPMENT) ? 'http' : 'https', - hostname: domain(env), - pathname: EVENTS_PATH -}); - -/** - * Pure function. - * - * @param {string} env Emoteev environment parameter - * @returns {string} The full URL which bidderRequest is sent to. - */ -export const bidderUrl = env => buildUrl({ - protocol: (env === DEVELOPMENT) ? 'http' : 'https', - hostname: domain(env), - pathname: BIDDER_PATH -}); - -/** - * Pure function. - * - * @param {string} env Emoteev environment parameter - * @returns {string} The full URL called for iframe-based user sync - */ -export const userSyncIframeUrl = env => buildUrl({ - protocol: (env === DEVELOPMENT) ? 'http' : 'https', - hostname: domain(env), - pathname: USER_SYNC_IFRAME_PATH -}); - -/** - * Pure function. - * - * @param {string} env Emoteev environment parameter - * @returns {string} The full URL called for image-based user sync - */ -export const userSyncImageUrl = env => buildUrl({ - protocol: (env === DEVELOPMENT) ? 'http' : 'https', - hostname: domain(env), - pathname: USER_SYNC_IMAGE_PATH -}); - -/** - * Pure function. - * - * @param {Array>} sizes - * @returns {boolean} are sizes valid? - */ -export const validateSizes = sizes => isArray(sizes) && sizes.length > 0 && sizes.every(size => isArray(size) && size.length === 2); - -/** - * Pure function. - * - * @param {string} context - * @returns {boolean} is param `context` valid? - */ -export const validateContext = context => contains([IN_CONTENT, FOOTER, OVERLAY, WALLPAPER], context); - -/** - * Pure function. - * - * @param {(number|null|undefined)} externalId - * @returns {boolean} is param `externalId` valid? - */ -export const validateExternalId = externalId => externalId === undefined || externalId === null || (isInteger(externalId) && externalId > 0); - -/** - * Pure function. - * - * @param {BidRequest} bidRequest - * @returns {object} An object which represents a BidRequest for Emoteev server side. - */ -export const conformBidRequest = bidRequest => { - return { - params: bidRequest.params, - crumbs: bidRequest.crumbs, - sizes: bidRequest.sizes, - bidId: bidRequest.bidId, - bidderRequestId: bidRequest.bidderRequestId, - }; -}; - -/** - * Pure function. - * - * @param {object} bidderRequest - * @returns {(boolean|undefined)} raw consent data. - */ -export const gdprConsent = (bidderRequest) => (deepAccess(bidderRequest, 'gdprConsent.vendorData.vendorConsents') || {})[VENDOR_ID]; - -/** - * Pure function. - * - * @param {boolean} debug Pbjs debug parameter - * @param {string} currency See http://prebid.org/dev-docs/modules/currency.html for detailed information - * @param {BidRequest} validBidRequests - * @param {object} bidderRequest - * @returns - */ -export const requestsPayload = (debug, currency, validBidRequests, bidderRequest) => { - return { - akPbjsVersion: ADAPTER_VERSION, - bidRequests: validBidRequests.map(conformBidRequest), - currency: currency, - debug: debug, - language: navigator.language, - refererInfo: bidderRequest.refererInfo, - deviceInfo: getDeviceInfo( - getDeviceDimensions(window), - getViewDimensions(window, document), - getDocumentDimensions(document), - isWebGLEnabled(document)), - userAgent: navigator.userAgent, - gdprApplies: deepAccess(bidderRequest, 'gdprConsent.gdprApplies'), - gdprConsent: gdprConsent(bidderRequest), - }; -}; - -/** - * Pure function - * @param {Window} window - * @param {Document} document - * @returns {{width: number, height: number}} View dimensions - */ -export const getViewDimensions = (window, document) => { - let w = window; - let prefix = 'inner'; - - if (window.innerWidth === undefined || window.innerWidth === null) { - w = document.documentElement || document.body; - prefix = 'client'; - } - - return { - width: w[`${prefix}Width`], - height: w[`${prefix}Height`], - }; -}; - -/** - * Pure function - * @param {Window} window - * @returns {{width: number, height: number}} Device dimensions - */ -export const getDeviceDimensions = (window) => { - return { - width: window.screen ? window.screen.width : '', - height: window.screen ? window.screen.height : '', - }; -}; - -/** - * Pure function - * @param {Document} document - * @returns {{width: number, height: number}} Document dimensions - */ -export const getDocumentDimensions = (document) => { - const de = document.documentElement; - const be = document.body; - - const bodyHeight = be ? Math.max(be.offsetHeight, be.scrollHeight) : 0; - - const w = Math.max(de.clientWidth, de.offsetWidth, de.scrollWidth); - const h = Math.max( - de.clientHeight, - de.offsetHeight, - de.scrollHeight, - bodyHeight - ); - - return { - width: isNaN(w) ? '' : w, - height: isNaN(h) ? '' : h, - }; -}; - -/** - * Unpure function - * @param {Document} document - * @returns {boolean} Is WebGL enabled? - */ -export const isWebGLEnabled = (document) => { - // Create test canvas - let canvas = document.createElement('canvas'); - - // The gl context - let gl = null; - - // Try to get the regular WebGL - try { - gl = canvas.getContext('webgl'); - } catch (ex) { - canvas = undefined; - return false; - } - - // No regular WebGL found - if (!gl) { - // Try experimental WebGL - try { - gl = canvas.getContext('experimental-webgl'); - } catch (ex) { - canvas = undefined; - return false; - } - } - - return !!gl; -}; - -/** - * Pure function - * @param {{width: number, height: number}} deviceDimensions - * @param {{width: number, height: number}} viewDimensions - * @param {{width: number, height: number}} documentDimensions - * @param {boolean} webGL - * @returns {object} Device information - */ -export const getDeviceInfo = (deviceDimensions, viewDimensions, documentDimensions, webGL) => { - return { - browserWidth: viewDimensions.width, - browserHeight: viewDimensions.height, - deviceWidth: deviceDimensions.width, - deviceHeight: deviceDimensions.height, - documentWidth: documentDimensions.width, - documentHeight: documentDimensions.height, - webGL: webGL, - }; -}; - -/** - * Pure function - * @param {object} config pbjs config value - * @param {string} parameter Environment override from URL query param. - * @returns {string} One of [PRODUCTION, STAGING, DEVELOPMENT]. - */ -export const resolveEnv = (config, parameter) => { - const configEnv = deepAccess(config, 'emoteev.env'); - - if (contains([PRODUCTION, STAGING, DEVELOPMENT], parameter)) return parameter; - else if (contains([PRODUCTION, STAGING, DEVELOPMENT], configEnv)) return configEnv; - else return DEFAULT_ENV; -}; - -/** - * Pure function - * @param {object} config pbjs config value - * @param {string} parameter Debug override from URL query param. - * @returns {boolean} - */ -export const resolveDebug = (config, parameter) => { - if (parameter && parameter.length && parameter.length > 0) return JSON.parse(parameter); - else if (config.debug) return config.debug; - else return false; -}; - -/** - * EmoteevBidAdapter spec - * @access public - * @type {BidderSpec} - */ -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - isBidRequestValid: isBidRequestValid, - buildRequests: (validBidRequests, bidderRequest) => - buildRequests( - resolveEnv(config.getConfig(), getParameterByName('emoteevEnv')), - resolveDebug(config.getConfig(), getParameterByName('debug')), - config.getConfig('currency'), - validBidRequests, - bidderRequest), - interpretResponse: interpretResponse, - onBidWon: (bidObject) => - triggerPixel(buildUrl(onBidWon( - resolveEnv(config.getConfig(), getParameterByName('emoteevEnv')), - storage.getCookie('_pubcid'), - bidObject))), - onTimeout: (bidRequest) => - triggerPixel(buildUrl(onTimeout( - resolveEnv(config.getConfig(), getParameterByName('emoteevEnv')), - bidRequest))), - getUserSyncs: (syncOptions) => - getUserSyncs( - resolveEnv(config.getConfig(), getParameterByName('emoteevEnv')), - syncOptions), -}; - -registerBidder(spec); diff --git a/modules/emoteevBidAdapter.md b/modules/emoteevBidAdapter.md deleted file mode 100644 index 226a8374369..00000000000 --- a/modules/emoteevBidAdapter.md +++ /dev/null @@ -1,36 +0,0 @@ -# Overview - -``` -Module Name: Emoteev Bidder Adapter -Module Type: Bidder Adapter -Maintainer: engineering@emoteev.io -``` - -# Description - -Module that connects to Emoteev's demand sources - -# Test Parameters - -``` javascript - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[720, 90]], - } - }, - bids: [ - { - bidder: 'emoteev', - params: { - adSpaceId: 5084, - context: 'footer', - externalId: 42, - } - } - ] - } - ]; -``` diff --git a/modules/emx_digitalBidAdapter.js b/modules/emx_digitalBidAdapter.js deleted file mode 100644 index 41a5af6d703..00000000000 --- a/modules/emx_digitalBidAdapter.js +++ /dev/null @@ -1,315 +0,0 @@ -import * as utils 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 includes from 'core-js-pure/features/array/includes.js'; -import find from 'core-js-pure/features/array/find.js'; - -const BIDDER_CODE = 'emx_digital'; -const ENDPOINT = 'hb.emxdgt.com'; -const RENDERER_URL = 'https://js.brealtime.com/outstream/1.30.0/bundle.js'; -const ADAPTER_VERSION = '1.5.1'; -const DEFAULT_CUR = 'USD'; - -export const emxAdapter = { - validateSizes: (sizes) => { - if (!utils.isArray(sizes) || typeof sizes[0] === 'undefined') { - utils.logWarn(BIDDER_CODE + ': Sizes should be an array'); - return false; - } - return sizes.every(size => utils.isArray(size) && size.length === 2); - }, - checkVideoContext: (bid) => { - return ((bid && bid.mediaTypes && bid.mediaTypes.video && bid.mediaTypes.video.context) && ((bid.mediaTypes.video.context === 'instream') || (bid.mediaTypes.video.context === 'outstream'))); - }, - buildBanner: (bid) => { - let sizes = []; - bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes ? sizes = bid.mediaTypes.banner.sizes : sizes = bid.sizes; - if (!emxAdapter.validateSizes(sizes)) { - utils.logWarn(BIDDER_CODE + ': could not detect mediaType banner sizes. Assigning to bid sizes instead'); - sizes = bid.sizes - } - return { - format: sizes.map((size) => { - return { - w: size[0], - h: size[1] - }; - }), - w: sizes[0][0], - h: sizes[0][1] - }; - }, - formatVideoResponse: (bidResponse, emxBid, bidRequest) => { - bidResponse.vastXml = emxBid.adm; - if (bidRequest.bidderRequest && bidRequest.bidderRequest.bids && bidRequest.bidderRequest.bids.length > 0) { - const matchingBid = find(bidRequest.bidderRequest.bids, bid => bidResponse.requestId && bid.bidId && bidResponse.requestId === bid.bidId && bid.mediaTypes && bid.mediaTypes.video && bid.mediaTypes.video.context === 'outstream'); - if (matchingBid) { - bidResponse.renderer = emxAdapter.createRenderer(bidResponse, { - id: emxBid.id, - url: RENDERER_URL - }); - } - } - return bidResponse; - }, - isMobile: () => { - return (/(ios|ipod|ipad|iphone|android)/i).test(navigator.userAgent); - }, - isConnectedTV: () => { - return (/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(navigator.userAgent); - }, - getDevice: () => { - return { - ua: navigator.userAgent, - js: 1, - dnt: (navigator.doNotTrack === 'yes' || navigator.doNotTrack === '1' || navigator.msDoNotTrack === '1') ? 1 : 0, - h: screen.height, - w: screen.width, - devicetype: emxAdapter.isMobile() ? 1 : emxAdapter.isConnectedTV() ? 3 : 2, - language: (navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage), - }; - }, - cleanProtocols: (video) => { - if (video.protocols && includes(video.protocols, 7)) { - // not supporting VAST protocol 7 (VAST 4.0); - utils.logWarn(BIDDER_CODE + ': VAST 4.0 is currently not supported. This protocol has been filtered out of the request.'); - video.protocols = video.protocols.filter(protocol => protocol !== 7); - } - return video; - }, - outstreamRender: (bid) => { - bid.renderer.push(function () { - let params = (bid && bid.params && bid.params[0] && bid.params[0].video) ? bid.params[0].video : {}; - window.emxVideoQueue = window.emxVideoQueue || []; - window.queueEmxVideo({ - id: bid.adUnitCode, - adsResponses: bid.vastXml, - options: params - }); - if (window.emxVideoReady && window.videojs) { - window.emxVideoReady(); - } - }); - }, - createRenderer: (bid, rendererParams) => { - const renderer = Renderer.install({ - id: rendererParams.id, - url: RENDERER_URL, - loaded: false - }); - try { - renderer.setRender(emxAdapter.outstreamRender); - } catch (err) { - utils.logWarn('Prebid Error calling setRender on renderer', err); - } - - return renderer; - }, - buildVideo: (bid) => { - let videoObj = Object.assign(bid.mediaTypes.video, bid.params.video); - - if (utils.isArray(bid.mediaTypes.video.playerSize[0])) { - videoObj['w'] = bid.mediaTypes.video.playerSize[0][0]; - videoObj['h'] = bid.mediaTypes.video.playerSize[0][1]; - } else { - videoObj['w'] = bid.mediaTypes.video.playerSize[0]; - videoObj['h'] = bid.mediaTypes.video.playerSize[1]; - } - return emxAdapter.cleanProtocols(videoObj); - }, - parseResponse: (bidResponseAdm) => { - try { - return decodeURIComponent(bidResponseAdm.replace(/%(?![0-9][0-9a-fA-F]+)/g, '%25')); - } catch (err) { - utils.logError('emx_digitalBidAdapter', 'error', err); - } - }, - getReferrer: () => { - try { - return window.top.document.referrer; - } catch (err) { - return document.referrer; - } - }, - getSite: (refInfo) => { - let url = utils.parseUrl(refInfo.referer); - return { - domain: url.hostname, - page: refInfo.referer, - ref: emxAdapter.getReferrer() - } - }, - getGdpr: (bidRequests, emxData) => { - if (bidRequests.gdprConsent) { - emxData.regs = { - ext: { - gdpr: bidRequests.gdprConsent.gdprApplies === true ? 1 : 0 - } - }; - } - if (bidRequests.gdprConsent && bidRequests.gdprConsent.gdprApplies) { - emxData.user = { - ext: { - consent: bidRequests.gdprConsent.consentString - } - }; - } - - return emxData; - }, - getSupplyChain: (bidderRequest, emxData) => { - if (bidderRequest.bids[0] && bidderRequest.bids[0].schain) { - emxData.source = { - ext: { - schain: bidderRequest.bids[0].schain - } - }; - } - - return emxData; - } -}; - -export const spec = { - code: BIDDER_CODE, - gvlid: 183, - supportedMediaTypes: [BANNER, VIDEO], - isBidRequestValid: function (bid) { - if (!bid || !bid.params) { - utils.logWarn(BIDDER_CODE + ': Missing bid or bid params.'); - return false; - } - - if (bid.bidder !== BIDDER_CODE) { - utils.logWarn(BIDDER_CODE + ': Must use "emx_digital" as bidder code.'); - return false; - } - - if (!bid.params.tagid || !utils.isStr(bid.params.tagid)) { - utils.logWarn(BIDDER_CODE + ': Missing tagid param or tagid present and not type String.'); - return false; - } - - if (bid.mediaTypes && bid.mediaTypes.banner) { - let sizes; - bid.mediaTypes.banner.sizes ? sizes = bid.mediaTypes.banner.sizes : sizes = bid.sizes; - if (!emxAdapter.validateSizes(sizes)) { - utils.logWarn(BIDDER_CODE + ': Missing sizes in bid'); - return false; - } - } else if (bid.mediaTypes && bid.mediaTypes.video) { - if (!emxAdapter.checkVideoContext(bid)) { - utils.logWarn(BIDDER_CODE + ': Missing video context: instream or outstream'); - return false; - } - - if (!bid.mediaTypes.video.playerSize) { - utils.logWarn(BIDDER_CODE + ': Missing video playerSize'); - return false; - } - } - - return true; - }, - buildRequests: function (validBidRequests, bidderRequest) { - const emxImps = []; - const timeout = bidderRequest.timeout || ''; - const timestamp = Date.now(); - const url = 'https://' + ENDPOINT + ('?t=' + timeout + '&ts=' + timestamp + '&src=pbjs'); - const secure = location.protocol.indexOf('https') > -1 ? 1 : 0; - const device = emxAdapter.getDevice(); - const site = emxAdapter.getSite(bidderRequest.refererInfo); - - utils._each(validBidRequests, function (bid) { - let tagid = utils.getBidIdParameter('tagid', bid.params); - let bidfloor = parseFloat(utils.getBidIdParameter('bidfloor', bid.params)) || 0; - let isVideo = !!bid.mediaTypes.video; - let data = { - id: bid.bidId, - tid: bid.transactionId, - tagid, - secure - }; - let typeSpecifics = isVideo ? { video: emxAdapter.buildVideo(bid) } : { banner: emxAdapter.buildBanner(bid) }; - let bidfloorObj = bidfloor > 0 ? { bidfloor, bidfloorcur: DEFAULT_CUR } : {}; - let emxBid = Object.assign(data, typeSpecifics, bidfloorObj); - - emxImps.push(emxBid); - }); - - let emxData = { - id: bidderRequest.auctionId, - imp: emxImps, - device, - site, - cur: DEFAULT_CUR, - version: ADAPTER_VERSION - }; - - emxData = emxAdapter.getGdpr(bidderRequest, Object.assign({}, emxData)); - emxData = emxAdapter.getSupplyChain(bidderRequest, Object.assign({}, emxData)); - if (bidderRequest && bidderRequest.uspConsent) { - emxData.us_privacy = bidderRequest.uspConsent - } - return { - method: 'POST', - url, - data: JSON.stringify(emxData), - options: { - withCredentials: true - }, - bidderRequest - }; - }, - interpretResponse: function (serverResponse, bidRequest) { - let emxBidResponses = []; - let response = serverResponse.body || {}; - if (response.seatbid && response.seatbid.length > 0 && response.seatbid[0].bid) { - response.seatbid.forEach(function (emxBid) { - emxBid = emxBid.bid[0]; - let isVideo = false; - let adm = emxAdapter.parseResponse(emxBid.adm) || ''; - let bidResponse = { - requestId: emxBid.id, - cpm: emxBid.price, - width: emxBid.w, - height: emxBid.h, - creativeId: emxBid.crid || emxBid.id, - dealId: emxBid.dealid || null, - currency: 'USD', - netRevenue: true, - ttl: emxBid.ttl, - ad: adm - }; - if (emxBid.adm && emxBid.adm.indexOf(' -1) { - isVideo = true; - bidResponse = emxAdapter.formatVideoResponse(bidResponse, Object.assign({}, emxBid), bidRequest); - } - bidResponse.mediaType = (isVideo ? VIDEO : BANNER); - emxBidResponses.push(bidResponse); - }); - } - return emxBidResponses; - }, - getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent) { - const syncs = []; - if (syncOptions.iframeEnabled) { - let url = 'https://biddr.brealtime.com/check.html'; - if (gdprConsent && typeof gdprConsent.consentString === 'string') { - // add 'gdpr' only if 'gdprApplies' is defined - if (typeof gdprConsent.gdprApplies === 'boolean') { - url += `?gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - url += `?gdpr_consent=${gdprConsent.consentString}`; - } - } - syncs.push({ - type: 'iframe', - url: url - }); - } - return syncs; - } -}; -registerBidder(spec); diff --git a/modules/emx_digitalBidAdapter.md b/modules/emx_digitalBidAdapter.md deleted file mode 100644 index 03ba554c5ad..00000000000 --- a/modules/emx_digitalBidAdapter.md +++ /dev/null @@ -1,62 +0,0 @@ -# Overview - -``` -Module Name: EMX Digital Adapter -Module Type: Bidder Adapter -Maintainer: git@emxdigital.com -``` - -# Description - -The EMX Digital adapter provides publishers with access to the EMX Marketplace. The adapter is GDPR compliant. Please note that the adapter supports Banner and Video (Instream & Outstream) media types. - -Note: The EMX Digital adapter requires approval and implementation guidelines from the EMX team, including existing publishers that work with EMX Digital. Please reach out to your account manager or prebid@emxdigital.com for more information. - -The bidder code should be ```emx_digital``` -The params used by the bidder are : -```tagid``` - string (mandatory) -```bidfloor``` - string (optional) - -# Test Parameters -``` -var adUnits = [{ - code: 'banner-div', - mediaTypes: { - banner: { - sizes: [ - [300, 250], [300, 600] - } - }, - bids: [ - { - bidder: 'emx_digital', - params: { - tagid: '25251', - } - }] -}]; -``` - -# Video Example -``` -var adUnits = [{ - code: 'video-div', - mediaTypes: { - video: { - context: 'instream', // also applicable for 'outstream' - playerSize: [640, 480] - } - }, - bids: [ - { - bidder: 'emx_digital', - params: { - tagid: '25251', - video: { - skippable: true, - playback_methods: ['auto_play_sound_off'] - } - } - }] -}]; -``` diff --git a/modules/engageyaBidAdapter.js b/modules/engageyaBidAdapter.js deleted file mode 100644 index 321b3287c2b..00000000000 --- a/modules/engageyaBidAdapter.js +++ /dev/null @@ -1,133 +0,0 @@ -import { - BANNER, - NATIVE -} from '../src/mediaTypes.js'; - -const { - registerBidder -} = require('../src/adapters/bidderFactory.js'); -const BIDDER_CODE = 'engageya'; -const ENDPOINT_URL = 'https://recs.engageya.com/rec-api/getrecs.json'; -const ENDPOINT_METHOD = 'GET'; - -function getPageUrl() { - var pUrl = window.location.href; - if (isInIframe()) { - pUrl = document.referrer ? document.referrer : pUrl; - } - pUrl = encodeURIComponent(pUrl); - return pUrl; -} - -function isInIframe() { - try { - var isInIframe = (window.self !== window.top); - } catch (e) { - isInIframe = true; - } - return isInIframe; -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, NATIVE], - isBidRequestValid: function(bid) { - return bid && bid.params && bid.params.hasOwnProperty('widgetId') && bid.params.hasOwnProperty('websiteId') && !isNaN(bid.params.widgetId) && !isNaN(bid.params.websiteId); - }, - - buildRequests: function(validBidRequests, bidderRequest) { - var bidRequests = []; - if (validBidRequests && validBidRequests.length > 0) { - validBidRequests.forEach(function(bidRequest) { - if (bidRequest.params) { - var mediaType = bidRequest.hasOwnProperty('nativeParams') ? 1 : 2; - var imageWidth = -1; - var imageHeight = -1; - if (bidRequest.sizes && bidRequest.sizes.length > 0) { - imageWidth = bidRequest.sizes[0][0]; - imageHeight = bidRequest.sizes[0][1]; - } else if (bidRequest.nativeParams && bidRequest.nativeParams.image && bidRequest.nativeParams.image.sizes) { - imageWidth = bidRequest.nativeParams.image.sizes[0]; - imageHeight = bidRequest.nativeParams.image.sizes[1]; - } - - var widgetId = bidRequest.params.widgetId; - var websiteId = bidRequest.params.websiteId; - var pageUrl = (bidRequest.params.pageUrl && bidRequest.params.pageUrl != '[PAGE_URL]') ? bidRequest.params.pageUrl : ''; - if (!pageUrl) { - pageUrl = (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer) ? bidderRequest.refererInfo.referer : getPageUrl(); - } - var bidId = bidRequest.bidId; - var finalUrl = ENDPOINT_URL + '?pubid=0&webid=' + websiteId + '&wid=' + widgetId + '&url=' + pageUrl + '&ireqid=' + bidId + '&pbtpid=' + mediaType + '&imw=' + imageWidth + '&imh=' + imageHeight; - if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprApplies && bidderRequest.consentString) { - finalUrl += '&is_gdpr=1&gdpr_consent=' + bidderRequest.consentString; - } - bidRequests.push({ - url: finalUrl, - method: ENDPOINT_METHOD, - data: '' - }); - } - }); - } - - return bidRequests; - }, - - interpretResponse: function(serverResponse, bidRequest) { - const bidResponses = []; - if (serverResponse.body && serverResponse.body.recs && serverResponse.body.recs.length > 0) { - var response = serverResponse.body; - var isNative = response.pbtypeId == 1; - response.recs.forEach(function(rec) { - var imageSrc = rec.thumbnail_path.indexOf('http') == -1 ? 'https:' + rec.thumbnail_path : rec.thumbnail_path; - if (isNative) { - bidResponses.push({ - requestId: response.ireqId, - cpm: rec.ecpm, - width: response.imageWidth, - height: response.imageHeight, - creativeId: rec.postId, - currency: 'USD', - netRevenue: false, - ttl: 360, - native: { - title: rec.title, - body: '', - image: { - url: imageSrc, - width: response.imageWidth, - height: response.imageHeight - }, - privacyLink: '', - clickUrl: rec.clickUrl, - displayUrl: rec.url, - cta: '', - sponsoredBy: rec.displayName, - impressionTrackers: [], - }, - }); - } else { - // var htmlTag = ""; - var htmlTag = '
'; - var tag = rec.tag ? rec.tag : htmlTag; - bidResponses.push({ - requestId: response.ireqId, - cpm: rec.ecpm, - width: response.imageWidth, - height: response.imageHeight, - creativeId: rec.postId, - currency: 'USD', - netRevenue: false, - ttl: 360, - ad: tag, - }); - } - }); - } - - return bidResponses; - } -}; - -registerBidder(spec); diff --git a/modules/engageyaBidAdapter.md b/modules/engageyaBidAdapter.md deleted file mode 100644 index 541ba548eeb..00000000000 --- a/modules/engageyaBidAdapter.md +++ /dev/null @@ -1,68 +0,0 @@ -# Overview - -``` -Module Name: Engageya's Bidder Adapter -Module Type: Bidder Adapter -Maintainer: reem@engageya.com -``` - -# Description - -Module that connects to Engageya's demand sources - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 250]], // a display size - } - }, - bids: [ - { - bidder: "engageya", - params: { - widgetId: '', - websiteId: '', - pageUrl:'[PAGE_URL]' - } - } - ] - },{ - code: 'test-div', - mediaTypes: { - native: { - image: { - required: true, - sizes: [236, 202] - }, - title: { - required: true, - len: 80 - }, - sponsoredBy: { - required: true - }, - clickUrl: { - required: true - }, - body: { - required: true - } - } - }, - bids: [ - { - bidder: "engageya", - params: { - widgetId: '', - websiteId: '', - pageUrl:'[PAGE_URL]' - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/enrichmentFpdModule.js b/modules/enrichmentFpdModule.js deleted file mode 100644 index a1d815917e0..00000000000 --- a/modules/enrichmentFpdModule.js +++ /dev/null @@ -1,107 +0,0 @@ -/** - * This module sets default values and validates ortb2 first part data - * @module modules/firstPartyData - */ -import * as utils from '../src/utils.js'; -import { submodule } from '../src/hook.js' -import { getRefererInfo } from '../src/refererDetection.js' - -let ortb2 = {}; -let win = (window === window.top) ? window : window.top; - -/** - * Checks for referer and if exists merges into ortb2 global data - */ -function setReferer() { - if (getRefererInfo().referer) utils.mergeDeep(ortb2, { site: { ref: getRefererInfo().referer } }); -} - -/** - * Checks for canonical url and if exists merges into ortb2 global data - */ -function setPage() { - if (getRefererInfo().canonicalUrl) utils.mergeDeep(ortb2, { site: { page: getRefererInfo().canonicalUrl } }); -} - -/** - * Checks for canonical url and if exists retrieves domain and merges into ortb2 global data - */ -function setDomain() { - let parseDomain = function(url) { - if (!url || typeof url !== 'string' || url.length === 0) return; - - var match = url.match(/^(?:https?:\/\/)?(?:www\.)?(.*?(?=(\?|\#|\/|$)))/i); - - return match && match[1]; - }; - - let domain = parseDomain(getRefererInfo().canonicalUrl) - - if (domain) utils.mergeDeep(ortb2, { site: { domain: domain } }); -} - -/** - * Checks for screen/device width and height and sets dimensions - */ -function setDimensions() { - let width; - let height; - - try { - width = win.innerWidth || win.document.documentElement.clientWidth || win.document.body.clientWidth; - height = win.innerHeight || win.document.documentElement.clientHeight || win.document.body.clientHeight; - } catch (e) { - width = window.innerWidth || window.document.documentElement.clientWidth || window.document.body.clientWidth; - height = window.innerHeight || window.document.documentElement.clientHeight || window.document.body.clientHeight; - } - - utils.mergeDeep(ortb2, { device: { w: width, h: height } }); -} - -/** - * Scans page for meta keywords, and if exists, merges into site.keywords - */ -function setKeywords() { - let keywords; - - try { - keywords = win.document.querySelector("meta[name='keywords']"); - } catch (e) { - keywords = window.document.querySelector("meta[name='keywords']"); - } - - if (keywords && keywords.content) utils.mergeDeep(ortb2, { site: { keywords: keywords.content.replace(/\s/g, '') } }); -} - -/** - * Resets modules global ortb2 data - */ -const resetOrtb2 = () => { ortb2 = {} }; - -function runEnrichments() { - setReferer(); - setPage(); - setDomain(); - setDimensions(); - setKeywords(); - - return ortb2; -} - -/** - * Sets default values to ortb2 if exists and adds currency and ortb2 setConfig callbacks on init - */ -export function initSubmodule(fpdConf, data) { - resetOrtb2(); - - return (!fpdConf.skipEnrichments) ? utils.mergeDeep(runEnrichments(), data) : data; -} - -/** @type {firstPartyDataSubmodule} */ -export const enrichmentsSubmodule = { - name: 'enrichments', - queue: 2, - init: initSubmodule -} - -submodule('firstPartyData', enrichmentsSubmodule) diff --git a/modules/envivoBidAdapter.js b/modules/envivoBidAdapter.js deleted file mode 100644 index b9c80ffd468..00000000000 --- a/modules/envivoBidAdapter.js +++ /dev/null @@ -1,129 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { config } from '../src/config.js'; -import * as utils from '../src/utils.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import { ajax } from '../src/ajax.js'; -import {Renderer} from '../src/Renderer.js'; - -const SUPPORTED_AD_TYPES = [BANNER, VIDEO]; -const BIDDER_CODE = 'envivo'; -const DOMAIN = 'https://ad.nvivo.tv/'; -const RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js'; - -function isBidRequestValid(bid) { - return (typeof bid.params !== 'undefined' && parseInt(utils.getValue(bid.params, 'publisherId')) > 0); -} - -function buildRequests(validBidRequests) { - return { - method: 'POST', - url: DOMAIN + 'ads/www/admin/plugins/Prebid/getAd.php', - options: { - withCredentials: false, - crossOrigin: true - }, - data: validBidRequests, - }; -} - -function interpretResponse(serverResponse, request) { - const response = serverResponse.body; - const bidResponses = []; - var bidRequestResponses = []; - - utils._each(response, function(bidAd) { - bidAd.adResponse = { - content: bidAd.vastXml, - height: bidAd.height, - width: bidAd.width - }; - bidAd.ttl = config.getConfig('_bidderTimeout') - bidAd.renderer = bidAd.context === 'outstream' ? createRenderer(bidAd, { - id: bidAd.adUnitCode, - url: RENDERER_URL - }, bidAd.adUnitCode) : undefined; - bidResponses.push(bidAd); - }); - - bidRequestResponses.push({ - function: 'saveResponses', - request: request, - response: bidResponses - }); - sendResponseToServer(bidRequestResponses); - return bidResponses; -} - -function outstreamRender(bidAd) { - bidAd.renderer.push(() => { - window.ANOutstreamVideo.renderAd({ - sizes: [bidAd.width, bidAd.height], - width: bidAd.width, - height: bidAd.height, - targetId: bidAd.adUnitCode, - adResponse: bidAd.adResponse, - rendererOptions: { - showVolume: false, - allowFullscreen: false - } - }); - }); -} - -function createRenderer(bidAd, rendererParams, adUnitCode) { - const renderer = Renderer.install({ - id: rendererParams.id, - url: rendererParams.url, - loaded: false, - config: {'player_height': bidAd.height, 'player_width': bidAd.width}, - adUnitCode - }); - try { - renderer.setRender(outstreamRender); - } catch (err) { - utils.logWarn('Prebid Error calling setRender on renderer', err); - } - return renderer; -} - -function onBidWon(bid) { - let wonBids = []; - wonBids.push(bid); - wonBids[0].function = 'onBidWon'; - sendResponseToServer(wonBids); -} - -function onTimeout(details) { - details.unshift({ 'function': 'onTimeout' }); - sendResponseToServer(details); -} - -function sendResponseToServer(data) { - ajax(DOMAIN + 'ads/www/admin/plugins/Prebid/tracking/track.php', null, JSON.stringify(data), { - withCredentials: false, - method: 'POST', - crossOrigin: true - }); -} - -function getUserSyncs(syncOptions) { - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: DOMAIN + 'ads/www/admin/plugins/Prebid/userSync.php' - }]; - } -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: SUPPORTED_AD_TYPES, - isBidRequestValid, - buildRequests, - interpretResponse, - getUserSyncs, - onBidWon, - onTimeout -}; - -registerBidder(spec); diff --git a/modules/envivoBidAdapter.md b/modules/envivoBidAdapter.md deleted file mode 100644 index 3ecc8a251f3..00000000000 --- a/modules/envivoBidAdapter.md +++ /dev/null @@ -1,50 +0,0 @@ -# Overview - -``` -Module Name: envivo Bid Adapter -Module Type: Bidder Adapter -Maintainer : adtech@nvivo.tv -``` - -# Description - -Connects to Envivo Ad Server for bids. - -envivo bid adapter supports Banner and Video. - -# Test Parameters -``` - var adUnits = [ - //bannner object - { - code: 'banner-ad-slot', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [{ - bidder: 'envivo', - params: { - publisherId: 14 - } - }] - - }, - //video object - { - code: 'video-ad-slot', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480], - }, - }, - bids: [{ - bidder: "envivo", - params: { - publisherId: 14 - } - }] - }]; -``` diff --git a/modules/eplanningAnalyticsAdapter.js b/modules/eplanningAnalyticsAdapter.js deleted file mode 100644 index 08db2f2ca9d..00000000000 --- a/modules/eplanningAnalyticsAdapter.js +++ /dev/null @@ -1,131 +0,0 @@ -import {ajax} from '../src/ajax.js'; -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -import * as utils from '../src/utils.js'; - -const CONSTANTS = require('../src/constants.json'); - -const analyticsType = 'endpoint'; -const EPL_HOST = 'https://ads.us.e-planning.net/hba/1/'; - -function auctionEndHandler(args) { - return {auctionId: args.auctionId}; -} - -function auctionInitHandler(args) { - return { - auctionId: args.auctionId, - time: args.timestamp - }; -} - -function bidRequestedHandler(args) { - return { - auctionId: args.auctionId, - time: args.start, - bidder: args.bidderCode, - bids: args.bids.map(function(bid) { - return { - time: bid.startTime, - bidder: bid.bidder, - placementCode: bid.placementCode, - auctionId: bid.auctionId, - sizes: bid.sizes - }; - }), - }; -} - -function bidResponseHandler(args) { - return { - bidder: args.bidder, - size: args.size, - auctionId: args.auctionId, - cpm: args.cpm, - time: args.responseTimestamp, - }; -} - -function bidWonHandler(args) { - return { - auctionId: args.auctionId, - size: args.width + 'x' + args.height, - }; -} - -function bidTimeoutHandler(args) { - return args.map(function(bid) { - return { - bidder: bid.bidder, - auctionId: bid.auctionId - }; - }) -} - -function callHandler(evtype, args) { - let handler = null; - - if (evtype === CONSTANTS.EVENTS.AUCTION_INIT) { - handler = auctionInitHandler; - eplAnalyticsAdapter.context.events = []; - } else if (evtype === CONSTANTS.EVENTS.AUCTION_END) { - handler = auctionEndHandler; - } else if (evtype === CONSTANTS.EVENTS.BID_REQUESTED) { - handler = bidRequestedHandler; - } else if (evtype === CONSTANTS.EVENTS.BID_RESPONSE) { - handler = bidResponseHandler - } else if (evtype === CONSTANTS.EVENTS.BID_TIMEOUT) { - handler = bidTimeoutHandler; - } else if (evtype === CONSTANTS.EVENTS.BID_WON) { - handler = bidWonHandler; - } - - if (handler) { - eplAnalyticsAdapter.context.events.push({ec: evtype, p: handler(args)}); - } -} - -var eplAnalyticsAdapter = Object.assign(adapter( - { - EPL_HOST, - analyticsType - }), -{ - track({eventType, args}) { - if (typeof args !== 'undefined') { - callHandler(eventType, args); - } - - if (eventType === CONSTANTS.EVENTS.AUCTION_END) { - try { - let strjson = JSON.stringify(eplAnalyticsAdapter.context.events); - ajax(eplAnalyticsAdapter.context.host + eplAnalyticsAdapter.context.ci + '?d=' + encodeURIComponent(strjson)); - } catch (err) {} - } - } -} -); - -eplAnalyticsAdapter.originEnableAnalytics = eplAnalyticsAdapter.enableAnalytics; - -eplAnalyticsAdapter.enableAnalytics = function (config) { - if (!config.options.ci) { - utils.logError('Client ID (ci) option is not defined. Analytics won\'t work'); - return; - } - - eplAnalyticsAdapter.context = { - events: [], - host: config.options.host || EPL_HOST, - ci: config.options.ci - }; - - eplAnalyticsAdapter.originEnableAnalytics(config); -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: eplAnalyticsAdapter, - code: 'eplanning' -}); - -export default eplAnalyticsAdapter; diff --git a/modules/eplanningAnalyticsAdapter.md b/modules/eplanningAnalyticsAdapter.md deleted file mode 100644 index 3127b523be0..00000000000 --- a/modules/eplanningAnalyticsAdapter.md +++ /dev/null @@ -1,23 +0,0 @@ -# Overview - -``` -Module Name: E-Planning Analytics Adapter -Module Type: Analytics Adapter -Maintainer: mmartinho@e-planning.net -``` - -# Description - -Analytics adapter for E-Planning. - -# Test Parameters - -``` -{ - provider: 'eplanning', - options : { - host: 'https://ads.us.e-planning.net/hba/1/', // Host (optional) - ci: "123456" // Client ID (required) - } -} -``` diff --git a/modules/eplanningBidAdapter.js b/modules/eplanningBidAdapter.js deleted file mode 100644 index 98a0e290575..00000000000 --- a/modules/eplanningBidAdapter.js +++ /dev/null @@ -1,475 +0,0 @@ -import * as utils from '../src/utils.js'; -import { getGlobal } from '../src/prebidGlobal.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { getStorageManager } from '../src/storageManager.js'; - -export const storage = getStorageManager(); - -const BIDDER_CODE = 'eplanning'; -const rnd = Math.random(); -const DEFAULT_SV = 'ads.us.e-planning.net'; -const DEFAULT_ISV = 'i.e-planning.net'; -const PARAMS = ['ci', 'sv', 't', 'ml', 'sn']; -const DOLLARS = 'USD'; -const NET_REVENUE = true; -const TTL = 120; -const NULL_SIZE = '1x1'; -const FILE = 'file'; -const STORAGE_RENDER_PREFIX = 'pbsr_'; -const STORAGE_VIEW_PREFIX = 'pbvi_'; -const mobileUserAgent = isMobileUserAgent(); -const PRIORITY_ORDER_FOR_MOBILE_SIZES_ASC = ['1x1', '300x50', '320x50', '300x250']; -const PRIORITY_ORDER_FOR_DESKTOP_SIZES_ASC = ['1x1', '970x90', '970x250', '160x600', '300x600', '728x90', '300x250']; - -export const spec = { - code: BIDDER_CODE, - - isBidRequestValid: function(bid) { - return Boolean(bid.params.ci) || Boolean(bid.params.t); - }, - - buildRequests: function(bidRequests, bidderRequest) { - const method = 'GET'; - const dfpClientId = '1'; - const sec = 'ROS'; - let url; - let params; - const urlConfig = getUrlConfig(bidRequests); - const pcrs = getCharset(); - const spaces = getSpaces(bidRequests, urlConfig.ml); - const pageUrl = bidderRequest.refererInfo.referer; - const getDomain = (url) => { - let anchor = document.createElement('a'); - anchor.href = url; - return anchor.hostname; - } - if (urlConfig.t) { - url = 'https://' + urlConfig.isv + '/layers/t_pbjs_2.json'; - params = {}; - } else { - url = 'https://' + (urlConfig.sv || DEFAULT_SV) + '/pbjs/1/' + urlConfig.ci + '/' + dfpClientId + '/' + getDomain(pageUrl) + '/' + sec; - const referrerUrl = bidderRequest.refererInfo.referer.reachedTop ? window.top.document.referrer : bidderRequest.refererInfo.referer; - - if (storage.hasLocalStorage()) { - registerViewabilityAllBids(bidRequests); - } - - params = { - rnd: rnd, - e: spaces.str, - ur: pageUrl || FILE, - pbv: '$prebid.version$', - ncb: '1', - vs: spaces.vs - }; - if (pcrs) { - params.crs = pcrs; - } - - if (referrerUrl) { - params.fr = referrerUrl; - } - - if (bidderRequest && bidderRequest.gdprConsent) { - if (typeof bidderRequest.gdprConsent.gdprApplies !== 'undefined') { - params.gdpr = bidderRequest.gdprConsent.gdprApplies ? '1' : '0'; - if (typeof bidderRequest.gdprConsent.consentString !== 'undefined') { - params.gdprcs = bidderRequest.gdprConsent.consentString; - } - } - } - - if (bidderRequest && bidderRequest.uspConsent) { - params.ccpa = bidderRequest.uspConsent; - } - const userIds = (getGlobal()).getUserIds(); - for (var id in userIds) { - params['e_' + id] = (typeof userIds[id] === 'object') ? encodeURIComponent(JSON.stringify(userIds[id])) : encodeURIComponent(userIds[id]); - } - } - - return { - method: method, - url: url, - data: params, - adUnitToBidId: spaces.map, - }; - }, - interpretResponse: function(serverResponse, request) { - const response = serverResponse.body; - let bidResponses = []; - - if (response && !utils.isEmpty(response.sp)) { - response.sp.forEach(space => { - if (!utils.isEmpty(space.a)) { - space.a.forEach(ad => { - const bidResponse = { - requestId: request.adUnitToBidId[space.k], - cpm: ad.pr, - width: ad.w, - height: ad.h, - ad: ad.adm, - ttl: TTL, - creativeId: ad.crid, - netRevenue: NET_REVENUE, - currency: DOLLARS, - }; - bidResponses.push(bidResponse); - }); - } - }); - } - - return bidResponses; - }, - getUserSyncs: function(syncOptions, serverResponses) { - const syncs = []; - const response = !utils.isEmpty(serverResponses) && serverResponses[0].body; - - if (response && !utils.isEmpty(response.cs)) { - const responseSyncs = response.cs; - responseSyncs.forEach(sync => { - if (typeof sync === 'string' && syncOptions.pixelEnabled) { - syncs.push({ - type: 'image', - url: sync, - }); - } else if (typeof sync === 'object' && sync.ifr && syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: sync.u, - }) - } - }); - } - - return syncs; - }, -} - -function getUserAgent() { - return window.navigator.userAgent; -} -function getInnerWidth() { - return utils.getWindowSelf().innerWidth; -} -function isMobileUserAgent() { - return getUserAgent().match(/(mobile)|(ip(hone|ad))|(android)|(blackberry)|(nokia)|(phone)|(opera\smini)/i); -} -function isMobileDevice() { - return (getInnerWidth() <= 1024) || window.orientation || mobileUserAgent; -} -function getUrlConfig(bidRequests) { - if (isTestRequest(bidRequests)) { - return getTestConfig(bidRequests.filter(br => br.params.t)); - } - - let config = {}; - bidRequests.forEach(bid => { - PARAMS.forEach(param => { - if (bid.params[param] && !config[param]) { - config[param] = bid.params[param]; - } - }); - }); - - return config; -} -function isTestRequest(bidRequests) { - for (let i = 0; i < bidRequests.length; i++) { - if (bidRequests[i].params.t) { - return true; - } - } - return false; -} -function getTestConfig(bidRequests) { - let isv; - bidRequests.forEach(br => isv = isv || br.params.isv); - return { - t: true, - isv: (isv || DEFAULT_ISV) - }; -} - -function compareSizesByPriority(size1, size2) { - var priorityOrderForSizesAsc = isMobileDevice() ? PRIORITY_ORDER_FOR_MOBILE_SIZES_ASC : PRIORITY_ORDER_FOR_DESKTOP_SIZES_ASC; - var index1 = priorityOrderForSizesAsc.indexOf(size1); - var index2 = priorityOrderForSizesAsc.indexOf(size2); - if (index1 > -1) { - if (index2 > -1) { - return (index1 < index2) ? 1 : -1; - } else { - return -1; - } - } else { - return (index2 > -1) ? 1 : 0; - } -} - -function getSizesSortedByPriority(sizes) { - return utils.parseSizesInput(sizes).sort(compareSizesByPriority); -} - -function getSize(bid, first) { - var arraySizes = bid.sizes && bid.sizes.length ? getSizesSortedByPriority(bid.sizes) : []; - if (arraySizes.length) { - return first ? arraySizes[0] : arraySizes.join(','); - } else { - return NULL_SIZE; - } -} - -function getSpacesStruct(bids) { - let e = {}; - bids.forEach(bid => { - let size = getSize(bid, true); - e[size] = e[size] ? e[size] : []; - e[size].push(bid); - }); - - return e; -} - -function cleanName(name) { - return name.replace(/_|\.|-|\//g, '').replace(/\)\(|\(|\)|:/g, '_').replace(/^_+|_+$/g, ''); -} - -function getSpaces(bidRequests, ml) { - let spacesStruct = getSpacesStruct(bidRequests); - let es = {str: '', vs: '', map: {}}; - es.str = Object.keys(spacesStruct).map(size => spacesStruct[size].map((bid, i) => { - es.vs += getVs(bid); - - let name; - if (ml) { - name = cleanName(bid.adUnitCode); - } else { - name = (bid.params && bid.params.sn) || (getSize(bid, true) + '_' + i); - } - - es.map[name] = bid.bidId; - return name + ':' + getSize(bid); - }).join('+')).join('+'); - return es; -} - -function getVs(bid) { - let s; - let vs = ''; - if (storage.hasLocalStorage()) { - s = getViewabilityData(bid); - vs += s.render >= 4 ? s.ratio.toString(16) : 'F'; - } else { - vs += 'F'; - } - return vs; -} - -function getViewabilityData(bid) { - let r = storage.getDataFromLocalStorage(STORAGE_RENDER_PREFIX + bid.adUnitCode) || 0; - let v = storage.getDataFromLocalStorage(STORAGE_VIEW_PREFIX + bid.adUnitCode) || 0; - let ratio = r > 0 ? (v / r) : 0; - return { - render: r, - ratio: window.parseInt(ratio * 10, 10) - }; -} - -function getCharset() { - try { - return window.top.document.charset || window.top.document.characterSet; - } catch (e) { - return document.charset || document.characterSet; - } -} - -function waitForElementsPresent(elements) { - const observer = new MutationObserver(function (mutationList, observer) { - if (mutationList && Array.isArray(mutationList)) { - mutationList.forEach(mr => { - if (mr && mr.addedNodes && Array.isArray(mr.addedNodes)) { - mr.addedNodes.forEach(ad => { - let index = elements.indexOf(ad.id); - if (index >= 0) { - registerViewability(ad); - elements.splice(index, 1); - if (!elements.length) { - observer.disconnect(); - } - } - }); - } - }); - } - }); - document.addEventListener('DOMContentLoaded', function (event) { - var config = { - childList: true, - subtree: true, - characterData: true - }; - observer.observe(document.body, config); - }); -} - -function registerViewability(div) { - visibilityHandler({ - name: div.id, - div: div - }); -} - -function registerViewabilityAllBids(bids) { - let elementsNotPresent = []; - bids.forEach(bid => { - let div = document.getElementById(bid.adUnitCode); - if (div) { - registerViewability(div); - } else { - elementsNotPresent.push(bid.adUnitCode); - } - }); - if (elementsNotPresent.length) { - waitForElementsPresent(elementsNotPresent); - } -} - -function getViewabilityTracker() { - let TIME_PARTITIONS = 5; - let VIEWABILITY_TIME = 1000; - let VIEWABILITY_MIN_RATIO = 0.5; - let publicApi; - let context; - - function segmentIsOutsideTheVisibleRange(visibleRangeEnd, p1, p2) { - return p1 > visibleRangeEnd || p2 < 0; - } - - function segmentBeginsBeforeTheVisibleRange(p1) { - return p1 < 0; - } - - function segmentEndsAfterTheVisibleRange(visibleRangeEnd, p2) { - return p2 < visibleRangeEnd; - } - - function axialVisibilityRatio(visibleRangeEnd, p1, p2) { - let visibilityRatio = 0; - if (!segmentIsOutsideTheVisibleRange(visibleRangeEnd, p1, p2)) { - if (segmentBeginsBeforeTheVisibleRange(p1)) { - visibilityRatio = p2 / (p2 - p1); - } else { - visibilityRatio = segmentEndsAfterTheVisibleRange(visibleRangeEnd, p2) ? 1 : (visibleRangeEnd - p1) / (p2 - p1); - } - } - return visibilityRatio; - } - - function isNotHiddenByNonFriendlyIframe() { - try { return (window === window.top) || window.frameElement; } catch (e) {} - } - - function defineContext(e) { - try { - context = e && window.document.body.contains(e) ? window : (window.top.document.body.contains(e) ? top : undefined); - } catch (err) {} - return context; - } - - function getContext(e) { - return context; - } - - function verticalVisibilityRatio(position) { - return axialVisibilityRatio(getContext().innerHeight, position.top, position.bottom); - } - - function horizontalVisibilityRatio(position) { - return axialVisibilityRatio(getContext().innerWidth, position.left, position.right); - } - - function itIsNotHiddenByBannerAreaPosition(e) { - let position = e.getBoundingClientRect(); - return (verticalVisibilityRatio(position) * horizontalVisibilityRatio(position)) > VIEWABILITY_MIN_RATIO; - } - - function itIsNotHiddenByDisplayStyleCascade(e) { - return e.offsetHeight > 0 && e.offsetWidth > 0; - } - - function itIsNotHiddenByOpacityStyleCascade(e) { - let s = e.style; - let p = e.parentNode; - return !(s && parseFloat(s.opacity) === 0) && (!p || itIsNotHiddenByOpacityStyleCascade(p)); - } - - function itIsNotHiddenByVisibilityStyleCascade(e) { - return getContext().getComputedStyle(e).visibility !== 'hidden'; - } - - function itIsNotHiddenByTabFocus() { - try { return getContext().top.document.hasFocus(); } catch (e) {} - } - - function isDefined(e) { - return (e !== null) && (typeof e !== 'undefined'); - } - - function itIsNotHiddenByOrphanBranch() { - return isDefined(getContext()); - } - - function isContextInAnIframe() { - return isDefined(getContext().frameElement); - } - - function processIntervalVisibilityStatus(elapsedVisibleIntervals, element, callback) { - let visibleIntervals = isVisible(element) ? (elapsedVisibleIntervals + 1) : 0; - if (visibleIntervals === TIME_PARTITIONS) { - callback(); - } else { - setTimeout(processIntervalVisibilityStatus.bind(this, visibleIntervals, element, callback), VIEWABILITY_TIME / TIME_PARTITIONS); - } - } - - function isVisible(element) { - defineContext(element); - return isNotHiddenByNonFriendlyIframe() && - itIsNotHiddenByOrphanBranch() && - itIsNotHiddenByTabFocus() && - itIsNotHiddenByDisplayStyleCascade(element) && - itIsNotHiddenByVisibilityStyleCascade(element) && - itIsNotHiddenByOpacityStyleCascade(element) && - itIsNotHiddenByBannerAreaPosition(element) && - (!isContextInAnIframe() || isVisible(getContext().frameElement)); - } - - publicApi = { - isVisible: isVisible, - onView: processIntervalVisibilityStatus.bind(this, 0) - }; - - return publicApi; -}; - -function visibilityHandler(obj) { - if (obj.div) { - registerAuction(STORAGE_RENDER_PREFIX + obj.name); - getViewabilityTracker().onView(obj.div, registerAuction.bind(undefined, STORAGE_VIEW_PREFIX + obj.name)); - } -} - -function registerAuction(storageID) { - let value; - try { - value = storage.getDataFromLocalStorage(storageID); - value = value ? window.parseInt(value, 10) + 1 : 1; - storage.setDataInLocalStorage(storageID, value); - } catch (exc) { - return false; - } - - return true; -} -registerBidder(spec); diff --git a/modules/eplanningBidAdapter.md b/modules/eplanningBidAdapter.md deleted file mode 100644 index b6cfbb535b6..00000000000 --- a/modules/eplanningBidAdapter.md +++ /dev/null @@ -1,25 +0,0 @@ -# Overview - -``` -Module Name: E-Planning Bid Adapter -Module Type: Bidder Adapter -Maintainer: ainsua@e-planning.net -``` - -# Description - -Connects to E-Planning exchange for bids. - -# Test Parameters -``` -var adUnits = [{ - code: 'div-gpt-ad-1460505748561-0', - sizes: [[300, 250]], - bids: [{ - bidder: 'eplanning', - params: { - t: 1 - } - }] -}]; -``` diff --git a/modules/etargetBidAdapter.js b/modules/etargetBidAdapter.js deleted file mode 100644 index 42c991a17a4..00000000000 --- a/modules/etargetBidAdapter.js +++ /dev/null @@ -1,126 +0,0 @@ -'use strict'; - -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'etarget'; -const countryMap = { - 1: 'sk', - 2: 'cz', - 3: 'hu', - 4: 'ro', - 5: 'rs', - 6: 'bg', - 7: 'pl', - 8: 'hr', - 9: 'at', - 10: 'co', - 11: 'de', - 255: 'en' -} -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [ BANNER, VIDEO ], - isBidRequestValid: function (bid) { - return !!(bid.params.refid && bid.params.country); - }, - buildRequests: function (validBidRequests, bidderRequest) { - var i, l, bid, reqParams, netRevenue, gdprObject; - var request = []; - var bids = JSON.parse(JSON.stringify(validBidRequests)); - var lastCountry = 'sk'; - for (i = 0, l = bids.length; i < l; i++) { - bid = bids[i]; - if (countryMap[bid.params.country]) { - lastCountry = countryMap[bid.params.country]; - } - reqParams = bid.params; - reqParams.transactionId = bid.transactionId; - request.push(formRequestUrl(reqParams)); - } - - request.unshift('https://' + lastCountry + '.search.etargetnet.com/hb/?hbget=1'); - netRevenue = 'net'; - - if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) { - gdprObject = { - gdpr: bidderRequest.gdprConsent.gdprApplies, - gdpr_consent: bidderRequest.gdprConsent.consentString - }; - request.push('gdpr=' + gdprObject.gdpr); - request.push('gdpr_consent=' + gdprObject.gdpr_consent); - } - - return { - method: 'POST', - url: request.join('&'), - data: bidderRequest, - bids: validBidRequests, - netRevenue: netRevenue, - bidder: 'etarget', - gdpr: gdprObject - }; - - function formRequestUrl(reqData) { - var key; - var url = []; - - for (key in reqData) { - if (reqData.hasOwnProperty(key) && reqData[key]) { url.push(key, '=', reqData[key], '&'); } - } - - return encodeURIComponent(btoa(url.join('').slice(0, -1))); - } - }, - interpretResponse: function (serverResponse, bidRequest) { - const VALID_RESPONSES = { - banner: 1, - video: 1 - }; - var bidObject, bid, type; - var bidRespones = []; - var bids = bidRequest.bids; - var responses = serverResponse.body; - var data = []; - for (var i = 0; i < responses.length; i++) { - data = responses[i]; - type = data.response === 'banner' ? BANNER : VIDEO; - bid = bids[i]; - if (VALID_RESPONSES[data.response] && (verifySize(data, bid.sizes) || type === VIDEO)) { - bidObject = { - requestId: bid.bidId, - cpm: data.win_bid ? data.win_bid : 0, - width: data.width, - height: data.height, - creativeId: data.creativeId, - currency: data.win_cur, - netRevenue: true, - ttl: 360, - reason: data.reason ? data.reason : 'none', - ad: data.banner, - vastXml: data.vast_content, - vastUrl: data.vast_link, - mediaType: data.response, - transactionId: bid.transactionId - }; - if (bidRequest.gdpr) { - bidObject.gdpr = bidRequest.gdpr.gdpr; - bidObject.gdpr_consent = bidRequest.gdpr.gdpr_consent; - } - bidRespones.push(bidObject); - } - } - return bidRespones; - - function verifySize(adItem, validSizes) { - for (var j = 0, k = validSizes.length; j < k; j++) { - if (adItem.width == validSizes[j][0] && - adItem.height == validSizes[j][1]) { - return true; - } - } - return false; - } - } -}; -registerBidder(spec); diff --git a/modules/etargetBidAdapter.md b/modules/etargetBidAdapter.md deleted file mode 100644 index 1032de2f9a1..00000000000 --- a/modules/etargetBidAdapter.md +++ /dev/null @@ -1,29 +0,0 @@ -# Overview - -Module Name: ETARGET Bidder Adapter -Module Type: Bidder Adapter -Maintainer: info@etarget.sk - -# Description - -Module that connects to ETARGET demand sources to fetch bids. -Banner and video formats are supported. - -# Test Parameters -``` - var adUnits = [ - { - code: 'div-gpt-ad-1460505748561-0', // ID of elemnt where ad will be shown - sizes: [[300, 250], [300, 300], [300, 600], [160, 600]], // a display size - bids: [ - { - bidder: "etarget", - params: { - country: 1, //require // specific to your country {1:'sk',2:'cz',3:'hu',4:'ro',5:'rs',6:'bg',7:'pl',8:'hr',9:'at',11:'de',255:'en'} - refid: '12345' // require // you can create/find this ID in Our portal administration on https://sk.etarget-media.com/partner/ - } - } - ] - } - ]; -``` diff --git a/modules/express.js b/modules/express.js deleted file mode 100644 index f4a76daefdf..00000000000 --- a/modules/express.js +++ /dev/null @@ -1,209 +0,0 @@ - -import * as utils from '../src/utils.js'; - -const MODULE_NAME = 'express'; - -/** - * Express Module - * - * The express module allows the initiation of Prebid.js auctions automatically based on calls such as gpt.defineSlot. - * It works by monkey-patching the gpt methods and overloading their functionality. In order for this module to be - * used gpt must be included in the page, this module must be included in the Prebid.js bundle, and a call to - * pbjs.express() must be made. - * - * @param {Object[]} [adUnits = pbjs.adUnits] - an array of adUnits for express to operate on. - */ -$$PREBID_GLOBAL$$.express = function(adUnits = $$PREBID_GLOBAL$$.adUnits) { - utils.logMessage('loading ' + MODULE_NAME); - - if (adUnits.length === 0) { - utils.logWarn('no valid adUnits found, not loading ' + MODULE_NAME); - } - - // store gpt slots in a more performant hash lookup by elementId (adUnit code) - var gptSlotCache = {}; - // put adUnits in a more performant hash lookup by code. - var adUnitsCache = adUnits.reduce(function (cache, adUnit) { - if (adUnit.code && adUnit.bids) { - cache[adUnit.code] = adUnit; - } else { - utils.logError('misconfigured adUnit', null, adUnit); - } - return cache; - }, {}); - - window.googletag = window.googletag || {}; - window.googletag.cmd = window.googletag.cmd || []; - window.googletag.cmd.push(function () { - // verify all necessary gpt functions exist - var gpt = window.googletag; - var pads = gpt.pubads; - if (!gpt.display || !gpt.enableServices || typeof pads !== 'function' || !pads().refresh || !pads().disableInitialLoad || !pads().getSlots || !pads().enableSingleRequest) { - utils.logError('could not bind to gpt googletag api'); - return; - } - utils.logMessage('running'); - - // function to convert google tag slot sizes to [[w,h],...] - function mapGptSlotSizes(aGPTSlotSizes) { - var aSlotSizes = []; - for (var i = 0; i < aGPTSlotSizes.length; i++) { - try { - aSlotSizes.push([aGPTSlotSizes[i].getWidth(), aGPTSlotSizes[i].getHeight()]); - } catch (e) { - utils.logWarn('slot size ' + aGPTSlotSizes[i].toString() + ' not supported by' + MODULE_NAME); - } - } - return aSlotSizes; - } - - // a helper function to verify slots or get slots if not present - function defaultSlots(slots) { - return Array.isArray(slots) - ? slots.slice() - // eslint-disable-next-line no-undef - : googletag.pubads().getSlots().slice(); - } - - // maps gpt slots to adUnits, matches are copied to new array and removed from passed array. - function pickAdUnits(gptSlots) { - var adUnits = []; - // traverse backwards (since gptSlots is mutated) to find adUnits in cache and remove non-mapped slots - for (var i = gptSlots.length - 1; i > -1; i--) { - const gptSlot = gptSlots[i]; - const elemId = gptSlot.getSlotElementId(); - const adUnit = adUnitsCache[elemId]; - - if (adUnit) { - gptSlotCache[elemId] = gptSlot; // store by elementId - adUnit.sizes = adUnit.sizes || mapGptSlotSizes(gptSlot.getSizes()); - adUnits.push(adUnit); - gptSlots.splice(i, 1); - } - } - - return adUnits; - } - - // store original gpt functions that will be overridden - var fGptDisplay = gpt.display; - var fGptEnableServices = gpt.enableServices; - var fGptRefresh = pads().refresh; - var fGptDisableInitialLoad = pads().disableInitialLoad; - var fGptEnableSingleRequest = pads().enableSingleRequest; - - // override googletag.enableServices() - // - make sure fGptDisableInitialLoad() has been called so we can - // better control when slots are displayed, then call original - // fGptEnableServices() - gpt.enableServices = function () { - if (!bInitialLoadDisabled) { - fGptDisableInitialLoad.apply(pads()); - } - return fGptEnableServices.apply(gpt, arguments); - }; - - // override googletag.display() - // - call the real fGptDisplay(). this won't initiate auctions because we've disabled initial load - // - define all corresponding rubicon slots - // - if disableInitialLoad() has been called by the pub, done - // - else run an auction and call the real fGptRefresh() to - // initiate the DFP request - gpt.display = function (sElementId) { - utils.logInfo('display:', sElementId); - // call original gpt display() function - fGptDisplay.apply(gpt, arguments); - - // if not SRA mode, get only the gpt slot corresponding to sEementId - var aGptSlots; - if (!bEnabledSRA) { - // eslint-disable-next-line no-undef - aGptSlots = googletag.pubads().getSlots().filter(function (oGptSlot) { - return oGptSlot.getSlotElementId() === sElementId; - }); - } - - aGptSlots = defaultSlots(aGptSlots).filter(function (gptSlot) { - return !gptSlot._displayed; - }); - - aGptSlots.forEach(function (gptSlot) { - gptSlot._displayed = true; - }); - - var adUnits = pickAdUnits(/* mutated: */ aGptSlots); - - if (!bInitialLoadDisabled) { - if (aGptSlots.length) { - fGptRefresh.apply(pads(), [aGptSlots]); - } - - if (adUnits.length) { - $$PREBID_GLOBAL$$.requestBids({ - adUnits: adUnits, - bidsBackHandler: function () { - $$PREBID_GLOBAL$$.setTargetingForGPTAsync(); - fGptRefresh.apply(pads(), [ - adUnits.map(function (adUnit) { - return gptSlotCache[adUnit.code]; - }) - ]); - } - }); - } - } - }; - - // override gpt refresh() function - // - run auctions for provided gpt slots, then initiate ad-server call - pads().refresh = function (aGptSlots, options) { - utils.logInfo('refresh:', aGptSlots); - // get already displayed adUnits from aGptSlots if provided, else all defined gptSlots - aGptSlots = defaultSlots(aGptSlots); - var adUnits = pickAdUnits(/* mutated: */ aGptSlots).filter(function (adUnit) { - return gptSlotCache[adUnit.code]._displayed; - }); - - if (aGptSlots.length) { - fGptRefresh.apply(pads(), [aGptSlots, options]); - } - - if (adUnits.length) { - $$PREBID_GLOBAL$$.requestBids({ - adUnits: adUnits, - bidsBackHandler: function () { - $$PREBID_GLOBAL$$.setTargetingForGPTAsync(); - fGptRefresh.apply(pads(), [ - adUnits.map(function (adUnit) { - return gptSlotCache[adUnit.code]; - }), - options - ]); - } - }); - } - }; - - // override gpt disableInitialLoad function - // Register that initial load was called, meaning calls to display() - // should not initiate an ad-server request. Instead a call to - // refresh() will be needed to iniate the request. - // We will assume the pub is using this the correct way, calling it - // before enableServices() - var bInitialLoadDisabled = false; - pads().disableInitialLoad = function () { - bInitialLoadDisabled = true; - return fGptDisableInitialLoad.apply(window.googletag.pubads(), arguments); - }; - - // override gpt useSingleRequest function - // Register that SRA has been turned on - // We will assume the pub is using this the correct way, calling it - // before enableServices() - var bEnabledSRA = false; - pads().enableSingleRequest = function () { - bEnabledSRA = true; - return fGptEnableSingleRequest.apply(window.googletag.pubads(), arguments); - }; - }); -}; diff --git a/modules/eywamediaBidAdapter.md b/modules/eywamediaBidAdapter.md deleted file mode 100644 index 76b9b032c1b..00000000000 --- a/modules/eywamediaBidAdapter.md +++ /dev/null @@ -1,37 +0,0 @@ -# Overview - -``` -Module Name: Eywamedia Bid Adapter -Module Type: Bidder Adapter -Maintainer: sharath@eywamedia.com -Note: Our ads will only render in mobile and desktop -``` - -# Description - -Connects to Eywamedia Ad Server for bids. - -Eywamedia bid adapter supports Banners. - -# Test Parameters -``` -var adUnits = [ - // Banner adUnit - { - code: 'div-gpt-ad-1460505748561-0', - sizes: [[300, 250], [300,600]], - bids: [{ - bidder: 'eywamedia', - params: { - publisherId: 'f63a2362-5aa4-4829-bbd2-2678ced8b63e', //Required - GUID (may include numbers and characters) - bidFloor: 0.50, // optional - cats: ["iab1-1","iab23-2"], // optional - keywords: ["sports", "cricket"], // optional - lat: 12.33333, // optional - lon: 77.32322, // optional - locn: "country$region$city$zip" // optional - } - }] - } -]; -``` diff --git a/modules/fabrickIdSystem.js b/modules/fabrickIdSystem.js deleted file mode 100644 index bb838788f07..00000000000 --- a/modules/fabrickIdSystem.js +++ /dev/null @@ -1,183 +0,0 @@ -/** - * This module adds neustar's fabrickId to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/fabrickIdSystem - * @requires module:modules/userId - */ - -import * as utils from '../src/utils.js' -import { ajax } from '../src/ajax.js'; -import { submodule } from '../src/hook.js'; -import { getRefererInfo } from '../src/refererDetection.js'; - -/** @type {Submodule} */ -export const fabrickIdSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: 'fabrickId', - - /** - * decode the stored id value for passing to bid requests - * @function decode - * @param {(Object|string)} value - * @returns {(Object|undefined)} - */ - decode(value) { - if (value && value.fabrickId) { - return { 'fabrickId': value.fabrickId }; - } else { - return undefined; - } - }, - - /** - * performs action to obtain id and return a value in the callback's response argument - * @function getId - * @param {SubmoduleConfig} [config] - * @param {ConsentData} - * @param {Object} cacheIdObj - existing id, if any consentData] - * @returns {IdResponse|undefined} - */ - getId(config, consentData, cacheIdObj) { - try { - const configParams = (config && config.params) || {}; - if (window.fabrickMod1) { - window.fabrickMod1(configParams, consentData, cacheIdObj); - } - if (!configParams || !configParams.apiKey || typeof configParams.apiKey !== 'string') { - utils.logError('fabrick submodule requires an apiKey.'); - return; - } - try { - let url = _getBaseUrl(configParams); - let keysArr = Object.keys(configParams); - for (let i in keysArr) { - let k = keysArr[i]; - if (k === 'url' || k === 'refererInfo' || (k.length > 3 && k.substring(0, 3) === 'max')) { - continue; - } - let v = configParams[k]; - if (Array.isArray(v)) { - for (let j in v) { - if (typeof v[j] === 'string' || typeof v[j] === 'number') { - url += `${k}=${v[j]}&`; - } - } - } else if (typeof v === 'string' || typeof v === 'number') { - url += `${k}=${v}&`; - } - } - // pull off the trailing & - url = url.slice(0, -1) - const referer = _getRefererInfo(configParams); - const refs = new Map(); - _setReferrer(refs, referer.referer); - if (referer.stack && referer.stack[0]) { - _setReferrer(refs, referer.stack[0]); - } - _setReferrer(refs, referer.canonicalUrl); - _setReferrer(refs, window.location.href); - - refs.forEach(v => { - url = appendUrl(url, 'r', v, configParams); - }); - - const resp = function (callback) { - const callbacks = { - success: response => { - if (window.fabrickMod2) { - return window.fabrickMod2( - callback, response, configParams, consentData, cacheIdObj); - } else { - let responseObj; - if (response) { - try { - responseObj = JSON.parse(response); - } catch (error) { - utils.logError(error); - responseObj = {}; - } - } - callback(responseObj); - } - }, - error: error => { - utils.logError(`fabrickId fetch encountered an error`, error); - callback(); - } - }; - ajax(url, callbacks, null, {method: 'GET', withCredentials: true}); - }; - return {callback: resp}; - } catch (e) { - utils.logError(`fabrickIdSystem encountered an error`, e); - } - } catch (e) { - utils.logError(`fabrickIdSystem encountered an error`, e); - } - } -}; - -function _getRefererInfo(configParams) { - if (configParams.refererInfo) { - return configParams.refererInfo; - } else { - return getRefererInfo(); - } -} - -function _getBaseUrl(configParams) { - if (configParams.url) { - return configParams.url; - } else { - return `https://fid.agkn.com/f?`; - } -} - -function _setReferrer(refs, s) { - if (s) { - // store the longest one for the same URI - const url = s.split('?')[0]; - // OR store the longest one for the same domain - // const url = s.split('?')[0].replace('http://','').replace('https://', '').split('/')[0]; - if (refs.has(url)) { - const prevRef = refs.get(url); - if (s.length > prevRef.length) { - refs.set(url, s); - } - } else { - refs.set(url, s); - } - } -} - -export function appendUrl(url, paramName, s, configParams) { - const maxUrlLen = (configParams && configParams.maxUrlLen) || 2000; - const maxRefLen = (configParams && configParams.maxRefLen) || 1000; - const maxSpaceAvailable = (configParams && configParams.maxSpaceAvailable) || 50; - // make sure we have enough space left to make it worthwhile - if (s && url.length < (maxUrlLen - maxSpaceAvailable)) { - let thisMaxRefLen = maxUrlLen - url.length; - if (thisMaxRefLen > maxRefLen) { - thisMaxRefLen = maxRefLen; - } - - s = `&${paramName}=${encodeURIComponent(s)}`; - - if (s.length >= thisMaxRefLen) { - s = s.substring(0, thisMaxRefLen); - if (s.charAt(s.length - 1) === '%') { - s = s.substring(0, thisMaxRefLen - 1); - } else if (s.charAt(s.length - 2) === '%') { - s = s.substring(0, thisMaxRefLen - 2); - } - } - return `${url}${s}` - } else { - return url; - } -} - -submodule('userId', fabrickIdSubmodule); diff --git a/modules/fabrickIdSystem.md b/modules/fabrickIdSystem.md deleted file mode 100644 index 268c861710a..00000000000 --- a/modules/fabrickIdSystem.md +++ /dev/null @@ -1,24 +0,0 @@ -## Neustar Fabrick User ID Submodule - -Fabrick ID Module - https://www.home.neustar/fabrick -Product and Sales Inquiries: 1-855-898-0036 - -## Example configuration for publishers: -``` -pbjs.setConfig({ - userSync: { - userIds: [{ - name: 'fabrickId', - storage: { - name: 'pbjs_fabrickId', - type: 'cookie', - expires: 7 - }, - params: { - apiKey: 'your apiKey', // provided to you by Neustar - e: '31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66' // example hash identifier (sha256) - } - }] - } -}); -``` diff --git a/modules/fairtradeBidAdapter.md b/modules/fairtradeBidAdapter.md deleted file mode 100644 index 56abb84d15a..00000000000 --- a/modules/fairtradeBidAdapter.md +++ /dev/null @@ -1,28 +0,0 @@ -# Overview - -Module Name: FairTrade Bidder Adapter -Module Type: Bidder Adapter -Maintainer: Tammy.l@VaticDigital.com - -# Description - -Module that connects to FairTrade demand source to fetch bids. - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - sizes: [[300, 250]], - bids: [ - { - bidder: "fairtrade", - params: { - uid: '166', - priceType: 'gross' // by default is 'net' - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/feedadBidAdapter.js b/modules/feedadBidAdapter.js deleted file mode 100644 index 54a4ef0c998..00000000000 --- a/modules/feedadBidAdapter.js +++ /dev/null @@ -1,300 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {ajax} from '../src/ajax.js'; - -/** - * Version of the FeedAd bid adapter - * @type {string} - */ -const VERSION = '1.0.2'; - -/** - * @typedef {object} FeedAdApiBidRequest - * @inner - * - * @property {number} ad_type - * @property {string} client_token - * @property {string} placement_id - * @property {string} sdk_version - * @property {boolean} app_hybrid - * - * @property {string} [app_bundle_id] - * @property {string} [app_name] - * @property {object} [custom_params] - * @property {number} [connectivity] - * @property {string} [device_adid] - * @property {string} [device_platform] - */ - -/** - * @typedef {object} FeedAdApiBidResponse - * @inner - * - * @property {string} ad - Ad HTML payload - * @property {number} cpm - number / float - * @property {string} creativeId - ID of creative for tracking - * @property {string} currency - 3-letter ISO 4217 currency-code - * @property {number} height - Height of creative returned in [].ad - * @property {boolean} netRevenue - Is the CPM net (true) or gross (false)? - * @property {string} requestId - bids[].bidId - * @property {number} ttl - Time to live for this ad - * @property {number} width - Width of creative returned in [].ad - */ - -/** - * @typedef {object} FeedAdApiTrackingParams - * @inner - * - * @property app_hybrid {boolean} - * @property client_token {string} - * @property klass {'prebid_bidWon'|'prebid_bidTimeout'} - * @property placement_id {string} - * @property prebid_auction_id {string} - * @property prebid_bid_id {string} - * @property prebid_transaction_id {string} - * @property referer {string} - * @property sdk_version {string} - * @property [app_bundle_id] {string} - * @property [app_name] {string} - * @property [device_adid] {string} - * @property [device_platform] {1|2|3} 1 - Android | 2 - iOS | 3 - Windows - */ - -/** - * The IAB TCF 2.0 vendor ID for the FeedAd GmbH - */ -const TCF_VENDOR_ID = 781; - -/** - * Bidder network identity code - * @type {string} - */ -const BIDDER_CODE = 'feedad'; - -/** - * The media types supported by FeedAd - * @type {MediaType[]} - */ -const MEDIA_TYPES = [BANNER]; - -/** - * Tag for logging - * @type {string} - */ -const TAG = '[FeedAd]'; - -/** - * Pattern for valid placement IDs - * @type {RegExp} - */ -const PLACEMENT_ID_PATTERN = /^[a-z0-9][a-z0-9_-]+[a-z0-9]$/; - -const API_ENDPOINT = 'https://api.feedad.com'; -const API_PATH_BID_REQUEST = '/1/prebid/web/bids'; -const API_PATH_TRACK_REQUEST = '/1/prebid/web/events'; - -/** - * Stores temporary auction metadata - * @type {Object.} - */ -const BID_METADATA = {}; - -/** - * Checks if the bid is compatible with FeedAd. - * - * @param {BidRequest} bid - the bid to check - * @return {boolean} true if the bid is valid - */ -function isBidRequestValid(bid) { - const clientToken = utils.deepAccess(bid, 'params.clientToken'); - if (!clientToken || !isValidClientToken(clientToken)) { - utils.logWarn(TAG, "missing or invalid parameter 'clientToken'. found value:", clientToken); - return false; - } - - const placementId = utils.deepAccess(bid, 'params.placementId'); - if (!placementId || !isValidPlacementId(placementId)) { - utils.logWarn(TAG, "missing or invalid parameter 'placementId'. found value:", placementId); - return false; - } - - return true; -} - -/** - * Checks if a client token is valid - * @param {string} clientToken - the client token - * @return {boolean} true if the token is valid - */ -function isValidClientToken(clientToken) { - return typeof clientToken === 'string' && clientToken.length > 0; -} - -/** - * Checks if the given placement id is of a correct format. - * Valid IDs are words of lowercase letters from a to z and numbers from 0 to 9. - * The words can be separated by hyphens or underscores. - * Multiple separators must not follow each other. - * The whole placement ID must not be larger than 256 characters. - * - * @param placementId - the placement id to verify - * @returns if the placement ID is valid. - */ -function isValidPlacementId(placementId) { - return typeof placementId === 'string' && - placementId.length > 0 && - placementId.length <= 256 && - PLACEMENT_ID_PATTERN.test(placementId); -} - -/** - * Checks if the given media types contain unsupported settings - * @param {MediaTypes} mediaTypes - the media types to check - * @return {MediaTypes} the unsupported settings, empty when all types are supported - */ -function filterSupportedMediaTypes(mediaTypes) { - return { - banner: mediaTypes.banner, - video: mediaTypes.video && mediaTypes.video.context === 'outstream' ? mediaTypes.video : undefined, - native: undefined - }; -} - -/** - * Checks if the given media types are empty - * @param {MediaTypes} mediaTypes - the types to check - * @return {boolean} true if the types are empty - */ -function isMediaTypesEmpty(mediaTypes) { - return Object.keys(mediaTypes).every(type => mediaTypes[type] === undefined); -} - -/** - * Creates the bid request params the api expects from the prebid bid request - * @param {BidRequest} request - the validated prebid bid request - * @return {FeedAdApiBidRequest} - */ -function createApiBidRParams(request) { - return { - ad_type: 0, - client_token: request.params.clientToken, - placement_id: request.params.placementId, - sdk_version: `prebid_${VERSION}`, - app_hybrid: false, - }; -} - -/** - * Builds the bid request to the FeedAd Server - * @param {BidRequest[]} validBidRequests - all validated bid requests - * @param {object} bidderRequest - meta information - * @return {ServerRequest|ServerRequest[]} - */ -function buildRequests(validBidRequests, bidderRequest) { - if (!bidderRequest) { - return []; - } - let acceptableRequests = validBidRequests.filter(request => !isMediaTypesEmpty(filterSupportedMediaTypes(request.mediaTypes))); - if (acceptableRequests.length === 0) { - return []; - } - let data = Object.assign({}, bidderRequest, { - bids: acceptableRequests.map(req => { - req.params = createApiBidRParams(req); - return req; - }) - }); - data.bids.forEach(bid => BID_METADATA[bid.bidId] = { - referer: data.refererInfo.referer, - transactionId: bid.transactionId - }); - if (bidderRequest.gdprConsent) { - data.consentIabTcf = bidderRequest.gdprConsent.consentString; - data.gdprApplies = bidderRequest.gdprConsent.gdprApplies; - } - return { - method: 'POST', - url: `${API_ENDPOINT}${API_PATH_BID_REQUEST}`, - data, - options: { - contentType: 'application/json' - } - }; -} - -/** - * Adapts the FeedAd server response to Prebid format - * @param {ServerResponse} serverResponse - the FeedAd server response - * @param {BidRequest} request - the initial bid request - * @returns {Bid[]} the FeedAd bids - */ -function interpretResponse(serverResponse, request) { - /** - * @type FeedAdApiBidResponse[] - */ - return typeof serverResponse.body === 'string' ? JSON.parse(serverResponse.body) : serverResponse.body; -} - -/** - * Creates the parameters for the FeedAd tracking call - * @param {object} data - prebid data - * @param {'prebid_bidWon'|'prebid_bidTimeout'} klass - type of tracking call - * @return {FeedAdApiTrackingParams|null} - */ -function createTrackingParams(data, klass) { - const bidId = data.bidId || data.requestId; - if (!BID_METADATA.hasOwnProperty(bidId)) { - return null; - } - const {referer, transactionId} = BID_METADATA[bidId]; - delete BID_METADATA[bidId]; - return { - app_hybrid: false, - client_token: data.params[0].clientToken, - placement_id: data.params[0].placementId, - klass, - prebid_auction_id: data.auctionId, - prebid_bid_id: bidId, - prebid_transaction_id: transactionId, - referer, - sdk_version: VERSION - }; -} - -/** - * Creates a tracking handler for the given event type - * @param klass - the event type - * @return {Function} the tracking handler function - */ -function trackingHandlerFactory(klass) { - return (data) => { - if (!data) { - return; - } - let params = createTrackingParams(data, klass); - if (params) { - ajax(`${API_ENDPOINT}${API_PATH_TRACK_REQUEST}`, null, JSON.stringify(params), { - withCredentials: true, - method: 'POST', - contentType: 'application/json' - }); - } - } -} - -/** - * @type {BidderSpec} - */ -export const spec = { - code: BIDDER_CODE, - gvlid: TCF_VENDOR_ID, - supportedMediaTypes: MEDIA_TYPES, - isBidRequestValid, - buildRequests, - interpretResponse, - onTimeout: trackingHandlerFactory('prebid_bidTimeout'), - onBidWon: trackingHandlerFactory('prebid_bidWon') -}; - -registerBidder(spec); diff --git a/modules/feedadBidAdapter.md b/modules/feedadBidAdapter.md deleted file mode 100644 index 6f705df36b5..00000000000 --- a/modules/feedadBidAdapter.md +++ /dev/null @@ -1,41 +0,0 @@ -# Overview - -``` -Module Name: FeedAd Adapter -Module Type: Bidder Adapter -Maintainer: mail@feedad.com -``` - -# Description - -Prebid.JS adapter that connects to the FeedAd demand sources. - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { // supports all banner sizes - sizes: [[300, 250]], - } - }, - bids: [ - { - bidder: "feedad", - params: { - clientToken: 'your-client-token' // see below for more info - placementId: 'your-placement-id' // see below for more info - } - } - ] - } - ]; -``` - -# Required Parameters - -| Parameter | Description | -| --------- | ----------- | -| `clientToken` | Your FeedAd web client token. You can view your client token inside the FeedAd admin panel. | -| `placementId` | You can choose placement IDs yourself. A placement ID should be named after the ad position inside your product. For example, if you want to display an ad inside a list of news articles, you could name it "ad-news-overview".
A placement ID may consist of lowercase `a-z`, `0-9`, `-` and `_`. You do not have to manually create the placement IDs before using them. Just specify them within the code, and they will appear in the FeedAd admin panel after the first request.
[Learn more](/concept/feed_ad/index.html) about Placement IDs and how they are grouped to play the same Creative. | diff --git a/modules/fidelityBidAdapter.js b/modules/fidelityBidAdapter.js deleted file mode 100644 index fac273721ff..00000000000 --- a/modules/fidelityBidAdapter.js +++ /dev/null @@ -1,146 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'fidelity'; -const BIDDER_SERVER = 'x.fidelity-media.com'; -const FIDELITY_VENDOR_ID = 408; -export const spec = { - code: BIDDER_CODE, - gvlid: 408, - isBidRequestValid: function isBidRequestValid(bid) { - return !!(bid && bid.params && bid.params.zoneid); - }, - buildRequests: function buildRequests(validBidRequests, bidderRequest) { - return validBidRequests.map(bidRequest => { - var server = bidRequest.params.server || BIDDER_SERVER; - - const payload = { - from: 'hb', - v: '1.0', - requestid: bidRequest.bidderRequestId, - impid: bidRequest.bidId, - zoneid: bidRequest.params.zoneid, - floor: parseFloat(bidRequest.params.floor) > 0 ? bidRequest.params.floor : 0, - charset: document.charSet || document.characterSet, - subid: 'hb', - flashver: getFlashVersion(), - tmax: bidderRequest.timeout, - defloc: bidderRequest.refererInfo.referer, - referrer: getTopWindowReferrer(), - schain: getSupplyChain(bidRequest.schain), - }; - setConsentParams(bidderRequest.gdprConsent, bidderRequest.uspConsent, payload); - - return { - method: 'GET', - url: 'https://' + server + '/delivery/hb.php', - data: payload - }; - }); - }, - interpretResponse: function interpretResponse(serverResponse) { - serverResponse = serverResponse.body; - const bidResponses = []; - if (serverResponse && serverResponse.seatbid) { - serverResponse.seatbid.forEach(seatBid => seatBid.bid.forEach(bid => { - const bidResponse = { - requestId: bid.impid, - creativeId: bid.impid, - cpm: bid.price, - width: bid.width, - height: bid.height, - ad: bid.adm, - netRevenue: bid.netRevenue, - currency: bid.cur, - ttl: bid.ttl, - }; - - bidResponses.push(bidResponse); - })); - } - return bidResponses; - }, - getUserSyncs: function getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent) { - if (syncOptions.iframeEnabled) { - var url = 'https://' + BIDDER_SERVER + '/delivery/matches.php'; - var payload = { - type: 'iframe' - }; - setConsentParams(gdprConsent, uspConsent, payload); - - return [{ - type: 'iframe', - url: url + '?' + utils.parseQueryStringParameters(payload).replace(/\&$/, '') - }]; - } - } -} - -function getFlashVersion() { - var plugins, plugin, result; - - if (navigator.plugins && navigator.plugins.length > 0) { - plugins = navigator.plugins; - for (var i = 0; i < plugins.length && !result; i++) { - plugin = plugins[i]; - if (plugin.name.indexOf('Shockwave Flash') > -1) { - result = plugin.description.split('Shockwave Flash ')[1]; - } - } - } - return result || ''; -} - -function getTopWindowReferrer() { - try { - return window.top.document.referrer; - } catch (e) { - return ''; - } -} - -function setConsentParams(gdprConsent, uspConsent, payload) { - if (gdprConsent) { - payload.gdpr = 0; - payload.consent_str = ''; - payload.consent_given = 0; - if (typeof gdprConsent.gdprApplies !== 'undefined') { - payload.gdpr = gdprConsent.gdprApplies ? 1 : 0; - } - if (typeof gdprConsent.consentString !== 'undefined') { - payload.consent_str = gdprConsent.consentString; - } - if (gdprConsent.apiVersion === 1 && gdprConsent.vendorData && gdprConsent.vendorData.vendorConsents && typeof gdprConsent.vendorData.vendorConsents[FIDELITY_VENDOR_ID.toString(10)] !== 'undefined') { - payload.consent_given = gdprConsent.vendorData.vendorConsents[FIDELITY_VENDOR_ID.toString(10)] ? 1 : 0; - } - if (gdprConsent.apiVersion === 2 && gdprConsent.vendorData && gdprConsent.vendorData.vendor && gdprConsent.vendorData.vendor.consents && typeof gdprConsent.vendorData.vendor.consents[FIDELITY_VENDOR_ID.toString(10)] !== 'undefined') { - payload.consent_given = gdprConsent.vendorData.vendor.consents[FIDELITY_VENDOR_ID.toString(10)] ? 1 : 0; - } - } - if (typeof uspConsent !== 'undefined') { - payload.us_privacy = uspConsent; - } -} - -function getSupplyChain(schain) { - var supplyChain = ''; - if (schain != null && schain.nodes) { - supplyChain = schain.ver + ',' + schain.complete; - for (let i = 0; i < schain.nodes.length; i++) { - supplyChain += '!'; - supplyChain += (schain.nodes[i].asi) ? encodeURIComponent(schain.nodes[i].asi) : ''; - supplyChain += ','; - supplyChain += (schain.nodes[i].sid) ? encodeURIComponent(schain.nodes[i].sid) : ''; - supplyChain += ','; - supplyChain += (schain.nodes[i].hp) ? encodeURIComponent(schain.nodes[i].hp) : ''; - supplyChain += ','; - supplyChain += (schain.nodes[i].rid) ? encodeURIComponent(schain.nodes[i].rid) : ''; - supplyChain += ','; - supplyChain += (schain.nodes[i].name) ? encodeURIComponent(schain.nodes[i].name) : ''; - supplyChain += ','; - supplyChain += (schain.nodes[i].domain) ? encodeURIComponent(schain.nodes[i].domain) : ''; - } - } - return supplyChain; -} -registerBidder(spec); diff --git a/modules/fidelityBidAdapter.md b/modules/fidelityBidAdapter.md deleted file mode 100644 index 0af75689bd6..00000000000 --- a/modules/fidelityBidAdapter.md +++ /dev/null @@ -1,30 +0,0 @@ -# Overview -​ -**Module Name**: Fidelity Media fmxSSP Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: on@fidelity-media.com -​ -# Description -​ -Connects to Fidelity Media fmxSSP demand source to fetch bids. -​ -# Test Parameters -``` - var adUnits = [{ - code: 'banner-ad-div', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [{ - bidder: 'fidelity', - params: { - zoneid: '27248', - floor: 0.005, - server: 'x.fidelity-media.com' - } - }] - }]; - -``` \ No newline at end of file diff --git a/modules/fintezaAnalyticsAdapter.js b/modules/fintezaAnalyticsAdapter.js deleted file mode 100644 index 8729035491f..00000000000 --- a/modules/fintezaAnalyticsAdapter.js +++ /dev/null @@ -1,453 +0,0 @@ -import { ajax } from '../src/ajax.js'; -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -import * as utils from '../src/utils.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const storage = getStorageManager(); -const CONSTANTS = require('../src/constants.json'); - -const ANALYTICS_TYPE = 'endpoint'; -const FINTEZA_HOST = 'https://content.mql5.com/tr'; -const BID_REQUEST_TRACK = 'Bid Request %BIDDER%'; -const BID_RESPONSE_PRICE_TRACK = 'Bid Response Price %BIDDER%'; -const BID_RESPONSE_TIME_TRACK = 'Bid Response Time %BIDDER%'; -const BID_TIMEOUT_TRACK = 'Bid Timeout %BIDDER%'; -const BID_WON_TRACK = 'Bid Won %BIDDER%'; - -const FIRST_VISIT_DATE = '_fz_fvdt'; -const SESSION_ID = '_fz_ssn'; -const SESSION_DURATION = 30 * 60 * 1000; -const SESSION_RAND_PART = 9; -const TRACK_TIME_KEY = '_fz_tr'; -const UNIQ_ID_KEY = '_fz_uniq'; - -function getPageInfo() { - const pageInfo = { - domain: window.location.hostname, - } - - if (document.referrer) { - pageInfo.referrerDomain = utils.parseUrl(document.referrer).hostname; - } - - return pageInfo; -} - -function getUniqId() { - let cookies; - - try { - cookies = parseCookies(document.cookie); - } catch (a) { - cookies = {}; - } - - let isUniqFromLS; - let uniq = cookies[ UNIQ_ID_KEY ]; - if (!uniq) { - try { - if (storage.hasLocalStorage()) { - uniq = storage.getDataFromLocalStorage(UNIQ_ID_KEY) || ''; - isUniqFromLS = true; - } - } catch (b) {} - } - - if (uniq && isNaN(uniq)) { - uniq = null; - } - - if (uniq && isUniqFromLS) { - let expires = new Date(); - expires.setFullYear(expires.getFullYear() + 10); - - try { - storage.setCookie(UNIQ_ID_KEY, uniq, expires.toUTCString()); - } catch (e) {} - } - - return uniq; -} - -function initFirstVisit() { - let now; - let visitDate; - let cookies; - - try { - cookies = parseCookies(document.cookie); - } catch (a) { - cookies = {}; - } - - visitDate = cookies[ FIRST_VISIT_DATE ]; - - if (!visitDate) { - now = new Date(); - - visitDate = parseInt(now.getTime() / 1000, 10); - - now.setFullYear(now.getFullYear() + 20); - - try { - storage.setCookie(FIRST_VISIT_DATE, visitDate, now.toUTCString()); - } catch (e) {} - } - - return visitDate; -} - -function trim(string) { - if (string.trim) { - return string.trim(); - } - return string.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); -} - -function parseCookies(cookie) { - let values = {}; - let arr, item; - let param, value; - let i, j; - - if (!cookie || !storage.cookiesAreEnabled()) { - return {}; - } - - arr = cookie.split(';'); - - for (i = 0, j = arr.length; i < j; i++) { - item = arr[ i ]; - if (!item) { - continue; - } - - param = item.split('='); - if (param.length <= 1) { - continue; - } - - value = decodeURIComponent(param[0]); - value = trim(value); - - values[value] = decodeURIComponent(param[1]); - } - - return values; -} - -function getRandAsStr(digits) { - let str = ''; - let rand = 0; - let i; - - digits = digits || 4; - - for (i = 0; i < digits; i++) { - rand = (Math.random() * 10) >>> 0; - str += '' + rand; - } - - return str; -} - -function getSessionBegin(session) { - if (!session || (typeof session !== 'string')) { - return 0; - } - - const len = session.length; - if (len && len <= SESSION_RAND_PART) { - return 0; - } - - const timestamp = session.substring(0, len - SESSION_RAND_PART); - - return parseInt(timestamp, 10); -} - -function initSession() { - const now = new Date(); - const expires = new Date(now.getTime() + SESSION_DURATION); - const timestamp = Math.floor(now.getTime() / 1000); - let begin = 0; - let cookies; - let sessionId; - let sessionDuration; - let isNew = false; - - try { - cookies = parseCookies(document.cookie); - } catch (a) { - cookies = {}; - } - - sessionId = cookies[ SESSION_ID ]; - - if (!sessionId || - !checkSessionByExpires() || - !checkSessionByReferer() || - !checkSessionByDay()) { - sessionId = '' + timestamp + getRandAsStr(SESSION_RAND_PART); - begin = timestamp; - - isNew = true; - } else { - begin = getSessionBegin(sessionId); - } - - if (begin > 0) { - sessionDuration = Math.floor(timestamp - begin); - } else { - sessionDuration = -1; - } - - try { - storage.setCookie(SESSION_ID, sessionId, expires.toUTCString()); - } catch (e) {} - - return { - isNew: isNew, - id: sessionId, - duration: sessionDuration - }; -} - -function checkSessionByExpires() { - const timestamp = getTrackRequestLastTime(); - const now = new Date().getTime(); - - if (now > timestamp + SESSION_DURATION) { - return false; - } - return true; -} - -function checkSessionByReferer() { - const referrer = fntzAnalyticsAdapter.context.pageInfo.referrerDomain; - const domain = fntzAnalyticsAdapter.context.pageInfo.domain; - - return referrer === '' || domain === referrer; -} - -function checkSessionByDay() { - let last = getTrackRequestLastTime(); - if (last) { - last = new Date(last); - const now = new Date(); - - return last.getUTCDate() === now.getUTCDate() && - last.getUTCMonth() === now.getUTCMonth() && - last.getUTCFullYear() === now.getUTCFullYear(); - } - - return false; -} - -function saveTrackRequestTime() { - const now = new Date().getTime(); - const expires = new Date(now + SESSION_DURATION); - - try { - if (storage.hasLocalStorage()) { - storage.setDataInLocalStorage(TRACK_TIME_KEY, now.toString()); - } else { - storage.setCookie(TRACK_TIME_KEY, now.toString(), expires.toUTCString()); - } - } catch (a) {} -} - -function getTrackRequestLastTime() { - let cookie; - - try { - if (storage.hasLocalStorage()) { - return parseInt( - storage.getDataFromLocalStorage(TRACK_TIME_KEY) || 0, - 10, - ); - } - - cookie = parseCookies(document.cookie); - cookie = cookie[ TRACK_TIME_KEY ]; - if (cookie) { - return parseInt(cookie, 10); - } - } catch (e) {} - - return 0; -} - -function getAntiCacheParam() { - const date = new Date(); - const rand = (Math.random() * 99999 + 1) >>> 0; - - return ([ date.getTime(), rand ].join('')); -} - -function replaceBidder(str, bidder) { - let _str = str; - _str = _str.replace(/\%bidder\%/, bidder.toLowerCase()); - _str = _str.replace(/\%BIDDER\%/, bidder.toUpperCase()); - _str = _str.replace(/\%Bidder\%/, bidder.charAt(0).toUpperCase() + bidder.slice(1).toLowerCase()); - - return _str; -} - -function prepareBidRequestedParams(args) { - return [{ - event: encodeURIComponent(replaceBidder(fntzAnalyticsAdapter.context.bidRequestTrack, args.bidderCode)), - ref: encodeURIComponent(window.location.href), - }]; -} - -function prepareBidResponseParams(args) { - return [{ - event: encodeURIComponent(replaceBidder(fntzAnalyticsAdapter.context.bidResponsePriceTrack, args.bidderCode)), - value: args.cpm, - unit: 'usd' - }, { - event: encodeURIComponent(replaceBidder(fntzAnalyticsAdapter.context.bidResponseTimeTrack, args.bidderCode)), - value: args.timeToRespond, - unit: 'ms' - }]; -} - -function prepareBidWonParams(args) { - return [{ - event: encodeURIComponent(replaceBidder(fntzAnalyticsAdapter.context.bidWonTrack, args.bidderCode)), - value: args.cpm, - unit: 'usd' - }]; -} - -function prepareBidTimeoutParams(args) { - return args.map(function(bid) { - return { - event: encodeURIComponent(replaceBidder(fntzAnalyticsAdapter.context.bidTimeoutTrack, bid.bidder)), - value: bid.timeout, - unit: 'ms' - }; - }) -} - -function prepareTrackData(evtype, args) { - let prepareParams = null; - - switch (evtype) { - case CONSTANTS.EVENTS.BID_REQUESTED: - prepareParams = prepareBidRequestedParams; - break; - case CONSTANTS.EVENTS.BID_RESPONSE: - prepareParams = prepareBidResponseParams; - break; - case CONSTANTS.EVENTS.BID_WON: - prepareParams = prepareBidWonParams; - break; - case CONSTANTS.EVENTS.BID_TIMEOUT: - prepareParams = prepareBidTimeoutParams; - break; - } - - if (!prepareParams) { return null; } - - const data = prepareParams(args); - - if (!data) { return null; } - - const session = initSession(); - - return data.map(d => { - const trackData = Object.assign(d, { - id: fntzAnalyticsAdapter.context.id, - ref: encodeURIComponent(window.location.href), - title: encodeURIComponent(document.title), - scr_res: fntzAnalyticsAdapter.context.screenResolution, - fv_date: fntzAnalyticsAdapter.context.firstVisit, - ac: getAntiCacheParam(), - }) - - if (fntzAnalyticsAdapter.context.uniqId) { - trackData.fz_uniq = fntzAnalyticsAdapter.context.uniqId; - } - - if (session.id) { - trackData.ssn = session.id; - } - if (session.isNew) { - session.isNew = false; - trackData.ssn_start = 1; - } - trackData.ssn_dr = session.duration; - - return trackData; - }); -} - -function sendTrackRequest(trackData) { - try { - ajax( - fntzAnalyticsAdapter.context.host, - null, - trackData, - { - method: 'GET', - withCredentials: true, - contentType: 'application/x-www-form-urlencoded' - }, - ); - saveTrackRequestTime(); - } catch (err) { - utils.logError('Error on send data: ', err); - } -} - -const fntzAnalyticsAdapter = Object.assign( - adapter({ - FINTEZA_HOST, - ANALYTICS_TYPE - }), - { - track({ eventType, args }) { - if (typeof args !== 'undefined') { - const trackData = prepareTrackData(eventType, args); - if (!trackData) { return; } - - trackData.forEach(sendTrackRequest); - } - } - } -); - -fntzAnalyticsAdapter.originEnableAnalytics = fntzAnalyticsAdapter.enableAnalytics; - -fntzAnalyticsAdapter.enableAnalytics = function (config) { - if (!config.options.id) { - utils.logError('Client ID (id) option is not defined. Analytics won\'t work'); - return; - } - - fntzAnalyticsAdapter.context = { - host: config.options.host || FINTEZA_HOST, - id: config.options.id, - bidRequestTrack: config.options.bidRequestTrack || BID_REQUEST_TRACK, - bidResponsePriceTrack: config.options.bidResponsePriceTrack || BID_RESPONSE_PRICE_TRACK, - bidResponseTimeTrack: config.options.bidResponseTimeTrack || BID_RESPONSE_TIME_TRACK, - bidTimeoutTrack: config.options.bidTimeoutTrack || BID_TIMEOUT_TRACK, - bidWonTrack: config.options.bidWonTrack || BID_WON_TRACK, - firstVisit: initFirstVisit(), - screenResolution: `${window.screen.width}x${window.screen.height}`, - uniqId: getUniqId(), - pageInfo: getPageInfo(), - }; - - fntzAnalyticsAdapter.originEnableAnalytics(config); -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: fntzAnalyticsAdapter, - code: 'finteza' -}); - -export default fntzAnalyticsAdapter; diff --git a/modules/fintezaAnalyticsAdapter.md b/modules/fintezaAnalyticsAdapter.md deleted file mode 100644 index 7c07861d89f..00000000000 --- a/modules/fintezaAnalyticsAdapter.md +++ /dev/null @@ -1,29 +0,0 @@ -# Overview - -``` -Module Name: Finteza Analytics Adapter -Module Type: Analytics Adapter -Maintainer: renat@finteza.com -``` - -# Description - -The Finteza adapter for integration with Prebid is an analytics tool for publishers who use the Header Bidding technology. The adapter tracks auction opening, offer sending to advertisers, receipt of bids by the publisher and auction winner selection. All tracks are sent to Finteza and enable visual advertiser quality evaluation: how many offers partners accept, what prices they provide, how fast they respond and how often their bids win. - -For more information, visit the [official Finteza website](https://www.finteza.com/). - -# Test Parameters - -``` -{ - provider: 'finteza', - options: { - id: 'xxxxx', // Website ID (required) - bidRequestTrack: 'Bid Request %BIDDER%', - bidResponsePriceTrack: 'Bid Response Price %BIDDER%', - bidResponseTimeTrack: 'Bid Response Time %BIDDER%', - bidTimeoutTrack: 'Bid Timeout %BIDDER%', - bidWonTrack: 'Bid Won %BIDDER%' - } -} -``` diff --git a/modules/flocIdSystem.js b/modules/flocIdSystem.js deleted file mode 100644 index e4bd31e49df..00000000000 --- a/modules/flocIdSystem.js +++ /dev/null @@ -1,110 +0,0 @@ -/** - * This module adds flocId to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/flocId - * @requires module:modules/userId - */ - -import * as utils from '../src/utils.js' -import {submodule} from '../src/hook.js' - -const MODULE_NAME = 'flocId'; - -/** - * Add meta tag to support enabling of floc origin trial - * @function - * @param {string} token - configured token for origin-trial - */ -function enableOriginTrial(token) { - const tokenElement = document.createElement('meta'); - tokenElement.httpEquiv = 'origin-trial'; - tokenElement.content = token; - document.head.appendChild(tokenElement); -} - -/** - * Get the interest cohort. - * @param successCallback - * @param errorCallback - */ -function getFlocData(successCallback, errorCallback) { - document.interestCohort() - .then((data) => { - successCallback(data); - }).catch((error) => { - errorCallback(error); - }); -} - -/** - * Encode the id - * @param value - * @returns {string|*} - */ -function encodeId(value) { - const result = {}; - if (value) { - result.flocId = value; - utils.logInfo('Decoded value ' + JSON.stringify(result)); - return result; - } - return undefined; -} - -/** @type {Submodule} */ -export const flocIdSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: MODULE_NAME, - - /** - * decode the stored id value for passing to bid requests - * @function - * @param {string} value - * @returns {{flocId:{ id: string }} or undefined if value doesn't exists - */ - decode(value) { - return (value) ? encodeId(value) : undefined; - }, - /** - * If chrome and cohort enabled performs action to obtain id and return a value in the callback's response argument - * @function - * @param {SubmoduleConfig} [config] - * @returns {IdResponse|undefined} - */ - getId(config) { - // Block usage of storage of cohort ID - const checkStorage = (config && config.storage); - if (checkStorage) { - utils.logError('User ID - flocId submodule storage should not defined'); - return; - } - // Validate feature is enabled - const isFlocEnabled = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime) && !!document.featurePolicy && !!document.featurePolicy.features() && document.featurePolicy.features().includes('interest-cohort'); - - if (isFlocEnabled) { - const configParams = (config && config.params) || {}; - if (configParams && (typeof configParams.token === 'string')) { - // Insert meta-tag with token from configuration - enableOriginTrial(configParams.token); - } - // Example expected output { "id": "14159", "version": "chrome.1.0" } - let returnCallback = (cb) => { - getFlocData((data) => { - returnCallback = () => { return data; } - utils.logInfo('Cohort id: ' + JSON.stringify(data)); - cb(data); - }, (err) => { - utils.logInfo(err); - cb(undefined); - }); - }; - - return {callback: returnCallback}; - } - } -}; - -submodule('userId', flocIdSubmodule); diff --git a/modules/flocIdSystem.md b/modules/flocIdSystem.md deleted file mode 100644 index 07184700a14..00000000000 --- a/modules/flocIdSystem.md +++ /dev/null @@ -1,34 +0,0 @@ -## FloC ID User ID Submodule - -### Building Prebid with Floc Id Support -Your Prebid build must include the modules for both **userId** and **flocIdSystem** submodule. Follow the build instructions for Prebid as -explained in the top level README.md file of the Prebid source tree. - -ex: $ gulp build --modules=userId,flocIdSystem - -### Prebid Params - -Individual params may be set for the FloC ID User ID Submodule. -``` -pbjs.setConfig({ - userSync: { - userIds: [{ - name: 'flocId', - params: { - token: "Registered token or default sharedid.org token" - } - }] - } -}); -``` - -### Parameter Descriptions for the `userSync` Configuration Section -The below parameters apply only to the FloC ID User ID Module integration. - -| Params under usersync.userIds[]| Scope | Type | Description | Example | -| --- | --- | --- | --- | --- | -| name | Required | String | ID value for the Floc ID module - `"flocId"` | `"flocId"` | -| params | Optional | Object | Details for flocId syncing. | | -| params.token | Optional | Object | Publisher registered token.To get new token, register https://developer.chrome.com/origintrials/#/trials/active for Federated Learning of Cohorts. Default sharedid.org token: token: "A3dHTSoNUMjjERBLlrvJSelNnwWUCwVQhZ5tNQ+sll7y+LkPPVZXtB77u2y7CweRIxiYaGwGXNlW1/dFp8VMEgIAAAB+eyJvcmlnaW4iOiJodHRwczovL3NoYXJlZGlkLm9yZzo0NDMiLCJmZWF0dXJlIjoiSW50ZXJlc3RDb2hvcnRBUEkiLCJleHBpcnkiOjE2MjYyMjA3OTksImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9"| token: "A3dHTSoNUMjjERBLlrvJSelNnwWUCwVQhZ5tNQ+sll7y+LkPPVZXtB77u2y7CweRIxiYaGwGXNlW1/dFp8VMEgIAAAB+eyJvcmlnaW4iOiJodHRwczovL3NoYXJlZGlkLm9yZzo0NDMiLCJmZWF0dXJlIjoiSW50ZXJlc3RDb2hvcnRBUEkiLCJleHBpcnkiOjE2MjYyMjA3OTksImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9" - | -| storage | Not Allowed | Object | Will ask browser for cohort everytime. Setting storage will fail id lookup || diff --git a/modules/fluctBidAdapter.js b/modules/fluctBidAdapter.js deleted file mode 100644 index 420fe04ddcb..00000000000 --- a/modules/fluctBidAdapter.js +++ /dev/null @@ -1,121 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'fluct'; -const END_POINT = 'https://hb.adingo.jp/prebid'; -const VERSION = '1.2'; -const NET_REVENUE = true; -const TTL = 300; - -export const spec = { - code: BIDDER_CODE, - aliases: ['adingo'], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: (bid) => { - return !!(bid.params.groupId && bid.params.tagId); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids. - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: (validBidRequests, bidderRequest) => { - const serverRequests = []; - const referer = bidderRequest.refererInfo.referer; - - utils._each(validBidRequests, (request) => { - const data = Object(); - - data.referer = referer; - data.adUnitCode = request.adUnitCode; - data.bidId = request.bidId; - data.transactionId = request.transactionId; - - data.sizes = []; - utils._each(request.sizes, (size) => { - data.sizes.push({ - w: size[0], - h: size[1] - }); - }); - - data.params = request.params; - - serverRequests.push({ - method: 'POST', - url: END_POINT, - options: { - contentType: 'application/json', - withCredentials: true, - customHeaders: { - 'x-fluct-app': 'prebid/fluctBidAdapter', - 'x-fluct-version': VERSION, - 'x-openrtb-version': 2.5 - } - }, - data: data - }); - }); - - return serverRequests; - }, - - /* - * Unpack the respnse from the server into a list of bids. - * - * @param {serverResponse} serverResponse A successful response from the server. - * @return {bid[]} An array of bids which weer nested inside the server. - */ - interpretResponse: (serverResponse, serverRequest) => { - const bidResponses = []; - - const res = serverResponse.body; - if (!utils.isEmpty(res) && !utils.isEmpty(res.seatbid) && !utils.isEmpty(res.seatbid[0].bid)) { - const bid = res.seatbid[0].bid[0]; - const dealId = bid.dealid; - const beaconUrl = bid.burl; - const callImpBeacon = ``; - let data = { - bidderCode: BIDDER_CODE, - requestId: res.id, - currency: res.cur, - cpm: parseFloat(bid.price) || 0, - netRevenue: NET_REVENUE, - width: bid.w, - height: bid.h, - creativeId: bid.crid, - ttl: TTL, - ad: bid.adm + callImpBeacon, - }; - if (!utils.isEmpty(dealId)) { - data.dealId = dealId; - } - bidResponses.push(data); - } - return bidResponses; - }, - - /* - * Register the user sync pixels which should be dropped after the auction. - * - * @params {syncOptions} syncOptions which user syncs are allowed? - * @params {ServerResponse[]} serverResponses List of server's responses. - * @return {UserSync[]} The user syncs which should be dropped. - * - */ - getUserSyncs: (syncOptions, serverResponses) => { - return []; - }, -}; - -registerBidder(spec); diff --git a/modules/fluctBidAdapter.md b/modules/fluctBidAdapter.md deleted file mode 100644 index a1dc4d6f225..00000000000 --- a/modules/fluctBidAdapter.md +++ /dev/null @@ -1,36 +0,0 @@ -# Overview - -``` -Module Name: fluct Bid Adapter -Module Type: Bidder Adapter -Maintainer: developer@fluct.jp -``` - -# Description - -Connects to fluct exchange for bids. - -# Test parameters - -``` -var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [ - { - bidder: 'fluct', - params: { - tagId: '25405:1000192893', - groupId: '1000105712', - dfpUnitCode: '/62532913/s_fluct.test_hb_prebid_11940', // Optional - } - } - ] - } -] -``` diff --git a/modules/fpdModule/index.js b/modules/fpdModule/index.js deleted file mode 100644 index 427547a4e4d..00000000000 --- a/modules/fpdModule/index.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * This module sets default values and validates ortb2 first part data - * @module modules/firstPartyData - */ -import { config } from '../../src/config.js'; -import { module, getHook } from '../../src/hook.js'; -import { getGlobal } from '../../src/prebidGlobal.js'; -import { addBidderRequests } from '../../src/auction.js'; - -let submodules = []; - -/** - * enable submodule in User ID - * @param {RtdSubmodule} submodule - */ -export function registerSubmodules(submodule) { - submodules.push(submodule); -} - -export function init() { - let modConf = config.getConfig('firstPartyData') || {}; - let ortb2 = config.getConfig('ortb2') || {}; - - submodules.sort((a, b) => { - return ((a.queue || 1) - (b.queue || 1)); - }).forEach(submodule => { - ortb2 = submodule.init(modConf, ortb2); - }); - - config.setConfig({ortb2}); -} - -/** - * BidderRequests hook to intiate module and reset modules ortb2 data object - */ -function addBidderRequestHook(fn, bidderRequests) { - init(); - fn.call(this, bidderRequests); - // Removes hook after run - addBidderRequests.getHooks({ hook: addBidderRequestHook }).remove(); -} - -/** - * Sets bidderRequests hook - */ -function setupHook() { - getHook('addBidderRequests').before(addBidderRequestHook); -} - -module('firstPartyData', registerSubmodules); - -// Runs setupHook on initial load -setupHook(); - -/** - * Global function to reinitiate module - */ -(getGlobal()).refreshFpd = setupHook; diff --git a/modules/fpdModule/index.md b/modules/fpdModule/index.md deleted file mode 100644 index 638c966883a..00000000000 --- a/modules/fpdModule/index.md +++ /dev/null @@ -1,46 +0,0 @@ -# Overview - -``` -Module Name: First Party Data Module -``` - -# Description - -Module to perform the following functions to allow for consistent set of first party data using the following submodules. - -Enrichment Submodule: -- populate available data into object: referer, meta-keywords, cur - -Validation Submodule: -- verify OpenRTB datatypes, remove/warn any that are likely to choke downstream readers -- verify that certain OpenRTB attributes are not specified -- optionally suppress user FPD based on the existence of _pubcid_optout - - -1. Module initializes on first load and set bidRequestHook -2. When hook runs, corresponding submodule init functions are run to perform enrichments/validations dependant on submodule -3. After hook complete, it is disabled - meaning module only runs on first auction -4. To reinitiate the module, run pbjs.refreshFPD(), which allows module to rerun as if initial load - - -This module will automatically run first party data enrichments and validations dependant on which submodules are included. There is no configuration required. In order to load the module and submodule(s) and opt out of either enrichements or validations, use the below opt out configuration - -# Module Control Configuration - -``` - -pbjs.setConfig({ - firstPartyData: { - skipValidations: true, // default to false - skipEnrichments: true // default to false - } -}); - -``` - -# Requirements - -At least one of the submodules must be included in order to successfully run the corresponding above operations. - -enrichmentFpdModule -validationFpdModule \ No newline at end of file diff --git a/modules/freeWheelAdserverVideo.js b/modules/freeWheelAdserverVideo.js deleted file mode 100644 index cb4bd938373..00000000000 --- a/modules/freeWheelAdserverVideo.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * This module adds Freewheel support for Video to Prebid. - */ - -import { registerVideoSupport } from '../src/adServerManager.js'; -import { getHook, submodule } from '../src/hook.js'; - -export const adpodUtils = {}; -export function notifyTranslationModule(fn) { - fn.call(this, 'freewheel'); -} - -getHook('registerAdserver').before(notifyTranslationModule); - -registerVideoSupport('freewheel', { - getTargeting: (args) => adpodUtils.getTargeting(args) -}); - -submodule('adpod', adpodUtils); diff --git a/modules/freewheel-sspBidAdapter.js b/modules/freewheel-sspBidAdapter.js deleted file mode 100644 index 1c9cd75f76f..00000000000 --- a/modules/freewheel-sspBidAdapter.js +++ /dev/null @@ -1,461 +0,0 @@ -import * as utils from '../src/utils.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'freewheel-ssp'; - -const PROTOCOL = getProtocol(); -const FREEWHEEL_ADSSETUP = PROTOCOL + '://ads.stickyadstv.com/www/delivery/swfIndex.php'; -const MUSTANG_URL = PROTOCOL + '://cdn.stickyadstv.com/mustang/mustang.min.js'; -const PRIMETIME_URL = PROTOCOL + '://cdn.stickyadstv.com/prime-time/'; -const USER_SYNC_URL = PROTOCOL + '://ads.stickyadstv.com/auto-user-sync'; - -function getProtocol() { - return 'https'; -} - -function isValidUrl(str) { - if (!str) { - return false; - } - - // regExp for url validation - var pattern = /^(https?|ftp|file):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/; - return pattern.test(str); -} - -function getBiggerSize(array) { - var result = [0, 0]; - for (var i = 0; i < array.length; i++) { - if (array[i][0] * array[i][1] > result[0] * result[1]) { - result = array[i]; - } - } - return result; -} - -function getBiggerSizeWithLimit(array, minSizeLimit, maxSizeLimit) { - var minSize = minSizeLimit || [0, 0]; - var maxSize = maxSizeLimit || [Number.MAX_VALUE, Number.MAX_VALUE]; - var candidates = []; - - for (var i = 0; i < array.length; i++) { - if (array[i][0] * array[i][1] >= minSize[0] * minSize[1] && array[i][0] * array[i][1] <= maxSize[0] * maxSize[1]) { - candidates.push(array[i]); - } - } - - return getBiggerSize(candidates); -} - -/* -* read the pricing extension with this format: 1.0000 -* @return {object} pricing data in format: {currency: "EUR", price:"1.000"} -*/ -function getPricing(xmlNode) { - var pricingExtNode; - var princingData = {}; - - var extensions = xmlNode.querySelectorAll('Extension'); - // Nodelist.forEach is not supported in IE and Edge - // Workaround given here https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/10638731/ - Array.prototype.forEach.call(extensions, function(node) { - if (node.getAttribute('type') === 'StickyPricing') { - pricingExtNode = node; - } - }); - - if (pricingExtNode) { - var priceNode = pricingExtNode.querySelector('Price'); - princingData = { - currency: priceNode.getAttribute('currency'), - price: priceNode.textContent || priceNode.innerText - }; - } else { - utils.logWarn('PREBID - ' + BIDDER_CODE + ': No bid received or missing pricing extension.'); - } - - return princingData; -} - -function hashcode(inputString) { - var hash = 0; - var char; - if (inputString.length == 0) return hash; - for (var i = 0; i < inputString.length; i++) { - char = inputString.charCodeAt(i); - hash = ((hash << 5) - hash) + char; - hash = hash & hash; // Convert to 32bit integer - } - return hash; -} - -function getCreativeId(xmlNode) { - var creaId = ''; - var adNodes = xmlNode.querySelectorAll('Ad'); - // Nodelist.forEach is not supported in IE and Edge - // Workaround given here https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/10638731/ - Array.prototype.forEach.call(adNodes, function(el) { - creaId += '[' + el.getAttribute('id') + ']'; - }); - - return creaId; -} - -function getValueFromKeyInImpressionNode(xmlNode, key) { - var value = ''; - var impNodes = xmlNode.querySelectorAll('Impression'); // Nodelist.forEach is not supported in IE and Edge - var isRootViewKeyPresent = false; - var isAdsDisplayStartedPresent = false; - Array.prototype.forEach.call(impNodes, function (el) { - if (isRootViewKeyPresent && isAdsDisplayStartedPresent) { - return value; - } - isRootViewKeyPresent = false; - isAdsDisplayStartedPresent = false; - var text = el.textContent; - var queries = text.substring(el.textContent.indexOf('?') + 1).split('&'); - var tempValue = ''; - Array.prototype.forEach.call(queries, function (item) { - var split = item.split('='); - if (split[0] == key) { - tempValue = split[1]; - } - if (split[0] == 'reqType' && split[1] == 'AdsDisplayStarted') { - isAdsDisplayStartedPresent = true; - } - if (split[0] == 'rootViewKey') { - isRootViewKeyPresent = true; - } - }); - if (isAdsDisplayStartedPresent) { - value = tempValue; - } - }); - return value; -} - -function getDealId(xmlNode) { - return getValueFromKeyInImpressionNode(xmlNode, 'dealId'); -} - -function getBannerId(xmlNode) { - return getValueFromKeyInImpressionNode(xmlNode, 'adId'); -} - -function getCampaignId(xmlNode) { - return getValueFromKeyInImpressionNode(xmlNode, 'campaignId'); -} - -/** -* returns the top most accessible window -*/ -function getTopMostWindow() { - var res = window; - - try { - while (top !== res) { - if (res.parent.location.href.length) { res = res.parent; } - } - } catch (e) {} - - return res; -} - -function getComponentId(inputFormat) { - var component = 'mustang'; // default component id - - if (inputFormat && inputFormat !== 'inbanner') { - // format identifiers are equals to their component ids. - component = inputFormat; - } - - return component; -} - -function getAPIName(componentId) { - componentId = componentId || ''; - - // remove dash in componentId to get API name - return componentId.replace('-', ''); -} - -function formatAdHTML(bid, size) { - var integrationType = bid.params.format; - - var divHtml = '
'; - - var script = ''; - var libUrl = ''; - if (integrationType && integrationType !== 'inbanner') { - libUrl = PRIMETIME_URL + getComponentId(bid.params.format) + '.min.js'; - script = getOutstreamScript(bid, size); - } else { - libUrl = MUSTANG_URL; - script = getInBannerScript(bid, size); - } - - return divHtml + - ''; -} - -var getInBannerScript = function(bid, size) { - return 'var config = {' + - ' preloadedVast:vast,' + - ' autoPlay:true' + - ' };' + - ' var ad = new window.com.stickyadstv.vpaid.Ad(document.getElementById("freewheelssp_prebid_target"),config);' + - ' (new window.com.stickyadstv.tools.ASLoader(' + bid.params.zoneId + ', \'' + getComponentId(bid.params.format) + '\')).registerEvents(ad);' + - ' ad.initAd(' + size[0] + ',' + size[1] + ',"",0,"","");'; -}; - -var getOutstreamScript = function(bid) { - var config = bid.params; - - // default placement if no placement is set - if (!config.hasOwnProperty('domId') && !config.hasOwnProperty('auto') && !config.hasOwnProperty('p') && !config.hasOwnProperty('article')) { - if (config.format === 'intext-roll') { - config.iframeMode = 'dfp'; - } else { - config.domId = 'freewheelssp_prebid_target'; - } - } - - var script = 'var config = {' + - ' preloadedVast:vast,' + - ' ASLoader:new window.com.stickyadstv.tools.ASLoader(' + bid.params.zoneId + ', \'' + getComponentId(bid.params.format) + '\')'; - - for (var key in config) { - // dont' send format parameter - // neither zone nor vastUrlParams value as Vast is already loaded - if (config.hasOwnProperty(key) && key !== 'format' && key !== 'zone' && key !== 'zoneId' && key !== 'vastUrlParams') { - script += ',' + key + ':"' + config[key] + '"'; - } - } - script += '};' + - - 'window.com.stickyadstv.' + getAPIName(bid.params.format) + '.start(config);'; - - return script; -}; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - aliases: ['stickyadstv'], // former name for freewheel-ssp - /** - * Determines whether or not the given bid request is valid. - * - * @param {object} bid The bid to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - return !!(bid.params.zoneId); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server. - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(bidRequests, bidderRequest) { - // var currency = config.getConfig(currency); - - let buildRequest = (currentBidRequest, bidderRequest) => { - var zone = currentBidRequest.params.zoneId; - var timeInMillis = new Date().getTime(); - var keyCode = hashcode(zone + '' + timeInMillis); - var requestParams = { - reqType: 'AdsSetup', - protocolVersion: '2.0', - zoneId: zone, - componentId: 'prebid', - componentSubId: getComponentId(currentBidRequest.params.format), - timestamp: timeInMillis, - pKey: keyCode - }; - - // Add GDPR flag and consent string - if (bidderRequest && bidderRequest.gdprConsent) { - requestParams._fw_gdpr_consent = bidderRequest.gdprConsent.consentString; - - if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') { - requestParams._fw_gdpr = bidderRequest.gdprConsent.gdprApplies; - } - } - - if (currentBidRequest.params.gdpr_consented_providers) { - requestParams._fw_gdpr_consented_providers = currentBidRequest.params.gdpr_consented_providers; - } - - // Add CCPA consent string - if (bidderRequest && bidderRequest.uspConsent) { - requestParams._fw_us_privacy = bidderRequest.uspConsent; - } - - var vastParams = currentBidRequest.params.vastUrlParams; - if (typeof vastParams === 'object') { - for (var key in vastParams) { - if (vastParams.hasOwnProperty(key)) { - requestParams[key] = vastParams[key]; - } - } - } - - var location = (bidderRequest && bidderRequest.refererInfo) ? bidderRequest.refererInfo.referer : getTopMostWindow().location.href; - if (isValidUrl(location)) { - requestParams.loc = location; - } - - var playerSize = []; - if (currentBidRequest.mediaTypes.video && currentBidRequest.mediaTypes.video.playerSize) { - // If mediaTypes is video, get size from mediaTypes.video.playerSize per http://prebid.org/blog/pbjs-3 - if (utils.isArray(currentBidRequest.mediaTypes.video.playerSize[0])) { - playerSize = currentBidRequest.mediaTypes.video.playerSize[0]; - } else { - playerSize = currentBidRequest.mediaTypes.video.playerSize; - } - } else if (currentBidRequest.mediaTypes.banner.sizes) { - // If mediaTypes is banner, get size from mediaTypes.banner.sizes per http://prebid.org/blog/pbjs-3 - playerSize = getBiggerSizeWithLimit(currentBidRequest.mediaTypes.banner.sizes, currentBidRequest.mediaTypes.banner.minSizeLimit, currentBidRequest.mediaTypes.banner.maxSizeLimit); - } else { - // Backward compatible code, in case size still pass by sizes in bid request - playerSize = getBiggerSize(currentBidRequest.sizes); - } - - if (playerSize[0] > 0 || playerSize[1] > 0) { - requestParams.playerSize = playerSize[0] + 'x' + playerSize[1]; - } - - return { - method: 'GET', - url: FREEWHEEL_ADSSETUP, - data: requestParams, - bidRequest: currentBidRequest - }; - }; - - return bidRequests.map(function(currentBidRequest) { - return buildRequest(currentBidRequest, bidderRequest); - }); - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @param {object} request: the built request object containing the initial bidRequest. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse, request) { - var bidrequest = request.bidRequest; - var playerSize = []; - if (bidrequest.mediaTypes.video && bidrequest.mediaTypes.video.playerSize) { - // If mediaTypes is video, get size from mediaTypes.video.playerSize per http://prebid.org/blog/pbjs-3 - if (utils.isArray(bidrequest.mediaTypes.video.playerSize[0])) { - playerSize = bidrequest.mediaTypes.video.playerSize[0]; - } else { - playerSize = bidrequest.mediaTypes.video.playerSize; - } - } else if (bidrequest.mediaTypes.banner.sizes) { - // If mediaTypes is banner, get size from mediaTypes.banner.sizes per http://prebid.org/blog/pbjs-3 - playerSize = getBiggerSizeWithLimit(bidrequest.mediaTypes.banner.sizes, bidrequest.mediaTypes.banner.minSizeLimit, bidrequest.mediaTypes.banner.maxSizeLimit); - } else { - // Backward compatible code, in case size still pass by sizes in bid request - playerSize = getBiggerSize(bidrequest.sizes); - } - - if (typeof serverResponse == 'object' && typeof serverResponse.body == 'string') { - serverResponse = serverResponse.body; - } - - var xmlDoc; - try { - var parser = new DOMParser(); - xmlDoc = parser.parseFromString(serverResponse, 'application/xml'); - } catch (err) { - utils.logWarn('Prebid.js - ' + BIDDER_CODE + ' : ' + err); - return; - } - - const princingData = getPricing(xmlDoc); - const creativeId = getCreativeId(xmlDoc); - const dealId = getDealId(xmlDoc); - const campaignId = getCampaignId(xmlDoc); - const bannerId = getBannerId(xmlDoc); - const topWin = getTopMostWindow(); - if (!topWin.freewheelssp_cache) { - topWin.freewheelssp_cache = {}; - } - topWin.freewheelssp_cache[bidrequest.adUnitCode] = serverResponse; - - const bidResponses = []; - - if (princingData.price) { - const bidResponse = { - requestId: bidrequest.bidId, - cpm: princingData.price, - width: playerSize[0], - height: playerSize[1], - creativeId: creativeId, - currency: princingData.currency, - netRevenue: true, - ttl: 360, - dealId: dealId, - campaignId: campaignId, - bannerId: bannerId - }; - - if (bidrequest.mediaTypes.video) { - bidResponse.vastXml = serverResponse; - bidResponse.mediaType = 'video'; - } - - bidResponse.ad = formatAdHTML(bidrequest, playerSize); - bidResponses.push(bidResponse); - } - - return bidResponses; - }, - - getUserSyncs: function(syncOptions, responses, gdprConsent, usPrivacy) { - var gdprParams = ''; - if (gdprConsent) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - gdprParams = `?gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - gdprParams = `?gdpr_consent=${gdprConsent.consentString}`; - } - } - - if (syncOptions && syncOptions.pixelEnabled) { - return [{ - type: 'image', - url: USER_SYNC_URL + gdprParams - }]; - } else { - return []; - } - }, -}; - -registerBidder(spec); diff --git a/modules/freewheel-sspBidAdapter.md b/modules/freewheel-sspBidAdapter.md deleted file mode 100644 index 0086aac6567..00000000000 --- a/modules/freewheel-sspBidAdapter.md +++ /dev/null @@ -1,33 +0,0 @@ -# Overview - -Module Name: Freewheel SSP Bidder Adapter -Module Type: Bidder Adapter -Maintainer: clientsidesdk@freewheel.tv - -# Description - -Module that connects to Freewheel ssp's demand sources - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - - mediaTypes: { - banner: { - sizes: [[300, 250]], // a display size - } - }, - - bids: [ - { - bidder: "freewheel-ssp", - params: { - zoneId : '277225' - } - } - ] - } - ]; -``` diff --git a/modules/fyberBidAdapter.md b/modules/fyberBidAdapter.md deleted file mode 100644 index c394addadfe..00000000000 --- a/modules/fyberBidAdapter.md +++ /dev/null @@ -1,56 +0,0 @@ -# Overview - -``` -Module Name: Fyber Bidder Adapter -Module Type: Bidder Adapter -Maintainer: uri@inner-active.com -``` - -# Description - -Module that connects to Fyber's demand sources - -# Test Parameters -``` -var adUnits = [ -{ -code: 'test-div', -mediaTypes: { -banner: { -sizes: [[300, 250]], // a display rectangle size -} -}, -bids: [ -{ -bidder: 'fyber', - params: { - APP_ID: 'MyCompany_MyApp', - spotType: 'rectangle', - customParams: { - portal: 7002 - } - } -} -] -},{ -code: 'test-div', -mediaTypes: { -banner: { -sizes: [[320, 50]], // a banner size -} -}, -bids: [ -{ -bidder: 'fyber', - params: { - APP_ID: 'MyCompany_MyApp', - spotType: 'banner', - customParams: { - portal: 7001 - } - } -} -] -} -]; -``` diff --git a/modules/gammaBidAdapter.js b/modules/gammaBidAdapter.js deleted file mode 100644 index 5fd3c56b2c6..00000000000 --- a/modules/gammaBidAdapter.js +++ /dev/null @@ -1,101 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; - -const ENDPOINT = 'https://hb.gammaplatform.com'; -const ENDPOINT_USERSYNC = 'https://cm-supply-web.gammaplatform.com'; -const BIDDER_CODE = 'gamma'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['gamma'], - supportedMediaTypes: ['banner', 'video'], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {object} bid The bid to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - return !!(bid.params.siteId || bid.params.zoneId); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server. - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(bidRequests, bidderRequest) { - const serverRequests = []; - const bidderRequestReferer = (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer) || ''; - for (var i = 0, len = bidRequests.length; i < len; i++) { - const gaxObjParams = bidRequests[i]; - serverRequests.push({ - method: 'GET', - url: ENDPOINT + '/adx/request?wid=' + gaxObjParams.params.siteId + '&zid=' + gaxObjParams.params.zoneId + '&hb=pbjs&bidid=' + gaxObjParams.bidId + '&urf=' + encodeURIComponent(bidderRequestReferer) - }); - } - return serverRequests; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse) { - serverResponse = serverResponse.body; - - const bids = []; - - if (serverResponse.id) { - const bid = newBid(serverResponse); - bids.push(bid); - } - - return bids; - }, - - getUserSyncs: function(syncOptions) { - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: ENDPOINT_USERSYNC + '/adx/usersync' - }]; - } - } -} - -/** - * Unpack the Server's Bid into a Prebid-compatible one. - * @param serverBid - * @return Bid - */ -function newBid(serverBid) { - const bid = { - ad: serverBid.seatbid[0].bid[0].adm, - cpm: serverBid.seatbid[0].bid[0].price, - creativeId: serverBid.seatbid[0].bid[0].adid, - currency: serverBid.cur, - dealId: serverBid.seatbid[0].bid[0].dealid, - width: serverBid.seatbid[0].bid[0].w, - height: serverBid.seatbid[0].bid[0].h, - mediaType: serverBid.type, - netRevenue: true, - requestId: serverBid.id, - ttl: serverBid.seatbid[0].bid[0].ttl || 300 - }; - - if (serverBid.type == 'video') { - Object.assign(bid, { - vastXml: serverBid.seatbid[0].bid[0].vastXml, - vastUrl: serverBid.seatbid[0].bid[0].vastUrl, - ttl: 3600 - }); - } - - return bid; -} - -registerBidder(spec); diff --git a/modules/gammaBidAdapter.md b/modules/gammaBidAdapter.md deleted file mode 100644 index 2902be78492..00000000000 --- a/modules/gammaBidAdapter.md +++ /dev/null @@ -1,84 +0,0 @@ -# Overview - -``` -Module Name: Gamma Bid Adapter -Module Type: Bidder Adapter -Maintainer: support@gammassp.com -``` - -# Description - -Connects to Gamma exchange for bids. - -Gamma bid adapter supports Banner, Video. - -# Test Parameters: For Banner -``` -var adUnits = [{ - code: 'gamma-hb-ad-123456-0', - sizes: [[300, 250]], - - // Replace this object to test a new Adapter! - bids: [{ - bidder: 'gamma', - params: { - siteId: '1465446377', - zoneId: '1515999290' - } - }] - - }]; -``` -# Test Parameters: For Video -``` -var adUnits = [{ - code: 'gamma-hb-ad-78910-0', - sizes: [[640, 480]], - - // Replace this object to test a new Adapter! - bids: [{ - bidder: 'gamma', - params: { - siteId: '1465446377', - zoneId: '1493280341' - } - }] - - }]; -``` -# Ad Unit and Setup: For Testing -In order to receive bids please map localhost to (any) test domain. - -``` -<--! Prebid Config section > - - - - -``` - -# Ad Unit and Setup: For Testing (Video Instream) - -```html - - - -``` -# Ad Unit and Setup: For Testing (Video Outstream) - -```html - - - -``` - -# Ad Unit and Setup: For Testing (Native) - -```html - - - - diff --git a/modules/mediasquareBidAdapter.js b/modules/mediasquareBidAdapter.js deleted file mode 100644 index 84783eb0991..00000000000 --- a/modules/mediasquareBidAdapter.js +++ /dev/null @@ -1,166 +0,0 @@ -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'; - -const BIDDER_CODE = 'mediasquare'; -const BIDDER_URL_PROD = 'https://pbs-front.mediasquare.fr/' -const BIDDER_URL_TEST = 'https://bidder-test.mediasquare.fr/' -const BIDDER_ENDPOINT_AUCTION = 'msq_prebid'; -const BIDDER_ENDPOINT_SYNC = 'cookie_sync'; -const BIDDER_ENDPOINT_WINNING = 'winning'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['msq'], // short code - supportedMediaTypes: [BANNER, NATIVE, VIDEO], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - return !!(bid.params.owner && bid.params.code); - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests, bidderRequest) { - let codes = []; - let endpoint = document.location.search.match(/msq_test=true/) ? BIDDER_URL_TEST : BIDDER_URL_PROD; - const test = config.getConfig('debug') ? 1 : 0; - let adunitValue = null; - Object.keys(validBidRequests).forEach(key => { - adunitValue = validBidRequests[key]; - codes.push({ - owner: adunitValue.params.owner, - code: adunitValue.params.code, - adunit: adunitValue.adUnitCode, - bidId: adunitValue.bidId, - auctionId: adunitValue.auctionId, - transactionId: adunitValue.transactionId, - mediatypes: adunitValue.mediaTypes - }); - }); - const payload = { - codes: codes, - referer: encodeURIComponent(bidderRequest.refererInfo.referer) - }; - if (bidderRequest) { // modules informations (gdpr, ccpa, schain, userId) - if (bidderRequest.gdprConsent) { - payload.gdpr = { - consent_string: bidderRequest.gdprConsent.consentString, - consent_required: bidderRequest.gdprConsent.gdprApplies - }; - } - if (bidderRequest.uspConsent) { payload.uspConsent = bidderRequest.uspConsent; } - if (bidderRequest.schain) { payload.schain = bidderRequest.schain; } - if (bidderRequest.userId) { - payload.userId = bidderRequest.userId; - } else if (bidderRequest.hasOwnProperty('bids') && typeof bidderRequest.bids == 'object' && bidderRequest.bids.length > 0 && bidderRequest.bids[0].hasOwnProperty('userId')) { - payload.userId = bidderRequest.bids[0].userId; - } - }; - if (test) { payload.debug = true; } - const payloadString = JSON.stringify(payload); - return { - method: 'POST', - url: endpoint + BIDDER_ENDPOINT_AUCTION, - data: payloadString, - }; - }, - /** - * Unpack the 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. - */ - interpretResponse: function(serverResponse, bidRequest) { - const serverBody = serverResponse.body; - // const headerValue = serverResponse.headers.get('some-response-header'); - const bidResponses = []; - let bidResponse = null; - let value = null; - if (serverBody.hasOwnProperty('responses')) { - Object.keys(serverBody['responses']).forEach(key => { - value = serverBody['responses'][key]; - bidResponse = { - requestId: value['bid_id'], - cpm: value['cpm'], - width: value['width'], - height: value['height'], - creativeId: value['creative_id'], - currency: value['currency'], - netRevenue: value['net_revenue'], - ttl: value['ttl'], - ad: value['ad'], - mediasquare: { - 'bidder': value['bidder'], - 'code': value['code'] - } - }; - if ('native' in value) { - bidResponse['native'] = value['native']; - bidResponse['mediaType'] = 'native'; - } else if ('video' in value) { - if ('url' in value['video']) { bidResponse['vastUrl'] = value['video']['url'] } - if ('xml' in value['video']) { bidResponse['vastXml'] = value['video']['xml'] } - bidResponse['mediaType'] = 'video'; - } - if (value.hasOwnProperty('deal_id')) { bidResponse['dealId'] = value['deal_id']; } - bidResponses.push(bidResponse); - }); - } - return bidResponses; - }, - - /** - * Register the user sync pixels which should be dropped after the auction. - * - * @param {SyncOptions} syncOptions Which user syncs are allowed? - * @param {ServerResponse[]} serverResponses List of server's responses. - * @return {UserSync[]} The user syncs which should be dropped. - */ - getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) { - let params = ''; - let endpoint = document.location.search.match(/msq_test=true/) ? BIDDER_URL_TEST : BIDDER_URL_PROD; - if (typeof serverResponses === 'object' && serverResponses != null && serverResponses.length > 0 && serverResponses[0].hasOwnProperty('body') && - serverResponses[0].body.hasOwnProperty('cookies') && typeof serverResponses[0].body.cookies === 'object') { - return serverResponses[0].body.cookies; - } else { - if (gdprConsent && typeof gdprConsent.consentString === 'string') { params += typeof gdprConsent.gdprApplies === 'boolean' ? `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}` : `&gdpr_consent=${gdprConsent.consentString}`; } - if (uspConsent && typeof uspConsent === 'string') { params += '&uspConsent=' + uspConsent } - return { - type: 'iframe', - url: endpoint + BIDDER_ENDPOINT_SYNC + '?type=iframe' + params - }; - } - }, - - /** - * Register bidder specific code, which will execute if a bid from this bidder won the auction - * @param {Bid} The bid that won the auction - */ - onBidWon: function(bid) { - // fires a pixel to confirm a winning bid - let params = []; - let endpoint = document.location.search.match(/msq_test=true/) ? BIDDER_URL_TEST : BIDDER_URL_PROD; - let paramsToSearchFor = ['cpm', 'size', 'mediaType', 'currency', 'creativeId', 'adUnitCode', 'timeToRespond', 'requestId', 'auctionId'] - if (bid.hasOwnProperty('mediasquare')) { - if (bid['mediasquare'].hasOwnProperty('bidder')) { params.push('bidder=' + bid['mediasquare']['bidder']); } - if (bid['mediasquare'].hasOwnProperty('code')) { params.push('code=' + bid['mediasquare']['code']); } - }; - for (let i = 0; i < paramsToSearchFor.length; i++) { - if (bid.hasOwnProperty(paramsToSearchFor[i])) { params.push(paramsToSearchFor[i] + '=' + bid[paramsToSearchFor[i]]); } - } - if (params.length > 0) { params = '?' + params.join('&'); } - ajax(endpoint + BIDDER_ENDPOINT_WINNING + params, null); - return true; - } - -} -registerBidder(spec); diff --git a/modules/mediasquareBidAdapter.md b/modules/mediasquareBidAdapter.md deleted file mode 100644 index f9f8d4be908..00000000000 --- a/modules/mediasquareBidAdapter.md +++ /dev/null @@ -1,35 +0,0 @@ -# Overview - -``` -Module Name: MediaSquare Bid Adapter -Module Type: Bidder Adapter -Maintainer: tech@mediasquare.fr -``` - -# Description - -Connects to Mediasquare network for bids. - -Mediasquare bid adapter supports Banner only for the time being. - -# Test Parameters -``` -var adUnits = [ - // Banner adUnit - { - code: 'banner-div', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]] - } - }, - bids: [{ - bidder: 'mediasquare', - params: { - owner: "test", - code: "publishername_atf_desktop_rg_pave" - } - }] - }, -]; -``` diff --git a/modules/merkleIdSystem.js b/modules/merkleIdSystem.js deleted file mode 100644 index 353cc45473d..00000000000 --- a/modules/merkleIdSystem.js +++ /dev/null @@ -1,125 +0,0 @@ -/** - * This module adds merkleId to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/merkleIdSystem - * @requires module:modules/userId - */ - -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'; - -const MODULE_NAME = 'merkleId'; -const SESSION_COOKIE_NAME = '_svsid'; -const ID_URL = 'https://id2.sv.rkdms.com/identity/'; - -export const storage = getStorageManager(); - -function getSession(configParams) { - let session = null; - if (typeof configParams.sv_session !== 'string') { - session = configParams.sv_session; - } else { - session = readCookie() || readFromLocalStorage(); - } - return session; -} - -function readCookie() { - return storage.cookiesAreEnabled() ? storage.getCookie(SESSION_COOKIE_NAME) : null; -} - -function readFromLocalStorage() { - return storage.localStorageIsEnabled() ? storage.getDataFromLocalStorage(SESSION_COOKIE_NAME) : null; -} - -function constructUrl(configParams) { - const session = getSession(configParams); - let url = ID_URL + `?vendor=${configParams.vendor}&sv_cid=${configParams.sv_cid}&sv_domain=${configParams.sv_domain}&sv_pubid=${configParams.sv_pubid}`; - if (session) { - url.append(`&sv_session=${session}`); - } - utils.logInfo('Merkle url :' + url); - return url; -} - -/** @type {Submodule} */ -export const merkleIdSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: MODULE_NAME, - /** - * decode the stored id value for passing to bid requests - * @function - * @param {string} value - * @returns {{merkleId:string}} - */ - decode(value) { - const id = (value && value.pam_id && typeof value.pam_id.id === 'string') ? value.pam_id : undefined; - utils.logInfo('Merkle id ' + JSON.stringify(id)); - return id ? { 'merkleId': id } : undefined; - }, - /** - * performs action to obtain id and return a value in the callback's response argument - * @function - * @param {SubmoduleConfig} [config] - * @param {ConsentData} [consentData] - * @returns {IdResponse|undefined} - */ - getId(config, consentData) { - const configParams = (config && config.params) || {}; - if (!configParams || typeof configParams.vendor !== 'string') { - utils.logError('User ID - merkleId submodule requires a valid vendor to be defined'); - return; - } - - if (typeof configParams.sv_cid !== 'string') { - utils.logError('User ID - merkleId submodule requires a valid sv_cid string to be defined'); - return; - } - - if (typeof configParams.sv_pubid !== 'string') { - utils.logError('User ID - merkleId submodule requires a valid sv_pubid string to be defined'); - return; - } - - if (typeof configParams.sv_domain !== 'string') { - utils.logError('User ID - merkleId submodule requires a valid sv_domain string to be defined'); - return; - } - - if (consentData && typeof consentData.gdprApplies === 'boolean' && consentData.gdprApplies) { - utils.logError('User ID - merkleId submodule does not currently handle consent strings'); - return; - } - const url = constructUrl(configParams); - - const resp = function (callback) { - const callbacks = { - success: response => { - let responseObj; - if (response) { - try { - responseObj = JSON.parse(response); - utils.logInfo('Merkle responseObj ' + JSON.stringify(responseObj)); - } catch (error) { - utils.logError(error); - } - } - callback(responseObj); - }, - error: error => { - utils.logError(`${MODULE_NAME}: merkleId fetch encountered an error`, error); - callback(); - } - }; - ajax(url, callbacks, undefined, {method: 'GET', withCredentials: true}); - }; - return {callback: resp}; - } -}; - -submodule('userId', merkleIdSubmodule); diff --git a/modules/mgidBidAdapter.js b/modules/mgidBidAdapter.js deleted file mode 100644 index 957b9a1d703..00000000000 --- a/modules/mgidBidAdapter.js +++ /dev/null @@ -1,576 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import * as utils from '../src/utils.js'; -import {BANNER, NATIVE} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const storage = getStorageManager(); -const DEFAULT_CUR = 'USD'; -const BIDDER_CODE = 'mgid'; -const ENDPOINT_URL = 'https://prebid.mgid.com/prebid/'; -const LOG_WARN_PREFIX = '[MGID warn]: '; -const LOG_INFO_PREFIX = '[MGID info]: '; -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 - 'DESC': { ID: 5, KEY: 'data', TYPE: 2 }, // please note that type of BODY is also set to 2 - 'PRICE': { ID: 6, KEY: 'price', TYPE: 6 }, - 'SALEPRICE': { ID: 7, KEY: 'saleprice', TYPE: 7 }, - 'DISPLAYURL': { ID: 8, KEY: 'displayurl', TYPE: 11 }, - 'CTA': { ID: 9, KEY: 'cta', TYPE: 12 }, - 'BODY': { ID: 10, KEY: 'body', TYPE: 2 }, // please note that type of DESC is also set to 2 - 'SPONSORED': { ID: 11, KEY: 'sponsored', TYPE: 1 }, // please note that type of SPONSOREDBY is also set to 1 -}; -const NATIVE_ASSET_IMAGE_TYPE = { - 'ICON': 1, - 'IMAGE': 3 -}; -const DEFAULT_IMAGE_WIDTH = 492; -const DEFAULT_IMAGE_HEIGHT = 328; -const DEFAULT_ICON_WIDTH = 50; -const DEFAULT_ICON_HEIGHT = 50; -const DEFAULT_TITLE_LENGTH = 80; - -let isInvalidNativeRequest = false; - -// check if title, image can be added with mandatory field default values -const NATIVE_MINIMUM_REQUIRED_IMAGE_ASSETS = [ - { - id: NATIVE_ASSETS.SPONSOREDBY.ID, - required: true, - data: { - type: 1 - } - }, - { - id: NATIVE_ASSETS.TITLE.ID, - required: true, - }, - { - id: NATIVE_ASSETS.IMAGE.ID, - required: true, - } -]; -let _NATIVE_ASSET_ID_TO_KEY_MAP = {}; -let _NATIVE_ASSET_KEY_TO_ASSET_MAP = {}; - -// loading _NATIVE_ASSET_ID_TO_KEY_MAP -utils._each(NATIVE_ASSETS, anAsset => { _NATIVE_ASSET_ID_TO_KEY_MAP[anAsset.ID] = anAsset.KEY }); -// loading _NATIVE_ASSET_KEY_TO_ASSET_MAP -utils._each(NATIVE_ASSETS, anAsset => { _NATIVE_ASSET_KEY_TO_ASSET_MAP[anAsset.KEY] = anAsset }); - -export const spec = { - VERSION: '1.4', - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, NATIVE], - reId: /^[1-9][0-9]*$/, - NATIVE_ASSET_ID_TO_KEY_MAP: _NATIVE_ASSET_ID_TO_KEY_MAP, - NATIVE_ASSET_KEY_TO_ASSET_MAP: _NATIVE_ASSET_KEY_TO_ASSET_MAP, - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: (bid) => { - const banner = utils.deepAccess(bid, 'mediaTypes.banner'); - const native = utils.deepAccess(bid, 'mediaTypes.native'); - let nativeOk = utils.isPlainObject(native); - if (nativeOk) { - const nativeParams = utils.deepAccess(bid, 'nativeParams'); - let assetsCount = 0; - if (utils.isPlainObject(nativeParams)) { - for (let k in nativeParams) { - let v = nativeParams[k]; - const supportProp = spec.NATIVE_ASSET_KEY_TO_ASSET_MAP.hasOwnProperty(k); - if (supportProp) { - assetsCount++ - } - if (!utils.isPlainObject(v) || (!supportProp && utils.deepAccess(v, 'required'))) { - nativeOk = false; - break; - } - } - } - nativeOk = nativeOk && (assetsCount > 0); - } - let bannerOk = utils.isPlainObject(banner); - if (bannerOk) { - const sizes = utils.deepAccess(banner, 'sizes'); - bannerOk = utils.isArray(sizes) && sizes.length > 0; - for (let f = 0; bannerOk && f < sizes.length; f++) { - bannerOk = sizes[f].length === 2; - } - } - let acc = Number(bid.params.accountId); - let plcmt = Number(bid.params.placementId); - return (bannerOk || nativeOk) && utils.isPlainObject(bid.params) && !!bid.adUnitCode && utils.isStr(bid.adUnitCode) && (plcmt > 0 ? bid.params.placementId.toString().search(spec.reId) === 0 : true) && - !!acc && acc > 0 && bid.params.accountId.toString().search(spec.reId) === 0; - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: (validBidRequests, bidderRequest) => { - utils.logInfo(LOG_INFO_PREFIX + `buildRequests`); - if (validBidRequests.length === 0) { - return; - } - const info = pageInfo(); - const page = info.location || utils.deepAccess(bidderRequest, 'refererInfo.referer') || utils.deepAccess(bidderRequest, 'refererInfo.canonicalUrl'); - const hostname = utils.parseUrl(page).hostname; - let domain = extractDomainFromHost(hostname) || hostname; - const accountId = setOnAny(validBidRequests, 'params.accountId'); - const muid = getLocalStorageSafely('mgMuidn'); - let url = (setOnAny(validBidRequests, 'params.bidUrl') || ENDPOINT_URL) + accountId; - if (utils.isStr(muid) && muid.length > 0) { - url += '?muid=' + muid; - } - const cur = [setOnAny(validBidRequests, 'params.currency') || setOnAny(validBidRequests, 'params.cur') || config.getConfig('currency.adServerCurrency') || DEFAULT_CUR]; - const secure = window.location.protocol === 'https:' ? 1 : 0; - let imp = []; - validBidRequests.forEach(bid => { - let tagid = utils.deepAccess(bid, 'params.placementId') || 0; - tagid = !tagid ? bid.adUnitCode : tagid + '/' + bid.adUnitCode; - let impObj = { - id: bid.bidId, - tagid, - secure, - }; - const bidFloor = utils.deepAccess(bid, 'params.bidFloor') || utils.deepAccess(bid, 'params.bidfloor') || 0; - if (bidFloor && utils.isNumber(bidFloor)) { - impObj.bidfloor = bidFloor; - } - for (let mediaTypes in bid.mediaTypes) { - switch (mediaTypes) { - case BANNER: - impObj.banner = createBannerRequest(bid); - imp.push(impObj); - break; - case NATIVE: - const native = createNativeRequest(bid.nativeParams); - if (!isInvalidNativeRequest) { - impObj.native = { - 'request': native - }; - imp.push(impObj); - } - break; - } - } - }); - - if (imp.length === 0) { - return; - } - - let request = { - id: utils.deepAccess(bidderRequest, 'bidderRequestId'), - site: {domain, page}, - cur: cur, - geo: {utcoffset: info.timeOffset}, - device: { - ua: navigator.userAgent, - js: 1, - dnt: (navigator.doNotTrack === 'yes' || navigator.doNotTrack === '1' || navigator.msDoNotTrack === '1') ? 1 : 0, - h: screen.height, - w: screen.width, - language: getLanguage() - }, - ext: {mgid_ver: spec.VERSION, prebid_ver: $$PREBID_GLOBAL$$.version}, - imp - }; - if (bidderRequest && bidderRequest.gdprConsent) { - request.user = {ext: {consent: bidderRequest.gdprConsent.consentString}}; - request.regs = {ext: {gdpr: (bidderRequest.gdprConsent.gdprApplies ? 1 : 0)}} - } - if (info.referrer) { - request.site.ref = info.referrer - } - utils.logInfo(LOG_INFO_PREFIX + `buildRequest:`, request); - return { - method: 'POST', - url: url, - data: JSON.stringify(request), - }; - }, - /** - * Unpack the 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. - */ - interpretResponse: (serverResponse, bidRequests) => { - utils.logInfo(LOG_INFO_PREFIX + `interpretResponse`, serverResponse); - if (serverResponse == null || serverResponse.body == null || serverResponse.body === '' || !utils.isArray(serverResponse.body.seatbid) || !serverResponse.body.seatbid.length) { - return; - } - const returnedBids = []; - const muidn = utils.deepAccess(serverResponse.body, 'ext.muidn') - if (utils.isStr(muidn) && muidn.length > 0) { - setLocalStorageSafely('mgMuidn', muidn) - } - serverResponse.body.seatbid.forEach((bids) => { - bids.bid.forEach((bid) => { - const pbid = prebidBid(bid, serverResponse.body.cur); - if (pbid.mediaType === NATIVE && utils.isEmpty(pbid.native)) { - return; - } - returnedBids.push(pbid); - }) - }); - - utils.logInfo(LOG_INFO_PREFIX + `interpretedResponse`, returnedBids); - return returnedBids; - }, - onBidWon: (bid) => { - const cpm = utils.deepAccess(bid, 'adserverTargeting.hb_pb') || ''; - if (utils.isStr(bid.nurl) && bid.nurl !== '') { - bid.nurl = bid.nurl.replace( - /\${AUCTION_PRICE}/, - cpm - ); - utils.triggerPixel(bid.nurl); - } - if (bid.isBurl) { - if (bid.mediaType === BANNER) { - bid.ad = bid.ad.replace( - /\${AUCTION_PRICE}/, - cpm - ) - } else { - bid.burl = bid.burl.replace( - /\${AUCTION_PRICE}/, - cpm - ); - utils.triggerPixel(bid.burl); - } - } - utils.logInfo(LOG_INFO_PREFIX + `onBidWon`); - }, - getUserSyncs: (syncOptions, serverResponses) => { - utils.logInfo(LOG_INFO_PREFIX + `getUserSyncs`); - } -}; - -registerBidder(spec); - -function setOnAny(collection, key) { - for (let i = 0, result; i < collection.length; i++) { - result = utils.deepAccess(collection[i], key); - if (result) { - return result; - } - } -} - -/** - * Unpack the Server's Bid into a Prebid-compatible one. - * @param serverBid - * @return Bid - */ -function prebidBid(serverBid, cur) { - if (!utils.isStr(cur) || cur === '') { - cur = DEFAULT_CUR; - } - const bid = { - requestId: serverBid.impid, - ad: serverBid.adm, - cpm: serverBid.price, - creativeId: serverBid.adid, - currency: cur, - dealId: serverBid.dealid || '', - width: serverBid.w, - height: serverBid.h, - mediaType: 'banner', - netRevenue: true, - ttl: serverBid.ttl || 300, - nurl: serverBid.nurl || '', - burl: serverBid.burl || '', - isBurl: utils.isStr(serverBid.burl) && serverBid.burl.length > 0, - }; - setMediaType(serverBid, bid); - switch (bid.mediaType) { - case BANNER: - break; - case NATIVE: - parseNativeResponse(serverBid, bid); - break; - } - return bid; -} - -function setMediaType(bid, newBid) { - if (utils.deepAccess(bid, 'ext.crtype') === 'native') { - newBid.mediaType = NATIVE; - } else { - newBid.mediaType = BANNER; - } -} - -function extractDomainFromHost(pageHost) { - if (pageHost == 'localhost') { - return 'localhost' - } - let domain = null; - try { - let domains = /[-\w]+\.([-\w]+|[-\w]{3,}|[-\w]{1,3}\.[-\w]{2})$/i.exec(pageHost); - if (domains != null && domains.length > 0) { - domain = domains[0]; - for (let i = 1; i < domains.length; i++) { - if (domains[i].length > domain.length) { - domain = domains[i]; - } - } - } - } catch (e) { - domain = null; - } - return domain; -} - -function getLanguage() { - const language = navigator.language ? 'language' : 'userLanguage'; - const lang2 = navigator[language].split('-')[0]; - if (lang2.length === 2 || lang2.length === 3) { - return lang2; - } - return ''; -} - -function getLocalStorageSafely(key) { - try { - return storage.getDataFromLocalStorage(key); - } catch (e) { - return null; - } -} - -function setLocalStorageSafely(key, val) { - try { - return storage.setDataInLocalStorage(key, val); - } catch (e) { - return null; - } -} - -function createBannerRequest(bid) { - const sizes = utils.deepAccess(bid, 'mediaTypes.banner.sizes'); - let format = []; - 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]}); - } - } - } - let r = { - w: sizes && sizes[0][0], - h: sizes && sizes[0][1], - }; - if (format.length) { - r.format = format - } - return r -} - -function createNativeRequest(params) { - let nativeRequestObject = { - plcmtcnt: 1, - assets: [] - }; - for (let key in params) { - let assetObj = {}; - if (params.hasOwnProperty(key)) { - if (!(nativeRequestObject.assets && nativeRequestObject.assets.length > 0 && nativeRequestObject.assets.hasOwnProperty(key))) { - switch (key) { - case NATIVE_ASSETS.TITLE.KEY: - assetObj = { - id: NATIVE_ASSETS.TITLE.ID, - required: params[key].required ? 1 : 0, - title: { - len: params[key].len || params[key].length || DEFAULT_TITLE_LENGTH - } - }; - break; - case NATIVE_ASSETS.IMAGE.KEY: - const wmin = params[key].wmin || params[key].minimumWidth || (utils.isArray(params[key].minsizes) && params[key].minsizes.length > 0 ? params[key].minsizes[0] : 0); - const hmin = params[key].hmin || params[key].minimumHeight || (utils.isArray(params[key].minsizes) && params[key].minsizes.length > 1 ? params[key].minsizes[1] : 0); - assetObj = { - id: NATIVE_ASSETS.IMAGE.ID, - required: params[key].required ? 1 : 0, - img: { - type: NATIVE_ASSET_IMAGE_TYPE.IMAGE, - w: params[key].w || params[key].width || (utils.isArray(params[key].sizes) && params[key].sizes.length > 0 ? params[key].sizes[0] : 0), - h: params[key].h || params[key].height || (utils.isArray(params[key].sizes) && params[key].sizes.length > 1 ? params[key].sizes[1] : 0), - mimes: params[key].mimes, - ext: params[key].ext, - } - }; - if (wmin > 0) { - assetObj.img.wmin = wmin; - } - if (hmin > 0) { - assetObj.img.hmin = hmin; - } - if (!assetObj.img.w) { - assetObj.img.w = DEFAULT_IMAGE_WIDTH; - } - if (!assetObj.img.h) { - assetObj.img.h = DEFAULT_IMAGE_HEIGHT; - } - break; - case NATIVE_ASSETS.ICON.KEY: - assetObj = { - id: NATIVE_ASSETS.ICON.ID, - required: params[key].required ? 1 : 0, - img: { - type: NATIVE_ASSET_IMAGE_TYPE.ICON, - w: params[key].w || params[key].width || (utils.isArray(params[key].sizes) && params[key].sizes.length > 0 ? params[key].sizes[0] : 0), - h: params[key].h || params[key].height || (utils.isArray(params[key].sizes) && params[key].sizes.length > 0 ? params[key].sizes[1] : 0), - } - }; - if (!assetObj.img.w) { - assetObj.img.w = DEFAULT_ICON_WIDTH; - } - if (!assetObj.img.h) { - assetObj.img.h = DEFAULT_ICON_HEIGHT; - } - break; - case NATIVE_ASSETS.SPONSORED.KEY: - case NATIVE_ASSETS.SPONSOREDBY.KEY: - case NATIVE_ASSETS.PRICE.KEY: - case NATIVE_ASSETS.SALEPRICE.KEY: - case NATIVE_ASSETS.DESC.KEY: - case NATIVE_ASSETS.BODY.KEY: - case NATIVE_ASSETS.DISPLAYURL.KEY: - case NATIVE_ASSETS.CTA.KEY: - assetObj = commonNativeRequestObject(spec.NATIVE_ASSET_KEY_TO_ASSET_MAP[key], params); - break; - default: - if (params[key].required) { - isInvalidNativeRequest = true; - return; - } - } - } - } - if (assetObj.id) { - nativeRequestObject.assets[nativeRequestObject.assets.length] = assetObj; - } - } - - // for native image adtype prebid has to have few required assests i.e. title,sponsoredBy, image - // if any of these are missing from the request then request will not be sent - let requiredAssetCount = NATIVE_MINIMUM_REQUIRED_IMAGE_ASSETS.length; - let presentrequiredAssetCount = 0; - NATIVE_MINIMUM_REQUIRED_IMAGE_ASSETS.forEach(ele => { - let lengthOfExistingAssets = nativeRequestObject.assets.length; - for (let i = 0; i < lengthOfExistingAssets; i++) { - if (ele.id === nativeRequestObject.assets[i].id) { - presentrequiredAssetCount++; - break; - } else { - if (ele.id === 4 && nativeRequestObject.assets[i].id === 11) { - if (utils.deepAccess(nativeRequestObject.assets[i], 'data.type') === ele.data.type) { - presentrequiredAssetCount++; - break; - } - } - } - } - }); - isInvalidNativeRequest = requiredAssetCount !== presentrequiredAssetCount; - return nativeRequestObject; -} - -function commonNativeRequestObject(nativeAsset, params) { - const key = nativeAsset.KEY; - return { - id: nativeAsset.ID, - required: params[key].required ? 1 : 0, - data: { - type: nativeAsset.TYPE, - len: params[key].len, - ext: params[key].ext - } - }; -} - -function parseNativeResponse(bid, newBid) { - newBid.native = {}; - if (bid.hasOwnProperty('adm')) { - let adm = ''; - try { - adm = JSON.parse(bid.adm); - } catch (ex) { - utils.logWarn(LOG_WARN_PREFIX + 'Error: Cannot parse native response for ad response: ' + newBid.adm); - return; - } - if (adm && adm.native && adm.native.assets && adm.native.assets.length > 0) { - newBid.mediaType = NATIVE; - for (let i = 0, len = adm.native.assets.length; i < len; i++) { - switch (adm.native.assets[i].id) { - case NATIVE_ASSETS.TITLE.ID: - newBid.native.title = adm.native.assets[i].title && adm.native.assets[i].title.text; - break; - case NATIVE_ASSETS.IMAGE.ID: - newBid.native.image = { - url: adm.native.assets[i].img && adm.native.assets[i].img.url, - height: adm.native.assets[i].img && adm.native.assets[i].img.h, - width: adm.native.assets[i].img && adm.native.assets[i].img.w, - }; - break; - case NATIVE_ASSETS.ICON.ID: - newBid.native.icon = { - url: adm.native.assets[i].img && adm.native.assets[i].img.url, - height: adm.native.assets[i].img && adm.native.assets[i].img.h, - width: adm.native.assets[i].img && adm.native.assets[i].img.w, - }; - break; - case NATIVE_ASSETS.SPONSOREDBY.ID: - case NATIVE_ASSETS.SPONSORED.ID: - case NATIVE_ASSETS.PRICE: - case NATIVE_ASSETS.SALEPRICE.ID: - case NATIVE_ASSETS.DESC.ID: - case NATIVE_ASSETS.BODY.ID: - case NATIVE_ASSETS.DISPLAYURL.ID: - case NATIVE_ASSETS.CTA.ID: - newBid.native[spec.NATIVE_ASSET_ID_TO_KEY_MAP[adm.native.assets[i].id]] = adm.native.assets[i].data && adm.native.assets[i].data.value; - break; - } - } - newBid.native.clickUrl = adm.native.link && adm.native.link.url; - newBid.native.clickTrackers = (adm.native.link && adm.native.link.clicktrackers) || []; - newBid.native.impressionTrackers = adm.native.imptrackers || []; - newBid.native.jstracker = adm.native.jstracker || []; - newBid.width = 0; - newBid.height = 0; - } - } -} - -function pageInfo() { - var w, d, l, r, m, p, t; - for (w = window, d = w.document, l = d.location.href, r = d.referrer, m = 0, t = new Date(); w !== w.parent;) { - try { - p = w.parent; l = p.location.href; r = p.document.referrer; w = p; - } catch (e) { - m = top !== w.parent ? 2 : 1; - break - } - } - return { - location: l, - referrer: r || '', - masked: m, - wWidth: w.innerWidth, - wHeight: w.innerHeight, - date: t.toUTCString(), - timeOffset: t.getTimezoneOffset() - }; -} diff --git a/modules/mgidBidAdapter.md b/modules/mgidBidAdapter.md deleted file mode 100644 index 8ab59c2247f..00000000000 --- a/modules/mgidBidAdapter.md +++ /dev/null @@ -1,86 +0,0 @@ -# Overview - -``` -Module Name: Mgid Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid@mgid.com -``` - -# Description - -One of the easiest way to gain access to MGID demand sources - MGID header bidding adapter. - -MGID header bidding adapter connects with MGID demand sources to fetch bids for display placements - -# Test Parameters - - -300x600 banner test -``` -var adUnits = [{ - code: 'div-prebid', - mediaTypes: { - banner: { - sizes: [[300, 600]] - } - }, - // Replace this object to test a new Adapter! - bids: [{ - bidder: 'mgid', - params : { - accountId : "219", //test accountId, please replace after test - placementId : "331749" // 300x600 test placementId, please replace after test - } - }] -}]; -``` - -300x250 banner test -``` -var adUnits = [{ - code: 'div-prebid', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - // Replace this object to test a new Adapter! - bids: [{ - bidder: 'mgid', - params : { - accountId : "219", //test accountId, please replace after test - placementId : "331748" // 300x250 test placementId, please replace after test - } - }] -}]; -``` - -# Bid Parameters -## Banner - -| Name | Scope | Type | Description | Example -| ---- | ----- | ---- | ----------- | ------- -| `accountId` | required | String | The account ID from Mgid | "123" -| `placementId` | required | String | The placement ID from Mgid | "123456" - - -# Ad Unit and page Setup: - -```html - - - -``` diff --git a/modules/microadBidAdapter.js b/modules/microadBidAdapter.js deleted file mode 100644 index 9611946b495..00000000000 --- a/modules/microadBidAdapter.js +++ /dev/null @@ -1,151 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'microad'; - -const ENDPOINT_URLS = { - 'production': 'https://s-rtb-pb.send.microad.jp/prebid', - 'test': 'https://rtbtest.send.microad.jp/prebid' -}; -export let ENVIRONMENT = 'production'; - -/* eslint-disable no-template-curly-in-string */ -const EXT_URL_STRING = '${COMPASS_EXT_URL}'; -const EXT_REF_STRING = '${COMPASS_EXT_REF}'; -const EXT_IFA_STRING = '${COMPASS_EXT_IFA}'; -const EXT_APPID_STRING = '${COMPASS_EXT_APPID}'; -const EXT_GEO_STRING = '${COMPASS_EXT_GEO}'; -/* eslint-enable no-template-curly-in-string */ - -const BANNER_CODE = 1; -const NATIVE_CODE = 2; -const VIDEO_CODE = 4; - -function createCBT() { - const randomValue = Math.floor(Math.random() * Math.pow(10, 18)).toString(16); - const date = new Date().getTime().toString(16); - return randomValue + date; -} - -function createBitSequenceFromMediaType(hi, code) { - return (hi ? -1 : 0) & code; -} - -function convertMediaTypes(bid) { - return createBitSequenceFromMediaType(bid.mediaTypes.banner, BANNER_CODE) | - createBitSequenceFromMediaType(bid.mediaTypes.native, NATIVE_CODE) | - createBitSequenceFromMediaType(bid.mediaTypes.video, VIDEO_CODE); -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - isBidRequestValid: function(bid) { - return !!(bid && bid.params && bid.params.spot && bid.mediaTypes && (bid.mediaTypes.banner || bid.mediaTypes.native || bid.mediaTypes.video)); - }, - buildRequests: function(validBidRequests, bidderRequest) { - const requests = []; - - validBidRequests.forEach(bid => { - const bidParams = bid.params; - const params = { - spot: bidParams.spot, - url: bidderRequest.refererInfo.canonicalUrl || window.location.href, - referrer: bidderRequest.refererInfo.referer, - bid_id: bid.bidId, - transaction_id: bid.transactionId, - media_types: convertMediaTypes(bid), - cbt: createCBT() - }; - - if (bidParams.url) { - params['url_macro'] = bidParams.url.replace(EXT_URL_STRING, ''); - } - - if (bidParams.referrer) { - params['referrer_macro'] = bidParams.referrer.replace(EXT_REF_STRING, ''); - } - - if (bidParams.ifa) { - params['ifa'] = bidParams.ifa.replace(EXT_IFA_STRING, ''); - } - - if (bidParams.appid) { - params['appid'] = bidParams.appid.replace(EXT_APPID_STRING, ''); - } - - if (bidParams.geo) { - const geo = bidParams.geo.replace(EXT_GEO_STRING, ''); - if (/^[0-9.\-]+,[0-9.\-]+$/.test(geo)) { - params['geo'] = geo; - } - } - - requests.push({ - method: 'GET', - url: ENDPOINT_URLS[ENVIRONMENT], - data: params, - options: { Accept: 'application/json' } - }); - }); - return requests; - }, - interpretResponse: function(serverResponse) { - const body = serverResponse.body; - const bidResponses = []; - - if (body.cpm && body.cpm > 0) { - const bidResponse = { - requestId: body.requestId, - cpm: body.cpm, - width: body.width, - height: body.height, - ad: body.ad, - ttl: body.ttl, - creativeId: body.creativeId, - netRevenue: body.netRevenue, - currency: body.currency, - }; - - if (body.dealId) { - bidResponse['dealId'] = body.dealId; - } - - bidResponses.push(bidResponse); - } - - return bidResponses; - }, - getUserSyncs: function(syncOptions, serverResponses) { - const syncs = []; - - if (!syncOptions.iframeEnabled && !syncOptions.pixelEnabled) { - return syncs; - } - - serverResponses.forEach(resp => { - const syncIframeUrls = resp.body.syncUrls.iframe; - const syncImageUrls = resp.body.syncUrls.image; - if (syncOptions.iframeEnabled && syncIframeUrls) { - syncIframeUrls.forEach(syncIframeUrl => { - syncs.push({ - type: 'iframe', - url: syncIframeUrl - }); - }); - } - if (syncOptions.pixelEnabled && syncImageUrls) { - syncImageUrls.forEach(syncImageUrl => { - syncs.push({ - type: 'image', - url: syncImageUrl - }); - }); - } - }); - - return syncs; - } -}; - -registerBidder(spec); diff --git a/modules/microadBidAdapter.md b/modules/microadBidAdapter.md deleted file mode 100644 index c805e5cf6fb..00000000000 --- a/modules/microadBidAdapter.md +++ /dev/null @@ -1,28 +0,0 @@ -# Overview - -Module Name: MicroAd SSP Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid@microad.co.jp - -# Description - -Module that connects to MicroAd SSP demand sources. - -# Test Parameters - -```javascript - var adUnits = [ - code: '209e56872ae8b0442a60477ae0c58be9', - mediaTypes: { - banner: { - sizes: [[200, 200]] - } - }, - bids: [{ - bidder: 'microad', - params: { - spot: '209e56872ae8b0442a60477ae0c58be9' - } - }] - ]; -``` diff --git a/modules/missenaBidAdapter.js b/modules/missenaBidAdapter.js deleted file mode 100644 index 2b1d6bdb118..00000000000 --- a/modules/missenaBidAdapter.js +++ /dev/null @@ -1,94 +0,0 @@ -import * as utils from '../src/utils.js'; -import { BANNER } from '../src/mediaTypes.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'missena'; -const ENDPOINT_URL = 'https://bid.missena.io/'; - -export const spec = { - aliases: [BIDDER_CODE], - code: BIDDER_CODE, - gvlid: 687, - supportedMediaTypes: [BANNER], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return typeof bid == 'object' && !!bid.params.apiKey; - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - return validBidRequests.map((bidRequest) => { - const payload = { - request_id: bidRequest.bidId, - timeout: bidderRequest.timeout, - }; - - if (bidderRequest && bidderRequest.refererInfo) { - payload.referer = bidderRequest.refererInfo.referer; - payload.referer_canonical = bidderRequest.refererInfo.canonicalUrl; - } - - if (bidderRequest && bidderRequest.gdprConsent) { - payload.consent_string = bidderRequest.gdprConsent.consentString; - payload.consent_required = bidderRequest.gdprConsent.gdprApplies; - } - - return { - method: 'POST', - url: - ENDPOINT_URL + - '?' + - utils.formatQS({ - t: bidRequest.params.apiKey, - }), - data: JSON.stringify(payload), - }; - }); - }, - - /** - * Unpack the 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. - */ - interpretResponse: function (serverResponse, bidRequest) { - const bidResponses = []; - const response = serverResponse.body; - - if (response && !response.timeout && !!response.ad) { - bidResponses.push(response); - } - - return bidResponses; - }, - - /** - * Register bidder specific code, which will execute if bidder timed out after an auction - * @param {data} Containing timeout specific data - */ - onTimeout: function onTimeout(timeoutData) { - utils.logInfo('Missena - Timeout from adapter', timeoutData); - }, - - /** - * Register bidder specific code, which@ will execute if a bid from this bidder won the auction - * @param {Bid} The bid that won the auction - */ - onBidWon: function (bid) { - utils.logInfo('Missena - Bid won', bid); - }, -}; - -registerBidder(spec); diff --git a/modules/missenaBidAdapter.md b/modules/missenaBidAdapter.md deleted file mode 100644 index d5fcacf04ab..00000000000 --- a/modules/missenaBidAdapter.md +++ /dev/null @@ -1,70 +0,0 @@ -# Overview - -``` -Module Name: Missena Bid Adapter -Module Type: Bidder Adapter -Maintainer: jney@missena.com -``` - -## Introduction - -Connects to Missena for bids. - -**Note:** this adapter doesn't support SafeFrame. - -Useful resources: - -- [README](../README.md#Build) -- [https://docs.prebid.org/dev-docs/bidder-adaptor.html](https://docs.prebid.org/dev-docs/bidder-adaptor.html) - -## Develop - -Setup the missena adapter in `integrationExamples/gpt/userId_example.html`. - -For example: - -```js -const AD_UNIT_CODE = "test-div"; -const PUBLISHER_MISSENA_TOKEN = "PA-34745704"; - -var adUnits = [ - { - code: AD_UNIT_CODE, - mediaTypes: { - banner: { - sizes: [1, 1], - }, - }, - bids: [ - { - bidder: "missena", - params: { - apiKey: PUBLISHER_MISSENA_TOKEN, - }, - }, - ], - }, -]; -``` - -Then start the demo app: - -```shell -gulp serve-fast --modules=missenaBidAdapter -``` - -And open [http://localhost:9999/integrationExamples/gpt/userId_example.html](http://localhost:9999/integrationExamples/gpt/userId_example.html) - -## Test - -```shell -gulp test --file test/spec/modules/missenaBidAdapter_spec.js -``` - -Add the `--watch` option to re-run unit tests whenever the source code changes. - -## Build - -```shell -gulp build --modules=missenaBidAdapter -``` diff --git a/modules/mobfoxBidAdapter.js b/modules/mobfoxBidAdapter.js deleted file mode 100644 index 7c356e71089..00000000000 --- a/modules/mobfoxBidAdapter.js +++ /dev/null @@ -1,133 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; - -const utils = require('../src/utils.js'); -const BIDDER_CODE = 'mobfox'; -const BID_REQUEST_BASE_URL = 'https://my.mobfox.com/request.php'; -const CPM_HEADER = 'X-Pricing-CPM'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['mf'], // short code - isBidRequestValid: function (bid) { - return bid.params.s !== null && bid.params.s !== undefined; - }, - buildRequests: function (validBidRequests) { - if (validBidRequests.length > 1) { - throw ('invalid number of valid bid requests, expected 1 element') - } - - let bidParams = validBidRequests[0].params; - let bid = validBidRequests[0]; - - let params = { - // -------------------- Mandatory Parameters ------------------ - rt: bidParams.rt || 'api-fetchip', - r_type: bidParams.r_type || 'banner', - r_resp: bidParams.r_resp || 'json', // string | vast20 - // i: bidParams.i || undefined , // string | 69.197.148.18 - s: bidParams.s, // string | 80187188f458cfde788d961b6882fd53 - u: bidParams.u || window.navigator.userAgent, // string - - // ------------------- Global Parameters ---------------------- - adspace_width: bidParams.adspace_width || bid.sizes[0][0], // integer | 320 - adspace_height: bidParams.adspace_height || bid.sizes[0][1], // integer | 48 - r_floor: bidParams.r_floor || undefined, // 0.8 - - o_andadvid: bidParams.o_andadvid || undefined, // 'c6292267-56ad-4326-965d-deef6fcd5er9' - longitude: bidParams.longitude || undefined, // 12.12 - latitude: bidParams.latitude || undefined, // 280.12 - demo_age: bidParams.demo_age || undefined, // 1978 - - // ------------------- banner / interstitial ---------------------- - adspace_strict: bidParams.adspace_strict || undefined, - - // ------------------- interstitial / video ---------------------- - imp_instl: bidParams.imp_instl || undefined, // integer | 1 - - // ------------------- mraid ---------------------- - c_mraid: bidParams.c_mraid || undefined, // integer | 1 - - // ------------------- video ---------------------- - v_dur_min: bidParams.v_dur_min || undefined, // integer | 0 - v_dur_max: bidParams.v_dur_max || undefined, // integer | 999 - v_autoplay: bidParams.v_autoplay || undefined, // integer | 1 - v_startmute: bidParams.v_startmute || undefined, // integer | 0 - v_rewarded: bidParams.v_rewarded || undefined, // integer | 0 - v_api: bidParams.v_api || undefined, // string | vpaid20 - n_ver: bidParams.n_ver || undefined, // - n_adunit: bidParams.n_adunit || undefined, // - n_layout: bidParams.n_layout || undefined, // - n_context: bidParams.n_context || undefined, // - n_plcmttype: bidParams.n_plcmttype || undefined, // - n_img_icon_req: bidParams.n_img_icon_req || undefined, // boolean0 - n_img_icon_size: bidParams.n_img_icon_size || undefined, // string80 - n_img_large_req: bidParams.n_img_large_req || undefined, // boolean0 - n_img_large_w: bidParams.n_img_large_w || undefined, // integer1200 - n_img_large_h: bidParams.n_img_large_h || undefined, // integer627 - n_title_req: bidParams.n_title_req || undefined, // boolean0 - n_title_len: bidParams.n_title_len || undefined, // string25 - n_desc_req: bidParams.n_desc_req || undefined, // boolean0 - n_desc_len: bidParams.n_desc_len || undefined, // string140 - n_rating_req: bidParams.n_rating_req || undefined - }; - - let payloadString = buildPayloadString(params); - - return { - method: 'GET', - url: BID_REQUEST_BASE_URL, - data: payloadString, - requestId: bid.bidId - }; - }, - interpretResponse: function (serverResponse, bidRequest) { - const bidResponses = []; - let serverResponseBody = serverResponse.body; - - if (!serverResponseBody || serverResponseBody.error) { - let errorMessage = `in response for ${BIDDER_CODE} adapter`; - if (serverResponseBody && serverResponseBody.error) { - errorMessage += `: ${serverResponseBody.error}`; - } - utils.logError(errorMessage); - return bidResponses; - } - try { - let serverResponseHeaders = serverResponse.headers; - let bidRequestData = bidRequest.data.split('&'); - const bidResponse = { - requestId: bidRequest.requestId, - cpm: serverResponseHeaders.get(CPM_HEADER), - width: bidRequestData[5].split('=')[1], - height: bidRequestData[6].split('=')[1], - creativeId: bidRequestData[3].split('=')[1], - currency: 'USD', - netRevenue: true, - ttl: 360, - referrer: serverResponseBody.request.clickurl, - ad: serverResponseBody.request.htmlString - }; - bidResponses.push(bidResponse); - } catch (e) { - throw 'could not build bid response: ' + e; - } - return bidResponses; - } -}; - -function buildPayloadString(params) { - for (let key in params) { - if (params.hasOwnProperty(key)) { - if (params[key] === undefined) { - delete params[key]; - } else { - params[key] = encodeURIComponent(params[key]); - } - } - } - - return utils._map(Object.keys(params), key => `${key}=${params[key]}`) - .join('&') -} - -registerBidder(spec); diff --git a/modules/mobfoxBidAdapter.md b/modules/mobfoxBidAdapter.md deleted file mode 100644 index 31b60606d2f..00000000000 --- a/modules/mobfoxBidAdapter.md +++ /dev/null @@ -1,29 +0,0 @@ -# Overview - -``` -Module Name: Mobfox Bidder Adapter -Module Type: Bidder Adapter -Maintainer: solutions-team@matomy.com -``` - -# Description - -Module that connects to Mobfox's demand sources - -# Test Parameters -``` - var adUnits = [{ - code: 'div-gpt-ad-1460505748561-0', - sizes: [[320, 480], [300, 250], [300,600]], - - // Replace this object to test a new Adapter! - bids: [{ - bidder: 'mobfox', - params: { - s: "267d72ac3f77a3f447b32cf7ebf20673", // required - The hash of your inventory to identify which app is making the request, - imp_instl: 1 // optional - set to 1 if using interstitial otherwise delete or set to 0 - } - }] - - }]; -``` diff --git a/modules/mobfoxpbBidAdapter.js b/modules/mobfoxpbBidAdapter.js deleted file mode 100644 index c7e96b95179..00000000000 --- a/modules/mobfoxpbBidAdapter.js +++ /dev/null @@ -1,99 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; - -const BIDDER_CODE = 'mobfoxpb'; -const AD_URL = 'https://bes.mobfox.com/?c=o&m=multi'; - -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency) { - return false; - } - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl); - case NATIVE: - return Boolean(bid.native && bid.native.impressionTrackers); - default: - return false; - } -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO, NATIVE], - - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && bid.params && !isNaN(parseInt(bid.params.placementId))); - }, - - buildRequests: (validBidRequests = [], bidderRequest) => { - const winTop = utils.getWindowTop(); - const location = winTop.location; - const placements = []; - const request = { - 'deviceWidth': winTop.screen.width, - 'deviceHeight': winTop.screen.height, - 'language': (navigator && navigator.language) ? navigator.language.split('-')[0] : '', - 'secure': 1, - 'host': location.host, - 'page': location.pathname, - 'placements': placements - }; - - if (bidderRequest) { - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - if (bidderRequest.gdprConsent) { - request.gdpr = bidderRequest.gdprConsent - } - } - - const len = validBidRequests.length; - for (let i = 0; i < len; i++) { - const bid = validBidRequests[i]; - const placement = { - placementId: bid.params.placementId, - bidId: bid.bidId, - schain: bid.schain || {}, - }; - const mediaType = bid.mediaTypes - - if (mediaType && mediaType[BANNER] && mediaType[BANNER].sizes) { - placement.sizes = mediaType[BANNER].sizes; - placement.traffic = BANNER; - } else if (mediaType && mediaType[VIDEO] && mediaType[VIDEO].playerSize) { - placement.wPlayer = mediaType[VIDEO].playerSize[0]; - placement.hPlayer = mediaType[VIDEO].playerSize[1]; - placement.traffic = VIDEO; - } else if (mediaType && mediaType[NATIVE]) { - placement.native = mediaType[NATIVE]; - placement.traffic = NATIVE; - } - placements.push(placement); - } - - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - response.push(resItem); - } - } - return response; - }, -}; - -registerBidder(spec); diff --git a/modules/mobfoxpbBidAdapter.md b/modules/mobfoxpbBidAdapter.md deleted file mode 100644 index 6eb549919d7..00000000000 --- a/modules/mobfoxpbBidAdapter.md +++ /dev/null @@ -1,72 +0,0 @@ -# Overview - -``` -Module Name: mobfox Bidder Adapter -Module Type: mobfox Bidder Adapter -Maintainer: platform@mobfox.com -``` - -# Description - -Module that connects to mobfox demand sources - -# Test Parameters -``` - var adUnits = [ - { - code:'1', - mediaTypes:{ - banner: { - sizes: [[300, 250]], - } - }, - bids:[ - { - bidder: 'mobfoxpb', - params: { - placementId: 0 - } - } - ] - }, - { - code:'1', - mediaTypes:{ - video: { - playerSize: [640, 480], - context: 'instream' - } - }, - bids:[ - { - bidder: 'mobfoxpb', - params: { - placementId: 0 - } - } - ] - }, - { - code:'1', - mediaTypes:{ - native: { - title: { - required: true - }, - icon: { - required: true, - size: [64, 64] - } - } - }, - bids:[ - { - bidder: 'mobfoxpb', - params: { - placementId: 0 - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/mobsmartBidAdapter.js b/modules/mobsmartBidAdapter.js deleted file mode 100644 index e5ff38ec69a..00000000000 --- a/modules/mobsmartBidAdapter.js +++ /dev/null @@ -1,94 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { config } from '../src/config.js'; - -const BIDDER_CODE = 'mobsmart'; -const ENDPOINT = 'https://prebid.mobsmart.net/prebid/endpoint'; - -export const spec = { - code: BIDDER_CODE, - isBidRequestValid: function(bid) { - if (bid.bidder !== BIDDER_CODE) { - return false; - } - - return true; - }, - buildRequests: function(validBidRequests, bidderRequest) { - const timeout = config.getConfig('bidderTimeout'); - const referrer = encodeURIComponent(bidderRequest.refererInfo.referer); - - return validBidRequests.map(bidRequest => { - const adUnit = { - code: bidRequest.adUnitCode, - bids: { - bidder: bidRequest.bidder, - params: bidRequest.params - }, - mediaTypes: bidRequest.mediaTypes - }; - - if (bidRequest.hasOwnProperty('sizes') && bidRequest.sizes.length > 0) { - adUnit.sizes = bidRequest.sizes; - } - - const request = { - auctionId: bidRequest.auctionId, - requestId: bidRequest.bidId, - bidRequestsCount: bidRequest.bidRequestsCount, - bidderRequestId: bidRequest.bidderRequestId, - transactionId: bidRequest.transactionId, - referrer: referrer, - timeout: timeout, - adUnit: adUnit - }; - - if (bidRequest.userId && bidRequest.userId.pubcid) { - request.userId = {pubcid: bidRequest.userId.pubcid}; - } - - return { - method: 'POST', - url: ENDPOINT, - data: JSON.stringify(request) - } - }); - }, - interpretResponse: function(serverResponse) { - const bidResponses = []; - - if (serverResponse.body) { - const response = serverResponse.body; - const bidResponse = { - requestId: response.requestId, - cpm: response.cpm, - width: response.width, - height: response.height, - creativeId: response.creativeId, - currency: response.currency, - netRevenue: response.netRevenue, - ttl: response.ttl, - ad: response.ad, - }; - bidResponses.push(bidResponse); - } - - return bidResponses; - }, - getUserSyncs: function(syncOptions, serverResponses) { - let syncs = []; - if (syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: 'https://tags.mobsmart.net/tags/iframe' - }); - } else if (syncOptions.pixelEnabled) { - syncs.push({ - type: 'image', - url: 'https://tags.mobsmart.net/tags/image' - }); - } - - return syncs; - } -} -registerBidder(spec); diff --git a/modules/mobsmartBidAdapter.md b/modules/mobsmartBidAdapter.md deleted file mode 100644 index 1240d6db494..00000000000 --- a/modules/mobsmartBidAdapter.md +++ /dev/null @@ -1,50 +0,0 @@ -# Overview - -``` -Module Name: Mobsmart Bidder Adapter -Module Type: Bidder Adapter -Maintainer: adx@kpis.jp -``` - -# Description - -Module that connects to Mobsmart demand sources to fetch bids. - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 250]], // a display size - } - }, - bids: [ - { - bidder: "mobsmart", - params: { - floorPrice: 100, - currency: 'JPY' - } - } - ] - },{ - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[320, 50]], // a mobile size - } - }, - bids: [ - { - bidder: "mobsmart", - params: { - floorPrice: 90, - currency: 'JPY' - } - } - ] - } - ]; -``` diff --git a/modules/multibid/index.js b/modules/multibid/index.js deleted file mode 100644 index dd4999b2dca..00000000000 --- a/modules/multibid/index.js +++ /dev/null @@ -1,234 +0,0 @@ -/** - * This module adds Multibid support to prebid.js - * @module modules/multibid - */ - -import {config} from '../../src/config.js'; -import {setupBeforeHookFnOnce, getHook} from '../../src/hook.js'; -import * as utils from '../../src/utils.js'; -import events from '../../src/events.js'; -import CONSTANTS from '../../src/constants.json'; -import {addBidderRequests} from '../../src/auction.js'; -import {getHighestCpmBidsFromBidPool, sortByDealAndPriceBucketOrCpm} from '../../src/targeting.js'; - -const MODULE_NAME = 'multibid'; -let hasMultibid = false; -let multiConfig = {}; -let multibidUnits = {}; - -// Storing this globally on init for easy reference to configuration -config.getConfig(MODULE_NAME, conf => { - if (!Array.isArray(conf.multibid) || !conf.multibid.length || !validateMultibid(conf.multibid)) return; - - resetMultiConfig(); - hasMultibid = true; - - conf.multibid.forEach(entry => { - if (entry.bidder) { - multiConfig[entry.bidder] = { - maxbids: entry.maxBids, - prefix: entry.targetBiddercodePrefix - } - } else { - entry.bidders.forEach(key => { - multiConfig[key] = { - maxbids: entry.maxBids, - prefix: entry.targetBiddercodePrefix - } - }); - } - }); -}); - -/** - * @summary validates multibid configuration entries - * @param {Object[]} multibid - example [{bidder: 'bidderA', maxbids: 2, prefix: 'bidA'}, {bidder: 'bidderB', maxbids: 2}] - * @return {Boolean} -*/ -export function validateMultibid(conf) { - let check = true; - let duplicate = conf.filter(entry => { - // Check if entry.bidder is not defined or typeof string, filter entry and reset configuration - if ((!entry.bidder || typeof entry.bidder !== 'string') && (!entry.bidders || !Array.isArray(entry.bidders))) { - utils.logWarn('Filtering multibid entry. Missing required bidder or bidders property.'); - check = false; - return false; - } - - return true; - }).map(entry => { - // Check if entry.maxbids is not defined, not typeof number, or less than 1, set maxbids to 1 and reset configuration - // Check if entry.maxbids is greater than 9, set maxbids to 9 and reset configuration - if (typeof entry.maxBids !== 'number' || entry.maxBids < 1 || entry.maxBids > 9) { - entry.maxBids = (typeof entry.maxBids !== 'number' || entry.maxBids < 1) ? 1 : 9; - check = false; - } - - return entry; - }); - - if (!check) config.setConfig({multibid: duplicate}); - - return check; -} - -/** - * @summary addBidderRequests before hook - * @param {Function} fn reference to original function (used by hook logic) - * @param {Object[]} array containing copy of each bidderRequest object -*/ -export function adjustBidderRequestsHook(fn, bidderRequests) { - bidderRequests.map(bidRequest => { - // Loop through bidderRequests and check if bidderCode exists in multiconfig - // If true, add bidderRequest.bidLimit to bidder request - if (multiConfig[bidRequest.bidderCode]) { - bidRequest.bidLimit = multiConfig[bidRequest.bidderCode].maxbids - } - return bidRequest; - }) - - fn.call(this, bidderRequests); -} - -/** - * @summary addBidResponse before hook - * @param {Function} fn reference to original function (used by hook logic) - * @param {String} ad unit code for bid - * @param {Object} bid object -*/ -export function addBidResponseHook(fn, adUnitCode, bid) { - let floor = utils.deepAccess(bid, 'floorData.floorValue'); - - if (!config.getConfig('multibid')) resetMultiConfig(); - // Checks if multiconfig exists and bid bidderCode exists within config and is an adpod bid - // Else checks if multiconfig exists and bid bidderCode exists within config - // Else continue with no modifications - if (hasMultibid && multiConfig[bid.bidderCode] && utils.deepAccess(bid, 'video.context') === 'adpod') { - fn.call(this, adUnitCode, bid); - } else if (hasMultibid && multiConfig[bid.bidderCode]) { - // Set property multibidPrefix on bid - if (multiConfig[bid.bidderCode].prefix) bid.multibidPrefix = multiConfig[bid.bidderCode].prefix; - bid.originalBidder = bid.bidderCode; - // Check if stored bids for auction include adUnitCode.bidder and max limit not reach for ad unit - if (utils.deepAccess(multibidUnits, `${adUnitCode}.${bid.bidderCode}`)) { - // Store request id under new property originalRequestId, create new unique bidId, - // and push bid into multibid stored bids for auction if max not reached and bid cpm above floor - if (!multibidUnits[adUnitCode][bid.bidderCode].maxReached && (!floor || floor <= bid.cpm)) { - bid.originalRequestId = bid.requestId; - - bid.requestId = utils.getUniqueIdentifierStr(); - multibidUnits[adUnitCode][bid.bidderCode].ads.push(bid); - - let length = multibidUnits[adUnitCode][bid.bidderCode].ads.length; - - if (multiConfig[bid.bidderCode].prefix) bid.targetingBidder = multiConfig[bid.bidderCode].prefix + length; - if (length === multiConfig[bid.bidderCode].maxbids) multibidUnits[adUnitCode][bid.bidderCode].maxReached = true; - - fn.call(this, adUnitCode, bid); - } else { - utils.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 (utils.deepAccess(bid, 'floorData.floorValue')) utils.deepSetValue(multibidUnits, `${adUnitCode}.${bid.bidderCode}`, {floor: utils.deepAccess(bid, 'floorData.floorValue')}); - - utils.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); - } - } else { - fn.call(this, adUnitCode, bid); - } -} - -/** -* A descending sort function that will sort the list of objects based on the following: -* - bids without dynamic aliases are sorted before bids with dynamic aliases -*/ -export function sortByMultibid(a, b) { - if (a.bidder !== a.bidderCode && b.bidder === b.bidderCode) { - return 1; - } - - if (a.bidder === a.bidderCode && b.bidder !== b.bidderCode) { - return -1; - } - - return 0; -} - -/** - * @summary getHighestCpmBidsFromBidPool before hook - * @param {Function} fn reference to original function (used by hook logic) - * @param {Object[]} array of objects containing all bids from bid pool - * @param {Function} function to reduce to only highest cpm value for each bidderCode - * @param {Number} adUnit bidder targeting limit, default set to 0 - * @param {Boolean} default set to false, this hook modifies targeting and sets to true -*/ -export function targetBidPoolHook(fn, bidsReceived, highestCpmCallback, adUnitBidLimit = 0, hasModified = false) { - if (!config.getConfig('multibid')) resetMultiConfig(); - if (hasMultibid) { - const dealPrioritization = config.getConfig('sendBidsControl.dealPrioritization'); - let modifiedBids = []; - let buckets = utils.groupBy(bidsReceived, 'adUnitCode'); - let bids = [].concat.apply([], Object.keys(buckets).reduce((result, slotId) => { - let bucketBids = []; - // Get bids and group by property originalBidder - let bidsByBidderName = utils.groupBy(buckets[slotId], 'originalBidder'); - let adjustedBids = [].concat.apply([], Object.keys(bidsByBidderName).map(key => { - // Reset all bidderCodes to original bidder values and sort by CPM - return bidsByBidderName[key].sort((bidA, bidB) => { - if (bidA.originalBidder && bidA.originalBidder !== bidA.bidderCode) bidA.bidderCode = bidA.originalBidder; - if (bidA.originalBidder && bidB.originalBidder !== bidB.bidderCode) bidB.bidderCode = bidB.originalBidder; - return bidA.cpm > bidB.cpm ? -1 : (bidA.cpm < bidB.cpm ? 1 : 0); - }).map((bid, index) => { - // For each bid (post CPM sort), set dynamic bidderCode using prefix and index if less than maxbid amount - if (utils.deepAccess(multiConfig, `${bid.bidderCode}.prefix`) && index !== 0 && index < multiConfig[bid.bidderCode].maxbids) { - bid.bidderCode = multiConfig[bid.bidderCode].prefix + (index + 1); - } - - return bid - }) - })); - // Get adjustedBids by bidderCode and reduce using highestCpmCallback - let bidsByBidderCode = utils.groupBy(adjustedBids, 'bidderCode'); - Object.keys(bidsByBidderCode).forEach(key => bucketBids.push(bidsByBidderCode[key].reduce(highestCpmCallback))); - // if adUnitBidLimit is set, pass top N number bids - if (adUnitBidLimit > 0) { - bucketBids = dealPrioritization ? bucketBids.sort(sortByDealAndPriceBucketOrCpm(true)) : bucketBids.sort((a, b) => b.cpm - a.cpm); - bucketBids.sort(sortByMultibid); - modifiedBids.push(...bucketBids.slice(0, adUnitBidLimit)); - } else { - modifiedBids.push(...bucketBids); - } - - return [].concat.apply([], modifiedBids); - }, [])); - - fn.call(this, bids, highestCpmCallback, adUnitBidLimit, true); - } else { - fn.call(this, bidsReceived, highestCpmCallback, adUnitBidLimit); - } -} - -/** -* Resets globally stored multibid configuration -*/ -export const resetMultiConfig = () => { hasMultibid = false; multiConfig = {}; }; - -/** -* Resets globally stored multibid ad unit bids -*/ -export const resetMultibidUnits = () => multibidUnits = {}; - -/** -* Set up hooks on init -*/ -function init() { - events.on(CONSTANTS.EVENTS.AUCTION_INIT, resetMultibidUnits); - setupBeforeHookFnOnce(addBidderRequests, adjustBidderRequestsHook); - getHook('addBidResponse').before(addBidResponseHook, 3); - setupBeforeHookFnOnce(getHighestCpmBidsFromBidPool, targetBidPoolHook); -} - -init(); diff --git a/modules/multibid/index.md b/modules/multibid/index.md deleted file mode 100644 index a431d9b7960..00000000000 --- a/modules/multibid/index.md +++ /dev/null @@ -1,40 +0,0 @@ -# Overview - -Module Name: multibid - -Purpose: To expand the number of key value pairs going to the ad server in the normal Prebid way by establishing the concept of a "dynamic alias" -- a bidder code that exists only on the response, not in the adunit. - - -# Description -Allowing a single bidder to multi-bid into an auction has several use cases: - -1. allows a bidder to provide both outstream and banner -2. supports the video VAST fallback scenario -3. allows one bid to be blocked in the ad server and the second one still considered -4. add extra high-value bids to the cache for future refreshes - - -# Example of using config -``` - pbjs.setConfig({ - multibid: [{ - bidder: "bidderA", - maxBids: 3, - targetBiddercodePrefix: "bidA" - },{ - bidder: "bidderB", - maxBids: 3, - targetBiddercodePrefix: "bidB" - },{ - bidder: "bidderC", - maxBids: 3 - },{ - bidders: ["bidderD", "bidderE"], - maxBids: 2 - }] - }); -``` - -# Please Note: -- - diff --git a/modules/mwOpenLinkIdSystem.js b/modules/mwOpenLinkIdSystem.js deleted file mode 100644 index b2381836d5d..00000000000 --- a/modules/mwOpenLinkIdSystem.js +++ /dev/null @@ -1,142 +0,0 @@ -/** - * This module adds MediaWallah OpenLink to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/mwOpenLinkIdSystem - * @requires module:modules/userId - */ - -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'; - -const openLinkID = { - name: 'mwol', - cookie_expiration: (86400 * 1000 * 365 * 1) // 1 year -} - -const storage = getStorageManager(); - -function getExpirationDate() { - return (new Date(utils.timestamp() + openLinkID.cookie_expiration)).toGMTString(); -} - -function isValidConfig(configParams) { - if (!configParams) { - utils.logError('User ID - mwOlId submodule requires configParams'); - return false; - } - if (!configParams.accountId) { - utils.logError('User ID - mwOlId submodule requires accountId to be defined'); - return false; - } - if (!configParams.partnerId) { - utils.logError('User ID - mwOlId submodule requires partnerId to be defined'); - return false; - } - return true; -} - -function deserializeMwOlId(mwOlIdStr) { - const mwOlId = {}; - const mwOlIdArr = mwOlIdStr.split(','); - - mwOlIdArr.forEach(function(value) { - const pair = value.split(':'); - // unpack a value of 1 as true - mwOlId[pair[0]] = +pair[1] === 1 ? true : pair[1]; - }); - - return mwOlId; -} - -function serializeMwOlId(mwOlId) { - let components = []; - - if (mwOlId.eid) { - components.push('eid:' + mwOlId.eid); - } - if (mwOlId.ibaOptout) { - components.push('ibaOptout:1'); - } - if (mwOlId.ccpaOptout) { - components.push('ccpaOptout:1'); - } - - return components.join(','); -} - -function readCookie(name) { - if (!name) name = openLinkID.name; - const mwOlIdStr = storage.getCookie(name); - if (mwOlIdStr) { - return deserializeMwOlId(decodeURIComponent(mwOlIdStr)); - } - return null; -} - -function writeCookie(mwOlId) { - if (mwOlId) { - const mwOlIdStr = encodeURIComponent(serializeMwOlId(mwOlId)); - storage.setCookie(openLinkID.name, mwOlIdStr, getExpirationDate(), 'lax'); - } -} - -function register(configParams, olid) { - const { accountId, partnerId, uid } = configParams; - const url = 'https://ol.mediawallahscript.com/?account_id=' + accountId + - '&partner_id=' + partnerId + - '&uid=' + uid + - '&olid=' + olid + - '&cb=' + Math.random() - ; - ajax(url); -} - -function setID(configParams) { - if (!isValidConfig(configParams)) return undefined; - const mwOlId = readCookie(); - const newMwOlId = mwOlId ? utils.deepClone(mwOlId) : {eid: utils.generateUUID()}; - writeCookie(newMwOlId); - register(configParams, newMwOlId.eid); - return { - id: newMwOlId - }; -}; - -/* End MW */ - -export { writeCookie }; - -/** @type {Submodule} */ -export const mwOpenLinkIdSubModule = { - /** - * used to link submodule with config - * @type {string} - */ - name: 'mwOpenLinkId', - /** - * decode the stored id value for passing to bid requests - * @function - * @param {MwOlId} mwOlId - * @return {(Object|undefined} - */ - decode(mwOlId) { - const id = mwOlId && utils.isPlainObject(mwOlId) ? mwOlId.eid : undefined; - return id ? { 'mwOpenLinkId': id } : undefined; - }, - - /** - * performs action to obtain id and return a value in the callback's response argument - * @function - * @param {SubmoduleParams} [submoduleParams] - * @returns {id:MwOlId | undefined} - */ - getId(submoduleConfig) { - const submoduleConfigParams = (submoduleConfig && submoduleConfig.params) || {}; - if (!isValidConfig(submoduleConfigParams)) return undefined; - return setID(submoduleConfigParams); - } -}; - -submodule('userId', mwOpenLinkIdSubModule); diff --git a/modules/mwOpenLinkIdSystem.md b/modules/mwOpenLinkIdSystem.md deleted file mode 100644 index f55913f2983..00000000000 --- a/modules/mwOpenLinkIdSystem.md +++ /dev/null @@ -1,43 +0,0 @@ -## MediaWallah openLink User ID Submodule - -OpenLink ID User ID Module generates a UUID that can be utilized to improve user matching. This module enables timely synchronization which handles MediaWallah optout. You must have a pre-existing relationship with MediaWallah prior to integrating. - -### Building Prebid with openLink Id Support -Your Prebid build must include the modules for both **userId** and **mwOpenLinkId** submodule. Follow the build instructions for Prebid as -explained in the top level README.md file of the Prebid source tree. - -ex: $ gulp build --modules=userId,mwOpenLinkIdSystem - -##$ MediaWallah openLink ID Example Configuration - -When the module is included, it's automatically enabled and saves an id to both cookie with an expiration time of 1 year. - -### Prebid Params - -Individual params may be set for the MediaWallah openLink User ID Submodule. At least accountId and partnerId must be set in the params. - -```javascript -pbjs.setConfig({ - userSync: { - userIds: [{ - name: 'mwOpenLinkId', - params: { - accountId: '1000', - partnerId: '1001', - uid: 'u-123xyz' - } - }] - } -}); -``` - -### Parameter Descriptions for the `usersync` Configuration Section -The below parameters apply only to the MediaWallah OpenLink ID User ID Module integration. - -| Params under usersync.userIds[]| Scope | Type | Description | Example | -| --- | --- | --- | --- | --- | -| name | Required | String | The name of this module. | `'mwOpenLinkId'` | -| params | Required | Object | Details for mwOLID syncing. | | -| params.accountId | Required | String | The MediaWallah assigned Account Id | `1000` | -| params.partnerId | Required | String | The MediaWallah assign Partner Id | `1001` | -| params.uid | Optional | String | Your unique Id for the user or browser. Used for matching | `u-123xyz` | \ No newline at end of file diff --git a/modules/my6senseBidAdapter.js b/modules/my6senseBidAdapter.js deleted file mode 100644 index 018baa37461..00000000000 --- a/modules/my6senseBidAdapter.js +++ /dev/null @@ -1,195 +0,0 @@ -import { BANNER, NATIVE } from '../src/mediaTypes.js'; - -const {registerBidder} = require('../src/adapters/bidderFactory.js'); -const BIDDER_CODE = 'my6sense'; -const END_POINT = 'https://hb.mynativeplatform.com/pub2/web/v1.15.0/hbwidget.json'; -const END_POINT_METHOD = 'POST'; - -// called first -function isBidRequestValid(bid) { - return !(bid.bidder !== BIDDER_CODE || !bid.params || !bid.params.key); -} - -function getUrl(url) { - if (!url) { - url = window.location.href;// "clean" url of current web page - } - var canonicalLink = null; - // first look for meta data with property "og:url" - var metaElements = document.getElementsByTagName('meta'); - for (var i = 0; i < metaElements.length && !canonicalLink; i++) { - if (metaElements[i].getAttribute('property') == 'og:url') { - canonicalLink = metaElements[i].content; - } - } - if (!canonicalLink) { - var canonicalLinkContainer = document.querySelector("link[rel='canonical']");// html element containing the canonical link - if (canonicalLinkContainer) { - // get clean url from href of - canonicalLink = canonicalLinkContainer.href; - } - } - url = canonicalLink || url; - return encodeURIComponent(url).toString(); -} - -/** - * this function is used to fix param value before sending them to server, if user did not set it, - * default value for parameter will be returned - * example1: paidClicks: '[PAID_TRACKING_PIXEL]', will return {value: '', fromUser: false} - * example2: pageURL: 'www.my6sense.com', will return {value: 'www.my6sense.com', fromUser: true} - * @param key - * @param value - * @returns {{value: *, fromUser: boolean}} - */ -function fixRequestParamForServer(key, value) { - function isEmptyValue(key, value) { - return value === parametersMap[key].emptyValue; - } - - const parametersMap = { - 'pageUrl': { - emptyValue: '[PAGE_URL]', - defaultValue: getUrl() - }, - 'displayWithinIframe': { - emptyValue: '', - defaultValue: '' - }, - 'dataParams': { - emptyValue: '[KEY_VALUES]', - defaultValue: '' - }, - 'paidClicks': { - emptyValue: '[PAID_TRACKING_PIXEL]', - defaultValue: '' - }, - 'organicClicks': { - emptyValue: '[ORGANIC_TRACKING_PIXEL]', - defaultValue: '' - }, - 'dataView': { - emptyValue: '[VIEW_TRACKING_PIXEL]', - defaultValue: '' - }, - // ZONE is not part of this object, handled on server side - }; - - // if param is not in list we do not change it (return it as is) - if (!parametersMap.hasOwnProperty(key)) { - return { - value: value, - fromUser: true - }; - } - - // if no value given by user set it to default - if (!value || isEmptyValue(key, value)) { - return { - value: parametersMap[key].defaultValue, - fromUser: false - }; - } - - return { - value: value, - fromUser: true - }; -} - -// called second - -function buildGdprServerProperty(bidderRequest) { - var gdprObj = { - gdpr_consent: null, - gdpr: null - }; - - if (bidderRequest && 'gdprConsent' in bidderRequest) { - gdprObj.gdpr_consent = bidderRequest.gdprConsent.consentString || null; - - gdprObj.gdpr = gdprObj.gdpr === null && bidderRequest.gdprConsent.gdprApplies == true ? true : gdprObj.gdpr; - gdprObj.gdpr = gdprObj.gdpr === null && bidderRequest.gdprConsent.gdprApplies == false ? false : gdprObj.gdpr; - gdprObj.gdpr = gdprObj.gdpr === null && bidderRequest.gdprConsent.gdprApplies == 1 ? true : gdprObj.gdpr; - gdprObj.gdpr = gdprObj.gdpr === null && bidderRequest.gdprConsent.gdprApplies == 0 ? false : gdprObj.gdpr; - } - - return gdprObj; -} - -function buildRequests(validBidRequests, bidderRequest) { - let requests = []; - - if (validBidRequests && validBidRequests.length) { - validBidRequests.forEach(bidRequest => { - bidRequest.widget_num = 1; // mandatory property for server side - let isDataUrlSetByUser = false; - let debug = false; - - if (bidRequest.params) { - for (let key in bidRequest.params) { - // loop over params and remove empty/untouched values - if (bidRequest.params.hasOwnProperty(key)) { - // if debug we update url string to get core debug version - if (key === 'debug' && bidRequest.params[key] === true) { - debug = true; - delete bidRequest.params[key]; - continue; - } - - let fixedObj = fixRequestParamForServer(key, bidRequest.params[key]); - bidRequest.params[key] = fixedObj.value; - - // if pageUrl is set by user we should update variable for query string param - if (key === 'pageUrl' && fixedObj.fromUser === true) { - isDataUrlSetByUser = true; - } - - // remove empty params from request - if (!bidRequest.params[key]) { - delete bidRequest.params[key]; - } - } - } - } - - let url = `${END_POINT}?widget_key=${bidRequest.params.key}&is_data_url_set=${isDataUrlSetByUser}`; // mandatory query string for server side - if (debug) { - url = `${END_POINT}?env=debug&widget_key=${bidRequest.params.key}&is_data_url_set=${isDataUrlSetByUser}`; // this url is for debugging - } - - bidRequest.gdpr = buildGdprServerProperty(bidderRequest); - - requests.push({ - url: url, - method: END_POINT_METHOD, - data: JSON.stringify(bidRequest) - }); - }); - } - - return requests; -} - -// called third - -function interpretResponse(serverResponse) { - const bidResponses = []; - // currently server returns a single response which is the body property - if (serverResponse.body) { - serverResponse.body.bidderCode = BIDDER_CODE; - bidResponses.push(serverResponse.body); - } - - return bidResponses; -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, NATIVE], - isBidRequestValid, - buildRequests, - interpretResponse -}; - -registerBidder(spec); diff --git a/modules/my6senseBidAdapter.md b/modules/my6senseBidAdapter.md deleted file mode 100644 index 7f422e6fabf..00000000000 --- a/modules/my6senseBidAdapter.md +++ /dev/null @@ -1,36 +0,0 @@ -# HeaderBiddingAdapter - -# Overview - -``` -Module Name: my6sense Bidder Adapter -Module Type: Bidder Adapter -``` - -# Description - -Module that connects to my6sense demand sources. -Banner formats are supported. - -# Test Parameters -``` - var adUnits = [ - - // { - // - // sizes: [[1000, 600]], - // bids: [{ - // bidder: 'my6sense', - // params: { - // key: 'OAJJBW2LRYi2CxfhzqogkA', - // pageUrl: '[PAGE_URL]', - // zone: '[ZONE]', - // dataView: '' - // organicClicks:'', - // paidClicks:'', - // } - // }] - // } - ]; - -``` diff --git a/modules/mytargetBidAdapter.js b/modules/mytargetBidAdapter.js deleted file mode 100644 index bcf8e7ad17f..00000000000 --- a/modules/mytargetBidAdapter.js +++ /dev/null @@ -1,113 +0,0 @@ -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'mytarget'; -const BIDDER_URL = 'https://ad.mail.ru/hbid_prebid/'; -const DEFAULT_CURRENCY = 'RUB'; -const DEFAULT_TTL = 180; - -function buildPlacement(bidRequest) { - let { bidId, params } = bidRequest; - let { placementId, position, response, bidfloor } = params; - let placement = { - placementId, - id: bidId, - position: position || 0, - response: response || 0 - }; - - if (typeof bidfloor !== 'undefined') { - placement.bidfloor = bidfloor; - } - - return placement; -} - -function getSiteName(referrer) { - let sitename = config.getConfig('mytarget.sitename'); - - if (!sitename) { - sitename = utils.parseUrl(referrer).hostname; - } - - return sitename; -} - -function getCurrency() { - let currency = config.getConfig('currency.adServerCurrency'); - - return (currency === 'USD') ? currency : DEFAULT_CURRENCY; -} - -function generateRandomId() { - return Math.random().toString(16).substring(2); -} - -export const spec = { - code: BIDDER_CODE, - - isBidRequestValid: function(bid) { - return !!bid.params.placementId; - }, - - buildRequests: function(validBidRequests, bidderRequest) { - let referrer = ''; - - if (bidderRequest && bidderRequest.refererInfo) { - referrer = bidderRequest.refererInfo.referer; - } - - const payload = { - places: utils._map(validBidRequests, buildPlacement), - site: { - sitename: getSiteName(referrer), - page: referrer - }, - settings: { - currency: getCurrency(), - windowSize: { - width: window.screen.width, - height: window.screen.height - } - } - }; - - return { - method: 'POST', - url: BIDDER_URL, - data: payload, - }; - }, - - interpretResponse: function(serverResponse, bidRequest) { - let { body } = serverResponse; - - if (body.bids) { - return utils._map(body.bids, (bid) => { - let bidResponse = { - requestId: bid.id, - cpm: bid.price, - width: bid.size.width, - height: bid.size.height, - ttl: bid.ttl || DEFAULT_TTL, - currency: bid.currency || DEFAULT_CURRENCY, - creativeId: bid.creativeId || generateRandomId(), - netRevenue: true - } - - if (bid.adm) { - bidResponse.ad = bid.adm; - } else { - bidResponse.adUrl = bid.displayUrl; - } - - return bidResponse; - }); - } - - return []; - } -} - -registerBidder(spec); diff --git a/modules/mytargetBidAdapter.md b/modules/mytargetBidAdapter.md deleted file mode 100644 index 3292ff561fa..00000000000 --- a/modules/mytargetBidAdapter.md +++ /dev/null @@ -1,40 +0,0 @@ -# Overview - -``` -Module Name: myTarget Bidder Adapter -Module Type: Bidder Adapter -Maintainer: support_target@corp.my.com -``` - -# Description - -Module that connects to myTarget demand sources. - -# Test Parameters - -``` - var adUnits = [{ - code: 'placementCode', - mediaTypes: { - banner: { - sizes: [[240, 400]], - } - }, - bids: [{ - bidder: 'mytarget', - params: { - placementId: '379783', - - // OPTIONAL: custom bid floor - bidfloor: 10000, - - // OPTIONAL: if you know the ad position on the page, specify it here - // (this corresponds to "Ad Position" in OpenRTB 2.3, section 5.4) - position: 0, - - // OPTIONAL: bid response type: 0 - ad url (default), 1 - ad markup - response: 0 - } - }] - }]; -``` diff --git a/modules/nafdigitalBidAdapter.js b/modules/nafdigitalBidAdapter.js deleted file mode 100644 index d64e079b52a..00000000000 --- a/modules/nafdigitalBidAdapter.js +++ /dev/null @@ -1,245 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; - -const BIDDER_CODE = 'nafdigital'; -const URL = 'https://nafdigitalbidder.com/hb'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - isBidRequestValid, - buildRequests, - interpretResponse, - getUserSyncs -}; - -function buildRequests(bidReqs, bidderRequest) { - try { - let referrer = ''; - if (bidderRequest && bidderRequest.refererInfo) { - referrer = bidderRequest.refererInfo.referer; - } - const nafdigitalImps = []; - const publisherId = utils.getBidIdParameter('publisherId', bidReqs[0].params); - utils._each(bidReqs, function (bid) { - bid.sizes = ((utils.isArray(bid.sizes) && utils.isArray(bid.sizes[0])) ? bid.sizes : [bid.sizes]); - bid.sizes = bid.sizes.filter(size => utils.isArray(size)); - const processedSizes = bid.sizes.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, utils.getWindowTop(), minSize) - : 'na'; - const viewabilityAmountRounded = isNaN(viewabilityAmount) ? viewabilityAmount : Math.round(viewabilityAmount); - - const imp = { - id: bid.bidId, - banner: { - format: processedSizes, - ext: { - viewability: viewabilityAmountRounded - } - }, - tagid: String(bid.adUnitCode) - }; - const bidFloor = utils.getBidIdParameter('bidFloor', bid.params); - if (bidFloor) { - imp.bidfloor = bidFloor; - } - nafdigitalImps.push(imp); - }); - const nafdigitalBidReq = { - id: utils.getUniqueIdentifierStr(), - imp: nafdigitalImps, - site: { - domain: utils.parseUrl(referrer).host, - page: referrer, - publisher: { - id: publisherId - } - }, - device: { - devicetype: _getDeviceType(), - w: screen.width, - h: screen.height - }, - tmax: config.getConfig('bidderTimeout') - }; - - return { - method: 'POST', - url: URL, - data: JSON.stringify(nafdigitalBidReq), - options: {contentType: 'text/plain', withCredentials: false} - }; - } catch (e) { - utils.logError(e, {bidReqs, bidderRequest}); - } -} - -function isBidRequestValid(bid) { - if (bid.bidder !== BIDDER_CODE || typeof bid.params === 'undefined') { - return false; - } - - if (typeof bid.params.publisherId === 'undefined') { - return false; - } - - return true; -} - -function interpretResponse(serverResponse) { - if (!serverResponse.body || typeof serverResponse.body != 'object') { - utils.logWarn('NAF digital server returned empty/non-json response: ' + JSON.stringify(serverResponse.body)); - return []; - } - const { body: {id, seatbid} } = serverResponse; - try { - const nafdigitalBidResponses = []; - if (id && - seatbid && - seatbid.length > 0 && - seatbid[0].bid && - seatbid[0].bid.length > 0) { - seatbid[0].bid.map(nafdigitalBid => { - nafdigitalBidResponses.push({ - requestId: nafdigitalBid.impid, - cpm: parseFloat(nafdigitalBid.price), - width: parseInt(nafdigitalBid.w), - height: parseInt(nafdigitalBid.h), - creativeId: nafdigitalBid.crid || nafdigitalBid.id, - currency: 'USD', - netRevenue: true, - mediaType: BANNER, - ad: _getAdMarkup(nafdigitalBid), - ttl: 60 - }); - }); - } - return nafdigitalBidResponses; - } catch (e) { - utils.logError(e, {id, seatbid}); - } -} - -// Don't do user sync for now -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 += utils.createTrackPixelHtml(bid.nurl); - } - return adm; -} - -function _isViewabilityMeasurable(element) { - return !_isIframe() && element !== null; -} - -function _getViewability(element, topWin, { w, h } = {}) { - return utils.getWindowTop().document.visibilityState === 'visible' - ? _getPercentInView(element, topWin, { w, h }) - : 0; -} - -function _isIframe() { - try { - return utils.getWindowSelf() !== utils.getWindowTop(); - } catch (e) { - return true; - } -} - -function _getMinSize(sizes) { - return sizes.reduce((min, size) => size.h * size.w < min.h * min.w ? size : min); -} - -function _getBoundingBox(element, { w, h } = {}) { - let { width, height, left, top, right, bottom } = element.getBoundingClientRect(); - - if ((width === 0 || height === 0) && w && h) { - width = w; - height = h; - right = left + w; - bottom = top + h; - } - - return { width, height, left, top, right, bottom }; -} - -function _getIntersectionOfRects(rects) { - const bbox = { - left: rects[0].left, - right: rects[0].right, - top: rects[0].top, - bottom: rects[0].bottom - }; - - for (let i = 1; i < rects.length; ++i) { - bbox.left = Math.max(bbox.left, rects[i].left); - bbox.right = Math.min(bbox.right, rects[i].right); - - if (bbox.left >= bbox.right) { - return null; - } - - bbox.top = Math.max(bbox.top, rects[i].top); - bbox.bottom = Math.min(bbox.bottom, rects[i].bottom); - - if (bbox.top >= bbox.bottom) { - return null; - } - } - - bbox.width = bbox.right - bbox.left; - bbox.height = bbox.bottom - bbox.top; - - return bbox; -} - -function _getPercentInView(element, topWin, { w, h } = {}) { - const elementBoundingBox = _getBoundingBox(element, { w, h }); - - // Obtain the intersection of the element and the viewport - const elementInViewBoundingBox = _getIntersectionOfRects([ { - left: 0, - top: 0, - right: topWin.innerWidth, - bottom: topWin.innerHeight - }, elementBoundingBox ]); - - let elementInViewArea, elementTotalArea; - - if (elementInViewBoundingBox !== null) { - // Some or all of the element is in view - elementInViewArea = elementInViewBoundingBox.width * elementInViewBoundingBox.height; - elementTotalArea = elementBoundingBox.width * elementBoundingBox.height; - - return ((elementInViewArea / elementTotalArea) * 100); - } - - // No overlap between element and the viewport; therefore, the element - // lies completely out of view - return 0; -} - -registerBidder(spec); diff --git a/modules/nafdigitalBidAdapter.md b/modules/nafdigitalBidAdapter.md deleted file mode 100644 index b17b1f13e1e..00000000000 --- a/modules/nafdigitalBidAdapter.md +++ /dev/null @@ -1,38 +0,0 @@ -# Overview - -``` -Module Name: NAF Digital Bid Adapter -Module Type: Bidder Adapter -Maintainer: vyatsun@gmail.com -``` - -# Description - -NAF Digital adapter integration to the Prebid library. - -# Test Parameters - -``` -var adUnits = [ - { - code: 'test-leaderboard', - sizes: [[728, 90]], - bids: [{ - bidder: 'nafdigital', - params: { - publisherId: 2141020, - bidFloor: 0.01 - } - }] - }, { - code: 'test-banner', - sizes: [[300, 250]], - bids: [{ - bidder: 'nafdigital', - params: { - publisherId: 2141020 - } - }] - } -] -``` diff --git a/modules/nanointeractiveBidAdapter.js b/modules/nanointeractiveBidAdapter.js deleted file mode 100644 index 42a343efc03..00000000000 --- a/modules/nanointeractiveBidAdapter.js +++ /dev/null @@ -1,159 +0,0 @@ -import * as utils from '../src/utils.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const storage = getStorageManager(); - -export const BIDDER_CODE = 'nanointeractive'; -export const END_POINT_URL = 'https://ad.audiencemanager.de'; - -export const SSP_PLACEMENT_ID = 'pid'; -export const NQ = 'nq'; -export const NQ_NAME = 'name'; -export const CATEGORY = 'category'; -export const CATEGORY_NAME = 'categoryName'; -export const SUB_ID = 'subId'; -export const REF = 'ref'; -export const LOCATION = 'loc'; - -var nanoPid = '5a1ec660eb0a191dfa591172'; - -export const spec = { - - code: BIDDER_CODE, - aliases: ['ni'], - - isBidRequestValid(bid) { - const pid = bid.params[SSP_PLACEMENT_ID]; - return !!(pid); - }, - - buildRequests(validBidRequests, bidderRequest) { - let payload = []; - validBidRequests.forEach( - bid => payload.push(createSingleBidRequest(bid, bidderRequest)) - ); - const url = getEndpointUrl() + '/hb'; - - return { - method: 'POST', - url: url, - data: JSON.stringify(payload) - }; - }, - interpretResponse(serverResponse) { - const bids = []; - serverResponse.body.forEach(serverBid => { - if (isEngineResponseValid(serverBid)) { - bids.push(createSingleBidResponse(serverBid)); - } - }); - return bids; - }, - getUserSyncs: function(syncOptions) { - const syncs = []; - if (syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: getEndpointUrl() + '/hb/cookieSync/' + nanoPid - }); - } - - if (syncOptions.pixelEnabled) { - syncs.push({ - type: 'image', - url: getEndpointUrl() + '/hb/cookieSync/' + nanoPid - }); - } - return syncs; - } - -}; - -function createSingleBidRequest(bid, bidderRequest) { - const location = utils.deepAccess(bidderRequest, 'refererInfo.referer'); - const origin = utils.getOrigin(); - - nanoPid = bid.params[SSP_PLACEMENT_ID] || nanoPid; - - const data = { - [SSP_PLACEMENT_ID]: bid.params[SSP_PLACEMENT_ID], - [NQ]: [createNqParam(bid)], - [CATEGORY]: [createCategoryParam(bid)], - [SUB_ID]: createSubIdParam(bid), - [REF]: createRefParam(), - sizes: bid.sizes.map(value => value[0] + 'x' + value[1]), - bidId: bid.bidId, - cors: origin, - [LOCATION]: location, - lsUserId: getLsUserId() - }; - - if (bidderRequest && bidderRequest.gdprConsent) { - data['gdprConsent'] = bidderRequest.gdprConsent.consentString; - data['gdprApplies'] = (bidderRequest.gdprConsent.gdprApplies) ? '1' : '0'; - } - - return data; -} - -function createSingleBidResponse(serverBid) { - if (serverBid.userId) { - storage.setDataInLocalStorage('lsUserId', serverBid.userId); - } - return { - requestId: serverBid.id, - cpm: serverBid.cpm, - width: serverBid.width, - height: serverBid.height, - ad: serverBid.ad, - ttl: serverBid.ttl, - creativeId: serverBid.creativeId, - netRevenue: serverBid.netRevenue || true, - currency: serverBid.currency - }; -} - -function createNqParam(bid) { - return bid.params[NQ_NAME] ? utils.getParameterByName(bid.params[NQ_NAME]) : bid.params[NQ] || null; -} - -function createCategoryParam(bid) { - return bid.params[CATEGORY_NAME] ? utils.getParameterByName(bid.params[CATEGORY_NAME]) : bid.params[CATEGORY] || null; -} - -function createSubIdParam(bid) { - return bid.params[SUB_ID] || null; -} - -function createRefParam() { - try { - return window.top.document.referrer; - } catch (ex) { - return document.referrer; - } -} - -function isEngineResponseValid(response) { - return !!response.cpm && !!response.ad; -} - -/** - * Used mainly for debugging - * - * @returns string - */ -function getEndpointUrl() { - const nanoConfig = config.getConfig('nano'); - return (nanoConfig && nanoConfig['endpointUrl']) || END_POINT_URL; -} - -function getLsUserId() { - if (storage.getDataFromLocalStorage('lsUserId') != null) { - return storage.getDataFromLocalStorage('lsUserId'); - } - return null; -} - -registerBidder(spec); diff --git a/modules/nanointeractiveBidAdapter.md b/modules/nanointeractiveBidAdapter.md deleted file mode 100644 index c1790ff6337..00000000000 --- a/modules/nanointeractiveBidAdapter.md +++ /dev/null @@ -1,152 +0,0 @@ -# Overview - -``` -Module Name: Nano Interactive Bid Adapter -Module Type: Bidder Adapter -Maintainer: rade@nanointeractive.com -``` - -# Description - -Connects to Nano Interactive search retargeting Ad Server for bids. - - - -
-### Requirements: -To be able to get identification key (`pid`), please contact us at
-`https://www.nanointeractive.com/publishers`
-


- -#### Send All Bids Ad Server Keys: -(truncated to 20 chars due to [DFP limit](https://support.google.com/dfp_premium/answer/1628457?hl=en#Key-values)) - -`hb_adid_nanointeract` -`hb_bidder_nanointera` -`hb_pb_nanointeractiv` -`hb_format_nanointera` -`hb_size_nanointeract` -`hb_source_nanointera` - -#### Default Deal ID Keys: -`hb_deal_nanointeract` - -### bid params - -{: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | -| :------------- | :------- | :----------------------------------------------- | :--------------------------- | -| `pid` | required | Identification key, provided by Nano Interactive | `'5afaa0280ae8996eb578de53'` | -| `category` | optional | Contextual taxonomy | `'automotive'` | -| `categoryName` | optional | Contextual taxonomy (from URL query param) | `'cat_name'` | -| `nq` | optional | User search query | `'automobile search query'` | -| `name` | optional | User search query (from URL query param) | `'search_param'` | -| `subId` | optional | Channel - used to separate traffic sources | `'123'` | - -#### Configuration -The `category` and `categoryName` are mutually exclusive. If you pass both, `categoryName` takes precedence. -
-The `nq` and `name` are mutually exclusive. If you pass both, `name` takes precedence. - -#### Example with only required field `pid` - var adUnits = [{ - code: 'nano-div', - sizes: [[300, 250], [300,600]], - bids: [{ - bidder: 'nanointeractive', - params: { - pid: '5afaa0280ae8996eb578de53' - } - }] - }]; - -#### Example with `category` - var adUnits = [{ - code: 'nano-div', - sizes: [[300, 250], [300,600]], - bids: [{ - bidder: 'nanointeractive', - params: { - pid: '5afaa0280ae8996eb578de53', - category: 'automotive', - subId: '123' - } - }] - }]; - -#### Example with `categoryName` - var adUnits = [{ - code: 'nano-div', - sizes: [[300, 250], [300,600]], - bids: [{ - bidder: 'nanointeractive', - params: { - pid: '5afaa0280ae8996eb578de53', - // Category "automotive" is in the URL like: - // https://www....?cat_name=automotive&... - categoryName: 'cat_name', - subId: '123' - } - }] - }]; - -#### Example with `nq` - var adUnits = [{ - code: 'nano-div', - sizes: [[300, 250], [300,600]], - bids: [{ - bidder: 'nanointeractive', - params: { - pid: '5afaa0280ae8996eb578de53', - // User searched "automobile search query" (extracted from search text field) - nq: 'automobile search query', - subId: '123' - } - }] - }]; - -#### Example with `name` - var adUnits = [{ - code: 'nano-div', - sizes: [[300, 250], [300,600]], - bids: [{ - bidder: 'nanointeractive', - params: { - pid: '5afaa0280ae8996eb578de53', - // User searched "automobile search query" and it is in the URL like: - // https://www....?search_param=automobile%20search%20query&... - name: 'search_param', - subId: '123' - } - }] - }]; - -#### Example with `category` and `nq` - var adUnits = [{ - code: 'nano-div', - sizes: [[300, 250], [300,600]], - bids: [{ - bidder: 'nanointeractive', - params: { - pid: '5afaa0280ae8996eb578de53', - category: 'automotive', - nq: 'automobile search query', - subId: '123' - } - }] - }]; - -#### Example with `categoryName` and `name` - var adUnits = [{ - code: 'nano-div', - sizes: [[300, 250], [300,600]], - bids: [{ - bidder: 'nanointeractive', - params: { - pid: '5afaa0280ae8996eb578de53', - categoryName: 'cat_name', - name: 'search_param', - subId: '123' - } - }] - }]; \ No newline at end of file diff --git a/modules/nasmediaAdmixerBidAdapter.js b/modules/nasmediaAdmixerBidAdapter.js deleted file mode 100644 index fd7a7baa58a..00000000000 --- a/modules/nasmediaAdmixerBidAdapter.js +++ /dev/null @@ -1,85 +0,0 @@ - -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; - -const ADMIXER_ENDPOINT = 'https://adn.admixer.co.kr:10443/prebid/ad_req'; -const BIDDER_CODE = 'nasmediaAdmixer'; - -const DEFAULT_BID_TTL = 360; -const DEFAULT_CURRENCY = 'USD'; -const DEFAULT_REVENUE = false; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - - isBidRequestValid: function (bid) { - return !!(bid && bid.params && bid.params.media_key && bid.params.adunit_id); - }, - - buildRequests: function (validBidRequests, bidderRequest) { - return validBidRequests.map(bid => { - const payload = { - media_key: bid.params.media_key, - adunit_id: bid.params.adunit_id, - req_id: bid.bidId, - referrer: bidderRequest.refererInfo.referer, - os: getOs(), - platform: getPlatform(), - }; - - return { - method: 'GET', - url: ADMIXER_ENDPOINT, - data: payload, - } - }) - }, - - interpretResponse: function (serverResponse, bidRequest) { - const serverBody = serverResponse.body; - const bidResponses = []; - - if (serverBody && serverBody.error_code === 0 && serverBody.body && serverBody.body.length > 0) { - let bidData = serverBody.body[0]; - - const bidResponse = { - ad: bidData.ad, - requestId: serverBody.req_id, - creativeId: bidData.ad_id, - cpm: bidData.cpm, - width: bidData.width, - height: bidData.height, - currency: bidData.currency ? bidData.currency : DEFAULT_CURRENCY, - netRevenue: DEFAULT_REVENUE, - ttl: DEFAULT_BID_TTL - }; - - bidResponses.push(bidResponse); - } - return bidResponses; - } -} - -function getOs() { - let ua = navigator.userAgent; - if (ua.match(/(iPhone|iPod|iPad)/)) { - return 'ios'; - } else if (ua.match(/Android/)) { - return 'android'; - } else if (ua.match(/Window/)) { - return 'windows'; - } else { - return 'etc'; - } -} - -function getPlatform() { - return (isMobile()) ? 'm_web' : 'pc_web'; -} - -function isMobile() { - return (/(ios|ipod|ipad|iphone|android)/i).test(navigator.userAgent.toLowerCase()); -} - -registerBidder(spec); diff --git a/modules/nasmediaAdmixerBidAdapter.md b/modules/nasmediaAdmixerBidAdapter.md deleted file mode 100644 index 096acf27f61..00000000000 --- a/modules/nasmediaAdmixerBidAdapter.md +++ /dev/null @@ -1,36 +0,0 @@ -# Overview - -``` -Module Name: NasmediaAdmixer Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid@nasmedia.co.kr -``` -`` -# Description - -Module that connects to NasmediaAdmixer demand sources. -Banner formats are supported. -The NasmediaAdmixer adapter doesn't support multiple sizes per ad-unit and will use the first one if multiple sizes are defined. - -# Test Parameters -``` - var adUnits = [ - { - code: 'banner-ad-div', - mediaTypes: { - banner: { // banner size - sizes: [[300, 250]] - } - }, - bids: [ - { - bidder: 'nasmediaAdmixer', - params: { - media_key: '19038695', //required - adunit_id: '24190632', //required - } - } - ] - } - ]; -``` diff --git a/modules/nativoBidAdapter.js b/modules/nativoBidAdapter.js deleted file mode 100644 index d396bd4d495..00000000000 --- a/modules/nativoBidAdapter.js +++ /dev/null @@ -1,307 +0,0 @@ -import * as utils from '../src/utils.js' -import { registerBidder } from '../src/adapters/bidderFactory.js' -import { BANNER } from '../src/mediaTypes.js' -// import { config } from 'src/config' - -const BIDDER_CODE = 'nativo' -const BIDDER_ENDPOINT = 'https://exchange.postrelease.com/prebid' - -const TIME_TO_LIVE = 360 - -const SUPPORTED_AD_TYPES = [BANNER] - -const bidRequestMap = {} - -// Prebid adapter referrence doc: https://docs.prebid.org/dev-docs/bidder-adaptor.html - -export const spec = { - code: BIDDER_CODE, - aliases: ['ntv'], // short code - supportedMediaTypes: SUPPORTED_AD_TYPES, - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return bid.params && !!bid.params.placementId - }, - - /** - * Called when the page asks Prebid.js for bids - * Make a server request from the list of BidRequests - * - * @param {Array} validBidRequests - An array of bidRequest objects, one for each AdUnit that your module is involved in. This array has been processed for special features like sizeConfig, so it’s the list that you should be looping through - * @param {Object} bidderRequest - The master bidRequest object. This object is useful because it carries a couple of bid parameters that are global to all the bids. - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - const placementIds = [] - const placmentBidIdMap = {} - let placementId, pageUrl - validBidRequests.forEach((request) => { - pageUrl = pageUrl || request.params.url // Use the first url value found - placementId = request.params.placementId - placementIds.push(placementId) - placmentBidIdMap[placementId] = { - bidId: request.bidId, - size: getLargestSize(request.sizes), - } - }) - bidRequestMap[bidderRequest.bidderRequestId] = placmentBidIdMap - - if (!pageUrl) pageUrl = bidderRequest.refererInfo.referer - - let params = [ - { key: 'ntv_ptd', value: placementIds.toString() }, - { key: 'ntv_pb_rid', value: bidderRequest.bidderRequestId }, - { - key: 'ntv_url', - value: encodeURIComponent(pageUrl), - }, - ] - - if (bidderRequest.gdprConsent) { - // Put on the beginning of the qs param array - params.unshift({ - key: 'ntv_gdpr_consent', - value: bidderRequest.gdprConsent.consentString, - }) - } - - if (bidderRequest.uspConsent) { - // Put on the beginning of the qs param array - params.unshift({ key: 'us_privacy', value: bidderRequest.uspConsent }) - } - - let serverRequest = { - method: 'GET', - url: BIDDER_ENDPOINT + arrayToQS(params), - } - - return serverRequest - }, - - /** - * Will be called when the browser has received the response from your server. - * The function will parse the response and create a bidResponse object containing one or more bids. - * The adapter should indicate no valid bids by returning an empty array. - * - * @param {Object} response - Data returned from the bidding server request endpoint - * @param {Object} request - The request object used to call the server request endpoint - * @return {Array} An array of bids which were nested inside the server. - */ - interpretResponse: function (response, request) { - // If the bid response was empty, return [] - if (!response || !response.body || utils.isEmpty(response.body)) return [] - - try { - const body = - typeof response.body === 'string' - ? JSON.parse(response.body) - : response.body - - const bidResponses = [] - const seatbids = body.seatbid - - // Step through and grab pertinent data - let bidResponse, adUnit - seatbids.forEach((seatbid) => { - seatbid.bid.forEach((bid) => { - adUnit = this.getRequestId(body.id, bid.impid) - bidResponse = { - requestId: adUnit.bidId, - cpm: bid.price, - currency: body.cur, - width: bid.w || adUnit.size[0], - height: bid.h || adUnit.size[1], - creativeId: bid.crid, - dealId: bid.id, - netRevenue: true, - ttl: bid.ttl || TIME_TO_LIVE, - ad: bid.adm, - meta: { - advertiserDomains: bid.adomain, - }, - } - - bidResponses.push(bidResponse) - }) - }) - - // Don't need the map anymore as it was unique for one request/response - delete bidRequestMap[body.id] - - return bidResponses - } catch (error) { - // If there is an error, return [] - return [] - } - }, - - /** - * All user ID sync activity should be done using the getUserSyncs callback of the BaseAdapter model. - * Given an array of all the responses from the server, getUserSyncs is used to determine which user syncs should occur. - * The order of syncs in the serverResponses array matters. The most important ones should come first, since publishers may limit how many are dropped on their page. - * @param {Object} syncOptions - Which user syncs are allowed? - * @param {Array} serverResponses - Array of server's responses - * @param {Object} gdprConsent - GDPR consent data - * @param {Object} uspConsent - USP consent data - * @return {Array} The user syncs which should be dropped. - */ - getUserSyncs: function ( - syncOptions, - serverResponses, - gdprConsent, - uspConsent - ) { - // Generate consent qs string - let params = '' - // GDPR - if (gdprConsent) { - params = appendQSParamString( - params, - 'gdpr', - gdprConsent.gdprApplies ? 1 : 0 - ) - params = appendQSParamString( - params, - 'gdpr_consent', - encodeURIComponent(gdprConsent.consentString || '') - ) - } - // CCPA - if (uspConsent) { - params = appendQSParamString( - params, - 'us_privacy', - encodeURIComponent(uspConsent.uspConsent) - ) - } - - // Get sync urls from the respnse and inject cinbsent params - const types = { - iframe: syncOptions.iframeEnabled, - image: syncOptions.pixelEnabled, - } - const syncs = [] - - let body - serverResponses.forEach((response) => { - // If the bid response was empty, return [] - if (!response || !response.body || utils.isEmpty(response.body)) { - return syncs - } - - body = - typeof response.body === 'string' - ? JSON.parse(response.body) - : response.body - - // Make sure we have valid content - if (!body || !body.seatbid || body.seatbid.length === 0) return - - body.seatbid.forEach((seatbid) => { - // Grab the syncs for each seatbid - seatbid.syncUrls.forEach((sync) => { - if (types[sync.type]) { - if (sync.url.trim() !== '') { - syncs.push({ - type: sync.type, - url: sync.url.replace('{GDPR_params}', params), - }) - } - } - }) - }) - }) - - return syncs - }, - - /** - * Will be called when an adpater timed out for an auction. - * Adapter can fire a ajax or pixel call to register a timeout at thier end. - * @param {Object} timeoutData - Timeout specific data - */ - onTimeout: function (timeoutData) {}, - - /** - * Will be called when a bid from the adapter won the auction. - * @param {Object} bid - The bid that won the auction - */ - onBidWon: function (bid) {}, - - /** - * Will be called when the adserver targeting has been set for a bid from the adapter. - * @param {Object} bidder - The bid of which the targeting has been set - */ - onSetTargeting: function (bid) {}, - - /** - * Maps Prebid's bidId to Nativo's placementId values per unique bidderRequestId - * @param {String} bidderRequestId - The unique ID value associated with the bidderRequest - * @param {String} placementId - The placement ID value from Nativo - * @returns {String} - The bidId value associated with the corresponding placementId - */ - getRequestId: function (bidderRequestId, placementId) { - return ( - bidRequestMap[bidderRequestId] && - bidRequestMap[bidderRequestId][placementId] - ) - }, -} -registerBidder(spec) - -// Utils -/** - * Append QS param to existing string - * @param {String} str - String to append to - * @param {String} key - Key to append - * @param {String} value - Value to append - * @returns - */ -function appendQSParamString(str, key, value) { - return str + `${str.length ? '&' : ''}${key}=${value}` -} - -/** - * Convert an object to query string parameters - * @param {Object} obj - Object to convert - * @returns - */ -function arrayToQS(arr) { - return ( - '?' + - arr.reduce((value, obj) => { - return appendQSParamString(value, obj.key, obj.value) - }, '') - ) -} - -/** - * Get the largest size array - * @param {Array} sizes - Array of size arrays - * @returns Size array with the largest area - */ -function getLargestSize(sizes, method = area) { - if (!sizes || sizes.length === 0) return [] - if (sizes.length === 1) return sizes[0] - - return sizes.reduce((prev, current) => { - if (method(current) > method(prev)) { - return current - } else { - return prev - } - }) -} - -/** - * Calculate the area - * @param {Array} size - [width, height] - * @returns The calculated area - */ -const area = (size) => size[0] * size[1] diff --git a/modules/nativoBidAdapter.md b/modules/nativoBidAdapter.md deleted file mode 100644 index ec0980aae50..00000000000 --- a/modules/nativoBidAdapter.md +++ /dev/null @@ -1,40 +0,0 @@ -# Overview - -``` -Module Name: Nativo Bid Adapter -Module Type: Bidder Adapter -Maintainer: prebiddev@nativo.com -``` - -# Description - -Module that connects to Nativo's demand sources - -# Dev - -gulp serve --modules=nativoBidAdapter - -# Test Parameters - -``` -var adUnits = [ - { - code: 'div-gpt-ad-1460505748561-0', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]], - } - }, - // Replace this object to test a new Adapter! - bids: [{ - bidder: 'nativo', - params: { - placementId: 1125609, - url: 'https://test-sites.internal.nativo.net/testing/prebid_adpater.html' - } - }] - - } - ]; - -``` diff --git a/modules/netIdSystem.js b/modules/netIdSystem.js deleted file mode 100644 index 90c8735c993..00000000000 --- a/modules/netIdSystem.js +++ /dev/null @@ -1,40 +0,0 @@ -/** - * This module adds netId to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/netIdSystem - * @requires module:modules/userId - */ - -import {submodule} from '../src/hook.js'; - -/** @type {Submodule} */ -export const netIdSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: 'netId', - /** - * decode the stored id value for passing to bid requests - * @function decode - * @param {(Object|string)} value - * @returns {(Object|undefined)} - */ - decode(value) { - return (value && typeof value['netId'] === 'string') ? { 'netId': value['netId'] } : undefined; - }, - /** - * performs action to obtain id and return a value in the callback's response argument - * @function - * @param {SubmoduleConfig} [config] - * @param {ConsentData} [consentData] - * @param {(Object|undefined)} cacheIdObj - * @returns {IdResponse|undefined} - */ - getId(config) { - /* currently not possible */ - return {}; - } -}; - -submodule('userId', netIdSubmodule); diff --git a/modules/newborntownWebBidAdapter.js b/modules/newborntownWebBidAdapter.js deleted file mode 100644 index 56c63e2bb4d..00000000000 --- a/modules/newborntownWebBidAdapter.js +++ /dev/null @@ -1,159 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE} from '../src/mediaTypes.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const storage = getStorageManager(); -const BIDDER_CODE = 'newborntownWeb'; - -const REQUEST_URL = 'https://us-west.solortb.com/adx/api/rtb?from=4' - -function randomn(n) { - return parseInt((Math.random() + 1) * Math.pow(10, n - 1)) + ''; -} -function generateGUID() { - var d = new Date().getTime(); - var guid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { - var r = (d + Math.random() * 16) % 16 | 0; - d = Math.floor(d / 16); - return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16); - }) - return guid; -} -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; -} -var platform = (function getPlatform() { - var ua = navigator.userAgent; - if (ua.indexOf('Android') > -1 || ua.indexOf('Adr') > -1) { - return 'Android' - } - if (ua.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)) { - return 'iOS' - } - return 'windows' -})(); -function getLanguage() { - const language = navigator.language ? 'language' : 'userLanguage'; - return navigator[language].split('-')[0]; -} -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, NATIVE], - isBidRequestValid: function(bid) { - return !!(bid.params.publisher_id && bid.params.slot_id && bid.params.bidfloor); - }, - - buildRequests: function(validBidRequests, bidderRequest) { - let requestArr = [] - if (validBidRequests.length === 0) { - return null; - } - var guid; - if (storage.getDataFromLocalStorage('sax_user_id') == null) { - storage.setDataInLocalStorage('sax_user_id', generateGUID()) - } - guid = storage.getDataFromLocalStorage('sax_user_id') - utils._each(validBidRequests, function(bidRequest) { - const bidRequestObj = bidRequest.params - var req = { - id: randomn(12) + randomn(12), - tmax: bidderRequest.timeout, - bidId: bidRequest.bidId, - user: { - id: guid - }, - imp: [ - { - id: '1', - bidfloor: bidRequestObj.bidfloor, - bidfloorcur: 'USD', - banner: { - w: 0, - h: 0 - } - } - ], - site: { - domain: window.location.host, - id: bidRequestObj.slot_id, - page: window.location.href, - publisher: { - id: bidRequestObj.publisher_id - }, - }, - device: { - ip: '', - ua: navigator.userAgent, - os: platform, - geo: { - country: '', - type: 0, - ipservice: 1, - region: '', - city: '', - }, - language: getLanguage(), - devicetype: _getDeviceType() - }, - ext: { - solomath: { - slotid: bidRequestObj.slot_id - } - } - }; - var sizes = bidRequest.sizes; - if (sizes) { - if (sizes && utils.isArray(sizes[0])) { - req.imp[0].banner.w = sizes[0][0]; - req.imp[0].banner.h = sizes[0][1]; - } else if (sizes && utils.isNumber(sizes[0])) { - req.imp[0].banner.w = sizes[0]; - req.imp[0].banner.h = sizes[1]; - } - } else { - return false; - } - const options = { - withCredentials: false - } - requestArr.push({ - method: 'POST', - url: REQUEST_URL, - data: req, - bidderRequest, - options: options - }) - }) - return requestArr; - }, - interpretResponse: function(serverResponse, request) { - var bidResponses = []; - if (serverResponse.body.seatbid && serverResponse.body.seatbid.length > 0 && serverResponse.body.seatbid[0].bid && serverResponse.body.seatbid[0].bid.length > 0 && serverResponse.body.seatbid[0].bid[0].adm) { - utils._each(serverResponse.body.seatbid[0].bid, function(bodyAds) { - var adstr = ''; - adstr = bodyAds.adm; - var bidResponse = { - requestId: request.data.bidId || 0, - cpm: bodyAds.price || 0, - width: bodyAds.w ? bodyAds.w : 0, - height: bodyAds.h ? bodyAds.h : 0, - ad: adstr, - netRevenue: true, - currency: serverResponse.body.cur || 'USD', - ttl: 600, - creativeId: bodyAds.cid - }; - bidResponses.push(bidResponse); - }); - } - return bidResponses; - } -} -registerBidder(spec); diff --git a/modules/newborntownWebBidAdapter.md b/modules/newborntownWebBidAdapter.md deleted file mode 100644 index f607369ffb6..00000000000 --- a/modules/newborntownWebBidAdapter.md +++ /dev/null @@ -1,35 +0,0 @@ -# Overview - -``` -Module Name: NewborntownWeb Bidder Adapter -Module Type: Bidder Adapter -Maintainer: zhuyushuang@newborntown.com -``` - -# Description - -Integration for website - -# Test Parameters -``` - var adUnits = [ - { - code: '/19968336/header-bid-tag-1', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [ - { - bidder: "newborntownWeb", - params: { - 'publisher_id': '1238122', - 'slot_id': '123123', - 'bidfloor': 0.2 - } - } - ] - } - ]; -``` diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js deleted file mode 100644 index af1f0562ba4..00000000000 --- a/modules/nextMillenniumBidAdapter.js +++ /dev/null @@ -1,85 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'nextMillennium'; -const HOST = 'https://brainlyads.com'; -const CURRENCY = 'USD'; -const TIME_TO_LIVE = 360; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - - isBidRequestValid: function(bid) { - return !!( - bid.params.placement_id && utils.isNumber(bid.params.placement_id) - ); - }, - - buildRequests: function(validBidRequests) { - let requests = []; - - utils._each(validBidRequests, function(bid) { - requests.push({ - method: 'POST', - url: HOST + '/hb/s2s', - options: { - contentType: 'application/json', - withCredentials: true - }, - data: JSON.stringify({ - placement_id: utils.getBidIdParameter('placement_id', bid.params) - }), - bidId: bid.bidId - }); - }); - - return requests; - }, - - interpretResponse: function(serverResponse, bidRequest) { - try { - const bidResponse = serverResponse.body; - const bidResponses = []; - - if (Number(bidResponse.cpm) > 0) { - bidResponses.push({ - requestId: bidRequest.bidId, - cpm: bidResponse.cpm, - width: bidResponse.width, - height: bidResponse.height, - creativeId: bidResponse.creativeId, - currency: CURRENCY, - netRevenue: false, - ttl: TIME_TO_LIVE, - ad: bidResponse.ad - }); - } - - return bidResponses; - } catch (err) { - utils.logError(err); - return []; - } - }, - - getUserSyncs: function(syncOptions) { - const syncs = [] - if (syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: HOST + '/hb/s2s/matching' - }); - } - - if (syncOptions.pixelEnabled) { - syncs.push({ - type: 'image', - url: HOST + '/hb/s2s/matching' - }); - } - return syncs; - } -}; -registerBidder(spec); diff --git a/modules/nextMillenniumBidAdapter.md b/modules/nextMillenniumBidAdapter.md deleted file mode 100644 index c583969b4af..00000000000 --- a/modules/nextMillenniumBidAdapter.md +++ /dev/null @@ -1,28 +0,0 @@ -# Overview -``` -Module Name: NextMillennium Bid Adapter -Module Type: Bidder Adapter -Maintainer: mikhail.ivanchenko@iageengineering.net -``` - -# Description -Module that connects to NextMillennium's server for bids. -Currently module supports only banner mediaType. - -# Test Parameters -``` - var adUnits = [{ - code: '/test/div', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [{ - bidder: 'nextMillennium', - params: { - placement_id: -1 - } - }] - }]; -``` \ No newline at end of file diff --git a/modules/nextrollBidAdapter.js b/modules/nextrollBidAdapter.js deleted file mode 100644 index cb317190bea..00000000000 --- a/modules/nextrollBidAdapter.js +++ /dev/null @@ -1,345 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE } from '../src/mediaTypes.js'; - -import find from 'core-js-pure/features/array/find.js'; - -const BIDDER_CODE = 'nextroll'; -const BIDDER_ENDPOINT = 'https://d.adroll.com/bid/prebid/'; -const ADAPTER_VERSION = 5; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, NATIVE], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bidRequest) { - return bidRequest !== undefined && !!bidRequest.params && !!bidRequest.bidId; - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - let topLocation = utils.parseUrl(utils.deepAccess(bidderRequest, 'refererInfo.referer')); - - return validBidRequests.map((bidRequest) => { - return { - method: 'POST', - options: { - withCredentials: true, - }, - url: BIDDER_ENDPOINT, - data: { - id: bidRequest.bidId, - imp: { - id: bidRequest.bidId, - bidfloor: utils.getBidIdParameter('bidfloor', bidRequest.params), - banner: _getBanner(bidRequest), - native: _getNative(utils.deepAccess(bidRequest, 'mediaTypes.native')), - ext: { - zone: { - id: utils.getBidIdParameter('zoneId', bidRequest.params) - }, - nextroll: { - adapter_version: ADAPTER_VERSION - } - } - }, - - user: _getUser(validBidRequests), - site: _getSite(bidRequest, topLocation), - seller: _getSeller(bidRequest), - device: _getDevice(bidRequest), - regs: _getRegs(bidderRequest) - } - }; - }); - }, - - /** - * Unpack the 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. - */ - interpretResponse: function (serverResponse, bidRequest) { - if (!serverResponse.body) { - return []; - } else { - let response = serverResponse.body - let bids = response.seatbid.reduce((acc, seatbid) => acc.concat(seatbid.bid), []); - return bids.map((bid) => _buildResponse(response, bid)); - } - } -} - -function _getBanner(bidRequest) { - let sizes = _getSizes(bidRequest); - if (sizes === undefined) return undefined; - return {format: sizes}; -} - -function _getNative(mediaTypeNative) { - if (mediaTypeNative === undefined) return undefined; - let assets = _getNativeAssets(mediaTypeNative); - if (assets === undefined || assets.length == 0) return undefined; - return { - request: { - native: { - assets: assets - } - } - }; -} - -/* - id: Unique numeric id for the asset - kind: OpenRTB kind of asset. Supported: title, img and data. - key: Name of property that comes in the mediaType.native object. - type: OpenRTB type for that spefic kind of asset. - 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} -]; - -const ASSET_KIND_MAP = { - title: _getTitleAsset, - img: _getImageAsset, - data: _getDataAsset, -}; - -function _getAsset(mediaTypeNative, assetMap) { - const asset = mediaTypeNative[assetMap.key]; - if (asset === undefined) return undefined; - const assetFunc = ASSET_KIND_MAP[assetMap.kind]; - return { - id: assetMap.id, - required: (assetMap.required || !!asset.required) ? 1 : 0, - [assetMap.kind]: assetFunc(asset, assetMap) - }; -} - -function _getTitleAsset(title, _assetMap) { - return {len: title.len || 0}; -} - -function _getMinAspectRatio(aspectRatio, property) { - if (!utils.isPlainObject(aspectRatio)) return 1; - - const ratio = aspectRatio['ratio_' + property]; - const min = aspectRatio['min_' + property]; - - if (utils.isNumber(ratio)) return ratio; - if (utils.isNumber(min)) return min; - - return 1; -} - -function _getImageAsset(image, assetMap) { - const sizes = image.sizes; - const aspectRatio = image.aspect_ratios ? image.aspect_ratios[0] : undefined; - - return { - type: assetMap.type, - w: (sizes ? sizes[0] : undefined), - h: (sizes ? sizes[1] : undefined), - wmin: _getMinAspectRatio(aspectRatio, 'width'), - hmin: _getMinAspectRatio(aspectRatio, 'height'), - }; -} - -function _getDataAsset(data, assetMap) { - return { - type: assetMap.type, - len: data.len || 0 - }; -} - -function _getNativeAssets(mediaTypeNative) { - return NATIVE_ASSET_MAP - .map(assetMap => _getAsset(mediaTypeNative, assetMap)) - .filter(asset => asset !== undefined); -} - -function _getUser(requests) { - const id = utils.deepAccess(requests, '0.userId.nextrollId'); - if (id === undefined) { - return; - } - - return { - ext: { - eid: [{ - 'source': 'nextroll', - id - }] - } - }; -} - -function _buildResponse(bidResponse, bid) { - let response = { - requestId: bidResponse.id, - cpm: bid.price, - width: bid.w, - height: bid.h, - creativeId: bid.crid, - dealId: bidResponse.dealId, - currency: 'USD', - netRevenue: true, - ttl: 300 - }; - if (utils.isStr(bid.adm)) { - response.mediaType = BANNER; - response.ad = utils.replaceAuctionPrice(bid.adm, bid.price); - } else { - response.mediaType = NATIVE; - response.native = _getNativeResponse(bid.adm, bid.price); - } - return response; -} - -const privacyLink = 'https://info.evidon.com/pub_info/573'; -const privacyIcon = 'https://c.betrad.com/pub/icon1.png'; - -function _getNativeResponse(adm, price) { - let baseResponse = { - clickTrackers: (adm.link && adm.link.clicktrackers) || [], - jstracker: adm.jstracker || [], - clickUrl: utils.replaceAuctionPrice(adm.link.url, price), - impressionTrackers: adm.imptrackers.map(impTracker => utils.replaceAuctionPrice(impTracker, price)), - privacyLink: privacyLink, - privacyIcon: privacyIcon - }; - return adm.assets.reduce((accResponse, asset) => { - const assetMaps = NATIVE_ASSET_MAP.filter(assetMap => assetMap.id === asset.id && asset[assetMap.kind] !== undefined); - if (assetMaps.length === 0) return accResponse; - const assetMap = assetMaps[0]; - accResponse[assetMap.key] = _getAssetResponse(asset, assetMap); - return accResponse; - }, baseResponse); -} - -function _getAssetResponse(asset, assetMap) { - switch (assetMap.kind) { - case 'title': - return asset.title.text; - - case 'img': - return { - url: asset.img.url, - width: asset.img.w, - height: asset.img.h - }; - - case 'data': - return asset.data.value; - } -} - -function _getSite(bidRequest, topLocation) { - return { - page: topLocation.href, - domain: topLocation.hostname, - publisher: { - id: utils.getBidIdParameter('publisherId', bidRequest.params) - } - }; -} - -function _getSeller(bidRequest) { - return { - id: utils.getBidIdParameter('sellerId', bidRequest.params) - }; -} - -function _getSizes(bidRequest) { - if (!utils.isArray(bidRequest.sizes)) { - return undefined; - } - return bidRequest.sizes.filter(_isValidSize).map(size => { - return { - w: size[0], - h: size[1] - } - }); -} - -function _isValidSize(size) { - const isNumber = x => typeof x === 'number'; - return (size.length === 2 && isNumber(size[0]) && isNumber(size[1])); -} - -function _getDevice(_bidRequest) { - return { - ua: navigator.userAgent, - language: navigator['language'], - os: _getOs(navigator.userAgent.toLowerCase()), - osv: _getOsVersion(navigator.userAgent) - }; -} - -function _getRegs(bidderRequest) { - if (!bidderRequest || !bidderRequest.uspConsent) { - return undefined; - } - return { - ext: { - us_privacy: bidderRequest.uspConsent - } - }; -} - -function _getOs(userAgent) { - const osTable = { - 'android': /android/i, - 'ios': /iphone|ipad/i, - 'mac': /mac/i, - 'linux': /linux/i, - 'windows': /windows/i - }; - - return find(Object.keys(osTable), os => { - if (userAgent.match(osTable[os])) { - return os; - } - }) || 'etc'; -} - -function _getOsVersion(userAgent) { - const clientStrings = [ - { s: 'Android', r: /Android/ }, - { s: 'iOS', r: /(iPhone|iPad|iPod)/ }, - { s: 'Mac OS X', r: /Mac OS X/ }, - { s: 'Mac OS', r: /(MacPPC|MacIntel|Mac_PowerPC|Macintosh)/ }, - { s: 'Linux', r: /(Linux|X11)/ }, - { s: 'Windows 10', r: /(Windows 10.0|Windows NT 10.0)/ }, - { s: 'Windows 8.1', r: /(Windows 8.1|Windows NT 6.3)/ }, - { s: 'Windows 8', r: /(Windows 8|Windows NT 6.2)/ }, - { s: 'Windows 7', r: /(Windows 7|Windows NT 6.1)/ }, - { s: 'Windows Vista', r: /Windows NT 6.0/ }, - { s: 'Windows Server 2003', r: /Windows NT 5.2/ }, - { s: 'Windows XP', r: /(Windows NT 5.1|Windows XP)/ }, - { s: 'UNIX', r: /UNIX/ }, - { s: 'Search Bot', r: /(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/ } - ]; - let cs = find(clientStrings, cs => cs.r.test(userAgent)); - return cs ? cs.s : 'unknown'; -} - -registerBidder(spec); diff --git a/modules/nextrollBidAdapter.md b/modules/nextrollBidAdapter.md deleted file mode 100644 index c706839c453..00000000000 --- a/modules/nextrollBidAdapter.md +++ /dev/null @@ -1,77 +0,0 @@ -# Overview - -``` -Module Name: NextRoll Bid Adapter -Module Type: Bidder Adapter -Maintainer: prebid@nextroll.com -``` - -# Description - -Module that connects to NextRoll's bidders. -The NextRoll bid adapter supports banner and native format. - -# Test Parameters - -## Banner Example -``` javascript -var adUnits = [ - { - code: 'div-1', - mediatypes: { - banner: {sizes: [[300, 250], [160, 600]]} - }, - bids: [{ - bidder: 'nextroll', - params: { - bidfloor: 1, - zoneId: "13144370", - publisherId: "publisherid", - sellerId: "sellerid" - } - }] - }, - { - code: 'div-2', - mediatypes: { - banner: { - sizes: [[728, 90], [970, 250]] - } - }, - bids: [{ - bidder: 'nextroll', - params: { - bidfloor: 2.3, - zoneId: "13144370", - publisherId: "publisherid", - sellerId: "sellerid" - } - }] - } -] -``` - -## Native Example -```javascript -var adUnits = [ - { - code: 'div-1', - mediaTypes: { - native: { - title: { required: true, len: 80 }, - image: { required: true, sizes: [728, 90] }, - sponsoredBy: { required: false, len: 20 } - } - }, - bids: [{ - bidder: 'nextroll', - params: { - bidfloor: 1, - zoneId: "13144370", - publisherId: "publisherId", - sellerId: "sellerId", - } - }] - } -]; -``` \ No newline at end of file diff --git a/modules/nextrollIdSystem.js b/modules/nextrollIdSystem.js deleted file mode 100644 index 5a59e216394..00000000000 --- a/modules/nextrollIdSystem.js +++ /dev/null @@ -1,50 +0,0 @@ -/** - * This module adds Nextroll ID to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/nextrollIdSystem - * @requires module:modules/userId - */ - -import { deepAccess } from '../src/utils.js'; -import { submodule } from '../src/hook.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const NEXTROLL_ID_LS_KEY = 'dca0.com'; -const KEY_PREFIX = 'AdID:' - -export const storage = getStorageManager(); - -/** @type {Submodule} */ -export const nextrollIdSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: 'nextrollId', - - /** - * decode the stored id value for passing to bid requests - * @function - * @return {{nextrollId: string} | undefined} - */ - decode(value) { - return value; - }, - - /** - * performs action to obtain id and return a value. - * @function - * @param {SubmoduleConfig} [config] - * @returns {{id: {nextrollId: string} | undefined}} - */ - getId(config) { - const key = KEY_PREFIX + deepAccess(config, 'params.partnerId', 'undefined'); - const dataString = storage.getDataFromLocalStorage(NEXTROLL_ID_LS_KEY) || '{}'; - const data = JSON.parse(dataString); - const idValue = deepAccess(data, `${key}.value`); - - return { id: idValue ? {nextrollId: idValue} : undefined }; - } -}; - -submodule('userId', nextrollIdSubmodule); diff --git a/modules/nobidBidAdapter.js b/modules/nobidBidAdapter.js deleted file mode 100644 index 051202cab97..00000000000 --- a/modules/nobidBidAdapter.js +++ /dev/null @@ -1,462 +0,0 @@ -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const storage = getStorageManager(); -const BIDDER_CODE = 'nobid'; -window.nobidVersion = '1.2.9'; -window.nobid = window.nobid || {}; -window.nobid.bidResponses = window.nobid.bidResponses || {}; -window.nobid.timeoutTotal = 0; -window.nobid.bidWonTotal = 0; -window.nobid.refreshCount = 0; -function log(msg, obj) { - utils.logInfo('-NoBid- ' + msg, obj) -} -function nobidSetCookie(cname, cvalue, hours) { - var d = new Date(); - d.setTime(d.getTime() + (hours * 60 * 60 * 1000)); - var expires = 'expires=' + d.toUTCString(); - storage.setCookie(cname, cvalue, expires); -} -function nobidGetCookie(cname) { - return storage.getCookie(cname); -} -function nobidHasPurpose1Consent(bidderRequest) { - let result = true; - if (bidderRequest && bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.gdprApplies && bidderRequest.gdprConsent.apiVersion === 2) { - result = !!(utils.deepAccess(bidderRequest.gdprConsent, 'vendorData.purpose.consents.1') === true); - } - } - return result; -} -function nobidBuildRequests(bids, bidderRequest) { - var serializeState = function(divIds, siteId, adunits) { - var filterAdUnitsByIds = function(divIds, adUnits) { - var filtered = []; - if (!divIds || !divIds.length) { - filtered = adUnits; - } else if (adUnits) { - var a = []; - if (!(divIds instanceof Array)) a.push(divIds); - else a = divIds; - for (var i = 0, l = adUnits.length; i < l; i++) { - var adUnit = adUnits[i]; - if (adUnit && adUnit.d && (a.indexOf(adUnit.d) > -1)) { - filtered.push(adUnit); - } - } - } - return filtered; - } - var gdprConsent = function(bidderRequest) { - var gdprConsent = {}; - if (bidderRequest && bidderRequest.gdprConsent) { - gdprConsent = { - consentString: bidderRequest.gdprConsent.consentString, - // will check if the gdprApplies field was populated with a boolean value (ie from page config). If it's undefined, then default to true - consentRequired: (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') ? bidderRequest.gdprConsent.gdprApplies : false - } - } - return gdprConsent; - } - var uspConsent = function(bidderRequest) { - var uspConsent = ''; - if (bidderRequest && bidderRequest.uspConsent) { - uspConsent = bidderRequest.uspConsent; - } - return uspConsent; - } - var schain = function(bids) { - if (bids && bids.length > 0) { - return bids[0].schain - } - return null; - } - var coppa = function() { - if (config.getConfig('coppa') === true) { - return {'coppa': true}; - } - if (bids && bids.length > 0) { - return bids[0].coppa - } - return null; - } - var topLocation = function(bidderRequest) { - var ret = ''; - if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { - ret = bidderRequest.refererInfo.referer; - } else { - ret = (window.context && window.context.location && window.context.location.href) ? window.context.location.href : document.location.href; - } - return encodeURIComponent(ret.replace(/\%/g, '')); - } - var timestamp = function() { - var date = new Date(); - var zp = function (val) { return (val <= 9 ? '0' + val : '' + val); } - var d = date.getDate(); - var y = date.getFullYear(); - var m = date.getMonth() + 1; - var h = date.getHours(); - var min = date.getMinutes(); - var s = date.getSeconds(); - return '' + y + '-' + zp(m) + '-' + zp(d) + ' ' + zp(h) + ':' + zp(min) + ':' + zp(s); - }; - var clientDim = function() { - try { - var width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); - var height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); - return `${width}x${height}`; - } catch (e) { - utils.logWarn('Could not parse screen dimensions, error details:', e); - } - } - var getEIDs = function(eids) { - if (utils.isArray(eids) && eids.length > 0) { - let src = []; - eids.forEach((eid) => { - let ids = []; - if (eid.uids) { - eid.uids.forEach(value => { - ids.push({'id': value.id + ''}); - }); - } - if (eid.source && ids.length > 0) { - src.push({source: eid.source, uids: ids}); - } - }); - return src; - } - } - var state = {}; - state['sid'] = siteId; - state['l'] = topLocation(bidderRequest); - state['tt'] = encodeURIComponent(document.title); - state['tt'] = state['tt'].replace(/'|;|quot;|39;|&|&|#|\r\n|\r|\n|\t|\f|\%0A|\"|\%22|\%5C|\%23|\%26|\%26|\%09/gm, ''); - state['a'] = filterAdUnitsByIds(divIds, adunits || []); - state['t'] = timestamp(); - state['tz'] = Math.round(new Date().getTimezoneOffset()); - state['r'] = clientDim(); - state['lang'] = (navigator.languages && navigator.languages[0]) || navigator.language || navigator.userLanguage; - state['ref'] = document.referrer; - state['gdpr'] = gdprConsent(bidderRequest); - state['usp'] = uspConsent(bidderRequest); - const sch = schain(bids); - if (sch) state['schain'] = sch; - const cop = coppa(); - if (cop) state['coppa'] = cop; - const eids = getEIDs(utils.deepAccess(bids, '0.userIdAsEids')); - if (eids && eids.length > 0) state['eids'] = eids; - return state; - } - function newAdunit(adunitObject, adunits) { - var getAdUnit = function(divid, adunits) { - for (var i = 0; i < adunits.length; i++) { - if (adunits[i].d === divid) { - return adunits[i]; - } - } - return false; - } - var removeByAttrValue = function(array, attribute, value) { - for (var i = array.length - 1; i >= 0; i--) { - var entry = array[i]; - if (entry[attribute] && entry[attribute] === value) { - array.splice(i, 1); - } - } - } - var a = getAdUnit(adunitObject.div, adunits) || {}; - if (adunitObject.account) { - a.s = adunitObject.account; - } - if (adunitObject.sizes) { - a.z = adunitObject.sizes; - } - if (adunitObject.div) { - a.d = adunitObject.div; - } - if (adunitObject.targeting) { - a.g = adunitObject.targeting; - } else { - a.g = {}; - } - if (adunitObject.div) { - removeByAttrValue(adunits, 'd', adunitObject.div); - } - if (adunitObject.sizeMapping) { - a.sm = adunitObject.sizeMapping; - } - if (adunitObject.siteId) { - a.sid = adunitObject.siteId; - } - if (adunitObject.placementId) { - a.pid = adunitObject.placementId; - } - if (adunitObject.ad_type) { - a.at = adunitObject.ad_type; - } - if (adunitObject.params) { - a.params = adunitObject.params; - } - adunits.push(a); - return adunits; - } - if (typeof window.nobid.refreshLimit !== 'undefined') { - if (window.nobid.refreshLimit < window.nobid.refreshCount) return false; - } - let ublock = nobidGetCookie('_ublock'); - if (ublock) { - log('Request blocked for user. hours: ', ublock); - return false; - } - /* DISCOVER SLOTS */ - var divids = []; - var siteId = 0; - var adunits = []; - for (var i = 0; i < bids.length; i++) { - var bid = bids[i]; - var divid = bid.adUnitCode; - divids.push(divid); - var sizes = bid.sizes; - siteId = (typeof bid.params['siteId'] != 'undefined' && bid.params['siteId']) ? bid.params['siteId'] : siteId; - var placementId = bid.params['placementId']; - - var adType = 'banner'; - const videoMediaType = utils.deepAccess(bid, 'mediaTypes.video'); - const context = utils.deepAccess(bid, 'mediaTypes.video.context'); - if (bid.mediaType === VIDEO || (videoMediaType && (context === 'instream' || context === 'outstream'))) { - adType = 'video'; - } - - if (siteId) { - newAdunit({ - div: divid, - sizes: sizes, - siteId: siteId, - placementId: placementId, - ad_type: adType, - params: bid.params - }, - adunits); - } - } - if (siteId) { - return serializeState(divids, siteId, adunits); - } else { - return false; - } -} -function nobidInterpretResponse(response, bidRequest) { - var findBid = function(divid, bids) { - for (var i = 0; i < bids.length; i++) { - if (bids[i].adUnitCode == divid) { - return bids[i]; - } - } - return false; - } - var setRefreshLimit = function(response) { - if (response && typeof response.rlimit !== 'undefined') window.nobid.refreshLimit = response.rlimit; - } - var setUserBlock = function(response) { - if (response && typeof response.ublock !== 'undefined') { - nobidSetCookie('_ublock', '1', response.ublock); - } - } - setRefreshLimit(response); - setUserBlock(response); - var bidResponses = []; - for (var i = 0; response.bids && i < response.bids.length; i++) { - var bid = response.bids[i]; - if (bid.bdrid < 100 || !bidRequest || !bidRequest.bidderRequest || !bidRequest.bidderRequest.bids) continue; - window.nobid.bidResponses['' + bid.id] = bid; - var reqBid = findBid(bid.divid, bidRequest.bidderRequest.bids); - if (!reqBid) continue; - const bidResponse = { - requestId: reqBid.bidId, - cpm: 1 * ((bid.price) ? bid.price : (bid.bucket) ? bid.bucket : 0), - width: bid.size.w, - height: bid.size.h, - creativeId: (bid.creativeid) || '', - dealId: (bid.dealid) || '', - currency: 'USD', - netRevenue: true, - ttl: 300, - ad: bid.adm, - mediaType: bid.atype || BANNER, - }; - if (bid.vastUrl) { - bidResponse.vastUrl = bid.vastUrl; - } - if (bid.vastXml) { - bidResponse.vastXml = bid.vastXml; - } - if (bid.videoCacheKey) { - bidResponse.videoCacheKey = bid.videoCacheKey; - } - - bidResponses.push(bidResponse); - } - return bidResponses; -}; -window.nobid.renderTag = function(doc, id, win) { - log('nobid.renderTag()', id); - var bid = window.nobid.bidResponses['' + id]; - if (bid && bid.adm2) { - log('nobid.renderTag() found tag', id); - var markup = bid.adm2; - doc.write(markup); - doc.close(); - return; - } - log('nobid.renderTag() tag NOT FOUND *ERROR*', id); -} -window.addEventListener('message', function (event) { - let key = event.message ? 'message' : 'data'; - var msg = '' + event[key]; - if (msg.substring(0, 'nbTagRenderer.requestAdMarkup|'.length) === 'nbTagRenderer.requestAdMarkup|') { - log('Prebid received nbTagRenderer.requestAdMarkup event'); - var adId = msg.substring(msg.indexOf('|') + 1); - if (window.nobid && window.nobid.bidResponses) { - var bid = window.nobid.bidResponses['' + adId]; - if (bid && bid.adm2) { - var markup = bid.adm2; - if (markup) { - event.source.postMessage('nbTagRenderer.renderAdInSafeFrame|' + markup, '*'); - } - } - } - } -}, false); -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - log('isBidRequestValid', bid); - return !!bid.params.siteId; - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests, bidderRequest) { - function resolveEndpoint() { - var ret = 'https://ads.servenobid.com/'; - var env = (typeof utils.getParameterByName === 'function') && (utils.getParameterByName('nobid-env')); - if (!env) ret = 'https://ads.servenobid.com/'; - else if (env == 'beta') ret = 'https://beta.servenobid.com/'; - else if (env == 'dev') ret = '//localhost:8282/'; - else if (env == 'qa') ret = 'https://qa-ads.nobid.com/'; - return ret; - } - var buildEndpoint = function() { - return resolveEndpoint() + 'adreq?cb=' + Math.floor(Math.random() * 11000); - } - log('validBidRequests', validBidRequests); - if (!validBidRequests || validBidRequests.length <= 0) { - log('Empty validBidRequests'); - return; - } - const payload = nobidBuildRequests(validBidRequests, bidderRequest); - if (!payload) return; - window.nobid.refreshCount++; - const payloadString = JSON.stringify(payload).replace(/'|&|#/g, '') - const endpoint = buildEndpoint(); - - let options = {}; - if (!nobidHasPurpose1Consent(bidderRequest)) { - options = { withCredentials: false }; - } - - return { - method: 'POST', - url: endpoint, - data: payloadString, - bidderRequest, - options - }; - }, - /** - * Unpack the 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. - */ - interpretResponse: function(serverResponse, bidRequest) { - log('interpretResponse -> serverResponse', serverResponse); - log('interpretResponse -> bidRequest', bidRequest); - return nobidInterpretResponse(serverResponse.body, bidRequest); - }, - - /** - * Register the user sync pixels which should be dropped after the auction. - * - * @param {SyncOptions} syncOptions Which user syncs are allowed? - * @param {ServerResponse[]} serverResponses List of server's responses. - * @return {UserSync[]} The user syncs which should be dropped. - */ - getUserSyncs: function(syncOptions, serverResponses, gdprConsent, usPrivacy) { - if (syncOptions.iframeEnabled) { - let params = ''; - if (gdprConsent && typeof gdprConsent.consentString === 'string') { - // add 'gdpr' only if 'gdprApplies' is defined - if (typeof gdprConsent.gdprApplies === 'boolean') { - params += `?gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - params += `?gdpr_consent=${gdprConsent.consentString}`; - } - } - if (usPrivacy) { - if (params.length > 0) params += '&'; - else params += '?'; - params += 'usp_consent=' + usPrivacy; - } - return [{ - type: 'iframe', - url: 'https://public.servenobid.com/sync.html' + params - }]; - } else if (syncOptions.pixelEnabled && serverResponses.length > 0) { - let syncs = []; - if (serverResponses[0].body.syncs && serverResponses[0].body.syncs.length > 0) { - serverResponses[0].body.syncs.forEach(element => { - syncs.push({ - type: 'image', - url: element - }); - }) - } - return syncs; - } else { - utils.logWarn('-NoBid- Please enable iframe based user sync.', syncOptions); - return []; - } - }, - - /** - * Register bidder specific code, which will execute if bidder timed out after an auction - * @param {data} Containing timeout specific data - */ - onTimeout: function(data) { - window.nobid.timeoutTotal++; - log('Timeout total: ' + window.nobid.timeoutTotal, data); - return window.nobid.timeoutTotal; - }, - onBidWon: function(data) { - window.nobid.bidWonTotal++; - log('BidWon total: ' + window.nobid.bidWonTotal, data); - return window.nobid.bidWonTotal; - } -} -registerBidder(spec); diff --git a/modules/nobidBidAdapter.md b/modules/nobidBidAdapter.md deleted file mode 100644 index 9e47aa5f43f..00000000000 --- a/modules/nobidBidAdapter.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -layout: bidder -title: Nobid -description: Prebid Nobid Bidder Adaptor -biddercode: nobid -hide: true -media_types: banner -gdpr_supported: true -usp_supported: true ---- - -### Bid Params - -{: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|---------------|----------|-------------|---------|----------| -| `siteId` | required | siteId is provided by your Nobid account manager | | `integer` | - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 250]], // a display size - } - }, - bids: [ - { - bidder: "nobid", - params: { - siteId: 2 - } - } - ] - },{ - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[320, 50]], // a mobile size - } - }, - bids: [ - { - bidder: "nobid", - params: { - siteId: 2 - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/novatiqIdSystem.js b/modules/novatiqIdSystem.js deleted file mode 100644 index fbfa6ca8abc..00000000000 --- a/modules/novatiqIdSystem.js +++ /dev/null @@ -1,88 +0,0 @@ -/** - * This module adds novatiqId to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/novatiqIdSystem - * @requires module:modules/userId - */ - -import * as utils from '../src/utils.js'; -import { ajax } from '../src/ajax.js'; -import { submodule } from '../src/hook.js'; - -/** @type {Submodule} */ -export const novatiqIdSubmodule = { - -/** -* used to link submodule with config -* @type {string} -*/ - name: 'novatiq', - - /** -* decode the stored id value for passing to bid requests -* @function -* @returns {novatiq: {snowflake: string}} -*/ - decode(novatiqId, config) { - let responseObj = { - novatiq: { - snowflake: novatiqId - } - }; - return responseObj; - }, - - /** -* performs action to obtain id and return a value in the callback's response argument -* @function -* @param {SubmoduleConfig} config -* @returns {id: string} -*/ - getId(config) { - function snowflakeId(placeholder) { - return placeholder - ? (placeholder ^ Math.random() * 16 >> placeholder / 4).toString(16) - : ([1e7] + -1e3 + -4e3 + -8e3 + -1e11 + 1e3).replace(/[018]/g, snowflakeId); - } - - const configParams = config.params || {}; - const srcId = this.getSrcId(configParams); - utils.logInfo('NOVATIQ Sync request used sourceid param: ' + srcId); - - let partnerhost; - partnerhost = window.location.hostname; - utils.logInfo('NOVATIQ partner hostname: ' + partnerhost); - - const novatiqId = snowflakeId(); - const url = 'https://spadsync.com/sync?sptoken=' + novatiqId + '&sspid=' + srcId + '&ssphost=' + partnerhost; - ajax(url, undefined, undefined, { method: 'GET', withCredentials: false }); - - utils.logInfo('NOVATIQ snowflake: ' + novatiqId); - return { 'id': novatiqId } - }, - - getSrcId(configParams) { - utils.logInfo('NOVATIQ Configured sourceid param: ' + configParams.sourceid); - - function isHex(str) { - var a = parseInt(str, 16); - return (a.toString(16) === str) - } - - let srcId; - if (typeof configParams.sourceid === 'undefined' || configParams.sourceid === null || configParams.sourceid === '') { - srcId = '000'; - utils.logInfo('NOVATIQ sourceid param set to value 000 due to undefined parameter or missing value in config section'); - } else if (configParams.sourceid.length < 3 || configParams.sourceid.length > 3) { - srcId = '001'; - utils.logInfo('NOVATIQ sourceid param set to value 001 due to wrong size in config section 3 chars max e.g. 1ab'); - } else if (isHex(configParams.sourceid) == false) { - srcId = '002'; - utils.logInfo('NOVATIQ sourceid param set to value 002 due to wrong format in config section expecting hex value only'); - } else { - srcId = configParams.sourceid; - } - return srcId - } -}; -submodule('userId', novatiqIdSubmodule); diff --git a/modules/novatiqIdSystem.md b/modules/novatiqIdSystem.md deleted file mode 100644 index ce561a696e3..00000000000 --- a/modules/novatiqIdSystem.md +++ /dev/null @@ -1,36 +0,0 @@ -# Novatiq Snowflake ID - -Novatiq proprietary dynamic snowflake ID is a unique, non sequential and single use identifier for marketing activation. Our in network solution matches verification requests to telco network IDs, safely and securely inside telecom infrastructure. Novatiq snowflake ID can be used for identity validation and as a secured 1st party data delivery mechanism. - -## Novatiq Snowflake ID Configuration - -Enable by adding the Novatiq submodule to your Prebid.js package with: - -``` -gulp build --modules=novatiqIdSystem,userId -``` - -Module activation and configuration: - -```javascript -pbjs.setConfig({ - userSync: { - userIds: [{ - name: 'novatiq', - params: { - sourceid '1a3', // change to the Partner Number you received from Novatiq - } - } - }], - auctionDelay: 50 // 50ms maximum auction delay, applies to all userId modules - } -}); -``` - -| Param under userSync.userIds[] | Scope | Type | Description | Example | -| --- | --- | --- | --- | --- | -| name | Required | String | Module identification: `"novatiq"` | `"novatiq"` | -| params | Required | Object | Configuration specifications for the Novatiq module. | | -| params.sourceid | Required | String | This is the Novatiq Partner Number obtained via Novatiq registration. | `1a3` | - -If you have any questions, please reach out to us at prebid@novatiq.com. diff --git a/modules/oneVideoBidAdapter.js b/modules/oneVideoBidAdapter.js deleted file mode 100644 index e57c9d12ff7..00000000000 --- a/modules/oneVideoBidAdapter.js +++ /dev/null @@ -1,370 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'oneVideo'; -export const spec = { - code: 'oneVideo', - VERSION: '3.1.0', - ENDPOINT: 'https://ads.adaptv.advertising.com/rtb/openrtb?ext_id=', - E2ETESTENDPOINT: 'https://ads-wc.v.ssp.yahoo.com/rtb/openrtb?ext_id=', - SYNC_ENDPOINT1: 'https://pixel.advertising.com/ups/57304/sync?gdpr=&gdpr_consent=&_origin=0&redir=true', - SYNC_ENDPOINT2: 'https://match.adsrvr.org/track/cmf/generic?ttd_pid=adaptv&ttd_tpi=1', - supportedMediaTypes: ['video', 'banner'], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - if (bid.bidder !== BIDDER_CODE || typeof bid.params === 'undefined') { - return false; - } - - // Video validations - if (typeof bid.params.video === 'undefined' || typeof bid.params.video.playerWidth === 'undefined' || typeof bid.params.video.playerHeight == 'undefined' || typeof bid.params.video.mimes == 'undefined') { - return false; - } - - // Prevend DAP Outstream validation, Banner DAP validation & Multi-Format adUnit support - if (bid.mediaTypes.video) { - if (bid.mediaTypes.video.context === 'outstream' && bid.params.video.display === 1) { - return false; - } - } else if (bid.mediaTypes.banner && !bid.params.video.display) { - return false; - } - - // Pub Id validation - if (typeof bid.params.pubId === 'undefined') { - return false; - } - - return true; - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @param bidderRequest - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(bids, bidRequest) { - let consentData = bidRequest ? bidRequest.gdprConsent : null; - - return bids.map(bid => { - let url = spec.ENDPOINT - let pubId = bid.params.pubId; - if (bid.params.video.e2etest) { - url = spec.E2ETESTENDPOINT; - pubId = 'HBExchange'; - } - return { - method: 'POST', - /** removing adding local protocal since we - * can get cookie data only if we call with https. */ - url: url + pubId, - data: getRequestData(bid, consentData, bidRequest), - bidRequest: bid - } - }) - }, - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(response, {bidRequest}) { - let bid; - let size; - let bidResponse; - try { - response = response.body; - bid = response.seatbid[0].bid[0]; - } catch (e) { - response = null; - } - if (!response || !bid || (!bid.adm && !bid.nurl) || !bid.price) { - utils.logWarn(`No valid bids from ${spec.code} bidder`); - return []; - } - size = getSize(bidRequest.sizes); - bidResponse = { - requestId: bidRequest.bidId, - bidderCode: spec.code, - cpm: bid.price, - creativeId: bid.crid, - width: size.width, - height: size.height, - currency: response.cur, - ttl: (bidRequest.params.video.ttl > 0 && bidRequest.params.video.ttl <= 3600) ? bidRequest.params.video.ttl : 300, - netRevenue: true, - adUnitCode: bidRequest.adUnitCode - }; - - bidResponse.mediaType = (bidRequest.mediaTypes.banner) ? 'banner' : 'video' - - if (bid.nurl) { - bidResponse.vastUrl = bid.nurl; - } else if (bid.adm && bidRequest.params.video.display === 1) { - bidResponse.ad = bid.adm - } else if (bid.adm) { - bidResponse.vastXml = bid.adm; - } - if (bidRequest.mediaTypes.video) { - bidResponse.renderer = (bidRequest.mediaTypes.video.context === 'outstream') ? newRenderer(bidRequest, bidResponse) : undefined; - } - - return bidResponse; - }, - /** - * Register the user sync pixels which should be dropped after the auction. - * - * @param {SyncOptions} syncOptions Which user syncs are allowed? - * @param {ServerResponse[]} serverResponses List of server's responses. - * @return {UserSync[]} The user syncs which should be dropped. - */ - getUserSyncs: function(syncOptions, responses, consentData = {}) { - let { - gdprApplies, - consentString = '' - } = consentData; - - if (syncOptions.pixelEnabled) { - return [{ - type: 'image', - url: spec.SYNC_ENDPOINT1 - }, - { - type: 'image', - url: `https://sync-tm.everesttech.net/upi/pid/m7y5t93k?gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${consentString}&redir=https%3A%2F%2Fpixel.advertising.com%2Fups%2F55986%2Fsync%3Fuid%3D%24%7BUSER_ID%7D%26_origin%3D0` + encodeURI(`&gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${consentString}`) - }, - { - type: 'image', - url: spec.SYNC_ENDPOINT2 - }]; - } - } -}; - -function getSize(sizes) { - let parsedSizes = utils.parseSizesInput(sizes); - let [ width, height ] = parsedSizes.length ? parsedSizes[0].split('x') : []; - return { - width: parseInt(width, 10) || undefined, - height: parseInt(height, 10) || undefined - }; -} - -function isConsentRequired(consentData) { - return !!(consentData && consentData.gdprApplies); -} - -function getRequestData(bid, consentData, bidRequest) { - let loc = bidRequest.refererInfo.referer; - let page = (bid.params.site && bid.params.site.page) ? (bid.params.site.page) : (loc.href); - let ref = (bid.params.site && bid.params.site.referrer) ? bid.params.site.referrer : bidRequest.refererInfo.referer; - let getFloorRequestObject = { - currency: bid.params.cur || 'USD', - mediaType: 'video', - size: '*' - }; - let bidData = { - id: utils.generateUUID(), - at: 2, - imp: [{ - id: '1', - secure: isSecure(), - ext: { - hb: 1, - prebidver: '$prebid.version$', - adapterver: spec.VERSION, - } - }], - site: { - page: page, - ref: ref - }, - device: { - ua: navigator.userAgent - }, - tmax: 200 - }; - - if (bid.params.video.display == undefined || bid.params.video.display != 1) { - bidData.imp[0].video = { - mimes: bid.params.video.mimes, - w: bid.params.video.playerWidth, - h: bid.params.video.playerHeight, - pos: bid.params.video.position, - }; - if (bid.params.video.maxbitrate) { - bidData.imp[0].video.maxbitrate = bid.params.video.maxbitrate - } - if (bid.params.video.maxduration) { - bidData.imp[0].video.maxduration = bid.params.video.maxduration - } - if (bid.params.video.minduration) { - bidData.imp[0].video.minduration = bid.params.video.minduration - } - if (bid.params.video.api) { - bidData.imp[0].video.api = bid.params.video.api - } - if (bid.params.video.delivery) { - bidData.imp[0].video.delivery = bid.params.video.delivery - } - if (bid.params.video.position) { - bidData.imp[0].video.pos = bid.params.video.position - } - if (bid.params.video.playbackmethod) { - bidData.imp[0].video.playbackmethod = bid.params.video.playbackmethod - } - if (bid.params.video.placement) { - bidData.imp[0].video.placement = bid.params.video.placement - } - if (bid.params.video.rewarded) { - bidData.imp[0].ext.rewarded = bid.params.video.rewarded - } - bidData.imp[0].video.linearity = 1; - bidData.imp[0].video.protocols = bid.params.video.protocols || [2, 5]; - } else if (bid.params.video.display == 1) { - getFloorRequestObject.mediaType = 'banner'; - bidData.imp[0].banner = { - mimes: bid.params.video.mimes, - w: bid.params.video.playerWidth, - h: bid.params.video.playerHeight, - pos: bid.params.video.position, - }; - if (bid.params.video.placement) { - bidData.imp[0].banner.placement = bid.params.video.placement - } - if (bid.params.video.maxduration) { - bidData.imp[0].banner.ext = bidData.imp[0].banner.ext || {} - bidData.imp[0].banner.ext.maxduration = bid.params.video.maxduration - } - if (bid.params.video.minduration) { - bidData.imp[0].banner.ext = bidData.imp[0].banner.ext || {} - bidData.imp[0].banner.ext.minduration = bid.params.video.minduration - } - } - - if (utils.isFn(bid.getFloor)) { - let floorData = bid.getFloor(getFloorRequestObject); - bidData.imp[0].bidfloor = floorData.floor; - bidData.cur = floorData.currency; - } else { - bidData.imp[0].bidfloor = bid.params.bidfloor; - }; - - if (bid.params.video.inventoryid) { - bidData.imp[0].ext.inventoryid = bid.params.video.inventoryid - } - if (bid.params.video.sid) { - bidData.source = { - ext: { - schain: { - complete: 1, - nodes: [{ - sid: bid.params.video.sid, - rid: bidData.id, - }] - } - } - } - if (bid.params.video.hp == 1) { - bidData.source.ext.schain.nodes[0].hp = bid.params.video.hp; - } - } else if (bid.schain) { - bidData.source = { - ext: { - schain: bid.schain - } - } - bidData.source.ext.schain.nodes[0].rid = bidData.id; - } - if (bid.params.site && bid.params.site.id) { - bidData.site.id = bid.params.site.id - } - if (isConsentRequired(consentData) || (bidRequest && bidRequest.uspConsent)) { - bidData.regs = { - ext: {} - }; - if (isConsentRequired(consentData)) { - bidData.regs.ext.gdpr = 1 - } - - if (consentData && consentData.consentString) { - bidData.user = { - ext: { - consent: consentData.consentString - } - }; - } - // ccpa support - if (bidRequest && bidRequest.uspConsent) { - bidData.regs.ext.us_privacy = bidRequest.uspConsent - } - } - if (bid.params.video.e2etest) { - utils.logMessage('+++ oneVideoBidAdapter: E2E test mode enabled. \n The following parameters are being overridden by e2etest mode:\n* bidfloor:null\n* width:300\n* height:250\n* mimes: video/mp4, application/javascript\n* api:2\n* site.page/ref: verizonmedia.com\n* tmax:1000'); - bidData.imp[0].bidfloor = null; - bidData.imp[0].video.w = 300; - bidData.imp[0].video.h = 250; - bidData.imp[0].video.mimes = ['video/mp4', 'application/javascript']; - bidData.imp[0].video.api = [2]; - bidData.site.page = 'https://verizonmedia.com'; - bidData.site.ref = 'https://verizonmedia.com'; - bidData.tmax = 1000; - } - if (bid.params.video.custom && utils.isPlainObject(bid.params.video.custom)) { - bidData.imp[0].ext.custom = {}; - for (const key in bid.params.video.custom) { - if (utils.isStr(bid.params.video.custom[key]) || utils.isNumber(bid.params.video.custom[key])) { - bidData.imp[0].ext.custom[key] = bid.params.video.custom[key]; - } - } - } - if (bid.params.video.content && utils.isPlainObject(bid.params.video.content)) { - bidData.site.content = {}; - const contentStringKeys = ['id', 'title', 'series', 'season', 'genre', 'contentrating', 'language']; - const contentNumberkeys = ['episode', 'prodq', 'context', 'livestream', 'len']; - const contentArrayKeys = ['cat']; - const contentObjectKeys = ['ext']; - for (const contentKey in bid.params.video.content) { - if ( - (contentStringKeys.indexOf(contentKey) > -1 && utils.isStr(bid.params.video.content[contentKey])) || - (contentNumberkeys.indexOf(contentKey) > -1 && utils.isNumber(bid.params.video.content[contentKey])) || - (contentObjectKeys.indexOf(contentKey) > -1 && utils.isPlainObject(bid.params.video.content[contentKey])) || - (contentArrayKeys.indexOf(contentKey) > -1 && utils.isArray(bid.params.video.content[contentKey]) && - bid.params.video.content[contentKey].every(catStr => utils.isStr(catStr)))) { - bidData.site.content[contentKey] = bid.params.video.content[contentKey]; - } else { - utils.logMessage('oneVideo bid adapter validation error: ', contentKey, ' is either not supported is OpenRTB V2.5 or value is undefined'); - } - } - } - return bidData; -} - -function isSecure() { - return document.location.protocol === 'https:'; -} -/** - * Create oneVideo renderer - * @returns {*} - */ -function newRenderer(bidRequest, bid) { - if (!bidRequest.renderer) { - bidRequest.renderer = {}; - bidRequest.renderer.url = 'https://cdn.vidible.tv/prod/hb-outstream-renderer/renderer.js'; - bidRequest.renderer.render = function(bid) { - setTimeout(function() { - // eslint-disable-next-line no-undef - o2PlayerRender(bid); - }, 700) - }; - } -} - -registerBidder(spec); diff --git a/modules/oneVideoBidAdapter.md b/modules/oneVideoBidAdapter.md deleted file mode 100644 index a42433e80b5..00000000000 --- a/modules/oneVideoBidAdapter.md +++ /dev/null @@ -1,396 +0,0 @@ -# Overview - -**Module Name**: One Video Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: deepthi.neeladri.sravana@verizonmedia.com - -# Description -Connects to Verizon Media's Video SSP (AKA ONE Video / Adap.tv) demand source to fetch bids. - -# Integration Examples: -## Instream Video adUnit example & parameters -*Note:* The Video SSP ad server will respond with an VAST XML to load into your defined player. -``` - var adUnits = [ - { - code: 'video1', - mediaTypes: { - video: { - context: 'instream', - playerSize: [480, 640] - } - }, - bids: [ - { - bidder: 'oneVideo', - params: { - video: { - playerWidth: 480, - playerHeight: 640, - mimes: ['video/mp4', 'application/javascript'], - protocols: [2,5], - api: [2], - position: 1, - delivery: [2], - playbackmethod: [1,5], - sid: YOUR_VSSP_ORG_ID, - hp: 1, - rewarded: 1, - placement: 1, - inventoryid: 123, - minduration: 10, - maxduration: 30, - ttl: 300, - custom: { - key1: "value1", - key2: 123345 - } - }, - bidfloor: 0.5, - site: { - id: 1, - page: 'https://verizonmedia.com', - referrer: 'https://verizonmedia.com' - }, - pubId: 'HBExchange' - } - } - ] - } - ] -``` -## Outstream Video adUnit example & parameters -*Note:* The Video SSP ad server will load it's own Outstream Renderer (player) as a fallback if no player is defined on the publisher page. The Outstream player will inject into the div id that has an identical adUnit code. -``` - var adUnits = [ - { - code: 'video1', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [480, 640] - } - }, - bids: [ - { - bidder: 'oneVideo', - params: { - video: { - playerWidth: 480, - playerHeight: 640, - mimes: ['video/mp4', 'application/javascript'], - protocols: [2,5], - api: [2], - position: 1, - delivery: [2], - playbackmethod: [1,5], - sid: YOUR_VSSP_ORG_ID, - hp: 1, - rewarded: 1, - placement: 1, - inventoryid: 123, - minduration: 10, - maxduration: 30, - ttl: 250 - }, - bidfloor: 0.5, - site: { - id: 1, - page: 'https://verizonmedia.com', - referrer: 'https://verizonmedia.com' - }, - pubId: 'HBExchange' - } - } - ] - } - ] -``` - -## S2S / Video: Dynamic Ad Placement (DAP) adUnit example & parameters -*Note:* The Video SSP ad server will respond with HTML embed tag to be injected into an iFrame you create. -``` - var adUnits = [ - { - code: 'video1', - mediaTypes: { - video: { - context: "instream", - playerSize: [480, 640] - } - }, - bids: [ - { - bidder: 'oneVideo', - params: { - video: { - playerWidth: 480, - playerHeight: 640, - mimes: ['video/mp4', 'application/javascript'], - position: 1, - display: 1 - }, - bidfloor: 0.5, - site: { - id: 1, - page: 'https://verizonmedia.com', - referrer: 'https://verizonmedia.com' - }, - pubId: 'HBExchangeDAP' - } - } - ] - } -] -``` -## Prebid.js / Banner: Dynamic Ad Placement (DAP) adUnit example & parameters -*Note:* The Video SSP ad server will respond with HTML embed tag to be injected into an iFrame created by Google Ad Manager (GAM). -``` - var adUnits = [ - { - code: 'banner-1', - mediaTypes: { - banner: { - sizes: [300, 250] - } - }, - bids: [ - { - bidder: 'oneVideo', - params: { - video: { - playerWidth: 300, - playerHeight: 250, - mimes: ['video/mp4', 'application/javascript'], - display: 1 - }, - bidfloor: 0.5, - site: { - id: 1, - page: 'https://verizonmedia.com', - referrer: 'https://verizonmedia.com' - }, - pubId: 'HBExchangeDAP' - } - } - ] - } -] -``` - -# End 2 End Testing Mode -By passing bid.params.video.e2etest = true you will be able to receive a test creative when connecting via VPN location U.S West Coast. This will allow you to trubleshoot how your player/ad-server parses and uses the VAST XML response. -This automatically sets default values for the outbound bid-request to respond from our test exchange. -No need to override the site/ref urls or change your pubId -``` -var adUnits = [ - { - code: 'video-1', - mediaTypes: { - video: { - context: "instream", - playerSize: [480, 640] - } - }, - bids: [ - { - bidder: 'oneVideo', - params: { - video: { - playerWidth: 300, - playerHeight: 250, - mimes: ['video/mp4', 'application/javascript'], - e2etest: true - }, - pubId: 'YOUR_PUBLISHER_ID' - } - } - ] - } -] -``` - -# Supply Chain Object Support -The oneVideoBidAdapter supports 2 methods for passing/creating an schain object. -1. By passing your Video SSP Org ID in the bid.video.params.sid - The adapter will create a new schain object and our ad-server will fill in the data for you. -2. Using the Prebid Supply Chain Object Module - The adapter will capture the schain object -*Note:* You cannot pass both schain object and bid.video.params.sid together. Option 1 will always be the default. - -## Create new schain using bid.video.params.sid -sid = your Video SSP Organization ID. -This is for direct publishers only. -``` -var adUnits = [ - { - code: 'video1', - mediaTypes: { - video: { - context: 'instream', - playerSize: [480, 640] - } - }, - bids: [ - { - bidder: 'oneVideo', - params: { - video: { - playerWidth: 480, - playerHeight: 640, - mimes: ['video/mp4', 'application/javascript'], - protocols: [2,5], - api: [2], - sid: - }, - bidfloor: 0.5, - site: { - id: 1, - page: 'https://verizonmedia.com', - referrer: 'https://verizonmedia.com' - }, - pubId: 'HBExchange' - } - } - ] - } - ] -``` - -## Pass global schain using pbjs.setConfig(SCHAIN_OBJECT) -For both Authorized resellers and direct publishers. -``` -pbjs.setConfig({ - "schain": { - "validation": "strict", - "config": { - "ver": "1.0", - "complete": 1, - "nodes": [{ - "asi": "some-platform.com", - "sid": "111111", - "hp": 1 - }] - } - } -}); - -var adUnits = [ - { - code: 'video1', - mediaTypes: { - video: { - context: 'instream', - playerSize: [480, 640] - } - }, - bids: [ - { - bidder: 'oneVideo', - params: { - video: { - playerWidth: 480, - playerHeight: 640, - mimes: ['video/mp4', 'application/javascript'], - protocols: [2,5], - api: [2], - }, - bidfloor: 0.5, - site: { - id: 1, - page: 'https://verizonmedia.com', - referrer: 'https://verizonmedia.com' - }, - pubId: 'HBExchange' - } - } - ] - } - ] -``` -# Content Object Support -The oneVideoBidAdapter supports passing of OpenRTB V2.5 Content Object. - -``` -const adUnits = [{ - code: 'video1', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [640, 480] - } - }, - bids: [{ - bidder: 'oneVideo', - params: { - video: { - playerWidth: 640, - playerHeight: 480, - mimes: ['video/mp4', 'application/javascript'], - protocols: [2, 5], - api: [1, 2], - ttl: 300, - content: { - id: "1234", - title: "Title", - series: "Series", - season: "Season", - episode: 1 - cat: [ - "IAB1", - "IAB1-1", - "IAB1-2", - "IAB2", - "IAB2-1" - ], - genre: "Genre", - contentrating: "C-Rating", - language: "EN", - prodq: 1, - context: 1, - livestream: 0, - len: 360, - ext: { - network: "ext-network", - channel: "ext-channel" - } - } - }, - bidfloor: 0.5, - pubId: 'HBExchange' - } - } - }] - }] -``` - - -# TTL Support -The oneVideoBidAdapter supports passing of "Time To Live" (ttl) that indicates to prebid chache for how long to keep the chaced winning bid alive. -Value is Number in seconds -You can enter any number between 1 - 3600 (seconds) -``` -const adUnits = [{ - code: 'video1', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [640, 480] - } - }, - bids: [{ - bidder: 'oneVideo', - params: { - video: { - playerWidth: 640, - playerHeight: 480, - mimes: ['video/mp4', 'application/javascript'], - protocols: [2, 5], - api: [1, 2], - ttl: 300 - }, - bidfloor: 0.5, - pubId: 'HBExchange' - } - }] - }] -``` - diff --git a/modules/oneplanetonlyBidAdapter.md b/modules/oneplanetonlyBidAdapter.md deleted file mode 100644 index 973adb33efd..00000000000 --- a/modules/oneplanetonlyBidAdapter.md +++ /dev/null @@ -1,50 +0,0 @@ -# Overview - -``` -Module Name: OnePlanetOnly Bidder Adapter -Module Type: Bidder Adapter -Maintainer: vitaly@oneplanetonly.com -``` - -# Description - -Module that connects to OnePlanetOnly's demand sources - -# Test Parameters -``` - var adUnits = [ - { - code: 'desktop-banner-ad-div', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - } - }, - bids: [ - { - bidder: 'oneplanetonly', - params: { - siteId: '5', - adUnitId: '5-4587544' - } - } - ] - },{ - code: 'mobile-banner-ad-div', - mediaTypes: { - banner: { - sizes: [[320, 50], [320, 100]], - } - }, - bids: [ - { - bidder: "oneplanetonly", - params: { - siteId: '5', - adUnitId: '5-81037880' - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/onetagBidAdapter.js b/modules/onetagBidAdapter.js deleted file mode 100644 index 16b8096646f..00000000000 --- a/modules/onetagBidAdapter.js +++ /dev/null @@ -1,379 +0,0 @@ -'use strict'; - -import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import { INSTREAM, OUTSTREAM } from '../src/video.js'; -import { Renderer } from '../src/Renderer.js'; -import find from 'core-js-pure/features/array/find.js'; -import { getStorageManager } from '../src/storageManager.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { createEidsArray } from './userId/eids.js'; - -const ENDPOINT = 'https://onetag-sys.com/prebid-request'; -const USER_SYNC_ENDPOINT = 'https://onetag-sys.com/usync/'; -const BIDDER_CODE = 'onetag'; -const GVLID = 241; - -const storage = getStorageManager(GVLID); - -/** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ -function isBidRequestValid(bid) { - if (typeof bid === 'undefined' || typeof bid.params === 'undefined' || typeof bid.params.pubId !== 'string') { - return false; - } - return isValid(BANNER, bid) || isValid(VIDEO, bid); -} - -export function hasTypeVideo(bid) { - return typeof bid.mediaTypes !== 'undefined' && typeof bid.mediaTypes.video !== 'undefined'; -} - -export function isValid(type, bid) { - if (type === BANNER) { - return parseSizes(bid).length > 0; - } else if (type === VIDEO && hasTypeVideo(bid)) { - const context = bid.mediaTypes.video.context; - if (context === 'outstream' || context === 'instream') { - return parseVideoSize(bid).length > 0; - } - } - return false; -} - -/** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ -function buildRequests(validBidRequests, bidderRequest) { - const payload = { - bids: requestsToBids(validBidRequests), - ...getPageInfo() - }; - if (bidderRequest && bidderRequest.gdprConsent) { - payload.gdprConsent = { - consentString: bidderRequest.gdprConsent.consentString, - consentRequired: bidderRequest.gdprConsent.gdprApplies - }; - } - if (bidderRequest && bidderRequest.uspConsent) { - payload.usPrivacy = bidderRequest.uspConsent; - } - if (validBidRequests && validBidRequests.length !== 0 && validBidRequests[0].userId) { - payload.userId = createEidsArray(validBidRequests[0].userId); - } - try { - if (storage.hasLocalStorage()) { - payload.onetagSid = storage.getDataFromLocalStorage('onetag_sid'); - } - } catch (e) {} - return { - method: 'POST', - url: ENDPOINT, - data: JSON.stringify(payload) - } -} - -function interpretResponse(serverResponse, bidderRequest) { - const body = serverResponse.body; - const bids = []; - const requestData = JSON.parse(bidderRequest.data); - if (!body || (body.nobid && body.nobid === true)) { - return bids; - } - if (!body.bids || !Array.isArray(body.bids) || body.bids.length === 0) { - return bids; - } - body.bids.forEach(bid => { - const responseBid = { - requestId: bid.requestId, - cpm: bid.cpm, - width: bid.width, - height: bid.height, - creativeId: bid.creativeId, - dealId: bid.dealId == null ? bid.dealId : '', - currency: bid.currency, - netRevenue: bid.netRevenue || false, - mediaType: bid.mediaType, - meta: { - mediaType: bid.mediaType - }, - ttl: bid.ttl || 300 - }; - if (bid.mediaType === BANNER) { - responseBid.ad = bid.ad; - } else if (bid.mediaType === VIDEO) { - const {context, adUnitCode} = find(requestData.bids, (item) => item.bidId === bid.requestId); - if (context === INSTREAM) { - responseBid.vastUrl = bid.vastUrl; - responseBid.videoCacheKey = bid.videoCacheKey; - } else if (context === OUTSTREAM) { - responseBid.vastXml = bid.ad; - responseBid.vastUrl = bid.vastUrl; - if (bid.rendererUrl) { - responseBid.renderer = createRenderer({ ...bid, adUnitCode }); - } - } - } - bids.push(responseBid); - }); - return bids; -} - -function createRenderer(bid, rendererOptions = {}) { - const renderer = Renderer.install({ - id: bid.requestId, - url: bid.rendererUrl, - config: rendererOptions, - adUnitCode: bid.adUnitCode, - loaded: false - }); - try { - renderer.setRender(({renderer, width, height, vastXml, adUnitCode}) => { - renderer.push(() => { - window.onetag.Player.init({ - ...bid, - width, - height, - vastXml, - nodeId: adUnitCode, - config: renderer.getConfig() - }); - }); - }); - } catch (e) { - - } - return renderer; -} - -function getFrameNesting() { - let topmostFrame = window; - let parent = window.parent; - let currentFrameNesting = 0; - try { - while (topmostFrame !== topmostFrame.parent) { - parent = topmostFrame.parent; - // eslint-disable-next-line no-unused-expressions - parent.location.href; - topmostFrame = topmostFrame.parent; - } - } catch (e) { - currentFrameNesting = parent === topmostFrame.top ? 1 : 2; - } - return { - topmostFrame, - currentFrameNesting - } -} - -function getDocumentVisibility(window) { - try { - if (typeof window.document.hidden !== 'undefined') { - return window.document.hidden; - } else if (typeof window.document['msHidden'] !== 'undefined') { - return window.document['msHidden']; - } else if (typeof window.document['webkitHidden'] !== 'undefined') { - return window.document['webkitHidden']; - } else { - return null; - } - } catch (e) { - return null; - } -} - -/** - * Returns information about the page needed by the server in an object to be converted in JSON - * @returns {{location: *, referrer: (*|string), masked: *, wWidth: (*|Number), wHeight: (*|Number), sWidth, sHeight, date: string, timeOffset: number}} - */ -function getPageInfo() { - const { topmostFrame, currentFrameNesting } = getFrameNesting(); - return { - location: topmostFrame.location.href, - referrer: - topmostFrame.document.referrer !== '' - ? topmostFrame.document.referrer - : null, - masked: currentFrameNesting, - wWidth: topmostFrame.innerWidth, - wHeight: topmostFrame.innerHeight, - oWidth: topmostFrame.outerWidth, - oHeight: topmostFrame.outerHeight, - sWidth: topmostFrame.screen.width, - sHeight: topmostFrame.screen.height, - aWidth: topmostFrame.screen.availWidth, - aHeight: topmostFrame.screen.availHeight, - sLeft: 'screenLeft' in topmostFrame ? topmostFrame.screenLeft : topmostFrame.screenX, - sTop: 'screenTop' in topmostFrame ? topmostFrame.screenTop : topmostFrame.screenY, - xOffset: topmostFrame.pageXOffset, - yOffset: topmostFrame.pageYOffset, - docHidden: getDocumentVisibility(topmostFrame), - docHeight: topmostFrame.document.body ? topmostFrame.document.body.scrollHeight : null, - hLength: history.length, - timing: getTiming(), - version: { - prebid: '$prebid.version$', - adapter: '1.1.0' - } - }; -} - -function requestsToBids(bidRequests) { - const videoBidRequests = bidRequests.filter(bidRequest => hasTypeVideo(bidRequest)).map(bidRequest => { - const videoObj = {}; - setGeneralInfo.call(videoObj, bidRequest); - // Pass parameters - // Context: instream - outstream - adpod - videoObj['context'] = bidRequest.mediaTypes.video.context; - // MIME Video Types - videoObj['mimes'] = bidRequest.mediaTypes.video.mimes; - // Sizes - videoObj['playerSize'] = parseVideoSize(bidRequest); - // Other params - videoObj['protocols'] = bidRequest.mediaTypes.video.protocols; - videoObj['maxDuration'] = bidRequest.mediaTypes.video.maxduration; - videoObj['api'] = bidRequest.mediaTypes.video.api; - videoObj['type'] = VIDEO; - return videoObj; - }); - const bannerBidRequests = bidRequests.filter(bidRequest => isValid(BANNER, bidRequest)).map(bidRequest => { - const bannerObj = {}; - setGeneralInfo.call(bannerObj, bidRequest); - bannerObj['sizes'] = parseSizes(bidRequest); - bannerObj['type'] = BANNER; - return bannerObj; - }); - return videoBidRequests.concat(bannerBidRequests); -} - -function setGeneralInfo(bidRequest) { - const params = bidRequest.params; - this['adUnitCode'] = bidRequest.adUnitCode; - this['bidId'] = bidRequest.bidId; - this['bidderRequestId'] = bidRequest.bidderRequestId; - this['auctionId'] = bidRequest.auctionId; - this['transactionId'] = bidRequest.transactionId; - this['pubId'] = params.pubId; - this['ext'] = params.ext; - if (params.pubClick) { - this['click'] = params.pubClick; - } - if (params.dealId) { - this['dealId'] = params.dealId; - } - const coords = getSpaceCoords(bidRequest.adUnitCode); - if (coords) { - this['coords'] = coords; - } -} - -function getSpaceCoords(id) { - const space = document.getElementById(id); - try { - const { top, left, width, height } = space.getBoundingClientRect(); - let window = space.ownerDocument.defaultView; - const coords = { top: top + window.pageYOffset, left: left + window.pageXOffset, width, height }; - let frame = window.frameElement; - while (frame != null) { - const { top, left } = frame.getBoundingClientRect(); - coords.top += top + window.pageYOffset; - coords.left += left + window.pageXOffset; - window = window.parent; - frame = window.frameElement; - } - return coords; - } catch (e) { - return null; - } -} - -function getTiming() { - try { - if (window.performance != null && window.performance.timing != null) { - const timing = {}; - const perf = window.performance.timing; - timing.pageLoadTime = perf.loadEventEnd - perf.navigationStart; - timing.connectTime = perf.responseEnd - perf.requestStart; - timing.renderTime = perf.domComplete - perf.domLoading; - return timing; - } - } catch (e) { - return null; - } - return null; -} - -function parseVideoSize(bid) { - const playerSize = bid.mediaTypes.video.playerSize; - if (typeof playerSize !== 'undefined' && Array.isArray(playerSize) && playerSize.length > 0) { - return getSizes(playerSize) - } - return []; -} - -function parseSizes(bid) { - let ret = []; - if (typeof bid.mediaTypes !== 'undefined' && typeof bid.mediaTypes.banner !== 'undefined' && typeof bid.mediaTypes.banner.sizes !== 'undefined' && Array.isArray(bid.mediaTypes.banner.sizes) && bid.mediaTypes.banner.sizes.length > 0) { - return getSizes(bid.mediaTypes.banner.sizes) - } - const isVideoBidRequest = hasTypeVideo(bid); - if (!isVideoBidRequest && bid.sizes && Array.isArray(bid.sizes)) { - return getSizes(bid.sizes); - } - return ret; -} - -function getSizes(sizes) { - const ret = []; - for (let i = 0; i < sizes.length; i++) { - const size = sizes[i]; - ret.push({width: size[0], height: size[1]}) - } - return ret; -} - -function getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent) { - let syncs = []; - let params = ''; - if (gdprConsent && typeof gdprConsent.consentString === 'string') { - params += '&gdpr_consent=' + gdprConsent.consentString; - if (typeof gdprConsent.gdprApplies === 'boolean') { - params += '&gdpr=' + (gdprConsent.gdprApplies ? 1 : 0); - } - } - if (uspConsent && typeof uspConsent === 'string') { - params += '&us_privacy=' + uspConsent; - } - if (syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: USER_SYNC_ENDPOINT + '?cb=' + new Date().getTime() + params - }); - } - if (syncOptions.pixelEnabled) { - syncs.push({ - type: 'image', - url: USER_SYNC_ENDPOINT + '?tag=img' + params - }); - } - return syncs; -} - -export const spec = { - code: BIDDER_CODE, - gvlid: GVLID, - supportedMediaTypes: [BANNER, VIDEO], - isBidRequestValid: isBidRequestValid, - buildRequests: buildRequests, - interpretResponse: interpretResponse, - getUserSyncs: getUserSyncs - -}; - -registerBidder(spec); diff --git a/modules/onetagBidAdapter.md b/modules/onetagBidAdapter.md deleted file mode 100644 index 7814403afbe..00000000000 --- a/modules/onetagBidAdapter.md +++ /dev/null @@ -1,60 +0,0 @@ -# Overview - -``` -Module Name: OneTag Bid Adapter -Module Type: Bidder Adapter -Maintainer: devops@onetag.com -``` - -# Description - -OneTag Bid Adapter supports banner and video at present. - -# Test Parameters -``` - var adUnits = [ - { - code: "banner-space", - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [{ - bidder: "onetag", - params: { - pubId: "your_publisher_id" // required, testing pubId: "386276e072" - } - }] - }, { - code: 'video-instream-space', - mediaTypes: { - video: { - context: "instream", - mimes: ["video/mp4", "video/webm", "application/javascript", "video/ogg"], - playerSize: [640,480] - } - }, - bids: [{ - bidder: "onetag", - params: { - pubId: "your_publisher_id" // required, testing pubId: "386276e072" - } - }] - }, { - code: 'video-outstream-space', - mediaTypes: { - video: { - context: "outstream", - playerSize: [640,480] - } - }, - bids: [{ - bidder: "onetag", - params: { - pubId: "your_publisher_id" // required, testing pubId: "386276e072" - } - }] - }]; - -``` diff --git a/modules/onomagicBidAdapter.js b/modules/onomagicBidAdapter.js deleted file mode 100644 index 55fca29fbf3..00000000000 --- a/modules/onomagicBidAdapter.js +++ /dev/null @@ -1,246 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; - -const BIDDER_CODE = 'onomagic'; -const URL = 'https://bidder.onomagic.com/hb'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - isBidRequestValid, - buildRequests, - interpretResponse, - getUserSyncs -}; - -function buildRequests(bidReqs, bidderRequest) { - try { - let referrer = ''; - if (bidderRequest && bidderRequest.refererInfo) { - referrer = bidderRequest.refererInfo.referer; - } - const onomagicImps = []; - const publisherId = utils.getBidIdParameter('publisherId', bidReqs[0].params); - utils._each(bidReqs, function (bid) { - let bidSizes = (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) || bid.sizes; - bidSizes = ((utils.isArray(bidSizes) && utils.isArray(bidSizes[0])) ? bidSizes : [bidSizes]); - bidSizes = bidSizes.filter(size => utils.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, utils.getWindowTop(), minSize) - : 'na'; - const viewabilityAmountRounded = isNaN(viewabilityAmount) ? viewabilityAmount : Math.round(viewabilityAmount); - - const imp = { - id: bid.bidId, - banner: { - format: processedSizes, - ext: { - viewability: viewabilityAmountRounded - } - }, - tagid: String(bid.adUnitCode) - }; - const bidFloor = utils.getBidIdParameter('bidFloor', bid.params); - if (bidFloor) { - imp.bidfloor = bidFloor; - } - onomagicImps.push(imp); - }); - const onomagicBidReq = { - id: utils.getUniqueIdentifierStr(), - imp: onomagicImps, - site: { - domain: utils.parseUrl(referrer).host, - page: referrer, - publisher: { - id: publisherId - } - }, - device: { - devicetype: _getDeviceType(), - w: screen.width, - h: screen.height - }, - tmax: config.getConfig('bidderTimeout') - }; - - return { - method: 'POST', - url: URL, - data: JSON.stringify(onomagicBidReq), - options: {contentType: 'text/plain', withCredentials: false} - }; - } catch (e) { - utils.logError(e, {bidReqs, bidderRequest}); - } -} - -function isBidRequestValid(bid) { - if (bid.bidder !== BIDDER_CODE || typeof bid.params === 'undefined') { - return false; - } - - if (typeof bid.params.publisherId === 'undefined') { - return false; - } - - return true; -} - -function interpretResponse(serverResponse) { - if (!serverResponse.body || typeof serverResponse.body != 'object') { - utils.logWarn('Onomagic server returned empty/non-json response: ' + JSON.stringify(serverResponse.body)); - return []; - } - const { body: {id, seatbid} } = serverResponse; - try { - const onomagicBidResponses = []; - if (id && - seatbid && - seatbid.length > 0 && - seatbid[0].bid && - seatbid[0].bid.length > 0) { - seatbid[0].bid.map(onomagicBid => { - onomagicBidResponses.push({ - requestId: onomagicBid.impid, - cpm: parseFloat(onomagicBid.price), - width: parseInt(onomagicBid.w), - height: parseInt(onomagicBid.h), - creativeId: onomagicBid.crid || onomagicBid.id, - currency: 'USD', - netRevenue: true, - mediaType: BANNER, - ad: _getAdMarkup(onomagicBid), - ttl: 60 - }); - }); - } - return onomagicBidResponses; - } catch (e) { - utils.logError(e, {id, seatbid}); - } -} - -// Don't do user sync for now -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 += utils.createTrackPixelHtml(bid.nurl); - } - return adm; -} - -function _isViewabilityMeasurable(element) { - return !_isIframe() && element !== null; -} - -function _getViewability(element, topWin, { w, h } = {}) { - return utils.getWindowTop().document.visibilityState === 'visible' - ? _getPercentInView(element, topWin, { w, h }) - : 0; -} - -function _isIframe() { - try { - return utils.getWindowSelf() !== utils.getWindowTop(); - } catch (e) { - return true; - } -} - -function _getMinSize(sizes) { - return sizes.reduce((min, size) => size.h * size.w < min.h * min.w ? size : min); -} - -function _getBoundingBox(element, { w, h } = {}) { - let { width, height, left, top, right, bottom } = element.getBoundingClientRect(); - - if ((width === 0 || height === 0) && w && h) { - width = w; - height = h; - right = left + w; - bottom = top + h; - } - - return { width, height, left, top, right, bottom }; -} - -function _getIntersectionOfRects(rects) { - const bbox = { - left: rects[0].left, - right: rects[0].right, - top: rects[0].top, - bottom: rects[0].bottom - }; - - for (let i = 1; i < rects.length; ++i) { - bbox.left = Math.max(bbox.left, rects[i].left); - bbox.right = Math.min(bbox.right, rects[i].right); - - if (bbox.left >= bbox.right) { - return null; - } - - bbox.top = Math.max(bbox.top, rects[i].top); - bbox.bottom = Math.min(bbox.bottom, rects[i].bottom); - - if (bbox.top >= bbox.bottom) { - return null; - } - } - - bbox.width = bbox.right - bbox.left; - bbox.height = bbox.bottom - bbox.top; - - return bbox; -} - -function _getPercentInView(element, topWin, { w, h } = {}) { - const elementBoundingBox = _getBoundingBox(element, { w, h }); - - // Obtain the intersection of the element and the viewport - const elementInViewBoundingBox = _getIntersectionOfRects([ { - left: 0, - top: 0, - right: topWin.innerWidth, - bottom: topWin.innerHeight - }, elementBoundingBox ]); - - let elementInViewArea, elementTotalArea; - - if (elementInViewBoundingBox !== null) { - // Some or all of the element is in view - elementInViewArea = elementInViewBoundingBox.width * elementInViewBoundingBox.height; - elementTotalArea = elementBoundingBox.width * elementBoundingBox.height; - - return ((elementInViewArea / elementTotalArea) * 100); - } - - // No overlap between element and the viewport; therefore, the element - // lies completely out of view - return 0; -} - -registerBidder(spec); diff --git a/modules/onomagicBidAdapter.md b/modules/onomagicBidAdapter.md deleted file mode 100644 index 7222a506b2c..00000000000 --- a/modules/onomagicBidAdapter.md +++ /dev/null @@ -1,46 +0,0 @@ -# Overview - -``` -Module Name: Onomagic Bid Adapter -Module Type: Bidder Adapter -Maintainer: vyatsun@gmail.com -``` - -# Description - -Onomagic's adapter integration to the Prebid library. - -# Test Parameters - -``` -var adUnits = [ - { - code: 'test-leaderboard', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - }, - bids: [{ - bidder: 'onomagic', - params: { - publisherId: 20167, - bidFloor: 0.01 - } - }] - }, { - code: 'test-banner', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [{ - bidder: 'onomagic', - params: { - publisherId: 20167 - } - }] - } -] -``` diff --git a/modules/ooloAnalyticsAdapter.js b/modules/ooloAnalyticsAdapter.js deleted file mode 100644 index 7195d6ac177..00000000000 --- a/modules/ooloAnalyticsAdapter.js +++ /dev/null @@ -1,547 +0,0 @@ -import adapter from '../src/AnalyticsAdapter.js' -import adapterManager from '../src/adapterManager.js' -import CONSTANTS from '../src/constants.json' -import * as utils from '../src/utils.js' -import { ajax } from '../src/ajax.js' -import { config } from '../src/config.js' - -const baseUrl = 'https://pbdata.oolo.io/' -const ENDPOINTS = { - CONFIG: 'https://config-pbdata.oolo.io', - PAGE_DATA: baseUrl + 'page', - AUCTION: baseUrl + 'auctionData', - BID_WON: baseUrl + 'bidWonData', - AD_RENDER_FAILED: baseUrl + 'adRenderFailedData', - RAW: baseUrl + 'raw', - HBCONFIG: baseUrl + 'hbconfig', -} - -const pbModuleVersion = '1.0.0' -const prebidVersion = '$prebid.version$' -const analyticsType = 'endpoint' -const ADAPTER_CODE = 'oolo' -const AUCTION_END_SEND_TIMEOUT = 1500 -export const PAGEVIEW_ID = +generatePageViewId() - -const { - AUCTION_INIT, - AUCTION_END, - BID_REQUESTED, - BID_RESPONSE, - NO_BID, - BID_WON, - BID_TIMEOUT, - AD_RENDER_FAILED -} = CONSTANTS.EVENTS - -const SERVER_EVENTS = { - AUCTION: 'auction', - WON: 'bidWon', - AD_RENDER_FAILED: 'adRenderFailed' -} - -const SERVER_BID_STATUS = { - NO_BID: 'noBid', - BID_REQUESTED: 'bidRequested', - BID_RECEIVED: 'bidReceived', - BID_TIMEDOUT: 'bidTimedOut', - BID_WON: 'bidWon' -} - -let auctions = {} -let initOptions = {} -let eventsQueue = [] - -const onAuctionInit = (args) => { - const { auctionId, adUnits, timestamp } = args - - let auction = auctions[auctionId] = { - ...args, - adUnits: {}, - auctionStart: timestamp, - _sentToServer: false - } - - handleCustomFields(auction, AUCTION_INIT, args) - - utils._each(adUnits, adUnit => { - auction.adUnits[adUnit.code] = { - ...adUnit, - auctionId, - adunid: adUnit.code, - bids: {}, - } - }) -} - -const onBidRequested = (args) => { - const { auctionId, bids, start, timeout } = args - const _start = start || Date.now() - const auction = auctions[auctionId] - const auctionAdUnits = auction.adUnits - - bids.forEach(bid => { - const { adUnitCode } = bid - const bidId = parseBidId(bid) - - auctionAdUnits[adUnitCode].bids[bidId] = { - ...bid, - timeout, - start: _start, - rs: _start - auction.auctionStart, - bidStatus: SERVER_BID_STATUS.BID_REQUESTED, - } - }) -} - -const onBidResponse = (args) => { - const { auctionId, adUnitCode } = args - const auction = auctions[auctionId] - const bidId = parseBidId(args) - let bid = auction.adUnits[adUnitCode].bids[bidId] - - Object.assign(bid, args, { - bidStatus: SERVER_BID_STATUS.BID_RECEIVED, - end: args.responseTimestamp, - re: args.responseTimestamp - auction.auctionStart - }) -} - -const onNoBid = (args) => { - const { auctionId, adUnitCode } = args - const bidId = parseBidId(args) - const end = Date.now() - const auction = auctions[auctionId] - let bid = auction.adUnits[adUnitCode].bids[bidId] - - Object.assign(bid, args, { - bidStatus: SERVER_BID_STATUS.NO_BID, - end, - re: end - auction.auctionStart - }) -} - -const onBidWon = (args) => { - const { auctionId, adUnitCode } = args - const bidId = parseBidId(args) - const bid = auctions[auctionId].adUnits[adUnitCode].bids[bidId] - - Object.assign(bid, args, { - bidStatus: SERVER_BID_STATUS.BID_WON, - isW: true, - isH: true - }) - - if (auctions[auctionId]._sentToServer) { - const payload = { - auctionId, - adunid: adUnitCode, - bid: mapBid(bid, BID_WON) - } - - sendEvent(SERVER_EVENTS.WON, payload) - } -} - -const onBidTimeout = (args) => { - utils._each(args, bid => { - const { auctionId, adUnitCode } = bid - const bidId = parseBidId(bid) - let bidCache = auctions[auctionId].adUnits[adUnitCode].bids[bidId] - - Object.assign(bidCache, bid, { - bidStatus: SERVER_BID_STATUS.BID_TIMEDOUT, - }) - }) -} - -const onAuctionEnd = (args) => { - const { auctionId, adUnits, ...restAuctionEnd } = args - - Object.assign(auctions[auctionId], restAuctionEnd, { - auctionEnd: args.auctionEnd || Date.now() - }) - - // wait for bidWon before sending to server - setTimeout(() => { - auctions[auctionId]._sentToServer = true - const finalAuctionData = buildAuctionData(auctions[auctionId]) - - sendEvent(SERVER_EVENTS.AUCTION, finalAuctionData) - }, initOptions.serverConfig.BID_WON_TIMEOUT || AUCTION_END_SEND_TIMEOUT) -} - -const onAdRenderFailed = (args) => { - const data = utils.deepClone(args) - data.timestamp = Date.now() - - if (data.bid) { - data.bid = mapBid(data.bid, AD_RENDER_FAILED) - } - - sendEvent(SERVER_EVENTS.AD_RENDER_FAILED, data) -} - -var ooloAdapter = Object.assign( - adapter({ analyticsType }), { - track({ eventType, args }) { - // wait for server configuration before processing the events - if (typeof initOptions.serverConfig !== 'undefined' && eventsQueue.length === 0) { - handleEvent(eventType, args) - } else { - eventsQueue.push({ eventType, args }) - } - } - } -) - -function handleEvent(eventType, args) { - try { - const { sendRaw } = initOptions.serverConfig.events[eventType] - if (sendRaw) { - sendEvent(eventType, args, true) - } - } catch (e) { } - - switch (eventType) { - case AUCTION_INIT: - onAuctionInit(args) - break - case BID_REQUESTED: - onBidRequested(args) - break - case NO_BID: - onNoBid(args) - break - case BID_RESPONSE: - onBidResponse(args) - break - case BID_WON: - onBidWon(args) - break - case BID_TIMEOUT: - onBidTimeout(args) - break - case AUCTION_END: - onAuctionEnd(args) - break - case AD_RENDER_FAILED: - onAdRenderFailed(args) - break - } -} - -function sendEvent(eventType, args, isRaw) { - let data = utils.deepClone(args) - - Object.assign(data, buildCommonDataProperties(), { - eventType - }) - - if (isRaw) { - let rawEndpoint - try { - const { endpoint, omitRawFields } = initOptions.serverConfig.events[eventType] - rawEndpoint = endpoint - handleCustomRawFields(data, omitRawFields) - } catch (e) { } - ajaxCall(rawEndpoint || ENDPOINTS.RAW, () => { }, JSON.stringify(data)) - } else { - let endpoint - if (eventType === SERVER_EVENTS.AD_RENDER_FAILED) { - endpoint = ENDPOINTS.AD_RENDER_FAILED - } else if (eventType === SERVER_EVENTS.WON) { - endpoint = ENDPOINTS.BID_WON - } else { - endpoint = ENDPOINTS.AUCTION - } - - ajaxCall(endpoint, () => { }, JSON.stringify(data)) - } -} - -function checkEventsQueue() { - while (eventsQueue.length) { - const event = eventsQueue.shift() - handleEvent(event.eventType, event.args) - } -} - -function buildAuctionData(auction) { - const auctionData = utils.deepClone(auction) - const keysToRemove = ['adUnitCodes', 'auctionStatus', 'bidderRequests', 'bidsReceived', 'noBids', 'winningBids', 'timestamp', 'config'] - - keysToRemove.forEach(key => { - delete auctionData[key] - }) - - handleCustomFields(auctionData, AUCTION_END, auction) - - // turn bids object into array of objects - Object.keys(auctionData.adUnits).forEach(adUnit => { - const adUnitObj = auctionData.adUnits[adUnit] - adUnitObj.bids = Object.keys(adUnitObj.bids).map(key => mapBid(adUnitObj.bids[key])) - delete adUnitObj['adUnitCode'] - delete adUnitObj['code'] - delete adUnitObj['transactionId'] - }) - - // turn adUnits objects into array of adUnits - auctionData.adUnits = Object.keys(auctionData.adUnits).map(key => auctionData.adUnits[key]) - - return auctionData -} - -function buildCommonDataProperties() { - return { - pvid: PAGEVIEW_ID, - pid: initOptions.pid, - pbModuleVersion - } -} - -function buildLogMessage(message) { - return `oolo: ${message}` -} - -function parseBidId(bid) { - return bid.bidId || bid.requestId -} - -function mapBid({ - bidStatus, - start, - end, - mediaType, - creativeId, - originalCpm, - originalCurrency, - source, - netRevenue, - currency, - width, - height, - timeToRespond, - responseTimestamp, - ...rest -}, eventType) { - const bidObj = { - bst: bidStatus, - s: start, - e: responseTimestamp || end, - mt: mediaType, - crId: creativeId, - oCpm: originalCpm, - oCur: originalCurrency, - src: source, - nrv: netRevenue, - cur: currency, - w: width, - h: height, - ttr: timeToRespond, - ...rest, - } - - delete bidObj['bidRequestsCount'] - delete bidObj['bidderRequestId'] - delete bidObj['bidderRequestsCount'] - delete bidObj['bidderWinsCount'] - delete bidObj['schain'] - delete bidObj['refererInfo'] - delete bidObj['statusMessage'] - delete bidObj['status'] - delete bidObj['adUrl'] - delete bidObj['ad'] - delete bidObj['usesGenericKeys'] - delete bidObj['requestTimestamp'] - - try { - handleCustomFields(bidObj, eventType || BID_RESPONSE, rest) - } catch (e) { } - - return bidObj -} - -function handleCustomFields(obj, eventType, args) { - try { - const { pickFields, omitFields } = initOptions.serverConfig.events[eventType] - - if (pickFields && obj && args) { - Object.assign(obj, utils.pick(args, pickFields)) - } - - if (omitFields && obj && args) { - omitFields.forEach(field => { - utils.deepSetValue(obj, field, undefined) - }) - } - } catch (e) { } -} - -function handleCustomRawFields(obj, omitRawFields) { - try { - if (omitRawFields && obj) { - omitRawFields.forEach(field => { - utils.deepSetValue(obj, field, undefined) - }) - } - } catch (e) { } -} - -function getServerConfig() { - const defaultConfig = { events: {} } - - ajaxCall( - ENDPOINTS.CONFIG + '?pid=' + initOptions.pid, - { - success: function (data) { - try { - initOptions.serverConfig = JSON.parse(data) || defaultConfig - } catch (e) { - initOptions.serverConfig = defaultConfig - } - checkEventsQueue() - }, - error: function () { - initOptions.serverConfig = defaultConfig - checkEventsQueue() - } - }, - null - ) -} - -function sendPage() { - setTimeout(() => { - const payload = { - timestamp: Date.now(), - screenWidth: window.screen.width, - screenHeight: window.screen.height, - url: window.location.href, - protocol: window.location.protocol, - origin: utils.getOrigin(), - referrer: getTopWindowReferrer(), - pbVersion: prebidVersion, - } - - Object.assign(payload, buildCommonDataProperties(), getPagePerformance()) - ajaxCall(ENDPOINTS.PAGE_DATA, () => { }, JSON.stringify(payload)) - }, 0) -} - -function sendHbConfigData() { - const conf = {} - const pbjsConfig = config.getConfig() - - Object.keys(pbjsConfig).forEach(key => { - if (key[0] !== '_') { - conf[key] = pbjsConfig[key] - } - }) - - ajaxCall(ENDPOINTS.HBCONFIG, () => { }, JSON.stringify(conf)) -} - -function getPagePerformance() { - let timing - - try { - timing = window.top.performance.timing - } catch (e) { } - - if (!timing) { - return - } - - const { navigationStart, domContentLoadedEventEnd, loadEventEnd } = timing - const domContentLoadTime = domContentLoadedEventEnd - navigationStart - const pageLoadTime = loadEventEnd - navigationStart - - return { - domContentLoadTime, - pageLoadTime, - } -} - -function getTopWindowReferrer() { - try { - return window.top.document.referrer - } catch (e) { - return '' - } -} - -function generatePageViewId(min = 10000, max = 90000) { - var randomNumber = Math.floor((Math.random() * max) + min) - var currentdate = new Date() - var currentTime = { - getDate: currentdate.getDate(), - getMonth: currentdate.getMonth(), - getFullYear: currentdate.getFullYear(), - getHours: currentdate.getHours(), - getMinutes: currentdate.getMinutes(), - getSeconds: currentdate.getSeconds(), - getMilliseconds: currentdate.getMilliseconds() - } - return ((currentTime.getDate <= 9) ? '0' + (currentTime.getDate) : (currentTime.getDate)) + '' + - (currentTime.getMonth + 1 <= 9 ? '0' + (currentTime.getMonth + 1) : (currentTime.getMonth + 1)) + '' + - currentTime.getFullYear % 100 + '' + - (currentTime.getHours <= 9 ? '0' + currentTime.getHours : currentTime.getHours) + '' + - (currentTime.getMinutes <= 9 ? '0' + currentTime.getMinutes : currentTime.getMinutes) + '' + - (currentTime.getSeconds <= 9 ? '0' + currentTime.getSeconds : currentTime.getSeconds) + '' + - (currentTime.getMilliseconds % 100 <= 9 ? '0' + (currentTime.getMilliseconds % 100) : (currentTime.getMilliseconds % 100)) + '' + - (randomNumber) -} - -function ajaxCall(endpoint, callback, data, options = {}) { - if (data) { - options.contentType = 'application/json' - } - - return ajax(endpoint, callback, data, options) -} - -ooloAdapter.originEnableAnalytics = ooloAdapter.enableAnalytics -ooloAdapter.enableAnalytics = function (config) { - ooloAdapter.originEnableAnalytics(config) - initOptions = config ? config.options : {} - - if (!initOptions.pid) { - utils.logError(buildLogMessage('enableAnalytics missing config object with "pid"')) - return - } - - getServerConfig() - sendHbConfigData() - - if (document.readyState === 'complete') { - sendPage() - } else { - window.addEventListener('load', sendPage) - } - - utils.logInfo(buildLogMessage('enabled analytics adapter'), config) - ooloAdapter.enableAnalytics = function () { - utils.logInfo(buildLogMessage('Analytics adapter already enabled..')) - } -} - -ooloAdapter.originDisableAnalytics = ooloAdapter.disableAnalytics -ooloAdapter.disableAnalytics = function () { - auctions = {} - initOptions = {} - ooloAdapter.originDisableAnalytics() -} - -adapterManager.registerAnalyticsAdapter({ - adapter: ooloAdapter, - code: ADAPTER_CODE -}) - -// export for testing -export { - buildAuctionData, - generatePageViewId -} - -export default ooloAdapter diff --git a/modules/ooloAnalyticsAdapter.md b/modules/ooloAnalyticsAdapter.md deleted file mode 100644 index 1ffb9cbe050..00000000000 --- a/modules/ooloAnalyticsAdapter.md +++ /dev/null @@ -1,24 +0,0 @@ -# Overview - -Module Name: oolo Analytics Adapter -Module Type: Analytics Adapter -Maintainer: admin@oolo.io - -# Description - -Analytics adapter for oolo. - -oolo is an anomaly detection based monitoring solution for web publishers, built by adops for adops. Its purpose is to eliminate most of the daily manual work that teams are required to do, while increasing the overall performance, due to full & faster detection of problems and opportunities. - -Contact admin@oolo.io for information. - -# Usage - -```javascript -pbjs.enableAnalytics({ - provider: 'oolo', - options: { - pid: 12345 // id provided by oolo - } -}) -``` diff --git a/modules/open8BidAdapter.js b/modules/open8BidAdapter.js deleted file mode 100644 index 744cce2b5f9..00000000000 --- a/modules/open8BidAdapter.js +++ /dev/null @@ -1,185 +0,0 @@ -import { Renderer } from '../src/Renderer.js'; -import {ajax} from '../src/ajax.js'; -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { VIDEO, BANNER } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'open8'; -const URL = 'https://as.vt.open8.com/v1/control/prebid'; -const AD_TYPE = { - VIDEO: 1, - BANNER: 2 -}; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [VIDEO, BANNER], - - isBidRequestValid: function(bid) { - return !!(bid.params.slotKey); - }, - - buildRequests: function(validBidRequests, bidderRequest) { - var requests = []; - for (var i = 0; i < validBidRequests.length; i++) { - var bid = validBidRequests[i]; - var queryString = ''; - var slotKey = utils.getBidIdParameter('slotKey', bid.params); - queryString = utils.tryAppendQueryString(queryString, 'slot_key', slotKey); - queryString = utils.tryAppendQueryString(queryString, 'imp_id', generateImpId()); - queryString += ('bid_id=' + bid.bidId); - - requests.push({ - method: 'GET', - url: URL, - data: queryString - }); - } - return requests; - }, - - interpretResponse: function(serverResponse, request) { - var bidderResponse = serverResponse.body; - - if (!bidderResponse.isAdReturn) { - return []; - } - - var ad = bidderResponse.ad; - - const bid = { - slotKey: bidderResponse.slotKey, - userId: bidderResponse.userId, - impId: bidderResponse.impId, - media: bidderResponse.media, - ds: ad.ds, - spd: ad.spd, - fa: ad.fa, - pr: ad.pr, - mr: ad.mr, - nurl: ad.nurl, - requestId: ad.bidId, - cpm: ad.price, - creativeId: ad.creativeId, - dealId: ad.dealId, - currency: ad.currency || 'JPY', - netRevenue: true, - ttl: 360, // 6 minutes - } - - if (ad.adType === AD_TYPE.VIDEO) { - const videoAd = bidderResponse.ad.video; - Object.assign(bid, { - vastXml: videoAd.vastXml, - width: videoAd.w, - height: videoAd.h, - renderer: newRenderer(bidderResponse), - adResponse: bidderResponse, - mediaType: VIDEO - }); - } else if (ad.adType === AD_TYPE.BANNER) { - const bannerAd = bidderResponse.ad.banner; - Object.assign(bid, { - width: bannerAd.w, - height: bannerAd.h, - ad: bannerAd.adm, - mediaType: BANNER - }); - if (bannerAd.imps) { - try { - bannerAd.imps.forEach(impTrackUrl => { - const tracker = utils.createTrackPixelHtml(impTrackUrl); - bid.ad += tracker; - }); - } catch (error) { - utils.logError('Error appending imp tracking pixel', error); - } - } - } - return [bid]; - }, - - getUserSyncs: function(syncOptions, serverResponses) { - const syncs = []; - if (syncOptions.iframeEnabled && serverResponses.length) { - const syncIFs = serverResponses[0].body.syncIFs; - if (syncIFs) { - syncIFs.forEach(sync => { - syncs.push({ - type: 'iframe', - url: sync - }); - }); - } - } - if (syncOptions.pixelEnabled && serverResponses.length) { - const syncPixs = serverResponses[0].body.syncPixels; - if (syncPixs) { - syncPixs.forEach(sync => { - syncs.push({ - type: 'image', - url: sync - }); - }); - } - } - return syncs; - }, - onBidWon: function(bid) { - if (!bid.nurl) { return; } - const winUrl = bid.nurl.replace( - /\$\{AUCTION_PRICE\}/, - bid.cpm - ); - ajax(winUrl, null); - } -} - -function generateImpId() { - var l = 16; - var c = 'abcdefghijklmnopqrstuvwsyz0123456789'; - var cl = c.length; - var r = ''; - for (var i = 0; i < l; i++) { - r += c[Math.floor(Math.random() * cl)]; - } - return r; -} - -function newRenderer(bidderResponse) { - const renderer = Renderer.install({ - id: bidderResponse.ad.bidId, - url: bidderResponse.ad.video.purl, - loaded: false, - }); - - try { - renderer.setRender(outstreamRender); - } catch (err) { - utils.logWarn('Prebid Error calling setRender on newRenderer', err); - } - - return renderer; -} - -function outstreamRender(bid) { - bid.renderer.push(() => { - window.op8.renderPrebid({ - vastXml: bid.vastXml, - adUnitCode: bid.adUnitCode, - slotKey: bid.slotKey, - impId: bid.impId, - userId: bid.userId, - media: bid.media, - ds: bid.ds, - spd: bid.spd, - fa: bid.fa, - pr: bid.pr, - mr: bid.mr, - adResponse: bid.adResponse, - mediaType: bid.mediaType - }); - }); -} - -registerBidder(spec); diff --git a/modules/open8BidAdapter.md b/modules/open8BidAdapter.md deleted file mode 100644 index 2c69e174ee6..00000000000 --- a/modules/open8BidAdapter.md +++ /dev/null @@ -1,50 +0,0 @@ -# Overview - -**Module Name**: Open8 Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: tdd-adtech@open8.com - - # Description - -Innity Bidder Adapter for Prebid.js. - -# Test Parameters -``` -var adUnits = [ - // Banner adUnit - { - code: 'banner-div', - mediaTypes: { - banner: { - sizes: [ - [300, 250] - ], - } - }, - bids: [{ - bidder: 'open8', - params: { - slotKey: '504c2e89' - } - }] - }, - // Video outstream adUnit - { - code: 'video-outstream', - sizes: [ - [640, 360] - ], - mediaTypes: { - video: { - context: 'outstream' - } - }, - bids: [{ - bidder: 'open8', - params: { - slotKey: '2ae5a533' - } - }] - }]; - -``` \ No newline at end of file diff --git a/modules/openxAnalyticsAdapter.js b/modules/openxAnalyticsAdapter.js deleted file mode 100644 index 07966e9e401..00000000000 --- a/modules/openxAnalyticsAdapter.js +++ /dev/null @@ -1,733 +0,0 @@ -import adapter from '../src/AnalyticsAdapter.js'; -import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager.js'; -import { ajax } from '../src/ajax.js'; -import find from 'core-js-pure/features/array/find.js'; -import includes from 'core-js-pure/features/array/includes.js'; -const utils = require('../src/utils.js'); - -export const AUCTION_STATES = { - INIT: 'initialized', // auction has initialized - ENDED: 'ended', // all auction requests have been accounted for - COMPLETED: 'completed' // all slots have rendered -}; - -const ADAPTER_VERSION = '0.1'; -const SCHEMA_VERSION = '0.1'; - -const AUCTION_END_WAIT_TIME = 1000; -const URL_PARAM = ''; -const ANALYTICS_TYPE = 'endpoint'; -const ENDPOINT = 'https://prebid.openx.net/ox/analytics/'; - -// Event Types -const { - EVENTS: { AUCTION_INIT, BID_REQUESTED, BID_RESPONSE, BID_TIMEOUT, AUCTION_END, BID_WON } -} = CONSTANTS; -const SLOT_LOADED = 'slotOnload'; - -const UTM_TAGS = [ - 'utm_campaign', - 'utm_source', - 'utm_medium', - 'utm_term', - 'utm_content' -]; -const UTM_TO_CAMPAIGN_PROPERTIES = { - 'utm_campaign': 'name', - 'utm_source': 'source', - 'utm_medium': 'medium', - 'utm_term': 'term', - 'utm_content': 'content' -}; - -/** - * @typedef {Object} OxAnalyticsConfig - * @property {string} orgId - * @property {string} publisherPlatformId - * @property {number} publisherAccountId - * @property {number} sampling - * @property {boolean} enableV2 - * @property {boolean} testPipeline - * @property {Object} campaign - * @property {number} payloadWaitTime - * @property {number} payloadWaitTimePadding - * @property {Array} adUnits - */ - -/** - * @type {OxAnalyticsConfig} - */ -const DEFAULT_ANALYTICS_CONFIG = { - orgId: void (0), - publisherPlatformId: void (0), - publisherAccountId: void (0), - sampling: 0.05, // default sampling rate of 5% - testCode: 'default', - campaign: {}, - adUnits: [], - payloadWaitTime: AUCTION_END_WAIT_TIME, - payloadWaitTimePadding: 2000 -}; - -// Initialization -/** - * @type {OxAnalyticsConfig} - */ -let analyticsConfig; -let auctionMap = {}; -let auctionOrder = 1; // tracks the number of auctions ran on the page - -let googletag = window.googletag || {}; -googletag.cmd = googletag.cmd || []; - -let openxAdapter = Object.assign(adapter({ urlParam: URL_PARAM, analyticsType: ANALYTICS_TYPE })); - -openxAdapter.originEnableAnalytics = openxAdapter.enableAnalytics; - -openxAdapter.enableAnalytics = function(adapterConfig = {options: {}}) { - if (isValidConfig(adapterConfig)) { - analyticsConfig = {...DEFAULT_ANALYTICS_CONFIG, ...adapterConfig.options}; - - // campaign properties defined by config will override utm query parameters - analyticsConfig.campaign = {...buildCampaignFromUtmCodes(), ...analyticsConfig.campaign}; - - utils.logInfo('OpenX Analytics enabled with config', analyticsConfig); - - // override track method with v2 handlers - openxAdapter.track = prebidAnalyticsEventHandler; - - googletag.cmd.push(function () { - let pubads = googletag.pubads(); - - if (pubads.addEventListener) { - pubads.addEventListener(SLOT_LOADED, args => { - openxAdapter.track({eventType: SLOT_LOADED, args}); - utils.logInfo('OX: SlotOnLoad event triggered'); - }); - } - }); - - openxAdapter.originEnableAnalytics(adapterConfig); - } -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: openxAdapter, - code: 'openx' -}); - -export default openxAdapter; - -/** - * Test Helper Functions - */ - -// reset the cache for unit tests -openxAdapter.reset = function() { - auctionMap = {}; - auctionOrder = 1; -}; - -/** - * Private Functions - */ - -function isValidConfig({options: analyticsOptions}) { - let hasOrgId = analyticsOptions && analyticsOptions.orgId !== void (0); - - const fieldValidations = [ - // tuple of property, type, required - ['orgId', 'string', hasOrgId], - ['publisherPlatformId', 'string', !hasOrgId], - ['publisherAccountId', 'number', !hasOrgId], - ['sampling', 'number', false], - ['enableV2', 'boolean', false], - ['testPipeline', 'boolean', false], - ['adIdKey', 'string', false], - ['payloadWaitTime', 'number', false], - ['payloadWaitTimePadding', 'number', false], - ]; - - let failedValidation = find(fieldValidations, ([property, type, required]) => { - // if required, the property has to exist - // if property exists, type check value - return (required && !analyticsOptions.hasOwnProperty(property)) || - /* eslint-disable valid-typeof */ - (analyticsOptions.hasOwnProperty(property) && typeof analyticsOptions[property] !== type); - }); - if (failedValidation) { - let [property, type, required] = failedValidation; - - if (required) { - utils.logError(`OpenXAnalyticsAdapter: Expected '${property}' to exist and of type '${type}'`); - } else { - utils.logError(`OpenXAnalyticsAdapter: Expected '${property}' to be type '${type}'`); - } - } - - return !failedValidation; -} - -function buildCampaignFromUtmCodes() { - const location = utils.getWindowLocation(); - const queryParams = utils.parseQS(location && location.search); - let campaign = {}; - - UTM_TAGS.forEach(function(utmKey) { - let utmValue = queryParams[utmKey]; - if (utmValue) { - let key = UTM_TO_CAMPAIGN_PROPERTIES[utmKey]; - campaign[key] = decodeURIComponent(utmValue); - } - }); - return campaign; -} - -function detectMob() { - if ( - navigator.userAgent.match(/Android/i) || - navigator.userAgent.match(/webOS/i) || - navigator.userAgent.match(/iPhone/i) || - navigator.userAgent.match(/iPad/i) || - navigator.userAgent.match(/iPod/i) || - navigator.userAgent.match(/BlackBerry/i) || - navigator.userAgent.match(/Windows Phone/i) - ) { - return true; - } else { - return false; - } -} - -function detectOS() { - if (navigator.userAgent.indexOf('Android') != -1) return 'Android'; - if (navigator.userAgent.indexOf('like Mac') != -1) return 'iOS'; - if (navigator.userAgent.indexOf('Win') != -1) return 'Windows'; - if (navigator.userAgent.indexOf('Mac') != -1) return 'Macintosh'; - if (navigator.userAgent.indexOf('Linux') != -1) return 'Linux'; - if (navigator.appVersion.indexOf('X11') != -1) return 'Unix'; - return 'Others'; -} - -function detectBrowser() { - var isChrome = - /Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor); - var isCriOS = navigator.userAgent.match('CriOS'); - var isSafari = - /Safari/.test(navigator.userAgent) && - /Apple Computer/.test(navigator.vendor); - var isFirefox = /Firefox/.test(navigator.userAgent); - var isIE = - /Trident/.test(navigator.userAgent) || /MSIE/.test(navigator.userAgent); - var isEdge = /Edge/.test(navigator.userAgent); - if (isIE) return 'Internet Explorer'; - if (isEdge) return 'Microsoft Edge'; - if (isCriOS) return 'Chrome'; - if (isSafari) return 'Safari'; - if (isFirefox) return 'Firefox'; - if (isChrome) return 'Chrome'; - return 'Others'; -} - -function prebidAnalyticsEventHandler({eventType, args}) { - utils.logMessage(eventType, Object.assign({}, args)); - switch (eventType) { - case AUCTION_INIT: - onAuctionInit(args); - break; - case BID_REQUESTED: - onBidRequested(args); - break; - case BID_RESPONSE: - onBidResponse(args); - break; - case BID_TIMEOUT: - onBidTimeout(args); - break; - case AUCTION_END: - onAuctionEnd(args); - break; - case BID_WON: - onBidWon(args); - break; - case SLOT_LOADED: - onSlotLoadedV2(args); - break; - } -} - -/** - * @typedef {Object} PbAuction - * @property {string} auctionId - Auction ID of the request this bid responded to - * @property {number} timestamp //: 1586675964364 - * @property {number} auctionEnd - timestamp of when auction ended //: 1586675964364 - * @property {string} auctionStatus //: "inProgress" - * @property {Array} adUnits //: [{…}] - * @property {string} adUnitCodes //: ["video1"] - * @property {string} labels //: undefined - * @property {Array} bidderRequests //: (2) [{…}, {…}] - * @property {Array} noBids //: [] - * @property {Array} bidsReceived //: [] - * @property {Array} winningBids //: [] - * @property {number} timeout //: 3000 - * @property {Object} config //: {publisherPlatformId: "a3aece0c-9e80-4316-8deb-faf804779bd1", publisherAccountId: 537143056, sampling: 1, enableV2: true}/* - */ - -function onAuctionInit({auctionId, timestamp: startTime, timeout, adUnitCodes}) { - auctionMap[auctionId] = { - id: auctionId, - startTime, - endTime: void (0), - timeout, - auctionOrder, - userIds: [], - adUnitCodesCount: adUnitCodes.length, - adunitCodesRenderedCount: 0, - state: AUCTION_STATES.INIT, - auctionSendDelayTimer: void (0), - }; - - // setup adunit properties in map - auctionMap[auctionId].adUnitCodeToAdUnitMap = adUnitCodes.reduce((obj, adunitCode) => { - obj[adunitCode] = { - code: adunitCode, - adPosition: void (0), - bidRequestsMap: {} - }; - return obj; - }, {}); - - auctionOrder++; -} - -/** - * @typedef {Object} PbBidRequest - * @property {string} auctionId - Auction ID of the request this bid responded to - * @property {number} auctionStart //: 1586675964364 - * @property {Object} refererInfo - * @property {PbBidderRequest} bids - * @property {number} start - Start timestamp of the bidder request - * - */ - -/** - * @typedef {Object} PbBidderRequest - * @property {string} adUnitCode - Name of div or google adunit path - * @property {string} bidder - Bame of bidder - * @property {string} bidId - Identifies the bid request - * @property {Object} mediaTypes - * @property {Object} params - * @property {string} src - * @property {Object} userId - Map of userId module to module object - */ - -/** - * Tracks the bid request - * @param {PbBidRequest} bidRequest - */ -function onBidRequested(bidRequest) { - const {auctionId, bids: bidderRequests, start, timeout} = bidRequest; - const auction = auctionMap[auctionId]; - const adUnitCodeToAdUnitMap = auction.adUnitCodeToAdUnitMap; - - bidderRequests.forEach(bidderRequest => { - const { adUnitCode, bidder, bidId: requestId, mediaTypes, params, src, userId } = bidderRequest; - - auction.userIds.push(userId); - adUnitCodeToAdUnitMap[adUnitCode].bidRequestsMap[requestId] = { - bidder, - params, - mediaTypes, - source: src, - startTime: start, - timedOut: false, - timeLimit: timeout, - bids: {} - }; - }); -} - -/** - * - * @param {BidResponse} bidResponse - */ -function onBidResponse(bidResponse) { - let { - auctionId, - adUnitCode, - requestId, - cpm, - creativeId, - requestTimestamp, - responseTimestamp, - ts, - mediaType, - dealId, - ttl, - netRevenue, - currency, - originalCpm, - originalCurrency, - width, - height, - timeToRespond: latency, - adId, - meta - } = bidResponse; - - auctionMap[auctionId].adUnitCodeToAdUnitMap[adUnitCode].bidRequestsMap[requestId].bids[adId] = { - cpm, - creativeId, - requestTimestamp, - responseTimestamp, - ts, - adId, - meta, - mediaType, - dealId, - ttl, - netRevenue, - currency, - originalCpm, - originalCurrency, - width, - height, - latency, - winner: false, - rendered: false, - renderTime: 0, - }; -} - -function onBidTimeout(args) { - utils._each(args, ({auctionId, adUnitCode, bidId: requestId}) => { - let timedOutRequest = utils.deepAccess(auctionMap, - `${auctionId}.adUnitCodeToAdUnitMap.${adUnitCode}.bidRequestsMap.${requestId}`); - - if (timedOutRequest) { - timedOutRequest.timedOut = true; - } - }); -} -/** - * - * @param {PbAuction} endedAuction - */ -function onAuctionEnd(endedAuction) { - let auction = auctionMap[endedAuction.auctionId]; - - if (!auction) { - return; - } - - clearAuctionTimer(auction); - auction.endTime = endedAuction.auctionEnd; - auction.state = AUCTION_STATES.ENDED; - delayedSend(auction); -} - -/** - * - * @param {BidResponse} bidResponse - */ -function onBidWon(bidResponse) { - const { auctionId, adUnitCode, requestId, adId } = bidResponse; - let winningBid = utils.deepAccess(auctionMap, - `${auctionId}.adUnitCodeToAdUnitMap.${adUnitCode}.bidRequestsMap.${requestId}.bids.${adId}`); - - if (winningBid) { - winningBid.winner = true - } -} - -/** - * - * @param {GoogleTagSlot} slot - * @param {string} serviceName - */ -function onSlotLoadedV2({ slot }) { - const renderTime = Date.now(); - const elementId = slot.getSlotElementId(); - const bidId = slot.getTargeting('hb_adid')[0]; - - let [auction, adUnit, bid] = getPathToBidResponseByBidId(bidId); - - if (!auction) { - // attempt to get auction by adUnitCode - auction = getAuctionByGoogleTagSLot(slot); - - if (!auction) { - return; // slot is not participating in an active prebid auction - } - } - - clearAuctionTimer(auction); - - // track that an adunit code has completed within an auction - auction.adunitCodesRenderedCount++; - - // mark adunit as rendered - if (bid) { - let {x, y} = getPageOffset(); - bid.rendered = true; - bid.renderTime = renderTime; - adUnit.adPosition = isAtf(elementId, x, y) ? 'ATF' : 'BTF'; - } - - if (auction.adunitCodesRenderedCount === auction.adUnitCodesCount) { - auction.state = AUCTION_STATES.COMPLETED; - } - - // prepare to send regardless if auction is complete or not as a failsafe in case not all events are tracked - // add additional padding when not all slots are rendered - delayedSend(auction); -} - -function isAtf(elementId, scrollLeft = 0, scrollTop = 0) { - let elem = document.querySelector('#' + elementId); - let isAtf = false; - if (elem) { - let bounding = elem.getBoundingClientRect(); - if (bounding) { - let windowWidth = (window.innerWidth || document.documentElement.clientWidth); - let windowHeight = (window.innerHeight || document.documentElement.clientHeight); - - // intersection coordinates - let left = Math.max(0, bounding.left + scrollLeft); - let right = Math.min(windowWidth, bounding.right + scrollLeft); - let top = Math.max(0, bounding.top + scrollTop); - let bottom = Math.min(windowHeight, bounding.bottom + scrollTop); - - let intersectionWidth = right - left; - let intersectionHeight = bottom - top; - - let intersectionArea = (intersectionHeight > 0 && intersectionWidth > 0) ? (intersectionHeight * intersectionWidth) : 0; - let adSlotArea = (bounding.right - bounding.left) * (bounding.bottom - bounding.top); - - if (adSlotArea > 0) { - // Atleast 50% of intersection in window - isAtf = intersectionArea * 2 >= adSlotArea; - } - } - } else { - utils.logWarn('OX: DOM element not for id ' + elementId); - } - return isAtf; -} - -// backwards compatible pageOffset from https://developer.mozilla.org/en-US/docs/Web/API/Window/scrollX -function getPageOffset() { - var x = (window.pageXOffset !== undefined) - ? window.pageXOffset - : (document.documentElement || document.body.parentNode || document.body).scrollLeft; - - var y = (window.pageYOffset !== undefined) - ? window.pageYOffset - : (document.documentElement || document.body.parentNode || document.body).scrollTop; - return {x, y}; -} - -function delayedSend(auction) { - const delayTime = auction.adunitCodesRenderedCount === auction.adUnitCodesCount - ? analyticsConfig.payloadWaitTime - : analyticsConfig.payloadWaitTime + analyticsConfig.payloadWaitTimePadding; - - auction.auctionSendDelayTimer = setTimeout(() => { - let payload = JSON.stringify([buildAuctionPayload(auction)]); - ajax(ENDPOINT, deleteAuctionMap, payload, { contentType: 'application/json' }); - - function deleteAuctionMap() { - delete auctionMap[auction.id]; - } - }, delayTime); -} - -function clearAuctionTimer(auction) { - // reset the delay timer to send the auction data - if (auction.auctionSendDelayTimer) { - clearTimeout(auction.auctionSendDelayTimer); - auction.auctionSendDelayTimer = void (0); - } -} - -/** - * Returns the path to a bid (auction, adunit, bidRequest, and bid) based on a bidId - * @param {string} bidId - * @returns {Array<*>} - */ -function getPathToBidResponseByBidId(bidId) { - let auction; - let adUnit; - let bidResponse; - - if (!bidId) { - return []; - } - - utils._each(auctionMap, currentAuction => { - // skip completed auctions - if (currentAuction.state === AUCTION_STATES.COMPLETED) { - return; - } - - utils._each(currentAuction.adUnitCodeToAdUnitMap, (currentAdunit) => { - utils._each(currentAdunit.bidRequestsMap, currentBiddRequest => { - utils._each(currentBiddRequest.bids, (currentBidResponse, bidResponseId) => { - if (bidId === bidResponseId) { - auction = currentAuction; - adUnit = currentAdunit; - bidResponse = currentBidResponse; - } - }); - }); - }); - }); - return [auction, adUnit, bidResponse]; -} - -function getAuctionByGoogleTagSLot(slot) { - let slotAdunitCodes = [slot.getSlotElementId(), slot.getAdUnitPath()]; - let slotAuction; - - utils._each(auctionMap, auction => { - if (auction.state === AUCTION_STATES.COMPLETED) { - return; - } - - utils._each(auction.adUnitCodeToAdUnitMap, (bidderRequestIdMap, adUnitCode) => { - if (includes(slotAdunitCodes, adUnitCode)) { - slotAuction = auction; - } - }); - }); - - return slotAuction; -} - -function buildAuctionPayload(auction) { - let {startTime, endTime, state, timeout, auctionOrder, userIds, adUnitCodeToAdUnitMap} = auction; - let {orgId, publisherPlatformId, publisherAccountId, campaign} = analyticsConfig; - - return { - adapterVersion: ADAPTER_VERSION, - schemaVersion: SCHEMA_VERSION, - orgId, - publisherPlatformId, - publisherAccountId, - campaign, - state, - startTime, - endTime, - timeLimit: timeout, - auctionOrder, - deviceType: detectMob() ? 'Mobile' : 'Desktop', - deviceOSType: detectOS(), - browser: detectBrowser(), - testCode: analyticsConfig.testCode, - // return an array of module name that have user data - userIdProviders: buildUserIdProviders(userIds), - adUnits: buildAdUnitsPayload(adUnitCodeToAdUnitMap), - }; - - function buildAdUnitsPayload(adUnitCodeToAdUnitMap) { - return utils._map(adUnitCodeToAdUnitMap, (adUnit) => { - let {code, adPosition} = adUnit; - - return { - code, - adPosition, - bidRequests: buildBidRequestPayload(adUnit.bidRequestsMap) - }; - - function buildBidRequestPayload(bidRequestsMap) { - return utils._map(bidRequestsMap, (bidRequest) => { - let {bidder, source, bids, mediaTypes, timeLimit, timedOut} = bidRequest; - return { - bidder, - source, - hasBidderResponded: Object.keys(bids).length > 0, - availableAdSizes: getMediaTypeSizes(mediaTypes), - availableMediaTypes: getMediaTypes(mediaTypes), - timeLimit, - timedOut, - bidResponses: utils._map(bidRequest.bids, (bidderBidResponse) => { - let { - cpm, - creativeId, - ts, - meta, - mediaType, - dealId, - ttl, - netRevenue, - currency, - width, - height, - latency, - winner, - rendered, - renderTime - } = bidderBidResponse; - - return { - microCpm: cpm * 1000000, - netRevenue, - currency, - mediaType, - height, - width, - size: `${width}x${height}`, - dealId, - latency, - ttl, - winner, - creativeId, - ts, - rendered, - renderTime, - meta - } - }) - } - }); - } - }); - } - - function buildUserIdProviders(userIds) { - return utils._map(userIds, (userId) => { - return utils._map(userId, (id, module) => { - return hasUserData(module, id) ? module : false - }).filter(module => module); - }).reduce(utils.flatten, []).filter(utils.uniques).sort(); - } - - function hasUserData(module, idOrIdObject) { - let normalizedId; - - switch (module) { - case 'digitrustid': - normalizedId = utils.deepAccess(idOrIdObject, 'data.id'); - break; - case 'lipb': - normalizedId = idOrIdObject.lipbid; - break; - default: - normalizedId = idOrIdObject; - } - - return !utils.isEmpty(normalizedId); - } - - function getMediaTypeSizes(mediaTypes) { - return utils._map(mediaTypes, (mediaTypeConfig, mediaType) => { - return utils.parseSizesInput(mediaTypeConfig.sizes) - .map(size => `${mediaType}_${size}`); - }).reduce(utils.flatten, []); - } - - function getMediaTypes(mediaTypes) { - return utils._map(mediaTypes, (mediaTypeConfig, mediaType) => mediaType); - } -} diff --git a/modules/openxAnalyticsAdapter.md b/modules/openxAnalyticsAdapter.md deleted file mode 100644 index af40486f2a4..00000000000 --- a/modules/openxAnalyticsAdapter.md +++ /dev/null @@ -1,131 +0,0 @@ - -# OpenX Analytics Adapter to Prebid.js -## Implementation Guide -#### Internal use only - ---- - -# About this Guide -This implementation guide walks through the flow of onboarding an alpha Publisher to test OpenX’s new Analytics Adapter. - -- [Adding OpenX Analytics Adapter to Prebid.js](#adding-openx-analytics-adapter-to-prebidjs) - - [Publisher Builds Prebid.js File Flow](#publisher-builds-prebidjs-file-flow) - - [OpenX Builds Prebid.js File Flow](#openx-builds-prebidjs-file-flow) -- [Website Configuration](#website-configuration) -- [Configuration Options](#configuration-options) -- [Viewing Data](#viewing-data) - ---- - -# Adding OpenX Analytics Adapter to Prebid.js -A Publisher has two options to add the OpenX Analytics Adapter to Prebid.js: - -1. [Publisher builds the Prebid.js file](#publisher-builds-prebid.js-file-flow): If the Publisher is familiar with building Prebid.js (through the command line and not through the download site), OpenX can provide to the Publisher only the Analytics Adapter code. - -2. [OpenX builds the Prebid.js file](#openx-builds-prebid.js-file-flow): If the Publisher is unfamiliar with building Prebid.js, the Publisher should advise OpenX which modules to include by going to the [Prebid download site](http://prebid.org/download.html) and selecting all the desired items (adapters and modules) for OpenX. - ---- - -## Publisher Builds Prebid.js File Flow -Use this option if the Publisher is building the Prebid.js file. - -1. OpenX sends Publisher the new Analytics Adapter code. - -2. Publisher replaces the file in `/modules/openxAnalyticsAdapter.js` with the file provided by OpenX. - -3. Publisher runs the build command in `` and includes `openxAnalyticsAdapter` as one of the modules to include. - - For example: - - ```shell - gulp build --modules=openxBidAdapter,rubiconBidAdapter,sovrnBidAdapter,openxBidAdapter,openxAnalyticsAdapter,dfpAdServerVideo - ``` - -4. Publisher deploys the Prebid.js file from `/build/dist/prebid.js` to a website. - ---- - -## OpenX Builds Prebid.js File Flow -Use this option if OpenX is building the Prebid.js file on behalf of the Publisher. - -1. Publisher refers to the [Prebid download site](http://prebid.org/download.html) and sends a list of adapters and modules to OpenX. - - >Note: The Publisher must be aware that only Prebid 3.0+ is supported. - - For example (does not have to follow exact format): - - ```yaml - Prebid Version: 3.10+ - Modules: - Bidders - OpenX - Rubicon - Sovrn - Consent Management - US Privacy - User ID - IdentityLink ID - DFP Video - Supply Chain Object - Currency - ``` - -2. OpenX uses the information to build a package to the user’s specification and includes `openxAnalyticsAdapter` as an additional module. - -3. OpenX sends the built package to the Publisher. - -4. Publisher deploys the modified Prebid.js to a website. - ---- - -# Website Configuration -To configure your website, add the following code snippet to your website: - -```javascript -pbjs.que.push(function () { - pbjs.enableAnalytics([{ - provider: "openx", - options: { - publisherPlatformId: "OPENX_PROVIDED_PLATFORM_ID", // eg: "a3aece0c-9e80-4316-8deb-faf804779bd1" - publisherAccountId: PUBLISHER_ACCOUNT_ID, // eg: 537143056 - sampling: 0.05, // 5% sample rate - testCode: 'test-code-1' - } - }]); -}); -``` - ---- - -## Configuration Options -Configuration options are a follows: - -| Property | Type | Required? | Description | Example | -|:---|:---|:---|:---|:---| -| `orgId` | `string` | Yes | Used to determine ownership of data. | `aa1bb2cc-3dd4-4316-8deb-faf804779bd1` | -| `publisherPlatformId` | `string` | No
**__Deprecated. Please use orgId__** | Used to determine ownership of data. | `a3aece0c-9e80-4316-8deb-faf804779bd1` | -| `publisherAccountId` | `number` | No
**__Deprecated. Please use orgId__** | Used to determine ownership of data. | `1537143056` | -| `sampling` | `number` | Yes | Sampling rate | Undefined or `1.00` - No sampling. Analytics is sent all the time.
0.5 - 50% of users will send analytics data. | -| `testCode` | `string` | No | Used to label analytics data for the purposes of tests.
This label is treated as a dimension and can be compared against other labels. | `timeout_config_1`
`timeout_config_2`
`timeout_default` | -| `campaign` | `Object` | No | Object with 5 parameters:
  • content
  • medium
  • name
  • source
  • term
Each parameter is a free-form string. Refer to metrics doc on when to use these fields. By setting a value to one of these properties, you override the associated url utm query parameter. | | -| `payloadWaitTime` | `number` | No | Delay after all slots of an auction renders before the payload is sent.
Defaults to 100ms | 1000 | ---- - -# Viewing Data -The Prebid Report available in the Reporting in the Cloud tool, allows you to view your data. - -**To view your data:** - -1. Log in to [OpenX Reporting](https://openx.sigmoid.io/app). - -2. In the top right, click on the **View** list and then select **Prebidreport**. - -3. On the left icon bar, click on the dimensions icon. - -4. Add the dimensions that you need. - -5. On the left icon bar, click on the metrics icon. - -6. Add the metrics (graphs) that you need. - - The data appears on the Analyze screen. diff --git a/modules/openxBidAdapter.js b/modules/openxBidAdapter.js deleted file mode 100644 index 8a455f6fa25..00000000000 --- a/modules/openxBidAdapter.js +++ /dev/null @@ -1,505 +0,0 @@ -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import * as utils from '../src/utils.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; - -const SUPPORTED_AD_TYPES = [BANNER, VIDEO]; -const BIDDER_CODE = 'openx'; -const BIDDER_CONFIG = 'hb_pb'; -const BIDDER_VERSION = '3.0.3'; - -const DEFAULT_CURRENCY = 'USD'; - -export const USER_ID_CODE_TO_QUERY_ARG = { - britepoolid: 'britepoolid', // BritePool ID - criteoId: 'criteoid', // CriteoID - fabrickId: 'nuestarid', // Fabrick ID by Nuestar - haloId: 'audigentid', // Halo ID from Audigent - id5id: 'id5id', // ID5 ID - idl_env: 'lre', // LiveRamp IdentityLink - IDP: 'zeotapid', // zeotapIdPlus ID+ - idxId: 'idxid', // idIDx, - intentIqId: 'intentiqid', // IntentIQ ID - lipb: 'lipbid', // LiveIntent ID - lotamePanoramaId: 'lotameid', // Lotame Panorama ID - merkleId: 'merkleid', // Merkle ID - netId: 'netid', // netID - parrableId: 'parrableid', // Parrable ID - pubcid: 'pubcid', // PubCommon ID - quantcastId: 'quantcastid', // Quantcast ID - sharedId: 'sharedid', // Shared ID User ID - tapadId: 'tapadid', // Tapad Id - tdid: 'ttduuid', // The Trade Desk Unified ID - verizonMediaId: 'verizonmediaid', // Verizon Media ConnectID -}; - -export const spec = { - code: BIDDER_CODE, - gvlid: 69, - supportedMediaTypes: SUPPORTED_AD_TYPES, - isBidRequestValid: function (bidRequest) { - const hasDelDomainOrPlatform = bidRequest.params.delDomain || bidRequest.params.platform; - if (utils.deepAccess(bidRequest, 'mediaTypes.banner') && hasDelDomainOrPlatform) { - return !!bidRequest.params.unit || utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes.length') > 0; - } - - return !!(bidRequest.params.unit && hasDelDomainOrPlatform); - }, - buildRequests: function (bidRequests, bidderRequest) { - if (bidRequests.length === 0) { - return []; - } - - let requests = []; - let [videoBids, bannerBids] = partitionByVideoBids(bidRequests); - - // build banner requests - if (bannerBids.length > 0) { - requests.push(buildOXBannerRequest(bannerBids, bidderRequest)); - } - // build video requests - if (videoBids.length > 0) { - videoBids.forEach(videoBid => { - requests.push(buildOXVideoRequest(videoBid, bidderRequest)) - }); - } - - return requests; - }, - interpretResponse: function ({body: oxResponseObj}, serverRequest) { - let mediaType = getMediaTypeFromRequest(serverRequest); - - return mediaType === VIDEO ? createVideoBidResponses(oxResponseObj, serverRequest.payload) - : createBannerBidResponses(oxResponseObj, serverRequest.payload); - }, - getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent) { - if (syncOptions.iframeEnabled || syncOptions.pixelEnabled) { - let pixelType = syncOptions.iframeEnabled ? 'iframe' : 'image'; - let url = utils.deepAccess(responses, '0.body.ads.pixels') || - utils.deepAccess(responses, '0.body.pixels') || - generateDefaultSyncUrl(gdprConsent, uspConsent); - - return [{ - type: pixelType, - url: url - }]; - } - }, - transformBidParams: function(params, isOpenRtb) { - return utils.convertTypes({ - 'unit': 'string', - 'customFloor': 'number' - }, params); - } -}; - -function generateDefaultSyncUrl(gdprConsent, uspConsent) { - let url = 'https://u.openx.net/w/1.0/pd'; - let queryParamStrings = []; - - if (gdprConsent) { - queryParamStrings.push('gdpr=' + (gdprConsent.gdprApplies ? 1 : 0)); - queryParamStrings.push('gdpr_consent=' + encodeURIComponent(gdprConsent.consentString || '')); - } - - // CCPA - if (uspConsent) { - queryParamStrings.push('us_privacy=' + encodeURIComponent(uspConsent)); - } - - return `${url}${queryParamStrings.length > 0 ? '?' + queryParamStrings.join('&') : ''}`; -} - -function isVideoRequest(bidRequest) { - return (utils.deepAccess(bidRequest, 'mediaTypes.video') && !utils.deepAccess(bidRequest, 'mediaTypes.banner')) || bidRequest.mediaType === VIDEO; -} - -function createBannerBidResponses(oxResponseObj, {bids, startTime}) { - let adUnits = oxResponseObj.ads.ad; - let bidResponses = []; - for (let i = 0; i < adUnits.length; i++) { - let adUnit = adUnits[i]; - let adUnitIdx = parseInt(adUnit.idx, 10); - let bidResponse = {}; - - bidResponse.requestId = bids[adUnitIdx].bidId; - - if (adUnit.pub_rev) { - bidResponse.cpm = Number(adUnit.pub_rev) / 1000; - } else { - // No fill, do not add the bidresponse - continue; - } - let creative = adUnit.creative[0]; - if (creative) { - bidResponse.width = creative.width; - bidResponse.height = creative.height; - } - bidResponse.creativeId = creative.id; - bidResponse.ad = adUnit.html; - if (adUnit.deal_id) { - bidResponse.dealId = adUnit.deal_id; - } - // default 5 mins - bidResponse.ttl = 300; - // true is net, false is gross - bidResponse.netRevenue = true; - bidResponse.currency = adUnit.currency; - - // additional fields to add - if (adUnit.tbd) { - bidResponse.tbd = adUnit.tbd; - } - bidResponse.ts = adUnit.ts; - - bidResponse.meta = {}; - if (adUnit.brand_id) { - bidResponse.meta.brandId = adUnit.brand_id; - } - - if (adUnit.adomain && length(adUnit.adomain) > 0) { - bidResponse.meta.advertiserDomains = adUnit.adomain; - } else { - bidResponse.meta.advertiserDomains = []; - } - - if (adUnit.adv_id) { - bidResponse.meta.dspid = adUnit.adv_id; - } - - bidResponses.push(bidResponse); - } - return bidResponses; -} - -function getViewportDimensions(isIfr) { - let width; - let height; - let tWin = window; - let tDoc = document; - let docEl = tDoc.documentElement; - let body; - - if (isIfr) { - try { - tWin = window.top; - tDoc = window.top.document; - } catch (e) { - return; - } - docEl = tDoc.documentElement; - body = tDoc.body; - - width = tWin.innerWidth || docEl.clientWidth || body.clientWidth; - height = tWin.innerHeight || docEl.clientHeight || body.clientHeight; - } else { - docEl = tDoc.documentElement; - width = tWin.innerWidth || docEl.clientWidth; - height = tWin.innerHeight || docEl.clientHeight; - } - - return `${width}x${height}`; -} - -function formatCustomParms(customKey, customParams) { - let value = customParams[customKey]; - if (utils.isArray(value)) { - // if value is an array, join them with commas first - value = value.join(','); - } - // return customKey=customValue format, escaping + to . and / to _ - return (customKey.toLowerCase() + '=' + value.toLowerCase()).replace('+', '.').replace('/', '_') -} - -function partitionByVideoBids(bidRequests) { - return bidRequests.reduce(function (acc, bid) { - // Fallback to banner ads if nothing specified - if (isVideoRequest(bid)) { - acc[0].push(bid); - } else { - acc[1].push(bid); - } - return acc; - }, [[], []]); -} - -function getMediaTypeFromRequest(serverRequest) { - return /avjp$/.test(serverRequest.url) ? VIDEO : BANNER; -} - -function buildCommonQueryParamsFromBids(bids, bidderRequest) { - const isInIframe = utils.inIframe(); - let defaultParams; - - defaultParams = { - ju: config.getConfig('pageUrl') || bidderRequest.refererInfo.referer, - ch: document.charSet || document.characterSet, - res: `${screen.width}x${screen.height}x${screen.colorDepth}`, - ifr: isInIframe, - tz: new Date().getTimezoneOffset(), - tws: getViewportDimensions(isInIframe), - be: 1, - bc: bids[0].params.bc || `${BIDDER_CONFIG}_${BIDDER_VERSION}`, - dddid: utils._map(bids, bid => bid.transactionId).join(','), - nocache: new Date().getTime() - }; - - if (bids[0].params.platform) { - defaultParams.ph = bids[0].params.platform; - } - - if (bidderRequest.gdprConsent) { - let gdprConsentConfig = bidderRequest.gdprConsent; - - if (gdprConsentConfig.consentString !== undefined) { - defaultParams.gdpr_consent = gdprConsentConfig.consentString; - } - - if (gdprConsentConfig.gdprApplies !== undefined) { - defaultParams.gdpr = gdprConsentConfig.gdprApplies ? 1 : 0; - } - - if (config.getConfig('consentManagement.cmpApi') === 'iab') { - defaultParams.x_gdpr_f = 1; - } - } - - if (bidderRequest && bidderRequest.uspConsent) { - defaultParams.us_privacy = bidderRequest.uspConsent; - } - - // normalize publisher common id - if (utils.deepAccess(bids[0], 'crumbs.pubcid')) { - utils.deepSetValue(bids[0], 'userId.pubcid', utils.deepAccess(bids[0], 'crumbs.pubcid')); - } - defaultParams = appendUserIdsToQueryParams(defaultParams, bids[0].userId); - - // supply chain support - if (bids[0].schain) { - defaultParams.schain = serializeSupplyChain(bids[0].schain); - } - - return defaultParams; -} - -function appendUserIdsToQueryParams(queryParams, userIds) { - utils._each(userIds, (userIdObjectOrValue, userIdProviderKey) => { - const key = USER_ID_CODE_TO_QUERY_ARG[userIdProviderKey]; - - if (USER_ID_CODE_TO_QUERY_ARG.hasOwnProperty(userIdProviderKey)) { - switch (userIdProviderKey) { - case 'lipb': - queryParams[key] = userIdObjectOrValue.lipbid; - break; - case 'parrableId': - queryParams[key] = userIdObjectOrValue.eid; - break; - case 'id5id': - queryParams[key] = userIdObjectOrValue.uid; - break; - default: - queryParams[key] = userIdObjectOrValue; - } - } - }); - - return queryParams; -} - -function serializeSupplyChain(supplyChain) { - return `${supplyChain.ver},${supplyChain.complete}!${serializeSupplyChainNodes(supplyChain.nodes)}`; -} - -function serializeSupplyChainNodes(supplyChainNodes) { - const supplyChainNodePropertyOrder = ['asi', 'sid', 'hp', 'rid', 'name', 'domain']; - - return supplyChainNodes.map(supplyChainNode => { - return supplyChainNodePropertyOrder.map(property => supplyChainNode[property] || '') - .join(','); - }).join('!'); -} - -function buildOXBannerRequest(bids, bidderRequest) { - let customParamsForAllBids = []; - let hasCustomParam = false; - let queryParams = buildCommonQueryParamsFromBids(bids, bidderRequest); - let auids = utils._map(bids, bid => bid.params.unit); - - queryParams.aus = utils._map(bids, bid => utils.parseSizesInput(bid.mediaTypes.banner.sizes).join(',')).join('|'); - queryParams.divIds = utils._map(bids, bid => encodeURIComponent(bid.adUnitCode)).join(','); - - if (auids.some(auid => auid)) { - queryParams.auid = auids.join(','); - } - - if (bids.some(bid => bid.params.doNotTrack)) { - queryParams.ns = 1; - } - - if (config.getConfig('coppa') === true || bids.some(bid => bid.params.coppa)) { - queryParams.tfcd = 1; - } - - bids.forEach(function (bid) { - if (bid.params.customParams) { - let customParamsForBid = utils._map(Object.keys(bid.params.customParams), customKey => formatCustomParms(customKey, bid.params.customParams)); - let formattedCustomParams = window.btoa(customParamsForBid.join('&')); - hasCustomParam = true; - customParamsForAllBids.push(formattedCustomParams); - } else { - customParamsForAllBids.push(''); - } - }); - if (hasCustomParam) { - queryParams.tps = customParamsForAllBids.join(','); - } - - enrichQueryWithFloors(queryParams, BANNER, bids); - - let url = queryParams.ph - ? `https://u.openx.net/w/1.0/arj` - : `https://${bids[0].params.delDomain}/w/1.0/arj`; - - return { - method: 'GET', - url: url, - data: queryParams, - payload: {'bids': bids, 'startTime': new Date()} - }; -} - -function buildOXVideoRequest(bid, bidderRequest) { - let oxVideoParams = generateVideoParameters(bid, bidderRequest); - let url = oxVideoParams.ph - ? `https://u.openx.net/v/1.0/avjp` - : `https://${bid.params.delDomain}/v/1.0/avjp`; - return { - method: 'GET', - url: url, - data: oxVideoParams, - payload: {'bid': bid, 'startTime': new Date()} - }; -} - -function generateVideoParameters(bid, bidderRequest) { - let queryParams = buildCommonQueryParamsFromBids([bid], bidderRequest); - let oxVideoConfig = utils.deepAccess(bid, 'params.video') || {}; - let context = utils.deepAccess(bid, 'mediaTypes.video.context'); - let playerSize = utils.deepAccess(bid, 'mediaTypes.video.playerSize'); - let width; - let height; - - // normalize config for video size - if (utils.isArray(bid.sizes) && bid.sizes.length === 2 && !utils.isArray(bid.sizes[0])) { - width = parseInt(bid.sizes[0], 10); - height = parseInt(bid.sizes[1], 10); - } else if (utils.isArray(bid.sizes) && utils.isArray(bid.sizes[0]) && bid.sizes[0].length === 2) { - width = parseInt(bid.sizes[0][0], 10); - height = parseInt(bid.sizes[0][1], 10); - } else if (utils.isArray(playerSize) && playerSize.length === 2) { - width = parseInt(playerSize[0], 10); - height = parseInt(playerSize[1], 10); - } - - Object.keys(oxVideoConfig).forEach(function (key) { - if (key === 'openrtb') { - oxVideoConfig[key].w = width || oxVideoConfig[key].w; - oxVideoConfig[key].v = height || oxVideoConfig[key].v; - queryParams[key] = JSON.stringify(oxVideoConfig[key]); - } else if (!(key in queryParams) && key !== 'url') { - // only allow video-related attributes - queryParams[key] = oxVideoConfig[key]; - } - }); - - queryParams.auid = bid.params.unit; - // override prebid config with openx config if available - queryParams.vwd = width || oxVideoConfig.vwd; - queryParams.vht = height || oxVideoConfig.vht; - - if (context === 'outstream') { - queryParams.vos = '101'; - } - - if (oxVideoConfig.mimes) { - queryParams.vmimes = oxVideoConfig.mimes; - } - - if (bid.params.test) { - queryParams.vtest = 1; - } - - // each video bid makes a separate request - enrichQueryWithFloors(queryParams, VIDEO, [bid]); - - return queryParams; -} - -function createVideoBidResponses(response, {bid, startTime}) { - let bidResponses = []; - - if (response !== undefined && response.vastUrl !== '' && response.pub_rev > 0) { - let vastQueryParams = utils.parseUrl(response.vastUrl).search || {}; - let bidResponse = {}; - bidResponse.requestId = bid.bidId; - if (response.deal_id) { - bidResponse.dealId = response.deal_id; - } - // default 5 mins - bidResponse.ttl = 300; - // true is net, false is gross - bidResponse.netRevenue = true; - bidResponse.currency = response.currency; - bidResponse.cpm = parseInt(response.pub_rev, 10) / 1000; - bidResponse.width = parseInt(response.width, 10); - bidResponse.height = parseInt(response.height, 10); - bidResponse.creativeId = response.adid; - bidResponse.vastUrl = response.vastUrl; - bidResponse.mediaType = VIDEO; - - // enrich adunit with vast parameters - response.ph = vastQueryParams.ph; - response.colo = vastQueryParams.colo; - response.ts = vastQueryParams.ts; - - bidResponses.push(bidResponse); - } - - return bidResponses; -} - -function enrichQueryWithFloors(queryParams, mediaType, bids) { - let customFloorsForAllBids = []; - let hasCustomFloor = false; - bids.forEach(function (bid) { - let floor = getBidFloor(bid, mediaType); - - if (floor) { - customFloorsForAllBids.push(floor); - hasCustomFloor = true; - } else { - customFloorsForAllBids.push(0); - } - }); - if (hasCustomFloor) { - queryParams.aumfs = customFloorsForAllBids.join(','); - } -} - -function getBidFloor(bidRequest, mediaType) { - let floorInfo = {}; - const currency = config.getConfig('currency.adServerCurrency') || DEFAULT_CURRENCY; - - if (typeof bidRequest.getFloor === 'function') { - floorInfo = bidRequest.getFloor({ - currency: currency, - mediaType: mediaType, - size: '*' - }); - } - let floor = floorInfo.floor || bidRequest.params.customFloor || 0; - - return Math.round(floor * 1000); // normalize to micro currency -} - -registerBidder(spec); diff --git a/modules/openxBidAdapter.md b/modules/openxBidAdapter.md deleted file mode 100644 index 965b8ee1948..00000000000 --- a/modules/openxBidAdapter.md +++ /dev/null @@ -1,104 +0,0 @@ -# Overview - -``` -Module Name: OpenX Bidder Adapter -Module Type: Bidder Adapter -Maintainer: team-openx@openx.com -``` - -# Description - -Module that connects to OpenX's demand sources - -# Bid Parameters -## Banner - -| Name | Scope | Type | Description | Example -| ---- | ----- | ---- | ----------- | ------- -| `delDomain` or `platform` | required | String | OpenX delivery domain or platform id provided by your OpenX representative. | "PUBLISHER-d.openx.net" or "555not5a-real-plat-form-id0123456789" -| `unit` | required | String | OpenX ad unit ID provided by your OpenX representative. | "1611023122" -| `customParams` | optional | Object | User-defined targeting key-value pairs. customParams applies to a specific unit. | `{key1: "v1", key2: ["v2","v3"]}` -| `customFloor` | optional | Number | Minimum price in USD. customFloor applies to a specific unit. For example, use the following value to set a $1.50 floor: 1.50

**WARNING:**
Misuse of this parameter can impact revenue | 1.50 -| `doNotTrack` | optional | Boolean | Prevents advertiser from using data for this user.

**WARNING:**
Request-level setting. May impact revenue. | true -| `coppa` | optional | Boolean | Enables Child's Online Privacy Protection Act (COPPA) regulations. | true - -## Video - -| Name | Scope | Type | Description | Example -| ---- | ----- | ---- | ----------- | ------- -| `unit` | required | String | OpenX ad unit ID provided by your OpenX representative. | "1611023122" -| `delDomain` | required | String | OpenX delivery domain provided by your OpenX representative. | "PUBLISHER-d.openx.net" -| `openrtb` | optional | OpenRTB Impression | An OpenRtb Impression with Video subtype properties | `{ imp: [{ video: {mimes: ['video/x-ms-wmv, video/mp4']} }] }` - - -# Example -```javascript -var adUnits = [ - { - code: 'test-div', - sizes: [[728, 90]], // a display size - mediaTypes: {'banner': {}}, - bids: [ - { - bidder: 'openx', - params: { - unit: '539439964', - delDomain: 'se-demo-d.openx.net', - customParams: { - key1: 'v1', - key2: ['v2', 'v3'] - }, - } - }, { - bidder: 'openx', - params: { - unit: '539439964', - platform: 'a3aece0c-9e80-4316-8deb-faf804779bd1', - customParams: { - key1: 'v1', - key2: ['v2', 'v3'] - }, - } - } - ] - }, - { - code: 'video1', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'instream' - } - }, - bids: [{ - bidder: 'openx', - params: { - unit: '1611023124', - delDomain: 'PUBLISHER-d.openx.net', - video: { - mimes: ['video/x-ms-wmv, video/mp4'] - } - } - }] - } -]; -``` - -# Configuration -Add the following code to enable user syncing. By default, Prebid.js version 0.34.0+ turns off user syncing through iframes. -OpenX strongly recommends enabling user syncing through iframes. This functionality improves DSP user match rates and increases the -OpenX bid rate and bid price. Be sure to call `pbjs.setConfig()` only once. - -```javascript -pbjs.setConfig({ - userSync: { - iframeEnabled: true - } -}); -``` - -# Additional Details -[Banner Ads](https://docs.openx.com/Content/developers/containers/prebid-adapter.html) - -[Video Ads](https://docs.openx.com/Content/developers/containers/prebid-video-adapter.html) - diff --git a/modules/optimaticBidAdapter.md b/modules/optimaticBidAdapter.md deleted file mode 100644 index edaa3da90f6..00000000000 --- a/modules/optimaticBidAdapter.md +++ /dev/null @@ -1,30 +0,0 @@ -# Overview - -``` -Module Name: Optimatic Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid@optimatic.com -``` - -# Description - -Optimatic Bid Adapter Module connects to Optimatic Demand Sources for Video Ads - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - sizes: [[640,480]], // a video size - bids: [ - { - bidder: "optimatic", - params: { - placement: "2chy7Gc2eSQL", - bidfloor: 2.5 - } - } - ] - }, - ]; -``` diff --git a/modules/optimeraBidAdapter.js b/modules/optimeraBidAdapter.js deleted file mode 100644 index b470e901ec6..00000000000 --- a/modules/optimeraBidAdapter.js +++ /dev/null @@ -1,85 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { deepAccess } from '../src/utils.js'; - -const BIDDER_CODE = 'optimera'; -const SCORES_BASE_URL = 'https://dyv1bugovvq1g.cloudfront.net/'; - -export const spec = { - code: BIDDER_CODE, - /** - * Determines whether or not the given bid request is valid. - * - * @param {bidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid (bidRequest) { - if (typeof bidRequest.params !== 'undefined' && typeof bidRequest.params.clientID !== 'undefined') { - return true; - } - return false; - }, - /** - * Make a server request from the list of BidRequests. - * - * We call the existing scores data file for ad slot placement scores. - * These scores will be added to the dealId to be pushed to DFP. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests (validBidRequests) { - const optimeraHost = window.location.host; - const optimeraPathName = window.location.pathname; - if (typeof validBidRequests[0].params.clientID !== 'undefined') { - const { clientID } = validBidRequests[0].params; - const scoresURL = `${SCORES_BASE_URL + clientID}/${optimeraHost}${optimeraPathName}.js`; - return { - method: 'GET', - url: scoresURL, - payload: validBidRequests, - }; - } - return {}; - }, - /** - * Unpack the response from the server into a list of bids. - * - * Some required bid params are not needed for this so default - * values are used. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse (serverResponse, bidRequest) { - const validBids = bidRequest.payload; - const bidResponses = []; - let dealId = ''; - if (typeof serverResponse.body !== 'undefined') { - const scores = serverResponse.body; - for (let i = 0; i < validBids.length; i += 1) { - if (typeof validBids[i].params.clientID !== 'undefined') { - if (validBids[i].adUnitCode in scores) { - const deviceDealId = deepAccess(scores, `device.${validBids[i].params.device}.${validBids[i].adUnitCode}`); - dealId = deviceDealId || scores[validBids[i].adUnitCode]; - } - const bidResponse = { - requestId: validBids[i].bidId, - ad: '
', - cpm: 0.01, - width: 0, - height: 0, - dealId, - ttl: 300, - creativeId: '1', - netRevenue: '0', - currency: 'USD' - }; - bidResponses.push(bidResponse); - } - } - } - return bidResponses; - } -} - -registerBidder(spec); diff --git a/modules/optimeraBidAdapter.md b/modules/optimeraBidAdapter.md deleted file mode 100644 index 25da9b6236f..00000000000 --- a/modules/optimeraBidAdapter.md +++ /dev/null @@ -1,58 +0,0 @@ -# Overview - -``` -Module Name: Optimera Bidder Adapter -Module Type: Bidder Adapter -Maintainer: kcandiotti@optimera.nyc -``` - -# Description - -Module that adds ad placement visibility scores for DFP. - -# Test Parameters -``` - var adUnits = [{ - code: 'div-1', - sizes: [[300, 250], [300,600]], - bids: [ - { - bidder: 'optimera', - params: { - clientID: '9999', - device: 'mo' - } - }] - },{ - code: 'div-0', - sizes: [[728, 90]], - bids: [ - { - bidder: 'optimera', - params: { - clientID: '9999', - device: 'mo' - } - }] - }]; -``` - -# AppNexus Issue -There is an issue where the plugin sometimes doesn't return impressions with AppNexus. - -There is an open issue here: [#3597](https://github.com/prebid/Prebid.js/issues/3597) - -## Configuration Workaround - -Optimera's configuration requires the use of size 0,0 which, in some instances, causes the AppNexus ad server to respond to ad requests but not fill impressions. AppNexus and vendors using the AppNexus ad server should monitor 3rd party numbers to ensure there is no decline in fill rate. - -Configuration Example: - -``` -code: ‘leaderboard', -mediaTypes: { - banner: { - sizes: [[970, 250],[970, 90],[970, 66],[728, 90],[320, 50],[320, 100],[300, 250],[0, 0]], - } -} -``` diff --git a/modules/optimonAnalyticsAdapter.js b/modules/optimonAnalyticsAdapter.js deleted file mode 100644 index 34b2778afc9..00000000000 --- a/modules/optimonAnalyticsAdapter.js +++ /dev/null @@ -1,25 +0,0 @@ -/** -* -********************************************************* -* -* Optimon.io Prebid Analytics Adapter -* -********************************************************* -* -*/ - -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; - -const optimonAnalyticsAdapter = adapter({ - global: 'OptimonAnalyticsAdapter', - handler: 'on', - analyticsType: 'bundle' -}); - -adapterManager.registerAnalyticsAdapter({ - adapter: optimonAnalyticsAdapter, - code: 'optimon', -}); - -export default optimonAnalyticsAdapter; diff --git a/modules/optimonAnalyticsAdapter.md b/modules/optimonAnalyticsAdapter.md deleted file mode 100644 index 4e2c00dfcab..00000000000 --- a/modules/optimonAnalyticsAdapter.md +++ /dev/null @@ -1,13 +0,0 @@ -# Overview - -Module Name: Optimon.io Prebid Analytics Adapter -Module Type: Analytics Adapter -Maintainer: hello@optimon.io - -# Description - -Start analyzing your Prebid performance by visiting our website [Optimon.io](https://optimon.io/?utm_source=prebid-org&utm_medium=analytics-adapter) or contact us directly by email: [hello@optimon.io](mailto:hello@optimon.io) to get started. - -# Platform Details - -[Optimon.io](https://optimon.io/?utm_source=prebid-org&utm_medium=analytics-adapter) is a Robust Alerting & Reporting Platform for Prebid and GAM that helps publishers make the right decisions by collecting data from your Google Ad Manager, Prebid, and other SSPs and providing smart insights and suggestions to optimize and maximize their overall yield and save manual work. diff --git a/modules/orbidderBidAdapter.js b/modules/orbidderBidAdapter.js deleted file mode 100644 index e01746af487..00000000000 --- a/modules/orbidderBidAdapter.js +++ /dev/null @@ -1,80 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const storageManager = getStorageManager(); - -export const spec = { - code: 'orbidder', - hostname: 'https://orbidder.otto.de', - - getHostname() { - let ret = this.hostname; - try { - ret = storageManager.getDataFromLocalStorage('ov_orbidder_host') || ret; - } catch (e) { - } - return ret; - }, - - isBidRequestValid(bid) { - return !!(bid.sizes && bid.bidId && bid.params && - (bid.params.accountId && (typeof bid.params.accountId === 'string')) && - (bid.params.placementId && (typeof bid.params.placementId === 'string')) && - ((typeof bid.params.bidfloor === 'undefined') || (typeof bid.params.bidfloor === 'number')) && - ((typeof bid.params.profile === 'undefined') || (typeof bid.params.profile === 'object'))); - }, - - buildRequests(validBidRequests, bidderRequest) { - const hostname = this.getHostname(); - return validBidRequests.map((bidRequest) => { - let referer = ''; - if (bidderRequest && bidderRequest.refererInfo) { - referer = bidderRequest.refererInfo.referer || ''; - } - - const ret = { - url: `${hostname}/bid`, - method: 'POST', - options: { withCredentials: true }, - data: { - v: $$PREBID_GLOBAL$$.version, - pageUrl: referer, - bidId: bidRequest.bidId, - auctionId: bidRequest.auctionId, - transactionId: bidRequest.transactionId, - adUnitCode: bidRequest.adUnitCode, - bidRequestCount: bidRequest.bidRequestCount, - sizes: bidRequest.sizes, - params: bidRequest.params - } - }; - if (bidderRequest && bidderRequest.gdprConsent) { - ret.data.gdprConsent = { - consentString: bidderRequest.gdprConsent.consentString, - consentRequired: (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') && bidderRequest.gdprConsent.gdprApplies - }; - } - return ret; - }); - }, - - interpretResponse(serverResponse) { - const bidResponses = []; - serverResponse = serverResponse.body; - if (serverResponse && (serverResponse.length > 0)) { - serverResponse.forEach((bid) => { - const bidResponse = {}; - for (const requiredKey of ['requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', 'netRevenue', 'currency']) { - if (!bid.hasOwnProperty(requiredKey)) { - return []; - } - bidResponse[requiredKey] = bid[requiredKey]; - } - bidResponses.push(bidResponse); - }); - } - return bidResponses; - }, -}; - -registerBidder(spec); diff --git a/modules/orbidderBidAdapter.md b/modules/orbidderBidAdapter.md deleted file mode 100644 index c7676e6774f..00000000000 --- a/modules/orbidderBidAdapter.md +++ /dev/null @@ -1,30 +0,0 @@ -#Overview - -``` -Module Name: Orbidder Bid Adapter -Module Type: Bidder Adapter -Maintainer: orbidder@otto.de -``` - -# Description - -Module that connects to orbidder demand sources - -# Test Parameters -``` -var adUnits = [{ - code: '/105091519/bidder_test', - mediaTypes: { - banner: { - sizes: [728, 90] - } - }, - bids: [{ - bidder: 'orbidder' - params: { - accountId: "someAccount", - placementId: "somePlace" - } - }] -}]; -``` diff --git a/modules/orbitsoftBidAdapter.md b/modules/orbitsoftBidAdapter.md deleted file mode 100644 index a18f075b6b1..00000000000 --- a/modules/orbitsoftBidAdapter.md +++ /dev/null @@ -1,60 +0,0 @@ -# Overview - -``` -Module Name: Orbitsoft Bidder Adapter -Module Type: Bidder Adapter -Maintainer: support@orbitsoft.com -``` - -# Description - -Module that connects to Orbitsoft's demand sources. The “sizes” option is not supported, and the size of the ad depends on the placement settings. You can use an optional “style” parameter to set the appearance only for text ad. Specify the “requestUrl” param to your Orbitsoft ad server header bidding endpoint. - -# Test Parameters -``` - var adUnits = [ - { - code: 'orbitsoft-div', - bids: [ - { - bidder: "orbitsoft", - params: { - placementId: '132', - requestUrl: 'https://orbitsoft.com/php/ads/hb.php', - style: { - title: { - family: 'Tahoma', - size: 'medium', - weight: 'normal', - style: 'normal', - color: '0053F9' - }, - description: { - family: 'Tahoma', - size: 'medium', - weight: 'normal', - style: 'normal', - color: '0053F9' - }, - url: { - family: 'Tahoma', - size: 'medium', - weight: 'normal', - style: 'normal', - color: '0053F9' - }, - colors: { - background: 'ffffff', - border: 'E0E0E0', - link: '5B99FE' - } - }, - customParams: { - macro_name: "macro_value" - } - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/otmBidAdapter.js b/modules/otmBidAdapter.js deleted file mode 100644 index 23f6d434ae1..00000000000 --- a/modules/otmBidAdapter.js +++ /dev/null @@ -1,95 +0,0 @@ -import {BANNER} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; - -export const spec = { - code: 'otm', - supportedMediaTypes: [BANNER], - isBidRequestValid: function (bid) { - return !!bid.params.tid; - }, - buildRequests: function (bidRequests) { - const requests = bidRequests.map(function (bid) { - const size = getMaxPrioritySize(bid.sizes); - const params = { - tz: getTz(), - w: size[0], - h: size[1], - s: bid.params.tid, - bidid: bid.bidId, - transactionid: bid.transactionId, - auctionid: bid.auctionId, - bidfloor: bid.params.bidfloor - }; - - return {method: 'GET', url: 'https://ssp.otm-r.com/adjson', data: params} - }); - - return requests; - }, - interpretResponse: function (serverResponse, bidRequest) { - if (!serverResponse || !serverResponse.body) { - return []; - } - - const answer = []; - - serverResponse.body.forEach(bid => { - if (bid.ad) { - answer.push({ - requestId: bid.bidid, - cpm: bid.cpm, - width: bid.w, - height: bid.h, - creativeId: bid.creativeid, - currency: bid.currency || 'RUB', - netRevenue: true, - ad: bid.ad, - ttl: bid.ttl, - transactionId: bid.transactionid - }); - } - }); - - return answer; - }, -}; - -function getTz() { - return new Date().getTimezoneOffset(); -} - -function getMaxPrioritySize(sizes) { - var maxPrioritySize = null; - - const sizesByPriority = [ - [300, 250], - [240, 400], - [728, 90], - [300, 600], - [970, 250], - [300, 50], - [320, 100] - ]; - - const sizeToString = (size) => { - return size[0] + 'x' + size[1]; - }; - - const sizesAsString = sizes.map(sizeToString); - - sizesByPriority.forEach(size => { - if (!maxPrioritySize) { - if (sizesAsString.indexOf(sizeToString(size)) !== -1) { - maxPrioritySize = size; - } - } - }); - - if (maxPrioritySize) { - return maxPrioritySize; - } else { - return sizes[0]; - } -} - -registerBidder(spec); diff --git a/modules/otmBidAdapter.md b/modules/otmBidAdapter.md deleted file mode 100644 index 4962d3a8052..00000000000 --- a/modules/otmBidAdapter.md +++ /dev/null @@ -1,36 +0,0 @@ -# Overview - -Module Name: OTM Bidder Adapter -Module Type: Bidder Adapter -Maintainer: ? - -# Description - -You can use this adapter to get a bid from otm-r.com. - -About us : http://otm-r.com - - -# Test Parameters -```javascript - var adUnits = [ - { - code: 'div-otm-example', - sizes: [[320, 480]], - bids: [ - { - bidder: "otm", - params: { - tid: "99", - bidfloor: 20 - } - } - ] - } - ]; -``` - -Where: - -* tid - A tag id (should have low cardinality) -* bidfloor - Floor price diff --git a/modules/outbrainBidAdapter.js b/modules/outbrainBidAdapter.js deleted file mode 100644 index c0af09c2b50..00000000000 --- a/modules/outbrainBidAdapter.js +++ /dev/null @@ -1,280 +0,0 @@ -// jshint esversion: 6, es3: false, node: true -'use strict'; - -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 { config } from '../src/config.js'; - -const BIDDER_CODE = 'outbrain'; -const GVLID = 164; -const CURRENCY = 'USD'; -const NATIVE_ASSET_IDS = { 0: 'title', 2: 'icon', 3: 'image', 5: 'sponsoredBy', 4: 'body', 1: 'cta' }; -const NATIVE_PARAMS = { - title: { id: 0, name: 'title' }, - icon: { id: 2, type: 1, name: 'img' }, - image: { id: 3, type: 3, name: 'img' }, - sponsoredBy: { id: 5, name: 'data', type: 1 }, - body: { id: 4, name: 'data', type: 2 }, - cta: { id: 1, type: 12, name: 'data' } -}; - -export const spec = { - code: BIDDER_CODE, - gvlid: GVLID, - supportedMediaTypes: [ NATIVE, BANNER ], - isBidRequestValid: (bid) => { - return ( - !!config.getConfig('outbrain.bidderUrl') && - !!utils.deepAccess(bid, 'params.publisher.id') && - !!(bid.nativeParams || bid.sizes) - ); - }, - buildRequests: (validBidRequests, bidderRequest) => { - const page = bidderRequest.refererInfo.referer; - const ua = navigator.userAgent; - const test = setOnAny(validBidRequests, 'params.test'); - const publisher = setOnAny(validBidRequests, 'params.publisher'); - const bcat = setOnAny(validBidRequests, 'params.bcat'); - const badv = setOnAny(validBidRequests, 'params.badv'); - const cur = CURRENCY; - const endpointUrl = config.getConfig('outbrain.bidderUrl'); - const timeout = bidderRequest.timeout; - - const imps = validBidRequests.map((bid, id) => { - bid.netRevenue = 'net'; - const imp = { - id: id + 1 + '' - } - - if (bid.params.tagid) { - imp.tagid = bid.params.tagid - } - - if (bid.nativeParams) { - imp.native = { - request: JSON.stringify({ - assets: getNativeAssets(bid) - }) - } - } else { - imp.banner = { - format: transformSizes(bid.sizes) - } - } - - return imp; - }); - - const request = { - id: bidderRequest.auctionId, - site: { page, publisher }, - device: { ua }, - source: { fd: 1 }, - cur: [cur], - tmax: timeout, - imp: imps, - bcat: bcat, - badv: badv, - }; - - if (test) { - request.is_debug = !!test; - request.test = 1; - } - - if (utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies')) { - utils.deepSetValue(request, 'user.ext.consent', bidderRequest.gdprConsent.consentString) - utils.deepSetValue(request, 'regs.ext.gdpr', bidderRequest.gdprConsent.gdprApplies & 1) - } - if (bidderRequest.uspConsent) { - utils.deepSetValue(request, 'regs.ext.us_privacy', bidderRequest.uspConsent) - } - if (config.getConfig('coppa') === true) { - utils.deepSetValue(request, 'regs.coppa', config.getConfig('coppa') & 1) - } - - return { - method: 'POST', - url: endpointUrl, - data: JSON.stringify(request), - bids: validBidRequests - }; - }, - interpretResponse: (serverResponse, { bids }) => { - if (!serverResponse.body) { - return []; - } - const { seatbid, cur } = serverResponse.body; - - const bidResponses = flatten(seatbid.map(seat => seat.bid)).reduce((result, bid) => { - result[bid.impid - 1] = bid; - return result; - }, []); - - return bids.map((bid, id) => { - const bidResponse = bidResponses[id]; - if (bidResponse) { - const type = bid.nativeParams ? NATIVE : BANNER; - const bidObject = { - requestId: bid.bidId, - cpm: bidResponse.price, - creativeId: bidResponse.crid, - ttl: 360, - netRevenue: bid.netRevenue === 'net', - currency: cur, - mediaType: type, - nurl: bidResponse.nurl, - }; - if (type === NATIVE) { - bidObject.native = parseNative(bidResponse); - } else { - bidObject.ad = bidResponse.adm; - bidObject.width = bidResponse.w; - bidObject.height = bidResponse.h; - } - bidObject.meta = {}; - if (bidResponse.adomain && bidResponse.adomain.length > 0) { - bidObject.meta.advertiserDomains = bidResponse.adomain; - } - return bidObject; - } - }).filter(Boolean); - }, - getUserSyncs: (syncOptions, responses, gdprConsent, uspConsent) => { - const syncs = []; - let syncUrl = config.getConfig('outbrain.usersyncUrl'); - - let query = []; - if (syncOptions.pixelEnabled && syncUrl) { - if (gdprConsent) { - query.push('gdpr=' + (gdprConsent.gdprApplies & 1)); - query.push('gdpr_consent=' + encodeURIComponent(gdprConsent.consentString || '')); - } - if (uspConsent) { - query.push('us_privacy=' + encodeURIComponent(uspConsent)); - } - - syncs.push({ - type: 'image', - url: syncUrl + (query.length ? '?' + query.join('&') : '') - }); - } - return syncs; - }, - onBidWon: (bid) => { - // for native requests we put the nurl as an imp tracker, otherwise if the auction takes place on prebid server - // the server JS adapter puts the nurl in the adm as a tracking pixel and removes the attribute - if (bid.nurl) { - ajax(utils.replaceAuctionPrice(bid.nurl, bid.originalCpm)) - } - } -}; - -registerBidder(spec); - -function parseNative(bid) { - const { assets, link, eventtrackers } = JSON.parse(bid.adm); - const result = { - clickUrl: link.url, - clickTrackers: link.clicktrackers || undefined - }; - assets.forEach(asset => { - const kind = NATIVE_ASSET_IDS[asset.id]; - const content = kind && asset[NATIVE_PARAMS[kind].name]; - if (content) { - result[kind] = content.text || content.value || { url: content.url, width: content.w, height: content.h }; - } - }); - if (eventtrackers) { - result.impressionTrackers = []; - eventtrackers.forEach(tracker => { - if (tracker.event !== 1) return; - switch (tracker.method) { - case 1: // img - result.impressionTrackers.push(tracker.url); - break; - case 2: // js - result.javascriptTrackers = ``; - break; - } - }); - } - return result; -} - -function setOnAny(collection, key) { - for (let i = 0, result; i < collection.length; i++) { - result = utils.deepAccess(collection[i], key); - if (result) { - return result; - } - } -} - -function flatten(arr) { - return [].concat(...arr); -} - -function getNativeAssets(bid) { - return utils._map(bid.nativeParams, (bidParams, key) => { - const props = NATIVE_PARAMS[key]; - const asset = { - required: bidParams.required & 1, - }; - if (props) { - asset.id = props.id; - let wmin, hmin, w, h; - let aRatios = bidParams.aspect_ratios; - - if (aRatios && aRatios[0]) { - aRatios = aRatios[0]; - wmin = aRatios.min_width || 0; - hmin = aRatios.ratio_height * wmin / aRatios.ratio_width | 0; - } - - if (bidParams.sizes) { - const sizes = flatten(bidParams.sizes); - w = sizes[0]; - h = sizes[1]; - } - - asset[props.name] = { - len: bidParams.len, - type: props.type, - wmin, - hmin, - w, - h - }; - - return asset; - } - }).filter(Boolean); -} - -/* Turn bid request sizes into ut-compatible format */ -function transformSizes(requestSizes) { - if (!utils.isArray(requestSizes)) { - return []; - } - - if (requestSizes.length === 2 && !utils.isArray(requestSizes[0])) { - return [{ - w: parseInt(requestSizes[0], 10), - h: parseInt(requestSizes[1], 10) - }]; - } else if (utils.isArray(requestSizes[0])) { - return requestSizes.map(item => - ({ - w: parseInt(item[0], 10), - h: parseInt(item[1], 10) - }) - ); - } - - return []; -} diff --git a/modules/outbrainBidAdapter.md b/modules/outbrainBidAdapter.md deleted file mode 100644 index 32df22ddad8..00000000000 --- a/modules/outbrainBidAdapter.md +++ /dev/null @@ -1,111 +0,0 @@ -# Overview - -``` -Module Name: Outbrain Adapter -Module Type: Bidder Adapter -Maintainer: prog-ops-team@outbrain.com -``` - -# Description - -Module that connects to Outbrain bidder to fetch bids. -Both native and display formats are supported but not at the same time. Using OpenRTB standard. - -# Configuration - -## Bidder and usersync URLs - -The Outbrain adapter does not work without setting the correct bidder and usersync URLs. -You will receive the URLs when contacting us. - -``` -pbjs.setConfig({ - outbrain: { - bidderUrl: 'https://bidder-url.com', - usersyncUrl: 'https://usersync-url.com' - } -}); -``` - - -# Test Native Parameters -``` - var adUnits = [ - code: '/19968336/prebid_native_example_1', - mediaTypes: { - native: { - image: { - required: false, - sizes: [100, 50] - }, - title: { - required: false, - len: 140 - }, - sponsoredBy: { - required: false - }, - clickUrl: { - required: false - }, - body: { - required: false - }, - icon: { - required: false, - sizes: [50, 50] - } - } - }, - bids: [{ - bidder: 'outbrain', - params: { - publisher: { - id: '2706', // required - name: 'Publishers Name', - domain: 'publisher.com' - }, - tagid: 'tag-id', - bcat: ['IAB1-1'], - badv: ['example.com'] - } - }] - ]; - - pbjs.setConfig({ - outbrain: { - bidderUrl: 'https://prebidtest.zemanta.com/api/bidder/prebidtest/bid/' - } - }); -``` - -# Test Display Parameters -``` - var adUnits = [ - code: '/19968336/prebid_display_example_1', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [{ - bidder: 'outbrain', - params: { - publisher: { - id: '2706', // required - name: 'Publishers Name', - domain: 'publisher.com' - }, - tagid: 'tag-id', - bcat: ['IAB1-1'], - badv: ['example.com'] - }, - }] - ]; - - pbjs.setConfig({ - outbrain: { - bidderUrl: 'https://prebidtest.zemanta.com/api/bidder/prebidtest/bid/' - } - }); -``` diff --git a/modules/outconAdapter.md b/modules/outconAdapter.md deleted file mode 100644 index 88ed45396bc..00000000000 --- a/modules/outconAdapter.md +++ /dev/null @@ -1,26 +0,0 @@ -# Overview - -``` -Module Name: outconAdapter -Module Type: Bidder Adapter -Maintainer: mfolmer@dokkogroup.com.ar -``` - -# Description - -Module that connects to Outcon demand sources - -# Test Parameters -``` - var adUnits = [ - { - bidder: 'outcon', - params: { - internalId: '12345678', - publisher: '5d5d66f2306ea4114a37c7c2', - bidId: '123456789', - env: 'test' - } - } - ]; -``` \ No newline at end of file diff --git a/modules/outconBidAdapter.js b/modules/outconBidAdapter.js deleted file mode 100644 index 0c3ac90172a..00000000000 --- a/modules/outconBidAdapter.js +++ /dev/null @@ -1,69 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'outcon'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: ['banner', 'video'], - isBidRequestValid: function(bid) { - return !!((bid.params.pod || (bid.params.internalId && bid.params.publisher)) && bid.params.env); - }, - buildRequests: function(validBidRequests) { - for (let i = 0; i < validBidRequests.length; i++) { - let url = ''; - let par = ''; - if (validBidRequests[i].params.pod != undefined) par = 'get?pod=' + validBidRequests[i].params.pod + '&bidId=' + validBidRequests[i].bidId; - else par = 'get?internalId=' + validBidRequests[i].params.internalId + '&publisher=' + validBidRequests[i].params.publisher + '&bidId=' + validBidRequests[i].bidId; - par = par + '&vast=true'; - switch (validBidRequests[i].params.env) { - case 'test': - par = par + '&demo=true'; - url = 'https://test.outcondigital.com/ad/' + par; - break; - case 'api': - url = 'https://api.outcondigital.com/ad/' + par; - break; - case 'stg': - url = 'https://stg.outcondigital.com/ad/' + par; - break; - } - return { - method: 'GET', - url: url, - data: {} - }; - } - }, - interpretResponse: function(serverResponse, bidRequest) { - const bidResponses = []; - const bidResponse = { - requestId: serverResponse.body.bidId, - cpm: serverResponse.body.cpm, - width: serverResponse.body.creatives[0].width, - height: serverResponse.body.creatives[0].height, - creativeId: serverResponse.body.creatives[0].id, - currency: serverResponse.body.cur, - netRevenue: true, - ttl: 300, - ad: wrapDisplayUrl(serverResponse.body.creatives[0].url, serverResponse.body.type), - vastImpUrl: serverResponse.body.trackingURL, - mediaType: serverResponse.body.type - }; - if (serverResponse.body.type == 'video') { - Object.assign(bidResponse, { - vastUrl: serverResponse.body.vastURL, - ttl: 3600 - }); - } - bidResponses.push(bidResponse); - return bidResponses; - }, -} - -function wrapDisplayUrl(displayUrl, type) { - if (type == 'video') return `
`; - if (type == 'banner') return `
`; - return null; -} - -registerBidder(spec); diff --git a/modules/ozoneBidAdapter.js b/modules/ozoneBidAdapter.js deleted file mode 100644 index 8ada9d59ae2..00000000000 --- a/modules/ozoneBidAdapter.js +++ /dev/null @@ -1,1088 +0,0 @@ -import * as utils 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 { Renderer } from '../src/Renderer.js'; -const BIDDER_CODE = 'ozone'; - -// *** PROD *** -const ORIGIN = 'https://elb.the-ozone-project.com' // applies only to auction & cookie -const AUCTIONURI = '/openrtb2/auction'; -const OZONECOOKIESYNC = '/static/load-cookie.html'; -const OZONE_RENDERER_URL = 'https://prebid.the-ozone-project.com/ozone-renderer.js'; - -const OZONEVERSION = '2.5.0'; -export const spec = { - gvlid: 524, - aliases: [{ code: 'lmc' }], - version: OZONEVERSION, - code: BIDDER_CODE, - supportedMediaTypes: [VIDEO, BANNER], - cookieSyncBag: {'publisherId': null, 'siteId': null, 'userIdObject': {}}, // variables we want to make available to cookie sync - propertyBag: {'pageId': null, 'buildRequestsStart': 0, 'buildRequestsEnd': 0}, /* allow us to store vars in instance scope - needs to be an object to be mutable */ - whitelabel_defaults: { - 'logId': 'OZONE', - 'bidder': 'ozone', - 'keyPrefix': 'oz', - 'auctionUrl': ORIGIN + AUCTIONURI, - 'cookieSyncUrl': ORIGIN + OZONECOOKIESYNC, - 'rendererUrl': OZONE_RENDERER_URL - }, - /** - * make sure that the whitelabel/default values are available in the propertyBag - * @param bid Object : the bid - */ - loadWhitelabelData(bid) { - if (this.propertyBag.whitelabel) { return; } - this.propertyBag.whitelabel = JSON.parse(JSON.stringify(this.whitelabel_defaults)); - let bidder = bid.bidder || 'ozone'; // eg. ozone - this.propertyBag.whitelabel.logId = bidder.toUpperCase(); - this.propertyBag.whitelabel.bidder = bidder; - let bidderConfig = config.getConfig(bidder) || {}; - if (bidderConfig.kvpPrefix) { - this.propertyBag.whitelabel.keyPrefix = bidderConfig.kvpPrefix; - } - if (bidderConfig.endpointOverride) { - if (bidderConfig.endpointOverride.origin) { - this.propertyBag.whitelabel.auctionUrl = bidderConfig.endpointOverride.origin + AUCTIONURI; - this.propertyBag.whitelabel.cookieSyncUrl = bidderConfig.endpointOverride.origin + OZONECOOKIESYNC; - } - if (bidderConfig.endpointOverride.rendererUrl) { - this.propertyBag.whitelabel.rendererUrl = bidderConfig.endpointOverride.rendererUrl; - } - } - this.logInfo('set propertyBag.whitelabel to', this.propertyBag.whitelabel); - }, - getAuctionUrl() { - return this.propertyBag.whitelabel.auctionUrl; - }, - getCookieSyncUrl() { - return this.propertyBag.whitelabel.cookieSyncUrl; - }, - getRendererUrl() { - return this.propertyBag.whitelabel.rendererUrl; - }, - /** - * wrappers for this.logInfo logWarn & logError, to add the proper prefix - */ - logInfo() { - if (!this.propertyBag.whitelabel) { return; } - let args = arguments; - args[0] = `${this.propertyBag.whitelabel.logId}: ${arguments[0]}`; - utils.logInfo.apply(this, args); - }, - logError() { - if (!this.propertyBag.whitelabel) { return; } - let args = arguments; - args[0] = `${this.propertyBag.whitelabel.logId}: ${arguments[0]}`; - utils.logError.apply(this, args); - }, - logWarn() { - if (!this.propertyBag.whitelabel) { return; } - let args = arguments; - args[0] = `${this.propertyBag.whitelabel.logId}: ${arguments[0]}`; - utils.logWarn.apply(this, args); - }, - /** - * Basic check to see whether required parameters are in the request. - * @param bid - * @returns {boolean} - */ - isBidRequestValid(bid) { - this.loadWhitelabelData(bid); - this.logInfo('isBidRequestValid : ', config.getConfig(), bid); - let adUnitCode = bid.adUnitCode; // adunit[n].code - - if (!(bid.params.hasOwnProperty('placementId'))) { - this.logError('BID ADAPTER VALIDATION FAILED : missing placementId : siteId, placementId and publisherId are REQUIRED', adUnitCode); - return false; - } - if (!this.isValidPlacementId(bid.params.placementId)) { - this.logError('BID ADAPTER VALIDATION FAILED : placementId must be exactly 10 numeric characters', adUnitCode); - return false; - } - if (!(bid.params.hasOwnProperty('publisherId'))) { - this.logError('BID ADAPTER VALIDATION FAILED : missing publisherId : siteId, placementId and publisherId are REQUIRED', adUnitCode); - return false; - } - if (!(bid.params.publisherId).toString().match(/^[a-zA-Z0-9\-]{12}$/)) { - this.logError('BID ADAPTER VALIDATION FAILED : publisherId must be exactly 12 alphanumieric characters including hyphens', adUnitCode); - return false; - } - if (!(bid.params.hasOwnProperty('siteId'))) { - this.logError('BID ADAPTER VALIDATION FAILED : missing siteId : siteId, placementId and publisherId are REQUIRED', adUnitCode); - return false; - } - if (!(bid.params.siteId).toString().match(/^[0-9]{10}$/)) { - this.logError('BID ADAPTER VALIDATION FAILED : siteId must be exactly 10 numeric characters', adUnitCode); - return false; - } - if (bid.params.hasOwnProperty('customParams')) { - this.logError('BID ADAPTER VALIDATION FAILED : customParams should be renamed to customData', adUnitCode); - return false; - } - if (bid.params.hasOwnProperty('customData')) { - if (!Array.isArray(bid.params.customData)) { - this.logError('BID ADAPTER VALIDATION FAILED : customData is not an Array', adUnitCode); - return false; - } - if (bid.params.customData.length < 1) { - this.logError('BID ADAPTER VALIDATION FAILED : customData is an array but does not contain any elements', adUnitCode); - return false; - } - if (!(bid.params.customData[0]).hasOwnProperty('targeting')) { - this.logError('BID ADAPTER VALIDATION FAILED : customData[0] does not contain "targeting"', adUnitCode); - return false; - } - if (typeof bid.params.customData[0]['targeting'] != 'object') { - this.logError('BID ADAPTER VALIDATION FAILED : customData[0] targeting is not an object', adUnitCode); - return false; - } - } - if (bid.hasOwnProperty('mediaTypes') && bid.mediaTypes.hasOwnProperty(VIDEO)) { - if (!bid.mediaTypes[VIDEO].hasOwnProperty('context')) { - this.logError('No video context key/value in bid. Rejecting bid: ', bid); - return false; - } - if (bid.mediaTypes[VIDEO].context !== 'instream' && bid.mediaTypes[VIDEO].context !== 'outstream') { - this.logError('video.context is invalid. Only instream/outstream video is supported. Rejecting bid: ', bid); - return false; - } - } - return true; - }, - - /** - * Split this out so that we can validate the placementId and also the override GET parameter ozstoredrequest - * @param placementId - */ - isValidPlacementId(placementId) { - return placementId.toString().match(/^[0-9]{10}$/); - }, - - buildRequests(validBidRequests, bidderRequest) { - this.loadWhitelabelData(validBidRequests[0]); - this.propertyBag.buildRequestsStart = new Date().getTime(); - let whitelabelBidder = this.propertyBag.whitelabel.bidder; // by default = ozone - let whitelabelPrefix = this.propertyBag.whitelabel.keyPrefix; - this.logInfo(`buildRequests time: ${this.propertyBag.buildRequestsStart} v ${OZONEVERSION} validBidRequests`, JSON.parse(JSON.stringify(validBidRequests)), 'bidderRequest', JSON.parse(JSON.stringify(bidderRequest))); - // First check - is there any config to block this request? - if (this.blockTheRequest()) { - return []; - } - let htmlParams = {'publisherId': '', 'siteId': ''}; - if (validBidRequests.length > 0) { - this.cookieSyncBag.userIdObject = Object.assign(this.cookieSyncBag.userIdObject, this.findAllUserIds(validBidRequests[0])); - this.cookieSyncBag.siteId = utils.deepAccess(validBidRequests[0], 'params.siteId'); - this.cookieSyncBag.publisherId = utils.deepAccess(validBidRequests[0], 'params.publisherId'); - htmlParams = validBidRequests[0].params; - } - this.logInfo('cookie sync bag', this.cookieSyncBag); - let singleRequest = this.getWhitelabelConfigItem('ozone.singleRequest'); - singleRequest = singleRequest !== false; // undefined & true will be true - this.logInfo(`config ${whitelabelBidder}.singleRequest : `, singleRequest); - let ozoneRequest = {}; // we only want to set specific properties on this, not validBidRequests[0].params - delete ozoneRequest.test; // don't allow test to be set in the config - ONLY use $_GET['pbjs_debug'] - - if (bidderRequest && bidderRequest.gdprConsent) { - this.logInfo('ADDING GDPR info'); - let apiVersion = bidderRequest.gdprConsent.apiVersion || '1'; - ozoneRequest.regs = {ext: {gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0, apiVersion: apiVersion}}; - if (ozoneRequest.regs.ext.gdpr) { - ozoneRequest.user = ozoneRequest.user || {}; - ozoneRequest.user.ext = {'consent': bidderRequest.gdprConsent.consentString}; - } else { - this.logInfo('**** Strange CMP info: bidderRequest.gdprConsent exists BUT bidderRequest.gdprConsent.gdprApplies is false. See bidderRequest logged above. ****'); - } - } else { - this.logInfo('WILL NOT ADD GDPR info; no bidderRequest.gdprConsent object was present.'); - } - const getParams = this.getGetParametersAsObject(); - const wlOztestmodeKey = whitelabelPrefix + 'testmode'; - const isTestMode = getParams[wlOztestmodeKey] || null; // this can be any string, it's used for testing ads - ozoneRequest.device = {'w': window.innerWidth, 'h': window.innerHeight}; - let placementIdOverrideFromGetParam = this.getPlacementIdOverrideFromGetParam(); // null or string - // build the array of params to attach to `imp` - let tosendtags = validBidRequests.map(ozoneBidRequest => { - var obj = {}; - let placementId = placementIdOverrideFromGetParam || this.getPlacementId(ozoneBidRequest); // prefer to use a valid override param, else the bidRequest placement Id - obj.id = ozoneBidRequest.bidId; // this causes an error if we change it to something else, even if you update the bidRequest object: "WARNING: Bidder ozone made bid for unknown request ID: mb7953.859498327448. Ignoring." - obj.tagid = placementId; - obj.secure = window.location.protocol === 'https:' ? 1 : 0; - // is there a banner (or nothing declared, so banner is the default)? - let arrBannerSizes = []; - if (!ozoneBidRequest.hasOwnProperty('mediaTypes')) { - if (ozoneBidRequest.hasOwnProperty('sizes')) { - this.logInfo('no mediaTypes detected - will use the sizes array in the config root'); - arrBannerSizes = ozoneBidRequest.sizes; - } else { - this.logInfo('no mediaTypes detected, no sizes array in the config root either. Cannot set sizes for banner type'); - } - } else { - if (ozoneBidRequest.mediaTypes.hasOwnProperty(BANNER)) { - arrBannerSizes = ozoneBidRequest.mediaTypes[BANNER].sizes; /* Note - if there is a sizes element in the config root it will be pushed into here */ - this.logInfo('setting banner size from the mediaTypes.banner element for bidId ' + obj.id + ': ', arrBannerSizes); - } - if (ozoneBidRequest.mediaTypes.hasOwnProperty(VIDEO)) { - this.logInfo('openrtb 2.5 compliant video'); - // examine all the video attributes in the config, and either put them into obj.video if allowed by IAB2.5 or else in to obj.video.ext - if (typeof ozoneBidRequest.mediaTypes[VIDEO] == 'object') { - let childConfig = utils.deepAccess(ozoneBidRequest, 'params.video', {}); - obj.video = this.unpackVideoConfigIntoIABformat(ozoneBidRequest.mediaTypes[VIDEO], childConfig); - obj.video = this.addVideoDefaults(obj.video, ozoneBidRequest.mediaTypes[VIDEO], childConfig); - } - // we need to duplicate some of the video values - let wh = getWidthAndHeightFromVideoObject(obj.video); - this.logInfo('setting video object from the mediaTypes.video element: ' + obj.id + ':', obj.video, 'wh=', wh); - if (wh && typeof wh === 'object') { - obj.video.w = wh['w']; - obj.video.h = wh['h']; - if (playerSizeIsNestedArray(obj.video)) { // this should never happen; it was in the original spec for this change though. - this.logInfo('setting obj.video.format to be an array of objects'); - obj.video.ext.format = [wh]; - } else { - this.logInfo('setting obj.video.format to be an object'); - obj.video.ext.format = wh; - } - } else { - this.logWarn('cannot set w, h & format values for video; the config is not right'); - } - } - // Native integration is not complete yet - if (ozoneBidRequest.mediaTypes.hasOwnProperty(NATIVE)) { - obj.native = ozoneBidRequest.mediaTypes[NATIVE]; - this.logInfo('setting native object from the mediaTypes.native element: ' + obj.id + ':', obj.native); - } - } - if (arrBannerSizes.length > 0) { - // build the banner request using banner sizes we found in either possible location: - obj.banner = { - topframe: 1, - w: arrBannerSizes[0][0] || 0, - h: arrBannerSizes[0][1] || 0, - format: arrBannerSizes.map(s => { - return {w: s[0], h: s[1]}; - }) - }; - } - // these 3 MUST exist - we check them in the validation method - obj.placementId = placementId; - // build the imp['ext'] object - obj.ext = {'prebid': {'storedrequest': {'id': placementId}}}; - obj.ext[whitelabelBidder] = {}; - obj.ext[whitelabelBidder].adUnitCode = ozoneBidRequest.adUnitCode; // eg. 'mpu' - obj.ext[whitelabelBidder].transactionId = ozoneBidRequest.transactionId; // this is the transactionId PER adUnit, common across bidders for this unit - if (ozoneBidRequest.params.hasOwnProperty('customData')) { - obj.ext[whitelabelBidder].customData = ozoneBidRequest.params.customData; - } - this.logInfo(`obj.ext.${whitelabelBidder} is `, obj.ext[whitelabelBidder]); - if (isTestMode != null) { - this.logInfo('setting isTestMode to ', isTestMode); - if (obj.ext[whitelabelBidder].hasOwnProperty('customData')) { - for (let i = 0; i < obj.ext[whitelabelBidder].customData.length; i++) { - obj.ext[whitelabelBidder].customData[i]['targeting'][wlOztestmodeKey] = isTestMode; - } - } else { - obj.ext[whitelabelBidder].customData = [{'settings': {}, 'targeting': {}}]; - obj.ext[whitelabelBidder].customData[0].targeting[wlOztestmodeKey] = isTestMode; - } - } - return obj; - }); - - // in v 2.0.0 we moved these outside of the individual ad slots - let extObj = {}; - extObj[whitelabelBidder] = {}; - extObj[whitelabelBidder][whitelabelPrefix + '_pb_v'] = OZONEVERSION; - extObj[whitelabelBidder][whitelabelPrefix + '_rw'] = placementIdOverrideFromGetParam ? 1 : 0; - if (validBidRequests.length > 0) { - let userIds = this.cookieSyncBag.userIdObject; // 2021-01-06 - slight optimisation - we've already found this info - // let userIds = this.findAllUserIds(validBidRequests[0]); - if (userIds.hasOwnProperty('pubcid')) { - extObj[whitelabelBidder].pubcid = userIds.pubcid; - } - } - extObj[whitelabelBidder].pv = this.getPageId(); // attach the page ID that will be common to all auciton calls for this page if refresh() is called - let ozOmpFloorDollars = this.getWhitelabelConfigItem('ozone.oz_omp_floor'); // valid only if a dollar value (typeof == 'number') - this.logInfo(`${whitelabelPrefix}_omp_floor dollar value = `, ozOmpFloorDollars); - if (typeof ozOmpFloorDollars === 'number') { - extObj[whitelabelBidder][whitelabelPrefix + '_omp_floor'] = ozOmpFloorDollars; - } else if (typeof ozOmpFloorDollars !== 'undefined') { - this.logError(`${whitelabelPrefix}_omp_floor is invalid - IF SET then this must be a number, representing dollar value eg. ${whitelabelPrefix}_omp_floor: 1.55. You have it set as a ` + (typeof ozOmpFloorDollars)); - } - let ozWhitelistAdserverKeys = this.getWhitelabelConfigItem('ozone.oz_whitelist_adserver_keys'); - let useOzWhitelistAdserverKeys = utils.isArray(ozWhitelistAdserverKeys) && ozWhitelistAdserverKeys.length > 0; - extObj[whitelabelBidder][whitelabelPrefix + '_kvp_rw'] = useOzWhitelistAdserverKeys ? 1 : 0; - if (whitelabelBidder != 'ozone') { - this.logInfo('setting aliases object'); - extObj.prebid = {aliases: {'ozone': whitelabelBidder}}; - } - - var userExtEids = this.generateEids(validBidRequests); // generate the UserIDs in the correct format for UserId module - - ozoneRequest.site = { - 'publisher': {'id': htmlParams.publisherId}, - 'page': document.location.href, - 'id': htmlParams.siteId - }; - ozoneRequest.test = (getParams.hasOwnProperty('pbjs_debug') && getParams['pbjs_debug'] === 'true') ? 1 : 0; - - // this is for 2.2.1 - // coppa compliance - if (config.getConfig('coppa') === true) { - utils.deepSetValue(ozoneRequest, 'regs.coppa', 1); - } - - // return the single request object OR the array: - if (singleRequest) { - this.logInfo('buildRequests starting to generate response for a single request'); - ozoneRequest.id = bidderRequest.auctionId; // Unique ID of the bid request, provided by the exchange. - ozoneRequest.auctionId = bidderRequest.auctionId; // not sure if this should be here? - ozoneRequest.imp = tosendtags; - ozoneRequest.ext = extObj; - ozoneRequest.source = {'tid': bidderRequest.auctionId}; // RTB 2.5 : tid is Transaction ID that must be common across all participants in this bid request (e.g., potentially multiple exchanges). - utils.deepSetValue(ozoneRequest, 'user.ext.eids', userExtEids); - var ret = { - method: 'POST', - url: this.getAuctionUrl(), - data: JSON.stringify(ozoneRequest), - bidderRequest: bidderRequest - }; - this.logInfo('buildRequests request data for single = ', ozoneRequest); - this.propertyBag.buildRequestsEnd = new Date().getTime(); - this.logInfo(`buildRequests going to return for single at time ${this.propertyBag.buildRequestsEnd} (took ${this.propertyBag.buildRequestsEnd - this.propertyBag.buildRequestsStart}ms): `, ret); - return ret; - } - // not single request - pull apart the tosendtags array & return an array of objects each containing one element in the imp array. - let arrRet = tosendtags.map(imp => { - this.logInfo('buildRequests starting to generate non-single response, working on imp : ', imp); - let ozoneRequestSingle = Object.assign({}, ozoneRequest); - imp.ext[whitelabelBidder].pageAuctionId = bidderRequest['auctionId']; // make a note in the ext object of what the original auctionId was, in the bidderRequest object - ozoneRequestSingle.id = imp.ext[whitelabelBidder].transactionId; // Unique ID of the bid request, provided by the exchange. - ozoneRequestSingle.auctionId = imp.ext[whitelabelBidder].transactionId; // not sure if this should be here? - ozoneRequestSingle.imp = [imp]; - ozoneRequestSingle.ext = extObj; - ozoneRequestSingle.source = {'tid': imp.ext[whitelabelBidder].transactionId}; - utils.deepSetValue(ozoneRequestSingle, 'user.ext.eids', userExtEids); - this.logInfo('buildRequests RequestSingle (for non-single) = ', ozoneRequestSingle); - return { - method: 'POST', - url: this.getAuctionUrl(), - data: JSON.stringify(ozoneRequestSingle), - bidderRequest: bidderRequest - }; - }); - this.propertyBag.buildRequestsEnd = new Date().getTime(); - this.logInfo(`buildRequests going to return for non-single at time ${this.propertyBag.buildRequestsEnd} (took ${this.propertyBag.buildRequestsEnd - this.propertyBag.buildRequestsStart}ms): `, arrRet); - return arrRet; - }, - /** - * Interpret the response if the array contains BIDDER elements, in the format: [ [bidder1 bid 1, bidder1 bid 2], [bidder2 bid 1, bidder2 bid 2] ] - * NOte that in singleRequest mode this will be called once, else it will be called for each adSlot's response - * - * Updated April 2019 to return all bids, not just the one we decide is the 'winner' - * - * @param serverResponse - * @param request - * @returns {*} - */ - interpretResponse(serverResponse, request) { - if (request && request.bidderRequest && request.bidderRequest.bids) { this.loadWhitelabelData(request.bidderRequest.bids[0]); } - let startTime = new Date().getTime(); - let whitelabelBidder = this.propertyBag.whitelabel.bidder; // by default = ozone - let whitelabelPrefix = this.propertyBag.whitelabel.keyPrefix; - this.logInfo(`interpretResponse time: ${startTime} . Time between buildRequests done and interpretResponse start was ${startTime - this.propertyBag.buildRequestsEnd}ms`); - this.logInfo(`serverResponse, request`, JSON.parse(JSON.stringify(serverResponse)), JSON.parse(JSON.stringify(request))); - serverResponse = serverResponse.body || {}; - // note that serverResponse.id value is the auction_id we might want to use for reporting reasons. - if (!serverResponse.hasOwnProperty('seatbid')) { - return []; - } - if (typeof serverResponse.seatbid !== 'object') { - return []; - } - let arrAllBids = []; - let enhancedAdserverTargeting = this.getWhitelabelConfigItem('ozone.enhancedAdserverTargeting'); - this.logInfo('enhancedAdserverTargeting', enhancedAdserverTargeting); - if (typeof enhancedAdserverTargeting == 'undefined') { - enhancedAdserverTargeting = true; - } - this.logInfo('enhancedAdserverTargeting', enhancedAdserverTargeting); - serverResponse.seatbid = injectAdIdsIntoAllBidResponses(serverResponse.seatbid); // we now make sure that each bid in the bidresponse has a unique (within page) adId attribute. - serverResponse.seatbid = this.removeSingleBidderMultipleBids(serverResponse.seatbid); - let ozOmpFloorDollars = this.getWhitelabelConfigItem('ozone.oz_omp_floor'); // valid only if a dollar value (typeof == 'number') - let addOzOmpFloorDollars = typeof ozOmpFloorDollars === 'number'; - let ozWhitelistAdserverKeys = this.getWhitelabelConfigItem('ozone.oz_whitelist_adserver_keys'); - let useOzWhitelistAdserverKeys = utils.isArray(ozWhitelistAdserverKeys) && ozWhitelistAdserverKeys.length > 0; - - for (let i = 0; i < serverResponse.seatbid.length; i++) { - let sb = serverResponse.seatbid[i]; - for (let j = 0; j < sb.bid.length; j++) { - let thisRequestBid = this.getBidRequestForBidId(sb.bid[j].impid, request.bidderRequest.bids); - this.logInfo(`seatbid:${i}, bid:${j} Going to set default w h for seatbid/bidRequest`, sb.bid[j], thisRequestBid); - const {defaultWidth, defaultHeight} = defaultSize(thisRequestBid); - let thisBid = ozoneAddStandardProperties(sb.bid[j], defaultWidth, defaultHeight); - let videoContext = null; - let isVideo = false; - let bidType = utils.deepAccess(thisBid, 'ext.prebid.type'); - this.logInfo(`this bid type is : ${bidType}`, j); - if (bidType === VIDEO) { - isVideo = true; - videoContext = this.getVideoContextForBidId(thisBid.bidId, request.bidderRequest.bids); // should be instream or outstream (or null if error) - if (videoContext === 'outstream') { - this.logInfo('going to attach a renderer to OUTSTREAM video : ', j); - thisBid.renderer = newRenderer(thisBid.bidId); - } else { - this.logInfo('bid is not an outstream video, will not attach a renderer: ', j); - } - } - let adserverTargeting = {}; - if (enhancedAdserverTargeting) { - let allBidsForThisBidid = ozoneGetAllBidsForBidId(thisBid.bidId, serverResponse.seatbid); - // add all the winning & non-winning bids for this bidId: - this.logInfo('Going to iterate allBidsForThisBidId', allBidsForThisBidid); - Object.keys(allBidsForThisBidid).forEach((bidderName, index, ar2) => { - this.logInfo(`adding adserverTargeting for ${bidderName} for bidId ${thisBid.bidId}`); - // let bidderName = bidderNameWH.split('_')[0]; - adserverTargeting[whitelabelPrefix + '_' + bidderName] = bidderName; - adserverTargeting[whitelabelPrefix + '_' + bidderName + '_crid'] = String(allBidsForThisBidid[bidderName].crid); - adserverTargeting[whitelabelPrefix + '_' + bidderName + '_adv'] = String(allBidsForThisBidid[bidderName].adomain); - adserverTargeting[whitelabelPrefix + '_' + bidderName + '_adId'] = String(allBidsForThisBidid[bidderName].adId); - adserverTargeting[whitelabelPrefix + '_' + bidderName + '_pb_r'] = getRoundedBid(allBidsForThisBidid[bidderName].price, allBidsForThisBidid[bidderName].ext.prebid.type); - if (allBidsForThisBidid[bidderName].hasOwnProperty('dealid')) { - adserverTargeting[whitelabelPrefix + '_' + bidderName + '_dealid'] = String(allBidsForThisBidid[bidderName].dealid); - } - if (addOzOmpFloorDollars) { - adserverTargeting[whitelabelPrefix + '_' + bidderName + '_omp'] = allBidsForThisBidid[bidderName].price >= ozOmpFloorDollars ? '1' : '0'; - } - if (isVideo) { - adserverTargeting[whitelabelPrefix + '_' + bidderName + '_vid'] = videoContext; // outstream or instream - } - let flr = utils.deepAccess(allBidsForThisBidid[bidderName], `ext.bidder.${whitelabelBidder}.floor`, null); - if (flr != null) { - adserverTargeting[whitelabelPrefix + '_' + bidderName + '_flr'] = flr; - } - let rid = utils.deepAccess(allBidsForThisBidid[bidderName], `ext.bidder.${whitelabelBidder}.ruleId`, null); - if (rid != null) { - adserverTargeting[whitelabelPrefix + '_' + bidderName + '_rid'] = rid; - } - if (bidderName.match(/^ozappnexus/)) { - adserverTargeting[whitelabelPrefix + '_' + bidderName + '_sid'] = String(allBidsForThisBidid[bidderName].cid); - } - }); - } else { - if (useOzWhitelistAdserverKeys) { - this.logWarn(`You have set a whitelist of adserver keys but this will be ignored because ${whitelabelBidder}.enhancedAdserverTargeting is set to false. No per-bid keys will be sent to adserver.`); - } else { - this.logInfo(`${whitelabelBidder}.enhancedAdserverTargeting is set to false, so no per-bid keys will be sent to adserver.`); - } - } - // also add in the winning bid, to be sent to dfp - let {seat: winningSeat, bid: winningBid} = ozoneGetWinnerForRequestBid(thisBid.bidId, serverResponse.seatbid); - adserverTargeting[whitelabelPrefix + '_auc_id'] = String(request.bidderRequest.auctionId); - adserverTargeting[whitelabelPrefix + '_winner'] = String(winningSeat); - if (enhancedAdserverTargeting) { - adserverTargeting[whitelabelPrefix + '_imp_id'] = String(winningBid.impid); - adserverTargeting[whitelabelPrefix + '_pb_v'] = OZONEVERSION; - } - if (useOzWhitelistAdserverKeys) { // delete any un-whitelisted keys - this.logInfo('Going to filter out adserver targeting keys not in the whitelist: ', ozWhitelistAdserverKeys); - Object.keys(adserverTargeting).forEach(function(key) { if (ozWhitelistAdserverKeys.indexOf(key) === -1) { delete adserverTargeting[key]; } }); - } - thisBid.adserverTargeting = adserverTargeting; - arrAllBids.push(thisBid); - } - } - let endTime = new Date().getTime(); - this.logInfo(`interpretResponse going to return at time ${endTime} (took ${endTime - startTime}ms) Time from buildRequests Start -> interpretRequests End = ${endTime - this.propertyBag.buildRequestsStart}ms`, arrAllBids); - return arrAllBids; - }, - /** - * Use this to get all config values - * Now it's getting complicated with whitelabeling, this simplifies the code for getting config values. - * eg. to get ozone.oz_omp_floor you just send '_omp_floor' - * @param ozoneVersion string like 'ozone.oz_omp_floor' - * @return {string|object} - */ - getWhitelabelConfigItem(ozoneVersion) { - if (this.propertyBag.whitelabel.bidder == 'ozone') { return config.getConfig(ozoneVersion); } - let whitelabelledSearch = ozoneVersion.replace('ozone', this.propertyBag.whitelabel.bidder); - whitelabelledSearch = ozoneVersion.replace('oz_', this.propertyBag.whitelabel.keyPrefix + '_'); - return config.getConfig(whitelabelledSearch); - }, - /** - * If a bidder bids for > 1 size for an adslot, allow only the highest bid - * @param seatbid object (serverResponse.seatbid) - */ - removeSingleBidderMultipleBids(seatbid) { - var ret = []; - for (let i = 0; i < seatbid.length; i++) { - let sb = seatbid[i]; - var retSeatbid = {'seat': sb.seat, 'bid': []}; - var bidIds = []; - for (let j = 0; j < sb.bid.length; j++) { - var candidate = sb.bid[j]; - if (utils.contains(bidIds, candidate.impid)) { - continue; // we've already fully assessed this impid, found the highest bid from this seat for it - } - bidIds.push(candidate.impid); - for (let k = j + 1; k < sb.bid.length; k++) { - if (sb.bid[k].impid === candidate.impid && sb.bid[k].price > candidate.price) { - candidate = sb.bid[k]; - } - } - retSeatbid.bid.push(candidate); - } - ret.push(retSeatbid); - } - return ret; - }, - // see http://prebid.org/dev-docs/bidder-adaptor.html#registering-user-syncs - getUserSyncs(optionsType, serverResponse, gdprConsent) { - this.logInfo('getUserSyncs optionsType, serverResponse, gdprConsent, cookieSyncBag', optionsType, serverResponse, gdprConsent, this.cookieSyncBag); - if (!serverResponse || serverResponse.length === 0) { - return []; - } - if (optionsType.iframeEnabled) { - var arrQueryString = []; - if (document.location.search.match(/pbjs_debug=true/)) { - arrQueryString.push('pbjs_debug=true'); - } - arrQueryString.push('gdpr=' + (utils.deepAccess(gdprConsent, 'gdprApplies', false) ? '1' : '0')); - arrQueryString.push('gdpr_consent=' + utils.deepAccess(gdprConsent, 'consentString', '')); - var objKeys = Object.getOwnPropertyNames(this.cookieSyncBag.userIdObject); - for (let idx in objKeys) { - let keyname = objKeys[idx]; - arrQueryString.push(keyname + '=' + this.cookieSyncBag.userIdObject[keyname]); - } - arrQueryString.push('publisherId=' + this.cookieSyncBag.publisherId); - arrQueryString.push('siteId=' + this.cookieSyncBag.siteId); - arrQueryString.push('cb=' + Date.now()); - arrQueryString.push('bidder=' + this.propertyBag.whitelabel.bidder); - - var strQueryString = arrQueryString.join('&'); - if (strQueryString.length > 0) { - strQueryString = '?' + strQueryString; - } - this.logInfo('getUserSyncs going to return cookie sync url : ' + this.getCookieSyncUrl() + strQueryString); - return [{ - type: 'iframe', - url: this.getCookieSyncUrl() + strQueryString - }]; - } - }, - /** - * Find the bid matching the bidId in the request object - * get instream or outstream if this was a video request else null - * @return object|null - */ - getBidRequestForBidId(bidId, arrBids) { - for (let i = 0; i < arrBids.length; i++) { - if (arrBids[i].bidId === bidId) { // bidId in the request comes back as impid in the seatbid bids - return arrBids[i]; - } - } - return null; - }, - /** - * Locate the bid inside the arrBids for this bidId, then discover the video context, and return it. - * IF the bid cannot be found return null, else return a string. - * @param bidId - * @param arrBids - * @return string|null - */ - getVideoContextForBidId(bidId, arrBids) { - let requestBid = this.getBidRequestForBidId(bidId, arrBids); - if (requestBid != null) { - return utils.deepAccess(requestBid, 'mediaTypes.video.context', 'unknown') - } - return null; - }, - /** - * Look for pubcid & all the other IDs according to http://prebid.org/dev-docs/modules/userId.html - * NOTE that criteortus is deprecated & should be removed asap - * @return map - */ - findAllUserIds(bidRequest) { - var ret = {}; - // @todo - what is fabrick called & where to look for it? If it's a simple value then it will automatically be ok - let searchKeysSingle = ['pubcid', 'tdid', 'id5id', 'parrableId', 'idl_env', 'criteoId', 'criteortus', - 'sharedid', 'lotamePanoramaId', 'fabrickId']; - if (bidRequest.hasOwnProperty('userId')) { - for (let arrayId in searchKeysSingle) { - let key = searchKeysSingle[arrayId]; - if (bidRequest.userId.hasOwnProperty(key)) { - if (typeof (bidRequest.userId[key]) == 'string') { - ret[key] = bidRequest.userId[key]; - } else if (typeof (bidRequest.userId[key]) == 'object') { - ret[key] = bidRequest.userId[key][Object.keys(bidRequest.userId[key])[0]]; // cannot use Object.values - } else { - this.logError(`failed to get string key value for userId : ${key}`); - } - } - } - var lipbid = utils.deepAccess(bidRequest.userId, 'lipb.lipbid'); - if (lipbid) { - ret['lipb'] = {'lipbid': lipbid}; - } - } - if (!ret.hasOwnProperty('pubcid')) { - var pubcid = utils.deepAccess(bidRequest, 'crumbs.pubcid'); - if (pubcid) { - ret['pubcid'] = pubcid; // if built with old pubCommonId module - } - } - return ret; - }, - /** - * Convenient method to get the value we need for the placementId - ONLY from the bidRequest - NOT taking into account any GET override ID - * @param bidRequest - * @return string - */ - getPlacementId(bidRequest) { - return (bidRequest.params.placementId).toString(); - }, - /** - * GET parameter introduced in 2.2.0 : ozstoredrequest - * IF the GET parameter exists then it must validate for placementId correctly - * IF there's a $_GET['ozstoredrequest'] & it's valid then return this. Else return null. - * @returns null|string - */ - getPlacementIdOverrideFromGetParam() { - let whitelabelPrefix = this.propertyBag.whitelabel.keyPrefix; - let arr = this.getGetParametersAsObject(); - if (arr.hasOwnProperty(whitelabelPrefix + 'storedrequest')) { - if (this.isValidPlacementId(arr[whitelabelPrefix + 'storedrequest'])) { - this.logInfo(`using GET ${whitelabelPrefix}storedrequest ` + arr[whitelabelPrefix + 'storedrequest'] + ' to replace placementId'); - return arr[whitelabelPrefix + 'storedrequest']; - } else { - this.logError(`GET ${whitelabelPrefix}storedrequest FAILED VALIDATION - will not use it`); - } - } - return null; - }, - /** - * Generate an object we can append to the auction request, containing user data formatted correctly for different ssps - * http://prebid.org/dev-docs/modules/userId.html - * @param validBidRequests - * @return {Array} - */ - generateEids(validBidRequests) { - let eids; - const bidRequest = validBidRequests[0]; - if (bidRequest && bidRequest.userId) { - eids = bidRequest.userIdAsEids; - this.handleTTDId(eids, validBidRequests); - } - return eids; - }, - handleTTDId(eids, validBidRequests) { - let ttdId = null; - let adsrvrOrgId = config.getConfig('adsrvrOrgId'); - if (utils.isStr(utils.deepAccess(validBidRequests, '0.userId.tdid'))) { - ttdId = validBidRequests[0].userId.tdid; - } else if (adsrvrOrgId && utils.isStr(adsrvrOrgId.TDID)) { - ttdId = adsrvrOrgId.TDID; - } - if (ttdId !== null) { - eids.push({ - 'source': 'adserver.org', - 'uids': [{ - 'id': ttdId, - 'atype': 1, - 'ext': { - 'rtiPartner': 'TDID' - } - }] - }); - } - }, - // Try to use this as the mechanism for reading GET params because it's easy to mock it for tests - getGetParametersAsObject() { - let items = location.search.substr(1).split('&'); - let ret = {}; - let tmp = null; - for (let index = 0; index < items.length; index++) { - tmp = items[index].split('='); - ret[tmp[0]] = tmp[1]; - } - return ret; - }, - /** - * Do we have to block this request? Could be due to config values (no longer checking gdpr) - * @return {boolean|*[]} true = block the request, else false - */ - blockTheRequest() { - // if there is an ozone.oz_request = false then quit now. - let ozRequest = this.getWhitelabelConfigItem('ozone.oz_request'); - if (typeof ozRequest == 'boolean' && !ozRequest) { - this.logWarn(`Will not allow auction : ${this.propertyBag.whitelabel.keyPrefix}one.${this.propertyBag.whitelabel.keyPrefix}_request is set to false`); - return true; - } - return false; - }, - /** - * This returns a random ID for this page. It starts off with the current ms timestamp then appends a random component - * @return {string} - */ - getPageId: function() { - if (this.propertyBag.pageId == null) { - let randPart = ''; - let allowable = '0123456789abcdefghijklmnopqrstuvwxyz'; - for (let i = 20; i > 0; i--) { - randPart += allowable[Math.floor(Math.random() * 36)]; - } - this.propertyBag.pageId = new Date().getTime() + '_' + randPart; - } - return this.propertyBag.pageId; - }, - unpackVideoConfigIntoIABformat(videoConfig, childConfig) { - let ret = {'ext': {}}; - ret = this._unpackVideoConfigIntoIABformat(ret, videoConfig); - ret = this._unpackVideoConfigIntoIABformat(ret, childConfig); - return ret; - }, - /** - * - * look in ONE object to get video config (we need to call this multiple times, so child settings override parent) - * @param ret - * @param objConfig - * @return {*} - * @private - */ - _unpackVideoConfigIntoIABformat(ret, objConfig) { - let arrVideoKeysAllowed = ['mimes', 'minduration', 'maxduration', 'protocols', 'w', 'h', 'startdelay', 'placement', 'linearity', 'skip', 'skipmin', 'skipafter', 'sequence', 'battr', 'maxextended', 'minbitrate', 'maxbitrate', 'boxingallowed', 'playbackmethod', 'playbackend', 'delivery', 'pos', 'companionad', 'api', 'companiontype']; - for (const key in objConfig) { - var found = false; - arrVideoKeysAllowed.forEach(function(arg) { - if (arg === key) { - ret[key] = objConfig[key]; - found = true; - } - }); - if (!found) { - ret.ext[key] = objConfig[key]; - } - } - // handle ext separately, if it exists; we have probably built up an ext object already - if (objConfig.hasOwnProperty('ext') && typeof objConfig.ext === 'object') { - if (objConfig.hasOwnProperty('ext')) { - ret.ext = utils.mergeDeep(ret.ext, objConfig.ext); - } else { - ret.ext = objConfig.ext; - } - } - return ret; - }, - addVideoDefaults(objRet, videoConfig, childConfig) { - objRet = this._addVideoDefaults(objRet, videoConfig, false); - objRet = this._addVideoDefaults(objRet, childConfig, true); // child config will override parent config - return objRet; - }, - /** - * modify objRet, adding in default values - * @param objRet - * @param objConfig - * @param addIfMissing - * @return {*} - * @private - */ - _addVideoDefaults(objRet, objConfig, addIfMissing) { - // add inferred values & any default values we want. - let context = utils.deepAccess(objConfig, 'context'); - if (context === 'outstream') { - objRet.placement = 3; - } else if (context === 'instream') { - objRet.placement = 1; - } - let skippable = utils.deepAccess(objConfig, 'skippable', null); - if (skippable == null) { - if (addIfMissing && !objRet.hasOwnProperty('skip')) { - objRet.skip = skippable ? 1 : 0; - } - } else { - objRet.skip = skippable ? 1 : 0; - } - return objRet; - } -}; - -/** - * add a page-level-unique adId element to all server response bids. - * NOTE that this is destructive - it mutates the serverResponse object sent in as a parameter - * @param seatbid object (serverResponse.seatbid) - * @returns seatbid object - */ -export function injectAdIdsIntoAllBidResponses(seatbid) { - spec.logInfo('injectAdIdsIntoAllBidResponses', seatbid); - for (let i = 0; i < seatbid.length; i++) { - let sb = seatbid[i]; - for (let j = 0; j < sb.bid.length; j++) { - // modify the bidId per-bid, so each bid has a unique adId within this response, and dfp can select one. - // 2020-06 we now need a second level of ID because there might be multiple identical impid's within a seatbid! - sb.bid[j]['adId'] = `${sb.bid[j]['impid']}-${i}-${j}`; - } - } - return seatbid; -} - -export function checkDeepArray(Arr) { - if (Array.isArray(Arr)) { - if (Array.isArray(Arr[0])) { - return Arr[0]; - } else { - return Arr; - } - } else { - return Arr; - } -} - -export function defaultSize(thebidObj) { - if (!thebidObj) { - spec.logInfo('defaultSize received empty bid obj! going to return fixed default size'); - return { - 'defaultHeight': 250, - 'defaultWidth': 300 - }; - } - const {sizes} = thebidObj; - const returnObject = {}; - returnObject.defaultWidth = checkDeepArray(sizes)[0]; - returnObject.defaultHeight = checkDeepArray(sizes)[1]; - return returnObject; -} - -/** - * Do the messy searching for the best bid response in the serverResponse.seatbid array matching the requestBid.bidId - * @param requestBid - * @param serverResponseSeatBid - * @returns {*} bid object - */ -export function ozoneGetWinnerForRequestBid(requestBidId, serverResponseSeatBid) { - let thisBidWinner = null; - let winningSeat = null; - for (let j = 0; j < serverResponseSeatBid.length; j++) { - let theseBids = serverResponseSeatBid[j].bid; - let thisSeat = serverResponseSeatBid[j].seat; - for (let k = 0; k < theseBids.length; k++) { - if (theseBids[k].impid === requestBidId) { - // we've found a matching server response bid for this request bid - if ((thisBidWinner == null) || (thisBidWinner.price < theseBids[k].price)) { - thisBidWinner = theseBids[k]; - winningSeat = thisSeat; - break; - } - } - } - } - return {'seat': winningSeat, 'bid': thisBidWinner}; -} - -/** - * Get a list of all the bids, for this bidId. The keys in the response object will be {seatname} OR {seatname}{w}x{h} if seatname already exists - * @param matchBidId - * @param serverResponseSeatBid - * @returns {} = {ozone|320x600:{obj}, ozone|320x250:{obj}, appnexus|300x250:{obj}, ... } - */ -export function ozoneGetAllBidsForBidId(matchBidId, serverResponseSeatBid) { - let objBids = {}; - for (let j = 0; j < serverResponseSeatBid.length; j++) { - let theseBids = serverResponseSeatBid[j].bid; - let thisSeat = serverResponseSeatBid[j].seat; - for (let k = 0; k < theseBids.length; k++) { - if (theseBids[k].impid === matchBidId) { - if (objBids.hasOwnProperty(thisSeat)) { // > 1 bid for an adunit from a bidder - only use the one with the highest bid - // objBids[`${thisSeat}${theseBids[k].w}x${theseBids[k].h}`] = theseBids[k]; - if (objBids[thisSeat]['price'] < theseBids[k].price) { - objBids[thisSeat] = theseBids[k]; - } - } else { - objBids[thisSeat] = theseBids[k]; - } - } - } - } - return objBids; -} - -/** - * Round the bid price down according to the granularity - * @param price - * @param mediaType = video, banner or native - */ -export function getRoundedBid(price, mediaType) { - const mediaTypeGranularity = config.getConfig(`mediaTypePriceGranularity.${mediaType}`); // might be string or object or nothing; if set then this takes precedence over 'priceGranularity' - let objBuckets = config.getConfig('customPriceBucket'); // this is always an object - {} if strBuckets is not 'custom' - let strBuckets = config.getConfig('priceGranularity'); // priceGranularity value, always a string ** if priceGranularity is set to an object then it's always 'custom' ** - let theConfigObject = getGranularityObject(mediaType, mediaTypeGranularity, strBuckets, objBuckets); - let theConfigKey = getGranularityKeyName(mediaType, mediaTypeGranularity, strBuckets); - - spec.logInfo('getRoundedBid. price:', price, 'mediaType:', mediaType, 'configkey:', theConfigKey, 'configObject:', theConfigObject, 'mediaTypeGranularity:', mediaTypeGranularity, 'strBuckets:', strBuckets); - - let priceStringsObj = getPriceBucketString( - price, - theConfigObject, - config.getConfig('currency.granularityMultiplier') - ); - spec.logInfo('priceStringsObj', priceStringsObj); - // by default, without any custom granularity set, you get granularity name : 'medium' - let granularityNamePriceStringsKeyMapping = { - 'medium': 'med', - 'custom': 'custom', - 'high': 'high', - 'low': 'low', - 'dense': 'dense' - }; - if (granularityNamePriceStringsKeyMapping.hasOwnProperty(theConfigKey)) { - let priceStringsKey = granularityNamePriceStringsKeyMapping[theConfigKey]; - spec.logInfo('getRoundedBid: looking for priceStringsKey:', priceStringsKey); - return priceStringsObj[priceStringsKey]; - } - return priceStringsObj['auto']; -} - -/** - * return the key to use to get the value out of the priceStrings object, taking into account anything at - * config.priceGranularity level or config.mediaType.xxx level - * I've noticed that the key specified by prebid core : config.getConfig('priceGranularity') does not properly - * take into account the 2-levels of config - */ -export function getGranularityKeyName(mediaType, mediaTypeGranularity, strBuckets) { - if (typeof mediaTypeGranularity === 'string') { - return mediaTypeGranularity; - } - if (typeof mediaTypeGranularity === 'object') { - return 'custom'; - } - if (typeof strBuckets === 'string') { - return strBuckets; - } - return 'auto'; // fall back to a default key - should literally never be needed. -} - -/** - * return the object to use to create the custom value of the priceStrings object, taking into account anything at - * config.priceGranularity level or config.mediaType.xxx level - */ -export function getGranularityObject(mediaType, mediaTypeGranularity, strBuckets, objBuckets) { - if (typeof mediaTypeGranularity === 'object') { - return mediaTypeGranularity; - } - if (strBuckets === 'custom') { - return objBuckets; - } - return ''; -} - -/** - * We expect to be able to find a standard set of properties on winning bid objects; add them here. - * @param seatBid - * @returns {*} - */ -export function ozoneAddStandardProperties(seatBid, defaultWidth, defaultHeight) { - seatBid.cpm = seatBid.price; - seatBid.bidId = seatBid.impid; - seatBid.requestId = seatBid.impid; - seatBid.width = seatBid.w || defaultWidth; - seatBid.height = seatBid.h || defaultHeight; - seatBid.ad = seatBid.adm; - seatBid.netRevenue = true; - seatBid.creativeId = seatBid.crid; - seatBid.currency = 'USD'; - seatBid.ttl = 300; - return seatBid; -} - -/** - * - * @param objVideo will be like {"playerSize":[640,480],"mimes":["video/mp4"],"context":"outstream"} or POSSIBLY {"playerSize":[[640,480]],"mimes":["video/mp4"],"context":"outstream"} - * @return object {w,h} or null - */ -export function getWidthAndHeightFromVideoObject(objVideo) { - let playerSize = getPlayerSizeFromObject(objVideo); - if (!playerSize) { - return null; - } - if (playerSize[0] && typeof playerSize[0] === 'object') { - spec.logInfo('getWidthAndHeightFromVideoObject found nested array inside playerSize.', playerSize[0]); - playerSize = playerSize[0]; - if (typeof playerSize[0] !== 'number' && typeof playerSize[0] !== 'string') { - spec.logInfo('getWidthAndHeightFromVideoObject found non-number/string type inside the INNER array in playerSize. This is totally wrong - cannot continue.', playerSize[0]); - return null; - } - } - if (playerSize.length !== 2) { - spec.logInfo('getWidthAndHeightFromVideoObject found playerSize with length of ' + playerSize.length + '. This is totally wrong - cannot continue.'); - return null; - } - return ({'w': playerSize[0], 'h': playerSize[1]}); -} - -/** - * @param objVideo will be like {"playerSize":[640,480],"mimes":["video/mp4"],"context":"outstream"} or POSSIBLY {"playerSize":[[640,480]],"mimes":["video/mp4"],"context":"outstream"} - * @return object {w,h} or null - */ -export function playerSizeIsNestedArray(objVideo) { - let playerSize = getPlayerSizeFromObject(objVideo); - if (!playerSize) { - return null; - } - if (playerSize.length < 1) { - return null; - } - return (playerSize[0] && typeof playerSize[0] === 'object'); -} - -/** - * Common functionality when looking at a video object, to get the playerSize - * @param objVideo - * @returns {*} - */ -function getPlayerSizeFromObject(objVideo) { - spec.logInfo('getPlayerSizeFromObject received object', objVideo); - let playerSize = utils.deepAccess(objVideo, 'playerSize'); - if (!playerSize) { - playerSize = utils.deepAccess(objVideo, 'ext.playerSize'); - } - if (!playerSize) { - spec.logError('getPlayerSizeFromObject FAILED: no playerSize in video object or ext', objVideo); - return null; - } - if (typeof playerSize !== 'object') { - spec.logError('getPlayerSizeFromObject FAILED: playerSize is not an object/array', objVideo); - return null; - } - return playerSize; -} -/* - Rendering video ads - create a renderer instance, mark it as not loaded, set a renderer function. - The renderer function will not assume that the renderer script is loaded - it will push() the ultimate render function call - */ -function newRenderer(adUnitCode, rendererOptions = {}) { - let isLoaded = window.ozoneVideo; - spec.logInfo(`newRenderer going to set loaded to ${isLoaded ? 'true' : 'false'}`); - const renderer = Renderer.install({ - url: spec.getRendererUrl(), - config: rendererOptions, - loaded: isLoaded, - adUnitCode - }); - try { - renderer.setRender(outstreamRender); - } catch (err) { - spec.logError('Prebid Error when calling setRender on renderer', JSON.parse(JSON.stringify(renderer)), err); - } - return renderer; -} -function outstreamRender(bid) { - spec.logInfo('outstreamRender called. Going to push the call to window.ozoneVideo.outstreamRender(bid) bid =', JSON.parse(JSON.stringify(bid))); - // push to render queue because ozoneVideo may not be loaded yet - bid.renderer.push(() => { - window.ozoneVideo.outstreamRender(bid); - }); -} - -registerBidder(spec); -utils.logInfo(`*BidAdapter ${OZONEVERSION} was loaded`); diff --git a/modules/ozoneBidAdapter.md b/modules/ozoneBidAdapter.md deleted file mode 100644 index ca18c962219..00000000000 --- a/modules/ozoneBidAdapter.md +++ /dev/null @@ -1,74 +0,0 @@ - -# Overview - -``` -Module Name: Ozone Project Bidder Adapter -Module Type: Bidder Adapter -Maintainer: engineering@ozoneproject.com - -``` - -# Description - -Module that connects to the Ozone Project's demand source(s). - -The Ozone Project bid adapter supports Banner and Outstream Video mediaTypes ONLY. - -# Test Parameters - - -A test ad unit that will consistently return test creatives: - -``` - -//Banner adUnit - -adUnits = [{ - code: 'id-of-your-banner-div', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]] - } - }, - bids: [{ - bidder: 'ozone', - params: { - publisherId: 'OZONENUK0001', /* an ID to identify the publisher account - required */ - siteId: '4204204201', /* An ID used to identify a site within a publisher account - required */ - placementId: '0420420421', /* an ID used to identify the piece of inventory - required - for appnexus test use 13144370. */ - customData: [{"settings": {}, "targeting": {"key": "value", "key2": ["value1", "value2"]}}],/* optional array with 'targeting' placeholder for passing publisher specific key-values for targeting. */ - } - }] - }]; -``` - - -``` - -//Outstream Video adUnit - -adUnits = [{ - code: 'id-of-your-video-div', - mediaTypes: { - video: { - playerSize: [640, 360], - mimes: ['video/mp4'], - context: 'outstream', - } - }, - bids: [{ - bidder: 'ozone', - params: { - publisherId: 'OZONENUK0001', /* an ID to identify the publisher account - required */ - siteId: '4204204201', /* An ID used to identify a site within a publisher account - required */ - customData: [{"settings": {}, "targeting": { "key": "value", "key2": ["value1", "value2"]}}] - placementId: '0440440442', /* an ID used to identify the piece of inventory - required - for unruly test use 0440440442. */ - video: { - skippable: true, /* optional */ - playback_method: ['auto_play_sound_off'], /* optional */ - targetDiv: 'some-different-div-id-to-my-adunitcode' /* optional */ - } - } - }] - }]; -``` diff --git a/modules/padsquadBidAdapter.js b/modules/padsquadBidAdapter.js deleted file mode 100644 index 24b1d5be3be..00000000000 --- a/modules/padsquadBidAdapter.js +++ /dev/null @@ -1,133 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import * as utils from '../src/utils.js'; -import {BANNER} from '../src/mediaTypes.js'; - -const ENDPOINT_URL = 'https://x.padsquad.com/auction'; - -const DEFAULT_BID_TTL = 30; -const DEFAULT_CURRENCY = 'USD'; -const DEFAULT_NET_REVENUE = true; - -export const spec = { - code: 'padsquad', - supportedMediaTypes: [BANNER], - - isBidRequestValid: function (bid) { - return (!!bid.params.unitId && typeof bid.params.unitId === 'string') || - (!!bid.params.networkId && typeof bid.params.networkId === 'string') || - (!!bid.params.publisherId && typeof bid.params.publisherId === 'string'); - }, - - buildRequests: function (validBidRequests, bidderRequest) { - if (!validBidRequests || !bidderRequest) { - return; - } - const publisherId = validBidRequests[0].params.publisherId; - const networkId = validBidRequests[0].params.networkId; - const impressions = validBidRequests.map(bidRequest => ({ - id: bidRequest.bidId, - banner: { - format: bidRequest.sizes.map(sizeArr => ({ - w: sizeArr[0], - h: sizeArr[1] - })) - }, - ext: { - exchange: { - unitId: bidRequest.params.unitId - } - } - })); - - const openrtbRequest = { - id: bidderRequest.auctionId, - imp: impressions, - site: { - domain: window.location.hostname, - page: window.location.href, - ref: bidderRequest.refererInfo ? bidderRequest.refererInfo.referer || null : null - }, - ext: { - exchange: { - publisherId: publisherId, - networkId: networkId, - } - } - }; - - // apply gdpr - if (bidderRequest.gdprConsent) { - openrtbRequest.regs = {ext: {gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0}}; - openrtbRequest.user = {ext: {consent: bidderRequest.gdprConsent.consentString}}; - } - - const payloadString = JSON.stringify(openrtbRequest); - return { - method: 'POST', - url: ENDPOINT_URL, - data: payloadString, - }; - }, - - interpretResponse: function (serverResponse, request) { - const bidResponses = []; - const response = (serverResponse || {}).body; - // response is always one seat with (optional) bids for each impression - if (response && response.seatbid && response.seatbid.length === 1 && response.seatbid[0].bid && response.seatbid[0].bid.length) { - response.seatbid[0].bid.forEach(bid => { - bidResponses.push({ - requestId: bid.impid, - cpm: bid.price, - width: bid.w, - height: bid.h, - ad: bid.adm, - ttl: DEFAULT_BID_TTL, - creativeId: bid.crid, - meta: { advertiserDomains: bid.adomain }, - netRevenue: DEFAULT_NET_REVENUE, - currency: DEFAULT_CURRENCY, - }) - }) - } else { - utils.logInfo('padsquad.interpretResponse :: no valid responses to interpret'); - } - return bidResponses; - }, - getUserSyncs: function (syncOptions, serverResponses) { - utils.logInfo('padsquad.getUserSyncs', 'syncOptions', syncOptions, 'serverResponses', serverResponses); - let syncs = []; - - if (!syncOptions.iframeEnabled && !syncOptions.pixelEnabled) { - return syncs; - } - - serverResponses.forEach(resp => { - const userSync = utils.deepAccess(resp, 'body.ext.usersync'); - if (userSync) { - let syncDetails = []; - Object.keys(userSync).forEach(key => { - const value = userSync[key]; - if (value.syncs && value.syncs.length) { - syncDetails = syncDetails.concat(value.syncs); - } - }); - syncDetails.forEach(syncDetails => { - syncs.push({ - type: syncDetails.type === 'iframe' ? 'iframe' : 'image', - url: syncDetails.url - }); - }); - - if (!syncOptions.iframeEnabled) { - syncs = syncs.filter(s => s.type !== 'iframe') - } - if (!syncOptions.pixelEnabled) { - syncs = syncs.filter(s => s.type !== 'image') - } - } - }); - return syncs; - }, - -}; -registerBidder(spec); diff --git a/modules/padsquadBidAdapter.md b/modules/padsquadBidAdapter.md deleted file mode 100644 index 0a69db42ce3..00000000000 --- a/modules/padsquadBidAdapter.md +++ /dev/null @@ -1,33 +0,0 @@ -# Overview - -``` -Module Name: Padsquad Bid Adapter -Module Type: Bidder Adapter -Maintainer: yeeldpadsquad@gmail.com -``` - -# Description - -Connects to Padsquad exchange for bids. - -Padsquad bid adapter supports Banner ads. - -# Test Parameters -``` -var adUnits = [ - { - code: 'banner-ad-div', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]] - } - }, - bids: [{ - bidder: 'padsquad', - params: { - unitId: 'test' - } - }] - } -]; -``` diff --git a/modules/papyrusBidAdapter.js b/modules/papyrusBidAdapter.js deleted file mode 100644 index a27c5cf618a..00000000000 --- a/modules/papyrusBidAdapter.js +++ /dev/null @@ -1,77 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; - -const PAPYRUS_ENDPOINT = 'https://prebid.papyrus.global'; -const PAPYRUS_CODE = 'papyrus'; - -export const spec = { - code: PAPYRUS_CODE, - - /** - * Determines whether or not the given bid request is valid. Valid bid request must have placementId and hbid - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: bid => { - return !!(bid && bid.params && bid.params.address && bid.params.placementId); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests) { - const bidParams = []; - utils._each(validBidRequests, function(bid) { - bidParams.push({ - address: bid.params.address, - placementId: bid.params.placementId, - bidId: bid.bidId, - transactionId: bid.transactionId, - sizes: utils.parseSizesInput(bid.sizes) - }); - }); - - return { - method: 'POST', - url: PAPYRUS_ENDPOINT, - data: bidParams - }; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse, request) { - const bidResponses = []; - - if (serverResponse && serverResponse.body && serverResponse.body.bids) { - serverResponse.body.bids.forEach(bid => { - const bidResponse = { - requestId: bid.id, - creativeId: bid.id, - adId: bid.id, - transactionId: bid.transactionId, - cpm: bid.cpm, - width: bid.width, - height: bid.height, - currency: bid.currency, - netRevenue: true, - ttl: 300, - ad: bid.ad - } - bidResponses.push(bidResponse); - }); - } - - return bidResponses; - } -}; - -registerBidder(spec); diff --git a/modules/papyrusBidAdapter.md b/modules/papyrusBidAdapter.md deleted file mode 100644 index 98a42e542ec..00000000000 --- a/modules/papyrusBidAdapter.md +++ /dev/null @@ -1,41 +0,0 @@ -# Overview - -``` -Module Name: Papyrus Bid Adapter -Module Type: Bidder Adapter -Maintainer: alexander.holodov@papyrus.global -``` - -# Description - -Connect to Papyrus system for bids. - -Papyrus bid adapter supports Banner. - -Please contact to info@papyrus.global for -further details - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [ - [320, 50] - ] - } - }, - bids: [ - { - bidder: 'papyrus', - params: { - address: '0xd7e2a771c5dcd5df7f789477356aecdaeee6c985', - placementId: 'b57e55fd18614b0591893e9fff41fbea' - } - } - ] - } - ]; -``` diff --git a/modules/parrableIdSystem.js b/modules/parrableIdSystem.js deleted file mode 100644 index 826dd9a933a..00000000000 --- a/modules/parrableIdSystem.js +++ /dev/null @@ -1,310 +0,0 @@ -/** - * This module adds Parrable to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/parrableIdSystem - * @requires module:modules/userId - */ - -import * as utils from '../src/utils.js' -import find from 'core-js-pure/features/array/find.js'; -import { ajax } from '../src/ajax.js'; -import { submodule } from '../src/hook.js'; -import { getRefererInfo } from '../src/refererDetection.js'; -import { uspDataHandler } from '../src/adapterManager.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const PARRABLE_URL = 'https://h.parrable.com/prebid'; -const PARRABLE_COOKIE_NAME = '_parrable_id'; -const PARRABLE_GVLID = 928; -const LEGACY_ID_COOKIE_NAME = '_parrable_eid'; -const LEGACY_OPTOUT_COOKIE_NAME = '_parrable_optout'; -const ONE_YEAR_MS = 364 * 24 * 60 * 60 * 1000; -const EXPIRE_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:00 GMT'; - -const storage = getStorageManager(PARRABLE_GVLID); - -function getExpirationDate() { - const oneYearFromNow = new Date(utils.timestamp() + ONE_YEAR_MS); - return oneYearFromNow.toGMTString(); -} - -function deserializeParrableId(parrableIdStr) { - const parrableId = {}; - const values = parrableIdStr.split(','); - - values.forEach(function(value) { - const pair = value.split(':'); - // unpack a value of 1 as true - parrableId[pair[0]] = +pair[1] === 1 ? true : pair[1]; - }); - - return parrableId; -} - -function serializeParrableId(parrableId) { - let components = []; - - if (parrableId.eid) { - components.push('eid:' + parrableId.eid); - } - if (parrableId.ibaOptout) { - components.push('ibaOptout:1'); - } - if (parrableId.ccpaOptout) { - components.push('ccpaOptout:1'); - } - - return components.join(','); -} - -function isValidConfig(configParams) { - if (!configParams) { - utils.logError('User ID - parrableId submodule requires configParams'); - return false; - } - if (!configParams.partners && !configParams.partner) { - utils.logError('User ID - parrableId submodule requires partner list'); - return false; - } - if (configParams.storage) { - utils.logWarn('User ID - parrableId submodule does not require a storage config'); - } - return true; -} - -function encodeBase64UrlSafe(base64) { - const ENC = { - '+': '-', - '/': '_', - '=': '.' - }; - return base64.replace(/[+/=]/g, (m) => ENC[m]); -} - -function readCookie() { - const parrableIdStr = storage.getCookie(PARRABLE_COOKIE_NAME); - if (parrableIdStr) { - return deserializeParrableId(decodeURIComponent(parrableIdStr)); - } - return null; -} - -function writeCookie(parrableId) { - if (parrableId) { - const parrableIdStr = encodeURIComponent(serializeParrableId(parrableId)); - storage.setCookie(PARRABLE_COOKIE_NAME, parrableIdStr, getExpirationDate(), 'lax'); - } -} - -function readLegacyCookies() { - const eid = storage.getCookie(LEGACY_ID_COOKIE_NAME); - const ibaOptout = (storage.getCookie(LEGACY_OPTOUT_COOKIE_NAME) === 'true'); - if (eid || ibaOptout) { - const parrableId = {}; - if (eid) { - parrableId.eid = eid; - } - if (ibaOptout) { - parrableId.ibaOptout = ibaOptout; - } - return parrableId; - } - return null; -} - -function migrateLegacyCookies(parrableId) { - if (parrableId) { - writeCookie(parrableId); - if (parrableId.eid) { - storage.setCookie(LEGACY_ID_COOKIE_NAME, '', EXPIRE_COOKIE_DATE); - } - if (parrableId.ibaOptout) { - storage.setCookie(LEGACY_OPTOUT_COOKIE_NAME, '', EXPIRE_COOKIE_DATE); - } - } -} - -function shouldFilterImpression(configParams, parrableId) { - const config = configParams.timezoneFilter; - - if (!config) { - return false; - } - - if (parrableId) { - return false; - } - - const offset = (new Date()).getTimezoneOffset() / 60; - const zone = Intl.DateTimeFormat().resolvedOptions().timeZone; - - function isZoneListed(list, zone) { - // IE does not provide a timeZone in IANA format so zone will be empty - const zoneLowercase = zone && zone.toLowerCase(); - return !!(list && zone && find(list, zn => zn.toLowerCase() === zoneLowercase)); - } - - function isAllowed() { - if (utils.isEmpty(config.allowedZones) && - utils.isEmpty(config.allowedOffsets)) { - return true; - } - if (isZoneListed(config.allowedZones, zone)) { - return true; - } - if (utils.contains(config.allowedOffsets, offset)) { - return true; - } - return false; - } - - function isBlocked() { - if (utils.isEmpty(config.blockedZones) && - utils.isEmpty(config.blockedOffsets)) { - return false; - } - if (isZoneListed(config.blockedZones, zone)) { - return true; - } - if (utils.contains(config.blockedOffsets, offset)) { - return true; - } - return false; - } - - return isBlocked() || !isAllowed(); -} - -function fetchId(configParams, gdprConsentData) { - if (!isValidConfig(configParams)) return; - - let parrableId = readCookie(); - if (!parrableId) { - parrableId = readLegacyCookies(); - migrateLegacyCookies(parrableId); - } - - if (shouldFilterImpression(configParams, parrableId)) { - return null; - } - - const eid = (parrableId) ? parrableId.eid : null; - const refererInfo = getRefererInfo(); - const uspString = uspDataHandler.getConsentData(); - const gdprApplies = (gdprConsentData && typeof gdprConsentData.gdprApplies === 'boolean' && gdprConsentData.gdprApplies); - const gdprConsentString = (gdprConsentData && gdprApplies && gdprConsentData.consentString) || ''; - const partners = configParams.partners || configParams.partner - const trackers = typeof partners === 'string' - ? partners.split(',') - : partners; - - const data = { - eid, - trackers, - url: refererInfo.referer, - prebidVersion: '$prebid.version$', - isIframe: utils.inIframe() - }; - - const searchParams = { - data: encodeBase64UrlSafe(btoa(JSON.stringify(data))), - gdpr: gdprApplies ? 1 : 0, - _rand: Math.random() - }; - - if (uspString) { - searchParams.us_privacy = uspString; - } - - if (gdprApplies) { - searchParams.gdpr_consent = gdprConsentString; - } - - const options = { - method: 'GET', - withCredentials: true - }; - - const callback = function (cb) { - const callbacks = { - success: response => { - let newParrableId = parrableId ? utils.deepClone(parrableId) : {}; - if (response) { - try { - let responseObj = JSON.parse(response); - if (responseObj) { - if (responseObj.ccpaOptout !== true) { - newParrableId.eid = responseObj.eid; - } else { - newParrableId.eid = null; - newParrableId.ccpaOptout = true; - } - if (responseObj.ibaOptout === true) { - newParrableId.ibaOptout = true; - } - } - } catch (error) { - utils.logError(error); - cb(); - } - writeCookie(newParrableId); - cb(newParrableId); - } else { - utils.logError('parrableId: ID fetch returned an empty result'); - cb(); - } - }, - error: error => { - utils.logError(`parrableId: ID fetch encountered an error`, error); - cb(); - } - }; - ajax(PARRABLE_URL, callbacks, searchParams, options); - }; - - return { - callback, - id: parrableId - }; -} - -/** @type {Submodule} */ -export const parrableIdSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: 'parrableId', - /** - * Global Vendor List ID - * @type {number} - */ - gvlid: PARRABLE_GVLID, - - /** - * decode the stored id value for passing to bid requests - * @function - * @param {ParrableId} parrableId - * @return {(Object|undefined} - */ - decode(parrableId) { - if (parrableId && utils.isPlainObject(parrableId)) { - return { parrableId }; - } - return undefined; - }, - - /** - * performs action to obtain id and return a value in the callback's response argument - * @function - * @param {SubmoduleConfig} [config] - * @param {ConsentData} [consentData] - * @returns {function(callback:function), id:ParrableId} - */ - getId(config, gdprConsentData, currentStoredId) { - const configParams = (config && config.params) || {}; - return fetchId(configParams, gdprConsentData); - } -}; - -submodule('userId', parrableIdSubmodule); diff --git a/modules/peak226BidAdapter.md b/modules/peak226BidAdapter.md deleted file mode 100644 index bae15d6c99f..00000000000 --- a/modules/peak226BidAdapter.md +++ /dev/null @@ -1,31 +0,0 @@ -# Overview - -``` -Module Name: Peak226 Bidder Adapter -Module Type: Bidder Adapter -Maintainer: support@edge226.com -``` - -# Description - -Module that connects to Peak226's demand sources - -# Test Parameters - -``` - var adUnits = [ - { - code: "test-div", - sizes: [[300, 250]], - mediaType: "banner", - bids: [ - { - bidder: "peak226", - params: { - uid: 76131369 - } - } - ] - } - ]; -``` diff --git a/modules/performaxBidAdapter.js b/modules/performaxBidAdapter.js deleted file mode 100644 index 8e22a0b2da9..00000000000 --- a/modules/performaxBidAdapter.js +++ /dev/null @@ -1,56 +0,0 @@ -import {logWarn} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; - -const CLIENT = 'hellboy:v0.0.1' -const BIDDER_CODE = 'performax'; -const BIDDER_SHORT_CODE = 'px'; -const ENDPOINT = 'https://dale.performax.cz/hb'; - -export const spec = { - code: BIDDER_CODE, - aliases: [BIDDER_SHORT_CODE], - - isBidRequestValid: function (bid) { - return !!bid.params.slotId; - }, - - buildUrl: function (validBidRequests, bidderRequest) { - const slotIds = validBidRequests.map(request => request.params.slotId); - let url = [`${ENDPOINT}?slotId[]=${slotIds.join()}`]; - url.push('client=' + CLIENT); - url.push('auctionId=' + bidderRequest.auctionId); - return url.join('&'); - }, - - buildRequests: function (validBidRequests, bidderRequest) { - return { - method: 'POST', - url: this.buildUrl(validBidRequests, bidderRequest), - data: {'validBidRequests': validBidRequests, 'bidderRequest': bidderRequest}, - options: {contentType: 'application/json'}, - } - }, - - buildHtml: function (ad) { - const keys = Object.keys(ad.data || {}); - return ad.code.replace( - new RegExp('\\$(' + keys.join('|') + ')\\$', 'g'), - (matched, key) => ad.data[key] || matched - ); - }, - - interpretResponse: function (serverResponse, request) { - let bidResponses = []; - for (let i = 0; i < serverResponse.body.length; i++) { - const ad = serverResponse.body[i].ad; - if (ad.type === 'empty') { - logWarn(`One of ads is empty (reason=${ad.reason})`); - continue; - } - serverResponse.body[i].ad = this.buildHtml(ad); - bidResponses.push(serverResponse.body[i]); - } - return bidResponses; - } -} -registerBidder(spec); diff --git a/modules/performaxBidAdapter.md b/modules/performaxBidAdapter.md deleted file mode 100644 index 4cf2984a79d..00000000000 --- a/modules/performaxBidAdapter.md +++ /dev/null @@ -1,36 +0,0 @@ -# Overview - -``` -Module Name: Performax Bid Adapter -Module Type: Bidder Adapter -Maintainer: development@performax.cz -``` - -# Description - -Connects to Performax exchange for bids. - -Performax bid adapter supports Banner. - - -# Sample Banner Ad Unit: For Publishers - -```javascript - var adUnits = [ - { - code: 'performax-div', - sizes: [[300, 300]], - bids: [ - { - bidder: "performax", - params: { - slotId: 28 // required - } - } - ] - } - ]; -``` - -Where: -* slotId - id of slot in PX system diff --git a/modules/permutiveRtdProvider.js b/modules/permutiveRtdProvider.js deleted file mode 100644 index 91e88d3e4e1..00000000000 --- a/modules/permutiveRtdProvider.js +++ /dev/null @@ -1,189 +0,0 @@ -/** - * This module adds permutive provider to the real time data module - * The {@link module:modules/realTimeData} module is required - * The module will add custom segment targeting to ad units of specific bidders - * @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 { deepSetValue, deepAccess, isFn, mergeDeep, logError } from '../src/utils.js' -import includes from 'core-js-pure/features/array/includes.js' -const MODULE_NAME = 'permutive' - -export const storage = getStorageManager(null, MODULE_NAME) - -function init (config, userConsent) { - return true -} - -/** -* Set segment targeting from cache and then try to wait for Permutive -* to initialise to get realtime segment targeting -*/ -export function initSegments (reqBidsConfigObj, callback, customConfig) { - const permutiveOnPage = isPermutiveOnPage() - const config = mergeDeep({ - waitForIt: false, - params: { - maxSegs: 500, - acBidders: [], - overwrites: {} - } - }, customConfig) - - setSegments(reqBidsConfigObj, config) - - if (config.waitForIt && permutiveOnPage) { - window.permutive.ready(function () { - setSegments(reqBidsConfigObj, config) - callback() - }, 'realtime') - } else { - callback() - } -} - -function setSegments (reqBidsConfigObj, config) { - const adUnits = reqBidsConfigObj.adUnits || getGlobal().adUnits - const data = getSegments(config.params.maxSegs) - const utils = { deepSetValue, deepAccess, isFn, mergeDeep } - - adUnits.forEach(adUnit => { - adUnit.bids.forEach(bid => { - const { bidder } = bid - const acEnabled = isAcEnabled(config, bidder) - const customFn = getCustomBidderFn(config, bidder) - const defaultFn = getDefaultBidderFn(bidder) - - if (customFn) { - customFn(bid, data, acEnabled, utils, defaultFn) - } else if (defaultFn) { - defaultFn(bid, data, acEnabled) - } - }) - }) -} - -function makeSafe (fn) { - try { - fn() - } catch (e) { - logError(e) - } -} - -function getCustomBidderFn (config, bidder) { - const overwriteFn = deepAccess(config, `params.overwrites.${bidder}`) - - if (overwriteFn && isFn(overwriteFn)) { - return overwriteFn - } else { - return null - } -} - -/** -* Returns a function that receives a `bid` object, a `data` object and a `acEnabled` boolean -* and which will set the right segment targeting keys for `bid` based on `data` and `acEnabled` -* @param {string} bidder -* @param {object} data -*/ -function getDefaultBidderFn (bidder) { - const bidderMapper = { - appnexus: function (bid, data, acEnabled) { - if (acEnabled && data.ac && data.ac.length) { - deepSetValue(bid, 'params.keywords.p_standard', data.ac) - } - if (data.appnexus && data.appnexus.length) { - deepSetValue(bid, 'params.keywords.permutive', data.appnexus) - } - - return bid - }, - rubicon: function (bid, data, acEnabled) { - if (acEnabled && data.ac && data.ac.length) { - deepSetValue(bid, 'params.visitor.p_standard', data.ac) - } - if (data.rubicon && data.rubicon.length) { - deepSetValue(bid, 'params.visitor.permutive', data.rubicon) - } - - return bid - }, - ozone: function (bid, data, acEnabled) { - if (acEnabled && data.ac && data.ac.length) { - deepSetValue(bid, 'params.customData.0.targeting.p_standard', data.ac) - } - - return bid - }, - trustx: function (bid, data, acEnabled) { - if (acEnabled && data.ac && data.ac.length) { - deepSetValue(bid, 'params.keywords.p_standard', data.ac) - } - - return bid - } - } - - return bidderMapper[bidder] -} - -export function isAcEnabled (config, bidder) { - const acBidders = deepAccess(config, 'params.acBidders') || [] - return includes(acBidders, bidder) -} - -export function isPermutiveOnPage () { - return typeof window.permutive !== 'undefined' && typeof window.permutive.ready === 'function' -} - -/** -* Returns all relevant segment IDs in an object -*/ -export function getSegments (maxSegs) { - const legacySegs = readSegments('_psegs').map(Number).filter(seg => seg >= 1000000).map(String) - const _ppam = readSegments('_ppam') - const _pcrprs = readSegments('_pcrprs') - - const segments = { - ac: [..._pcrprs, ..._ppam, ...legacySegs], - rubicon: readSegments('_prubicons'), - appnexus: readSegments('_papns'), - gam: readSegments('_pdfps') - } - - for (const type in segments) { - segments[type] = segments[type].slice(0, maxSegs) - } - - return segments -} - -/** - * Gets an array of segment IDs from LocalStorage - * or returns an empty array - * @param {string} key - */ -function readSegments (key) { - try { - return JSON.parse(storage.getDataFromLocalStorage(key) || '[]') - } catch (e) { - return [] - } -} - -/** @type {RtdSubmodule} */ -export const permutiveSubmodule = { - name: MODULE_NAME, - getBidRequestData: function (reqBidsConfigObj, callback, customConfig) { - makeSafe(function () { - initSegments(reqBidsConfigObj, callback, customConfig) - }) - }, - init: init -} - -submodule('realTimeData', permutiveSubmodule) diff --git a/modules/permutiveRtdProvider.md b/modules/permutiveRtdProvider.md deleted file mode 100644 index 3738c6e8be7..00000000000 --- a/modules/permutiveRtdProvider.md +++ /dev/null @@ -1,103 +0,0 @@ -# Permutive Real-time Data Submodule -This submodule reads segments from Permutive and attaches them as targeting keys to bid requests. Using this module will deliver best targeting results, leveraging Permutive's real-time segmentation and modelling capabilities. - -## Usage -Compile the Permutive RTD module into your Prebid build: -``` -gulp build --modules=rtdModule,permutiveRtdProvider -``` - -> Note that the global RTD module, `rtdModule`, is a prerequisite of the Permutive RTD module. - -You then need to enable the Permutive RTD in your Prebid configuration, using the below format: - -```javascript -pbjs.setConfig({ - ..., - realTimeData: { - auctionDelay: 50, // optional auction delay - dataProviders: [{ - name: 'permutive', - waitForIt: true, // should be true if there's an `auctionDelay` - params: { - acBidders: ['appnexus', 'rubicon', 'ozone'] - } - }] - }, - ... -}) -``` - -## Supported Bidders -The below bidders are currently support by the Permutive RTD module. Please reach out to your Permutive Account Manager to request support for any additional bidders. - -| Bidder | ID | First-party segments | Audience Connector | -| ----------- | ---------- | -------------------- | ------------------ | -| Xandr | `appnexus` | Yes | Yes | -| Magnite | `rubicon` | Yes | Yes | -| Ozone | `ozone` | No | Yes | -| TrustX | `trustx` | No | Yes | - -* **First-party segments:** When enabling the respective Activation for a segment in Permutive, this module will automatically attach that segment to the bid request. There is no need to enable individual bidders in the module configuration, it will automatically reflect which SSP integrations you have enabled in Permutive. Permutive segments will be sent in the `permutive` key-value. - -* **Audience Connector:** You'll need to define which bidder should receive Audience Connector segments. You need to include the `ID` of any bidder in the `acBidders` array. Audience Connector segments will be sent in the `p_standard` key-value. - - -## Parameters -| Name | Type | Description | Default | -| ----------------- | -------------------- | ------------------ | ------------------ | -| name | String | This should always be `permutive` | - | -| waitForIt | Boolean | Should be `true` if there's an `auctionDelay` defined (optional) | `false` | -| params | Object | | - | -| params.acBidders | String[] | An array of bidders which should receive AC segments. Pleasee see `Supported Bidders` for bidder support and possible values. | `[]` | -| params.maxSegs | Integer | Maximum number of segments to be included in either the `permutive` or `p_standard` key-value. | `500` | -| params.overwrites | Object | See `Custom Bidder Setup` for details on how to define custom bidder functions. | `{}` | - - -## Custom Bidder Setup -You can overwrite the default bidder function, for example to include a different set of segments or to support additional bidders. The below example modifies what first-party segments Magnite receives (segments from `gam` instead of `rubicon`). As best practise we recommend to first call `defaultFn` and then only overwrite specific key-values. The below example only overwrites `permutive` while `p_standard` are still set by `defaultFn` (if `rubicon` is an enabled `acBidder`). - -```javascript -pbjs.setConfig({ - ..., - realTimeData: { - auctionDelay: 50, - dataProviders: [{ - name: 'permutive', - waitForIt: true, - params: { - acBidders: ['appnexus', 'rubicon'], - maxSegs: 450, - overwrites: { - rubicon: function (bid, data, acEnabled, utils, defaultFn) { - if (defaultFn){ - bid = defaultFn(bid, data, acEnabled) - } - if (data.gam && data.gam.length) { - utils.deepSetValue(bid, 'params.visitor.permutive', data.gam) - } - } - } - } - }] - }, - ... -}) -``` -Any custom bidder function will receive the following parameters: - -| Name | Type | Description | -| ------------- |-------------- | --------------------------------------- | -| bid | Object | The bidder specific bidder object. You will mutate this object to set the appropriate targeting keys. | -| data | Object | An object containing Permutive segments | -| data.appnexus | string[] | Segments exposed by the Xandr SSP integration | -| data.rubicon | string[] | Segments exposed by the Magnite SSP integration | -| data.gam | string[] | Segments exposed by the Google Ad Manager integration | -| data.ac | string[] | Segments exposed by the Audience Connector | -| acEnabled | Boolean | `true` if the current bidder in included in `params.acBidders` | -| utils | {} | An object containing references to various util functions used by `permutiveRtdProvider.js`. Please make sure not to overwrite any of these. | -| defaultFn | Function | The default function for this bidder. Please note that this can be `undefined` if there is no default function for this bidder (see `Supported Bidders`). The function expect the following parameters: `bid`, `data`, `acEnabled` and will return `bid`. | - -**Warning** - -The custom bidder function will mutate the `bid` object. Please be aware that this could break your bid request if you accidentally overwrite any fields other than the `permutive` or `p_standard` key-values or if you change the structure of the `bid` object in any way. diff --git a/modules/piximediaBidAdapter.js b/modules/piximediaBidAdapter.js deleted file mode 100644 index 2617cc8fe42..00000000000 --- a/modules/piximediaBidAdapter.js +++ /dev/null @@ -1,47 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'piximedia'; -const ENDPOINT = 'https://ad.piximedia.com/prebid'; - -export const spec = { - code: BIDDER_CODE, - isBidRequestValid: function(bid) { - return !!(bid.params && bid.params.siteId && bid.params.placementId); - }, - buildRequests: function(validBidRequests) { - return validBidRequests.map(bidRequest => { - let parseSized = utils.parseSizesInput(bidRequest.sizes); - let arrSize = parseSized[0].split('x'); - return { - method: 'GET', - url: ENDPOINT, - data: { - timestamp: utils.timestamp(), - pver: '1.0', - pbparams: JSON.stringify(bidRequest.params), - pbsizes: JSON.stringify(parseSized), - pbwidth: arrSize[0], - pbheight: arrSize[1], - pbbidid: bidRequest.bidId, - }, - }; - }); - }, - interpretResponse: function(serverResponse, request) { - const res = serverResponse.body; - const bidResponse = { - requestId: res.bidId, - cpm: parseFloat(res.cpm), - width: res.width, - height: res.height, - creativeId: res.creative_id, - currency: res.currency, - netRevenue: true, - ttl: 300, - ad: res.adm - }; - return [bidResponse]; - } -} -registerBidder(spec); diff --git a/modules/piximediaBidAdapter.md b/modules/piximediaBidAdapter.md deleted file mode 100644 index fae014cbdff..00000000000 --- a/modules/piximediaBidAdapter.md +++ /dev/null @@ -1,25 +0,0 @@ -# Overview - -**Module Name**: Piximedia Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: contact@piximedia.fr - -# Description - -Piximedia Bidder Adapter for Prebid.js. - -# Test Parameters -``` - var adUnits = [{ - code: 'mpu', - sizes: [[300, 250]], - bids: [{ - bidder: 'piximedia', - params: { - siteId: 'PIXIMEDIA', - placementId: 'PREBID' - } - }] - }]; - -``` diff --git a/modules/platformioBidAdapter.js b/modules/platformioBidAdapter.js deleted file mode 100644 index 314f738ef81..00000000000 --- a/modules/platformioBidAdapter.js +++ /dev/null @@ -1,307 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -const NATIVE_DEFAULTS = { - TITLE_LEN: 100, - DESCR_LEN: 200, - SPONSORED_BY_LEN: 50, - IMG_MIN: 150, - ICON_MIN: 50, -}; -const DEFAULT_MIMES = ['video/mp4', 'video/webm', 'application/x-shockwave-flash', 'application/javascript']; -const VIDEO_TARGETING = ['mimes', 'skippable', 'playback_method', 'protocols', 'api']; -const DEFAULT_PROTOCOLS = [2, 3, 5, 6]; -const DEFAULT_APIS = [1, 2]; - -export const spec = { - - code: 'platformio', - supportedMediaTypes: ['banner', 'native', 'video'], - - isBidRequestValid: bid => ( - !!(bid && bid.params && bid.params.pubId && bid.params.placementId) - ), - buildRequests: (bidRequests, bidderRequest) => { - const request = { - id: bidRequests[0].bidderRequestId, - at: 2, - imp: bidRequests.map(slot => impression(slot)), - site: site(bidRequests), - app: app(bidRequests), - device: device(bidRequests), - }; - applyGdpr(bidderRequest, request); - return { - method: 'POST', - url: 'https://piohbdisp.hb.adx1.com/', - data: JSON.stringify(request), - }; - }, - interpretResponse: (response, request) => ( - bidResponseAvailable(request, response.body) - ), -}; - -function bidResponseAvailable(bidRequest, bidResponse) { - const idToImpMap = {}; - const idToBidMap = {}; - const ortbRequest = parse(bidRequest.data); - ortbRequest.imp.forEach(imp => { - idToImpMap[imp.id] = imp; - }); - if (bidResponse) { - bidResponse.seatbid.forEach(seatBid => seatBid.bid.forEach(bid => { - idToBidMap[bid.impid] = bid; - })); - } - const bids = []; - Object.keys(idToImpMap).forEach(id => { - if (idToBidMap[id]) { - const bid = {}; - bid.requestId = id; - bid.adId = id; - bid.creativeId = id; - bid.cpm = idToBidMap[id].price; - bid.currency = bidResponse.cur; - bid.ttl = 360; - bid.netRevenue = true; - if (idToImpMap[id]['native']) { - bid['native'] = nativeResponse(idToImpMap[id], idToBidMap[id]); - let nurl = idToBidMap[id].nurl; - nurl = nurl.replace(/\$(%7B|\{)AUCTION_IMP_ID(%7D|\})/gi, idToBidMap[id].impid); - nurl = nurl.replace(/\$(%7B|\{)AUCTION_PRICE(%7D|\})/gi, idToBidMap[id].price); - nurl = nurl.replace(/\$(%7B|\{)AUCTION_CURRENCY(%7D|\})/gi, bidResponse.cur); - nurl = nurl.replace(/\$(%7B|\{)AUCTION_BID_ID(%7D|\})/gi, bidResponse.bidid); - bid['native']['impressionTrackers'] = [nurl]; - bid.mediaType = 'native'; - } else if (idToImpMap[id]['video']) { - bid.vastUrl = idToBidMap[id].adm; - bid.vastUrl = bid.vastUrl.replace(/\$(%7B|\{)AUCTION_PRICE(%7D|\})/gi, idToBidMap[id].price); - bid.crid = idToBidMap[id].crid; - bid.width = idToImpMap[id].video.w; - bid.height = idToImpMap[id].video.h; - bid.mediaType = 'video'; - } else if (idToImpMap[id]['banner']) { - bid.ad = idToBidMap[id].adm; - bid.ad = bid.ad.replace(/\$(%7B|\{)AUCTION_IMP_ID(%7D|\})/gi, idToBidMap[id].impid); - bid.ad = bid.ad.replace(/\$(%7B|\{)AUCTION_AD_ID(%7D|\})/gi, idToBidMap[id].adid); - bid.ad = bid.ad.replace(/\$(%7B|\{)AUCTION_PRICE(%7D|\})/gi, idToBidMap[id].price); - bid.ad = bid.ad.replace(/\$(%7B|\{)AUCTION_CURRENCY(%7D|\})/gi, bidResponse.cur); - bid.ad = bid.ad.replace(/\$(%7B|\{)AUCTION_BID_ID(%7D|\})/gi, bidResponse.bidid); - bid.width = idToBidMap[id].w; - bid.height = idToBidMap[id].h; - bid.mediaType = 'banner'; - } - bids.push(bid); - } - }); - return bids; -} -function impression(slot) { - return { - id: slot.bidId, - secure: window.location.protocol === 'https:' ? 1 : 0, - 'banner': banner(slot), - 'native': nativeImpression(slot), - 'video': videoImpression(slot), - bidfloor: slot.params.bidFloor || '0.000001', - tagid: slot.params.placementId.toString(), - }; -} - -function banner(slot) { - if (slot.mediaType === 'banner' || utils.deepAccess(slot, 'mediaTypes.banner')) { - const sizes = utils.deepAccess(slot, 'mediaTypes.banner.sizes'); - if (sizes.length > 1) { - let format = []; - for (let f = 0; f < sizes.length; f++) { - format.push({'w': sizes[f][0], 'h': sizes[f][1]}); - } - return {'format': format}; - } else { - return { - w: sizes[0][0], - h: sizes[0][1] - } - } - } - return null; -} - -function videoImpression(slot) { - if (slot.mediaType === 'video' || utils.deepAccess(slot, 'mediaTypes.video')) { - const sizes = utils.deepAccess(slot, 'mediaTypes.video.playerSize'); - const video = { - w: sizes[0][0], - h: sizes[0][1], - mimes: DEFAULT_MIMES, - protocols: DEFAULT_PROTOCOLS, - api: DEFAULT_APIS, - }; - if (slot.params.video) { - Object.keys(slot.params.video).filter(param => includes(VIDEO_TARGETING, param)).forEach(param => video[param] = slot.params.video[param]); - } - return video; - } - return null; -} - -function nativeImpression(slot) { - if (slot.mediaType === 'native' || utils.deepAccess(slot, 'mediaTypes.native')) { - const assets = []; - addAsset(assets, titleAsset(1, slot.nativeParams.title, NATIVE_DEFAULTS.TITLE_LEN)); - addAsset(assets, dataAsset(2, slot.nativeParams.body, 2, NATIVE_DEFAULTS.DESCR_LEN)); - addAsset(assets, dataAsset(3, slot.nativeParams.sponsoredBy, 1, NATIVE_DEFAULTS.SPONSORED_BY_LEN)); - addAsset(assets, imageAsset(4, slot.nativeParams.icon, 1, NATIVE_DEFAULTS.ICON_MIN, NATIVE_DEFAULTS.ICON_MIN)); - addAsset(assets, imageAsset(5, slot.nativeParams.image, 3, NATIVE_DEFAULTS.IMG_MIN, NATIVE_DEFAULTS.IMG_MIN)); - return { - request: JSON.stringify({ assets }), - ver: '1.1', - }; - } - return null; -} - -function addAsset(assets, asset) { - if (asset) { - assets.push(asset); - } -} - -function titleAsset(id, params, defaultLen) { - if (params) { - return { - id, - required: params.required ? 1 : 0, - title: { - len: params.len || defaultLen, - }, - }; - } - return null; -} - -function imageAsset(id, params, type, defaultMinWidth, defaultMinHeight) { - return params ? { - id, - required: params.required ? 1 : 0, - img: { - type, - wmin: params.wmin || defaultMinWidth, - hmin: params.hmin || defaultMinHeight, - } - } : null; -} - -function dataAsset(id, params, type, defaultLen) { - return params ? { - id, - required: params.required ? 1 : 0, - data: { - type, - len: params.len || defaultLen, - } - } : null; -} - -function site(bidderRequest) { - const pubId = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.pubId : '0'; - const siteId = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.siteId : '0'; - const appParams = bidderRequest[0].params.app; - if (!appParams) { - return { - publisher: { - id: pubId.toString(), - domain: window.location.hostname, - }, - id: siteId.toString(), - ref: window.top.document.referrer, - page: window.location.href, - } - } - return null; -} - -function app(bidderRequest) { - const pubId = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.pubId : '0'; - const appParams = bidderRequest[0].params.app; - if (appParams) { - return { - publisher: { - id: pubId.toString(), - }, - id: appParams.id, - name: appParams.name, - bundle: appParams.bundle, - storeurl: appParams.storeUrl, - domain: appParams.domain, - } - } - return null; -} - -function device(bidderRequest) { - const lat = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.latitude : ''; - const lon = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.longitude : ''; - const ifa = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.ifa : ''; - return { - dnt: utils.getDNT() ? 1 : 0, - ua: navigator.userAgent, - language: (navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage), - w: (window.screen.width || window.innerWidth), - h: (window.screen.height || window.innerHeigh), - geo: { - lat: lat, - lon: lon, - }, - ifa: ifa, - }; -} - -function parse(rawResponse) { - try { - if (rawResponse) { - return JSON.parse(rawResponse); - } - } catch (ex) { - utils.logError('platformio.parse', 'ERROR', ex); - } - return null; -} - -function applyGdpr(bidderRequest, ortbRequest) { - if (bidderRequest && bidderRequest.gdprConsent) { - ortbRequest.regs = { ext: { gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0 } }; - ortbRequest.user = { ext: { consent: bidderRequest.gdprConsent.consentString } }; - } -} - -function nativeResponse(imp, bid) { - if (imp['native']) { - const nativeAd = parse(bid.adm); - const keys = {}; - keys.image = {}; - keys.icon = {}; - if (nativeAd && nativeAd['native'] && nativeAd['native'].assets) { - nativeAd['native'].assets.forEach(asset => { - keys.title = asset.title ? asset.title.text : keys.title; - keys.body = asset.data && asset.id === 2 ? asset.data.value : keys.body; - keys.sponsoredBy = asset.data && asset.id === 3 ? asset.data.value : keys.sponsoredBy; - keys.icon.url = asset.img && asset.id === 4 ? asset.img.url : keys.icon.url; - keys.icon.width = asset.img && asset.id === 4 ? asset.img.w : keys.icon.width; - keys.icon.height = asset.img && asset.id === 4 ? asset.img.h : keys.icon.height; - keys.image.url = asset.img && asset.id === 5 ? asset.img.url : keys.image.url; - keys.image.width = asset.img && asset.id === 5 ? asset.img.w : keys.image.width; - keys.image.height = asset.img && asset.id === 5 ? asset.img.h : keys.image.height; - }); - if (nativeAd['native'].link) { - keys.clickUrl = encodeURIComponent(nativeAd['native'].link.url); - } - return keys; - } - } - return null; -} - -registerBidder(spec); diff --git a/modules/platformioBidAdapter.md b/modules/platformioBidAdapter.md deleted file mode 100644 index 863e023f0d7..00000000000 --- a/modules/platformioBidAdapter.md +++ /dev/null @@ -1,86 +0,0 @@ -# Overview - -**Module Name**: Platform.io Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: siarhei.kasukhin@platform.io - -# Description - -Connects to Platform.io demand source to fetch bids. -Banner, Native, Video formats are supported. -Please use ```platformio``` as the bidder code. - -# Test Parameters -``` - var adUnits = [{ - code: 'dfp-native-div', - mediaTypes: { - native: { - title: { - required: true, - len: 75 - }, - image: { - required: true - }, - body: { - len: 200 - }, - icon: { - required: false - } - } - }, - bids: [{ - bidder: 'platformio', - params: { - pubId: '29521', - siteId: '26048', - placementId: '123', - bidFloor: '0.001', // optional - ifa: 'XXX-XXX', // optional - latitude: '40.712775', // optional - longitude: '-74.005973', // optional - } - }] - }, - { - code: 'dfp-banner-div', - mediaTypes: { - banner: { - sizes: [ - [300, 250],[300,600] - ], - } - }, - bids: [{ - bidder: 'platformio', - params: { - pubId: '29521', - siteId: '26049', - placementId: '123', - } - }] - }, - { - code: 'dfp-video-div', - mediaTypes: { - video: { - playerSize: [[640, 480]], - context: "instream" - } - }, - bids: [{ - bidder: 'platformio', - params: { - pubId: '29521', - siteId: '26049', - placementId: '123', - video: { - skipppable: true, - } - } - }] - } - ]; -``` diff --git a/modules/polluxBidAdapter.md b/modules/polluxBidAdapter.md deleted file mode 100644 index 79bf84e79b9..00000000000 --- a/modules/polluxBidAdapter.md +++ /dev/null @@ -1,33 +0,0 @@ -# Overview - -**Module Name**: Pollux Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: tech@polluxnetwork.com - -# Description - -Module that connects to Pollux Network LLC demand source to fetch bids. -All bids will present CPM in EUR (Euro). - -# Test Parameters -``` - var adUnits = [{ - code: '34f724kh32', - sizes: [[300, 250]], // a single size - bids: [{ - bidder: 'pollux', - params: { - zone: '1806' // a single zone - } - }] - },{ - code: '34f789r783', - sizes: [[300, 250], [728, 90]], // multiple sizes - bids: [{ - bidder: 'pollux', - params: { - zone: '1806,276' // multiple zones, max 5 - } - }] - }]; -``` diff --git a/modules/polymorphBidAdapter.md b/modules/polymorphBidAdapter.md deleted file mode 100644 index e778b312e56..00000000000 --- a/modules/polymorphBidAdapter.md +++ /dev/null @@ -1,43 +0,0 @@ -# Overview - -``` -Module Name: Polymorph Bidder Adapter -Module Type: Bidder Adapter -Maintainer: kuldeep@getpolymorph.com -``` - -# Description - -Connects to Polymorph Demand Cloud (s2s header-bidding) - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div-1', - sizes: [[300, 250]], - bids: [ - { - bidder: "polymorph", - params: { - placementId: 'ping' - } - } - ] - },{ - code: 'test-div-2', - sizes: [[300, 250], [300,600]] - bids: [ - { - bidder: "polymorph", - params: { - placementId: 'ping', - // In case multiple ad sizes are supported, it's recommended to specify default height and width for native ad (in case native ad is chose as a winner). In case of banner or outstream ad any one of the above sizes can be chosen depending on the highest bid. - defaultWidth: 300, - defaultHeight: 600 - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/prebidServerBidAdapter/config.js b/modules/prebidServerBidAdapter/config.js deleted file mode 100644 index 92a8f5deaa5..00000000000 --- a/modules/prebidServerBidAdapter/config.js +++ /dev/null @@ -1,42 +0,0 @@ -// accountId and bidders params are not included here, should be configured by end-user -export const S2S_VENDORS = { - 'appnexus': { - adapter: 'prebidServer', - enabled: true, - endpoint: { - p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction', - noP1Consent: 'https://prebid.adnxs-simple.com/pbs/v1/openrtb2/auction' - }, - syncEndpoint: { - p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync', - noP1Consent: 'https://prebid.adnxs-simple.com/pbs/v1/cookie_sync' - }, - timeout: 1000 - }, - 'rubicon': { - adapter: 'prebidServer', - enabled: true, - endpoint: { - p1Consent: 'https://prebid-server.rubiconproject.com/openrtb2/auction', - noP1Consent: 'https://prebid-server.rubiconproject.com/openrtb2/auction', - }, - syncEndpoint: { - p1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync', - noP1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync', - }, - timeout: 500 - }, - 'openx': { - adapter: 'prebidServer', - enabled: true, - endpoint: { - p1Consent: 'https://prebid.openx.net/openrtb2/auction', - noP1Consent: 'https://prebid.openx.net/openrtb2/auction' - }, - syncEndpoint: { - p1Consent: 'https://prebid.openx.net/cookie_sync', - noP1Consent: 'https://prebid.openx.net/cookie_sync' - }, - timeout: 1000 - } -} diff --git a/modules/prebidServerBidAdapter/index.js b/modules/prebidServerBidAdapter/index.js deleted file mode 100644 index ec5d05f0fe0..00000000000 --- a/modules/prebidServerBidAdapter/index.js +++ /dev/null @@ -1,1148 +0,0 @@ -import Adapter from '../../src/adapter.js'; -import { createBid } from '../../src/bidfactory.js'; -import * as utils from '../../src/utils.js'; -import CONSTANTS from '../../src/constants.json'; -import adapterManager from '../../src/adapterManager.js'; -import { config } from '../../src/config.js'; -import { VIDEO, NATIVE } from '../../src/mediaTypes.js'; -import { processNativeAdUnitParams } from '../../src/native.js'; -import { isValid } from '../../src/adapters/bidderFactory.js'; -import events from '../../src/events.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import { S2S_VENDORS } from './config.js'; -import { ajax } from '../../src/ajax.js'; -import find from 'core-js-pure/features/array/find.js'; -import { getPrebidInternal } from '../../src/utils.js'; - -const getConfig = config.getConfig; - -const TYPE = CONSTANTS.S2S.SRC; -let _syncCount = 0; -const DEFAULT_S2S_TTL = 60; -const DEFAULT_S2S_CURRENCY = 'USD'; -const DEFAULT_S2S_NETREVENUE = true; - -let _s2sConfigs; - -let eidPermissions; - -/** - * @typedef {Object} AdapterOptions - * @summary s2sConfig parameter that adds arguments to resulting OpenRTB payload that goes to Prebid Server - * @property {string} adapter - * @property {boolean} enabled - * @property {string} endpoint - * @property {string} syncEndpoint - * @property {number} timeout - * @example - * // example of multiple bidder configuration - * pbjs.setConfig({ - * s2sConfig: { - * adapterOptions: { - * rubicon: {singleRequest: false} - * appnexus: {key: "value"} - * } - * } - * }); - */ - -/** - * @typedef {Object} S2SDefaultConfig - * @summary Base config properties for server to server header bidding - * @property {string} [adapter='prebidServer'] adapter code to use for S2S - * @property {boolean} [enabled=false] enables S2S bidding - * @property {number} [timeout=1000] timeout for S2S bidders - should be lower than `pbjs.requestBids({timeout})` - * @property {number} [maxBids=1] - * @property {AdapterOptions} [adapterOptions] adds arguments to resulting OpenRTB payload to Prebid Server - * @property {Object} [syncUrlModifier] - */ - -/** - * @typedef {S2SDefaultConfig} S2SConfig - * @summary Configuration for server to server header bidding - * @property {string[]} bidders bidders to request S2S - * @property {string} endpoint endpoint to contact - * @property {string} [defaultVendor] used as key to select the bidder's default config from ßprebidServer/config.js - * @property {boolean} [cacheMarkup] whether to cache the adm result - * @property {string} [syncEndpoint] endpoint URL for syncing cookies - * @property {Object} [extPrebid] properties will be merged into request.ext.prebid - */ - -/** - * @type {S2SDefaultConfig} - */ -const s2sDefaultConfig = { - timeout: 1000, - maxBids: 1, - adapter: 'prebidServer', - adapterOptions: {}, - syncUrlModifier: {} -}; - -config.setDefaults({ - 's2sConfig': s2sDefaultConfig -}); - -/** - * @param {S2SConfig} option - * @return {boolean} - */ -function updateConfigDefaultVendor(option) { - if (option.defaultVendor) { - let vendor = option.defaultVendor; - let optionKeys = Object.keys(option); - if (S2S_VENDORS[vendor]) { - // vendor keys will be set if either: the key was not specified by user - // or if the user did not set their own distinct value (ie using the system default) to override the vendor - Object.keys(S2S_VENDORS[vendor]).forEach((vendorKey) => { - if (s2sDefaultConfig[vendorKey] === option[vendorKey] || !includes(optionKeys, vendorKey)) { - option[vendorKey] = S2S_VENDORS[vendor][vendorKey]; - } - }); - } else { - utils.logError('Incorrect or unavailable prebid server default vendor option: ' + vendor); - return false; - } - } - // this is how we can know if user / defaultVendor has set it, or if we should default to false - return option.enabled = typeof option.enabled === 'boolean' ? option.enabled : false; -} - -/** - * @param {S2SConfig} option - * @return {boolean} - */ -function validateConfigRequiredProps(option) { - const keys = Object.keys(option); - if (['accountId', 'bidders', 'endpoint'].filter(key => { - if (!includes(keys, key)) { - utils.logError(key + ' missing in server to server config'); - return true; - } - return false; - }).length > 0) { - return false; - } -} - -// temporary change to modify the s2sConfig for new format used for endpoint URLs; -// could be removed later as part of a major release, if we decide to not support the old format -function formatUrlParams(option) { - ['endpoint', 'syncEndpoint'].forEach((prop) => { - if (utils.isStr(option[prop])) { - let temp = option[prop]; - option[prop] = { p1Consent: temp, noP1Consent: temp }; - } - }); -} - -/** - * @param {(S2SConfig[]|S2SConfig)} options - */ -function setS2sConfig(options) { - if (!options) { - return; - } - const normalizedOptions = Array.isArray(options) ? options : [options]; - - const activeBidders = []; - const optionsValid = normalizedOptions.every((option, i, array) => { - formatUrlParams(options); - const updateSuccess = updateConfigDefaultVendor(option); - if (updateSuccess !== false) { - const valid = validateConfigRequiredProps(option); - if (valid !== false) { - if (Array.isArray(option['bidders'])) { - array[i]['bidders'] = option['bidders'].filter(bidder => { - if (activeBidders.indexOf(bidder) === -1) { - activeBidders.push(bidder); - return true; - } - return false; - }); - } - return true; - } - } - utils.logWarn('prebidServer: s2s config is disabled'); - return false; - }); - - if (optionsValid) { - return _s2sConfigs = normalizedOptions; - } -} -getConfig('s2sConfig', ({s2sConfig}) => setS2sConfig(s2sConfig)); - -/** - * resets the _synced variable back to false, primiarily used for testing purposes -*/ -export function resetSyncedStatus() { - _syncCount = 0; -} - -/** - * @param {Array} bidderCodes list of bidders to request user syncs for. - */ -function queueSync(bidderCodes, gdprConsent, uspConsent, s2sConfig) { - if (_s2sConfigs.length === _syncCount) { - return; - } - _syncCount++; - - const payload = { - uuid: utils.generateUUID(), - bidders: bidderCodes, - account: s2sConfig.accountId - }; - - let userSyncLimit = s2sConfig.userSyncLimit; - if (utils.isNumber(userSyncLimit) && userSyncLimit > 0) { - payload['limit'] = userSyncLimit; - } - - if (gdprConsent) { - payload.gdpr = (gdprConsent.gdprApplies) ? 1 : 0; - // attempt to populate gdpr_consent if we know gdprApplies or it may apply - if (gdprConsent.gdprApplies !== false) { - payload.gdpr_consent = gdprConsent.consentString; - } - } - - // US Privacy (CCPA) support - if (uspConsent) { - payload.us_privacy = uspConsent; - } - - if (typeof s2sConfig.coopSync === 'boolean') { - payload.coopSync = s2sConfig.coopSync; - } - - const jsonPayload = JSON.stringify(payload); - ajax(getMatchingConsentUrl(s2sConfig.syncEndpoint, gdprConsent), - (response) => { - try { - response = JSON.parse(response); - doAllSyncs(response.bidder_status, s2sConfig); - } catch (e) { - utils.logError(e); - } - }, - jsonPayload, - { - contentType: 'text/plain', - withCredentials: true - }); -} - -function doAllSyncs(bidders, s2sConfig) { - if (bidders.length === 0) { - return; - } - - // pull the syncs off the list in the order that prebid server sends them - const thisSync = bidders.shift(); - - // if PBS reports this bidder doesn't have an ID, then call the sync and recurse to the next sync entry - if (thisSync.no_cookie) { - doPreBidderSync(thisSync.usersync.type, thisSync.usersync.url, thisSync.bidder, utils.bind.call(doAllSyncs, null, bidders, s2sConfig), s2sConfig); - } else { - // bidder already has an ID, so just recurse to the next sync entry - doAllSyncs(bidders, s2sConfig); - } -} - -/** - * Modify the cookie sync url from prebid server to add new params. - * - * @param {string} type the type of sync, "image", "redirect", "iframe" - * @param {string} url the url to sync - * @param {string} bidder name of bidder doing sync for - * @param {function} done an exit callback; to signify this pixel has either: finished rendering or something went wrong - * @param {S2SConfig} s2sConfig - */ -function doPreBidderSync(type, url, bidder, done, s2sConfig) { - if (s2sConfig.syncUrlModifier && typeof s2sConfig.syncUrlModifier[bidder] === 'function') { - const newSyncUrl = s2sConfig.syncUrlModifier[bidder](type, url, bidder); - doBidderSync(type, newSyncUrl, bidder, done) - } else { - doBidderSync(type, url, bidder, done) - } -} - -/** - * Run a cookie sync for the given type, url, and bidder - * - * @param {string} type the type of sync, "image", "redirect", "iframe" - * @param {string} url the url to sync - * @param {string} bidder name of bidder doing sync for - * @param {function} done an exit callback; to signify this pixel has either: finished rendering or something went wrong - */ -function doBidderSync(type, url, bidder, done) { - if (!url) { - utils.logError(`No sync url for bidder "${bidder}": ${url}`); - done(); - } else if (type === 'image' || type === 'redirect') { - utils.logMessage(`Invoking image pixel user sync for bidder: "${bidder}"`); - utils.triggerPixel(url, done); - } else if (type == 'iframe') { - utils.logMessage(`Invoking iframe user sync for bidder: "${bidder}"`); - utils.insertUserSyncIframe(url, done); - } else { - utils.logError(`User sync type "${type}" not supported for bidder: "${bidder}"`); - done(); - } -} - -/** - * Do client-side syncs for bidders. - * - * @param {Array} bidders a list of bidder names - */ -function doClientSideSyncs(bidders, gdprConsent, uspConsent) { - bidders.forEach(bidder => { - let clientAdapter = adapterManager.getBidAdapter(bidder); - if (clientAdapter && clientAdapter.registerSyncs) { - config.runWithBidder( - bidder, - utils.bind.call( - clientAdapter.registerSyncs, - clientAdapter, - [], - gdprConsent, - uspConsent - ) - ); - } - }); -} - -function _appendSiteAppDevice(request, pageUrl, accountId) { - if (!request) return; - - // ORTB specifies app OR site - if (typeof config.getConfig('app') === 'object') { - request.app = config.getConfig('app'); - request.app.publisher = {id: accountId} - } else { - request.site = {}; - if (utils.isPlainObject(config.getConfig('site'))) { - request.site = config.getConfig('site'); - } - // set publisher.id if not already defined - if (!utils.deepAccess(request.site, 'publisher.id')) { - utils.deepSetValue(request.site, 'publisher.id', accountId); - } - // set site.page if not already defined - if (!request.site.page) { - request.site.page = pageUrl; - } - } - if (typeof config.getConfig('device') === 'object') { - request.device = config.getConfig('device'); - } - if (!request.device) { - request.device = {}; - } - if (!request.device.w) { - request.device.w = window.innerWidth; - } - if (!request.device.h) { - request.device.h = window.innerHeight; - } -} - -function addBidderFirstPartyDataToRequest(request) { - const bidderConfig = config.getBidderConfig(); - const fpdConfigs = Object.keys(bidderConfig).reduce((acc, bidder) => { - const currBidderConfig = bidderConfig[bidder]; - if (currBidderConfig.ortb2) { - const ortb2 = {}; - if (currBidderConfig.ortb2.site) { - ortb2.site = currBidderConfig.ortb2.site; - } - if (currBidderConfig.ortb2.user) { - ortb2.user = currBidderConfig.ortb2.user; - } - - acc.push({ - bidders: [ bidder ], - config: { ortb2 } - }); - } - return acc; - }, []); - - if (fpdConfigs.length) { - utils.deepSetValue(request, 'ext.prebid.bidderconfig', fpdConfigs); - } -} - -// https://iabtechlab.com/wp-content/uploads/2016/07/OpenRTB-Native-Ads-Specification-Final-1.2.pdf#page=40 -let nativeDataIdMap = { - sponsoredBy: 1, // sponsored - body: 2, // desc - rating: 3, - likes: 4, - downloads: 5, - price: 6, - salePrice: 7, - phone: 8, - address: 9, - body2: 10, // desc2 - cta: 12 // ctatext -}; -let nativeDataNames = Object.keys(nativeDataIdMap); - -let nativeImgIdMap = { - icon: 1, - image: 3 -}; - -let nativeEventTrackerEventMap = { - impression: 1, - 'viewable-mrc50': 2, - 'viewable-mrc100': 3, - 'viewable-video50': 4, -}; - -let nativeEventTrackerMethodMap = { - img: 1, - js: 2 -}; - -// enable reverse lookup -[ - nativeDataIdMap, - nativeImgIdMap, - nativeEventTrackerEventMap, - nativeEventTrackerMethodMap -].forEach(map => { - Object.keys(map).forEach(key => { - map[map[key]] = key; - }); -}); - -/* - * Protocol spec for OpenRTB endpoint - * e.g., https:///v1/openrtb2/auction - */ -let bidIdMap = {}; -let nativeAssetCache = {}; // store processed native params to preserve - -/** - * map wurl to auction id and adId for use in the BID_WON event - */ -let wurlMap = {}; - -/** - * @param {string} auctionId - * @param {string} adId generated value set to bidObject.adId by bidderFactory Bid() - * @param {string} wurl events.winurl passed from prebidServer as wurl - */ -function addWurl(auctionId, adId, wurl) { - if ([auctionId, adId].every(utils.isStr)) { - wurlMap[`${auctionId}${adId}`] = wurl; - } -} - -function getPbsResponseData(bidderRequests, response, pbsName, pbjsName) { - const bidderValues = utils.deepAccess(response, `ext.${pbsName}`); - if (bidderValues) { - Object.keys(bidderValues).forEach(bidder => { - let biddersReq = find(bidderRequests, bidderReq => bidderReq.bidderCode === bidder); - if (biddersReq) { - biddersReq[pbjsName] = bidderValues[bidder]; - } - }); - } -} - -/** - * @param {string} auctionId - * @param {string} adId generated value set to bidObject.adId by bidderFactory Bid() - */ -function removeWurl(auctionId, adId) { - if ([auctionId, adId].every(utils.isStr)) { - wurlMap[`${auctionId}${adId}`] = undefined; - } -} -/** - * @param {string} auctionId - * @param {string} adId generated value set to bidObject.adId by bidderFactory Bid() - * @return {(string|undefined)} events.winurl which was passed as wurl - */ -function getWurl(auctionId, adId) { - if ([auctionId, adId].every(utils.isStr)) { - return wurlMap[`${auctionId}${adId}`]; - } -} - -/** - * remove all cached wurls - */ -export function resetWurlMap() { - wurlMap = {}; -} - -const OPEN_RTB_PROTOCOL = { - buildRequest(s2sBidRequest, bidRequests, adUnits, s2sConfig, requestedBidders) { - let imps = []; - let aliases = {}; - const firstBidRequest = bidRequests[0]; - - // transform ad unit into array of OpenRTB impression objects - adUnits.forEach(adUnit => { - const nativeParams = processNativeAdUnitParams(utils.deepAccess(adUnit, 'mediaTypes.native')); - let nativeAssets; - if (nativeParams) { - try { - nativeAssets = nativeAssetCache[adUnit.code] = Object.keys(nativeParams).reduce((assets, type) => { - let params = nativeParams[type]; - - function newAsset(obj) { - return Object.assign({ - required: params.required ? 1 : 0 - }, obj ? utils.cleanObj(obj) : {}); - } - - switch (type) { - case 'image': - case 'icon': - let imgTypeId = nativeImgIdMap[type]; - let asset = utils.cleanObj({ - type: imgTypeId, - w: utils.deepAccess(params, 'sizes.0'), - h: utils.deepAccess(params, 'sizes.1'), - wmin: utils.deepAccess(params, 'aspect_ratios.0.min_width'), - hmin: utils.deepAccess(params, 'aspect_ratios.0.min_height') - }); - if (!((asset.w && asset.h) || (asset.hmin && asset.wmin))) { - throw 'invalid img sizes (must provide sizes or min_height & min_width if using aspect_ratios)'; - } - if (Array.isArray(params.aspect_ratios)) { - // pass aspect_ratios as ext data I guess? - asset.ext = { - aspectratios: params.aspect_ratios.map( - ratio => `${ratio.ratio_width}:${ratio.ratio_height}` - ) - } - } - assets.push(newAsset({ - img: asset - })); - break; - case 'title': - if (!params.len) { - throw 'invalid title.len'; - } - assets.push(newAsset({ - title: { - len: params.len - } - })); - break; - default: - let dataAssetTypeId = nativeDataIdMap[type]; - if (dataAssetTypeId) { - assets.push(newAsset({ - data: { - type: dataAssetTypeId, - len: params.len - } - })) - } - } - return assets; - }, []); - } catch (e) { - utils.logError('error creating native request: ' + String(e)) - } - } - const videoParams = utils.deepAccess(adUnit, 'mediaTypes.video'); - const bannerParams = utils.deepAccess(adUnit, 'mediaTypes.banner'); - - adUnit.bids.forEach(bid => { - // OpenRTB response contains the adunit code and bidder name. These are - // combined to create a unique key for each bid since an id isn't returned - bidIdMap[`${adUnit.code}${bid.bidder}`] = bid.bid_id; - - // check for and store valid aliases to add to the request - if (adapterManager.aliasRegistry[bid.bidder]) { - const bidder = adapterManager.bidderRegistry[bid.bidder]; - // adding alias only if alias source bidder exists and alias isn't configured to be standalone - // pbs adapter - if (bidder && !bidder.getSpec().skipPbsAliasing) { - aliases[bid.bidder] = adapterManager.aliasRegistry[bid.bidder]; - } - } - }); - - let mediaTypes = {}; - if (bannerParams && bannerParams.sizes) { - const sizes = utils.parseSizesInput(bannerParams.sizes); - - // get banner sizes in form [{ w: , h: }, ...] - const format = sizes.map(size => { - const [ width, height ] = size.split('x'); - const w = parseInt(width, 10); - const h = parseInt(height, 10); - return { w, h }; - }); - - mediaTypes['banner'] = {format}; - } - - if (!utils.isEmpty(videoParams)) { - if (videoParams.context === 'outstream' && !adUnit.renderer) { - // Don't push oustream w/o renderer to request object. - utils.logError('Outstream bid without renderer cannot be sent to Prebid Server.'); - } else { - if (videoParams.context === 'instream' && !videoParams.hasOwnProperty('placement')) { - videoParams.placement = 1; - } - - mediaTypes['video'] = Object.keys(videoParams).filter(param => param !== 'context') - .reduce((result, param) => { - if (param === 'playerSize') { - result.w = utils.deepAccess(videoParams, `${param}.0.0`); - result.h = utils.deepAccess(videoParams, `${param}.0.1`); - } else { - result[param] = videoParams[param]; - } - return result; - }, {}); - } - } - - if (nativeAssets) { - try { - mediaTypes['native'] = { - request: JSON.stringify({ - // TODO: determine best way to pass these and if we allow defaults - context: 1, - plcmttype: 1, - eventtrackers: [ - {event: 1, methods: [1]} - ], - // TODO: figure out how to support privacy field - // privacy: int - assets: nativeAssets - }), - ver: '1.2' - } - } catch (e) { - utils.logError('error creating native request: ' + String(e)) - } - } - - // get bidder params in form { : {...params} } - // initialize reduce function with the user defined `ext` properties on the ad unit - const ext = adUnit.bids.reduce((acc, bid) => { - const adapter = adapterManager.bidderRegistry[bid.bidder]; - if (adapter && adapter.getSpec().transformBidParams) { - bid.params = adapter.getSpec().transformBidParams(bid.params, true); - } - acc[bid.bidder] = (s2sConfig.adapterOptions && s2sConfig.adapterOptions[bid.bidder]) ? Object.assign({}, bid.params, s2sConfig.adapterOptions[bid.bidder]) : bid.params; - return acc; - }, {...utils.deepAccess(adUnit, 'ortb2Imp.ext')}); - - const imp = { id: adUnit.code, ext, secure: s2sConfig.secure }; - - const ortb2 = {...utils.deepAccess(adUnit, 'ortb2Imp.ext.data')}; - Object.keys(ortb2).forEach(prop => { - /** - * Prebid AdSlot - * @type {(string|undefined)} - */ - if (prop === 'pbadslot') { - if (typeof ortb2[prop] === 'string' && ortb2[prop]) { - utils.deepSetValue(imp, 'ext.data.pbadslot', ortb2[prop]); - } else { - // remove pbadslot property if it doesn't meet the spec - delete imp.ext.data.pbadslot; - } - } else if (prop === 'adserver') { - /** - * Copy GAM AdUnit and Name to imp - */ - ['name', 'adslot'].forEach(name => { - /** @type {(string|undefined)} */ - const value = utils.deepAccess(ortb2, `adserver.${name}`); - if (typeof value === 'string' && value) { - utils.deepSetValue(imp, `ext.data.adserver.${name.toLowerCase()}`, value); - } - }); - } else { - utils.deepSetValue(imp, `ext.data.${prop}`, ortb2[prop]); - } - }); - - Object.assign(imp, mediaTypes); - - // if storedAuctionResponse has been set, pass SRID - const storedAuctionResponseBid = find(firstBidRequest.bids, bid => (bid.adUnitCode === adUnit.code && bid.storedAuctionResponse)); - if (storedAuctionResponseBid) { - utils.deepSetValue(imp, 'ext.prebid.storedauctionresponse.id', storedAuctionResponseBid.storedAuctionResponse.toString()); - } - - const getFloorBid = find(firstBidRequest.bids, bid => bid.adUnitCode === adUnit.code && typeof bid.getFloor === 'function'); - - if (getFloorBid) { - let floorInfo; - try { - floorInfo = getFloorBid.getFloor({ - currency: config.getConfig('currency.adServerCurrency') || DEFAULT_S2S_CURRENCY, - }); - } catch (e) { - utils.logError('PBS: getFloor threw an error: ', e); - } - if (floorInfo && floorInfo.currency && !isNaN(parseFloat(floorInfo.floor))) { - imp.bidfloor = parseFloat(floorInfo.floor); - imp.bidfloorcur = floorInfo.currency - } - } - - if (imp.banner || imp.video || imp.native) { - imps.push(imp); - } - }); - - if (!imps.length) { - utils.logError('Request to Prebid Server rejected due to invalid media type(s) in adUnit.'); - return; - } - const request = { - id: s2sBidRequest.tid, - source: {tid: s2sBidRequest.tid}, - tmax: s2sConfig.timeout, - imp: imps, - test: getConfig('debug') ? 1 : 0, - ext: { - prebid: { - // set ext.prebid.auctiontimestamp with the auction timestamp. Data type is long integer. - auctiontimestamp: firstBidRequest.auctionStart, - targeting: { - // includewinners is always true for openrtb - includewinners: true, - // includebidderkeys always false for openrtb - includebidderkeys: false - } - } - } - }; - - // Sets pbjs version, can be overwritten below if channel exists in s2sConfig.extPrebid - request.ext.prebid = Object.assign(request.ext.prebid, {channel: {name: 'pbjs', version: $$PREBID_GLOBAL$$.version}}) - - // s2sConfig video.ext.prebid is passed through openrtb to PBS - if (s2sConfig.extPrebid && typeof s2sConfig.extPrebid === 'object') { - request.ext.prebid = Object.assign(request.ext.prebid, s2sConfig.extPrebid); - } - - /** - * @type {(string[]|string|undefined)} - OpenRTB property 'cur', currencies available for bids - */ - const adServerCur = config.getConfig('currency.adServerCurrency'); - if (adServerCur && typeof adServerCur === 'string') { - // if the value is a string, wrap it with an array - request.cur = [adServerCur]; - } else if (Array.isArray(adServerCur) && adServerCur.length) { - // if it's an array, get the first element - request.cur = [adServerCur[0]]; - } - - _appendSiteAppDevice(request, bidRequests[0].refererInfo.referer, s2sConfig.accountId); - - // pass schain object if it is present - const schain = utils.deepAccess(bidRequests, '0.bids.0.schain'); - if (schain) { - request.source.ext = { - schain: schain - }; - } - - if (!utils.isEmpty(aliases)) { - request.ext.prebid.aliases = {...request.ext.prebid.aliases, ...aliases}; - } - - const bidUserIdAsEids = utils.deepAccess(bidRequests, '0.bids.0.userIdAsEids'); - if (utils.isArray(bidUserIdAsEids) && bidUserIdAsEids.length > 0) { - utils.deepSetValue(request, 'user.ext.eids', bidUserIdAsEids); - } - - if (utils.isArray(eidPermissions) && eidPermissions.length > 0) { - if (requestedBidders && utils.isArray(requestedBidders)) { - eidPermissions.forEach(i => { - if (i.bidders) { - i.bidders = i.bidders.filter(bidder => requestedBidders.includes(bidder)) - } - }); - } - utils.deepSetValue(request, 'ext.prebid.data.eidpermissions', eidPermissions); - } - - const multibid = config.getConfig('multibid'); - if (multibid) { - utils.deepSetValue(request, 'ext.prebid.multibid', multibid.reduce((result, i) => { - let obj = {}; - - Object.keys(i).forEach(key => { - obj[key.toLowerCase()] = i[key]; - }); - - result.push(obj); - - return result; - }, [])); - } - - if (bidRequests) { - if (firstBidRequest.gdprConsent) { - // note - gdprApplies & consentString may be undefined in certain use-cases for consentManagement module - let gdprApplies; - if (typeof firstBidRequest.gdprConsent.gdprApplies === 'boolean') { - gdprApplies = firstBidRequest.gdprConsent.gdprApplies ? 1 : 0; - } - utils.deepSetValue(request, 'regs.ext.gdpr', gdprApplies); - utils.deepSetValue(request, 'user.ext.consent', firstBidRequest.gdprConsent.consentString); - if (firstBidRequest.gdprConsent.addtlConsent && typeof firstBidRequest.gdprConsent.addtlConsent === 'string') { - utils.deepSetValue(request, 'user.ext.ConsentedProvidersSettings.consented_providers', firstBidRequest.gdprConsent.addtlConsent); - } - } - - // US Privacy (CCPA) support - if (firstBidRequest.uspConsent) { - utils.deepSetValue(request, 'regs.ext.us_privacy', firstBidRequest.uspConsent); - } - } - - if (getConfig('coppa') === true) { - utils.deepSetValue(request, 'regs.coppa', 1); - } - - const commonFpd = getConfig('ortb2') || {}; - if (commonFpd.site) { - utils.mergeDeep(request, {site: commonFpd.site}); - } - if (commonFpd.user) { - utils.mergeDeep(request, {user: commonFpd.user}); - } - addBidderFirstPartyDataToRequest(request); - - return request; - }, - - interpretResponse(response, bidderRequests, s2sConfig) { - const bids = []; - - [['errors', 'serverErrors'], ['responsetimemillis', 'serverResponseTimeMs']] - .forEach(info => getPbsResponseData(bidderRequests, response, info[0], info[1])) - - if (response.seatbid) { - // a seatbid object contains a `bid` array and a `seat` string - response.seatbid.forEach(seatbid => { - (seatbid.bid || []).forEach(bid => { - let bidRequest; - let key = `${bid.impid}${seatbid.seat}`; - if (bidIdMap[key]) { - bidRequest = utils.getBidRequest( - bidIdMap[key], - bidderRequests - ); - } - - const cpm = bid.price; - const status = cpm !== 0 ? CONSTANTS.STATUS.GOOD : CONSTANTS.STATUS.NO_BID; - let bidObject = createBid(status, bidRequest || { - bidder: seatbid.seat, - src: TYPE - }); - - bidObject.cpm = cpm; - - // temporarily leaving attaching it to each bidResponse so no breaking change - // BUT: this is a flat map, so it should be only attached to bidderRequest, a the change above does - let serverResponseTimeMs = utils.deepAccess(response, ['ext', 'responsetimemillis', seatbid.seat].join('.')); - if (bidRequest && serverResponseTimeMs) { - bidRequest.serverResponseTimeMs = serverResponseTimeMs; - } - - // Look for seatbid[].bid[].ext.prebid.bidid and place it in the bidResponse object for use in analytics adapters as 'pbsBidId' - const bidId = utils.deepAccess(bid, 'ext.prebid.bidid'); - if (utils.isStr(bidId)) { - bidObject.pbsBidId = bidId; - } - - // store wurl by auctionId and adId so it can be accessed from the BID_WON event handler - if (utils.isStr(utils.deepAccess(bid, 'ext.prebid.events.win'))) { - addWurl(bidRequest.auctionId, bidObject.adId, utils.deepAccess(bid, 'ext.prebid.events.win')); - } - - let extPrebidTargeting = utils.deepAccess(bid, 'ext.prebid.targeting'); - - // If ext.prebid.targeting exists, add it as a property value named 'adserverTargeting' - // The removal of hb_winurl and hb_bidid targeting values is temporary - // once we get through the transition, this block will be removed. - if (utils.isPlainObject(extPrebidTargeting)) { - // If wurl exists, remove hb_winurl and hb_bidid targeting attributes - if (utils.isStr(utils.deepAccess(bid, 'ext.prebid.events.win'))) { - extPrebidTargeting = utils.getDefinedParams(extPrebidTargeting, Object.keys(extPrebidTargeting) - .filter(i => (i.indexOf('hb_winurl') === -1 && i.indexOf('hb_bidid') === -1))); - } - bidObject.adserverTargeting = extPrebidTargeting; - } - - bidObject.seatBidId = bid.id; - - if (utils.deepAccess(bid, 'ext.prebid.type') === VIDEO) { - bidObject.mediaType = VIDEO; - let sizes = bidRequest.sizes && bidRequest.sizes[0]; - bidObject.playerWidth = sizes[0]; - bidObject.playerHeight = sizes[1]; - - // try to get cache values from 'response.ext.prebid.cache.js' - // else try 'bid.ext.prebid.targeting' as fallback - if (bid.ext.prebid.cache && typeof bid.ext.prebid.cache.vastXml === 'object' && bid.ext.prebid.cache.vastXml.cacheId && bid.ext.prebid.cache.vastXml.url) { - bidObject.videoCacheKey = bid.ext.prebid.cache.vastXml.cacheId; - bidObject.vastUrl = bid.ext.prebid.cache.vastXml.url; - } else if (extPrebidTargeting && extPrebidTargeting.hb_uuid && extPrebidTargeting.hb_cache_host && extPrebidTargeting.hb_cache_path) { - bidObject.videoCacheKey = extPrebidTargeting.hb_uuid; - // build url using key and cache host - bidObject.vastUrl = `https://${extPrebidTargeting.hb_cache_host}${extPrebidTargeting.hb_cache_path}?uuid=${extPrebidTargeting.hb_uuid}`; - } - - if (bid.adm) { bidObject.vastXml = bid.adm; } - if (!bidObject.vastUrl && bid.nurl) { bidObject.vastUrl = bid.nurl; } - } else if (utils.deepAccess(bid, 'ext.prebid.type') === NATIVE) { - bidObject.mediaType = NATIVE; - let adm; - if (typeof bid.adm === 'string') { - adm = bidObject.adm = JSON.parse(bid.adm); - } else { - adm = bidObject.adm = bid.adm; - } - - let trackers = { - [nativeEventTrackerMethodMap.img]: adm.imptrackers || [], - [nativeEventTrackerMethodMap.js]: adm.jstracker ? [adm.jstracker] : [] - }; - if (adm.eventtrackers) { - adm.eventtrackers.forEach(tracker => { - switch (tracker.method) { - case nativeEventTrackerMethodMap.img: - trackers[nativeEventTrackerMethodMap.img].push(tracker.url); - break; - case nativeEventTrackerMethodMap.js: - trackers[nativeEventTrackerMethodMap.js].push(tracker.url); - break; - } - }); - } - - if (utils.isPlainObject(adm) && Array.isArray(adm.assets)) { - let origAssets = nativeAssetCache[bidRequest.adUnitCode]; - bidObject.native = utils.cleanObj(adm.assets.reduce((native, asset) => { - let origAsset = origAssets[asset.id]; - if (utils.isPlainObject(asset.img)) { - native[origAsset.img.type ? nativeImgIdMap[origAsset.img.type] : 'image'] = utils.pick( - asset.img, - ['url', 'w as width', 'h as height'] - ); - } else if (utils.isPlainObject(asset.title)) { - native['title'] = asset.title.text - } else if (utils.isPlainObject(asset.data)) { - nativeDataNames.forEach(dataType => { - if (nativeDataIdMap[dataType] === origAsset.data.type) { - native[dataType] = asset.data.value; - } - }); - } - return native; - }, utils.cleanObj({ - clickUrl: adm.link, - clickTrackers: utils.deepAccess(adm, 'link.clicktrackers'), - impressionTrackers: trackers[nativeEventTrackerMethodMap.img], - javascriptTrackers: trackers[nativeEventTrackerMethodMap.js] - }))); - } else { - utils.logError('prebid server native response contained no assets'); - } - } else { // banner - if (bid.adm && bid.nurl) { - bidObject.ad = bid.adm; - bidObject.ad += utils.createTrackPixelHtml(decodeURIComponent(bid.nurl)); - } else if (bid.adm) { - bidObject.ad = bid.adm; - } else if (bid.nurl) { - bidObject.adUrl = bid.nurl; - } - } - - bidObject.width = bid.w; - bidObject.height = bid.h; - if (bid.dealid) { bidObject.dealId = bid.dealid; } - bidObject.requestId = bidRequest.bidId || bidRequest.bid_Id; - bidObject.creative_id = bid.crid; - bidObject.creativeId = bid.crid; - if (bid.burl) { bidObject.burl = bid.burl; } - bidObject.currency = (response.cur) ? response.cur : DEFAULT_S2S_CURRENCY; - bidObject.meta = bidObject.meta || {}; - if (bid.ext && bid.ext.dchain) { bidObject.meta.dchain = utils.deepClone(bid.ext.dchain); } - if (bid.adomain) { bidObject.meta.advertiserDomains = bid.adomain; } - - // the OpenRTB location for "TTL" as understood by Prebid.js is "exp" (expiration). - const configTtl = s2sConfig.defaultTtl || DEFAULT_S2S_TTL; - bidObject.ttl = (bid.exp) ? bid.exp : configTtl; - bidObject.netRevenue = (bid.netRevenue) ? bid.netRevenue : DEFAULT_S2S_NETREVENUE; - - bids.push({ adUnit: bid.impid, bid: bidObject }); - }); - }); - } - - return bids; - } -}; - -/** - * BID_WON event to request the wurl - * @param {Bid} bid the winning bid object - */ -function bidWonHandler(bid) { - const wurl = getWurl(bid.auctionId, bid.adId); - if (utils.isStr(wurl)) { - utils.logMessage(`Invoking image pixel for wurl on BID_WIN: "${wurl}"`); - utils.triggerPixel(wurl); - - // remove from wurl cache, since the wurl url was called - removeWurl(bid.auctionId, bid.adId); - } -} - -function hasPurpose1Consent(gdprConsent) { - let result = true; - if (gdprConsent) { - if (gdprConsent.gdprApplies && gdprConsent.apiVersion === 2) { - result = !!(utils.deepAccess(gdprConsent, 'vendorData.purpose.consents.1') === true); - } - } - return result; -} - -function getMatchingConsentUrl(urlProp, gdprConsent) { - return hasPurpose1Consent(gdprConsent) ? urlProp.p1Consent : urlProp.noP1Consent; -} - -function getConsentData(bidRequests) { - let gdprConsent, uspConsent; - if (Array.isArray(bidRequests) && bidRequests.length > 0) { - gdprConsent = bidRequests[0].gdprConsent; - uspConsent = bidRequests[0].uspConsent; - } - return { gdprConsent, uspConsent }; -} - -/** - * Bidder adapter for Prebid Server - */ -export function PrebidServer() { - const baseAdapter = new Adapter('prebidServer'); - - /* Prebid executes this function when the page asks to send out bid requests */ - baseAdapter.callBids = function(s2sBidRequest, bidRequests, addBidResponse, done, ajax) { - const adUnits = utils.deepClone(s2sBidRequest.ad_units); - let { gdprConsent, uspConsent } = getConsentData(bidRequests); - - // at this point ad units should have a size array either directly or mapped so filter for that - const validAdUnits = adUnits.filter(unit => - unit.mediaTypes && (unit.mediaTypes.native || (unit.mediaTypes.banner && unit.mediaTypes.banner.sizes) || (unit.mediaTypes.video && unit.mediaTypes.video.playerSize)) - ); - - // in case config.bidders contains invalid bidders, we only process those we sent requests for - const requestedBidders = validAdUnits - .map(adUnit => adUnit.bids.map(bid => bid.bidder).filter(utils.uniques)) - .reduce(utils.flatten) - .filter(utils.uniques); - - if (Array.isArray(_s2sConfigs)) { - if (s2sBidRequest.s2sConfig && s2sBidRequest.s2sConfig.syncEndpoint && getMatchingConsentUrl(s2sBidRequest.s2sConfig.syncEndpoint, gdprConsent)) { - let syncBidders = s2sBidRequest.s2sConfig.bidders - .map(bidder => adapterManager.aliasRegistry[bidder] || bidder) - .filter((bidder, index, array) => (array.indexOf(bidder) === index)); - - queueSync(syncBidders, gdprConsent, uspConsent, s2sBidRequest.s2sConfig); - } - - const request = OPEN_RTB_PROTOCOL.buildRequest(s2sBidRequest, bidRequests, validAdUnits, s2sBidRequest.s2sConfig, requestedBidders); - const requestJson = request && JSON.stringify(request); - utils.logInfo('BidRequest: ' + requestJson); - if (request && requestJson) { - ajax( - getMatchingConsentUrl(s2sBidRequest.s2sConfig.endpoint, gdprConsent), - { - success: response => handleResponse(response, requestedBidders, bidRequests, addBidResponse, done, s2sBidRequest.s2sConfig), - error: done - }, - requestJson, - { contentType: 'text/plain', withCredentials: true } - ); - } - } - }; - - /* Notify Prebid of bid responses so bids can get in the auction */ - function handleResponse(response, requestedBidders, bidderRequests, addBidResponse, done, s2sConfig) { - let result; - let bids = []; - let { gdprConsent, uspConsent } = getConsentData(bidderRequests); - - try { - result = JSON.parse(response); - - bids = OPEN_RTB_PROTOCOL.interpretResponse( - result, - bidderRequests, - s2sConfig - ); - - bids.forEach(({adUnit, bid}) => { - if (isValid(adUnit, bid, bidderRequests)) { - addBidResponse(adUnit, bid); - } - }); - - bidderRequests.forEach(bidderRequest => events.emit(CONSTANTS.EVENTS.BIDDER_DONE, bidderRequest)); - } catch (error) { - utils.logError(error); - } - - if (!result || (result.status && includes(result.status, 'Error'))) { - utils.logError('error parsing response: ', result.status); - } - - done(); - doClientSideSyncs(requestedBidders, gdprConsent, uspConsent); - } - - // Listen for bid won to call wurl - events.on(CONSTANTS.EVENTS.BID_WON, bidWonHandler); - - return Object.assign(this, { - callBids: baseAdapter.callBids, - setBidderCode: baseAdapter.setBidderCode, - type: TYPE - }); -} - -/** - * Global setter that sets eids permissions for bidders - * This setter is to be used by userId module when included - * @param {array} newEidPermissions - */ -function setEidPermissions(newEidPermissions) { - eidPermissions = newEidPermissions; -} -getPrebidInternal().setEidPermissions = setEidPermissions; - -adapterManager.registerBidAdapter(new PrebidServer(), 'prebidServer'); diff --git a/modules/prebidmanagerAnalyticsAdapter.js b/modules/prebidmanagerAnalyticsAdapter.js deleted file mode 100644 index b9a7d79f991..00000000000 --- a/modules/prebidmanagerAnalyticsAdapter.js +++ /dev/null @@ -1,236 +0,0 @@ -import {ajaxBuilder} from '../src/ajax.js'; -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -import { getStorageManager } from '../src/storageManager.js'; - -/** - * prebidmanagerAnalyticsAdapter.js - analytics adapter for prebidmanager - */ -export const storage = getStorageManager(undefined, 'prebidmanager'); -const DEFAULT_EVENT_URL = 'https://endpoint.prebidmanager.com/endpoint' -const analyticsType = 'endpoint'; -const analyticsName = 'Prebid Manager Analytics: '; - -var utils = require('../src/utils.js'); -var CONSTANTS = require('../src/constants.json'); -let ajax = ajaxBuilder(0); - -var _VERSION = 1; -var initOptions = null; -var _pageViewId = utils.generateUUID(); -var _startAuction = 0; -var _bidRequestTimeout = 0; -let flushInterval; -var pmAnalyticsEnabled = false; -const utmTags = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']; - -var w = window; -var d = document; -var e = d.documentElement; -var g = d.getElementsByTagName('body')[0]; -var x = w.innerWidth || e.clientWidth || g.clientWidth; -var y = w.innerHeight || e.clientHeight || g.clientHeight; - -var _pageView = { - eventType: 'pageView', - userAgent: window.navigator.userAgent, - timestamp: Date.now(), - timezoneOffset: new Date().getTimezoneOffset(), - language: window.navigator.language, - vendor: window.navigator.vendor, - screenWidth: x, - screenHeight: y -}; - -var _eventQueue = [ - _pageView -]; - -let prebidmanagerAnalytics = Object.assign(adapter({url: DEFAULT_EVENT_URL, analyticsType}), { - track({eventType, args}) { - handleEvent(eventType, args); - } -}); - -prebidmanagerAnalytics.originEnableAnalytics = prebidmanagerAnalytics.enableAnalytics; -prebidmanagerAnalytics.enableAnalytics = function (config) { - initOptions = config.options || {}; - initOptions.url = initOptions.url || DEFAULT_EVENT_URL; - pmAnalyticsEnabled = true; - prebidmanagerAnalytics.originEnableAnalytics(config); - flushInterval = setInterval(flush, 1000); -}; - -prebidmanagerAnalytics.originDisableAnalytics = prebidmanagerAnalytics.disableAnalytics; -prebidmanagerAnalytics.disableAnalytics = function() { - if (!pmAnalyticsEnabled) { - return; - } - flush(); - clearInterval(flushInterval); - prebidmanagerAnalytics.originDisableAnalytics(); -}; - -function collectUtmTagData() { - let newUtm = false; - let pmUtmTags = {}; - try { - utmTags.forEach(function (utmKey) { - let utmValue = utils.getParameterByName(utmKey); - if (utmValue !== '') { - newUtm = true; - } - pmUtmTags[utmKey] = utmValue; - }); - if (newUtm === false) { - utmTags.forEach(function (utmKey) { - let itemValue = storage.getDataFromLocalStorage(`pm_${utmKey}`); - if (itemValue && itemValue.length !== 0) { - pmUtmTags[utmKey] = itemValue; - } - }); - } else { - utmTags.forEach(function (utmKey) { - storage.setDataInLocalStorage(`pm_${utmKey}`, pmUtmTags[utmKey]); - }); - } - } catch (e) { - utils.logError(`${analyticsName}Error`, e); - pmUtmTags['error_utm'] = 1; - } - return pmUtmTags; -} - -function collectPageInfo() { - const pageInfo = { - domain: window.location.hostname, - } - if (document.referrer) { - pageInfo.referrerDomain = utils.parseUrl(document.referrer).hostname; - } - return pageInfo; -} - -function flush() { - if (!pmAnalyticsEnabled) { - return; - } - - if (_eventQueue.length > 1) { - var data = { - pageViewId: _pageViewId, - ver: _VERSION, - bundleId: initOptions.bundleId, - events: _eventQueue, - utmTags: collectUtmTagData(), - pageInfo: collectPageInfo(), - }; - - ajax( - initOptions.url, - () => utils.logInfo(`${analyticsName} sent events batch`), - _VERSION + ':' + JSON.stringify(data), - { - contentType: 'text/plain', - method: 'POST', - withCredentials: true - } - ); - _eventQueue = [ - _pageView - ]; - } -} - -function handleEvent(eventType, eventArgs) { - eventArgs = eventArgs ? JSON.parse(JSON.stringify(eventArgs)) : {}; - var pmEvent = {}; - - switch (eventType) { - case CONSTANTS.EVENTS.AUCTION_INIT: { - pmEvent = eventArgs; - _startAuction = pmEvent.timestamp; - _bidRequestTimeout = pmEvent.timeout; - break; - } - case CONSTANTS.EVENTS.AUCTION_END: { - pmEvent = eventArgs; - pmEvent.start = _startAuction; - pmEvent.end = Date.now(); - break; - } - case CONSTANTS.EVENTS.BID_ADJUSTMENT: { - pmEvent.bidders = eventArgs; - break; - } - case CONSTANTS.EVENTS.BID_TIMEOUT: { - pmEvent.bidders = eventArgs; - pmEvent.duration = _bidRequestTimeout; - break; - } - case CONSTANTS.EVENTS.BID_REQUESTED: { - pmEvent = eventArgs; - break; - } - case CONSTANTS.EVENTS.BID_RESPONSE: { - pmEvent = eventArgs; - delete pmEvent.ad; - break; - } - case CONSTANTS.EVENTS.BID_WON: { - pmEvent = eventArgs; - delete pmEvent.ad; - delete pmEvent.adUrl; - break; - } - case CONSTANTS.EVENTS.BIDDER_DONE: { - pmEvent = eventArgs; - break; - } - case CONSTANTS.EVENTS.SET_TARGETING: { - pmEvent.targetings = eventArgs; - break; - } - case CONSTANTS.EVENTS.REQUEST_BIDS: { - pmEvent = eventArgs; - break; - } - case CONSTANTS.EVENTS.ADD_AD_UNITS: { - pmEvent = eventArgs; - break; - } - case CONSTANTS.EVENTS.AD_RENDER_FAILED: { - pmEvent = eventArgs; - break; - } - default: - return; - } - - pmEvent.eventType = eventType; - pmEvent.timestamp = pmEvent.timestamp || Date.now(); - - sendEvent(pmEvent); -} - -function sendEvent(event) { - _eventQueue.push(event); - utils.logInfo(`${analyticsName}Event ${event.eventType}:`, event); - - if (event.eventType === CONSTANTS.EVENTS.AUCTION_END) { - flush(); - } -} - -adapterManager.registerAnalyticsAdapter({ - adapter: prebidmanagerAnalytics, - code: 'prebidmanager' -}); - -prebidmanagerAnalytics.getOptions = function () { - return initOptions; -}; - -prebidmanagerAnalytics.flush = flush; - -export default prebidmanagerAnalytics; diff --git a/modules/prebidmanagerAnalyticsAdapter.md b/modules/prebidmanagerAnalyticsAdapter.md deleted file mode 100644 index 030e79b406f..00000000000 --- a/modules/prebidmanagerAnalyticsAdapter.md +++ /dev/null @@ -1,9 +0,0 @@ -# Overview - -Module Name: Prebid Manager Analytics Adapter -Module Type: Analytics Adapter -Maintainer: admin@prebidmanager.com - -# Description - -Analytics adapter for Prebid Manager. Contact admin@prebidmanager.com for information. diff --git a/modules/priceFloors.js b/modules/priceFloors.js deleted file mode 100644 index 3555fedbf3a..00000000000 --- a/modules/priceFloors.js +++ /dev/null @@ -1,723 +0,0 @@ -import { getGlobal } from '../src/prebidGlobal.js'; -import { config } from '../src/config.js'; -import * as utils from '../src/utils.js'; -import { ajaxBuilder } from '../src/ajax.js'; -import events from '../src/events.js'; -import CONSTANTS from '../src/constants.json'; -import { getHook } from '../src/hook.js'; -import { createBid } from '../src/bidfactory.js'; -import find from 'core-js-pure/features/array/find.js'; -import { getRefererInfo } from '../src/refererDetection.js'; - -/** - * @summary This Module is intended to provide users with the ability to dynamically set and enforce price floors on a per auction basis. - */ -const MODULE_NAME = 'Price Floors'; - -/** - * @summary Instantiate Ajax so we control the timeout - */ -const ajax = ajaxBuilder(10000); - -/** - * @summary Allowed fields for rules to have - */ -export let allowedFields = ['gptSlot', 'adUnitCode', 'size', 'domain', 'mediaType']; - -/** - * @summary This is a flag to indicate if a AJAX call is processing for a floors request -*/ -let fetching = false; - -/** - * @summary so we only register for our hooks once -*/ -let addedFloorsHook = false; - -/** - * @summary The config to be used. Can be updated via: setConfig or a real time fetch - */ -let _floorsConfig = {}; - -/** - * @summary If a auction is to be delayed by an ongoing fetch we hold it here until it can be resumed - */ -let _delayedAuctions = []; - -/** - * @summary Each auction can have differing floors data depending on execution time or per adunit setup - * So we will be saving each auction offset by it's auctionId in order to make sure data is not changed - * Once the auction commences - */ -export let _floorDataForAuction = {}; - -/** - * @summary Simple function to round up to a certain decimal degree - */ -function roundUp(number, precision) { - return Math.ceil((parseFloat(number) * Math.pow(10, precision)).toFixed(1)) / Math.pow(10, precision); -} - -let referrerHostname; -function getHostNameFromReferer(referer) { - referrerHostname = utils.parseUrl(referer, {noDecodeWholeURL: true}).hostname; - return referrerHostname; -} - -/** - * @summary floor field types with their matching functions to resolve the actual matched value - */ -export let fieldMatchingFunctions = { - 'size': (bidRequest, bidResponse) => utils.parseGPTSingleSizeArray(bidResponse.size) || '*', - 'mediaType': (bidRequest, bidResponse) => bidResponse.mediaType || 'banner', - 'gptSlot': (bidRequest, bidResponse) => utils.getGptSlotInfoForAdUnitCode(bidRequest.adUnitCode).gptSlot, - 'domain': (bidRequest, bidResponse) => referrerHostname || getHostNameFromReferer(getRefererInfo().referer), - 'adUnitCode': (bidRequest, bidResponse) => bidRequest.adUnitCode -} - -/** - * @summary Based on the fields array in floors data, it enumerates all possible matches based on exact match coupled with - * a "*" catch-all match - * Returns array of Tuple [exact match, catch all] for each field in rules file - */ -function enumeratePossibleFieldValues(floorFields, bidObject, responseObject) { - // generate combination of all exact matches and catch all for each field type - return floorFields.reduce((accum, field) => { - let exactMatch = fieldMatchingFunctions[field](bidObject, responseObject) || '*'; - // storing exact matches as lowerCase since we want to compare case insensitively - accum.push(exactMatch === '*' ? ['*'] : [exactMatch.toLowerCase(), '*']); - return accum; - }, []); -} - -/** - * @summary get's the first matching floor based on context provided. - * Generates all possible rule matches and picks the first matching one. - */ -export function getFirstMatchingFloor(floorData, bidObject, responseObject = {}) { - let fieldValues = enumeratePossibleFieldValues(utils.deepAccess(floorData, 'schema.fields') || [], bidObject, responseObject); - if (!fieldValues.length) return { matchingFloor: floorData.default }; - - // look to see if a request for this context was made already - let matchingInput = fieldValues.map(field => field[0]).join('-'); - // if we already have gotten the matching rule from this matching input then use it! No need to look again - let previousMatch = utils.deepAccess(floorData, `matchingInputs.${matchingInput}`); - if (previousMatch) { - return {...previousMatch}; - } - let allPossibleMatches = generatePossibleEnumerations(fieldValues, utils.deepAccess(floorData, 'schema.delimiter') || '|'); - let matchingRule = find(allPossibleMatches, hashValue => floorData.values.hasOwnProperty(hashValue)); - - let matchingData = { - floorMin: floorData.floorMin || 0, - floorRuleValue: floorData.values[matchingRule] || floorData.default, - matchingData: allPossibleMatches[0], // the first possible match is an "exact" so contains all data relevant for anlaytics adapters - matchingRule - }; - matchingData.matchingFloor = Math.max(matchingData.floorMin, matchingData.floorRuleValue); - // save for later lookup if needed - utils.deepSetValue(floorData, `matchingInputs.${matchingInput}`, {...matchingData}); - return matchingData; -} - -/** - * @summary Generates all possible rule hash's based on input array of array's - * The generated list is of all possible key matches based on fields input - * The list is sorted by least amount of * in rule to most with left most fields taking precedence - */ -function generatePossibleEnumerations(arrayOfFields, delimiter) { - return arrayOfFields.reduce((accum, currentVal) => { - let ret = []; - accum.map(obj => { - currentVal.map(obj1 => { - ret.push(obj + delimiter + obj1) - }); - }); - return ret; - }).sort((left, right) => left.split('*').length - right.split('*').length); -} - -/** - * @summary If a the input bidder has a registered cpmadjustment it returns the input CPM after being adjusted - */ -export function getBiddersCpmAdjustment(bidderName, inputCpm, bid = {}) { - const adjustmentFunction = utils.deepAccess(getGlobal(), `bidderSettings.${bidderName}.bidCpmAdjustment`) || utils.deepAccess(getGlobal(), 'bidderSettings.standard.bidCpmAdjustment'); - if (adjustmentFunction) { - return parseFloat(adjustmentFunction(inputCpm, {...bid, cpm: inputCpm})); - } - return parseFloat(inputCpm); -} - -/** - * @summary This function takes the original floor and the adjusted floor in order to determine the bidders actual floor - * With js rounding errors with decimal division we utilize similar method as shown in cpmBucketManager.js - */ -export function calculateAdjustedFloor(oldFloor, newFloor) { - const pow = Math.pow(10, 10); - return ((oldFloor * pow) / (newFloor * pow) * (oldFloor * pow)) / pow; -} - -/** - * @summary gets the prebid set sizes depending on the input mediaType - */ -const getMediaTypesSizes = { - banner: (bid) => utils.deepAccess(bid, 'mediaTypes.banner.sizes') || [], - video: (bid) => utils.deepAccess(bid, 'mediaTypes.video.playerSize') || [], - native: (bid) => utils.deepAccess(bid, 'mediaTypes.native.image.sizes') ? [utils.deepAccess(bid, 'mediaTypes.native.image.sizes')] : [] -} - -/** - * @summary for getFloor only, before selecting a rule, if a bidAdapter asks for * in their getFloor params - * Then we may be able to get a better rule than the * ones depending on context of the adUnit - */ -function updateRequestParamsFromContext(bidRequest, requestParams) { - // if adapter asks for *'s then we can do some logic to infer if we can get a more specific rule based on context of bid - let mediaTypesOnBid = Object.keys(bidRequest.mediaTypes || {}); - // if there is only one mediaType then we can just use it - if (requestParams.mediaType === '*' && mediaTypesOnBid.length === 1) { - requestParams.mediaType = mediaTypesOnBid[0]; - } - // if they asked for * size, but for the given mediaType there is only one size, we can just use it - if (requestParams.size === '*' && mediaTypesOnBid.indexOf(requestParams.mediaType) !== -1 && getMediaTypesSizes[requestParams.mediaType] && getMediaTypesSizes[requestParams.mediaType](bidRequest).length === 1) { - requestParams.size = getMediaTypesSizes[requestParams.mediaType](bidRequest)[0]; - } - return requestParams; -} - -/** - * @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 = {currency: 'USD', mediaType: '*', size: '*'}) { - let bidRequest = this; - let floorData = _floorDataForAuction[bidRequest.auctionId]; - if (!floorData || floorData.skipped) return {}; - - requestParams = updateRequestParamsFromContext(bidRequest, requestParams); - let 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 - if (floorInfo.matchingFloor && currency !== floorData.data.currency) { - try { - floorInfo.matchingFloor = getGlobal().convertCurrency(floorInfo.matchingFloor, floorData.data.currency, currency); - } catch (err) { - utils.logWarn(`${MODULE_NAME}: Unable to get currency conversion for getFloor for bidder ${bidRequest.bidder}. You must have currency module enabled with defaultRates in your currency config`); - // since we were unable to convert to the bidders requested currency, we send back just the actual floors currency to them - currency = floorData.data.currency; - } - } - - // if cpmAdjustment flag is true and we have a valid floor then run the adjustment on it - if (floorData.enforcement.bidAdjustment && floorInfo.matchingFloor) { - let cpmAdjustment = getBiddersCpmAdjustment(bidRequest.bidder, floorInfo.matchingFloor); - floorInfo.matchingFloor = cpmAdjustment ? calculateAdjustedFloor(floorInfo.matchingFloor, cpmAdjustment) : floorInfo.matchingFloor; - } - - if (floorInfo.matchingFloor) { - return { - floor: roundUp(floorInfo.matchingFloor, 4), - currency, - }; - } - return {}; -} - -/** - * @summary Takes a floorsData object and converts it into a hash map with appropriate keys - */ -export function getFloorsDataForAuction(floorData, adUnitCode) { - let auctionFloorData = utils.deepClone(floorData); - auctionFloorData.schema.delimiter = floorData.schema.delimiter || '|'; - auctionFloorData.values = normalizeRulesForAuction(auctionFloorData, adUnitCode); - // default the currency to USD if not passed in - auctionFloorData.currency = auctionFloorData.currency || 'USD'; - return auctionFloorData; -} - -/** - * @summary if adUnitCode needs to be added to the offset then it will add it else just return the values - */ -function normalizeRulesForAuction(floorData, adUnitCode) { - let fields = floorData.schema.fields; - let delimiter = floorData.schema.delimiter - - // if we are building the floor data form an ad unit, we need to append adUnit code as to not cause collisions - let prependAdUnitCode = adUnitCode && fields.indexOf('adUnitCode') === -1 && fields.unshift('adUnitCode'); - return Object.keys(floorData.values).reduce((rulesHash, oldKey) => { - let newKey = prependAdUnitCode ? `${adUnitCode}${delimiter}${oldKey}` : oldKey - // we store the rule keys as lower case for case insensitive compare - rulesHash[newKey.toLowerCase()] = floorData.values[oldKey]; - return rulesHash; - }, {}); -} - -/** - * @summary This function will take the adUnits and generate a floor data object to be used during the auction - * Only called if no set config or fetch level data has returned - */ -export function getFloorDataFromAdUnits(adUnits) { - return adUnits.reduce((accum, adUnit) => { - if (isFloorsDataValid(adUnit.floors)) { - // if values already exist we want to not overwrite them - if (!accum.values) { - accum = getFloorsDataForAuction(adUnit.floors, adUnit.code); - accum.location = 'adUnit'; - } else { - let newRules = getFloorsDataForAuction(adUnit.floors, adUnit.code).values; - // copy over the new rules into our values object - Object.assign(accum.values, newRules); - } - } - return accum; - }, {}); -} - -/** - * @summary This function takes the adUnits for the auction and update them accordingly as well as returns the rules hashmap for the auction - */ -export function updateAdUnitsForAuction(adUnits, floorData, auctionId) { - adUnits.forEach((adUnit) => { - adUnit.bids.forEach(bid => { - if (floorData.skipped) { - delete bid.getFloor; - } else { - bid.getFloor = getFloor; - } - // information for bid and analytics adapters - bid.auctionId = auctionId; - bid.floorData = { - skipped: floorData.skipped, - skipRate: floorData.skipRate, - floorMin: floorData.floorMin, - modelVersion: utils.deepAccess(floorData, 'data.modelVersion'), - modelWeight: utils.deepAccess(floorData, 'data.modelWeight'), - modelTimestamp: utils.deepAccess(floorData, 'data.modelTimestamp'), - location: utils.deepAccess(floorData, 'data.location', 'noData'), - floorProvider: floorData.floorProvider, - fetchStatus: _floorsConfig.fetchStatus - }; - }); - }); -} - -export function pickRandomModel(modelGroups, weightSum) { - // we loop through the models subtracting the current model weight from our random number - // once we are at or below zero, we return the associated model - let random = Math.floor(Math.random() * weightSum + 1) - for (let i = 0; i < modelGroups.length; i++) { - random -= modelGroups[i].modelWeight; - if (random <= 0) { - return modelGroups[i]; - } - } -}; - -/** - * @summary Updates the adUnits accordingly and returns the necessary floorsData for the current auction - */ -export function createFloorsDataForAuction(adUnits, auctionId) { - let resolvedFloorsData = utils.deepClone(_floorsConfig); - // if using schema 2 pick a model here: - if (utils.deepAccess(resolvedFloorsData, 'data.floorsSchemaVersion') === 2) { - // merge the models specific stuff into the top level data settings (now it looks like floorsSchemaVersion 1!) - let { modelGroups, ...rest } = resolvedFloorsData.data; - resolvedFloorsData.data = Object.assign(rest, pickRandomModel(modelGroups, rest.modelWeightSum)); - } - - // if we do not have a floors data set, we will try to use data set on adUnits - let useAdUnitData = Object.keys(utils.deepAccess(resolvedFloorsData, 'data.values') || {}).length === 0; - if (useAdUnitData) { - resolvedFloorsData.data = getFloorDataFromAdUnits(adUnits); - } else { - resolvedFloorsData.data = getFloorsDataForAuction(resolvedFloorsData.data); - } - // if we still do not have a valid floor data then floors is not on for this auction, so skip - if (Object.keys(utils.deepAccess(resolvedFloorsData, 'data.values') || {}).length === 0) { - resolvedFloorsData.skipped = true; - } else { - // determine the skip rate now - const auctionSkipRate = utils.getParameterByName('pbjs_skipRate') || resolvedFloorsData.skipRate; - const isSkipped = Math.random() * 100 < parseFloat(auctionSkipRate); - resolvedFloorsData.skipped = isSkipped; - } - // copy FloorMin to floorData.data - if (resolvedFloorsData.hasOwnProperty('floorMin')) resolvedFloorsData.data.floorMin = resolvedFloorsData.floorMin; - // add floorData to bids - updateAdUnitsForAuction(adUnits, resolvedFloorsData, auctionId); - return resolvedFloorsData; -} - -/** - * @summary This is the function which will be called to exit our module and continue the auction. - */ -export function continueAuction(hookConfig) { - // only run if hasExited - if (!hookConfig.hasExited) { - // if this current auction is still fetching, remove it from the _delayedAuctions - _delayedAuctions = _delayedAuctions.filter(auctionConfig => auctionConfig.timer !== hookConfig.timer); - - // We need to know the auctionId at this time. So we will use the passed in one or generate and set it ourselves - hookConfig.reqBidsConfigObj.auctionId = hookConfig.reqBidsConfigObj.auctionId || utils.generateUUID(); - - // now we do what we need to with adUnits and save the data object to be used for getFloor and enforcement calls - _floorDataForAuction[hookConfig.reqBidsConfigObj.auctionId] = createFloorsDataForAuction(hookConfig.reqBidsConfigObj.adUnits || getGlobal().adUnits, hookConfig.reqBidsConfigObj.auctionId); - - hookConfig.nextFn.apply(hookConfig.context, [hookConfig.reqBidsConfigObj]); - hookConfig.hasExited = true; - } -} - -function validateSchemaFields(fields) { - if (Array.isArray(fields) && fields.length > 0 && fields.every(field => allowedFields.indexOf(field) !== -1)) { - return true; - } - utils.logError(`${MODULE_NAME}: Fields recieved do not match allowed fields`); - return false; -} - -function isValidRule(key, floor, numFields, delimiter) { - if (typeof key !== 'string' || key.split(delimiter).length !== numFields) { - return false; - } - return typeof floor === 'number'; -} - -function validateRules(floorsData, numFields, delimiter) { - if (typeof floorsData.values !== 'object') { - return false; - } - // if an invalid rule exists we remove it - floorsData.values = Object.keys(floorsData.values).reduce((filteredRules, key) => { - if (isValidRule(key, floorsData.values[key], numFields, delimiter)) { - filteredRules[key] = floorsData.values[key]; - } - return filteredRules - }, {}); - // rules is only valid if at least one rule remains - return Object.keys(floorsData.values).length > 0; -} - -function modelIsValid(model) { - // schema.fields has only allowed attributes - if (!validateSchemaFields(utils.deepAccess(model, 'schema.fields'))) { - return false; - } - return validateRules(model, model.schema.fields.length, model.schema.delimiter || '|') -} - -/** - * @summary Mapping of floor schema version to it's corresponding validation - */ -const floorsSchemaValidation = { - 1: data => modelIsValid(data), - 2: data => { - // model groups should be an array with at least one element - if (!Array.isArray(data.modelGroups) || data.modelGroups.length === 0) { - return false; - } - // every model should have valid schema, as well as an accompanying modelWeight - data.modelWeightSum = 0; - return data.modelGroups.every(model => { - if (typeof model.modelWeight === 'number' && modelIsValid(model)) { - data.modelWeightSum += model.modelWeight; - return true; - } - return false; - }); - } -}; - -/** - * @summary Fields array should have at least one entry and all should match allowed fields - * Each rule in the values array should have a 'key' and 'floor' param - * And each 'key' should have the correct number of 'fields' after splitting - * on the delim. If rule does not match remove it. return if still at least 1 rule - */ -export function isFloorsDataValid(floorsData) { - if (typeof floorsData !== 'object') { - return false; - } - floorsData.floorsSchemaVersion = floorsData.floorsSchemaVersion || 1; - if (typeof floorsSchemaValidation[floorsData.floorsSchemaVersion] !== 'function') { - utils.logError(`${MODULE_NAME}: Unknown floorsSchemaVersion: `, floorsData.floorsSchemaVersion); - return false; - } - return floorsSchemaValidation[floorsData.floorsSchemaVersion](floorsData); -} - -/** - * @summary This function updates the global Floors Data field based on the new one passed in if it is valid - */ -export function parseFloorData(floorsData, location) { - if (floorsData && typeof floorsData === 'object' && isFloorsDataValid(floorsData)) { - utils.logInfo(`${MODULE_NAME}: A ${location} set the auction floor data set to `, floorsData); - return { - ...floorsData, - location - }; - } - utils.logError(`${MODULE_NAME}: The floors data did not contain correct values`, floorsData); -} - -/** - * - * @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.js - */ -export function requestBidsHook(fn, reqBidsConfigObj) { - // preserves all module related variables for the current auction instance (used primiarily for concurrent auctions) - const hookConfig = { - reqBidsConfigObj, - context: this, - nextFn: fn, - haveExited: false, - timer: null - }; - - // If auction delay > 0 AND we are fetching -> Then wait until it finishes - if (_floorsConfig.auctionDelay > 0 && fetching) { - hookConfig.timer = setTimeout(() => { - utils.logWarn(`${MODULE_NAME}: Fetch attempt did not return in time for auction`); - _floorsConfig.fetchStatus = 'timeout'; - continueAuction(hookConfig); - }, _floorsConfig.auctionDelay); - _delayedAuctions.push(hookConfig); - } else { - continueAuction(hookConfig); - } -} - -/** - * @summary If an auction was queued to be delayed (waiting for a fetch) then this function will resume - * those delayed auctions when delay is hit or success return or fail return - */ -function resumeDelayedAuctions() { - _delayedAuctions.forEach(auctionConfig => { - // clear the timeout - clearTimeout(auctionConfig.timer); - continueAuction(auctionConfig); - }); - _delayedAuctions = []; -} - -/** - * This function handles the ajax response which comes from the user set URL to fetch floors data from - * @param {object} fetchResponse The floors data response which came back from the url configured in config.floors - */ -export function handleFetchResponse(fetchResponse) { - fetching = false; - _floorsConfig.fetchStatus = 'success'; - let floorResponse; - try { - floorResponse = JSON.parse(fetchResponse); - } catch (ex) { - floorResponse = fetchResponse; - } - // Update the global floors object according to the fetched data - const fetchData = parseFloorData(floorResponse, 'fetch'); - if (fetchData) { - // set .data to it - _floorsConfig.data = fetchData; - // set skipRate override if necessary - _floorsConfig.skipRate = utils.isNumber(fetchData.skipRate) ? fetchData.skipRate : _floorsConfig.skipRate; - _floorsConfig.floorProvider = fetchData.floorProvider || _floorsConfig.floorProvider; - } - - // if any auctions are waiting for fetch to finish, we need to continue them! - resumeDelayedAuctions(); -} - -function handleFetchError(status) { - fetching = false; - _floorsConfig.fetchStatus = 'error'; - utils.logError(`${MODULE_NAME}: Fetch errored with: `, status); - - // if any auctions are waiting for fetch to finish, we need to continue them! - resumeDelayedAuctions(); -} - -/** - * This function handles sending and recieving the AJAX call for a floors fetch - * @param {object} floorsConfig the floors config coming from setConfig - */ -export function generateAndHandleFetch(floorEndpoint) { - // if a fetch url is defined and one is not already occuring, fire it! - if (floorEndpoint.url && !fetching) { - // default to GET and we only support GET for now - let requestMethod = floorEndpoint.method || 'GET'; - if (requestMethod !== 'GET') { - utils.logError(`${MODULE_NAME}: 'GET' is the only request method supported at this time!`); - } else { - ajax(floorEndpoint.url, { success: handleFetchResponse, error: handleFetchError }, null, { method: 'GET' }); - fetching = true; - } - } else if (fetching) { - utils.logWarn(`${MODULE_NAME}: A fetch is already occuring. Skipping.`); - } -} - -/** - * @summary Updates our allowedFields and fieldMatchingFunctions with the publisher defined new ones - */ -function addFieldOverrides(overrides) { - Object.keys(overrides).forEach(override => { - // we only add it if it is not already in the allowed fields and if the passed in value is a function - if (allowedFields.indexOf(override) === -1 && typeof overrides[override] === 'function') { - allowedFields.push(override); - fieldMatchingFunctions[override] = overrides[override]; - } - }); -} - -/** - * @summary This is the function which controls what happens during a pbjs.setConfig({...floors: {}}) is called - */ -export function handleSetFloorsConfig(config) { - _floorsConfig = utils.pick(config, [ - 'floorMin', - 'enabled', enabled => enabled !== false, // defaults to true - 'auctionDelay', auctionDelay => auctionDelay || 0, - 'floorProvider', floorProvider => utils.deepAccess(config, 'data.floorProvider', floorProvider), - 'endpoint', endpoint => endpoint || {}, - 'skipRate', () => !isNaN(utils.deepAccess(config, 'data.skipRate')) ? config.data.skipRate : config.skipRate || 0, - 'enforcement', enforcement => utils.pick(enforcement || {}, [ - 'enforceJS', enforceJS => enforceJS !== false, // defaults to true - 'enforcePBS', enforcePBS => enforcePBS === true, // defaults to false - 'floorDeals', floorDeals => floorDeals === true, // defaults to false - 'bidAdjustment', bidAdjustment => bidAdjustment !== false, // defaults to true - ]), - 'additionalSchemaFields', additionalSchemaFields => typeof additionalSchemaFields === 'object' && Object.keys(additionalSchemaFields).length > 0 ? addFieldOverrides(additionalSchemaFields) : undefined, - 'data', data => (data && parseFloorData(data, 'setConfig')) || _floorsConfig.data // do not overwrite if passed in data not valid - ]); - - // if enabled then do some stuff - if (_floorsConfig.enabled) { - // handle the floors fetch - generateAndHandleFetch(_floorsConfig.endpoint); - - if (!addedFloorsHook) { - // register hooks / listening events - // when auction finishes remove it's associated floor data after 3 seconds so we stil have it for latent responses - events.on(CONSTANTS.EVENTS.AUCTION_END, (args) => { - setTimeout(() => delete _floorDataForAuction[args.auctionId], 3000); - }); - - // we want our hooks to run after the currency hooks - getGlobal().requestBids.before(requestBidsHook, 50); - // if user has debug on then we want to allow the debugging module to run before this, assuming they are testing priceFloors - // debugging is currently set at 5 priority - getHook('addBidResponse').before(addBidResponseHook, utils.debugTurnedOn() ? 4 : 50); - addedFloorsHook = true; - } - } else { - utils.logInfo(`${MODULE_NAME}: Turning off module`); - - _floorsConfig = {}; - _floorDataForAuction = {}; - - getHook('addBidResponse').getHooks({hook: addBidResponseHook}).remove(); - getGlobal().requestBids.getHooks({hook: requestBidsHook}).remove(); - - addedFloorsHook = false; - } -} - -/** - * @summary Analytics adapters especially need context of what the floors module is doing in order - * to best create informed models. This function attaches necessary information to the bidResponse object for processing - */ -function addFloorDataToBid(floorData, floorInfo, bid, adjustedCpm) { - bid.floorData = { - floorValue: floorInfo.matchingFloor, - floorRule: floorInfo.matchingRule, - floorRuleValue: floorInfo.floorRuleValue, - floorCurrency: floorData.data.currency, - cpmAfterAdjustments: adjustedCpm, - enforcements: {...floorData.enforcement}, - matchedFields: {} - }; - floorData.data.schema.fields.forEach((field, index) => { - let matchedValue = floorInfo.matchingData.split(floorData.data.schema.delimiter)[index]; - bid.floorData.matchedFields[field] = matchedValue; - }); -} - -/** - * @summary takes the enforcement flags and the bid itself and determines if it should be floored - */ -function shouldFloorBid(floorData, floorInfo, bid) { - let enforceJS = utils.deepAccess(floorData, 'enforcement.enforceJS') !== false; - let shouldFloorDeal = utils.deepAccess(floorData, 'enforcement.floorDeals') === true || !bid.dealId; - let bidBelowFloor = bid.floorData.cpmAfterAdjustments < floorInfo.matchingFloor; - return enforceJS && (bidBelowFloor && shouldFloorDeal); -} - -/** - * @summary The main driving force of floors. On bidResponse we hook in and intercept bidResponses. - * And if the rule we find determines a bid should be floored we will do so. - */ -export function addBidResponseHook(fn, adUnitCode, bid) { - let floorData = _floorDataForAuction[this.bidderRequest.auctionId]; - // if no floor data or associated bidRequest then bail - const matchingBidRequest = find(this.bidderRequest.bids, bidRequest => bidRequest.bidId && bidRequest.bidId === bid.requestId); - if (!floorData || !bid || floorData.skipped || !matchingBidRequest) { - return fn.call(this, adUnitCode, bid); - } - - // get the matching rule - let floorInfo = getFirstMatchingFloor(floorData.data, {...matchingBidRequest}, {...bid, size: [bid.width, bid.height]}); - - if (!floorInfo.matchingFloor) { - utils.logWarn(`${MODULE_NAME}: unable to determine a matching price floor for bidResponse`, bid); - return fn.call(this, adUnitCode, bid); - } - - // determine the base cpm to use based on if the currency matches the floor currency - let adjustedCpm; - let floorCurrency = floorData.data.currency.toUpperCase(); - let bidResponseCurrency = bid.currency || 'USD'; // if an adapter does not set a bid currency and currency module not on it may come in as undefined - if (floorCurrency === bidResponseCurrency.toUpperCase()) { - adjustedCpm = bid.cpm; - } else if (bid.originalCurrency && floorCurrency === bid.originalCurrency.toUpperCase()) { - adjustedCpm = bid.originalCpm; - } else { - try { - adjustedCpm = getGlobal().convertCurrency(bid.cpm, bidResponseCurrency.toUpperCase(), floorCurrency); - } catch (err) { - utils.logError(`${MODULE_NAME}: Unable do get currency conversion for bidResponse to Floor Currency. Do you have Currency module enabled? ${bid}`); - return fn.call(this, adUnitCode, bid); - } - } - - // ok we got the bid response cpm in our desired currency. Now we need to run the bidders CPMAdjustment function if it exists - adjustedCpm = getBiddersCpmAdjustment(bid.bidderCode, adjustedCpm, bid); - - // add necessary data information for analytics adapters / floor providers would possibly need - addFloorDataToBid(floorData, floorInfo, bid, adjustedCpm); - - // now do the compare! - if (shouldFloorBid(floorData, floorInfo, bid)) { - // bid fails floor -> throw it out - // create basic bid no-bid with necessary data fro analytics adapters - let flooredBid = createBid(CONSTANTS.STATUS.NO_BID, matchingBidRequest); - Object.assign(flooredBid, utils.pick(bid, [ - 'floorData', - 'width', - 'height', - 'mediaType', - 'currency', - 'originalCpm', - 'originalCurrency', - 'getCpmInNewCurrency', - ])); - flooredBid.status = CONSTANTS.BID_STATUS.BID_REJECTED; - // if floor not met update bid with 0 cpm so it is not included downstream and marked as no-bid - flooredBid.cpm = 0; - utils.logWarn(`${MODULE_NAME}: ${flooredBid.bidderCode}'s Bid Response for ${adUnitCode} was rejected due to floor not met`, bid); - return fn.call(this, adUnitCode, flooredBid); - } - return fn.call(this, adUnitCode, bid); -} - -config.getConfig('floors', config => handleSetFloorsConfig(config.floors)); diff --git a/modules/priceFloors.md b/modules/priceFloors.md deleted file mode 100644 index 36ac07ee972..00000000000 --- a/modules/priceFloors.md +++ /dev/null @@ -1,64 +0,0 @@ -## Dynamic Price Floors - -### Setup -```javascript -pbjs.setConfig({ - floors: { - enabled: true, //defaults to true - enforcement: { - floorDeals: false, //defaults to false - bidAdjustment: true, //defaults to true - enforceJS: true //defaults to true - }, - auctionDelay: 150, // in milliseconds defaults to 0 - floorProvider: 'awesomeFloorProviderName', // name of the floor provider (optional) - endpoint: { - url: 'http://localhost:1500/floor-domains', - method: 'GET' // Only get supported for now - }, - data: { - schema: { - fields: ['mediaType', 'size'] - }, - values: { - 'banner|300x250': 0.86, - 'banner|300x600': 0.97, - 'banner|728x90': 1.12, - 'banner|*': 0.54, - 'video|640x480': 6.76, - 'video|1152x648': 11.76, - 'video|*': 4.55, - '*|*': 0.30 - }, - default: 0.01 - } - } -}); -``` - -| Parameter | Description | -|------------------------|---------------------------------------------------------------------------------------------------------------------| -| enabled | Wether to turn off or on the floors module | -| enforcement | object of booleans which control certain features of the module | -| auctionDelay | The time to suspend and auction while waiting for a real time price floors fetch to come back | -| floorProvider | A string identifying the floor provider.| -| endpoint | An object describing the endpoint to retrieve floor data from. GET only | -| data | The data to be used to select appropriate floors. See schema for more detail | -| additionalSchemaFields | An object of additional fields to be used in a floor data object. The schema is KEY: function to retrieve the match | - -### Passing floors to Bid Adapters -Because it is possible for many rules to match any given bidRequest, (wether it be due to more than one size or more than one mediaType), an encapsolated function is to be passed to bidders which will allow bidders to have insight as to what the floor could be. - -The function `getFloor` will be attached to every bidRequestObject passed to bid adapters if the price floors are enabled for a given auction. - -This function can takes in an object with the following optional parameters: - -| Parameter | Description | Example | Default | -|-----------|------------------------------------------------------------------------|------------|---------| -| currency | The 3 character currency code which the bid adapter wants the floor in | "JPY" | "USD" | -| mediaType | The specific mediaType to get a floor for | "banner" | "*" | -| size | The specific size to get a matching floor on | [300, 250] | "*" | - -If a bid adapter passes in `*` as an attribute, then the `priceFloors` module will attempt to select the best rule based on context. - -For example, if an adapter passes in a `*`, but the bidRequest only has a single size and a single mediaType, then the `getFloor` function will attempt to get a rule for that size before matching with the `*` catch-all. Similarily, if mediaType can be inferred on the bidRequest, it will use it. diff --git a/modules/projectLimeLightBidAdapter.js b/modules/projectLimeLightBidAdapter.js deleted file mode 100644 index 1beba906917..00000000000 --- a/modules/projectLimeLightBidAdapter.js +++ /dev/null @@ -1,122 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import {ajax} from '../src/ajax.js'; -import * as utils from '../src/utils.js'; - -const BIDDER_CODE = 'project-limelight'; - -/** - * Determines whether or not the given bid response is valid. - * - * @param {object} bid The bid to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastXml || bid.vastUrl); - } - return false; -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {object} bid The bid to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && bid.params); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: (validBidRequests, bidderRequest) => { - let winTop; - try { - winTop = window.top; - winTop.location.toString(); - } catch (e) { - utils.logMessage(e); - winTop = window; - } - const placements = utils.groupBy(validBidRequests.map(bidRequest => buildPlacement(bidRequest)), 'host') - return Object.keys(placements) - .map(host => buildRequest(winTop, host, placements[host].map(placement => placement.adUnit))); - }, - - onBidWon: (bid) => { - const cpm = bid.pbMg; - if (bid.nurl !== '') { - bid.nurl = bid.nurl.replace( - /\$\{AUCTION_PRICE\}/, - cpm - ); - ajax(bid.nurl, null); - }; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: (bidResponses) => { - const res = []; - const bidResponsesBody = bidResponses.body; - const len = bidResponsesBody.length; - for (let i = 0; i < len; i++) { - const bid = bidResponsesBody[i]; - if (isBidResponseValid(bid)) { - res.push(bid); - } - } - return res; - }, -}; - -registerBidder(spec); - -function buildRequest(winTop, host, adUnits) { - return { - method: 'POST', - url: `https://${host}/hb`, - data: { - secure: (location.protocol === 'https:'), - deviceWidth: winTop.screen.width, - deviceHeight: winTop.screen.height, - adUnits: adUnits - } - } -} - -function buildPlacement(bidRequest) { - return { - host: bidRequest.params.host, - adUnit: { - id: bidRequest.params.adUnitId, - bidId: bidRequest.bidId, - transactionId: bidRequest.transactionId, - sizes: bidRequest.sizes.map(size => { - return { - width: size[0], - height: size[1] - } - }), - type: bidRequest.params.adUnitType.toUpperCase() - } - } -} diff --git a/modules/projectLimeLightBidAdapter.md b/modules/projectLimeLightBidAdapter.md deleted file mode 100644 index 15aa170cd2e..00000000000 --- a/modules/projectLimeLightBidAdapter.md +++ /dev/null @@ -1,57 +0,0 @@ -# Overview - -``` -Module Name: Project LimeLight SSP Adapter -Module Type: Bidder Adapter -Maintainer: engineering@project-limelight.com -``` - -# Description - -Module that connects to Project Limelight SSP demand sources - -# Test Parameters for banner -``` - var adUnits = [{ - code: 'placementCode', - sizes: [[300, 250]], - bids: [{ - bidder: 'project-limelight', - params: { - host: 'ads.project-limelight.com', - adUnitId: 0, - adUnitType: 'banner' - } - }] - } - ]; -``` - -# Test Parameters for video -``` -var videoAdUnit = [{ - code: 'video1', - sizes: [[300, 250]], - bids: [{ - bidder: 'project-limelight', - params: { - host: 'ads.project-limelight.com', - adUnitId: 0, - adUnitType: 'video' - } - }] - }]; -``` - -# Configuration - -The Project Limelight Bid Adapter expects Prebid Cache(for video) to be enabled so that we can store and retrieve a single vastXml. - -``` -pbjs.setConfig({ - usePrebidCache: true, - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } -}); -``` diff --git a/modules/proxistoreBidAdapter.js b/modules/proxistoreBidAdapter.js deleted file mode 100644 index ff07ee9ede9..00000000000 --- a/modules/proxistoreBidAdapter.js +++ /dev/null @@ -1,151 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -const BIDDER_CODE = 'proxistore'; -const PROXISTORE_VENDOR_ID = 418; - -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 = { - auctionId: bidRequests[0].auctionId, - transactionId: bidRequests[0].auctionId, - bids: sizeIds, - website: bidRequests[0].params.website, - language: bidRequests[0].params.language, - gdpr: { - applies: false, - consentGiven: false - }, - }; - - if (bidderRequest && bidderRequest.gdprConsent) { - const { gdprConsent } = bidderRequest; - if (typeof gdprConsent.gdprApplies === 'boolean' && gdprConsent.gdprApplies) { - payload.gdpr.applies = true; - } - - if (typeof gdprConsent.consentString === 'string' && gdprConsent.consentString) { - payload.gdpr.consentString = bidderRequest.gdprConsent.consentString; - } - if (gdprConsent.vendorData) { - const {vendorData} = gdprConsent; - const {apiVersion} = gdprConsent; - if (apiVersion === 2 && vendorData.vendor && vendorData.vendor.consents && typeof vendorData.vendor.consents[PROXISTORE_VENDOR_ID.toString(10)] !== 'undefined') { - payload.gdpr.consentGiven = !!vendorData.vendor.consents[PROXISTORE_VENDOR_ID.toString(10)]; - } else if (apiVersion === 1 && vendorData.vendorConsents && typeof vendorData.vendorConsents[PROXISTORE_VENDOR_ID.toString(10)] !== 'undefined') { - payload.gdpr.consentGiven = !!vendorData.vendorConsents[PROXISTORE_VENDOR_ID.toString(10)]; - } - } - } - - const options = { - contentType: 'application/json', - withCredentials: payload.gdpr.consentGiven, - }; - - const endPointUri = payload.gdpr.consentGiven || !payload.gdpr.applies - ? `https://abs.proxistore.com/${payload.language}/v3/rtb/prebid/multi` - : `https://abs.cookieless-proxistore.com/${payload.language}/v3/rtb/prebid/multi`; - - return { - method: 'POST', - url: endPointUri, - data: JSON.stringify(payload), - options: options, - }; -} - -function _assignSegments(bid) { - if (bid.ortb2 && bid.ortb2.user && bid.ortb2.user.ext && bid.ortb2.user.ext.data) { - return bid.ortb2.user.ext.data || {segments: [], contextual_categories: {}}; - } - return {segments: [], contextual_categories: {}}; -} - -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, - }; -} -/** - * 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); -} -/** - * 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. - * - * @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. - */ - -function interpretResponse(serverResponse, bidRequest) { - return serverResponse.body.map(_createBidResponse); -} - -function _assignFloor(bid) { - if (typeof bid.getFloor === 'function') { - var floorInfo = bid.getFloor({ - currency: 'EUR', - mediaType: 'banner', - size: '*', - }); - - if (floorInfo.currency === 'EUR') { - return floorInfo.floor; - } - } - - return null; -} - -export const spec = { - code: BIDDER_CODE, - isBidRequestValid: isBidRequestValid, - buildRequests: buildRequests, - interpretResponse: interpretResponse, - -}; - -registerBidder(spec); diff --git a/modules/proxistoreBidAdapter.md b/modules/proxistoreBidAdapter.md deleted file mode 100644 index e958d52c321..00000000000 --- a/modules/proxistoreBidAdapter.md +++ /dev/null @@ -1,73 +0,0 @@ -# Overview - -``` -Module Name: Proxistore Bid Adapter -Module Type: Bidder Adapter -GDPR compliant: true -``` - -# Description - -Connects any publisher to Proxistore.com's exchange for bids. - -The present document is available [online](https://abs.proxistore.com/scripts/proxistore-prebid-adapter.md); -the companion Javascript file is available [online](https://abs.proxistore.com/scripts/proxistore-prebid-adapter.js) as well. - -# Sample Ad Unit: For Publishers - -Parameters: -* website: __Required__ - Publisher website as registered with Proxistore - __Each publisher must get this value from Proxistore__ -* language: __Required__ - Publisher website language - Must be one of __fr__,__nl__,__es__ - -Example for a website 'example.com' in French - -``` -var adUnits = [ -{ - code: 'half-page', - mediaTypes: { - banner: { - sizes: [[300,600]] - } - }, - bids: [ - { - bidder: 'proxistore', - params: { - website: 'example.com', - language: 'fr' - } - }] -}, -{ - code: 'rectangle', - mediaTypes: { - banner: { - sizes: [[300,250]] - } - }, - bids: [{ - bidder: 'proxistore', - params: { - website: 'example.com', - language: 'fr' - } - }] -}, -{ - code: 'leaderboard', - mediaTypes: { - banner: { - sizes: [[970,250]] - } - }, - bids: [{ - bidder: 'proxistore', - params: { - website: 'example.com', - language: 'fr' - } - }] -} -]; -``` diff --git a/modules/pubCommonId.js b/modules/pubCommonId.js deleted file mode 100644 index 427f775c44b..00000000000 --- a/modules/pubCommonId.js +++ /dev/null @@ -1,297 +0,0 @@ -/** - * This modules adds Publisher Common ID support to prebid.js. It's a simple numeric id - * stored in the page's domain. When the module is included, an id is generated if needed, - * persisted as a cookie, and automatically appended to all the bidRequest as bid.crumbs.pubcid. - */ -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; -import events from '../src/events.js'; -import CONSTANTS from '../src/constants.json'; -import { getStorageManager } from '../src/storageManager.js'; - -const storage = getStorageManager(); - -const ID_NAME = '_pubcid'; -const OPTOUT_NAME = '_pubcid_optout'; -const DEFAULT_EXPIRES = 525600; // 1-year worth of minutes -const PUB_COMMON = 'PublisherCommonId'; -const EXP_SUFFIX = '_exp'; -const COOKIE = 'cookie'; -const LOCAL_STORAGE = 'html5'; - -let pubcidConfig = { - enabled: true, - interval: DEFAULT_EXPIRES, - typeEnabled: LOCAL_STORAGE, - create: true, - extend: true, - pixelUrl: '' -}; - -/** - * Set an item in the storage with expiry time. - * @param {string} key Key of the item to be stored - * @param {string} val Value of the item to be stored - * @param {number} expires Expiry time in minutes - */ - -export function setStorageItem(key, val, expires) { - try { - if (expires !== undefined && expires != null) { - const expStr = (new Date(Date.now() + (expires * 60 * 1000))).toUTCString(); - storage.setDataInLocalStorage(key + EXP_SUFFIX, expStr); - } - - storage.setDataInLocalStorage(key, val); - } catch (e) { - utils.logMessage(e); - } -} - -/** - * Retrieve an item from storage if it exists and hasn't expired. - * @param {string} key Key of the item. - * @returns {string|null} Value of the item. - */ -export function getStorageItem(key) { - let val = null; - - try { - const expVal = storage.getDataFromLocalStorage(key + EXP_SUFFIX); - - if (!expVal) { - // If there is no expiry time, then just return the item - val = storage.getDataFromLocalStorage(key); - } else { - // Only return the item if it hasn't expired yet. - // Otherwise delete the item. - const expDate = new Date(expVal); - const isValid = (expDate.getTime() - Date.now()) > 0; - if (isValid) { - val = storage.getDataFromLocalStorage(key); - } else { - removeStorageItem(key); - } - } - } catch (e) { - utils.logMessage(e); - } - - return val; -} - -/** - * Remove an item from storage - * @param {string} key Key of the item to be removed - */ -export function removeStorageItem(key) { - try { - storage.removeDataFromLocalStorage(key + EXP_SUFFIX); - storage.removeDataFromLocalStorage(key); - } catch (e) { - utils.logMessage(e); - } -} - -/** - * Read a value either from cookie or local storage - * @param {string} name Name of the item - * @param {string} type storage type override - * @returns {string|null} a string if item exists - */ -function readValue(name, type) { - let value; - if (!type) { type = pubcidConfig.typeEnabled; } - if (type === COOKIE) { - value = storage.getCookie(name); - } else if (type === LOCAL_STORAGE) { - value = getStorageItem(name); - } - - if (value === 'undefined' || value === 'null') { return null; } - - return value; -} - -/** - * Write a value to either cookies or local storage - * @param {string} name Name of the item - * @param {string} value Value to be stored - * @param {number} expInterval Expiry time in minutes - */ -function writeValue(name, value, expInterval) { - if (name && value) { - if (pubcidConfig.typeEnabled === COOKIE) { - setCookie(name, value, expInterval, 'Lax'); - } else if (pubcidConfig.typeEnabled === LOCAL_STORAGE) { - setStorageItem(name, value, expInterval); - } - } -} - -/** - * Add a callback at end of auction to fetch a pixel - * @param {string} pixelUrl Pixel URL - * @param {string} id pubcid - * @returns {boolean} True if callback is queued - */ -function queuePixelCallback(pixelUrl, id) { - if (!pixelUrl) { return false; } - - id = id || ''; - - // Use pubcid as a cache buster - const urlInfo = utils.parseUrl(pixelUrl); - urlInfo.search.id = encodeURIComponent('pubcid:' + id); - const targetUrl = utils.buildUrl(urlInfo); - - events.on(CONSTANTS.EVENTS.AUCTION_END, function auctionEndHandler() { - events.off(CONSTANTS.EVENTS.AUCTION_END, auctionEndHandler); - utils.triggerPixel(targetUrl); - }); - - return true; -} - -export function isPubcidEnabled() { return pubcidConfig.enabled; } -export function getExpInterval() { return pubcidConfig.interval; } -export function getPubcidConfig() { return pubcidConfig; } - -/** - * Decorate ad units with pubcid. This hook function is called before the - * real pbjs.requestBids is invoked, and can modify its parameter. The cookie is - * not updated until this function is called. - * @param {Object} config This is the same parameter as pbjs.requestBids, and config.adUnits will be updated. - * @param {function} next The next function in the chain - */ - -export function requestBidHook(next, config) { - let adUnits = config.adUnits || $$PREBID_GLOBAL$$.adUnits; - let pubcid = null; - - // Pass control to the next function if not enabled - if (!pubcidConfig.enabled || !pubcidConfig.typeEnabled) { - return next.call(this, config); - } - - if (typeof window[PUB_COMMON] === 'object') { - // If the page includes its own pubcid object, then use that instead. - pubcid = window[PUB_COMMON].getId(); - utils.logMessage(PUB_COMMON + ': pubcid = ' + pubcid); - } else { - // Otherwise get the existing cookie - pubcid = readValue(ID_NAME); - - if (!pubcid) { - if (pubcidConfig.create) { - // Special handling for local storage to retain previously stored id in cookies - if (pubcidConfig.typeEnabled === LOCAL_STORAGE) { - pubcid = readValue(ID_NAME, COOKIE); - } - // Generate a new id - if (!pubcid) { - pubcid = utils.generateUUID(); - } - // Update the cookie/storage with the latest expiration date - writeValue(ID_NAME, pubcid, pubcidConfig.interval); - // Only return pubcid if it is saved successfully - pubcid = readValue(ID_NAME); - } - queuePixelCallback(pubcidConfig.pixelUrl, pubcid); - } else if (pubcidConfig.extend) { - // Update the cookie/storage with the latest expiration date - if (!queuePixelCallback(pubcidConfig.pixelUrl, pubcid)) { - writeValue(ID_NAME, pubcid, pubcidConfig.interval); - } - } - - utils.logMessage('pbjs: pubcid = ' + pubcid); - } - - // Append pubcid to each bid object, which will be incorporated - // into bid requests later. - if (adUnits && pubcid) { - adUnits.forEach((unit) => { - if (unit.bids && utils.isArray(unit.bids)) { - unit.bids.forEach((bid) => { - Object.assign(bid, {crumbs: {pubcid}}); - }); - } - }); - } - - return next.call(this, config); -} - -// Helper to set a cookie -export function setCookie(name, value, expires, sameSite) { - let expTime = new Date(); - expTime.setTime(expTime.getTime() + expires * 1000 * 60); - storage.setCookie(name, value, expTime.toGMTString(), sameSite); -} - -// Helper to read a cookie -export function getCookie(name) { - return storage.getCookie(name); -} - -/** - * Configuration function - * @param {boolean} enable Enable or disable pubcid. By default the module is enabled. - * @param {number} expInterval Expiration interval of the cookie in minutes. - * @param {string} type Type of storage to use - * @param {boolean} create Create the id if missing. Default is true. - * @param {boolean} extend Extend the stored value when id is retrieved. Default is true. - * @param {string} pixelUrl A pixel URL back to the publisher's own domain that may modify cookie attributes. - */ - -export function setConfig({ enable, expInterval, type = 'html5,cookie', create, extend, pixelUrl } = {}) { - if (enable !== undefined) { pubcidConfig.enabled = enable; } - - if (expInterval !== undefined) { pubcidConfig.interval = parseInt(expInterval, 10); } - - if (isNaN(pubcidConfig.interval)) { - pubcidConfig.interval = DEFAULT_EXPIRES; - } - - if (create !== undefined) { pubcidConfig.create = create; } - if (extend !== undefined) { pubcidConfig.extend = extend; } - if (pixelUrl !== undefined) { pubcidConfig.pixelUrl = pixelUrl; } - - // Default is to use local storage. Fall back to - // cookie only if local storage is not supported. - - pubcidConfig.typeEnabled = null; - - const typeArray = type.split(','); - for (let i = 0; i < typeArray.length; ++i) { - const name = typeArray[i].trim(); - if (name === COOKIE) { - if (storage.cookiesAreEnabled()) { - pubcidConfig.typeEnabled = COOKIE; - break; - } - } else if (name === LOCAL_STORAGE) { - if (storage.hasLocalStorage()) { - pubcidConfig.typeEnabled = LOCAL_STORAGE; - break; - } - } - } -} - -/** - * Initialize module by 1) subscribe to configuration changes and 2) register hook - */ -export function initPubcid() { - config.getConfig('pubcid', config => setConfig(config.pubcid)); - - const optout = (storage.cookiesAreEnabled() && readValue(OPTOUT_NAME, COOKIE)) || - (storage.hasLocalStorage() && readValue(OPTOUT_NAME, LOCAL_STORAGE)); - - if (!optout) { - $$PREBID_GLOBAL$$.requestBids.before(requestBidHook); - } -} - -initPubcid(); diff --git a/modules/pubCommonId.md b/modules/pubCommonId.md deleted file mode 100644 index 79531bfe87c..00000000000 --- a/modules/pubCommonId.md +++ /dev/null @@ -1,37 +0,0 @@ -## Publisher Common ID Example Configuration - -When the module is included, it's automatically enabled and saves an id to both cookie and local storage with an expiration time of 1 year. - -Example of disabling publisher common id. - -``` -pbjs.setConfig( - pubcid: { - enable: false - } -); -``` - -Example of setting expiration interval to 30 days. The interval is expressed in minutes. - -``` -pbjs.setConfig( - pubcid: { - expInterval: 43200 - } -); -``` - -Example of using local storage only and setting expiration interval to 30 days. - -``` -pbjs.setConfig( - pubcid: { - expInterval: 43200, - type: 'html5' - } -); -``` - - - diff --git a/modules/pubCommonIdSystem.js b/modules/pubCommonIdSystem.js deleted file mode 100644 index 95e539a4d6a..00000000000 --- a/modules/pubCommonIdSystem.js +++ /dev/null @@ -1,345 +0,0 @@ -/** - * This module adds PubCommonId to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/pubCommonIdSystem - * @requires module:modules/userId - */ - -import * as utils from '../src/utils.js'; -import {submodule} from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {ajax} from '../src/ajax.js'; -import { uspDataHandler, coppaDataHandler } from '../src/adapterManager.js'; - -const PUB_COMMON_ID = 'PublisherCommonId'; -const MODULE_NAME = 'pubCommonId'; - -const COOKIE = 'cookie'; -const LOCAL_STORAGE = 'html5'; -const SHAREDID_OPT_OUT_VALUE = '00000000000000000000000000'; -const SHAREDID_URL = 'https://id.sharedid.org/id'; -const SHAREDID_SUFFIX = '_sharedid'; -const EXPIRED_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:01 GMT'; -const SHAREDID_DEFAULT_STATE = false; -const GVLID = 887; - -const storage = getStorageManager(GVLID, 'pubCommonId'); - -/** - * Store sharedid in either cookie or local storage - * @param {Object} config Need config.storage object to derive key, expiry time, and storage type. - * @param {string} value Shareid value to store - */ - -function storeData(config, value) { - try { - if (value) { - const key = config.storage.name + SHAREDID_SUFFIX; - const expiresStr = (new Date(Date.now() + (storage.expires * (60 * 60 * 24 * 1000)))).toUTCString(); - - if (config.storage.type === COOKIE) { - if (storage.cookiesAreEnabled()) { - storage.setCookie(key, value, expiresStr, 'LAX', pubCommonIdSubmodule.domainOverride()); - } - } else if (config.storage.type === LOCAL_STORAGE) { - if (storage.hasLocalStorage()) { - storage.setDataInLocalStorage(`${key}_exp`, expiresStr); - storage.setDataInLocalStorage(key, value); - } - } - } - } catch (error) { - utils.logError(error); - } -} - -/** - * Read sharedid from cookie or local storage - * @param config Need config.storage to derive key and storage type - * @return {string} - */ -function readData(config) { - try { - const key = config.storage.name + SHAREDID_SUFFIX; - if (config.storage.type === COOKIE) { - if (storage.cookiesAreEnabled()) { - return storage.getCookie(key); - } - } else if (config.storage.type === LOCAL_STORAGE) { - if (storage.hasLocalStorage()) { - const expValue = storage.getDataFromLocalStorage(`${key}_exp`); - if (!expValue) { - return storage.getDataFromLocalStorage(key); - } else if ((new Date(expValue)).getTime() - Date.now() > 0) { - return storage.getDataFromLocalStorage(key) - } - } - } - } catch (error) { - utils.logError(error); - } -} - -/** - * Delete sharedid from cookie or local storage - * @param config Need config.storage to derive key and storage type - */ -function delData(config) { - try { - const key = config.storage.name + SHAREDID_SUFFIX; - if (config.storage.type === COOKIE) { - if (storage.cookiesAreEnabled()) { - storage.setCookie(key, '', EXPIRED_COOKIE_DATE); - } - } else if (config.storage.type === LOCAL_STORAGE) { - storage.removeDataFromLocalStorage(`${key}_exp`); - storage.removeDataFromLocalStorage(key); - } - } catch (error) { - utils.logError(error); - } -} - -/** - * setup success and error handler for sharedid callback thru ajax - * @param {string} pubcid Current pubcommon id - * @param {function} callback userId module callback. - * @param {Object} config Need config.storage to derive sharedid storage params - * @return {{success: success, error: error}} - */ - -function handleResponse(pubcid, callback, config) { - return { - success: function (responseBody) { - if (responseBody) { - try { - let responseObj = JSON.parse(responseBody); - utils.logInfo('PubCommonId: Generated SharedId: ' + responseObj.sharedId); - if (responseObj.sharedId) { - if (responseObj.sharedId !== SHAREDID_OPT_OUT_VALUE) { - // Store sharedId locally - storeData(config, responseObj.sharedId); - } else { - // Delete local copy if the user has opted out - delData(config); - } - } - // Pass pubcid even though there is no change in order to trigger decode - callback(pubcid); - } catch (error) { - utils.logError(error); - } - } - }, - error: function (statusText, responseBody) { - utils.logInfo('PubCommonId: failed to get sharedid'); - } - } -} - -/** - * Builds and returns the shared Id URL with attached consent data if applicable - * @param {Object} consentData - * @return {string} - */ -function sharedIdUrl(consentData) { - const usPrivacyString = uspDataHandler.getConsentData(); - let sharedIdUrl = SHAREDID_URL; - if (usPrivacyString && typeof usPrivacyString === 'string') { - sharedIdUrl = `${SHAREDID_URL}?us_privacy=${usPrivacyString}`; - } - if (!consentData || typeof consentData.gdprApplies !== 'boolean' || !consentData.gdprApplies) return sharedIdUrl; - if (usPrivacyString) { - sharedIdUrl = `${sharedIdUrl}&gdpr=1&gdpr_consent=${consentData.consentString}` - return sharedIdUrl; - } - sharedIdUrl = `${SHAREDID_URL}?gdpr=1&gdpr_consent=${consentData.consentString}`; - return sharedIdUrl -} - -/** - * Wraps pixelCallback in order to call sharedid sync - * @param {string} pubcid Pubcommon id value - * @param {function|undefined} pixelCallback fires a pixel to first party server - * @param {Object} config Need config.storage to derive sharedid storage params. - * @return {function(...[*]=)} - */ - -function getIdCallback(pubcid, pixelCallback, config, consentData) { - return function (callback) { - if (typeof pixelCallback === 'function') { - pixelCallback(); - } - ajax(sharedIdUrl(consentData), handleResponse(pubcid, callback, config), undefined, {method: 'GET', withCredentials: true}); - } -} - -/** @type {Submodule} */ -export const pubCommonIdSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: MODULE_NAME, - /** - * Vendor id of prebid - * @type {Number} - */ - gvlid: GVLID, - /** - * Return a callback function that calls the pixelUrl with id as a query parameter - * @param pixelUrl - * @param id - * @returns {function} - */ - makeCallback: function (pixelUrl, id = '') { - if (!pixelUrl) { - return; - } - - // Use pubcid as a cache buster - const urlInfo = utils.parseUrl(pixelUrl); - urlInfo.search.id = encodeURIComponent('pubcid:' + id); - const targetUrl = utils.buildUrl(urlInfo); - - return function () { - utils.triggerPixel(targetUrl); - }; - }, - /** - * decode the stored id value for passing to bid requests - * @function - * @param {string} value - * @param {SubmoduleConfig} config - * @returns {{pubcid:string}} - */ - decode(value, config) { - const idObj = {'pubcid': value}; - const {params: {enableSharedId = SHAREDID_DEFAULT_STATE} = {}} = config; - - if (enableSharedId) { - const sharedId = readData(config); - if (sharedId) idObj['sharedid'] = {id: sharedId}; - } - - return idObj; - }, - /** - * performs action to obtain id - * @function - * @param {SubmoduleConfig} [config] Config object with params and storage properties - * @param {Object} consentData - * @param {string} storedId Existing pubcommon id - * @returns {IdResponse} - */ - getId: function (config = {}, consentData, storedId) { - const coppa = coppaDataHandler.getCoppa(); - if (coppa) { - utils.logInfo('PubCommonId: IDs not provided for coppa requests, exiting PubCommonId'); - return; - } - const {params: {create = true, pixelUrl, enableSharedId = SHAREDID_DEFAULT_STATE} = {}} = config; - let newId = storedId; - if (!newId) { - try { - if (typeof window[PUB_COMMON_ID] === 'object') { - // If the page includes its own pubcid module, then save a copy of id. - newId = window[PUB_COMMON_ID].getId(); - } - } catch (e) { - } - - if (!newId) newId = (create && utils.hasDeviceAccess()) ? utils.generateUUID() : undefined; - } - - const pixelCallback = this.makeCallback(pixelUrl, newId); - const combinedCallback = enableSharedId ? getIdCallback(newId, pixelCallback, config, consentData) : pixelCallback; - - return {id: newId, callback: combinedCallback}; - }, - /** - * performs action to extend an id. There are generally two ways to extend the expiration time - * of stored id: using pixelUrl or return the id and let main user id module write it again with - * the new expiration time. - * - * PixelUrl, if defined, should point back to a first party domain endpoint. On the server - * side, there is either a plugin, or customized logic to read and write back the pubcid cookie. - * The extendId function itself should return only the callback, and not the id itself to avoid - * having the script-side overwriting server-side. This applies to both pubcid and sharedid. - * - * On the other hand, if there is no pixelUrl, then the extendId should return storedId so that - * its expiration time is updated. Sharedid, however, will have to be updated by this submodule - * separately. - * - * @function - * @param {SubmoduleParams} [config] - * @param {ConsentData|undefined} consentData - * @param {Object} storedId existing id - * @returns {IdResponse|undefined} - */ - extendId: function(config = {}, consentData, storedId) { - const coppa = coppaDataHandler.getCoppa(); - if (coppa) { - utils.logInfo('PubCommonId: IDs not provided for coppa requests, exiting PubCommonId'); - return; - } - const {params: {extend = false, pixelUrl, enableSharedId = SHAREDID_DEFAULT_STATE} = {}} = config; - - if (extend) { - try { - if (typeof window[PUB_COMMON_ID] === 'object') { - if (enableSharedId) { - // If the page includes its own pubcid module, then there is nothing to do - // except to update sharedid's expiration time - storeData(config, readData(config)); - } - return; - } - } catch (e) { - } - - if (pixelUrl) { - const callback = this.makeCallback(pixelUrl, storedId); - return {callback: callback}; - } else { - if (enableSharedId) { - // Update with the same value to extend expiration time - storeData(config, readData(config)); - } - return {id: storedId}; - } - } - }, - - /** - * @param {string} domain - * @param {HTMLDocument} document - * @return {(string|undefined)} - */ - domainOverride: function () { - const domainElements = document.domain.split('.'); - const cookieName = `_gd${Date.now()}`; - for (let i = 0, topDomain, testCookie; i < domainElements.length; i++) { - const nextDomain = domainElements.slice(i).join('.'); - - // write test cookie - storage.setCookie(cookieName, '1', undefined, undefined, nextDomain); - - // read test cookie to verify domain was valid - testCookie = storage.getCookie(cookieName); - - // delete test cookie - storage.setCookie(cookieName, '', 'Thu, 01 Jan 1970 00:00:01 GMT', undefined, nextDomain); - - if (testCookie === '1') { - // cookie was written successfully using test domain so the topDomain is updated - topDomain = nextDomain; - } else { - // cookie failed to write using test domain so exit by returning the topDomain - return topDomain; - } - } - } -}; - -submodule('userId', pubCommonIdSubmodule); diff --git a/modules/pubProvidedIdSystem.js b/modules/pubProvidedIdSystem.js deleted file mode 100644 index 0b2175f57cb..00000000000 --- a/modules/pubProvidedIdSystem.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * This module adds Publisher Provided ids support to the User ID module - * The {@link module:modules/userId} module is required. - * @module modules/pubProvidedSystem - * @requires module:modules/userId - */ - -import {submodule} from '../src/hook.js'; -import * as utils from '../src/utils.js'; - -const MODULE_NAME = 'pubProvidedId'; - -/** @type {Submodule} */ -export const pubProvidedIdSubmodule = { - - /** - * used to link submodule with config - * @type {string} - */ - name: MODULE_NAME, - - /** - * decode the stored id value for passing to bid request - * @function - * @param {string} value - * @returns {{pubProvidedId: array}} or undefined if value doesn't exists - */ - decode(value) { - const res = value ? {pubProvidedId: value} : undefined; - utils.logInfo('PubProvidedId: Decoded value ' + JSON.stringify(res)); - return res; - }, - - /** - * performs action to obtain id and return a value. - * @function - * @param {SubmoduleConfig} [config] - * @returns {{id: array}} - */ - getId(config) { - const configParams = (config && config.params) || {}; - let res = []; - if (utils.isArray(configParams.eids)) { - res = res.concat(configParams.eids); - } - if (typeof configParams.eidsFunction === 'function') { - res = res.concat(configParams.eidsFunction()); - } - return {id: res}; - } -}; - -// Register submodule for userId -submodule('userId', pubProvidedIdSubmodule); diff --git a/modules/pubgeniusBidAdapter.js b/modules/pubgeniusBidAdapter.js deleted file mode 100644 index 2df2d25f627..00000000000 --- a/modules/pubgeniusBidAdapter.js +++ /dev/null @@ -1,300 +0,0 @@ -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, - inIframe, - isArrayOfNums, - isFn, - isInteger, - isStr, - logError, - parseQueryStringParameters, - pick, -} from '../src/utils.js'; - -const BIDDER_VERSION = '1.1.0'; -const BASE_URL = 'https://ortb.adpearl.io'; - -export const spec = { - code: 'pubgenius', - - supportedMediaTypes: [ BANNER, VIDEO ], - - isBidRequestValid(bid) { - const adUnitId = bid.params.adUnitId; - if (!isStr(adUnitId) && !isInteger(adUnitId)) { - logError('pubgenius bidder params: adUnitId must be a string or integer.'); - return false; - } - - const { mediaTypes } = bid; - - if (mediaTypes.banner) { - return isValidBanner(mediaTypes.banner); - } - - return isValidVideo(mediaTypes.video, bid.params.video); - }, - - buildRequests: function (bidRequests, bidderRequest) { - const data = { - id: bidderRequest.auctionId, - imp: bidRequests.map(buildImp), - tmax: bidderRequest.timeout, - ext: { - pbadapter: { - version: BIDDER_VERSION, - }, - }, - }; - - const site = buildSite(bidderRequest); - if (site) { - data.site = site; - } - - const gdpr = bidderRequest.gdprConsent; - if (gdpr) { - const applies = gdpr.gdprApplies; - const consent = gdpr.consentString; - deepSetValue(data, 'regs.ext.gdpr', numericBoolean(applies)); - if (applies && consent) { - deepSetValue(data, 'user.ext.consent', consent); - } - } - - const usp = bidderRequest.uspConsent; - if (usp) { - deepSetValue(data, 'regs.ext.us_privacy', usp); - } - - const schain = bidRequests[0].schain; - if (schain) { - deepSetValue(data, 'source.ext.schain', schain); - } - - if (config.getConfig('coppa')) { - deepSetValue(data, 'regs.coppa', 1); - } - - const bidUserIdAsEids = deepAccess(bidRequests, '0.userIdAsEids'); - if (bidUserIdAsEids && bidUserIdAsEids.length) { - const eids = bidUserIdAsEids.filter(eid => eid.source === 'adserver.org'); - if (eids.length) { - deepSetValue(data, 'user.ext.eids', eids); - } - } - - return { - method: 'POST', - url: `${getBaseUrl()}/prebid/auction`, - data, - }; - }, - - interpretResponse({ body }) { - const bidResponses = []; - const currency = body.cur || 'USD'; - const seatbids = body.seatbid; - - if (seatbids) { - seatbids.forEach(seatbid => { - seatbid.bid.forEach(bid => { - const bidResponse = interpretBid(bid); - bidResponse.currency = currency; - bidResponses.push(bidResponse); - }); - }); - } - - return bidResponses; - }, - - getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent) { - const syncs = [] - - if (syncOptions.iframeEnabled) { - let params = {}; - - if (gdprConsent) { - params.gdpr = numericBoolean(gdprConsent.gdprApplies); - if (gdprConsent.consentString) { - params.consent = gdprConsent.consentString; - } - } - - if (uspConsent) { - params.us_privacy = uspConsent; - } - - const qs = parseQueryStringParameters(params); - syncs.push({ - type: 'iframe', - url: `${getBaseUrl()}/usersync/pixels.html?${qs}`, - }); - } - - return syncs; - }, - - onTimeout(data) { - ajax(`${getBaseUrl()}/prebid/events?type=timeout`, null, JSON.stringify(data), { - method: 'POST', - }); - }, -}; - -function buildVideoParams(videoMediaType, videoParams) { - videoMediaType = videoMediaType || {}; - const params = pick(videoMediaType, ['api', 'mimes', 'protocols', 'playbackmethod']); - - switch (videoMediaType.context) { - case 'instream': - params.placement = 1; - break; - case 'outstream': - params.placement = 2; - break; - default: - break; - } - - if (videoMediaType.playerSize) { - params.w = videoMediaType.playerSize[0][0]; - params.h = videoMediaType.playerSize[0][1]; - } - - return Object.assign(params, videoParams); -} - -function buildImp(bid) { - const imp = { - id: bid.bidId, - tagid: String(bid.params.adUnitId), - }; - - if (bid.mediaTypes.banner) { - imp.banner = { - format: bid.mediaTypes.banner.sizes.map(size => ({ w: size[0], h: size[1] })), - topframe: numericBoolean(!inIframe()), - }; - } else { - imp.video = buildVideoParams(bid.mediaTypes.video, bid.params.video); - } - - if (isFn(bid.getFloor)) { - const { floor } = bid.getFloor({ - mediaType: bid.mediaTypes.banner ? 'banner' : 'video', - size: '*', - currency: 'USD', - }); - - if (floor) { - imp.bidfloor = floor; - } - } - - const pos = bid.params.position; - if (isInteger(pos)) { - imp.banner.pos = pos; - } - - if (bid.params.test) { - deepSetValue(imp, 'ext.test', 1); - } - - return imp; -} - -function buildSite(bidderRequest) { - let site = null; - const { refererInfo } = bidderRequest; - - const pageUrl = config.getConfig('pageUrl') || refererInfo.canonicalUrl || refererInfo.referer; - if (pageUrl) { - site = site || {}; - site.page = pageUrl; - } - - if (refererInfo.reachedTop) { - try { - const pageRef = window.top.document.referrer; - if (pageRef) { - site = site || {}; - site.ref = pageRef; - } - } catch (e) {} - } - - return site; -} - -function interpretBid(bid) { - const bidResponse = { - requestId: bid.impid, - cpm: bid.price, - width: bid.w, - height: bid.h, - ttl: bid.exp, - creativeId: bid.crid, - netRevenue: true, - }; - - if (bid.adomain && bid.adomain.length) { - bidResponse.meta = { - advertiserDomains: bid.adomain, - }; - } - - const pbadapter = deepAccess(bid, 'ext.pbadapter') || {}; - switch (pbadapter.mediaType) { - case 'video': - if (bid.nurl) { - bidResponse.vastUrl = bid.nurl; - } - - if (bid.adm) { - bidResponse.vastXml = bid.adm; - } - - bidResponse.mediaType = VIDEO; - break; - default: // banner by default - bidResponse.ad = bid.adm; - break; - } - - return bidResponse; -} - -function numericBoolean(value) { - return value ? 1 : 0; -} - -function getBaseUrl() { - const pubg = config.getConfig('pubgenius'); - return (pubg && pubg.endpoint) || BASE_URL; -} - -function isValidSize(size) { - return isArrayOfNums(size, 2) && size[0] > 0 && size[1] > 0; -} - -function isValidBanner(banner) { - const sizes = banner.sizes; - return !!(sizes && sizes.length) && sizes.every(isValidSize); -} - -function isValidVideo(videoMediaType, videoParams) { - const params = buildVideoParams(videoMediaType, videoParams); - - return !!(params.placement && - isValidSize([params.w, params.h]) && - params.mimes && params.mimes.length && - isArrayOfNums(params.protocols) && params.protocols.length); -} - -registerBidder(spec); diff --git a/modules/pubgeniusBidAdapter.md b/modules/pubgeniusBidAdapter.md deleted file mode 100644 index 66e0c382285..00000000000 --- a/modules/pubgeniusBidAdapter.md +++ /dev/null @@ -1,94 +0,0 @@ -# Overview - -``` -Module Name: pubGENIUS Bidder Adapter -Module Type: Bidder Adapter -Maintainer: meng@pubgenius.io -``` - -# Description - -Module that connects to pubGENIUS's demand sources - -# Test Parameters - -``` -var adUnits = [ - { - code: 'test-desktop-banner', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [ - { - bidder: 'pubgenius', - params: { - adUnitId: '1000', - test: true - } - } - ] - }, - { - code: 'test-mobile-banner', - mediaTypes: { - banner: { - sizes: [[320, 50]] - } - }, - bids: [ - { - bidder: 'pubgenius', - params: { - adUnitId: '1000', - test: true - } - } - ] - }, - { - code: 'test-video', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 360], - mimes: ['video/mp4'], - protocols: [3], - } - }, - bids: [ - { - bidder: 'pubgenius', - params: { - adUnitId: '1001', - test: true, - - // other video parameters as in OpenRTB v2.5 spec - video: { - skip: 1 - - // the following overrides mediaTypes.video of the ad unit - placement: 1, - w: 640, - h: 360, - mimes: ['video/mp4'], - protocols: [3], - } - } - } - ] - }, -]; -``` - -# Optional Config - -By default, the adapter uses the page URL as provided in referer info by Prebid.js. -The following config overrides this behavior and specifies the URL to be used: -``` -pbjs.setConfig({ - pageUrl: 'https://example.com/top-page-url/' -}); -``` diff --git a/modules/pubmaticAnalyticsAdapter.js b/modules/pubmaticAnalyticsAdapter.js deleted file mode 100755 index c7eeaf87fdc..00000000000 --- a/modules/pubmaticAnalyticsAdapter.js +++ /dev/null @@ -1,478 +0,0 @@ -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -import CONSTANTS from '../src/constants.json'; -import { ajax } from '../src/ajax.js'; -import { config } from '../src/config.js'; -import * as utils from '../src/utils.js'; -import { getGlobal } from '../src/prebidGlobal.js'; - -/// /////////// CONSTANTS ////////////// -const ADAPTER_CODE = 'pubmatic'; -const SEND_TIMEOUT = 2000; -const END_POINT_HOST = 'https://t.pubmatic.com/'; -const END_POINT_BID_LOGGER = END_POINT_HOST + 'wl?'; -const END_POINT_WIN_BID_LOGGER = END_POINT_HOST + 'wt?'; -const LOG_PRE_FIX = 'PubMatic-Analytics: '; -const cache = { - auctions: {} -}; -const SUCCESS = 'success'; -const NO_BID = 'no-bid'; -const ERROR = 'error'; -const REQUEST_ERROR = 'request-error'; -const TIMEOUT_ERROR = 'timeout-error'; -const EMPTY_STRING = ''; -const MEDIA_TYPE_BANNER = 'banner'; -const CURRENCY_USD = 'USD'; -const BID_PRECISION = 2; -// todo: input profileId and profileVersionId ; defaults to zero or one -const DEFAULT_PUBLISHER_ID = 0; -const DEFAULT_PROFILE_ID = 0; -const DEFAULT_PROFILE_VERSION_ID = 0; -const enc = window.encodeURIComponent; - -/// /////////// VARIABLES ////////////// -let publisherId = DEFAULT_PUBLISHER_ID; // int: mandatory -let profileId = DEFAULT_PROFILE_ID; // int: optional -let profileVersionId = DEFAULT_PROFILE_VERSION_ID; // int: optional -let s2sBidders = []; - -/// /////////// HELPER FUNCTIONS ////////////// - -function sizeToDimensions(size) { - return { - width: size.w || size[0], - height: size.h || size[1] - }; -} - -function validMediaType(type) { - return ({'banner': 1, 'native': 1, 'video': 1}).hasOwnProperty(type); -} - -function formatSource(src) { - if (typeof src === 'undefined') { - src = 'client'; - } else if (src === 's2s') { - src = 'server'; - } - return src.toLowerCase(); -} - -function setMediaTypes(types, bid) { - if (bid.mediaType && validMediaType(bid.mediaType)) { - return [bid.mediaType]; - } - if (Array.isArray(types)) { - return types.filter(validMediaType); - } - if (typeof types === 'object') { - if (!bid.sizes) { - bid.dimensions = []; - utils._each(types, (type) => - bid.dimensions = bid.dimensions.concat( - type.sizes.map(sizeToDimensions) - ) - ); - } - return Object.keys(types).filter(validMediaType); - } - return [MEDIA_TYPE_BANNER]; -} - -function copyRequiredBidDetails(bid) { - return utils.pick(bid, [ - 'bidder', bidder => bidder.toLowerCase(), - 'bidId', - 'status', () => NO_BID, // default a bid to NO_BID until response is recieved or bid is timed out - 'finalSource as source', - 'params', - 'adUnit', () => utils.pick(bid, [ - 'adUnitCode', - 'transactionId', - 'sizes as dimensions', sizes => sizes.map(sizeToDimensions), - 'mediaTypes', (types) => setMediaTypes(types, bid) - ]) - ]); -} - -function setBidStatus(bid, args) { - switch (args.getStatusCode()) { - case CONSTANTS.STATUS.GOOD: - bid.status = SUCCESS; - delete bid.error; // it's possible for this to be set by a previous timeout - break; - case CONSTANTS.STATUS.NO_BID: - bid.status = NO_BID; - delete bid.error; - break; - default: - bid.status = ERROR; - bid.error = { - code: REQUEST_ERROR - }; - } -} - -function parseBidResponse(bid) { - return utils.pick(bid, [ - 'bidPriceUSD', () => { - // todo: check whether currency cases are handled here - if (typeof bid.currency === 'string' && bid.currency.toUpperCase() === CURRENCY_USD) { - return window.parseFloat(Number(bid.cpm).toFixed(BID_PRECISION)); - } - // use currency conversion function if present - if (typeof bid.getCpmInNewCurrency === 'function') { - return window.parseFloat(Number(bid.getCpmInNewCurrency(CURRENCY_USD)).toFixed(BID_PRECISION)); - } - utils.logWarn(LOG_PRE_FIX + 'Could not determine the Net cpm in USD for the bid thus using bid.cpm', bid); - return bid.cpm - }, - 'bidGrossCpmUSD', () => { - if (typeof bid.originalCurrency === 'string' && bid.originalCurrency.toUpperCase() === CURRENCY_USD) { - return window.parseFloat(Number(bid.originalCpm).toFixed(BID_PRECISION)); - } - // use currency conversion function if present - if (typeof getGlobal().convertCurrency === 'function') { - return window.parseFloat(Number(getGlobal().convertCurrency(bid.originalCpm, bid.originalCurrency, CURRENCY_USD)).toFixed(BID_PRECISION)); - } - utils.logWarn(LOG_PRE_FIX + 'Could not determine the Gross cpm in USD for the bid, thus using bid.originalCpm', bid); - return bid.originalCpm - }, - 'dealId', - 'currency', - 'cpm', () => window.parseFloat(Number(bid.cpm).toFixed(BID_PRECISION)), - 'originalCpm', () => window.parseFloat(Number(bid.originalCpm).toFixed(BID_PRECISION)), - 'originalCurrency', - 'dealChannel', - 'meta', - 'status', - 'error', - 'bidId', - 'mediaType', - 'params', - 'mi', - 'regexPattern', () => bid.regexPattern || undefined, - 'partnerImpId', // partner impression ID - 'dimensions', () => utils.pick(bid, [ - 'width', - 'height' - ]) - ]); -} - -function getDomainFromUrl(url) { - let a = window.document.createElement('a'); - a.href = url; - return a.hostname; -} - -function getDevicePlatform() { - var deviceType = 3; - try { - var ua = navigator.userAgent; - if (ua && utils.isStr(ua) && ua.trim() != '') { - ua = ua.toLowerCase().trim(); - var isMobileRegExp = new RegExp('(mobi|tablet|ios).*'); - if (ua.match(isMobileRegExp)) { - deviceType = 2; - } else { - deviceType = 1; - } - } - } catch (ex) {} - return deviceType; -} - -function getValueForKgpv(bid, adUnitId) { - if (bid.params.regexPattern) { - return bid.params.regexPattern; - } else if (bid.bidResponse && bid.bidResponse.regexPattern) { - return bid.bidResponse.regexPattern; - } else if (bid.params.kgpv) { - return bid.params.kgpv; - } else { - return adUnitId; - } -} - -function gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestBid) { - highestBid = (highestBid && highestBid.length > 0) ? highestBid[0] : null; - return Object.keys(adUnit.bids).reduce(function(partnerBids, bidId) { - let bid = adUnit.bids[bidId]; - partnerBids.push({ - 'pn': bid.bidder, - 'bidid': bid.bidId, - 'db': bid.bidResponse ? 0 : 1, - 'kgpv': getValueForKgpv(bid, adUnitId), - 'kgpsv': bid.params.kgpv ? bid.params.kgpv : adUnitId, - 'psz': bid.bidResponse ? (bid.bidResponse.dimensions.width + 'x' + bid.bidResponse.dimensions.height) : '0x0', - 'eg': bid.bidResponse ? bid.bidResponse.bidGrossCpmUSD : 0, - 'en': bid.bidResponse ? bid.bidResponse.bidPriceUSD : 0, - 'di': bid.bidResponse ? (bid.bidResponse.dealId || EMPTY_STRING) : EMPTY_STRING, - 'dc': bid.bidResponse ? (bid.bidResponse.dealChannel || EMPTY_STRING) : EMPTY_STRING, - 'l1': bid.bidResponse ? bid.clientLatencyTimeMs : 0, - 'l2': 0, - 'ss': (s2sBidders.indexOf(bid.bidder) > -1) ? 1 : 0, - 't': (bid.status == ERROR && bid.error.code == TIMEOUT_ERROR) ? 1 : 0, - 'wb': (highestBid && highestBid.requestId === bid.bidId ? 1 : 0), - 'mi': bid.bidResponse ? (bid.bidResponse.mi || undefined) : undefined, - 'af': bid.bidResponse ? (bid.bidResponse.mediaType || undefined) : undefined, - 'ocpm': bid.bidResponse ? (bid.bidResponse.originalCpm || 0) : 0, - 'ocry': bid.bidResponse ? (bid.bidResponse.originalCurrency || CURRENCY_USD) : CURRENCY_USD, - 'piid': bid.bidResponse ? (bid.bidResponse.partnerImpId || EMPTY_STRING) : EMPTY_STRING - }); - return partnerBids; - }, []) -} - -function executeBidsLoggerCall(e, highestCpmBids) { - let auctionId = e.auctionId; - let referrer = config.getConfig('pageUrl') || cache.auctions[auctionId].referer || ''; - let auctionCache = cache.auctions[auctionId]; - let outputObj = { s: [] }; - let pixelURL = END_POINT_BID_LOGGER; - - if (!auctionCache) { - return; - } - - if (auctionCache.sent) { - return; - } - - pixelURL += 'pubid=' + publisherId; - outputObj['pubid'] = '' + publisherId; - outputObj['iid'] = '' + auctionId; - outputObj['to'] = '' + auctionCache.timeout; - outputObj['purl'] = referrer; - outputObj['orig'] = getDomainFromUrl(referrer); - outputObj['tst'] = Math.round((new window.Date()).getTime() / 1000); - outputObj['pid'] = '' + profileId; - outputObj['pdvid'] = '' + profileVersionId; - outputObj['dvc'] = {'plt': getDevicePlatform()}; - outputObj['tgid'] = (function() { - var testGroupId = parseInt(config.getConfig('testGroupId') || 0); - if (testGroupId <= 15 && testGroupId >= 0) { - return testGroupId; - } - return 0; - })(); - - outputObj.s = Object.keys(auctionCache.adUnitCodes).reduce(function(slotsArray, adUnitId) { - let adUnit = auctionCache.adUnitCodes[adUnitId]; - let slotObject = { - 'sn': adUnitId, - 'sz': adUnit.dimensions.map(e => e[0] + 'x' + e[1]), - 'ps': gatherPartnerBidsForAdUnitForLogger(adUnit, adUnitId, highestCpmBids.filter(bid => bid.adUnitCode === adUnitId)) - }; - slotsArray.push(slotObject); - return slotsArray; - }, []); - - auctionCache.sent = true; - - ajax( - pixelURL, - null, - 'json=' + enc(JSON.stringify(outputObj)), - { - contentType: 'application/x-www-form-urlencoded', - withCredentials: true, - method: 'POST' - } - ); -} - -function executeBidWonLoggerCall(auctionId, adUnitId) { - const winningBidId = cache.auctions[auctionId].adUnitCodes[adUnitId].bidWon; - const winningBid = cache.auctions[auctionId].adUnitCodes[adUnitId].bids[winningBidId]; - let pixelURL = END_POINT_WIN_BID_LOGGER; - pixelURL += 'pubid=' + publisherId; - pixelURL += '&purl=' + enc(config.getConfig('pageUrl') || cache.auctions[auctionId].referer || ''); - pixelURL += '&tst=' + Math.round((new window.Date()).getTime() / 1000); - pixelURL += '&iid=' + enc(auctionId); - pixelURL += '&bidid=' + enc(winningBidId); - pixelURL += '&pid=' + enc(profileId); - pixelURL += '&pdvid=' + enc(profileVersionId); - pixelURL += '&slot=' + enc(adUnitId); - pixelURL += '&pn=' + enc(winningBid.bidder); - pixelURL += '&en=' + enc(winningBid.bidResponse.bidPriceUSD); - pixelURL += '&eg=' + enc(winningBid.bidResponse.bidGrossCpmUSD); - pixelURL += '&kgpv=' + enc(getValueForKgpv(winningBid, adUnitId)); - pixelURL += '&piid=' + enc(winningBid.bidResponse.partnerImpId || EMPTY_STRING); - ajax( - pixelURL, - null, - null, - { - contentType: 'application/x-www-form-urlencoded', - withCredentials: true, - method: 'GET' - } - ); -} - -/// /////////// ADAPTER EVENT HANDLER FUNCTIONS ////////////// - -function auctionInitHandler(args) { - s2sBidders = (function() { - let s2sConf = config.getConfig('s2sConfig'); - return (s2sConf && utils.isArray(s2sConf.bidders)) ? s2sConf.bidders : []; - }()); - let cacheEntry = utils.pick(args, [ - 'timestamp', - 'timeout', - 'bidderDonePendingCount', () => args.bidderRequests.length, - ]); - cacheEntry.adUnitCodes = {}; - cacheEntry.referer = args.bidderRequests[0].refererInfo.referer; - cache.auctions[args.auctionId] = cacheEntry; -} - -function bidRequestedHandler(args) { - args.bids.forEach(function(bid) { - if (!cache.auctions[args.auctionId].adUnitCodes.hasOwnProperty(bid.adUnitCode)) { - cache.auctions[args.auctionId].adUnitCodes[bid.adUnitCode] = { - bids: {}, - bidWon: false, - dimensions: bid.sizes - }; - } - cache.auctions[args.auctionId].adUnitCodes[bid.adUnitCode].bids[bid.bidId] = copyRequiredBidDetails(bid); - }) -} - -function bidResponseHandler(args) { - let bid = cache.auctions[args.auctionId].adUnitCodes[args.adUnitCode].bids[args.requestId]; - if (!bid) { - utils.logError(LOG_PRE_FIX + 'Could not find associated bid request for bid response with requestId: ', args.requestId); - return; - } - bid.source = formatSource(bid.source || args.source); - setBidStatus(bid, args); - bid.clientLatencyTimeMs = Date.now() - cache.auctions[args.auctionId].timestamp; - bid.bidResponse = parseBidResponse(args); -} - -function bidderDoneHandler(args) { - cache.auctions[args.auctionId].bidderDonePendingCount--; - args.bids.forEach(bid => { - let cachedBid = cache.auctions[bid.auctionId].adUnitCodes[bid.adUnitCode].bids[bid.bidId || bid.requestId]; - if (typeof bid.serverResponseTimeMs !== 'undefined') { - cachedBid.serverLatencyTimeMs = bid.serverResponseTimeMs; - } - if (!cachedBid.status) { - cachedBid.status = NO_BID; - } - if (!cachedBid.clientLatencyTimeMs) { - cachedBid.clientLatencyTimeMs = Date.now() - cache.auctions[bid.auctionId].timestamp; - } - }); -} - -function bidWonHandler(args) { - let auctionCache = cache.auctions[args.auctionId]; - auctionCache.adUnitCodes[args.adUnitCode].bidWon = args.requestId; - executeBidWonLoggerCall(args.auctionId, args.adUnitCode); -} - -function auctionEndHandler(args) { - // if for the given auction bidderDonePendingCount == 0 then execute logger call sooners - let highestCpmBids = getGlobal().getHighestCpmBids() || []; - setTimeout(() => { - executeBidsLoggerCall.call(this, args, highestCpmBids); - }, (cache.auctions[args.auctionId].bidderDonePendingCount === 0 ? 500 : SEND_TIMEOUT)); -} - -function bidTimeoutHandler(args) { - // db = 1 and t = 1 means bidder did NOT respond with a bid but we got a timeout notification - // db = 0 and t = 1 means bidder did respond with a bid but post timeout - args.forEach(badBid => { - let auctionCache = cache.auctions[badBid.auctionId]; - let bid = auctionCache.adUnitCodes[badBid.adUnitCode].bids[ badBid.bidId || badBid.requestId ]; - if (bid) { - bid.status = ERROR; - bid.error = { - code: TIMEOUT_ERROR - }; - } else { - utils.logWarn(LOG_PRE_FIX + 'bid not found'); - } - }); -} - -/// /////////// ADAPTER DEFINITION ////////////// - -let baseAdapter = adapter({analyticsType: 'endpoint'}); -let pubmaticAdapter = Object.assign({}, baseAdapter, { - - enableAnalytics(conf = {}) { - let error = false; - - if (typeof conf.options === 'object') { - if (conf.options.publisherId) { - publisherId = Number(conf.options.publisherId); - } - profileId = Number(conf.options.profileId) || DEFAULT_PROFILE_ID; - profileVersionId = Number(conf.options.profileVersionId) || DEFAULT_PROFILE_VERSION_ID; - } else { - utils.logError(LOG_PRE_FIX + 'Config not found.'); - error = true; - } - - if (!publisherId) { - utils.logError(LOG_PRE_FIX + 'Missing publisherId(Number).'); - error = true; - } - - if (error) { - utils.logError(LOG_PRE_FIX + 'Not collecting data due to error(s).'); - } else { - baseAdapter.enableAnalytics.call(this, conf); - } - }, - - disableAnalytics() { - publisherId = DEFAULT_PUBLISHER_ID; - profileId = DEFAULT_PROFILE_ID; - profileVersionId = DEFAULT_PROFILE_VERSION_ID; - s2sBidders = []; - baseAdapter.disableAnalytics.apply(this, arguments); - }, - - track({eventType, args}) { - switch (eventType) { - case CONSTANTS.EVENTS.AUCTION_INIT: - auctionInitHandler(args); - break; - case CONSTANTS.EVENTS.BID_REQUESTED: - bidRequestedHandler(args); - break; - case CONSTANTS.EVENTS.BID_RESPONSE: - bidResponseHandler(args); - break; - case CONSTANTS.EVENTS.BIDDER_DONE: - bidderDoneHandler(args); - break; - case CONSTANTS.EVENTS.BID_WON: - bidWonHandler(args); - break; - case CONSTANTS.EVENTS.AUCTION_END: - auctionEndHandler(args); - break; - case CONSTANTS.EVENTS.BID_TIMEOUT: - bidTimeoutHandler(args); - break; - } - } -}); - -/// /////////// ADAPTER REGISTRATION ////////////// - -adapterManager.registerAnalyticsAdapter({ - adapter: pubmaticAdapter, - code: ADAPTER_CODE -}); - -export default pubmaticAdapter; diff --git a/modules/pubmaticAnalyticsAdapter.md b/modules/pubmaticAnalyticsAdapter.md deleted file mode 100644 index 097f0b3d792..00000000000 --- a/modules/pubmaticAnalyticsAdapter.md +++ /dev/null @@ -1,23 +0,0 @@ -# PubMatic Analytics Adapter - -``` -Module Name: PubMatic Analytics Adapter -Module Type: Analytics Adapter -Maintainer: header-bidding@pubmatic.com -``` - -## How to configure? -``` -pbjs.enableAnalytics({ - provider: 'pubmatic', - options: { - "publisherId": 12345 // please contact PubMatic to get a publisherId for yourself - } -}); -``` - -## Limitations: -- Supports only Banner and Video media-type -- Does not supports Native media type -- Does not supports instream-video creative-render tracker -- If a currency module is NOT included and a bidder responds in a non-USD currency then PubMatic analytics bidder will log values in original bid currency otherwise always logged in USD \ No newline at end of file diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js deleted file mode 100644 index ff934204b43..00000000000 --- a/modules/pubmaticBidAdapter.js +++ /dev/null @@ -1,1266 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO, NATIVE } from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import { Renderer } from '../src/Renderer.js'; - -const BIDDER_CODE = 'pubmatic'; -const LOG_WARN_PREFIX = 'PubMatic: '; -const ENDPOINT = 'https://hbopenbid.pubmatic.com/translator?source=prebid-client'; -const USER_SYNC_URL_IFRAME = 'https://ads.pubmatic.com/AdServer/js/showad.js#PIX&kdntuid=1&p='; -const USER_SYNC_URL_IMAGE = 'https://image8.pubmatic.com/AdServer/ImgSync?p='; -const DEFAULT_CURRENCY = 'USD'; -const AUCTION_TYPE = 1; -const UNDEFINED = undefined; -const DEFAULT_WIDTH = 0; -const DEFAULT_HEIGHT = 0; -const PREBID_NATIVE_HELP_LINK = 'http://prebid.org/dev-docs/show-native-ads.html'; -const PUBLICATION = 'pubmatic'; // Your publication on Blue Billywig, potentially with environment (e.g. publication.bbvms.com or publication.test.bbvms.com) -const RENDERER_URL = 'https://pubmatic.bbvms.com/r/'.concat('$RENDERER', '.js'); // URL of the renderer application -const CUSTOM_PARAMS = { - 'kadpageurl': '', // Custom page url - 'gender': '', // User gender - 'yob': '', // User year of birth - 'lat': '', // User location - Latitude - 'lon': '', // User Location - Longitude - 'wiid': '', // OpenWrap Wrapper Impression ID - 'profId': '', // OpenWrap Legacy: Profile ID - 'verId': '' // OpenWrap Legacy: version ID -}; -const DATA_TYPES = { - 'NUMBER': 'number', - 'STRING': 'string', - 'BOOLEAN': 'boolean', - 'ARRAY': 'array', - 'OBJECT': 'object' -}; -const VIDEO_CUSTOM_PARAMS = { - 'mimes': DATA_TYPES.ARRAY, - 'minduration': DATA_TYPES.NUMBER, - 'maxduration': DATA_TYPES.NUMBER, - 'startdelay': DATA_TYPES.NUMBER, - 'playbackmethod': DATA_TYPES.ARRAY, - 'api': DATA_TYPES.ARRAY, - 'protocols': DATA_TYPES.ARRAY, - 'w': DATA_TYPES.NUMBER, - 'h': DATA_TYPES.NUMBER, - 'battr': DATA_TYPES.ARRAY, - 'linearity': DATA_TYPES.NUMBER, - 'placement': DATA_TYPES.NUMBER, - 'minbitrate': DATA_TYPES.NUMBER, - 'maxbitrate': DATA_TYPES.NUMBER -} - -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 } -}; - -const NATIVE_ASSET_IMAGE_TYPE = { - 'ICON': 1, - 'LOGO': 2, - 'IMAGE': 3 -} - -// check if title, image can be added with mandatory field default values -const NATIVE_MINIMUM_REQUIRED_IMAGE_ASSETS = [ - { - id: NATIVE_ASSETS.SPONSOREDBY.ID, - required: true, - data: { - type: 1 - } - }, - { - id: NATIVE_ASSETS.TITLE.ID, - required: true, - }, - { - id: NATIVE_ASSETS.IMAGE.ID, - required: true, - } -] - -const NET_REVENUE = true; -const dealChannelValues = { - 1: 'PMP', - 5: 'PREF', - 6: 'PMPG' -}; - -const FLOC_FORMAT = { - 'EID': 1, - 'SEGMENT': 2 -} -// BB stands for Blue BillyWig -const BB_RENDERER = { - bootstrapPlayer: function(bid) { - const config = { - code: bid.adUnitCode, - }; - - if (bid.vastXml) config.vastXml = bid.vastXml; - else if (bid.vastUrl) config.vastUrl = bid.vastUrl; - - if (!bid.vastXml && !bid.vastUrl) { - utils.logWarn(`${LOG_WARN_PREFIX}: No vastXml or vastUrl on bid, bailing...`); - return; - } - - const rendererId = BB_RENDERER.getRendererId(PUBLICATION, bid.rendererCode); - - const ele = document.getElementById(bid.adUnitCode); // NB convention - - let renderer; - - for (let rendererIndex = 0; rendererIndex < window.bluebillywig.renderers.length; rendererIndex++) { - if (window.bluebillywig.renderers[rendererIndex]._id === rendererId) { - renderer = window.bluebillywig.renderers[rendererIndex]; - break; - } - } - - if (renderer) renderer.bootstrap(config, ele); - else utils.logWarn(`${LOG_WARN_PREFIX}: Couldn't find a renderer with ${rendererId}`); - }, - newRenderer: function(rendererCode, adUnitCode) { - var rendererUrl = RENDERER_URL.replace('$RENDERER', rendererCode); - const renderer = Renderer.install({ - url: rendererUrl, - loaded: false, - adUnitCode - }); - - try { - renderer.setRender(BB_RENDERER.outstreamRender); - } catch (err) { - utils.logWarn(`${LOG_WARN_PREFIX}: Error tying to setRender on renderer`, err); - } - - return renderer; - }, - outstreamRender: function(bid) { - bid.renderer.push(function() { BB_RENDERER.bootstrapPlayer(bid) }); - }, - getRendererId: function(pub, renderer) { - return `${pub}-${renderer}`; // NB convention! - } -}; - -let publisherId = 0; -let isInvalidNativeRequest = false; -let NATIVE_ASSET_ID_TO_KEY_MAP = {}; -let NATIVE_ASSET_KEY_TO_ASSET_MAP = {}; - -// loading NATIVE_ASSET_ID_TO_KEY_MAP -utils._each(NATIVE_ASSETS, anAsset => { NATIVE_ASSET_ID_TO_KEY_MAP[anAsset.ID] = anAsset.KEY }); -// loading NATIVE_ASSET_KEY_TO_ASSET_MAP -utils._each(NATIVE_ASSETS, anAsset => { NATIVE_ASSET_KEY_TO_ASSET_MAP[anAsset.KEY] = anAsset }); - -function _getDomainFromURL(url) { - let anchor = document.createElement('a'); - anchor.href = url; - return anchor.hostname; -} - -function _parseSlotParam(paramName, paramValue) { - if (!utils.isStr(paramValue)) { - paramValue && utils.logWarn(LOG_WARN_PREFIX + 'Ignoring param key: ' + paramName + ', expects string-value, found ' + typeof paramValue); - return UNDEFINED; - } - - switch (paramName) { - case 'pmzoneid': - return paramValue.split(',').slice(0, 50).map(id => id.trim()).join(); - case 'kadfloor': - return parseFloat(paramValue) || UNDEFINED; - case 'lat': - return parseFloat(paramValue) || UNDEFINED; - case 'lon': - return parseFloat(paramValue) || UNDEFINED; - case 'yob': - return parseInt(paramValue) || UNDEFINED; - default: - return paramValue; - } -} - -function _cleanSlot(slotName) { - if (utils.isStr(slotName)) { - return slotName.replace(/^\s+/g, '').replace(/\s+$/g, ''); - } - if (slotName) { - utils.logWarn(BIDDER_CODE + ': adSlot must be a string. Ignoring adSlot'); - } - return ''; -} - -function _parseAdSlot(bid) { - bid.params.adUnit = ''; - bid.params.adUnitIndex = '0'; - bid.params.width = 0; - bid.params.height = 0; - bid.params.adSlot = _cleanSlot(bid.params.adSlot); - - var slot = bid.params.adSlot; - var splits = slot.split(':'); - - slot = splits[0]; - if (splits.length == 2) { - bid.params.adUnitIndex = splits[1]; - } - // check if size is mentioned in sizes array. in that case do not check for @ in adslot - splits = slot.split('@'); - bid.params.adUnit = splits[0]; - if (splits.length > 1) { - // i.e size is specified in adslot, so consider that and ignore sizes array - splits = splits[1].split('x'); - if (splits.length != 2) { - utils.logWarn(LOG_WARN_PREFIX + 'AdSlot Error: adSlot not in required format'); - return; - } - bid.params.width = parseInt(splits[0], 10); - bid.params.height = parseInt(splits[1], 10); - } else if (bid.hasOwnProperty('mediaTypes') && - bid.mediaTypes.hasOwnProperty(BANNER) && - bid.mediaTypes.banner.hasOwnProperty('sizes')) { - var i = 0; - var sizeArray = []; - for (;i < bid.mediaTypes.banner.sizes.length; i++) { - if (bid.mediaTypes.banner.sizes[i].length === 2) { // sizes[i].length will not be 2 in case where size is set as fluid, we want to skip that entry - sizeArray.push(bid.mediaTypes.banner.sizes[i]); - } - } - bid.mediaTypes.banner.sizes = sizeArray; - if (bid.mediaTypes.banner.sizes.length >= 1) { - // set the first size in sizes array in bid.params.width and bid.params.height. These will be sent as primary size. - // The rest of the sizes will be sent in format array. - bid.params.width = bid.mediaTypes.banner.sizes[0][0]; - bid.params.height = bid.mediaTypes.banner.sizes[0][1]; - bid.mediaTypes.banner.sizes = bid.mediaTypes.banner.sizes.splice(1, bid.mediaTypes.banner.sizes.length - 1); - } - } -} - -function _initConf(refererInfo) { - return { - pageURL: (refererInfo && refererInfo.referer) ? refererInfo.referer : window.location.href, - refURL: window.document.referrer - }; -} - -function _handleCustomParams(params, conf) { - if (!conf.kadpageurl) { - conf.kadpageurl = conf.pageURL; - } - - var key, value, entry; - for (key in CUSTOM_PARAMS) { - if (CUSTOM_PARAMS.hasOwnProperty(key)) { - value = params[key]; - if (value) { - entry = CUSTOM_PARAMS[key]; - - if (typeof entry === 'object') { - // will be used in future when we want to process a custom param before using - // 'keyname': {f: function() {}} - value = entry.f(value, conf); - } - - if (utils.isStr(value)) { - conf[key] = value; - } else { - utils.logWarn(LOG_WARN_PREFIX + 'Ignoring param : ' + key + ' with value : ' + CUSTOM_PARAMS[key] + ', expects string-value, found ' + typeof value); - } - } - } - } - return conf; -} - -function _createOrtbTemplate(conf) { - return { - id: '' + new Date().getTime(), - at: AUCTION_TYPE, - cur: [DEFAULT_CURRENCY], - imp: [], - site: { - page: conf.pageURL, - ref: conf.refURL, - publisher: {} - }, - device: { - ua: navigator.userAgent, - js: 1, - dnt: (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0, - h: screen.height, - w: screen.width, - language: navigator.language - }, - user: {}, - ext: {} - }; -} - -function _checkParamDataType(key, value, datatype) { - var errMsg = 'Ignoring param key: ' + key + ', expects ' + datatype + ', found ' + typeof value; - var functionToExecute; - switch (datatype) { - case DATA_TYPES.BOOLEAN: - functionToExecute = utils.isBoolean; - break; - case DATA_TYPES.NUMBER: - functionToExecute = utils.isNumber; - break; - case DATA_TYPES.STRING: - functionToExecute = utils.isStr; - break; - case DATA_TYPES.ARRAY: - functionToExecute = utils.isArray; - break; - } - if (functionToExecute(value)) { - return value; - } - utils.logWarn(LOG_WARN_PREFIX + errMsg); - return UNDEFINED; -} - -function _commonNativeRequestObject(nativeAsset, params) { - var key = nativeAsset.KEY; - return { - id: nativeAsset.ID, - required: params[key].required ? 1 : 0, - data: { - type: nativeAsset.TYPE, - len: params[key].len, - ext: params[key].ext - } - }; -} - -function _createNativeRequest(params) { - var nativeRequestObject = { - assets: [] - }; - for (var key in params) { - if (params.hasOwnProperty(key)) { - var assetObj = {}; - if (!(nativeRequestObject.assets && nativeRequestObject.assets.length > 0 && nativeRequestObject.assets.hasOwnProperty(key))) { - switch (key) { - case NATIVE_ASSETS.TITLE.KEY: - if (params[key].len || params[key].length) { - assetObj = { - id: NATIVE_ASSETS.TITLE.ID, - required: params[key].required ? 1 : 0, - title: { - len: params[key].len || params[key].length, - ext: params[key].ext - } - }; - } else { - utils.logWarn(LOG_WARN_PREFIX + 'Error: Title Length is required for native ad: ' + JSON.stringify(params)); - } - break; - case NATIVE_ASSETS.IMAGE.KEY: - if (params[key].sizes && params[key].sizes.length > 0) { - assetObj = { - id: NATIVE_ASSETS.IMAGE.ID, - required: params[key].required ? 1 : 0, - img: { - type: NATIVE_ASSET_IMAGE_TYPE.IMAGE, - w: params[key].w || params[key].width || (params[key].sizes ? params[key].sizes[0] : UNDEFINED), - h: params[key].h || params[key].height || (params[key].sizes ? params[key].sizes[1] : UNDEFINED), - wmin: params[key].wmin || params[key].minimumWidth || (params[key].minsizes ? params[key].minsizes[0] : UNDEFINED), - hmin: params[key].hmin || params[key].minimumHeight || (params[key].minsizes ? params[key].minsizes[1] : UNDEFINED), - mimes: params[key].mimes, - ext: params[key].ext, - } - }; - } else { - utils.logWarn(LOG_WARN_PREFIX + 'Error: Image sizes is required for native ad: ' + JSON.stringify(params)); - } - break; - case NATIVE_ASSETS.ICON.KEY: - if (params[key].sizes && params[key].sizes.length > 0) { - assetObj = { - id: NATIVE_ASSETS.ICON.ID, - required: params[key].required ? 1 : 0, - img: { - type: NATIVE_ASSET_IMAGE_TYPE.ICON, - w: params[key].w || params[key].width || (params[key].sizes ? params[key].sizes[0] : UNDEFINED), - h: params[key].h || params[key].height || (params[key].sizes ? params[key].sizes[1] : UNDEFINED), - } - }; - } else { - utils.logWarn(LOG_WARN_PREFIX + 'Error: Icon sizes is required for native ad: ' + JSON.stringify(params)); - }; - break; - case NATIVE_ASSETS.VIDEO.KEY: - assetObj = { - id: NATIVE_ASSETS.VIDEO.ID, - required: params[key].required ? 1 : 0, - video: { - minduration: params[key].minduration, - maxduration: params[key].maxduration, - protocols: params[key].protocols, - mimes: params[key].mimes, - ext: params[key].ext - } - }; - break; - case NATIVE_ASSETS.EXT.KEY: - assetObj = { - id: NATIVE_ASSETS.EXT.ID, - required: params[key].required ? 1 : 0, - }; - break; - case NATIVE_ASSETS.LOGO.KEY: - assetObj = { - id: NATIVE_ASSETS.LOGO.ID, - required: params[key].required ? 1 : 0, - img: { - type: NATIVE_ASSET_IMAGE_TYPE.LOGO, - w: params[key].w || params[key].width || (params[key].sizes ? params[key].sizes[0] : UNDEFINED), - h: params[key].h || params[key].height || (params[key].sizes ? params[key].sizes[1] : UNDEFINED) - } - }; - break; - case NATIVE_ASSETS.SPONSOREDBY.KEY: - case NATIVE_ASSETS.BODY.KEY: - case NATIVE_ASSETS.RATING.KEY: - case NATIVE_ASSETS.LIKES.KEY: - case NATIVE_ASSETS.DOWNLOADS.KEY: - case NATIVE_ASSETS.PRICE.KEY: - case NATIVE_ASSETS.SALEPRICE.KEY: - case NATIVE_ASSETS.PHONE.KEY: - case NATIVE_ASSETS.ADDRESS.KEY: - case NATIVE_ASSETS.DESC2.KEY: - case NATIVE_ASSETS.DISPLAYURL.KEY: - case NATIVE_ASSETS.CTA.KEY: - assetObj = _commonNativeRequestObject(NATIVE_ASSET_KEY_TO_ASSET_MAP[key], params); - break; - } - } - } - if (assetObj && assetObj.id) { - nativeRequestObject.assets[nativeRequestObject.assets.length] = assetObj; - } - }; - - // for native image adtype prebid has to have few required assests i.e. title,sponsoredBy, image - // if any of these are missing from the request then request will not be sent - var requiredAssetCount = NATIVE_MINIMUM_REQUIRED_IMAGE_ASSETS.length; - var presentrequiredAssetCount = 0; - NATIVE_MINIMUM_REQUIRED_IMAGE_ASSETS.forEach(ele => { - var lengthOfExistingAssets = nativeRequestObject.assets.length; - for (var i = 0; i < lengthOfExistingAssets; i++) { - if (ele.id == nativeRequestObject.assets[i].id) { - presentrequiredAssetCount++; - break; - } - } - }); - if (requiredAssetCount == presentrequiredAssetCount) { - isInvalidNativeRequest = false; - } else { - isInvalidNativeRequest = true; - } - return nativeRequestObject; -} - -function _createBannerRequest(bid) { - var sizes = bid.mediaTypes.banner.sizes; - var format = []; - var bannerObj; - if (sizes !== UNDEFINED && utils.isArray(sizes)) { - bannerObj = {}; - if (!bid.params.width && !bid.params.height) { - if (sizes.length === 0) { - // i.e. since bid.params does not have width or height, and length of sizes is 0, need to ignore this banner imp - bannerObj = UNDEFINED; - utils.logWarn(LOG_WARN_PREFIX + 'Error: mediaTypes.banner.size missing for adunit: ' + bid.params.adUnit + '. Ignoring the banner impression in the adunit.'); - return bannerObj; - } else { - bannerObj.w = parseInt(sizes[0][0], 10); - bannerObj.h = parseInt(sizes[0][1], 10); - sizes = sizes.splice(1, sizes.length - 1); - } - } else { - bannerObj.w = bid.params.width; - bannerObj.h = bid.params.height; - } - if (sizes.length > 0) { - format = []; - sizes.forEach(function (size) { - if (size.length > 1) { - format.push({ w: size[0], h: size[1] }); - } - }); - if (format.length > 0) { - bannerObj.format = format; - } - } - bannerObj.pos = 0; - bannerObj.topframe = utils.inIframe() ? 0 : 1; - } else { - utils.logWarn(LOG_WARN_PREFIX + 'Error: mediaTypes.banner.size missing for adunit: ' + bid.params.adUnit + '. Ignoring the banner impression in the adunit.'); - bannerObj = UNDEFINED; - } - return bannerObj; -} - -function _createVideoRequest(bid) { - var videoData = bid.params.video; - var videoObj; - - if (videoData !== UNDEFINED) { - videoObj = {}; - for (var key in VIDEO_CUSTOM_PARAMS) { - if (videoData.hasOwnProperty(key)) { - videoObj[key] = _checkParamDataType(key, videoData[key], VIDEO_CUSTOM_PARAMS[key]); - } - } - // read playersize and assign to h and w. - if (utils.isArray(bid.mediaTypes.video.playerSize[0])) { - videoObj.w = parseInt(bid.mediaTypes.video.playerSize[0][0], 10); - videoObj.h = parseInt(bid.mediaTypes.video.playerSize[0][1], 10); - } else if (utils.isNumber(bid.mediaTypes.video.playerSize[0])) { - videoObj.w = parseInt(bid.mediaTypes.video.playerSize[0], 10); - videoObj.h = parseInt(bid.mediaTypes.video.playerSize[1], 10); - } - if (bid.params.video.hasOwnProperty('skippable')) { - videoObj.ext = { - 'video_skippable': bid.params.video.skippable ? 1 : 0 - }; - } - } else { - videoObj = UNDEFINED; - utils.logWarn(LOG_WARN_PREFIX + 'Error: Video config params missing for adunit: ' + bid.params.adUnit + ' with mediaType set as video. Ignoring video impression in the adunit.'); - } - return videoObj; -} - -// support for PMP deals -function _addPMPDealsInImpression(impObj, bid) { - if (bid.params.deals) { - if (utils.isArray(bid.params.deals)) { - bid.params.deals.forEach(function(dealId) { - if (utils.isStr(dealId) && dealId.length > 3) { - if (!impObj.pmp) { - impObj.pmp = { private_auction: 0, deals: [] }; - } - impObj.pmp.deals.push({ id: dealId }); - } else { - utils.logWarn(LOG_WARN_PREFIX + 'Error: deal-id present in array bid.params.deals should be a strings with more than 3 charaters length, deal-id ignored: ' + dealId); - } - }); - } else { - utils.logWarn(LOG_WARN_PREFIX + 'Error: bid.params.deals should be an array of strings.'); - } - } -} - -function _createImpressionObject(bid, conf) { - var impObj = {}; - var bannerObj; - var videoObj; - var nativeObj = {}; - var sizes = bid.hasOwnProperty('sizes') ? bid.sizes : []; - var mediaTypes = ''; - var format = []; - - impObj = { - id: bid.bidId, - tagid: bid.params.adUnit || undefined, - bidfloor: _parseSlotParam('kadfloor', bid.params.kadfloor), - secure: 1, - ext: { - pmZoneId: _parseSlotParam('pmzoneid', bid.params.pmzoneid) - }, - bidfloorcur: bid.params.currency ? _parseSlotParam('currency', bid.params.currency) : DEFAULT_CURRENCY - }; - - _addPMPDealsInImpression(impObj, bid); - - if (bid.hasOwnProperty('mediaTypes')) { - for (mediaTypes in bid.mediaTypes) { - switch (mediaTypes) { - case BANNER: - bannerObj = _createBannerRequest(bid); - if (bannerObj !== UNDEFINED) { - impObj.banner = bannerObj; - } - break; - case NATIVE: - nativeObj['request'] = JSON.stringify(_createNativeRequest(bid.nativeParams)); - if (!isInvalidNativeRequest) { - impObj.native = nativeObj; - } else { - utils.logWarn(LOG_WARN_PREFIX + 'Error: Error in Native adunit ' + bid.params.adUnit + '. Ignoring the adunit. Refer to ' + PREBID_NATIVE_HELP_LINK + ' for more details.'); - } - break; - case VIDEO: - videoObj = _createVideoRequest(bid); - if (videoObj !== UNDEFINED) { - impObj.video = videoObj; - } - break; - } - } - } 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. - bannerObj = { - pos: 0, - w: bid.params.width, - h: bid.params.height, - topframe: utils.inIframe() ? 0 : 1 - }; - if (utils.isArray(sizes) && sizes.length > 1) { - sizes = sizes.splice(1, sizes.length - 1); - sizes.forEach(size => { - format.push({ - w: size[0], - h: size[1] - }); - }); - bannerObj.format = format; - } - impObj.banner = bannerObj; - } - - _addImpressionFPD(impObj, bid); - - _addFloorFromFloorModule(impObj, bid); - - return impObj.hasOwnProperty(BANNER) || - impObj.hasOwnProperty(NATIVE) || - impObj.hasOwnProperty(VIDEO) ? impObj : UNDEFINED; -} - -function _addImpressionFPD(imp, bid) { - const ortb2 = {...utils.deepAccess(bid, 'ortb2Imp.ext.data')}; - Object.keys(ortb2).forEach(prop => { - /** - * Prebid AdSlot - * @type {(string|undefined)} - */ - if (prop === 'pbadslot') { - if (typeof ortb2[prop] === 'string' && ortb2[prop]) utils.deepSetValue(imp, 'ext.data.pbadslot', ortb2[prop]); - } else if (prop === 'adserver') { - /** - * Copy GAM AdUnit and Name to imp - */ - ['name', 'adslot'].forEach(name => { - /** @type {(string|undefined)} */ - const value = utils.deepAccess(ortb2, `adserver.${name}`); - if (typeof value === 'string' && value) { - utils.deepSetValue(imp, `ext.data.adserver.${name.toLowerCase()}`, value); - // copy GAM ad unit id as imp[].ext.dfp_ad_unit_code - if (name === 'adslot') { - utils.deepSetValue(imp, `ext.dfp_ad_unit_code`, value); - } - } - }); - } else { - utils.deepSetValue(imp, `ext.data.${prop}`, ortb2[prop]); - } - }); -} - -function _addFloorFromFloorModule(impObj, bid) { - let bidFloor = -1; - // get lowest floor from floorModule - if (typeof bid.getFloor === 'function' && !config.getConfig('pubmatic.disableFloors')) { - [BANNER, VIDEO, NATIVE].forEach(mediaType => { - if (impObj.hasOwnProperty(mediaType)) { - let floorInfo = bid.getFloor({ currency: impObj.bidfloorcur, mediaType: mediaType, size: '*' }); - if (typeof floorInfo === 'object' && floorInfo.currency === impObj.bidfloorcur && !isNaN(parseInt(floorInfo.floor))) { - let mediaTypeFloor = parseFloat(floorInfo.floor); - bidFloor = (bidFloor == -1 ? mediaTypeFloor : Math.min(mediaTypeFloor, bidFloor)) - } - } - }); - } - // get highest from impObj.bidfllor and floor from floor module - // as we are using Math.max, it is ok if we have not got any floor from floorModule, then value of bidFloor will be -1 - if (impObj.bidfloor) { - bidFloor = Math.max(bidFloor, impObj.bidfloor) - } - - // assign value only if bidFloor is > 0 - impObj.bidfloor = ((!isNaN(bidFloor) && bidFloor > 0) ? bidFloor : UNDEFINED); -} - -function _getFlocId(validBidRequests, flocFormat) { - var flocIdObject = null; - var flocId = utils.deepAccess(validBidRequests, '0.userId.flocId'); - if (flocId && flocId.id) { - switch (flocFormat) { - case FLOC_FORMAT.SEGMENT: - flocIdObject = { - id: 'FLOC', - name: 'FLOC', - ext: { - ver: flocId.version - }, - segment: [{ - id: flocId.id, - name: 'chrome.com', - value: flocId.id.toString() - }] - } - break; - case FLOC_FORMAT.EID: - default: - flocIdObject = { - source: 'chrome.com', - uids: [ - { - atype: 1, - id: flocId.id, - ext: { - ver: flocId.version - } - }, - ] - } - break; - } - } - return flocIdObject; -} - -function _handleFlocId(payload, validBidRequests) { - var flocObject = _getFlocId(validBidRequests, FLOC_FORMAT.SEGMENT); - if (flocObject) { - if (!payload.user) { - payload.user = {}; - } - if (!payload.user.data) { - payload.user.data = []; - } - payload.user.data.push(flocObject); - } -} - -function _handleEids(payload, validBidRequests) { - let bidUserIdAsEids = utils.deepAccess(validBidRequests, '0.userIdAsEids'); - let flocObject = _getFlocId(validBidRequests, FLOC_FORMAT.EID); - if (flocObject) { - if (!bidUserIdAsEids) { - bidUserIdAsEids = []; - } - bidUserIdAsEids.push(flocObject); - } - if (utils.isArray(bidUserIdAsEids) && bidUserIdAsEids.length > 0) { - utils.deepSetValue(payload, 'user.eids', bidUserIdAsEids); - } -} - -function _checkMediaType(adm, newBid) { - // Create a regex here to check the strings - var admStr = ''; - var videoRegex = new RegExp(/VAST\s+version/); - if (adm.indexOf('span class="PubAPIAd"') >= 0) { - newBid.mediaType = BANNER; - } else if (videoRegex.test(adm)) { - newBid.mediaType = VIDEO; - } else { - try { - admStr = JSON.parse(adm.replace(/\\/g, '')); - if (admStr && admStr.native) { - newBid.mediaType = NATIVE; - } - } catch (e) { - utils.logWarn(LOG_WARN_PREFIX + 'Error: Cannot parse native reponse for ad response: ' + adm); - } - } -} - -function _parseNativeResponse(bid, newBid) { - newBid.native = {}; - if (bid.hasOwnProperty('adm')) { - var adm = ''; - try { - adm = JSON.parse(bid.adm.replace(/\\/g, '')); - } catch (ex) { - utils.logWarn(LOG_WARN_PREFIX + 'Error: Cannot parse native reponse for ad response: ' + newBid.adm); - return; - } - if (adm && adm.native && adm.native.assets && adm.native.assets.length > 0) { - newBid.mediaType = NATIVE; - for (let i = 0, len = adm.native.assets.length; i < len; i++) { - switch (adm.native.assets[i].id) { - case NATIVE_ASSETS.TITLE.ID: - newBid.native.title = adm.native.assets[i].title && adm.native.assets[i].title.text; - break; - case NATIVE_ASSETS.IMAGE.ID: - newBid.native.image = { - url: adm.native.assets[i].img && adm.native.assets[i].img.url, - height: adm.native.assets[i].img && adm.native.assets[i].img.h, - width: adm.native.assets[i].img && adm.native.assets[i].img.w, - }; - break; - case NATIVE_ASSETS.ICON.ID: - newBid.native.icon = { - url: adm.native.assets[i].img && adm.native.assets[i].img.url, - height: adm.native.assets[i].img && adm.native.assets[i].img.h, - width: adm.native.assets[i].img && adm.native.assets[i].img.w, - }; - break; - case NATIVE_ASSETS.SPONSOREDBY.ID: - case NATIVE_ASSETS.BODY.ID: - case NATIVE_ASSETS.LIKES.ID: - case NATIVE_ASSETS.DOWNLOADS.ID: - case NATIVE_ASSETS.PRICE: - case NATIVE_ASSETS.SALEPRICE.ID: - case NATIVE_ASSETS.PHONE.ID: - case NATIVE_ASSETS.ADDRESS.ID: - case NATIVE_ASSETS.DESC2.ID: - case NATIVE_ASSETS.CTA.ID: - case NATIVE_ASSETS.RATING.ID: - case NATIVE_ASSETS.DISPLAYURL.ID: - newBid.native[NATIVE_ASSET_ID_TO_KEY_MAP[adm.native.assets[i].id]] = adm.native.assets[i].data && adm.native.assets[i].data.value; - break; - } - } - newBid.native.clickUrl = adm.native.link && adm.native.link.url; - newBid.native.clickTrackers = (adm.native.link && adm.native.link.clicktrackers) || []; - newBid.native.impressionTrackers = adm.native.imptrackers || []; - newBid.native.jstracker = adm.native.jstracker || []; - if (!newBid.width) { - newBid.width = DEFAULT_WIDTH; - } - if (!newBid.height) { - newBid.height = DEFAULT_HEIGHT; - } - } - } -} - -function _blockedIabCategoriesValidation(payload, blockedIabCategories) { - blockedIabCategories = blockedIabCategories - .filter(function(category) { - if (typeof category === 'string') { // only strings - return true; - } else { - utils.logWarn(LOG_WARN_PREFIX + 'bcat: Each category should be a string, ignoring category: ' + category); - return false; - } - }) - .map(category => category.trim()) // trim all - .filter(function(category, index, arr) { // more than 3 charaters length - if (category.length > 3) { - return arr.indexOf(category) === index; // unique value only - } else { - utils.logWarn(LOG_WARN_PREFIX + 'bcat: Each category should have a value of a length of more than 3 characters, ignoring category: ' + category) - } - }); - if (blockedIabCategories.length > 0) { - utils.logWarn(LOG_WARN_PREFIX + 'bcat: Selected: ', blockedIabCategories); - payload.bcat = blockedIabCategories; - } -} - -function _handleDealCustomTargetings(payload, dctrArr, validBidRequests) { - var dctr = ''; - var dctrLen; - // set dctr value in site.ext, if present in validBidRequests[0], else ignore - if (dctrArr.length > 0) { - if (validBidRequests[0].params.hasOwnProperty('dctr')) { - dctr = validBidRequests[0].params.dctr; - if (utils.isStr(dctr) && dctr.length > 0) { - var arr = dctr.split('|'); - dctr = ''; - arr.forEach(val => { - dctr += (val.length > 0) ? (val.trim() + '|') : ''; - }); - dctrLen = dctr.length; - if (dctr.substring(dctrLen, dctrLen - 1) === '|') { - dctr = dctr.substring(0, dctrLen - 1); - } - payload.site.ext = { - key_val: dctr.trim() - } - } else { - utils.logWarn(LOG_WARN_PREFIX + 'Ignoring param : dctr with value : ' + dctr + ', expects string-value, found empty or non-string value'); - } - if (dctrArr.length > 1) { - utils.logWarn(LOG_WARN_PREFIX + 'dctr value found in more than 1 adunits. Value from 1st adunit will be picked. Ignoring values from subsequent adunits'); - } - } else { - utils.logWarn(LOG_WARN_PREFIX + 'dctr value not found in 1st adunit, ignoring values from subsequent adunits'); - } - } -} - -function _assignRenderer(newBid, request) { - let bidParams, context, adUnitCode; - if (request.bidderRequest && request.bidderRequest.bids) { - for (let bidderRequestBidsIndex = 0; bidderRequestBidsIndex < request.bidderRequest.bids.length; bidderRequestBidsIndex++) { - if (request.bidderRequest.bids[bidderRequestBidsIndex].bidId === newBid.requestId) { - bidParams = request.bidderRequest.bids[bidderRequestBidsIndex].params; - context = request.bidderRequest.bids[bidderRequestBidsIndex].mediaTypes[VIDEO].context; - adUnitCode = request.bidderRequest.bids[bidderRequestBidsIndex].adUnitCode; - } - } - if (context && context === 'outstream' && bidParams && bidParams.outstreamAU && adUnitCode) { - newBid.rendererCode = bidParams.outstreamAU; - newBid.renderer = BB_RENDERER.newRenderer(newBid.rendererCode, adUnitCode); - } - } -}; - -export const spec = { - code: BIDDER_CODE, - gvlid: 76, - supportedMediaTypes: [BANNER, VIDEO, NATIVE], - /** - * Determines whether or not the given bid request is valid. Valid bid request must have placementId and hbid - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: bid => { - if (bid && bid.params) { - if (!utils.isStr(bid.params.publisherId)) { - utils.logWarn(LOG_WARN_PREFIX + 'Error: publisherId is mandatory and cannot be numeric (wrap it in quotes in your config). Call to OpenBid will not be sent for ad unit: ' + JSON.stringify(bid)); - return false; - } - // video ad validation - if (bid.params.hasOwnProperty('video')) { - if (!bid.params.video.hasOwnProperty('mimes') || !utils.isArray(bid.params.video.mimes) || bid.params.video.mimes.length === 0) { - utils.logWarn(LOG_WARN_PREFIX + 'Error: For video ads, mimes is mandatory and must specify atlease 1 mime value. Call to OpenBid will not be sent for ad unit:' + JSON.stringify(bid)); - return false; - } - if (bid.hasOwnProperty('mediaTypes') && bid.mediaTypes.hasOwnProperty(VIDEO)) { - if (!bid.mediaTypes[VIDEO].hasOwnProperty('context')) { - utils.logError(`${LOG_WARN_PREFIX}: no context specified in bid. Rejecting bid: `, bid); - return false; - } - if (bid.mediaTypes[VIDEO].context === 'outstream' && !utils.isStr(bid.params.outstreamAU) && !bid.hasOwnProperty('renderer') && !bid.mediaTypes[VIDEO].hasOwnProperty('renderer')) { - utils.logError(`${LOG_WARN_PREFIX}: for "outstream" bids either outstreamAU parameter must be provided or ad unit supplied renderer is required. Rejecting bid: `, bid); - return false; - } - } else { - utils.logError(`${LOG_WARN_PREFIX}: mediaTypes or mediaTypes.video is not specified. Rejecting bid: `, bid); - return false; - } - } - return true; - } - return false; - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: (validBidRequests, bidderRequest) => { - var refererInfo; - if (bidderRequest && bidderRequest.refererInfo) { - refererInfo = bidderRequest.refererInfo; - } - var conf = _initConf(refererInfo); - var payload = _createOrtbTemplate(conf); - var bidCurrency = ''; - var dctrArr = []; - var bid; - var blockedIabCategories = []; - - validBidRequests.forEach(originalBid => { - bid = utils.deepClone(originalBid); - bid.params.adSlot = bid.params.adSlot || ''; - _parseAdSlot(bid); - if (bid.params.hasOwnProperty('video')) { - // Nothing to do - } else { - // If we have a native mediaType configured alongside banner, its ok if the banner size is not set in width and height - // The corresponding banner imp object will not be generated, but we still want the native object to be sent, hence the following check - if (!(bid.hasOwnProperty('mediaTypes') && bid.mediaTypes.hasOwnProperty(NATIVE)) && bid.params.width === 0 && bid.params.height === 0) { - utils.logWarn(LOG_WARN_PREFIX + 'Skipping the non-standard adslot: ', bid.params.adSlot, JSON.stringify(bid)); - return; - } - } - conf.pubId = conf.pubId || bid.params.publisherId; - conf = _handleCustomParams(bid.params, conf); - conf.transactionId = bid.transactionId; - if (bidCurrency === '') { - bidCurrency = bid.params.currency || UNDEFINED; - } else if (bid.params.hasOwnProperty('currency') && bidCurrency !== bid.params.currency) { - utils.logWarn(LOG_WARN_PREFIX + 'Currency specifier ignored. Only one currency permitted.'); - } - bid.params.currency = bidCurrency; - // check if dctr is added to more than 1 adunit - if (bid.params.hasOwnProperty('dctr') && utils.isStr(bid.params.dctr)) { - dctrArr.push(bid.params.dctr); - } - if (bid.params.hasOwnProperty('bcat') && utils.isArray(bid.params.bcat)) { - blockedIabCategories = blockedIabCategories.concat(bid.params.bcat); - } - var impObj = _createImpressionObject(bid, conf); - if (impObj) { - payload.imp.push(impObj); - } - }); - - if (payload.imp.length == 0) { - return; - } - - payload.site.publisher.id = conf.pubId.trim(); - publisherId = conf.pubId.trim(); - payload.ext.wrapper = {}; - payload.ext.wrapper.profile = parseInt(conf.profId) || UNDEFINED; - payload.ext.wrapper.version = parseInt(conf.verId) || UNDEFINED; - payload.ext.wrapper.wiid = conf.wiid || bidderRequest.auctionId; - // eslint-disable-next-line no-undef - payload.ext.wrapper.wv = $$REPO_AND_VERSION$$; - payload.ext.wrapper.transactionId = conf.transactionId; - payload.ext.wrapper.wp = 'pbjs'; - payload.user.gender = (conf.gender ? conf.gender.trim() : UNDEFINED); - payload.user.geo = {}; - payload.user.geo.lat = _parseSlotParam('lat', conf.lat); - payload.user.geo.lon = _parseSlotParam('lon', conf.lon); - payload.user.yob = _parseSlotParam('yob', conf.yob); - payload.device.geo = payload.user.geo; - payload.site.page = conf.kadpageurl.trim() || payload.site.page.trim(); - payload.site.domain = _getDomainFromURL(payload.site.page); - - // add the content object from config in request - if (typeof config.getConfig('content') === 'object') { - payload.site.content = config.getConfig('content'); - } - - // merge the device from config.getConfig('device') - if (typeof config.getConfig('device') === 'object') { - payload.device = Object.assign(payload.device, config.getConfig('device')); - } - - // passing transactionId in source.tid - utils.deepSetValue(payload, 'source.tid', conf.transactionId); - - // test bids - if (window.location.href.indexOf('pubmaticTest=true') !== -1) { - payload.test = 1; - } - - // adding schain object - if (validBidRequests[0].schain) { - utils.deepSetValue(payload, 'source.ext.schain', validBidRequests[0].schain); - } - - // Attaching GDPR Consent Params - if (bidderRequest && bidderRequest.gdprConsent) { - utils.deepSetValue(payload, 'user.ext.consent', bidderRequest.gdprConsent.consentString); - utils.deepSetValue(payload, 'regs.ext.gdpr', (bidderRequest.gdprConsent.gdprApplies ? 1 : 0)); - } - - // CCPA - if (bidderRequest && bidderRequest.uspConsent) { - utils.deepSetValue(payload, 'regs.ext.us_privacy', bidderRequest.uspConsent); - } - - // coppa compliance - if (config.getConfig('coppa') === true) { - utils.deepSetValue(payload, 'regs.coppa', 1); - } - - _handleDealCustomTargetings(payload, dctrArr, validBidRequests); - _handleEids(payload, validBidRequests); - _blockedIabCategoriesValidation(payload, blockedIabCategories); - _handleFlocId(payload, validBidRequests); - // First Party Data - const commonFpd = config.getConfig('ortb2') || {}; - if (commonFpd.site) { - utils.mergeDeep(payload, {site: commonFpd.site}); - } - if (commonFpd.user) { - utils.mergeDeep(payload, {user: commonFpd.user}); - } - - // Note: Do not move this block up - // if site object is set in Prebid config then we need to copy required fields from site into app and unset the site object - if (typeof config.getConfig('app') === 'object') { - payload.app = config.getConfig('app'); - // not copying domain from site as it is a derived value from page - payload.app.publisher = payload.site.publisher; - payload.app.ext = payload.site.ext || UNDEFINED; - // We will also need to pass content object in app.content if app object is also set into the config; - // BUT do not use content object from config if content object is present in app as app.content - if (typeof payload.app.content !== 'object') { - payload.app.content = payload.site.content || UNDEFINED; - } - delete payload.site; - } - - return { - method: 'POST', - url: ENDPOINT, - data: JSON.stringify(payload), - bidderRequest: bidderRequest - }; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} response A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: (response, request) => { - const bidResponses = []; - var respCur = DEFAULT_CURRENCY; - let parsedRequest = JSON.parse(request.data); - let parsedReferrer = parsedRequest.site && parsedRequest.site.ref ? parsedRequest.site.ref : ''; - try { - if (response.body && response.body.seatbid && utils.isArray(response.body.seatbid)) { - // Supporting multiple bid responses for same adSize - respCur = response.body.cur || respCur; - response.body.seatbid.forEach(seatbidder => { - seatbidder.bid && - utils.isArray(seatbidder.bid) && - seatbidder.bid.forEach(bid => { - let newBid = { - requestId: bid.impid, - cpm: (parseFloat(bid.price) || 0).toFixed(2), - width: bid.w, - height: bid.h, - creativeId: bid.crid || bid.id, - dealId: bid.dealid, - currency: respCur, - netRevenue: NET_REVENUE, - ttl: 300, - referrer: parsedReferrer, - ad: bid.adm, - pm_seat: seatbidder.seat || null, - pm_dspid: bid.ext && bid.ext.dspid ? bid.ext.dspid : null, - partnerImpId: bid.id || '' // partner impression Id - }; - if (parsedRequest.imp && parsedRequest.imp.length > 0) { - parsedRequest.imp.forEach(req => { - if (bid.impid === req.id) { - _checkMediaType(bid.adm, newBid); - switch (newBid.mediaType) { - case BANNER: - break; - case VIDEO: - newBid.width = bid.hasOwnProperty('w') ? bid.w : req.video.w; - newBid.height = bid.hasOwnProperty('h') ? bid.h : req.video.h; - newBid.vastXml = bid.adm; - _assignRenderer(newBid, request); - break; - case NATIVE: - _parseNativeResponse(bid, newBid); - break; - } - } - }); - } - if (bid.ext && bid.ext.deal_channel) { - newBid['dealChannel'] = dealChannelValues[bid.ext.deal_channel] || null; - } - - newBid.meta = {}; - if (bid.ext && bid.ext.dspid) { - newBid.meta.networkId = bid.ext.dspid; - } - if (bid.ext && bid.ext.advid) { - newBid.meta.buyerId = bid.ext.advid; - } - if (bid.adomain && bid.adomain.length > 0) { - newBid.meta.advertiserDomains = bid.adomain; - newBid.meta.clickUrl = bid.adomain[0]; - } - - // adserverTargeting - if (seatbidder.ext && seatbidder.ext.buyid) { - newBid.adserverTargeting = { - 'hb_buyid_pubmatic': seatbidder.ext.buyid - }; - } - - bidResponses.push(newBid); - }); - }); - } - } catch (error) { - utils.logError(error); - } - return bidResponses; - }, - - /** - * Register User Sync. - */ - getUserSyncs: (syncOptions, responses, gdprConsent, uspConsent) => { - let syncurl = '' + publisherId; - - // Attaching GDPR Consent Params in UserSync url - if (gdprConsent) { - syncurl += '&gdpr=' + (gdprConsent.gdprApplies ? 1 : 0); - syncurl += '&gdpr_consent=' + encodeURIComponent(gdprConsent.consentString || ''); - } - - // CCPA - if (uspConsent) { - syncurl += '&us_privacy=' + encodeURIComponent(uspConsent); - } - - // coppa compliance - if (config.getConfig('coppa') === true) { - syncurl += '&coppa=1'; - } - - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: USER_SYNC_URL_IFRAME + syncurl - }]; - } else { - return [{ - type: 'image', - url: USER_SYNC_URL_IMAGE + syncurl - }]; - } - }, - - /** - * Covert bid param types for S2S - * @param {Object} params bid params - * @param {Boolean} isOpenRtb boolean to check openrtb2 protocol - * @return {Object} params bid params - */ - transformBidParams: function (params, isOpenRtb) { - return utils.convertTypes({ - 'publisherId': 'string', - 'adSlot': 'string' - }, params); - } -}; - -registerBidder(spec); diff --git a/modules/pubmaticBidAdapter.md b/modules/pubmaticBidAdapter.md deleted file mode 100644 index e9d93d79758..00000000000 --- a/modules/pubmaticBidAdapter.md +++ /dev/null @@ -1,209 +0,0 @@ -# Overview - -``` -Module Name: PubMatic Bid Adapter -Module Type: Bidder Adapter -Maintainer: header-bidding@pubmatic.com -``` - -# Description - -Connects to PubMatic exchange for bids. - -PubMatic bid adapter supports Video, Banner and Native currently. - -# Sample Banner Ad Unit: For Publishers -``` -var adUnits = [ -{ - code: 'test-div', - sizes: [ - [300, 250], - [728, 90] - ], - bids: [{ - bidder: 'pubmatic', - params: { - publisherId: '156209', // required, must be a string, not an integer or other js type. - oustreamAU: 'renderer_test_pubmatic', // required if mediaTypes-> video-> context is 'outstream' and optional if renderer is defined in adUnits or in mediaType video. This value can be get by BlueBillyWig Team. - adSlot: 'pubmatic_test2', // optional, must be a string, not an integer or other js type. - pmzoneid: 'zone1, zone11', // optional - lat: '40.712775', // optional - lon: '-74.005973', // optional - yob: '1982', // optional - kadpageurl: 'www.test.com', // optional - gender: 'M', // optional - kadfloor: '0.50', // optional - currency: 'AUD', // optional (Value configured only in the 1st adunit will be passed on. < br/> Values if present in subsequent adunits, will be ignored.) - dctr: 'key1=123|key2=345', // optional (Value configured only in the 1st adunit will be passed on. < br/> Values if present in subsequent adunits, will be ignored.) - bcat: ['IAB1-5', 'IAB1-7'], // Optional: Blocked IAB Categories. (Values from all slots will be combined and only unique values will be passed. An array of strings only. Each category should be a string of a length of more than 3 characters.) - deals: ['deal-id-1', 'deal-id-200'] // optional: PMP Deals, should be array of strings - } - }] -}]; -``` - -# Sample Video Ad Unit: For Publishers -``` -var adVideoAdUnits = [ -{ - code: 'test-div-video', - mediaTypes: { - video: { - playerSize: [640, 480], // required - context: 'instream' - } - }, - bids: [{ - bidder: 'pubmatic', - params: { - publisherId: '156209', // required - adSlot: 'pubmatic_video1', // optional - video: { - mimes: ['video/mp4','video/x-flv'], // required - skippable: true, // optional - minduration: 5, // optional - maxduration: 30, // optional - startdelay: 5, // optional - playbackmethod: [1,3], // optional - api: [ 1, 2 ], // optional - protocols: [ 2, 3 ], // optional - battr: [ 13, 14 ], // optional - linearity: 1, // optional - placement: 2, // optional - minbitrate: 10, // optional - maxbitrate: 10 // optional - } - } - }] -}] -``` - -# Sample Native Ad Unit: For Publishers -``` -var adUnits = [ -{ - code: 'test-div', - mediaTypes: { - native: { - image: { - required: true, - sizes: [150, 50] - }, - title: { - required: true, - len: 80 - }, - sponsoredBy: { - required: true - }, - clickUrl: { - required: true - } - } - }, - bids: [{ - bidder: 'pubmatic', - params: { - publisherId: '156295', // required - adSlot: 'pubmatic_test2@1x1', // optional - } - }] -}]; -``` -# Sample Configuration for Multi-format Ad Unit: For Publishers -``` -var adUnits = [ -{ - code: 'test-div', - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [728, 90] - ] - }, - video: { - playerSize: [640, 480], // required - context: 'instream' - }, - native: { - image: { - required: true, - sizes: [150, 50] - }, - title: { - required: true, - len: 80 - }, - sponsoredBy: { - required: true - }, - clickUrl: { - required: true - } - } - }, - bids: [{ - bidder: 'pubmatic', - params: { - publisherId: '156209', // required - adSlot: 'pubmatic_test2@300x250', // optional - pmzoneid: 'zone1, zone11', // optional - lat: '40.712775', // optional - lon: '-74.005973', // optional - yob: '1982', // optional - kadpageurl: 'www.test.com', // optional - gender: 'M', // optional - kadfloor: '0.50', // optional - currency: 'AUD', // optional (Value configured only in the 1st adunit will be passed on. < br/> Values if present in subsequent adunits, will be ignored.) - dctr: 'key1=123|key2=345', // optional (Value configured only in the 1st adunit will be passed on. < br/> Values if present in subsequent adunits, will be ignored.) - video: { - mimes: ['video/mp4','video/x-flv'], // required - skippable: true, // optional - minduration: 5, // optional - maxduration: 30, // optional - startdelay: 5, // optional - playbackmethod: [1,3], // optional - api: [ 1, 2 ], // optional - protocols: [ 2, 3 ], // optional - battr: [ 13, 14 ], // optional - linearity: 1, // optional - placement: 2, // optional - minbitrate: 10, // optional - maxbitrate: 10 // optional - } - } - }] -}]; -``` - - -# ## Configuration - -PubMatic recommends the UserSync configuration below. Without it, the PubMatic adapter will not able to perform user syncs, which lowers match rate and reduces monetization. - -```javascript -pbjs.setConfig({ - userSync: { - iframeEnabled: true, - enabledBidders: ['pubmatic'], - syncDelay: 6000 - }}); - - -For Video ads, prebid cache needs to be enabled for PubMatic adapter. -pbjs.setConfig({ - debug: true, - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } -}); - -``` -Note: Combine the above the configuration with any other UserSync configuration. Multiple setConfig() calls overwrite each other and only last call for a given attribute will take effect. - -# Notes: -- PubMatic will return a test-bid if "pubmaticTest=true" is present in page URL -- PubMatic will set bid.adserverTargeting.hb_buyid_pubmatic targeting key while submitting a bid into Prebid - diff --git a/modules/pubnxBidAdapter.md b/modules/pubnxBidAdapter.md deleted file mode 100644 index 6c843322402..00000000000 --- a/modules/pubnxBidAdapter.md +++ /dev/null @@ -1,31 +0,0 @@ -# Overview - -``` -Module Name: PubNX Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid-team@pubnx.com -``` - -# Description - -Connects to PubNX exchange for bids. -PubNX Bidder adapter supports Banner ads. -Use bidder code ```pubnx``` for all PubNX traffic. - -# Test Parameters -``` -var adUnits = [ - // Banner adUnit - { - code: 'banner-div', - sizes: [[300, 250], [300,600]], // a display size(s) - bids: [{ - bidder: 'pubnx', - params: { - placementId: 'PNX-HB-G396432V4809F3' - } - }] - }, -]; -``` - diff --git a/modules/pubperfAnalyticsAdapter.js b/modules/pubperfAnalyticsAdapter.js deleted file mode 100644 index 800ea1cd550..00000000000 --- a/modules/pubperfAnalyticsAdapter.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Analytics Adapter for Pubperf - */ - -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -import * as utils from '../src/utils.js'; - -var pubperfAdapter = adapter({ - global: 'pubperf_pbjs', - analyticsType: 'bundle', - handler: 'on' -}); - -pubperfAdapter.originEnableAnalytics = pubperfAdapter.enableAnalytics; - -pubperfAdapter.enableAnalytics = config => { - if (!config || !config.provider || config.provider !== 'pubperf') { - utils.logError('expected config.provider to equal pubperf'); - return; - } - if (!window['pubperf_pbjs']) { - utils.logError( - `Make sure that Pubperf tag from https://www.pubperf.com is included before the Prebid configuration.` - ); - return; - } - pubperfAdapter.originEnableAnalytics(config); -} - -adapterManager.registerAnalyticsAdapter({ - adapter: pubperfAdapter, - code: 'pubperf' -}); - -export default pubperfAdapter; diff --git a/modules/pubperfAnalyticsAdapter.md b/modules/pubperfAnalyticsAdapter.md deleted file mode 100644 index 50ac3691dda..00000000000 --- a/modules/pubperfAnalyticsAdapter.md +++ /dev/null @@ -1,27 +0,0 @@ -# Overview - -``` -Module Name: Pubperf Analytics Adapter -Module Type: Analytics Adapter -Maintainer: support@transfon.com -``` - -# Description - -Transfon's pubperf analytics adaptor allows you to view detailed auction and prebid information in Meridian. Contact support@transfon.com for more information or to sign up for analytics. - -For more information, please visit https://www.pubperf.com. - - -# Sample pubperf tag to be placed before prebid tag - -``` -(function(i, s, o, g, r, a, m, z) {i['pubperf_pbjs'] = r;i[r] = i[r] || function() {z = Array.prototype.slice.call(arguments);z.unshift(+new Date());(i[r].q = i[r].q || []).push(z)}, i[r].t = 1, i[r].l = 1 * new Date();a = s.createElement(o),m = s.getElementsByTagName(o)[0];a.async = 1;a.src = g;m.parentNode.insertBefore(a, m)})(window, document, 'script', 'https://t.pubperf.com/t/b5a635e307.js', 'pubperf_pbjs'); -``` - -# Test Parameters -``` -{ - provider: 'pubperf' -} -``` diff --git a/modules/pubstackAnalyticsAdapter.js b/modules/pubstackAnalyticsAdapter.js deleted file mode 100644 index b1da40c5b89..00000000000 --- a/modules/pubstackAnalyticsAdapter.js +++ /dev/null @@ -1,15 +0,0 @@ -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; - -const pubstackAnalytics = adapter({ - global: 'PubstackAnalytics', - handler: 'on', - analyticsType: 'bundle' -}); - -adapterManager.registerAnalyticsAdapter({ - adapter: pubstackAnalytics, - code: 'pubstack', -}); - -export default pubstackAnalytics; diff --git a/modules/pubstackAnalyticsAdapter.md b/modules/pubstackAnalyticsAdapter.md deleted file mode 100644 index 0b473bd39d7..00000000000 --- a/modules/pubstackAnalyticsAdapter.md +++ /dev/null @@ -1,9 +0,0 @@ -# Overview - -Module Name: Pubstack Analytics Adapter -Module Type: Analytics Adapter -Maintainer: support@pubstack.io - -# Description - -This is the Pubstack Analytics Adapter. [Contact Guillaume from our Support Team](mailto:support@pubstack.io) to start analyzing your HB stack. diff --git a/modules/pubwiseAnalyticsAdapter.js b/modules/pubwiseAnalyticsAdapter.js deleted file mode 100644 index fe217454b88..00000000000 --- a/modules/pubwiseAnalyticsAdapter.js +++ /dev/null @@ -1,337 +0,0 @@ -import {ajax} from '../src/ajax.js'; -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -import CONSTANTS from '../src/constants.json'; -import { getStorageManager } from '../src/storageManager.js'; -const utils = require('../src/utils.js'); -const storage = getStorageManager(); - -/**** - * PubWise.io Analytics - * Contact: support@pubwise.io - * Developer: Stephen Johnston - * - * For testing: - * - pbjs.enableAnalytics({ - provider: 'pubwise', - options: { - site: 'b1ccf317-a6fc-428d-ba69-0c9c208aa61c' - } - }); - -Changes in 4.0 Version -4.0.1 - Initial Version for Prebid 4.x, adds activationId, adds additiona testing, removes prebid global in favor of a prebid.version const -4.0.2 - Updates to include dedicated default site to keep everything from getting rate limited - -*/ - -const analyticsType = 'endpoint'; -const analyticsName = 'PubWise:'; -const prebidVersion = '$prebid.version$'; -let pubwiseVersion = '4.0.1'; -let configOptions = {site: '', endpoint: 'https://api.pubwise.io/api/v5/event/add/', debug: null}; -let pwAnalyticsEnabled = false; -let utmKeys = {utm_source: '', utm_medium: '', utm_campaign: '', utm_term: '', utm_content: ''}; -let sessionData = {sessionId: '', activationId: ''}; -let pwNamespace = 'pubwise'; -let pwEvents = []; -let metaData = {}; -let auctionEnded = false; -let sessTimeout = 60 * 30 * 1000; // 30 minutes, G Analytics default session length -let sessName = 'sess_id'; -let sessTimeoutName = 'sess_timeout'; - -function enrichWithSessionInfo(dataBag) { - try { - // eslint-disable-next-line - // console.log(sessionData); - dataBag['session_id'] = sessionData.sessionId; - dataBag['activation_id'] = sessionData.activationId; - } catch (e) { - dataBag['error_sess'] = 1; - } - - return dataBag; -} - -function enrichWithMetrics(dataBag) { - try { - if (window.PREBID_TIMEOUT) { - dataBag['target_timeout'] = window.PREBID_TIMEOUT; - } else { - dataBag['target_timeout'] = 'NA'; - } - dataBag['pw_version'] = pubwiseVersion; - dataBag['pbjs_version'] = prebidVersion; - dataBag['debug'] = configOptions.debug; - } catch (e) { - dataBag['error_metric'] = 1; - } - - return dataBag; -} - -function enrichWithUTM(dataBag) { - let newUtm = false; - try { - for (let prop in utmKeys) { - utmKeys[prop] = utils.getParameterByName(prop); - if (utmKeys[prop]) { - newUtm = true; - dataBag[prop] = utmKeys[prop]; - } - } - - if (newUtm === false) { - for (let prop in utmKeys) { - let itemValue = storage.getDataFromLocalStorage(setNamespace(prop)); - if (itemValue !== null && typeof itemValue !== 'undefined' && itemValue.length !== 0) { - dataBag[prop] = itemValue; - } - } - } else { - for (let prop in utmKeys) { - storage.setDataInLocalStorage(setNamespace(prop), utmKeys[prop]); - } - } - } catch (e) { - pwInfo(`Error`, e); - dataBag['error_utm'] = 1; - } - return dataBag; -} - -function expireUtmData() { - pwInfo(`Session Expiring UTM Data`); - for (let prop in utmKeys) { - storage.removeDataFromLocalStorage(setNamespace(prop)); - } -} - -function enrichWithCustomSegments(dataBag) { - // c_script_type: '', c_slot1: '', c_slot2: '', c_slot3: '', c_slot4: '' - if (configOptions.custom) { - if (configOptions.custom.c_script_type) { - dataBag['c_script_type'] = configOptions.custom.c_script_type; - } - - if (configOptions.custom.c_host) { - dataBag['c_host'] = configOptions.custom.c_host; - } - - if (configOptions.custom.c_slot1) { - dataBag['c_slot1'] = configOptions.custom.c_slot1; - } - - if (configOptions.custom.c_slot2) { - dataBag['c_slot2'] = configOptions.custom.c_slot2; - } - - if (configOptions.custom.c_slot3) { - dataBag['c_slot3'] = configOptions.custom.c_slot3; - } - - if (configOptions.custom.c_slot4) { - dataBag['c_slot4'] = configOptions.custom.c_slot4; - } - } - - return dataBag; -} - -function setNamespace(itemText) { - return pwNamespace.concat('_' + itemText); -} - -function localStorageSessTimeoutName() { - return setNamespace(sessTimeoutName); -} - -function localStorageSessName() { - return setNamespace(sessName); -} - -function extendUserSessionTimeout() { - storage.setDataInLocalStorage(localStorageSessTimeoutName(), Date.now().toString()); -} - -function userSessionID() { - return storage.getDataFromLocalStorage(localStorageSessName()) ? localStorage.getItem(localStorageSessName()) : ''; -} - -function sessionExpired() { - let sessLastTime = storage.getDataFromLocalStorage(localStorageSessTimeoutName()); - return (Date.now() - parseInt(sessLastTime)) > sessTimeout; -} - -function flushEvents() { - if (pwEvents.length > 0) { - let 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)); - } -} - -function isIngestedEvent(eventType) { - const ingested = [ - CONSTANTS.EVENTS.AUCTION_INIT, - CONSTANTS.EVENTS.BID_REQUESTED, - CONSTANTS.EVENTS.BID_RESPONSE, - CONSTANTS.EVENTS.BID_WON, - CONSTANTS.EVENTS.BID_TIMEOUT, - CONSTANTS.EVENTS.AD_RENDER_FAILED, - CONSTANTS.EVENTS.TCF2_ENFORCEMENT - ]; - return ingested.indexOf(eventType) !== -1; -} - -function markEnabled() { - pwInfo(`Enabled`, configOptions); - pwAnalyticsEnabled = true; - setInterval(flushEvents, 100); -} - -function pwInfo(info, context) { - utils.logInfo(`${analyticsName} ` + info, context); -} - -function filterBidResponse(data) { - let modified = Object.assign({}, data); - // clean up some properties we don't track in public version - if (typeof modified.ad !== 'undefined') { - modified.ad = ''; - } - if (typeof modified.adUrl !== 'undefined') { - modified.adUrl = ''; - } - if (typeof modified.adserverTargeting !== 'undefined') { - modified.adserverTargeting = ''; - } - if (typeof modified.ts !== 'undefined') { - modified.ts = ''; - } - // clean up a property to make simpler - if (typeof modified.statusMessage !== 'undefined' && modified.statusMessage === 'Bid returned empty or error response') { - modified.statusMessage = 'eoe'; - } - modified.auctionEnded = auctionEnded; - return modified; -} - -function filterAuctionInit(data) { - let modified = Object.assign({}, data); - - modified.refererInfo = {}; - // handle clean referrer, we only need one - if (typeof modified.bidderRequests !== 'undefined' && typeof modified.bidderRequests[0] !== 'undefined' && typeof modified.bidderRequests[0].refererInfo !== 'undefined') { - modified.refererInfo = modified.bidderRequests[0].refererInfo; - } - - if (typeof modified.adUnitCodes !== 'undefined') { - delete modified.adUnitCodes; - } - if (typeof modified.adUnits !== 'undefined') { - delete modified.adUnits; - } - if (typeof modified.bidderRequests !== 'undefined') { - delete modified.bidderRequests; - } - if (typeof modified.bidsReceived !== 'undefined') { - delete modified.bidsReceived; - } - if (typeof modified.config !== 'undefined') { - delete modified.config; - } - if (typeof modified.noBids !== 'undefined') { - delete modified.noBids; - } - if (typeof modified.winningBids !== 'undefined') { - delete modified.winningBids; - } - - return modified; -} - -let pubwiseAnalytics = Object.assign(adapter({analyticsType}), { - // Override AnalyticsAdapter functions by supplying custom methods - track({eventType, args}) { - this.handleEvent(eventType, args); - } -}); - -pubwiseAnalytics.handleEvent = function(eventType, data) { - // we log most events, but some are information - if (isIngestedEvent(eventType)) { - pwInfo(`Emitting Event ${eventType} ${pwAnalyticsEnabled}`, data); - - // record metadata - metaData = { - target_site: configOptions.site, - debug: configOptions.debug ? 1 : 0, - }; - metaData = enrichWithSessionInfo(metaData); - metaData = enrichWithMetrics(metaData); - metaData = enrichWithUTM(metaData); - metaData = enrichWithCustomSegments(metaData); - - // add data on init to the metadata container - if (eventType === CONSTANTS.EVENTS.AUCTION_INIT) { - data = filterAuctionInit(data); - } else if (eventType === CONSTANTS.EVENTS.BID_RESPONSE) { - data = filterBidResponse(data); - } - - // add all ingested events - pwEvents.push({ - eventType: eventType, - args: data - }); - } else { - pwInfo(`Skipping Event ${eventType} ${pwAnalyticsEnabled}`, data); - } - - // once the auction ends, or the event is a bid won send events - if (eventType === CONSTANTS.EVENTS.AUCTION_END || eventType === CONSTANTS.EVENTS.BID_WON) { - flushEvents(); - } -} - -pubwiseAnalytics.storeSessionID = function (userSessID) { - storage.setDataInLocalStorage(localStorageSessName(), userSessID); - pwInfo(`New Session Generated`, userSessID); -}; - -// ensure a session exists, if not make one, always store it -pubwiseAnalytics.ensureSession = function () { - if (sessionExpired() === true || userSessionID() === null || userSessionID() === '') { - let generatedId = utils.generateUUID(); - expireUtmData(); - this.storeSessionID(generatedId); - sessionData.sessionId = generatedId; - } - // eslint-disable-next-line - // console.log('ensured session'); - extendUserSessionTimeout(); -}; - -pubwiseAnalytics.adapterEnableAnalytics = pubwiseAnalytics.enableAnalytics; - -pubwiseAnalytics.enableAnalytics = function (config) { - configOptions = Object.assign(configOptions, config.options); - // take the PBJS debug for our debug setting if no PW debug is defined - if (configOptions.debug === null) { - configOptions.debug = utils.debugTurnedOn(); - } - markEnabled(); - sessionData.activationId = utils.generateUUID(); - this.ensureSession(); - pubwiseAnalytics.adapterEnableAnalytics(config); -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: pubwiseAnalytics, - code: 'pubwise', - gvlid: 842 -}); - -export default pubwiseAnalytics; diff --git a/modules/pubwiseBidAdapter.js b/modules/pubwiseBidAdapter.js deleted file mode 100644 index f450a8bede8..00000000000 --- a/modules/pubwiseBidAdapter.js +++ /dev/null @@ -1,777 +0,0 @@ -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE } from '../src/mediaTypes.js'; -const VERSION = '0.1.0'; -const GVLID = 842; -const NET_REVENUE = true; -const UNDEFINED = undefined; -const DEFAULT_CURRENCY = 'USD'; -const AUCTION_TYPE = 1; -const BIDDER_CODE = 'pwbid'; -const ENDPOINT_URL = 'https://bid.pubwise.io/prebid'; -const DEFAULT_WIDTH = 0; -const DEFAULT_HEIGHT = 0; -const PREBID_NATIVE_HELP_LINK = 'https://prebid.org/dev-docs/show-native-ads.html'; -// const USERSYNC_URL = '//127.0.0.1:8080/usersync' - -const CUSTOM_PARAMS = { - 'gender': '', // User gender - 'yob': '', // User year of birth - 'lat': '', // User location - Latitude - 'lon': '', // User Location - Longitude -}; - -// rtb native types are meant to be dynamic and extendable -// the extendable data asset types are nicely aligned -// in practice we set an ID that is distinct for each real type of return -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 }, - 'BODY': { ID: 5, KEY: 'body', TYPE: 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 }, - 'DESC': { ID: 12, KEY: 'data', TYPE: 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 } -}; - -const NATIVE_ASSET_IMAGE_TYPE = { - 'ICON': 1, - 'LOGO': 2, - 'IMAGE': 3 -} - -// to render any native unit we have to have a few items -const NATIVE_MINIMUM_REQUIRED_IMAGE_ASSETS = [ - { - id: NATIVE_ASSETS.SPONSOREDBY.ID, - required: true, - data: { - type: 1 - } - }, - { - id: NATIVE_ASSETS.TITLE.ID, - required: true, - }, - { - id: NATIVE_ASSETS.IMAGE.ID, - required: true, - } -] - -let isInvalidNativeRequest = false -let NATIVE_ASSET_ID_TO_KEY_MAP = {}; -let NATIVE_ASSET_KEY_TO_ASSET_MAP = {}; - -// together allows traversal of NATIVE_ASSETS_LIST in any direction -// id -> key -utils._each(NATIVE_ASSETS, anAsset => { NATIVE_ASSET_ID_TO_KEY_MAP[anAsset.ID] = anAsset.KEY }); -// key -> asset -utils._each(NATIVE_ASSETS, anAsset => { NATIVE_ASSET_KEY_TO_ASSET_MAP[anAsset.KEY] = anAsset }); - -export const spec = { - code: BIDDER_CODE, - gvlid: GVLID, - supportedMediaTypes: [BANNER, NATIVE], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - // siteId is required - if (bid.params && bid.params.siteId) { - // it must be a string - if (!utils.isStr(bid.params.siteId)) { - _logWarn('siteId is required for bid', bid); - return false; - } - } else { - return false; - } - - return true; - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - var refererInfo; - if (bidderRequest && bidderRequest.refererInfo) { - refererInfo = bidderRequest.refererInfo; - } - var conf = _initConf(refererInfo); - var payload = _createOrtbTemplate(conf); - var bidCurrency = ''; - var bid; - var blockedIabCategories = []; - - validBidRequests.forEach(originalBid => { - bid = utils.deepClone(originalBid); - bid.params.adSlot = bid.params.adSlot || ''; - _parseAdSlot(bid); - - conf = _handleCustomParams(bid.params, conf); - conf.transactionId = bid.transactionId; - bidCurrency = bid.params.currency || UNDEFINED; - bid.params.currency = bidCurrency; - - if (bid.params.hasOwnProperty('bcat') && utils.isArray(bid.params.bcat)) { - blockedIabCategories = blockedIabCategories.concat(bid.params.bcat); - } - - var impObj = _createImpressionObject(bid, conf); - if (impObj) { - payload.imp.push(impObj); - } - }); - - // no payload imps, no rason to continue - if (payload.imp.length == 0) { - return; - } - - // test bids can also be turned on here - if (window.location.href.indexOf('pubwiseTestBid=true') !== -1) { - payload.test = 1; - } - - if (bid.params.isTest) { - payload.test = Number(bid.params.isTest) // should be 1 or 0 - } - payload.site.publisher.id = bid.params.siteId.trim(); - payload.user.gender = (conf.gender ? conf.gender.trim() : UNDEFINED); - payload.user.geo = {}; - payload.user.geo.lat = _parseSlotParam('lat', conf.lat); - payload.user.geo.lon = _parseSlotParam('lon', conf.lon); - payload.user.yob = _parseSlotParam('yob', conf.yob); - payload.device.geo = payload.user.geo; - payload.site.page = payload.site.page.trim(); - payload.site.domain = _getDomainFromURL(payload.site.page); - - // add the content object from config in request - if (typeof config.getConfig('content') === 'object') { - payload.site.content = config.getConfig('content'); - } - - // merge the device from config.getConfig('device') - if (typeof config.getConfig('device') === 'object') { - payload.device = Object.assign(payload.device, config.getConfig('device')); - } - - // passing transactionId in source.tid - utils.deepSetValue(payload, 'source.tid', conf.transactionId); - - // schain - if (validBidRequests[0].schain) { - utils.deepSetValue(payload, 'source.ext.schain', validBidRequests[0].schain); - } - - // gdpr consent - if (bidderRequest && bidderRequest.gdprConsent) { - utils.deepSetValue(payload, 'user.ext.consent', bidderRequest.gdprConsent.consentString); - utils.deepSetValue(payload, 'regs.ext.gdpr', (bidderRequest.gdprConsent.gdprApplies ? 1 : 0)); - } - - // ccpa on the root object - if (bidderRequest && bidderRequest.uspConsent) { - utils.deepSetValue(payload, 'regs.ext.us_privacy', bidderRequest.uspConsent); - } - - // if coppa is in effect then note it - if (config.getConfig('coppa') === true) { - utils.deepSetValue(payload, 'regs.coppa', 1); - } - - var options = {contentType: 'text/plain'} - - _logInfo('buildRequests payload', payload); - _logInfo('buildRequests bidderRequest', bidderRequest); - - return { - method: 'POST', - url: ENDPOINT_URL, - data: payload, - options: options, - bidderRequest: bidderRequest, - }; - }, - /** - * Unpack the 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. - */ - interpretResponse: function (response, request) { - const bidResponses = []; - var respCur = DEFAULT_CURRENCY; - _logInfo('interpretResponse request', request); - let parsedRequest = request.data; // not currently stringified - // let parsedReferrer = parsedRequest.site && parsedRequest.site.ref ? parsedRequest.site.ref : ''; - - // try { - if (response.body && response.body.seatbid && utils.isArray(response.body.seatbid)) { - // Supporting multiple bid responses for same adSize - respCur = response.body.cur || respCur; - response.body.seatbid.forEach(seatbidder => { - seatbidder.bid && - utils.isArray(seatbidder.bid) && - seatbidder.bid.forEach(bid => { - let newBid = { - requestId: bid.impid, - cpm: (parseFloat(bid.price) || 0).toFixed(2), - width: bid.w, - height: bid.h, - creativeId: bid.crid || bid.id, - currency: respCur, - netRevenue: NET_REVENUE, - ttl: 300, - ad: bid.adm, - pw_seat: seatbidder.seat || null, - pw_dspid: bid.ext && bid.ext.dspid ? bid.ext.dspid : null, - partnerImpId: bid.id || '' // partner impression Id - }; - if (parsedRequest.imp && parsedRequest.imp.length > 0) { - parsedRequest.imp.forEach(req => { - if (bid.impid === req.id) { - _checkMediaType(bid.adm, newBid); - switch (newBid.mediaType) { - case BANNER: - break; - case NATIVE: - _parseNativeResponse(bid, newBid); - break; - } - } - }); - } - - newBid.meta = {}; - if (bid.ext && bid.ext.dspid) { - newBid.meta.networkId = bid.ext.dspid; - } - if (bid.ext && bid.ext.advid) { - newBid.meta.buyerId = bid.ext.advid; - } - if (bid.adomain && bid.adomain.length > 0) { - newBid.meta.advertiserDomains = bid.adomain; - newBid.meta.clickUrl = bid.adomain[0]; - } - - bidResponses.push(newBid); - }); - }); - } - // } catch (error) { - // _logError(error); - // } - return bidResponses; - } -} - -function _checkMediaType(adm, newBid) { - // Create a regex here to check the strings - var admJSON = ''; - if (adm.indexOf('"ver":') >= 0) { - try { - admJSON = JSON.parse(adm.replace(/\\/g, '')); - if (admJSON && admJSON.assets) { - newBid.mediaType = NATIVE; - } - } catch (e) { - _logWarn('Error: Cannot parse native reponse for ad response: ' + adm); - } - } else { - newBid.mediaType = BANNER; - } -} - -function _parseNativeResponse(bid, newBid) { - newBid.native = {}; - if (bid.hasOwnProperty('adm')) { - var adm = ''; - try { - adm = JSON.parse(bid.adm.replace(/\\/g, '')); - } catch (ex) { - _logWarn('Error: Cannot parse native reponse for ad response: ' + newBid.adm); - return; - } - if (adm && adm.assets && adm.assets.length > 0) { - newBid.mediaType = NATIVE; - for (let i = 0, len = adm.assets.length; i < len; i++) { - switch (adm.assets[i].id) { - case NATIVE_ASSETS.TITLE.ID: - newBid.native.title = adm.assets[i].title && adm.assets[i].title.text; - break; - case NATIVE_ASSETS.IMAGE.ID: - newBid.native.image = { - url: adm.assets[i].img && adm.assets[i].img.url, - height: adm.assets[i].img && adm.assets[i].img.h, - width: adm.assets[i].img && adm.assets[i].img.w, - }; - break; - case NATIVE_ASSETS.ICON.ID: - newBid.native.icon = { - url: adm.assets[i].img && adm.assets[i].img.url, - height: adm.assets[i].img && adm.assets[i].img.h, - width: adm.assets[i].img && adm.assets[i].img.w, - }; - break; - case NATIVE_ASSETS.SPONSOREDBY.ID: - case NATIVE_ASSETS.BODY.ID: - case NATIVE_ASSETS.LIKES.ID: - case NATIVE_ASSETS.DOWNLOADS.ID: - case NATIVE_ASSETS.PRICE: - case NATIVE_ASSETS.SALEPRICE.ID: - case NATIVE_ASSETS.PHONE.ID: - case NATIVE_ASSETS.ADDRESS.ID: - case NATIVE_ASSETS.DESC2.ID: - case NATIVE_ASSETS.CTA.ID: - case NATIVE_ASSETS.RATING.ID: - case NATIVE_ASSETS.DISPLAYURL.ID: - newBid.native[NATIVE_ASSET_ID_TO_KEY_MAP[adm.assets[i].id]] = adm.assets[i].data && adm.assets[i].data.value; - break; - } - } - newBid.clickUrl = adm.link && adm.link.url; - newBid.clickTrackers = (adm.link && adm.link.clicktrackers) || []; - newBid.impressionTrackers = adm.imptrackers || []; - newBid.jstracker = adm.jstracker || []; - if (!newBid.width) { - newBid.width = DEFAULT_WIDTH; - } - if (!newBid.height) { - newBid.height = DEFAULT_HEIGHT; - } - } - } -} - -function _getDomainFromURL(url) { - let anchor = document.createElement('a'); - anchor.href = url; - return anchor.hostname; -} - -function _handleCustomParams(params, conf) { - var key, value, entry; - for (key in CUSTOM_PARAMS) { - if (CUSTOM_PARAMS.hasOwnProperty(key)) { - value = params[key]; - if (value) { - entry = CUSTOM_PARAMS[key]; - - if (typeof entry === 'object') { - // will be used in future when we want to - // process a custom param before using - // 'keyname': {f: function() {}} - value = entry.f(value, conf); - } - - if (utils.isStr(value)) { - conf[key] = value; - } else { - _logWarn('Ignoring param : ' + key + ' with value : ' + CUSTOM_PARAMS[key] + ', expects string-value, found ' + typeof value); - } - } - } - } - return conf; -} - -function _createOrtbTemplate(conf) { - return { - id: '' + new Date().getTime(), - at: AUCTION_TYPE, - cur: [DEFAULT_CURRENCY], - imp: [], - site: { - page: conf.pageURL, - ref: conf.refURL, - publisher: {} - }, - device: { - ua: navigator.userAgent, - js: 1, - dnt: (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0, - h: screen.height, - w: screen.width, - language: navigator.language - }, - user: {}, - ext: { - version: VERSION - } - }; -} - -function _createImpressionObject(bid, conf) { - var impObj = {}; - var bannerObj; - var nativeObj = {}; - var mediaTypes = ''; - - impObj = { - id: bid.bidId, - tagid: bid.params.adUnit || undefined, - bidfloor: _parseSlotParam('bidFloor', bid.params.bidFloor), // capitalization dicated by 3.2.4 spec - secure: 1, - bidfloorcur: bid.params.currency ? _parseSlotParam('currency', bid.params.currency) : DEFAULT_CURRENCY // capitalization dicated by 3.2.4 spec - }; - - if (bid.hasOwnProperty('mediaTypes')) { - for (mediaTypes in bid.mediaTypes) { - switch (mediaTypes) { - case BANNER: - bannerObj = _createBannerRequest(bid); - if (bannerObj !== UNDEFINED) { - impObj.banner = bannerObj; - } - break; - case NATIVE: - nativeObj['request'] = JSON.stringify(_createNativeRequest(bid.nativeParams)); - if (!isInvalidNativeRequest) { - impObj.native = nativeObj; - } else { - _logWarn('Error: Error in Native adunit ' + bid.params.adUnit + '. Ignoring the adunit. Refer to ' + PREBID_NATIVE_HELP_LINK + ' for more details.'); - } - break; - } - } - } else { - _logWarn('MediaTypes are Required for all Adunit Configs', bid) - } - - _addFloorFromFloorModule(impObj, bid); - - return impObj.hasOwnProperty(BANNER) || - impObj.hasOwnProperty(NATIVE) ? impObj : UNDEFINED; -} - -function _parseSlotParam(paramName, paramValue) { - if (!utils.isStr(paramValue)) { - paramValue && _logWarn('Ignoring param key: ' + paramName + ', expects string-value, found ' + typeof paramValue); - return UNDEFINED; - } - - switch (paramName) { - case 'bidFloor': - return parseFloat(paramValue) || UNDEFINED; - case 'lat': - return parseFloat(paramValue) || UNDEFINED; - case 'lon': - return parseFloat(paramValue) || UNDEFINED; - case 'yob': - return parseInt(paramValue) || UNDEFINED; - default: - return paramValue; - } -} - -function _parseAdSlot(bid) { - _logInfo('parseAdSlot bid', bid) - bid.params.adUnit = ''; - bid.params.width = 0; - bid.params.height = 0; - bid.params.adSlot = _cleanSlotName(bid.params.adSlot); - - if (bid.hasOwnProperty('mediaTypes')) { - if (bid.mediaTypes.hasOwnProperty(BANNER) && - bid.mediaTypes.banner.hasOwnProperty('sizes')) { // if its a banner, has mediaTypes and sizes - var i = 0; - var sizeArray = []; - for (;i < bid.mediaTypes.banner.sizes.length; i++) { - if (bid.mediaTypes.banner.sizes[i].length === 2) { // sizes[i].length will not be 2 in case where size is set as fluid, we want to skip that entry - sizeArray.push(bid.mediaTypes.banner.sizes[i]); - } - } - bid.mediaTypes.banner.sizes = sizeArray; - if (bid.mediaTypes.banner.sizes.length >= 1) { - // if there is more than one size then pop one onto the banner params width - // pop the first into the params, then remove it from mediaTypes - bid.params.width = bid.mediaTypes.banner.sizes[0][0]; - bid.params.height = bid.mediaTypes.banner.sizes[0][1]; - bid.mediaTypes.banner.sizes = bid.mediaTypes.banner.sizes.splice(1, bid.mediaTypes.banner.sizes.length - 1); - } - } - } else { - _logWarn('MediaTypes are Required for all Adunit Configs', bid) - } -} - -function _cleanSlotName(slotName) { - if (utils.isStr(slotName)) { - return slotName.replace(/^\s+/g, '').replace(/\s+$/g, ''); - } - return ''; -} - -function _initConf(refererInfo) { - return { - pageURL: (refererInfo && refererInfo.referer) ? refererInfo.referer : window.location.href, - refURL: window.document.referrer - }; -} - -function _commonNativeRequestObject(nativeAsset, params) { - var key = nativeAsset.KEY; - return { - id: nativeAsset.ID, - required: params[key].required ? 1 : 0, - data: { - type: nativeAsset.TYPE, - len: params[key].len, - ext: params[key].ext - } - }; -} - -function _addFloorFromFloorModule(impObj, bid) { - let bidFloor = -1; // indicates no floor - - // get lowest floor from floorModule - if (typeof bid.getFloor === 'function' && !config.getConfig('pubwise.disableFloors')) { - [BANNER, NATIVE].forEach(mediaType => { - if (impObj.hasOwnProperty(mediaType)) { - let floorInfo = bid.getFloor({ currency: impObj.bidFloorCur, mediaType: mediaType, size: '*' }); - if (typeof floorInfo === 'object' && floorInfo.currency === impObj.bidFloorCur && !isNaN(parseInt(floorInfo.floor))) { - let mediaTypeFloor = parseFloat(floorInfo.floor); - bidFloor = (bidFloor == -1 ? mediaTypeFloor : Math.min(mediaTypeFloor, bidFloor)) - } - } - }); - } - - // get highest, if none then take the default -1 - if (impObj.bidfloor) { - bidFloor = Math.max(bidFloor, impObj.bidfloor) - } - - // assign if it has a valid floor - > 0 - impObj.bidfloor = ((!isNaN(bidFloor) && bidFloor > 0) ? bidFloor : UNDEFINED); -} - -function _createNativeRequest(params) { - var nativeRequestObject = { - assets: [] - }; - for (var key in params) { - if (params.hasOwnProperty(key)) { - var assetObj = {}; - if (!(nativeRequestObject.assets && nativeRequestObject.assets.length > 0 && nativeRequestObject.assets.hasOwnProperty(key))) { - switch (key) { - case NATIVE_ASSETS.TITLE.KEY: - if (params[key].len || params[key].length) { - assetObj = { - id: NATIVE_ASSETS.TITLE.ID, - required: params[key].required ? 1 : 0, - title: { - len: params[key].len || params[key].length, - ext: params[key].ext - } - }; - } else { - _logWarn('Error: Title Length is required for native ad: ' + JSON.stringify(params)); - } - break; - case NATIVE_ASSETS.IMAGE.KEY: - if (params[key].sizes && params[key].sizes.length > 0) { - assetObj = { - id: NATIVE_ASSETS.IMAGE.ID, - required: params[key].required ? 1 : 0, - img: { - type: NATIVE_ASSET_IMAGE_TYPE.IMAGE, - w: params[key].w || params[key].width || (params[key].sizes ? params[key].sizes[0] : UNDEFINED), - h: params[key].h || params[key].height || (params[key].sizes ? params[key].sizes[1] : UNDEFINED), - wmin: params[key].wmin || params[key].minimumWidth || (params[key].minsizes ? params[key].minsizes[0] : UNDEFINED), - hmin: params[key].hmin || params[key].minimumHeight || (params[key].minsizes ? params[key].minsizes[1] : UNDEFINED), - mimes: params[key].mimes, - ext: params[key].ext, - } - }; - } else { - _logWarn('Error: Image sizes is required for native ad: ' + JSON.stringify(params)); - } - break; - case NATIVE_ASSETS.ICON.KEY: - if (params[key].sizes && params[key].sizes.length > 0) { - assetObj = { - id: NATIVE_ASSETS.ICON.ID, - required: params[key].required ? 1 : 0, - img: { - type: NATIVE_ASSET_IMAGE_TYPE.ICON, - w: params[key].w || params[key].width || (params[key].sizes ? params[key].sizes[0] : UNDEFINED), - h: params[key].h || params[key].height || (params[key].sizes ? params[key].sizes[1] : UNDEFINED), - } - }; - } else { - _logWarn('Error: Icon sizes is required for native ad: ' + JSON.stringify(params)); - }; - break; - case NATIVE_ASSETS.VIDEO.KEY: - assetObj = { - id: NATIVE_ASSETS.VIDEO.ID, - required: params[key].required ? 1 : 0, - video: { - minduration: params[key].minduration, - maxduration: params[key].maxduration, - protocols: params[key].protocols, - mimes: params[key].mimes, - ext: params[key].ext - } - }; - break; - case NATIVE_ASSETS.EXT.KEY: - assetObj = { - id: NATIVE_ASSETS.EXT.ID, - required: params[key].required ? 1 : 0, - }; - break; - case NATIVE_ASSETS.LOGO.KEY: - assetObj = { - id: NATIVE_ASSETS.LOGO.ID, - required: params[key].required ? 1 : 0, - img: { - type: NATIVE_ASSET_IMAGE_TYPE.LOGO, - w: params[key].w || params[key].width || (params[key].sizes ? params[key].sizes[0] : UNDEFINED), - h: params[key].h || params[key].height || (params[key].sizes ? params[key].sizes[1] : UNDEFINED) - } - }; - break; - case NATIVE_ASSETS.SPONSOREDBY.KEY: - case NATIVE_ASSETS.BODY.KEY: - case NATIVE_ASSETS.RATING.KEY: - case NATIVE_ASSETS.LIKES.KEY: - case NATIVE_ASSETS.DOWNLOADS.KEY: - case NATIVE_ASSETS.PRICE.KEY: - case NATIVE_ASSETS.SALEPRICE.KEY: - case NATIVE_ASSETS.PHONE.KEY: - case NATIVE_ASSETS.ADDRESS.KEY: - case NATIVE_ASSETS.DESC2.KEY: - case NATIVE_ASSETS.DISPLAYURL.KEY: - case NATIVE_ASSETS.CTA.KEY: - assetObj = _commonNativeRequestObject(NATIVE_ASSET_KEY_TO_ASSET_MAP[key], params); - break; - } - } - } - if (assetObj && assetObj.id) { - nativeRequestObject.assets[nativeRequestObject.assets.length] = assetObj; - } - }; - - // for native image adtype prebid has to have few required assests i.e. title,sponsoredBy, image - // if any of these are missing from the request then request will not be sent - var requiredAssetCount = NATIVE_MINIMUM_REQUIRED_IMAGE_ASSETS.length; - var presentrequiredAssetCount = 0; - NATIVE_MINIMUM_REQUIRED_IMAGE_ASSETS.forEach(ele => { - var lengthOfExistingAssets = nativeRequestObject.assets.length; - for (var i = 0; i < lengthOfExistingAssets; i++) { - if (ele.id == nativeRequestObject.assets[i].id) { - presentrequiredAssetCount++; - break; - } - } - }); - if (requiredAssetCount == presentrequiredAssetCount) { - isInvalidNativeRequest = false; - } else { - isInvalidNativeRequest = true; - } - return nativeRequestObject; -} - -function _createBannerRequest(bid) { - var sizes = bid.mediaTypes.banner.sizes; - var format = []; - var bannerObj; - if (sizes !== UNDEFINED && utils.isArray(sizes)) { - bannerObj = {}; - if (!bid.params.width && !bid.params.height) { - if (sizes.length === 0) { - // i.e. since bid.params does not have width or height, and length of sizes is 0, need to ignore this banner imp - bannerObj = UNDEFINED; - _logWarn('Error: mediaTypes.banner.size missing for adunit: ' + bid.params.adUnit + '. Ignoring the banner impression in the adunit.'); - return bannerObj; - } else { - bannerObj.w = parseInt(sizes[0][0], 10); - bannerObj.h = parseInt(sizes[0][1], 10); - sizes = sizes.splice(1, sizes.length - 1); - } - } else { - bannerObj.w = bid.params.width; - bannerObj.h = bid.params.height; - } - if (sizes.length > 0) { - format = []; - sizes.forEach(function (size) { - if (size.length > 1) { - format.push({ w: size[0], h: size[1] }); - } - }); - if (format.length > 0) { - bannerObj.format = format; - } - } - bannerObj.pos = 0; - bannerObj.topframe = utils.inIframe() ? 0 : 1; - } else { - _logWarn('Error: mediaTypes.banner.size missing for adunit: ' + bid.params.adUnit + '. Ignoring the banner impression in the adunit.'); - bannerObj = UNDEFINED; - } - return bannerObj; -} - -// various error levels are not always used -// eslint-disable-next-line no-unused-vars -function _logMessage(textValue, objectValue) { - utils.logMessage('PubWise: ' + textValue, objectValue); -} - -// eslint-disable-next-line no-unused-vars -function _logInfo(textValue, objectValue) { - utils.logInfo('PubWise: ' + textValue, objectValue); -} - -// eslint-disable-next-line no-unused-vars -function _logWarn(textValue, objectValue) { - utils.logWarn('PubWise: ' + textValue, objectValue); -} - -// eslint-disable-next-line no-unused-vars -function _logError(textValue, objectValue) { - utils.logError('PubWise: ' + textValue, objectValue); -} - -// function _decorateLog() { -// arguments[0] = 'PubWise' + arguments[0]; -// return arguments -// } - -// these are exported only for testing so maintaining the JS convention of _ to indicate the intent -export { - _checkMediaType, - _parseAdSlot -} - -registerBidder(spec); diff --git a/modules/pubwiseBidAdapter.md b/modules/pubwiseBidAdapter.md deleted file mode 100644 index 8cf38a63913..00000000000 --- a/modules/pubwiseBidAdapter.md +++ /dev/null @@ -1,78 +0,0 @@ -# Overview - -``` -Module Name: PubWise Bid Adapter -Module Type: Bidder Adapter -Maintainer: info@pubwise.io -``` - -# Description - -Connects to PubWise exchange for bids. - -# Sample Banner Ad Unit: For Publishers - -With isTest parameter the system will respond in whatever dimensions provided. - -## Params - - - -## Banner -``` -var adUnits = [ - { - code: "div-gpt-ad-1460505748561-0", - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [{ - bidder: 'pubwise', - params: { - siteId: "xxxxxx", - isTest: true - } - }] - } -] -``` -## Native -``` -var adUnits = [ - { - code: 'div-gpt-ad-1460505748561-1', - sizes: [[1, 1]], - mediaTypes: { - native: { - title: { - required: true, - len: 80 - }, - body: { - required: true - }, - image: { - required: true, - sizes: [150, 50] - }, - sponsoredBy: { - required: true - }, - icon: { - required: false - } - } - }, - bids: [{ - bidder: 'pubwise', - params: { - siteId: "xxxxxx", - isTest: true, - }, - }] - } -] -``` - diff --git a/modules/pubxBidAdapter.js b/modules/pubxBidAdapter.js deleted file mode 100644 index 35d75e96f95..00000000000 --- a/modules/pubxBidAdapter.js +++ /dev/null @@ -1,94 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -const BIDDER_CODE = 'pubx'; -const BID_ENDPOINT = 'https://api.primecaster.net/adlogue/api/slot/bid'; -const USER_SYNC_URL = 'https://api.primecaster.net/primecaster_dmppv.html' -export const spec = { - code: BIDDER_CODE, - isBidRequestValid: function(bid) { - if (!(bid.params.sid)) { - return false; - } else { return true } - }, - buildRequests: function(validBidRequests) { - return validBidRequests.map(bidRequest => { - const bidId = bidRequest.bidId; - const params = bidRequest.params; - const sid = params.sid; - const payload = { - sid: sid - }; - return { - id: bidId, - method: 'GET', - url: BID_ENDPOINT, - data: payload, - } - }); - }, - interpretResponse: function(serverResponse, bidRequest) { - const body = serverResponse.body; - const bidResponses = []; - if (body.cid) { - const bidResponse = { - requestId: bidRequest.id, - cpm: body.cpm, - currency: body.currency, - width: body.width, - height: body.height, - creativeId: body.cid, - netRevenue: true, - ttl: body.TTL, - ad: body.adm - }; - bidResponses.push(bidResponse); - } else {}; - return bidResponses; - }, - /** - * Determine which user syncs should occur - * @param {object} syncOptions - * @param {array} serverResponses - * @returns {array} User sync pixels - */ - getUserSyncs: function (syncOptions, serverResponses) { - const kwTag = document.getElementsByName('keywords'); - let kwString = ''; - let kwEnc = ''; - let titleContent = !!document.title && document.title; - let titleEnc = ''; - let descContent = !!document.getElementsByName('description') && !!document.getElementsByName('description')[0] && document.getElementsByName('description')[0].content; - let descEnc = ''; - const pageUrl = location.href.replace(/\?.*$/, ''); - const pageEnc = encodeURIComponent(pageUrl); - const refUrl = document.referrer.replace(/\?.*$/, ''); - const refEnc = encodeURIComponent(refUrl); - if (kwTag.length) { - const kwContents = kwTag[0].content; - if (kwContents.length > 20) { - const kwArray = kwContents.substr(0, 20).split(','); - kwArray.pop(); - kwString = kwArray.join(); - } else { - kwString = kwContents; - } - kwEnc = encodeURIComponent(kwString) - } else { } - if (titleContent) { - if (titleContent.length > 30) { - titleContent = titleContent.substr(0, 30); - } else {}; - titleEnc = encodeURIComponent(titleContent); - } else { }; - if (descContent) { - if (descContent.length > 60) { - descContent = descContent.substr(0, 60); - } else {}; - descEnc = encodeURIComponent(descContent); - } else { }; - return (syncOptions.iframeEnabled) ? [{ - type: 'iframe', - url: USER_SYNC_URL + '?pkw=' + kwEnc + '&pd=' + descEnc + '&pu=' + pageEnc + '&pref=' + refEnc + '&pt=' + titleEnc - }] : []; - } -} -registerBidder(spec); diff --git a/modules/pubxBidAdapter.md b/modules/pubxBidAdapter.md deleted file mode 100644 index da7d960c831..00000000000 --- a/modules/pubxBidAdapter.md +++ /dev/null @@ -1,32 +0,0 @@ -# Overview - -Module Name: pubx Bid Adapter - -Maintainer: x@pub-x.io - -# Description - -Module that connects to Pub-X's demand sources -Supported MediaTypes: banner only - -# Test Parameters -```javascript - var adUnits = [ - { - code: 'test', - mediaTypes: { - banner: { - sizes: [300,250] - } - }, - bids: [ - { - bidder: 'pubx', - params: { - sid: 'eDMR' //ID should be provided by Pub-X - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/pubxaiAnalyticsAdapter.js b/modules/pubxaiAnalyticsAdapter.js deleted file mode 100644 index 136b328d381..00000000000 --- a/modules/pubxaiAnalyticsAdapter.js +++ /dev/null @@ -1,182 +0,0 @@ -import { ajax } from '../src/ajax.js'; -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -import CONSTANTS from '../src/constants.json'; -import * as utils from '../src/utils.js'; - -const emptyUrl = ''; -const analyticsType = 'endpoint'; -const pubxaiAnalyticsVersion = 'v1.1.0'; -const defaultHost = 'api.pbxai.com'; -const auctionPath = '/analytics/auction'; -const winningBidPath = '/analytics/bidwon'; - -let initOptions; -let auctionTimestamp; -let auctionCache = []; -let events = { - bids: [], - floorDetail: {}, - pageDetail: {}, - deviceDetail: {} -}; - -var pubxaiAnalyticsAdapter = Object.assign(adapter( - { - emptyUrl, - analyticsType - }), { - track({ eventType, args }) { - if (typeof args !== 'undefined') { - if (eventType === CONSTANTS.EVENTS.BID_TIMEOUT) { - args.forEach(item => { mapBidResponse(item, 'timeout'); }); - } else if (eventType === CONSTANTS.EVENTS.AUCTION_INIT) { - events.auctionInit = args; - events.floorDetail = {}; - events.bids = []; - const floorData = utils.deepAccess(args, 'bidderRequests.0.bids.0.floorData'); - if (typeof floorData !== 'undefined') { - Object.assign(events.floorDetail, floorData); - } - auctionTimestamp = args.timestamp; - } else if (eventType === CONSTANTS.EVENTS.BID_RESPONSE) { - mapBidResponse(args, 'response'); - } else if (eventType === CONSTANTS.EVENTS.BID_WON) { - send({ - winningBid: mapBidResponse(args, 'bidwon') - }, 'bidwon'); - } - } - if (eventType === CONSTANTS.EVENTS.AUCTION_END) { - send(events, 'auctionEnd'); - } - } -}); - -function mapBidResponse(bidResponse, status) { - if (typeof bidResponse !== 'undefined') { - let bid = { - adUnitCode: bidResponse.adUnitCode, - auctionId: bidResponse.auctionId, - bidderCode: bidResponse.bidder, - cpm: bidResponse.cpm, - creativeId: bidResponse.creativeId, - currency: bidResponse.currency, - floorData: bidResponse.floorData, - mediaType: bidResponse.mediaType, - netRevenue: bidResponse.netRevenue, - requestTimestamp: bidResponse.requestTimestamp, - responseTimestamp: bidResponse.responseTimestamp, - status: bidResponse.status, - statusMessage: bidResponse.statusMessage, - timeToRespond: bidResponse.timeToRespond, - transactionId: bidResponse.transactionId - }; - if (status !== 'bidwon') { - Object.assign(bid, { - bidId: status === 'timeout' ? bidResponse.bidId : bidResponse.requestId, - renderStatus: status === 'timeout' ? 3 : 2, - sizes: utils.parseSizesInput(bidResponse.size).toString(), - }); - events.bids.push(bid); - } else { - Object.assign(bid, { - bidId: bidResponse.requestId, - floorProvider: events.floorDetail ? events.floorDetail.floorProvider : null, - isWinningBid: true, - placementId: bidResponse.params ? utils.deepAccess(bidResponse, 'params.0.placementId') : null, - renderedSize: bidResponse.size, - renderStatus: 4 - }); - return bid; - } - } -} - -export function getDeviceType() { - if ((/ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i.test(navigator.userAgent.toLowerCase()))) { - return 'tablet'; - } - if ((/iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i.test(navigator.userAgent.toLowerCase()))) { - return 'mobile'; - } - return 'desktop'; -} - -export function getBrowser() { - if (/Chrome/.test(navigator.userAgent) && /Google Inc/.test(navigator.vendor)) return 'Chrome'; - else if (navigator.userAgent.match('CriOS')) return 'Chrome'; - else if (/Firefox/.test(navigator.userAgent)) return 'Firefox'; - else if (/Edg/.test(navigator.userAgent)) return 'Microsoft Edge'; - else if (/Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor)) return 'Safari'; - else if (/Trident/.test(navigator.userAgent) || /MSIE/.test(navigator.userAgent)) return 'Internet Explorer'; - else return 'Others'; -} - -export function getOS() { - if (navigator.userAgent.indexOf('Android') != -1) return 'Android'; - if (navigator.userAgent.indexOf('like Mac') != -1) return 'iOS'; - if (navigator.userAgent.indexOf('Win') != -1) return 'Windows'; - if (navigator.userAgent.indexOf('Mac') != -1) return 'Macintosh'; - if (navigator.userAgent.indexOf('Linux') != -1) return 'Linux'; - if (navigator.appVersion.indexOf('X11') != -1) return 'Unix'; - return 'Others'; -} - -// add sampling rate -pubxaiAnalyticsAdapter.shouldFireEventRequest = function (samplingRate = 1) { - return (Math.floor((Math.random() * samplingRate + 1)) === parseInt(samplingRate)); -} - -function send(data, status) { - if (pubxaiAnalyticsAdapter.shouldFireEventRequest(initOptions.samplingRate)) { - let location = utils.getWindowLocation(); - data.initOptions = initOptions; - if (typeof data !== 'undefined' && typeof data.auctionInit !== 'undefined') { - Object.assign(data.pageDetail, { - host: location.host, - path: location.pathname, - search: location.search, - adUnitCount: data.auctionInit.adUnitCodes ? data.auctionInit.adUnitCodes.length : null - }); - data.initOptions.auctionId = data.auctionInit.auctionId; - delete data.auctionInit; - } - data.deviceDetail = {}; - Object.assign(data.deviceDetail, { - platform: navigator.platform, - deviceType: getDeviceType(), - deviceOS: getOS(), - browser: getBrowser() - }); - let pubxaiAnalyticsRequestUrl = utils.buildUrl({ - protocol: 'https', - hostname: (initOptions && initOptions.hostName) || defaultHost, - pathname: status == 'bidwon' ? winningBidPath : auctionPath, - search: { - auctionTimestamp: auctionTimestamp, - pubxaiAnalyticsVersion: pubxaiAnalyticsVersion, - prebidVersion: $$PREBID_GLOBAL$$.version - } - }); - if (status == 'bidwon') { - ajax(pubxaiAnalyticsRequestUrl, undefined, JSON.stringify(data), { method: 'POST', contentType: 'text/json' }); - } else if (status == 'auctionEnd' && auctionCache.indexOf(data.initOptions.auctionId) === -1) { - ajax(pubxaiAnalyticsRequestUrl, undefined, JSON.stringify(data), { method: 'POST', contentType: 'text/json' }); - auctionCache.push(data.initOptions.auctionId); - } - } -} - -pubxaiAnalyticsAdapter.originEnableAnalytics = pubxaiAnalyticsAdapter.enableAnalytics; -pubxaiAnalyticsAdapter.enableAnalytics = function (config) { - initOptions = config.options; - pubxaiAnalyticsAdapter.originEnableAnalytics(config); -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: pubxaiAnalyticsAdapter, - code: 'pubxai' -}); - -export default pubxaiAnalyticsAdapter; diff --git a/modules/pubxaiAnalyticsAdapter.md b/modules/pubxaiAnalyticsAdapter.md deleted file mode 100644 index 112329fc171..00000000000 --- a/modules/pubxaiAnalyticsAdapter.md +++ /dev/null @@ -1,27 +0,0 @@ -# Overview -Module Name: PubX.io Analytics Adapter -Module Type: Analytics Adapter -Maintainer: phaneendra@pubx.ai - -# Description - -Analytics adapter for prebid provided by Pubx.ai. Contact alex@pubx.ai for information. - -# Test Parameters - -``` -{ - provider: 'pubxai', - options : { - pubxId: 'xxx', - hostName: 'example.com', - samplingRate: 1 - } -} -``` -Property | Data Type | Is required? | Description |Example -:-----:|:-----:|:-----:|:-----:|:-----: -pubxId|string|Yes | A unique identifier provided by PubX.ai to indetify publishers. |`"a9d48e2f-24ec-4ec1-b3e2-04e32c3aeb03"` -hostName|string|No|hostName is provided by Pubx.ai. |`"https://example.com"` -samplingRate |number |No|How often the sampling must be taken. |`2` - (sample one in two cases) \ `3` - (sample one in three cases) - | | | | \ No newline at end of file diff --git a/modules/pulsepointAnalyticsAdapter.js b/modules/pulsepointAnalyticsAdapter.js deleted file mode 100644 index 375a817f257..00000000000 --- a/modules/pulsepointAnalyticsAdapter.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * pulsepoint.js - Analytics Adapter for PulsePoint - */ - -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; - -var pulsepointAdapter = adapter({ - global: 'PulsePointPrebidAnalytics', - handler: 'on', - analyticsType: 'bundle' -}); - -adapterManager.registerAnalyticsAdapter({ - adapter: pulsepointAdapter, - code: 'pulsepoint' -}); - -export default pulsepointAdapter; diff --git a/modules/pulsepointBidAdapter.js b/modules/pulsepointBidAdapter.js deleted file mode 100644 index f74d79a3dc5..00000000000 --- a/modules/pulsepointBidAdapter.js +++ /dev/null @@ -1,522 +0,0 @@ -/* eslint dot-notation:0, quote-props:0 */ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { Renderer } from '../src/Renderer.js'; - -const NATIVE_DEFAULTS = { - TITLE_LEN: 100, - DESCR_LEN: 200, - SPONSORED_BY_LEN: 50, - IMG_MIN: 150, - ICON_MIN: 50, -}; - -const DEFAULT_BID_TTL = 20; -const DEFAULT_CURRENCY = 'USD'; -const DEFAULT_NET_REVENUE = true; -const KNOWN_PARAMS = ['cp', 'ct', 'cf', 'video', 'battr', 'bcat', 'badv', 'bidfloor']; - -/** - * PulsePoint Bid Adapter. - * Contact: ExchangeTeam@pulsepoint.com - * - * Aliases - pulseLite and pulsepointLite are supported for backwards compatibility. - * Formats - Display/Native/Video formats supported. - * - */ -export const spec = { - - code: 'pulsepoint', - - gvlid: 81, - - aliases: ['pulseLite', 'pulsepointLite'], - - supportedMediaTypes: ['banner', 'native', 'video'], - - isBidRequestValid: bid => ( - !!(bid && bid.params && bid.params.cp && bid.params.ct) - ), - - buildRequests: (bidRequests, bidderRequest) => { - const request = { - id: bidRequests[0].bidderRequestId, - imp: bidRequests.map(slot => impression(slot)), - site: site(bidRequests, bidderRequest), - app: app(bidRequests), - device: device(), - bcat: bidRequests[0].params.bcat, - badv: bidRequests[0].params.badv, - user: user(bidRequests[0], bidderRequest), - regs: regs(bidderRequest), - source: source(bidRequests[0].schain), - }; - return { - method: 'POST', - url: 'https://bid.contextweb.com/header/ortb?src=prebid', - data: request, - bidderRequest - }; - }, - - interpretResponse: (response, request) => ( - bidResponseAvailable(request, response) - ), - - getUserSyncs: syncOptions => { - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: 'https://bh.contextweb.com/visitormatch' - }]; - } else if (syncOptions.pixelEnabled) { - return [{ - type: 'image', - url: 'https://bh.contextweb.com/visitormatch/prebid' - }]; - } - }, - transformBidParams: function(params, isOpenRtb) { - return utils.convertTypes({ - 'cf': 'string', - 'cp': 'number', - 'ct': 'number' - }, params); - } -}; - -/** - * Callback for bids, after the call to PulsePoint completes. - */ -function bidResponseAvailable(request, response) { - const idToImpMap = {}; - const idToBidMap = {}; - const idToSlotConfig = {}; - const bidResponse = response.body - // extract the request bids and the response bids, keyed by impr-id - const ortbRequest = request.data; - ortbRequest.imp.forEach(imp => { - idToImpMap[imp.id] = imp; - }); - if (bidResponse) { - bidResponse.seatbid.forEach(seatBid => seatBid.bid.forEach(bid => { - idToBidMap[bid.impid] = bid; - })); - } - if (request.bidderRequest && request.bidderRequest.bids) { - request.bidderRequest.bids.forEach(bid => { - idToSlotConfig[bid.bidId] = bid; - }); - } - const bids = []; - Object.keys(idToImpMap).forEach(id => { - if (idToBidMap[id]) { - const bid = { - requestId: id, - cpm: idToBidMap[id].price, - creative_id: idToBidMap[id].crid, - creativeId: idToBidMap[id].crid, - adId: id, - ttl: idToBidMap[id].exp || DEFAULT_BID_TTL, - netRevenue: DEFAULT_NET_REVENUE, - currency: bidResponse.cur || DEFAULT_CURRENCY - }; - if (idToImpMap[id].video) { - // for outstream, a renderer is specified - if (idToSlotConfig[id] && utils.deepAccess(idToSlotConfig[id], 'mediaTypes.video.context') === 'outstream') { - bid.renderer = outstreamRenderer(utils.deepAccess(idToSlotConfig[id], 'renderer.options'), utils.deepAccess(idToBidMap[id], 'ext.outstream')); - } - bid.vastXml = idToBidMap[id].adm; - bid.mediaType = 'video'; - bid.width = idToBidMap[id].w; - bid.height = idToBidMap[id].h; - } else if (idToImpMap[id].banner) { - bid.ad = idToBidMap[id].adm; - bid.width = idToBidMap[id].w || idToImpMap[id].banner.w; - bid.height = idToBidMap[id].h || idToImpMap[id].banner.h; - } else if (idToImpMap[id]['native']) { - bid['native'] = nativeResponse(idToImpMap[id], idToBidMap[id]); - bid.mediaType = 'native'; - } - bids.push(bid); - } - }); - return bids; -} - -/** - * Produces an OpenRTBImpression from a slot config. - */ -function impression(slot) { - return { - id: slot.bidId, - banner: banner(slot), - 'native': nativeImpression(slot), - tagid: slot.params.ct.toString(), - video: video(slot), - bidfloor: slot.params.bidfloor, - ext: ext(slot), - }; -} - -/** - * Produces an OpenRTB Banner object for the slot given. - */ -function banner(slot) { - const sizes = parseSizes(slot); - const size = adSize(slot, sizes); - return (slot.mediaTypes && slot.mediaTypes.banner) ? { - w: size[0], - h: size[1], - battr: slot.params.battr, - format: sizes - } : null; -} - -/** - * Produce openrtb format objects based on the sizes configured for the slot. - */ -function parseSizes(slot) { - const sizes = utils.deepAccess(slot, 'mediaTypes.banner.sizes'); - if (sizes && utils.isArray(sizes)) { - return sizes.filter(sz => utils.isArray(sz) && sz.length === 2).map(sz => ({ - w: sz[0], - h: sz[1] - })); - } - return null; -} - -/** - * Produces an OpenRTB Video object for the slot given - */ -function video(slot) { - if (slot.params.video) { - return Object.assign({}, slot.params.video, {battr: slot.params.battr}); - } - return null; -} - -/** - * Unknown params are captured and sent on ext - */ -function ext(slot) { - const ext = {}; - const knownParamsMap = {}; - KNOWN_PARAMS.forEach(value => knownParamsMap[value] = 1); - Object.keys(slot.params).forEach(key => { - if (!knownParamsMap[key]) { - ext[key] = slot.params[key]; - } - }); - return Object.keys(ext).length > 0 ? { prebid: ext } : null; -} - -/** - * Sets up the renderer on the bid, for outstream bid responses. - */ -function outstreamRenderer(rendererOptions, outstreamExtOptions) { - const renderer = Renderer.install({ - url: outstreamExtOptions.rendererUrl, - config: { - defaultOptions: outstreamExtOptions.config, - rendererOptions, - type: outstreamExtOptions.type - }, - loaded: false, - }); - renderer.setRender((bid) => { - bid.renderer.push(() => { - const config = bid.renderer.getConfig(); - new window.PulsePointOutstreamRenderer().render({ - adUnitCode: bid.adUnitCode, - vastXml: bid.vastXml, - type: config.type, - defaultOptions: config.defaultOptions, - rendererOptions - }); - }); - }); - return renderer; -} - -/** - * Produces an OpenRTB Native object for the slot given. - */ -function nativeImpression(slot) { - if (slot.nativeParams) { - const assets = []; - addAsset(assets, titleAsset(assets.length + 1, slot.nativeParams.title, NATIVE_DEFAULTS.TITLE_LEN)); - addAsset(assets, dataAsset(assets.length + 1, slot.nativeParams.body, 2, NATIVE_DEFAULTS.DESCR_LEN)); - addAsset(assets, dataAsset(assets.length + 1, slot.nativeParams.sponsoredBy, 1, NATIVE_DEFAULTS.SPONSORED_BY_LEN)); - addAsset(assets, imageAsset(assets.length + 1, slot.nativeParams.icon, 1, NATIVE_DEFAULTS.ICON_MIN, NATIVE_DEFAULTS.ICON_MIN)); - addAsset(assets, imageAsset(assets.length + 1, slot.nativeParams.image, 3, NATIVE_DEFAULTS.IMG_MIN, NATIVE_DEFAULTS.IMG_MIN)); - return { - request: JSON.stringify({ assets }), - ver: '1.1', - battr: slot.params.battr, - }; - } - return null; -} - -/** - * Helper method to add an asset to the assets list. - */ -function addAsset(assets, asset) { - if (asset) { - assets.push(asset); - } -} - -/** - * Produces a Native Title asset for the configuration given. - */ -function titleAsset(id, params, defaultLen) { - if (params) { - return { - id, - required: params.required ? 1 : 0, - title: { - len: params.len || defaultLen, - }, - }; - } - return null; -} - -/** - * Produces a Native Image asset for the configuration given. - */ -function imageAsset(id, params, type, defaultMinWidth, defaultMinHeight) { - return params ? { - id, - required: params.required ? 1 : 0, - img: { - type, - wmin: params.wmin || defaultMinWidth, - hmin: params.hmin || defaultMinHeight, - } - } : null; -} - -/** - * Produces a Native Data asset for the configuration given. - */ -function dataAsset(id, params, type, defaultLen) { - return params ? { - id, - required: params.required ? 1 : 0, - data: { - type, - len: params.len || defaultLen, - } - } : null; -} - -/** - * Produces an OpenRTB site object. - */ -function site(bidRequests, bidderRequest) { - const pubId = bidRequests && bidRequests.length > 0 ? bidRequests[0].params.cp : '0'; - const appParams = bidRequests[0].params.app; - if (!appParams) { - return { - publisher: { - id: pubId.toString(), - }, - ref: referrer(), - page: bidderRequest && bidderRequest.refererInfo ? bidderRequest.refererInfo.referer : '', - } - } - return null; -} - -/** - * Produces an OpenRTB App object. - */ -function app(bidderRequest) { - const pubId = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.cp : '0'; - const appParams = bidderRequest[0].params.app; - if (appParams) { - return { - publisher: { - id: pubId.toString(), - }, - bundle: appParams.bundle, - storeurl: appParams.storeUrl, - domain: appParams.domain, - } - } - return null; -} - -/** - * Attempts to capture the referrer url. - */ -function referrer() { - try { - return window.top.document.referrer; - } catch (e) { - return document.referrer; - } -} - -/** - * Produces an OpenRTB Device object. - */ -function device() { - return { - ua: navigator.userAgent, - language: (navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage), - }; -} - -/** - * Safely parses the input given. Returns null on - * parsing failure. - */ -function parse(rawResponse) { - try { - if (rawResponse) { - return JSON.parse(rawResponse); - } - } catch (ex) { - utils.logError('pulsepointLite.safeParse', 'ERROR', ex); - } - return null; -} - -/** - * Determines the AdSize for the slot. - */ -function adSize(slot, sizes) { - if (slot.params.cf) { - const size = slot.params.cf.toUpperCase().split('X'); - const width = parseInt(slot.params.cw || size[0], 10); - const height = parseInt(slot.params.ch || size[1], 10); - return [width, height]; - } else if (sizes && sizes.length > 0) { - return [sizes[0].w, sizes[0].h]; - } - return [1, 1]; -} - -/** - * Handles the user level attributes and produces - * an openrtb User object. - */ -function user(bidRequest, bidderRequest) { - var ext = {}; - if (bidderRequest) { - if (bidderRequest.gdprConsent) { - ext.consent = bidderRequest.gdprConsent.consentString; - } - } - if (bidRequest) { - if (bidRequest.userId) { - ext.eids = []; - addExternalUserId(ext.eids, bidRequest.userId.pubcid, 'pubcommon'); - addExternalUserId(ext.eids, bidRequest.userId.britepoolid, 'britepool.com'); - addExternalUserId(ext.eids, bidRequest.userId.criteoId, 'criteo'); - addExternalUserId(ext.eids, bidRequest.userId.idl_env, 'identityLink'); - addExternalUserId(ext.eids, utils.deepAccess(bidRequest, 'userId.id5id.uid'), 'id5-sync.com', utils.deepAccess(bidRequest, 'userId.id5id.ext')); - addExternalUserId(ext.eids, utils.deepAccess(bidRequest, 'userId.parrableId.eid'), 'parrable.com'); - // liveintent - if (bidRequest.userId.lipb && bidRequest.userId.lipb.lipbid) { - addExternalUserId(ext.eids, bidRequest.userId.lipb.lipbid, 'liveintent.com'); - } - // TTD - addExternalUserId(ext.eids, bidRequest.userId.tdid, 'adserver.org', { - rtiPartner: 'TDID' - }); - // digitrust - const digitrustResponse = bidRequest.userId.digitrustid; - if (digitrustResponse && digitrustResponse.data) { - var digitrust = {}; - if (digitrustResponse.data.id) { - digitrust.id = digitrustResponse.data.id; - } - if (digitrustResponse.data.keyv) { - digitrust.keyv = digitrustResponse.data.keyv; - } - ext.digitrust = digitrust; - } - } - } - return { ext }; -} - -/** - * Produces external userid object in ortb 3.0 model. - */ -function addExternalUserId(eids, id, source, uidExt) { - if (id) { - var uid = { id }; - if (uidExt) { - uid.ext = uidExt; - } - eids.push({ - source, - uids: [ uid ] - }); - } -} - -/** - * Produces the regulations ortb object - */ -function regs(bidderRequest) { - if (bidderRequest.gdprConsent || bidderRequest.uspConsent) { - var ext = {}; - // GDPR applies attribute (actual consent value is in user object) - if (bidderRequest.gdprConsent) { - ext.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; - } - // CCPA - if (bidderRequest.uspConsent) { - ext.us_privacy = bidderRequest.uspConsent; - } - return { ext }; - } - return null; -} - -/** - * Creates source object with supply chain - */ -function source(schain) { - if (schain) { - return { - ext: { schain } - }; - } - return null; -} - -/** - * Parses the native response from the Bid given. - */ -function nativeResponse(imp, bid) { - if (imp['native']) { - const nativeAd = parse(bid.adm); - const keys = {}; - if (nativeAd && nativeAd['native'] && nativeAd['native'].assets) { - nativeAd['native'].assets.forEach(asset => { - keys.title = asset.title ? asset.title.text : keys.title; - keys.body = asset.data && asset.data.type === 2 ? asset.data.value : keys.body; - keys.sponsoredBy = asset.data && asset.data.type === 1 ? asset.data.value : keys.sponsoredBy; - keys.image = asset.img && asset.img.type === 3 ? asset.img.url : keys.image; - keys.icon = asset.img && asset.img.type === 1 ? asset.img.url : keys.icon; - }); - if (nativeAd['native'].link) { - keys.clickUrl = encodeURIComponent(nativeAd['native'].link.url); - } - keys.impressionTrackers = nativeAd['native'].imptrackers; - return keys; - } - } - return null; -} - -registerBidder(spec); diff --git a/modules/pulsepointBidAdapter.md b/modules/pulsepointBidAdapter.md deleted file mode 100644 index 36d4ef6cce5..00000000000 --- a/modules/pulsepointBidAdapter.md +++ /dev/null @@ -1,96 +0,0 @@ -# Overview - -**Module Name**: PulsePoint Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: ExchangeTeam@pulsepoint.com - -# Description - -Connects to PulsePoint demand source to fetch bids. -Banner, Video and Native formats are supported. -Please use ```pulsepoint``` as the bidder code. -```pulseLite``` and ```pulsepointLite``` aliases also supported as well. - -# Test Parameters -``` - var adUnits = [{ - code: 'banner-ad-div', - sizes: [[300, 250]], - bids: [{ - bidder: 'pulsepoint', - params: { - cf: '300X250', - cp: 512379, - ct: 486653 - } - }] - },{ - code: 'native-ad-div', - sizes: [[1, 1]], - nativeParams: { - title: { required: true, len: 75 }, - image: { required: true }, - body: { len: 200 }, - sponsoredBy: { len: 20 } - }, - bids: [{ - bidder: 'pulsepoint', - params: { - cp: 512379, - ct: 505642 - } - }] - },{ - code: 'outstream-div', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'outstream' - } - }, - bids: [{ - bidder: 'pulsepoint', - params: { - cp: 512379, - ct: 505642, - video: { - h: 300, - w: 400, - minduration: 1, - maxduration: 210, - linearity: 1, - mimes: ["video/mp4", "video/ogg", "video/webm"], - pos: 3 - } - } - }], - renderer: { - options: { - text: "PulsePoint Outstream" - } - } - },{ - code: 'instream', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'instream' - } - }, - bids: [{ - bidder: 'pulsepoint', - params: { - cp: 512379, - ct: 694973, - video: { - battr: [1,3], - h: 300, - w: 400, - minduration: 1, - maxduration: 210, - protocols: [2,3,5] - } - } - }] - }]; -``` diff --git a/modules/pxyzBidAdapter.js b/modules/pxyzBidAdapter.js deleted file mode 100644 index bd2189ccc39..00000000000 --- a/modules/pxyzBidAdapter.js +++ /dev/null @@ -1,195 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; - -const BIDDER_CODE = 'pxyz'; -const URL = 'https://ads.playground.xyz/host-config/prebid?v=2'; -const DEFAULT_CURRENCY = 'USD'; - -export const spec = { - code: BIDDER_CODE, - - // This adapter was previously named playgroundxyz - this alias ensures - // backwards compatibility for publishers - aliases: ['playgroundxyz'], - - supportedMediaTypes: [BANNER], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {object} bid The bid to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return !!(bid.params.placementId); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server. - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (bidRequests, bidderRequest) { - const referer = bidderRequest.refererInfo.referer; - const parts = referer.split('/'); - - let protocol, hostname; - if (parts.length >= 3) { - protocol = parts[0]; - hostname = parts[2]; - } - - const payload = { - id: bidRequests[0].auctionId, - site: { - domain: protocol + '//' + hostname, - name: hostname, - page: referer, - }, - device: { - ua: navigator.userAgent, - language: navigator.language, - devicetype: isMobile() ? 1 : isConnectedTV() ? 3 : 2, - }, - imp: bidRequests.map(mapImpression), - Regs: { ext: {} } - }; - - // GDPR - if (bidderRequest && bidderRequest.gdprConsent) { - const gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; - const consentString = bidderRequest.gdprConsent.consentString; - utils.logInfo(`PXYZ: GDPR applies ${gdpr}`); - utils.logInfo(`PXYZ: GDPR consent string ${consentString}`); - payload.Regs.ext.gdpr = gdpr; - payload.User = { ext: { consent: consentString } }; - } - - // CCPA - if (bidderRequest && bidderRequest.uspConsent) { - utils.logInfo(`PXYZ: USP Consent ${bidderRequest.uspConsent}`); - payload.Regs.ext['us_privacy'] = bidderRequest.uspConsent; - } - - return { - method: 'POST', - url: URL, - data: JSON.stringify(payload), - bidderRequest - }; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function (serverResponse, { bidderRequest }) { - serverResponse = serverResponse.body; - const bids = []; - - if (!serverResponse || serverResponse.error) { - let errorMessage = `in response for ${bidderRequest.bidderCode} adapter`; - if (serverResponse && serverResponse.error) { - errorMessage += `: ${serverResponse.error}`; - utils.logError(errorMessage); - } - return bids; - } - - if (!utils.isArray(serverResponse.seatbid)) { - let errorMessage = `in response for ${bidderRequest.bidderCode} adapter `; - utils.logError(errorMessage += 'Malformed seatbid response'); - return bids; - } - - if (!serverResponse.seatbid) { - return bids; - } - - const currency = serverResponse.cur || DEFAULT_CURRENCY; - serverResponse.seatbid.forEach(sBid => { - if (sBid.hasOwnProperty('bid')) { - sBid.bid.forEach(iBid => { - if (iBid.price !== 0) { - const bid = newBid(iBid, currency); - bids.push(bid); - } - }); - } - }); - return bids; - }, - - getUserSyncs: function (syncOptions) { - return [{ - type: 'image', - url: '//ib.adnxs.com/getuidnb?https://ads.playground.xyz/usersync?partner=appnexus&uid=$UID' - }]; - } -} - -function newBid(bid, currency) { - return { - requestId: bid.impid, - mediaType: BANNER, - cpm: bid.price, - creativeId: bid.adid, - ad: bid.adm, - width: bid.w, - height: bid.h, - ttl: 300, - netRevenue: true, - currency: currency, - }; -} - -function mapImpression(bid) { - return { - id: bid.bidId, - banner: mapBanner(bid), - ext: { - appnexus: { - placement_id: parseInt(bid.params.placementId, 10) - }, - pxyz: { - adapter: { - vendor: 'prebid', - prebid: '$prebid.version$' - } - } - } - }; -} - -function mapBanner(bid) { - return { - w: parseInt(bid.sizes[0][0], 10), - h: parseInt(bid.sizes[0][1], 10), - format: mapSizes(bid.sizes) - }; -} - -function mapSizes(bidSizes) { - const format = []; - bidSizes.forEach(size => { - format.push({ - w: parseInt(size[0], 10), - h: parseInt(size[1], 10) - }); - }); - return format; -} - -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); -} - -registerBidder(spec); diff --git a/modules/pxyzBidAdapter.md b/modules/pxyzBidAdapter.md deleted file mode 100644 index eced908eed8..00000000000 --- a/modules/pxyzBidAdapter.md +++ /dev/null @@ -1,37 +0,0 @@ -# Overview - -``` -Module Name: Playground XYZ Bid Adapter -Module Type: Bidder Adapter -Maintainer: tech+prebid@playgroundxyz.com -``` - -# Description - -Connects to the Playground XYZ marketplace for demand. - -This bid adapter supports the Banner media type only. - -# Test Parameters - -```js -var adUnits = [ - // Banner adUnit - { - code: 'div-gpt-ad-1460505748561-0', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - sizes: [[300, 250]], - bids: [{ - bidder: 'pxyz', - params: { - placementId: '13473562' - } - }] - } -]; -``` - diff --git a/modules/quantcastBidAdapter.js b/modules/quantcastBidAdapter.js deleted file mode 100644 index e9541edb534..00000000000 --- a/modules/quantcastBidAdapter.js +++ /dev/null @@ -1,306 +0,0 @@ -import * as utils 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 find from 'core-js-pure/features/array/find.js'; - -const BIDDER_CODE = 'quantcast'; -const DEFAULT_BID_FLOOR = 0.0000000001; - -const QUANTCAST_VENDOR_ID = '11'; -// Check other required purposes on server -const PURPOSE_DATA_COLLECT = '1'; - -export const QUANTCAST_DOMAIN = 'qcx.quantserve.com'; -export const QUANTCAST_TEST_DOMAIN = 's2s-canary.quantserve.com'; -export const QUANTCAST_NET_REVENUE = true; -export const QUANTCAST_TEST_PUBLISHER = 'test-publisher'; -export const QUANTCAST_TTL = 4; -export const QUANTCAST_PROTOCOL = 'https'; -export const QUANTCAST_PORT = '8443'; -export const QUANTCAST_FPA = '__qca'; - -export const storage = getStorageManager(QUANTCAST_VENDOR_ID, BIDDER_CODE); - -function makeVideoImp(bid) { - const video = {}; - if (bid.params.video) { - video['mimes'] = bid.params.video.mimes; - video['minduration'] = bid.params.video.minduration; - video['maxduration'] = bid.params.video.maxduration; - video['protocols'] = bid.params.video.protocols; - video['startdelay'] = bid.params.video.startdelay; - video['linearity'] = bid.params.video.linearity; - video['battr'] = bid.params.video.battr; - video['maxbitrate'] = bid.params.video.maxbitrate; - video['playbackmethod'] = bid.params.video.playbackmethod; - video['delivery'] = bid.params.video.delivery; - video['placement'] = bid.params.video.placement; - video['api'] = bid.params.video.api; - } - if (bid.mediaTypes.video.mimes) { - video['mimes'] = bid.mediaTypes.video.mimes; - } - if (utils.isArray(bid.mediaTypes.video.playerSize[0])) { - video['w'] = bid.mediaTypes.video.playerSize[0][0]; - video['h'] = bid.mediaTypes.video.playerSize[0][1]; - } else { - video['w'] = bid.mediaTypes.video.playerSize[0]; - video['h'] = bid.mediaTypes.video.playerSize[1]; - } - return { - video: video, - placementCode: bid.placementCode, - bidFloor: bid.params.bidFloor || DEFAULT_BID_FLOOR - }; -} - -function makeBannerImp(bid) { - const sizes = bid.sizes || bid.mediaTypes.banner.sizes; - - return { - banner: { - battr: bid.params.battr, - sizes: sizes.map(size => { - return { - width: size[0], - height: size[1] - }; - }) - }, - placementCode: bid.placementCode, - bidFloor: bid.params.bidFloor || DEFAULT_BID_FLOOR - }; -} - -function getDomain(url) { - if (!url) { - return url; - } - return url.replace('http://', '').replace('https://', '').replace('www.', '').split(/[/?#]/)[0]; -} - -function checkTCFv1(vendorData) { - let vendorConsent = vendorData.vendorConsents && vendorData.vendorConsents[QUANTCAST_VENDOR_ID]; - let purposeConsent = vendorData.purposeConsents && vendorData.purposeConsents[PURPOSE_DATA_COLLECT]; - - return !!(vendorConsent && purposeConsent); -} - -function checkTCFv2(tcData) { - let restrictions = tcData.publisher ? tcData.publisher.restrictions : {}; - let qcRestriction = restrictions && restrictions[PURPOSE_DATA_COLLECT] - ? restrictions[PURPOSE_DATA_COLLECT][QUANTCAST_VENDOR_ID] - : null; - - if (qcRestriction === 0 || qcRestriction === 2) { - // Not allowed by publisher, or requires legitimate interest - return false; - } - - let vendorConsent = tcData.vendor && tcData.vendor.consents && tcData.vendor.consents[QUANTCAST_VENDOR_ID]; - let purposeConsent = tcData.purpose && tcData.purpose.consents && tcData.purpose.consents[PURPOSE_DATA_COLLECT]; - - return !!(vendorConsent && purposeConsent); -} - -function getQuantcastFPA() { - let fpa = storage.getCookie(QUANTCAST_FPA) - return fpa || '' -} - -let hasUserSynced = false; - -/** - * The documentation for Prebid.js Adapter 1.0 can be found at link below, - * http://prebid.org/dev-docs/bidder-adapter-1.html - */ -export const spec = { - code: BIDDER_CODE, - GVLID: QUANTCAST_VENDOR_ID, - supportedMediaTypes: ['banner', 'video'], - - /** - * Verify the `AdUnits.bids` response with `true` for valid request and `false` - * for invalid request. - * - * @param {object} bid - * @return boolean `true` is this is a valid bid, and `false` otherwise - */ - isBidRequestValid(bid) { - return !!bid.params.publisherId; - }, - - /** - * Make a server request when the page asks Prebid.js for bids from a list of - * `BidRequests`. - * - * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be send to Quantcast server - * @param bidderRequest - * @return ServerRequest information describing the request to the server. - */ - buildRequests(bidRequests, bidderRequest) { - const bids = bidRequests || []; - const gdprConsent = utils.deepAccess(bidderRequest, 'gdprConsent') || {}; - const uspConsent = utils.deepAccess(bidderRequest, 'uspConsent'); - const referrer = utils.deepAccess(bidderRequest, 'refererInfo.referer'); - const page = utils.deepAccess(bidderRequest, 'refererInfo.canonicalUrl') || config.getConfig('pageUrl') || utils.deepAccess(window, 'location.href'); - const domain = getDomain(page); - - // Check for GDPR consent for purpose 1, and drop request if consent has not been given - // Remaining consent checks are performed server-side. - if (gdprConsent.gdprApplies) { - if (gdprConsent.vendorData) { - if (gdprConsent.apiVersion === 1 && !checkTCFv1(gdprConsent.vendorData)) { - utils.logInfo(`${BIDDER_CODE}: No purpose 1 consent for TCF v1`); - return; - } - if (gdprConsent.apiVersion === 2 && !checkTCFv2(gdprConsent.vendorData)) { - utils.logInfo(`${BIDDER_CODE}: No purpose 1 consent for TCF v2`); - return; - } - } - } - - let bidRequestsList = []; - - bids.forEach(bid => { - let imp; - if (bid.mediaTypes) { - if (bid.mediaTypes.video && bid.mediaTypes.video.context === 'instream') { - imp = makeVideoImp(bid); - } else if (bid.mediaTypes.banner) { - imp = makeBannerImp(bid); - } else { - // Unsupported mediaType - utils.logInfo(`${BIDDER_CODE}: No supported mediaTypes found in ${JSON.stringify(bid.mediaTypes)}`); - return; - } - } else { - // Parse as banner by default - imp = makeBannerImp(bid); - } - - // Request Data Format can be found at https://wiki.corp.qc/display/adinf/QCX - const requestData = { - publisherId: bid.params.publisherId, - requestId: bid.bidId, - imp: [imp], - site: { - page, - referrer, - domain - }, - bidId: bid.bidId, - gdprSignal: gdprConsent.gdprApplies ? 1 : 0, - gdprConsent: gdprConsent.consentString, - uspSignal: uspConsent ? 1 : 0, - uspConsent, - coppa: config.getConfig('coppa') === true ? 1 : 0, - prebidJsVersion: '$prebid.version$', - fpa: getQuantcastFPA() - }; - - const data = JSON.stringify(requestData); - const qcDomain = bid.params.publisherId === QUANTCAST_TEST_PUBLISHER - ? QUANTCAST_TEST_DOMAIN - : QUANTCAST_DOMAIN; - const url = `${QUANTCAST_PROTOCOL}://${qcDomain}:${QUANTCAST_PORT}/qchb`; - - bidRequestsList.push({ - data, - method: 'POST', - url - }); - }); - - return bidRequestsList; - }, - - /** - * Function get called when the browser has received the response from Quantcast server. - * The function parse the response and create a `bidResponse` object containing one/more bids. - * Returns an empty array if no valid bids - * - * Response Data Format can be found at https://wiki.corp.qc/display/adinf/QCX - * - * @param {*} serverResponse A successful response from Quantcast server. - * @return {Bid[]} An array of bids which were nested inside the server. - * - */ - interpretResponse(serverResponse) { - if (serverResponse === undefined) { - utils.logError('Server Response is undefined'); - return []; - } - - const response = serverResponse['body']; - - if (response === undefined || !response.hasOwnProperty('bids')) { - utils.logError('Sub-optimal JSON received from Quantcast server'); - return []; - } - - if (utils.isEmpty(response.bids)) { - // Shortcut response handling if no bids are present - return []; - } - - const bidResponsesList = response.bids.map(bid => { - const { ad, cpm, width, height, creativeId, currency, videoUrl, dealId } = bid; - - const result = { - requestId: response.requestId, - cpm, - width, - height, - ad, - ttl: QUANTCAST_TTL, - creativeId, - netRevenue: QUANTCAST_NET_REVENUE, - currency - }; - - if (videoUrl !== undefined && videoUrl) { - result['vastUrl'] = videoUrl; - result['mediaType'] = 'video'; - } - - if (dealId !== undefined && dealId) { - result['dealId'] = dealId; - } - - return result; - }); - - return bidResponsesList; - }, - onTimeout(timeoutData) { - const url = `${QUANTCAST_PROTOCOL}://${QUANTCAST_DOMAIN}:${QUANTCAST_PORT}/qchb_notify?type=timeout`; - ajax(url, null, null); - }, - getUserSyncs(syncOptions, serverResponses) { - const syncs = [] - if (!hasUserSynced && syncOptions.pixelEnabled) { - const responseWithUrl = find(serverResponses, serverResponse => - utils.deepAccess(serverResponse.body, 'userSync.url') - ); - - if (responseWithUrl) { - const url = utils.deepAccess(responseWithUrl.body, 'userSync.url') - syncs.push({ - type: 'image', - url: url - }); - } - hasUserSynced = true; - } - return syncs; - }, - resetUserSync() { - hasUserSynced = false; - } -}; - -registerBidder(spec); diff --git a/modules/quantcastBidAdapter.md b/modules/quantcastBidAdapter.md deleted file mode 100644 index edbbc538b65..00000000000 --- a/modules/quantcastBidAdapter.md +++ /dev/null @@ -1,74 +0,0 @@ -# Overview - -``` -Module Name: Quantcast Bidder Adapter -Module Type: Bidder Adapter -Maintainer: inventoryteam@quantcast.com -``` - -# Description - -Module that connects to Quantcast demand sources to fetch bids. - -# Test Parameters - -## Sample Banner Ad Unit -```js -const adUnits = [{ - code: 'banner', - sizes: [ - [300, 250] - ], - bids: [ - { - bidder: 'quantcast', - params: { - publisherId: 'test-publisher', // REQUIRED - Publisher ID provided by Quantcast - battr: [1, 2] // OPTIONAL - Array of blocked creative attributes as per OpenRTB Spec List 5.3 - } - } - ], - userSync: { - url: 'https://quantcast.com/pixelUrl' - } -}]; -``` - -## Sample Video Ad Unit -```js -var adUnits = [{ - code: 'video', - mediaTypes: { - video: { - context: 'instream', // required - playerSize: [600, 300] // required - } - }, - bids: [ - { - bidder: 'quantcast', - params: { - publisherId: 'test-publisher', // REQUIRED - Publisher ID provided by Quantcast - // Video object as specified in OpenRTB 2.5 - video: { - mimes: ['video/mp4'], // required - minduration: 3, // optional - maxduration: 5, // optional - protocols: [3], // optional - startdelay: 1, // optional - linearity: 1, // optinal - battr: [1, 2], // optional - maxbitrate: 10, // optional - playbackmethod: [1], // optional - delivery: [1], // optional - placement: 1, // optional - api: [2, 3] // optional - } - } - } - ], - userSync: { - url: 'https://quantcast.com/pixelUrl' - } -}]; -``` diff --git a/modules/quantcastIdSystem.js b/modules/quantcastIdSystem.js deleted file mode 100644 index e86c130dc5b..00000000000 --- a/modules/quantcastIdSystem.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * This module adds QuantcastID to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/quantcastIdSystem - * @requires module:modules/userId - */ - -import {submodule} from '../src/hook.js' -import { getStorageManager } from '../src/storageManager.js'; - -const QUANTCAST_FPA = '__qca'; - -export const storage = getStorageManager(); - -/** @type {Submodule} */ -export const quantcastIdSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: 'quantcastId', - - /** - * decode the stored id value for passing to bid requests - * @function - * @returns {{quantcastId: string} | undefined} - */ - decode(value) { - return value; - }, - - /** - * read Quantcast first party cookie and pass it along in quantcastId - * @function - * @returns {{id: {quantcastId: string} | undefined}}} - */ - getId() { - // Consent signals are currently checked on the server side. - let fpa = storage.getCookie(QUANTCAST_FPA); - return { id: fpa ? { quantcastId: fpa } : undefined } - } -}; - -submodule('userId', quantcastIdSubmodule); diff --git a/modules/qwarryBidAdapter.js b/modules/qwarryBidAdapter.js deleted file mode 100644 index 7ed5e5c984c..00000000000 --- a/modules/qwarryBidAdapter.js +++ /dev/null @@ -1,98 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { deepClone } from '../src/utils.js'; -import { ajax } from '../src/ajax.js'; -import { VIDEO } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'qwarry'; -export const ENDPOINT = 'https://bidder.qwarry.co/bid/adtag?prebid=true' - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: ['banner', 'video'], - - isBidRequestValid: function (bid) { - return !!(bid.params && bid.params.zoneToken); - }, - - buildRequests: function (validBidRequests, bidderRequest) { - let bids = []; - validBidRequests.forEach(bidRequest => { - bids.push({ - bidId: bidRequest.bidId, - zoneToken: bidRequest.params.zoneToken, - pos: bidRequest.params.pos, - sizes: prepareSizes(bidRequest.sizes) - }) - }) - - let payload = { - requestId: bidderRequest.bidderRequestId, - bids, - referer: bidderRequest.refererInfo.referer - } - - if (bidderRequest && bidderRequest.gdprConsent) { - payload.gdprConsent = { - consentRequired: (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') ? bidderRequest.gdprConsent.gdprApplies : false, - consentString: bidderRequest.gdprConsent.consentString - } - } - - const options = { - contentType: 'application/json', - customHeaders: { - 'Rtb-Direct': true - } - } - - return { - method: 'POST', - url: ENDPOINT, - data: payload, - options - }; - }, - - interpretResponse: function (serverResponse, request) { - const serverBody = serverResponse.body; - if (!serverBody || typeof serverBody !== 'object') { - return []; - } - - const { prebidResponse } = serverBody; - if (!prebidResponse || typeof prebidResponse !== 'object') { - return []; - } - - let bids = []; - prebidResponse.forEach(bidResponse => { - let bid = deepClone(bidResponse); - bid.cpm = parseFloat(bidResponse.cpm); - - // banner or video - if (VIDEO === bid.format) { - bid.vastXml = bid.ad; - } - - bids.push(bid); - }) - - return bids; - }, - - onBidWon: function (bid) { - if (bid.winUrl) { - const cpm = bid.cpm; - const winUrl = bid.winUrl.replace(/\$\{AUCTION_PRICE\}/, cpm); - ajax(winUrl, null); - return true; - } - return false; - } -} - -function prepareSizes(sizes) { - return sizes && sizes.map(size => ({ width: size[0], height: size[1] })); -} - -registerBidder(spec); diff --git a/modules/qwarryBidAdapter.md b/modules/qwarryBidAdapter.md deleted file mode 100644 index 056ccb51293..00000000000 --- a/modules/qwarryBidAdapter.md +++ /dev/null @@ -1,28 +0,0 @@ -# Overview - -``` -Module Name: Qwarry Bidder Adapter -Module Type: Bidder Adapter -Maintainer: akascheev@asteriosoft.com -``` - -# Description - -Connects to Qwarry Bidder for bids. -Qwarry bid adapter supports Banner and Video ads. - -# Test Parameters -``` -const adUnits = [ - { - bids: [ - { - bidder: 'qwarry', - params: { - zoneToken: '?????????????????????', // zoneToken provided by Qwarry - } - } - ] - } -]; -``` diff --git a/modules/radsBidAdapter.js b/modules/radsBidAdapter.js deleted file mode 100644 index 8f3cbe02f23..00000000000 --- a/modules/radsBidAdapter.js +++ /dev/null @@ -1,201 +0,0 @@ -import * as utils from '../src/utils.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'rads'; -const ENDPOINT_URL = 'https://rads.recognified.net/md.request.php'; -const ENDPOINT_URL_DEV = 'https://dcradn1.online-solution.biz/md.request.php'; -const DEFAULT_VAST_FORMAT = 'vast2'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['rads'], - supportedMediaTypes: [BANNER, VIDEO], - isBidRequestValid: function(bid) { - return !!(bid.params.placement); - }, - buildRequests: function(validBidRequests, bidderRequest) { - return validBidRequests.map(bidRequest => { - const params = bidRequest.params; - const videoData = utils.deepAccess(bidRequest, 'mediaTypes.video') || {}; - const sizes = utils.parseSizesInput(videoData.playerSize || bidRequest.sizes)[0]; - const [width, height] = sizes.split('x'); - const placementId = params.placement; - - const rnd = Math.floor(Math.random() * 99999999999); - const referrer = encodeURIComponent(bidderRequest.refererInfo.referer); - const bidId = bidRequest.bidId; - const isDev = params.devMode || false; - - let endpoint = isDev ? ENDPOINT_URL_DEV : ENDPOINT_URL; - - let payload = {}; - if (isVideoRequest(bidRequest)) { - let vastFormat = params.vastFormat || DEFAULT_VAST_FORMAT; - payload = { - rt: vastFormat, - _f: 'prebid_js', - _ps: placementId, - srw: width, - srh: height, - idt: 100, - rnd: rnd, - p: referrer, - bid_id: bidId, - }; - } else { - payload = { - rt: 'bid-response', - _f: 'prebid_js', - _ps: placementId, - srw: width, - srh: height, - idt: 100, - rnd: rnd, - p: referrer, - bid_id: bidId, - }; - } - prepareExtraParams(params, payload, bidderRequest); - - return { - method: 'GET', - url: endpoint, - data: objectToQueryString(payload), - } - }); - }, - interpretResponse: function(serverResponse, bidRequest) { - const bidResponses = []; - const response = serverResponse.body; - const crid = response.crid || 0; - const cpm = response.cpm / 1000000 || 0; - if (cpm !== 0 && crid !== 0) { - const dealId = response.dealid || ''; - const currency = response.currency || 'EUR'; - const netRevenue = (response.netRevenue === undefined) ? true : response.netRevenue; - const bidResponse = { - requestId: response.bid_id, - cpm: cpm, - width: response.width, - height: response.height, - creativeId: crid, - dealId: dealId, - currency: currency, - netRevenue: netRevenue, - ttl: config.getConfig('_bidderTimeout') - }; - - if (response.vastXml) { - bidResponse.vastXml = response.vastXml; - bidResponse.mediaType = 'video'; - } else { - bidResponse.ad = response.adTag; - } - - bidResponses.push(bidResponse); - } - return bidResponses; - }, - getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) { - if (!serverResponses || serverResponses.length === 0) { - return []; - } - - const syncs = [] - - let gdprParams = ''; - if (gdprConsent) { - if ('gdprApplies' in gdprConsent && typeof gdprConsent.gdprApplies === 'boolean') { - gdprParams = `gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - gdprParams = `gdpr_consent=${gdprConsent.consentString}`; - } - } - - if (syncOptions.iframeEnabled) { - serverResponses[0].body.userSync.iframeUrl.forEach((url) => syncs.push({ - type: 'iframe', - url: appendToUrl(url, gdprParams) - })); - } - if (syncOptions.pixelEnabled && serverResponses.length > 0) { - serverResponses[0].body.userSync.imageUrl.forEach((url) => syncs.push({ - type: 'image', - url: appendToUrl(url, gdprParams) - })); - } - return syncs; - } -} - -function appendToUrl(url, what) { - if (!what) { - return url; - } - return url + (url.indexOf('?') !== -1 ? '&' : '?') + what; -} - -function objectToQueryString(obj, prefix) { - let str = []; - let p; - for (p in obj) { - if (obj.hasOwnProperty(p)) { - let k = prefix ? prefix + '[' + p + ']' : p; - let v = obj[p]; - str.push((v !== null && typeof v === 'object') - ? objectToQueryString(v, k) - : encodeURIComponent(k) + '=' + encodeURIComponent(v)); - } - } - return str.join('&'); -} - -/** - * Check if it's a video bid request - * - * @param {BidRequest} bid - Bid request generated from ad slots - * @returns {boolean} True if it's a video bid - */ -function isVideoRequest(bid) { - return bid.mediaType === 'video' || !!utils.deepAccess(bid, 'mediaTypes.video'); -} - -function prepareExtraParams(params, payload, bidderRequest) { - if (params.pfilter !== undefined) { - payload.pfilter = params.pfilter; - } - - if (bidderRequest && bidderRequest.gdprConsent) { - if (payload.pfilter !== undefined) { - payload.pfilter.gdpr_consent = bidderRequest.gdprConsent.consentString; - payload.pfilter.gdpr = bidderRequest.gdprConsent.gdprApplies; - } else { - payload.pfilter = { - 'gdpr_consent': bidderRequest.gdprConsent.consentString, - 'gdpr': bidderRequest.gdprConsent.gdprApplies - }; - } - } - - if (params.bcat !== undefined) { - payload.bcat = params.bcat; - } - if (params.dvt !== undefined) { - payload.dvt = params.dvt; - } - - if (params.latitude !== undefined) { - payload.latitude = params.latitude; - } - - if (params.longitude !== undefined) { - payload.longitude = params.longitude; - } - if (params.ip !== undefined) { - payload.i = params.ip; - } -} - -registerBidder(spec); diff --git a/modules/radsBidAdapter.md b/modules/radsBidAdapter.md deleted file mode 100644 index 6e970093154..00000000000 --- a/modules/radsBidAdapter.md +++ /dev/null @@ -1,37 +0,0 @@ -# Overview - -``` -Module Name: RADS Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid@recognified.net -``` - -# Description - -RADS Bidder Adapter for Prebid.js 1.x - -# Test Parameters -``` - var adUnits = [ - { - code: "test-div", - mediaTypes: { - banner: { - sizes: [[320, 50]] - } - }, - bids: [ - { - bidder: "rads", - params: { - placement: 3, // placement ID - devMode: true // if true: library uses dev server for tests - } - } - ] - } - ]; -``` - -Required param field is only `placement`. - diff --git a/modules/rakutenBidAdapter/index.js b/modules/rakutenBidAdapter/index.js deleted file mode 100644 index e567509b3c1..00000000000 --- a/modules/rakutenBidAdapter/index.js +++ /dev/null @@ -1,80 +0,0 @@ -import { registerBidder } from '../../src/adapters/bidderFactory.js'; -import { BANNER } from '../../src/mediaTypes.js'; -import { config } from '../../src/config.js'; -const BIDDER_CODE = 'rakuten'; -const ENDPOINT = 'https://s-bid.rmp.rakuten.com/h'; -export const spec = { - code: BIDDER_CODE, - isBidRequestValid: bid => !!bid.params.adSpotId, - buildRequests: (validBidRequests, bidderRequest) => { - const bidRequests = []; - validBidRequests.forEach(bid => { - var _a, _b; - const params = bid.params; - bidRequests.push({ - method: 'GET', - url: config.getConfig('rakuten.endpoint') || ENDPOINT, - data: { - bi: bid.bidId, - t: params.adSpotId, - s: document.location.protocol, - ua: navigator.userAgent, - l: navigator.browserLanguage || - navigator.language, - d: document.domain, - tp: bidderRequest.refererInfo.stack[0] || window.location.href, - pp: bidderRequest.refererInfo.referer, - gdpr: ((_a = bidderRequest.gdprConsent) === null || _a === void 0 ? void 0 : _a.gdprApplies) ? 1 : 0, - ...((_b = bidderRequest.gdprConsent) === null || _b === void 0 ? void 0 : _b.consentString) && { - cd: bidderRequest.gdprConsent.consentString - }, - ...bidderRequest.uspConsent && { - ccpa: bidderRequest.uspConsent - } - } - }); - }); - return bidRequests; - }, - interpretResponse: (response, request) => { - const sb = response.body; - const bidResponses = []; - if (sb.cpm && sb.ad) { - bidResponses.push({ - requestId: sb.bid_id, - cpm: sb.cpm, - width: sb.width || 0, - height: sb.height || 0, - creativeId: sb.creative_id || 0, - dealId: sb.deal_id || '', - currency: sb.currency || 'USD', - netRevenue: (typeof sb.net_revenue === 'undefined') ? true : !!sb.net_revenue, - mediaType: BANNER, - ttl: sb.ttl, - ad: sb.ad - }); - } - return bidResponses; - }, - getUserSyncs: function (syncOptions, serverResponses) { - const syncs = []; - if (syncOptions.pixelEnabled && serverResponses[0].body !== undefined) { - const bidResponseObj = serverResponses[0].body; - if (!bidResponseObj) { - return []; - } - if (bidResponseObj.sync_urls && bidResponseObj.sync_urls.length > 0) { - bidResponseObj.sync_urls.forEach(syncUrl => { - if (syncUrl && syncUrl !== 'null' && syncUrl.length > 0) { - syncs.push({ - type: 'image', - url: syncUrl - }); - } - }); - } - } - return syncs; - } -}; -registerBidder(spec); diff --git a/modules/rakutenBidAdapter/index.md b/modules/rakutenBidAdapter/index.md deleted file mode 100644 index cc6aa68151d..00000000000 --- a/modules/rakutenBidAdapter/index.md +++ /dev/null @@ -1,33 +0,0 @@ -# Overview - -``` -Module Name: Rakuten Bidder Adapter -Module Type: Bidder Adapter -Maintainer: @snapwich -``` - -# Description - -Bid adapter for Rakuten RSSP - -Rakuten bid adapter supports Banner currently. - -# Test Parameters - -``` - var adUnits = [ - { - code: 'test-ad-div', - sizes: [[300, 250]], - mediaTypes: {banner: {}}, - bids: [ - { - bidder: 'rakuten', - params: { - adSpotId: 42 - } - } - ] - } - ]; -``` diff --git a/modules/rdnBidAdapter.md b/modules/rdnBidAdapter.md deleted file mode 100644 index 9082c95c520..00000000000 --- a/modules/rdnBidAdapter.md +++ /dev/null @@ -1,33 +0,0 @@ -# Overview - -``` -Module Name: RDN Bidder Adapter -Module Type: Bidder Adapter -Maintainer: engineer@lob-inc.com -``` - -# Description - -Connect to RDN for bids. - -RDN bid adapter supports Banner currently. - -# Test Parameters - -``` - var adUnits = [ - { - code: 'test-ad-div', - sizes: [[300, 250]], - mediaTypes: {banner: {}}, - bids: [ - { - bidder: 'rdn', - params: { - adSpotId: '10000' - } - } - ] - } - ]; -``` diff --git a/modules/readpeakBidAdapter.js b/modules/readpeakBidAdapter.js deleted file mode 100644 index 31e430d79f9..00000000000 --- a/modules/readpeakBidAdapter.js +++ /dev/null @@ -1,338 +0,0 @@ -import { logError, replaceAuctionPrice, parseUrl } from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { config } from '../src/config.js'; -import { NATIVE } from '../src/mediaTypes.js'; - -export const ENDPOINT = 'https://app.readpeak.com/header/prebid'; - -const NATIVE_DEFAULTS = { - TITLE_LEN: 70, - DESCR_LEN: 120, - SPONSORED_BY_LEN: 50, - IMG_MIN: 150, - ICON_MIN: 50, - CTA_LEN: 50 -}; - -const BIDDER_CODE = 'readpeak'; - -export const spec = { - code: BIDDER_CODE, - - supportedMediaTypes: [NATIVE], - - isBidRequestValid: bid => - !!(bid && bid.params && bid.params.publisherId && bid.nativeParams), - - buildRequests: (bidRequests, bidderRequest) => { - const currencyObj = config.getConfig('currency'); - const currency = (currencyObj && currencyObj.adServerCurrency) || 'USD'; - - const request = { - id: bidRequests[0].bidderRequestId, - imp: bidRequests - .map(slot => impression(slot)) - .filter(imp => imp.native != null), - site: site(bidRequests, bidderRequest), - app: app(bidRequests), - device: device(), - cur: [currency], - source: { - fd: 1, - tid: bidRequests[0].transactionId, - ext: { - prebid: '$prebid.version$' - } - } - }; - - if (bidderRequest.gdprConsent) { - request.user = { - ext: { - consent: bidderRequest.gdprConsent.consentString || '' - }, - }; - request.regs = { - ext: { - gdpr: bidderRequest.gdprConsent.gdprApplies !== undefined ? bidderRequest.gdprConsent.gdprApplies : true - } - }; - } - - return { - method: 'POST', - url: ENDPOINT, - data: JSON.stringify(request) - }; - }, - - interpretResponse: (response, request) => - bidResponseAvailable(request, response) -}; - -function bidResponseAvailable(bidRequest, bidResponse) { - const idToImpMap = {}; - const idToBidMap = {}; - if (!bidResponse['body']) { - return []; - } - bidResponse = bidResponse.body; - parse(bidRequest.data).imp.forEach(imp => { - idToImpMap[imp.id] = imp; - }); - if (bidResponse) { - bidResponse.seatbid.forEach(seatBid => - seatBid.bid.forEach(bid => { - idToBidMap[bid.impid] = bid; - }) - ); - } - const bids = []; - Object.keys(idToImpMap).forEach(id => { - if (idToBidMap[id]) { - const bid = { - requestId: id, - cpm: idToBidMap[id].price, - creativeId: idToBidMap[id].crid, - ttl: 300, - netRevenue: true, - mediaType: NATIVE, - currency: bidResponse.cur, - native: nativeResponse(idToImpMap[id], idToBidMap[id]) - }; - if (idToBidMap[id].adomain) { - bid.meta = { - advertiserDomains: idToBidMap[id].adomain - } - } - bids.push(bid); - } - }); - return bids; -} - -function impression(slot) { - let bidFloorFromModule - if (typeof slot.getFloor === 'function') { - const floorInfo = slot.getFloor({ - currency: 'USD', - mediaType: 'native', - size: '\*' - }); - bidFloorFromModule = floorInfo.currency === 'USD' ? floorInfo.floor : undefined; - } - return { - id: slot.bidId, - native: nativeImpression(slot), - bidfloor: bidFloorFromModule || slot.params.bidfloor || 0, - bidfloorcur: (bidFloorFromModule && 'USD') || slot.params.bidfloorcur || 'USD', - tagId: slot.params.tagId || '0' - }; -} - -function nativeImpression(slot) { - if (slot.nativeParams) { - const assets = []; - addAsset( - assets, - titleAsset(1, slot.nativeParams.title, NATIVE_DEFAULTS.TITLE_LEN) - ); - addAsset( - assets, - imageAsset( - 2, - slot.nativeParams.image, - 3, - slot.nativeParams.wmin || NATIVE_DEFAULTS.IMG_MIN, - slot.nativeParams.hmin || NATIVE_DEFAULTS.IMG_MIN - ) - ); - addAsset( - assets, - dataAsset( - 3, - slot.nativeParams.sponsoredBy, - 1, - NATIVE_DEFAULTS.SPONSORED_BY_LEN - ) - ); - addAsset( - assets, - dataAsset(4, slot.nativeParams.body, 2, NATIVE_DEFAULTS.DESCR_LEN) - ); - addAsset( - assets, - dataAsset(5, slot.nativeParams.cta, 12, NATIVE_DEFAULTS.CTA_LEN) - ); - return { - request: JSON.stringify({ assets }), - ver: '1.1' - }; - } - return null; -} - -function addAsset(assets, asset) { - if (asset) { - assets.push(asset); - } -} - -function titleAsset(id, params, defaultLen) { - if (params) { - return { - id, - required: params.required ? 1 : 0, - title: { - len: params.len || defaultLen - } - }; - } - return null; -} - -function imageAsset(id, params, type, defaultMinWidth, defaultMinHeight) { - return params - ? { - id, - required: params.required ? 1 : 0, - img: { - type, - wmin: params.wmin || defaultMinWidth, - hmin: params.hmin || defaultMinHeight - } - } - : null; -} - -function dataAsset(id, params, type, defaultLen) { - return params - ? { - id, - required: params.required ? 1 : 0, - data: { - type, - len: params.len || defaultLen - } - } - : null; -} - -function site(bidRequests, bidderRequest) { - const url = - config.getConfig('pageUrl') || - (bidderRequest && - bidderRequest.refererInfo && - bidderRequest.refererInfo.referer); - - const pubId = - bidRequests && bidRequests.length > 0 - ? bidRequests[0].params.publisherId - : '0'; - const siteId = - bidRequests && bidRequests.length > 0 ? bidRequests[0].params.siteId : '0'; - const appParams = bidRequests[0].params.app; - if (!appParams) { - return { - publisher: { - id: pubId.toString(), - domain: config.getConfig('publisherDomain') - }, - id: siteId ? siteId.toString() : pubId.toString(), - page: url, - domain: - (url && parseUrl(url).hostname) || config.getConfig('publisherDomain') - }; - } - return undefined; -} - -function app(bidderRequest) { - const pubId = - bidderRequest && bidderRequest.length > 0 - ? bidderRequest[0].params.publisherId - : '0'; - const appParams = bidderRequest[0].params.app; - if (appParams) { - return { - publisher: { - id: pubId.toString() - }, - bundle: appParams.bundle, - storeurl: appParams.storeUrl, - domain: appParams.domain - }; - } - return undefined; -} - -function isMobile() { - return /(ios|ipod|ipad|iphone|android)/i.test(global.navigator.userAgent); -} - -function isConnectedTV() { - return /(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i.test( - global.navigator.userAgent - ); -} - -function device() { - return { - ua: navigator.userAgent, - language: - navigator.language || - navigator.browserLanguage || - navigator.userLanguage || - navigator.systemLanguage, - devicetype: isMobile() ? 1 : isConnectedTV() ? 3 : 2 - }; -} - -function parse(rawResponse) { - try { - if (rawResponse) { - if (typeof rawResponse === 'object') { - return rawResponse; - } else { - return JSON.parse(rawResponse); - } - } - } catch (ex) { - logError('readpeakBidAdapter.safeParse', 'ERROR', ex); - } - return null; -} - -function nativeResponse(imp, bid) { - if (imp && imp['native']) { - const nativeAd = parse(bid.adm); - const keys = {}; - if (nativeAd && nativeAd.assets) { - nativeAd.assets.forEach(asset => { - keys.title = asset.title ? asset.title.text : keys.title; - keys.body = asset.data && asset.id === 4 ? asset.data.value : keys.body; - keys.sponsoredBy = - asset.data && asset.id === 3 ? asset.data.value : keys.sponsoredBy; - keys.image = - asset.img && asset.id === 2 - ? { - url: asset.img.url, - width: asset.img.w || 750, - height: asset.img.h || 500 - } - : keys.image; - keys.cta = asset.data && asset.id === 5 ? asset.data.value : keys.cta; - }); - if (nativeAd.link) { - keys.clickUrl = encodeURIComponent(nativeAd.link.url); - } - const trackers = nativeAd.imptrackers || []; - trackers.unshift(replaceAuctionPrice(bid.burl, bid.price)); - keys.impressionTrackers = trackers; - return keys; - } - } - return null; -} - -registerBidder(spec); diff --git a/modules/readpeakBidAdapter.md b/modules/readpeakBidAdapter.md deleted file mode 100644 index da250e7f77a..00000000000 --- a/modules/readpeakBidAdapter.md +++ /dev/null @@ -1,31 +0,0 @@ -# Overview - -Module Name: ReadPeak Bid Adapter - -Module Type: Bidder Adapter - -Maintainer: devteam@readpeak.com - -# Description - -Module that connects to ReadPeak's demand sources - -This adapter requires setup and approval from ReadPeak. -Please reach out to your account team or hello@readpeak.com for more information. - -# Test Parameters -```javascript - var adUnits = [{ - code: '/19968336/prebid_native_example_2', - mediaTypes: { native: { type: 'image' } }, - bids: [{ - bidder: 'readpeak', - params: { - bidfloor: 5.00, - publisherId: 'test', - siteId: 'test', - tagId: 'test-tag-1' - }, - }] - }]; -``` diff --git a/modules/realvuAnalyticsAdapter.js b/modules/realvuAnalyticsAdapter.js deleted file mode 100644 index 95e62397c2c..00000000000 --- a/modules/realvuAnalyticsAdapter.js +++ /dev/null @@ -1,957 +0,0 @@ -// RealVu Analytics Adapter -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -import CONSTANTS from '../src/constants.json'; -import { getStorageManager } from '../src/storageManager.js'; - -const storage = getStorageManager(); - -const utils = require('../src/utils.js'); - -let realvuAnalyticsAdapter = adapter({ - global: 'realvuAnalytics', - handler: 'on', - analyticsType: 'bundle' -}); -window.top1 = window; -try { - let wnd = window; - while ((window.top1 != top) && (typeof (wnd.document) != 'undefined')) { - window.top1 = wnd; - wnd = wnd.parent; - } -} catch (e) { - /* continue regardless of error */ -} - -export let lib = { - ads: [], - x1: 0, - y1: 0, - x2: 0, - y2: 0, - t0: new Date(), - nn: 0, - frm: false, // check first if we are inside other domain iframe - msg: [], - foc: !window.top1.document.hidden, // 1-in, 0-out of focus - c: '', // owner id - sr: '', // - beacons: [], // array of beacons to collect while 'conf' is not responded - defer: [], - init: function () { - let z = this; - let u = navigator.userAgent; - z.device = u.match(/iPad|Tablet/gi) ? 'tablet' : u.match(/iPhone|iPod|Android|Opera Mini|IEMobile/gi) ? 'mobile' : 'desktop'; - if (typeof (z.len) == 'undefined') z.len = 0; - z.ie = navigator.appVersion.match(/MSIE/); - z.saf = (u.match(/Safari/) && !u.match(/Chrome/)); - z.ff = u.match(/Firefox/i); - z.cr = (u.match(/Chrome/)); - z.ope = window.opera; - z.fr = 0; - if (window.top1 != top) { - z.fr = 2; - if (typeof window.top1.$sf != 'undefined') { - z.fr = 1; - } - } - z.add_evt(window.top1, 'focus', function () { - window.top1.realvu_aa.foc = 1; - }); - z.add_evt(window.top1, 'scroll', function () { - window.top1.realvu_aa.foc = 1; - }); - z.add_evt(window.top1, 'blur', function () { - window.top1.realvu_aa.foc = 0; - }); - z.add_evt(window.top1.document, 'blur', function () { - window.top1.realvu_aa.foc = 0; - }); - z.add_evt(window.top1, 'visibilitychange', function () { - window.top1.realvu_aa.foc = !window.top1.document.hidden; - }); - z.doLog = (window.top1.location.search.match(/boost_log/) || document.referrer.match(/boost_log/)) ? 1 : 0; - if (z.doLog) { - window.setTimeout(z.scr('https://ac.realvu.net/realvu_aa_viz.js'), 500); - } - }, - - add_evt: function (elem, evtType, func) { - elem.addEventListener(evtType, func, true); - this.defer.push(function() { - elem.removeEventListener(evtType, func, true); - }); - }, - - update: function () { - let z = this; - let t = window.top1; - let de = t.document.documentElement; - z.x1 = t.pageXOffset ? t.pageXOffset : de.scrollLeft; - z.y1 = t.pageYOffset ? t.pageYOffset : de.scrollTop; - let w1 = t.innerWidth ? t.innerWidth : de.clientWidth; - let h1 = t.innerHeight ? t.innerHeight : de.clientHeight; - z.x2 = z.x1 + w1; - z.y2 = z.y1 + h1; - }, - brd: function (s, p) { // return a board Width, s-element, p={Top,Right,Bottom, Left} - let u; - if (window.getComputedStyle) u = window.getComputedStyle(s, null); - else u = s.style; - let a = u['border' + p + 'Width']; - return parseInt(a.length > 2 ? a.slice(0, -2) : 0); - }, - - padd: function (s, p) { // return a board Width, s-element, p={Top,Right,Bottom, Left} - let u; - if (window.getComputedStyle) u = window.getComputedStyle(s, null); - else u = s.style; - let a = u['padding' + p]; - return parseInt(a.length > 2 ? a.slice(0, -2) : 0); - }, - - viz_area: function (x1, x2, y1, y2) { // coords of Ad - if (this.fr == 1) { - try { - let iv = Math.round(100 * window.top1.$sf.ext.geom().self.iv); - return iv; - } catch (e) { - /* continue regardless of error */ - } - } - let xv1 = Math.max(x1, this.x1); - let yv1 = Math.max(y1, this.y1); - let xv2 = Math.min(x2, this.x2); - let yv2 = Math.min(y2, this.y2); - let A = Math.round(100 * ((xv2 - xv1) * (yv2 - yv1)) / ((x2 - x1) * (y2 - y1))); - return (A > 0) ? A : 0; - }, - - viz_dist: function (x1, x2, y1, y2) { // coords of Ad - let d = Math.max(0, this.x1 - x2, x1 - this.x2) + Math.max(0, this.y1 - y2, y1 - this.y2); - return d; - }, - - track: function (a, f, params) { - let z = this; - let s1 = z.tru(a, f) + params; - if (f == 'conf') { - z.scr(s1, a); - z.log(' ' + f + '', a.num); - } else { - let bk = { - s1: s1, - a: a, - f: f - }; - z.beacons.push(bk); - } - }, - - send_track: function () { - let z = this; - if (z.sr >= 'a') { // conf, send beacons - let bk = z.beacons.shift(); - while (typeof bk != 'undefined') { - bk.s1 = bk.s1.replace(/_sr=0*_/, '_sr=' + z.sr + '_'); - z.log(' ' + bk.a.riff + ' ' + bk.a.unit_id + /* ' '+pin.mode+ */ ' ' + bk.a.w + 'x' + bk.a.h + '@' + bk.a.x + ',' + bk.a.y + - ' ' + bk.f + '', bk.a.num); - if (bk.a.rnd < Math.pow(10, 1 - (z.sr.charCodeAt(0) & 7))) { - z.scr(bk.s1, bk.a); - } - bk = z.beacons.shift(); - } - } - }, - - scr: function (s1, a) { - let st = document.createElement('script'); - st.async = true; - st.type = 'text/javascript'; - st.src = s1; - if (a && a.dv0 != null) { - a.dv0.appendChild(st); - } else { - let x = document.getElementsByTagName('script')[0]; - x.parentNode.insertBefore(st, x); - } - }, - - tru: function (a, f) { - let pin = a.pins[0]; - let s2 = 'https://ac.realvu.net/flip/3/c=' + pin.partner_id + - '_f=' + f + '_r=' + a.riff + - '_s=' + a.w + 'x' + a.h; - if (a.p) s2 += '_p=' + a.p; - if (f != 'conf') s2 += '_ps=' + this.enc(a.unit_id); - s2 += '_dv=' + this.device + - // + '_a=' + this.enc(a.a) - '_d=' + pin.mode + - '_sr=' + this.sr + - '_h=' + this.enc(a.ru) + '?'; - return s2.replace(/%/g, '!'); - }, - - enc: function (s1) { - // return escape(s1).replace(/[0-9a-f]{5,}/gi,'RANDOM').replace(/\*/g, '%2A').replace(/_/g, '%5F').replace(/\+/g, - return escape(s1).replace(/\*/g, '%2A').replace(/_/g, '%5F').replace(/\+/g, - '%2B').replace(/\./g, '%2E').replace(/\x2F/g, '%2F'); - }, - - findPosG: function (adi) { - let t = this; - let ad = adi; - let xp = 0; - let yp = 0; - let dc = adi.ownerDocument; - let wnd = dc.defaultView || dc.parentWindow; - - try { - while (ad != null && typeof (ad) != 'undefined') { - if (ad.getBoundingClientRect) { // Internet Explorer, Firefox 3+, Google Chrome, Opera 9.5+, Safari 4+ - let r = ad.getBoundingClientRect(); - xp += r.left; // +sL; - yp += r.top; // +sT; - if (wnd == window.top1) { - xp += t.x1; - yp += t.y1; - } - } else { - if (ad.tagName == 'IFRAME') { - xp += t.brd(ad, 'Left'); - yp += t.brd(ad, 'Top'); - } - xp += ad.offsetLeft; - yp += ad.offsetTop; - - let op = ad.offsetParent; - let pn = ad.parentNode; - let opf = ad; - while (opf != null) { - let cs = window.getComputedStyle(opf, null); - if (cs.position == 'fixed') { - if (cs.top) yp += parseInt(cs.top) + this.y1; - } - if (opf == op) break; - opf = opf.parentNode; - } - while (op != null && typeof (op) != 'undefined') { - xp += op.offsetLeft; - yp += op.offsetTop; - let ptn = op.tagName; - if (t.cr || t.saf || (t.ff && ptn == 'TD')) { - xp += t.brd(op, 'Left'); - yp += t.brd(op, 'Top'); - } - if (ad.tagName != 'IFRAME' && op != document.body && op != document.documentElement) { - xp -= op.scrollLeft; - yp -= op.scrollTop; - } - if (!t.ie) { - while (op != pn && pn != null) { - xp -= pn.scrollLeft; - yp -= pn.scrollTop; - if (t.ff_o) { - xp += t.brd(pn, 'Left'); - yp += t.brd(pn, 'Top'); - } - pn = pn.parentNode; - } - } - pn = pn.parentNode; - op = op.offsetParent; - } - } - if (this.fr) break; // inside different domain iframe or sf - ad = wnd.frameElement; // in case Ad is allocated inside iframe here we go up - wnd = wnd.parent; - } - } catch (e) { - /* continue regardless of error */ - } - let q = { - 'x': Math.round(xp), - 'y': Math.round(yp) - }; - return q; - }, - - poll: function () { - let fifo = window.top1.realvu_aa_fifo; - while (fifo.length > 0) { - (fifo.shift())(); - } - let z = this; - z.update(); - let now = new Date(); - if (typeof (z.ptm) == 'undefined') { - z.ptm = now; - } - let dvz = now - z.ptm; - z.ptm = now; - for (let i = 0; i < z.len; i++) { - let a = z.ads[i]; - let restored = false; - if (a.div == null) { // ad unit is not found yet - let adobj = document.getElementById(a.pins[0].unit_id); - if (adobj == null) { - restored = z.readPos(a); - if (!restored) continue; // do nothing if not found - } else { - z.bind_obj(a, adobj); - z.log('{m}"' + a.unit_id + '" is bound', a.num); - } - } - if (!restored) { - a.target = z.questA(a.div); - let target = (a.target !== null) ? a.target : a.div; - a.box.w = Math.max(target.offsetWidth, a.w); - a.box.h = Math.max(target.offsetHeight, a.h); - let q = z.findPosG(target); - let pad = {}; - pad.t = z.padd(target, 'Top'); - pad.l = z.padd(target, 'Left'); - pad.r = z.padd(target, 'Right'); - pad.b = z.padd(target, 'Bottom'); - let ax = q.x + pad.l; - let ay = q.y + pad.t; - a.box.x = ax; - a.box.y = ay; - if (a.box.w > a.w && a.box.w > 1) { - ax += (a.box.w - a.w - pad.l - pad.r) / 2; - } - if (a.box.h > a.h && a.box.h > 1) { - ay += (a.box.h - a.h - pad.t - pad.b) / 2; - } - if ((ax > 0 && ay > 0) && (a.x != ax || a.y != ay)) { - a.x = ax; - a.y = ay; - z.writePos(a); - } - } - let vtr = ((a.box.w * a.box.h) < 242500) ? 49 : 29; // treashfold more then 49% and more then 29% for "oversized" - if (a.pins[0].edge) { - vtr = a.pins[0].edge - 1; // override default edge 50% (>49) - } - a.vz = z.viz_area(a.box.x, a.box.x + a.box.w, a.box.y, a.box.y + a.box.h); - a.r = (z.fr > 1 ? 'frame' : (((a.vz > vtr) && z.foc) ? 'yes' : 'no')); // f-frame, y-yes in view,n-not in view - if (a.y < 0) { - a.r = 'out'; // if the unit intentionaly moved out, count it as out. - } - if (a.vz > vtr && z.foc) { - a.vt += dvz; // real dt counter in milliseconds, because of poll() can be called irregularly - a.vtu += dvz; - } - // now process every pin - let plen = a.pins.length; - for (let j = 0; j < plen; j++) { - let pin = a.pins[j]; - if (pin.state <= 1) { - let dist = z.viz_dist(a.x, a.x + a.w, a.y, a.y + a.h); - let near = (pin.dist != null && dist <= pin.dist); - // apply "near" rule for ad call only - a.r = (z.fr > 1) ? 'frame' : (((a.vz > vtr) && z.foc) ? 'yes' : 'no'); - if (near && a.r == 'no') { - a.r = 'yes'; - } - if (a.riff === '') { - a.riff = a.r; - let vrScore = z.score(a, 'v:r'); - if (vrScore != null) { - if (a.r == 'no' && vrScore > 75) { - a.riff = 'yes'; - } - } - let vv0Score = z.score(a, 'v:v0'); - if (vv0Score != null) { - if (a.r == 'yes' && vv0Score < (30 + 25 * Math.random())) { - a.riff = 'no'; - } - } - } - if ((pin.mode == 'kvp' || pin.mode == 'tx2') || (((a.vz > vtr) || near) && ((pin.mode == 'in-view' || pin.mode == 'video')))) { - z.show(a, pin); // in-view or flip show immediately if initial realvu=yes, or delay is over - } - } - if (pin.state == 2) { - a.target = z.questA(a.div); - if (a.target != null) { - pin.state = 3; - dvz = 0; - a.vt = 0; - // @if NODE_ENV='debug' - let now = new Date(); - let msg = (now.getTime() - time0) / 1000 + ' RENDERED ' + a.unit_id; - utils.logMessage(msg); - // @endif - let rpt = z.bids_rpt(a, true); - z.track(a, 'rend', rpt); - z.incrMem(a, 'r', 'v:r'); - } - } - if (pin.state > 2) { - let tmin = (pin.mode == 'video') ? 2E3 : 1E3; // mrc min view time - if (a.vz > vtr) { - pin.vt += dvz; // real dt counter in milliseconds, because of poll() can be called irregularly - if (pin.state == 3) { - pin.state = 4; - z.incrMem(a, 'r', 'v:v0'); - } - if (pin.state == 4 && pin.vt >= tmin) { - pin.state = 5; - let rpt = z.bids_rpt(a, true); - z.track(a, 'view', rpt); - z.incrMem(a, 'v', 'v:r'); - z.incrMem(a, 'v', 'v:v0'); - } - if (pin.state == 5 && pin.vt >= 5 * tmin) { - pin.state = 6; - let rpt = z.bids_rpt(a, true); - z.track(a, 'view2', rpt); - } - } else if (pin.vt < tmin) { - pin.vt = 0; // reset to track continuous 1 sec - } - } - if (pin.state >= 2 && pin.mode === 'tx2' && - ((a.vtu > pin.rotate) || (pin.delay > 0 && a.vtu > pin.delay && a.riff === 'no' && a.ncall < 2)) && pin.tx2n > 0) { - // flip or rotate - pin.tx2n--; - pin.state = 1; - a.vtu = 0; - a.target = null; - } - } - } - this.send_track(); - }, - - questA: function (a) { // look for the visible object of ad_sizes size - // returns the object or null - if (a == null) return a; - if (a.nodeType == Node.TEXT_NODE) { - let dc = a.ownerDocument; - let wnd = dc.defaultView || dc.parentWindow; - let par = a.parentNode; - if (wnd == wnd.top) { - return par; - } else { - return par.offsetParent; - } - } - let notFriendly = false; - let ain = null; - let tn = a.tagName; - if (tn == 'HEAD' || tn == 'SCRIPT') return null; - if (tn == 'IFRAME') { - ain = this.doc(a); - if (ain == null) { - notFriendly = true; - } else { - a = ain; - tn = a.tagName; - } - } - if (notFriendly || tn == 'OBJECT' || tn == 'IMG' || tn == 'EMBED' || tn == 'SVG' || tn == 'CANVAS' || - (tn == 'DIV' && a.style.backgroundImage)) { - let w1 = a.offsetWidth; - let h1 = a.offsetHeight; - if (w1 > 33 && h1 > 33 && a.style.display != 'none') return a; - } - if (a.hasChildNodes()) { - let b = a.firstChild; - while (b != null) { - let c = this.questA(b); - if (c != null) return c; - b = b.nextSibling; - } - } - return null; - }, - - doc: function(f) { // return document of f-iframe - let d = null; - try { - if (f.contentDocument) d = f.contentDocument; // DOM - else if (f.contentWindow) d = f.contentWindow.document; // IE - } catch (e) { - /* continue regardless of error */ - } - return d; - }, - - bind_obj: function (a, adobj) { - a.div = adobj; - a.target = null; // initially null, found ad when served - a.unit_id = adobj.id; // placement id or name - a.w = adobj.offsetWidth || 1; // width, min 1 - a.h = adobj.offsetHeight || 1; // height, min 1 - }, - add: function (wnd1, p) { // p - realvu unit id - let a = { - num: this.len, - x: 0, - y: 0, - box: { - x: 0, - y: 0, - h: 1, - w: 1 - }, // measured ad box - p: p, - state: 0, // 0-init, (1-loaded,2-rendered,3-viewed) - delay: 0, // delay in msec to show ad after gets in view - vt: 0, // total view time - vtu: 0, // view time to update and mem - a: '', // ad_placement id - wnd: wnd1, - div: null, - pins: [], - frm: null, // it will be frame when "show" - riff: '', // r to report - rnd: Math.random(), - ncall: 0, // a callback number - rq_bids: [], // rq bids of registered partners - bids: [] // array of bids - }; - a.ru = window.top1.location.hostname; - window.top1.realvu_aa.ads[this.len++] = a; - return a; - }, - - fmt: function (a, pin) { - return { - 'realvu': a.r, - 'riff': a.riff, - 'area': a.vz, - 'ncall': a.ncall, - 'n': a.num, - 'id': a.unit_id, - 'pin': pin - }; - }, - - show: function (a, pin) { - pin.state = 2; // 2-published - pin.vt = 0; // reset view time counter - if (pin.size) { - let asz = this.setSize(pin.size); - if (asz != null) { - a.w = asz.w; - a.h = asz.h; - } - } - if (typeof pin.callback != 'undefined') { - pin.callback(this.fmt(a, pin)); - } - a.ncall++; - this.track(a, 'show', ''); - }, - - check: function (p1) { - let pin = { - dist: 150, - state: 0, - tx2n: 7 - }; // if dist is set trigger ad when distance < pin.dist - for (let attr in p1) { - if (p1.hasOwnProperty(attr)) { - if ((attr == 'ad_sizes') && (typeof (p1[attr]) == 'string')) { - pin[attr] = p1[attr].split(','); - } else if (attr == 'edge') { - try { - let ed = parseInt(p1[attr]); - if (ed > 0 && ed < 251) pin[attr] = ed; - } catch (e) { - /* continue regardless of error */ - } - } else { - pin[attr] = p1[attr]; - } - } - } - let a = null; - let z = this; - try { - // not to track the same object more than one time - for (let i = 0; i < z.len; i++) { - // if (z.ads[i].div == adobj) { a = z.ads[i]; break; } - if (z.ads[i].unit_id == pin.unit_id) { - a = z.ads[i]; - break; - } - } - pin.wnd = pin.wnd || window; - if (a == null) { - a = z.add(pin.wnd, pin.p); - a.unit_id = pin.unit_id; - let adobj = (pin.unit) ? pin.unit : document.getElementById(a.unit_id); - if (adobj != null) { - z.bind_obj(a, adobj); - } else { - z.log('{w}"' + pin.unit_id + '" not found', a.num); - } - if (pin.size) { - let asz = z.setSize(pin.size); - if (asz != null) { - a.w = asz.w; - a.h = asz.h; - } - } - pin.delay = pin.delay || 0; // delay in msec - if (typeof pin.mode == 'undefined') { - if ((typeof pin.callback != 'undefined') || (typeof pin.content != 'undefined')) { - pin.mode = (pin.delay > 0) ? 'tx2' : 'in-view'; - } else { - pin.mode = 'kvp'; - } - // delays are for views only - } - pin.vt = 0; // view time - pin.state = 0; - a.pins.push(pin); - } - if (this.sr === '') { - z.track(a, 'conf', ''); - this.sr = '0'; - } - this.poll(); - return a; - } catch (e) { - z.log(e.message, -1); - return { - r: 'err' - }; - } - }, - - setSize: function (sa) { - let sb = sa; - try { - if (typeof (sa) == 'string') sb = sa.split('x'); // pin.size is a string WWWxHHH or array - else if (Array.isArray(sa)) { - let mm = 4; - while (--mm > 0 && Array.isArray(sa[0]) && Array.isArray(sa[0][0])) { - sa = sa[0]; - } - for (let m = 0; m < sa.length; m++) { - if (Array.isArray(sa[m])) { - sb = sa[m]; // if size is [][] - let s = sb[0] + 'x' + sb[1]; - if (s == '300x250' || s == '728x90' || s == '320x50' || s == '970x90') { - break; // use most popular sizes - } - } else if (sa.length > 1) { - sb = sa; - } - } - } - let w1 = parseInt(sb[0]); - let h1 = parseInt(sb[1]); - return { - w: w1, - h: h1 - }; - } catch (e) { - /* continue regardless of error */ - } - return null; - }, - // API functions - addUnitById: function (partnerId, unitId, callback, delay) { - let p1 = partnerId; - if (typeof (p1) == 'string') { - p1 = { - partner_id: partnerId, - unit_id: unitId, - callback: callback, - delay: delay - }; - } - let a = window.top1.realvu_aa.check(p1); - return a.r; - }, - - checkBidIn: function(partnerId, args, b) { // process a bid from hb - // b==true - add/update, b==false - update only - if (args.cpm == 0) return; // collect only bids submitted - const boost = window.top1.realvu_aa; - let pushBid = false; - let adi = null; - if (!b) { // update only if already checked in by xyzBidAdapter - for (let i = 0; i < boost.ads.length; i++) { - adi = boost.ads[i]; - if (adi.unit_id == args.adUnitCode) { - pushBid = true; - break; - } - } - } else { - pushBid = true; - adi = window.top1.realvu_aa.check({ - unit_id: args.adUnitCode, - size: args.size, - partner_id: partnerId - }); - } - if (pushBid) { - let pb = { - bidder: args.bidder, - cpm: args.cpm, - size: args.size, - adId: args.adId, - requestId: args.requestId, - crid: '', - ttr: args.timeToRespond, - winner: 0 - }; - if (args.creative_id) { - pb.crid = args.creative_id; - } - adi.bids.push(pb); - } - }, - - checkBidWon: function(partnerId, args, b) { - // b==true - add/update, b==false - update only - const z = this; - const unitId = args.adUnitCode; - for (let i = 0; i < z.ads.length; i++) { - let adi = z.ads[i]; - if (adi.unit_id == unitId) { - for (let j = 0; j < adi.bids.length; j++) { - let bj = adi.bids[j]; - if (bj.adId == args.adId) { - bj.winner = 1; - break; - } - } - let rpt = z.bids_rpt(adi, false); - z.track(adi, 'win', rpt); - break; - } - } - }, - - bids_rpt: function(a, wo) { // a-unit, wo=true - WinnerOnly - let rpt = ''; - for (let i = 0; i < a.bids.length; i++) { - let g = a.bids[i]; - if (wo && !g.winner) continue; - rpt += '&bdr=' + g.bidder + '&cpm=' + g.cpm + '&vi=' + a.riff + - '&gw=' + g.winner + '&crt=' + g.crid + '&ttr=' + g.ttr; - // append bid partner_id if any - let pid = ''; - for (let j = 0; j < a.rq_bids.length; j++) { - let rqb = a.rq_bids[j]; - if (rqb.adId == g.adId) { - pid = rqb.partner_id; - break; - } - } - rpt += '&bc=' + pid; - } - return rpt; - }, - - getStatusById: function (unitId) { // return status object - for (let i = 0; i < this.ads.length; i++) { - let adi = this.ads[i]; - if (adi.unit_id == unitId) return this.fmt(adi); - } - return null; - }, - - log: function (m1, i) { - if (this.doLog) { - this.msg.push({ - dt: new Date() - this.t0, - s: 'U' + (i + 1) + m1 - }); - } - }, - - keyPos: function (a) { - if (a.pins[0].unit_id) { - let level = 'L' + (window.top1.location.pathname.match(/\//g) || []).length; - return 'realvu.' + level + '.' + a.pins[0].unit_id.replace(/[0-9]{5,}/gi, 'RANDOM'); - } - }, - - writePos: function (a) { - try { - let v = a.x + ',' + a.y + ',' + a.w + ',' + a.h; - storage.setDataInLocalStorage(this.keyPos(a), v); - } catch (ex) { - /* continue regardless of error */ - } - }, - - readPos: function (a) { - try { - let s = storage.getDataFromLocalStorage(this.keyPos(a)); - if (s) { - let v = s.split(','); - a.x = parseInt(v[0], 10); - a.y = parseInt(v[1], 10); - a.w = parseInt(v[2], 10); - a.h = parseInt(v[3], 10); - a.box = {x: a.x, y: a.y, w: a.w, h: a.h}; - return true; - } - } catch (ex) { - /* do nothing */ - } - return false; - }, - - incrMem: function(a, evt, name) { - try { - let k1 = this.keyPos(a) + '.' + name; - let vmem = storage.getDataFromLocalStorage(k1); - if (vmem == null) vmem = '1:3'; - let vr = vmem.split(':'); - let nv = parseInt(vr[0], 10); - let nr = parseInt(vr[1], 10); - if (evt == 'r') { - nr <<= 1; - nr |= 1; - nv <<= 1; - } - if (evt == 'v') { - nv |= 1; - } - storage.setDataInLocalStorage(k1, nv + ':' + nr); - } catch (ex) { - /* do nothing */ - } - }, - - score: function (a, name) { - try { - let vstr = storage.getDataFromLocalStorage(this.keyPos(a) + '.' + name); - if (vstr != null) { - let vr = vstr.split(':'); - let nv = parseInt(vr[0], 10); - let nr = parseInt(vr[1], 10); - let sv = 0; - let sr = 0; - for (nr &= 0x3FF; nr > 0; nr >>>= 1, nv >>>= 1) { // count 10 deliveries - if (nr & 0x1) sr++; - if (nv & 0x1) sv++; - } - return Math.round(sv * 100 / sr); - } - } catch (ex) { - /* do nothing */ - } - return null; - } -}; - -window.top1.realvu_aa_fifo = window.top1.realvu_aa_fifo || []; -window.top1.realvu_aa = window.top1.realvu_aa || lib; - -if (typeof (window.top1.boost_poll) == 'undefined') { - window.top1.realvu_aa.init(); - window.top1.boost_poll = setInterval(function () { - window.top1 && window.top1.realvu_aa && window.top1.realvu_aa.poll(); - }, 20); -} - -let _options = {}; - -realvuAnalyticsAdapter.originEnableAnalytics = realvuAnalyticsAdapter.enableAnalytics; - -realvuAnalyticsAdapter.enableAnalytics = function (config) { - _options = config.options; - if (typeof (_options.partnerId) == 'undefined' || _options.partnerId == '') { - utils.logError('Missed realvu.com partnerId parameter', 101, 'Missed partnerId parameter'); - } - realvuAnalyticsAdapter.originEnableAnalytics(config); - return _options.partnerId; -}; - -const time0 = (new Date()).getTime(); - -realvuAnalyticsAdapter.track = function ({eventType, args}) { - // @if NODE_ENV='debug' - let msg = ''; - let now = new Date(); - msg += (now.getTime() - time0) / 1000 + ' eventType=' + eventType; - if (typeof (args) != 'undefined') { - msg += ', args.bidder=' + args.bidder + ' args.adUnitCode=' + args.adUnitCode + - ' args.adId=' + args.adId + - ' args.cpm=' + args.cpm + - ' creativei_id=' + args.creative_id; - } - // msg += '\nargs=' + JSON.stringify(args) + '
'; - utils.logMessage(msg); - // @endif - - const boost = window.top1.realvu_aa; - let b = false; // false - update only, true - add if not checked in yet - let partnerId = null; - if (_options && _options.partnerId && args) { - partnerId = _options.partnerId; - let code = args.adUnitCode; - b = _options.regAllUnits; - if (!b && _options.unitIds) { - for (let j = 0; j < _options.unitIds.length; j++) { - if (code === _options.unitIds[j]) { - b = true; - break; - } - } - } - } - if (eventType === CONSTANTS.EVENTS.BID_RESPONSE) { - boost.checkBidIn(partnerId, args, b); - } else if (eventType === CONSTANTS.EVENTS.BID_WON) { - boost.checkBidWon(partnerId, args, b); - } -}; - -// xyzBidAdapter calls checkin() to obtain "yes/no" viewability -realvuAnalyticsAdapter.checkIn = function (bid, partnerId) { - // find (or add if not registered yet) the unit in boost - if (typeof (partnerId) == 'undefined' || partnerId == '') { - utils.logError('Missed realvu.com partnerId parameter', 102, 'Missed partnerId parameter'); - } - let a = window.top1.realvu_aa.check({ - unit_id: bid.adUnitCode, - size: bid.sizes, - partner_id: partnerId - }); - a.rq_bids.push({ - bidder: bid.bidder, - adId: bid.bidId, - partner_id: partnerId - }); - return a.riff; -}; - -realvuAnalyticsAdapter.isInView = function (adUnitCode) { - let r = 'NA'; - let s = window.top1.realvu_aa.getStatusById(adUnitCode); - if (s) { - r = s.realvu; - } - return r; -}; - -let disableAnalyticsSuper = realvuAnalyticsAdapter.disableAnalytics; -realvuAnalyticsAdapter.disableAnalytics = function () { - while (lib.defer.length) { - lib.defer.pop()(); - } - disableAnalyticsSuper.apply(this, arguments); -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: realvuAnalyticsAdapter, - code: 'realvuAnalytics' -}); - -export default realvuAnalyticsAdapter; diff --git a/modules/realvuAnalyticsAdapter.md b/modules/realvuAnalyticsAdapter.md deleted file mode 100644 index c534f78bc94..00000000000 --- a/modules/realvuAnalyticsAdapter.md +++ /dev/null @@ -1,9 +0,0 @@ -# Overview - -Module Name: RealVu Analytics Adapter -Module Type: Analytics Adapter -Maintainer: it@realvu.com - -# Description - -Analytics adapter for realvu.com. Contact support@realvu.com for information. diff --git a/modules/reconciliationRtdProvider.js b/modules/reconciliationRtdProvider.js deleted file mode 100644 index f8636862d4c..00000000000 --- a/modules/reconciliationRtdProvider.js +++ /dev/null @@ -1,295 +0,0 @@ -/** - * This module adds reconciliation provider to the real time data module - * The {@link module:modules/realTimeData} module is required - * The module will add custom targetings to ad units - * The module will listen to post messages from rendered creatives with Reconciliation Tag - * The module will call tracking pixels to log info needed for reconciliation matching - * @module modules/reconciliationRtdProvider - * @requires module:modules/realTimeData - */ - -/** - * @typedef {Object} ModuleParams - * @property {string} publisherMemberId - * @property {?string} initUrl - * @property {?string} impressionUrl - * @property {?boolean} allowAccess - */ - -import { submodule } from '../src/hook.js'; -import { ajaxBuilder } from '../src/ajax.js'; -import * as utils from '../src/utils.js'; -import find from 'core-js-pure/features/array/find.js'; - -/** @type {Object} */ -const MessageType = { - IMPRESSION_REQUEST: 'rsdk:impression:req', - IMPRESSION_RESPONSE: 'rsdk:impression:res', -}; -/** @type {ModuleParams} */ -const DEFAULT_PARAMS = { - initUrl: 'https://confirm.fiduciadlt.com/init', - impressionUrl: 'https://confirm.fiduciadlt.com/pimp', - allowAccess: false, -}; -/** @type {ModuleParams} */ -let _moduleParams = {}; - -/** - * Handle postMesssage from ad creative, track impression - * and send response to reconciliation ad tag - * @param {Event} e - */ -function handleAdMessage(e) { - let data = {}; - let adUnitId = ''; - let adDeliveryId = ''; - - try { - data = JSON.parse(e.data); - } catch (e) { - return; - } - - if (data.type === MessageType.IMPRESSION_REQUEST) { - if (utils.isGptPubadsDefined()) { - // 1. Find the last iframed window before window.top where the tracker was injected - // (the tracker could be injected in nested iframes) - const adWin = getTopIFrameWin(e.source); - if (adWin && adWin !== window.top) { - // 2. Find the GPT slot for the iframed window - const adSlot = getSlotByWin(adWin); - // 3. Get AdUnit IDs for the selected slot - if (adSlot) { - adUnitId = adSlot.getAdUnitPath(); - adDeliveryId = adSlot.getTargeting('RSDK_ADID'); - adDeliveryId = adDeliveryId.length - ? adDeliveryId[0] - : `${utils.timestamp()}-${utils.generateUUID()}`; - } - } - } - - // Call local impression callback - const args = Object.assign({}, data.args, { - publisherDomain: window.location.hostname, - publisherMemberId: _moduleParams.publisherMemberId, - adUnitId, - adDeliveryId, - }); - - track.trackPost(_moduleParams.impressionUrl, args); - - // Send response back to the Advertiser tag - let response = { - type: MessageType.IMPRESSION_RESPONSE, - id: data.id, - args: Object.assign( - { - publisherDomain: window.location.hostname, - }, - data.args - ), - }; - - // If access is allowed - add ad unit id to response - if (_moduleParams.allowAccess) { - Object.assign(response.args, { - adUnitId, - adDeliveryId, - }); - } - - e.source.postMessage(JSON.stringify(response), '*'); - } -} - -/** - * Get top iframe window for nested Window object - * - top - * -- iframe.window <-- top iframe window - * --- iframe.window - * ---- iframe.window <-- win - * - * @param {Window} win nested iframe window object - * @param {Window} topWin top window - */ -export function getTopIFrameWin(win, topWin) { - topWin = topWin || window; - - if (!win) { - return null; - } - - try { - while (win.parent !== topWin) { - win = win.parent; - } - return win; - } catch (e) { - return null; - } -} - -/** - * get all slots on page - * @return {Object[]} slot GoogleTag slots - */ -function getAllSlots() { - return utils.isGptPubadsDefined() && window.googletag.pubads().getSlots(); -} - -/** - * get GPT slot by placement id - * @param {string} code placement id - * @return {?Object} - */ -function getSlotByCode(code) { - const slots = getAllSlots(); - if (!slots || !slots.length) { - return null; - } - return ( - find( - slots, - (s) => s.getSlotElementId() === code || s.getAdUnitPath() === code - ) || null - ); -} - -/** - * get GPT slot by iframe window - * @param {Window} win - * @return {?Object} - */ -export function getSlotByWin(win) { - const slots = getAllSlots(); - - if (!slots || !slots.length) { - return null; - } - - return ( - find(slots, (s) => { - let slotElement = document.getElementById(s.getSlotElementId()); - - if (slotElement) { - let slotIframe = slotElement.querySelector('iframe'); - - if (slotIframe && slotIframe.contentWindow === win) { - return true; - } - } - - return false; - }) || null - ); -} - -/** - * Init Reconciliation post messages listeners to handle - * impressions messages from ad creative - */ -function initListeners() { - window.addEventListener('message', handleAdMessage, false); -} - -/** - * Send init event to log - * @param {Array} adUnits - */ -function trackInit(adUnits) { - track.trackPost( - _moduleParams.initUrl, - { - adUnits, - publisherDomain: window.location.hostname, - publisherMemberId: _moduleParams.publisherMemberId, - } - ); -} - -/** - * Track event via POST request - * wrap method to allow stubbing in tests - * @param {string} url - * @param {Object} data - */ -export const track = { - trackPost(url, data) { - const ajax = ajaxBuilder(); - - ajax( - url, - function() {}, - JSON.stringify(data), - { - method: 'POST', - } - ); - } -} - -/** - * Set custom targetings for provided adUnits - * @param {string[]} adUnitsCodes - * @return {Object} key-value object with custom targetings - */ -function getReconciliationData(adUnitsCodes) { - const dataToReturn = {}; - const adUnitsToTrack = []; - - adUnitsCodes.forEach((adUnitCode) => { - if (!adUnitCode) { - return; - } - - const adSlot = getSlotByCode(adUnitCode); - const adUnitId = adSlot ? adSlot.getAdUnitPath() : adUnitCode; - const adDeliveryId = `${utils.timestamp()}-${utils.generateUUID()}`; - - dataToReturn[adUnitCode] = { - RSDK_AUID: adUnitId, - RSDK_ADID: adDeliveryId, - }; - - adUnitsToTrack.push({ - adUnitId, - adDeliveryId - }); - }, {}); - - // Track init event - trackInit(adUnitsToTrack); - - return dataToReturn; -} - -/** @type {RtdSubmodule} */ -export const reconciliationSubmodule = { - /** - * used to link submodule with realTimeData - * @type {string} - */ - name: 'reconciliation', - /** - * get data and send back to realTimeData module - * @function - * @param {string[]} adUnitsCodes - */ - getTargetingData: getReconciliationData, - init: init, -}; - -function init(moduleConfig) { - const params = moduleConfig.params; - if (params && params.publisherMemberId) { - _moduleParams = Object.assign({}, DEFAULT_PARAMS, params); - initListeners(); - } else { - utils.logError('missing params for Reconciliation provider'); - } - return true; -} - -submodule('realTimeData', reconciliationSubmodule); diff --git a/modules/reconciliationRtdProvider.md b/modules/reconciliationRtdProvider.md deleted file mode 100644 index 53883ad99eb..00000000000 --- a/modules/reconciliationRtdProvider.md +++ /dev/null @@ -1,49 +0,0 @@ -The purpose of this Real Time Data Provider is to allow publishers to match impressions accross the supply chain. - -**Reconciliation SDK** -The purpose of Reconciliation SDK module is to collect supply chain structure information and vendor-specific impression IDs from suppliers participating in ad creative delivery and report it to the Reconciliation Service, allowing publishers, advertisers and other supply chain participants to match and reconcile ad server, SSP, DSP and veritifation system log file records. Reconciliation SDK was created as part of TAG DLT initiative ( https://www.tagtoday.net/pressreleases/dlt_9_7_2020 ). - -**Usage for Publishers:** - -Compile the Reconciliation Provider into your Prebid build: - -`gulp build --modules=reconciliationRtdProvider` - -Add Reconciliation real time data provider configuration by setting up a Prebid Config: - -```javascript -const reconciliationDataProvider = { - name: "reconciliation", - params: { - publisherMemberId: "test_prebid_publisher", // required - allowAccess: true, //optional - } -}; - -pbjs.setConfig({ - ..., - realTimeData: { - dataProviders: [ - reconciliationDataProvider - ] - } -}); -``` - -where: -- `publisherMemberId` (required) - ID associated with the publisher -- `access` (optional) true/false - Whether ad markup will recieve Ad Unit Id's via Reconciliation Tag - -**Example:** - -To view an example: - -- in your cli run: - -`gulp serve --modules=reconciliationRtdProvider,appnexusBidAdapter` - -Your could also change 'appnexusBidAdapter' to another one. - -- in your browser, navigate to: - -`http://localhost:9999/integrationExamples/gpt/reconciliationRtdProvider_example.html` diff --git a/modules/reklamstoreBidAdapter.js b/modules/reklamstoreBidAdapter.js deleted file mode 100644 index 3d78cf95978..00000000000 --- a/modules/reklamstoreBidAdapter.js +++ /dev/null @@ -1,148 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'reklamstore'; -const ENDPOINT_URL = 'https://ads.rekmob.com/m/prebid'; -const CURRENCY = 'USD'; -const TIME_TO_LIVE = 360; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return !!(bid.params.regionId); - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - const url = bidderRequest.refererInfo.referer; - let requests = []; - utils._each(validBidRequests, function(bid) { - requests.push({ - method: 'GET', - url: ENDPOINT_URL, - data: { - regionId: bid.params.regionId, - dt: getDeviceType(), - os: getOS(), - ref: extractDomain(url), - _: (new Date().getTime()), - mobile_web: 1 - }, - bidId: bid.bidId - }); - }); - return requests; - }, - - /** - * Unpack the 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. - */ - interpretResponse: function (serverResponse, bidRequest) { - try { - const bidResponse = serverResponse.body; - const bidResponses = []; - if (bidResponse) { - bidResponses.push({ - requestId: bidRequest.bidId, - cpm: parseFloat(bidResponse.cpm), - width: bidResponse.w, - height: bidResponse.h, - creativeId: bidResponse.adId || 1, - currency: CURRENCY, - netRevenue: true, - ttl: TIME_TO_LIVE, - ad: bidResponse.ad - }); - } - return bidResponses; - } catch (err) { - utils.logError(err); - return []; - } - }, - /** - * Register the user sync pixels which should be dropped after the auction. - * - * @param {SyncOptions} syncOptions Which user syncs are allowed? - * @param {ServerResponse[]} serverResponses List of server's responses. - * @return {UserSync[]} The user syncs which should be dropped. - */ - getUserSyncs: function(syncOptions, serverResponses) { - const syncs = []; - utils._each(serverResponses, function(bidResponse) { - utils._each(bidResponse.body.syncs, function(sync) { - if (syncOptions.pixelEnabled && sync.type == 'image') { - syncs.push({ - type: sync.type, - url: sync.url - }); - } else if (syncOptions.iframeEnabled && sync.type == 'iframe') { - syncs.push({ - type: sync.type, - url: sync.url - }); - } - }); - }); - return syncs; - } -} -registerBidder(spec); - -function getDeviceType() { - let PHONE = 0; - let TABLET = 2; - let DESKTOP = 3; - if (isPhone()) { - return PHONE; - } else if (isTablet()) { - return TABLET; - } else { - return DESKTOP; - } -} -function isPhone() { - var check = false; - (function (a) { if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4))) check = true })(navigator.userAgent || navigator.vendor || window.opera); - return check; -} -function isTablet() { - var check = false; - (function(a) { if (/ipad|android|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i.test(a)) { check = true; } })(navigator.userAgent || navigator.vendor || window.opera); - return check; -} -function getOS() { - var ua = navigator.userAgent; - if (ua.match(/(iPhone|iPod|iPad)/)) { - return '1'; - } else if (ua.match(/Android/)) { - return '0'; - } else { - return '3'; - } -} -function extractDomain(url) { - var domain; - if (url.indexOf('://') > -1) { - domain = url.split('/')[2]; - } else { - domain = url.split('/')[0]; - } - domain = domain.split(':')[0]; - return domain; -} diff --git a/modules/reklamstoreBidAdapter.md b/modules/reklamstoreBidAdapter.md deleted file mode 100644 index 8615341f5cc..00000000000 --- a/modules/reklamstoreBidAdapter.md +++ /dev/null @@ -1,32 +0,0 @@ -# Overview - -Module Name: ReklamStore Bidder Adapter -Module Type: Bidder Adapter -Maintainer: it@reklamstore.com - -# Description - -Module that connects to ReklamStore's demand sources. - -ReklamStore supports display. - - -# Test Parameters -# display -``` - - var adUnits = [ - { - code: 'banner-ad-div', - sizes: [[300, 250]], - bids: [ - { - bidder: 'reklamstore', - params: { - regionId:532211 - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/relaidoBidAdapter.js b/modules/relaidoBidAdapter.js deleted file mode 100644 index 92709b7c047..00000000000 --- a/modules/relaidoBidAdapter.js +++ /dev/null @@ -1,291 +0,0 @@ -import * as utils 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 { getStorageManager } from '../src/storageManager.js'; - -const BIDDER_CODE = 'relaido'; -const BIDDER_DOMAIN = 'api.relaido.jp'; -const ADAPTER_VERSION = '1.0.3'; -const DEFAULT_TTL = 300; -const UUID_KEY = 'relaido_uuid'; - -const storage = getStorageManager(); - -function isBidRequestValid(bid) { - if (!utils.deepAccess(bid, 'params.placementId')) { - utils.logWarn('placementId param is reqeuired.'); - return false; - } - if (hasVideoMediaType(bid) && isVideoValid(bid)) { - return true; - } else { - utils.logWarn('Invalid mediaType video.'); - } - if (hasBannerMediaType(bid) && isBannerValid(bid)) { - return true; - } else { - utils.logWarn('Invalid mediaType banner.'); - } - return false; -} - -function buildRequests(validBidRequests, bidderRequest) { - let bidRequests = []; - - for (let i = 0; i < validBidRequests.length; i++) { - const bidRequest = validBidRequests[i]; - const placementId = utils.getBidIdParameter('placementId', bidRequest.params); - const bidDomain = bidRequest.params.domain || BIDDER_DOMAIN; - const bidUrl = `https://${bidDomain}/bid/v1/prebid/${placementId}`; - const uuid = getUuid(); - let mediaType = ''; - let width = 0; - let height = 0; - - if (hasVideoMediaType(bidRequest) && isVideoValid(bidRequest)) { - const playerSize = getValidSizes(utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize')); - width = playerSize[0][0]; - height = playerSize[0][1]; - mediaType = VIDEO; - } else if (hasBannerMediaType(bidRequest) && isBannerValid(bidRequest)) { - const sizes = getValidSizes(utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes')); - width = sizes[0][0]; - height = sizes[0][1]; - mediaType = BANNER; - } - - let payload = { - version: ADAPTER_VERSION, - timeout_ms: bidderRequest.timeout, - ad_unit_code: bidRequest.adUnitCode, - auction_id: bidRequest.auctionId, - bidder: bidRequest.bidder, - bidder_request_id: bidRequest.bidderRequestId, - bid_requests_count: bidRequest.bidRequestsCount, - bid_id: bidRequest.bidId, - transaction_id: bidRequest.transactionId, - media_type: mediaType, - uuid: uuid, - width: width, - height: height - }; - - // It may not be encoded, so add it at the end of the payload - payload.ref = bidderRequest.refererInfo.referer; - - bidRequests.push({ - method: 'GET', - url: bidUrl, - data: payload, - options: { - withCredentials: true - }, - bidId: bidRequest.bidId, - player: bidRequest.params.player, - width: payload.width, - height: payload.height, - mediaType: payload.media_type - }); - } - return bidRequests; -} - -function interpretResponse(serverResponse, bidRequest) { - const bidResponses = []; - const body = serverResponse.body; - if (!body || body.status != 'ok') { - return []; - } - - const playerUrl = bidRequest.player || body.playerUrl; - const mediaType = bidRequest.mediaType || VIDEO; - - let bidResponse = { - requestId: bidRequest.bidId, - width: bidRequest.width, - height: bidRequest.height, - cpm: body.price, - currency: body.currency, - creativeId: body.creativeId, - dealId: body.dealId || '', - ttl: body.ttl || DEFAULT_TTL, - netRevenue: true, - mediaType: mediaType, - }; - if (mediaType === VIDEO) { - bidResponse.vastXml = body.vast; - bidResponse.renderer = newRenderer(bidRequest.bidId, playerUrl); - } else { - const playerTag = createPlayerTag(playerUrl); - const renderTag = createRenderTag(bidRequest.width, bidRequest.height, body.vast); - bidResponse.ad = `
${playerTag}${renderTag}
`; - } - bidResponses.push(bidResponse); - - return bidResponses; -} - -function getUserSyncs(syncOptions, serverResponses) { - if (!syncOptions.iframeEnabled) { - return []; - } - let syncUrl = `https://${BIDDER_DOMAIN}/tr/v1/prebid/sync.html`; - if (serverResponses.length > 0) { - syncUrl = utils.deepAccess(serverResponses, '0.body.syncUrl') || syncUrl; - } - return [{ - type: 'iframe', - url: syncUrl - }]; -} - -function onBidWon(bid) { - let query = utils.parseQueryStringParameters({ - placement_id: utils.deepAccess(bid, 'params.0.placementId'), - creative_id: utils.deepAccess(bid, 'creativeId'), - price: utils.deepAccess(bid, 'cpm'), - auction_id: utils.deepAccess(bid, 'auctionId'), - bid_id: utils.deepAccess(bid, 'requestId'), - ad_id: utils.deepAccess(bid, 'adId'), - ad_unit_code: utils.deepAccess(bid, 'adUnitCode'), - ref: window.location.href, - }).replace(/\&$/, ''); - const bidDomain = utils.deepAccess(bid, 'params.0.domain') || BIDDER_DOMAIN; - const burl = `https://${bidDomain}/tr/v1/prebid/win.gif?${query}`; - utils.triggerPixel(burl); -} - -function onTimeout(data) { - let query = utils.parseQueryStringParameters({ - placement_id: utils.deepAccess(data, '0.params.0.placementId'), - timeout: utils.deepAccess(data, '0.timeout'), - auction_id: utils.deepAccess(data, '0.auctionId'), - bid_id: utils.deepAccess(data, '0.bidId'), - ad_unit_code: utils.deepAccess(data, '0.adUnitCode'), - version: ADAPTER_VERSION, - ref: window.location.href, - }).replace(/\&$/, ''); - const bidDomain = utils.deepAccess(data, '0.params.0.domain') || BIDDER_DOMAIN; - const timeoutUrl = `https://${bidDomain}/tr/v1/prebid/timeout.gif?${query}`; - utils.triggerPixel(timeoutUrl); -} - -function createPlayerTag(playerUrl) { - return ``; -} - -function createRenderTag(width, height, vast) { - return ``; -}; - -function newRenderer(bidId, playerUrl) { - const renderer = Renderer.install({ - id: bidId, - url: playerUrl, - loaded: false - }); - try { - renderer.setRender(outstreamRender); - } catch (err) { - utils.logWarn('renderer.setRender Error', err); - } - return renderer; -} - -function outstreamRender(bid) { - bid.renderer.push(() => { - window.RelaidoPlayer.renderAd({ - adUnitCode: bid.adUnitCode, - width: bid.width, - height: bid.height, - vastXml: bid.vastXml, - mediaType: bid.mediaType, - }); - }); -} - -function isBannerValid(bid) { - if (!isMobile()) { - return false; - } - const sizes = getValidSizes(utils.deepAccess(bid, 'mediaTypes.banner.sizes')); - if (sizes.length > 0) { - return true; - } - return false; -} - -function isVideoValid(bid) { - const playerSize = getValidSizes(utils.deepAccess(bid, 'mediaTypes.video.playerSize')); - if (playerSize.length > 0) { - const context = utils.deepAccess(bid, 'mediaTypes.video.context'); - if (context && context === 'outstream') { - return true; - } - } - return false; -} - -function getUuid() { - const id = storage.getCookie(UUID_KEY) - if (id) return id; - const newId = utils.generateUUID(); - storage.setCookie(UUID_KEY, newId); - return newId; -} - -export function isMobile() { - const ua = navigator.userAgent; - if (ua.indexOf('iPhone') > -1 || ua.indexOf('iPod') > -1 || (ua.indexOf('Android') > -1 && ua.indexOf('Tablet') == -1)) { - return true; - } - return false; -} - -function hasBannerMediaType(bid) { - return !!utils.deepAccess(bid, 'mediaTypes.banner'); -} - -function hasVideoMediaType(bid) { - return !!utils.deepAccess(bid, 'mediaTypes.video'); -} - -function getValidSizes(sizes) { - let result = []; - if (sizes && utils.isArray(sizes) && sizes.length > 0) { - for (let i = 0; i < sizes.length; i++) { - if (utils.isArray(sizes[i]) && sizes[i].length == 2) { - const width = sizes[i][0]; - const height = sizes[i][1]; - if (width == 1 && height == 1) { - return [[1, 1]]; - } - if ((width >= 300 && height >= 250)) { - result.push([width, height]); - } - } - } - } - return result; -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - isBidRequestValid, - buildRequests, - interpretResponse, - getUserSyncs: getUserSyncs, - onBidWon, - onTimeout -} - -registerBidder(spec); diff --git a/modules/relaidoBidAdapter.md b/modules/relaidoBidAdapter.md deleted file mode 100644 index 459f772c66b..00000000000 --- a/modules/relaidoBidAdapter.md +++ /dev/null @@ -1,48 +0,0 @@ -# Overview - -``` -Module Name: Relaido Bidder Adapter -Module Type: Bidder Adapter -Maintainer: video-dev@cg.relaido.co.jp -``` - -# Description - -Connects to Relaido exchange for bids. - -Relaido bid adapter supports Outstream Video. - -# Test Parameters - -```javascript - var adUnits=[{ - code: 'banner-ad-div', - mediaTypes: { - banner: { - sizes: [ - [300, 250] - ] - } - }, - bids: [{ - bidder: 'relaido', - params: { - placementId: '9900' - } - }] - },{ - code: 'video-ad-player', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [640, 360] - } - }, - bids: [{ - bidder: 'relaido', - params: { - placementId: '9900' - } - }] - }]; -``` \ No newline at end of file diff --git a/modules/relevantAnalyticsAdapter.js b/modules/relevantAnalyticsAdapter.js deleted file mode 100644 index 5917262c810..00000000000 --- a/modules/relevantAnalyticsAdapter.js +++ /dev/null @@ -1,33 +0,0 @@ -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; - -const relevantAnalytics = adapter({ analyticsType: 'bundle', handler: 'on' }); - -const { enableAnalytics: orgEnableAnalytics } = relevantAnalytics; - -Object.assign(relevantAnalytics, { - /** - * Save event in the global array that will be consumed later by the Relevant Yield library - */ - track: ({ eventType: ev, args }) => { - window.relevantDigital.pbEventLog.push({ ev, args, ts: new Date() }); - }, - - /** - * Before forwarding the call to the original enableAnalytics function - - * create (if needed) the global array that is used to pass events to the Relevant Yield library - * by the 'track' function above. - */ - enableAnalytics: function(...args) { - window.relevantDigital = window.relevantDigital || {}; - window.relevantDigital.pbEventLog = window.relevantDigital.pbEventLog || []; - return orgEnableAnalytics.call(this, ...args); - }, -}); - -adapterManager.registerAnalyticsAdapter({ - adapter: relevantAnalytics, - code: 'relevant', -}); - -export default relevantAnalytics; diff --git a/modules/relevantAnalyticsAdapter.md b/modules/relevantAnalyticsAdapter.md deleted file mode 100644 index e6383fa77e1..00000000000 --- a/modules/relevantAnalyticsAdapter.md +++ /dev/null @@ -1,13 +0,0 @@ -# Overview - -Module Name: Relevant Yield Analytics Adapter - -Module Type: Analytics Adapter - -Maintainer: [support@relevant-digital.com](mailto:support@relevant-digital.com) - -# Description - -Analytics adapter to be used with [Relevant Yield](https://www.relevant-digital.com/relevantyield) - -Contact [sales@relevant-digital.com](mailto:sales@relevant-digital.com) for information. diff --git a/modules/reloadBidAdapter.js b/modules/reloadBidAdapter.js deleted file mode 100644 index 94ea4be281f..00000000000 --- a/modules/reloadBidAdapter.js +++ /dev/null @@ -1,419 +0,0 @@ -import { - registerBidder -} - from '../src/adapters/bidderFactory.js'; -import * as utils from '../src/utils.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const storage = getStorageManager(); - -const BIDDER_CODE = 'reload'; -const VERSION_ADAPTER = '1.10'; -export const spec = { - code: BIDDER_CODE, - png: {}, - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return !!(bid.params && bid.params.plcmID && bid.params.partID && 'opdomID' in bid.params && - 'bsrvID' in bid.params && bid.params.bsrvID >= 0 && bid.params.bsrvID <= 99); - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - let vRequests = []; - let bidReq = { - id: Math.random().toString(10).substring(2), - imp: [] - }; - let vgdprConsent = null; - if (utils.deepAccess(bidderRequest, 'gdprConsent')) { - vgdprConsent = bidderRequest.gdprConsent; - } - let vPrxClientTool = null; - let vSrvUrl = null; - for (let vIdx = 0; vIdx < validBidRequests.length; vIdx++) { - let bidRequest = validBidRequests[vIdx]; - vPrxClientTool = new ReloadClientTool({ - prxVer: VERSION_ADAPTER, - prxType: 'bd', - plcmID: bidRequest.params.plcmID, - partID: bidRequest.params.partID, - opdomID: bidRequest.params.opdomID, - bsrvID: bidRequest.params.bsrvID, - gdprObj: vgdprConsent, - mediaObj: bidRequest.mediaTypes, - wnd: utils.getWindowTop(), - rtop: utils.deepAccess(bidderRequest, 'refererInfo.reachedTop') || false - }); - if (vSrvUrl === null) vSrvUrl = vPrxClientTool.getSrvUrl(); - let vImpression = { - id: bidRequest.bidId, - bidId: bidRequest.bidId, - adUnitCode: bidRequest.adUnitCode, - transactionId: bidRequest.transactionId, - bidderRequestId: bidRequest.bidderRequestId, - auctionId: bidRequest.auctionId, - banner: { - ext: { - type: bidRequest.params.type || 'pcm', - pcmdata: vPrxClientTool.getPCMObj() - } - } - }; - bidReq.imp.push(vImpression); - } - if (bidReq.imp.length > 0) { - const payloadString = JSON.stringify(bidReq); - vRequests.push({ - method: 'POST', - url: vSrvUrl, - data: payloadString - }); - } - return vRequests; - }, - /** - * Unpack the 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. - */ - interpretResponse: function (serverResponse, bidRequest) { - const serverBody = serverResponse.body; - const bidResponses = []; - for (let vIdx = 0; vIdx < serverBody.seatbid.length; vIdx++) { - let vSeatBid = serverBody.seatbid[vIdx]; - for (let vIdxBid = 0; vIdxBid < vSeatBid.bid.length; vIdxBid++) { - let vBid = vSeatBid.bid[vIdxBid]; - let vPrxClientTool = new ReloadClientTool({ - plcmID: vBid.ext.plcmID, - partID: vBid.ext.partID, - opdomID: vBid.ext.opdomID, - bsrvID: vBid.ext.bsrvID - }); - vPrxClientTool.setPCMObj(vBid.ext.pcmdata); - if (vPrxClientTool.getBP() > 0) { - let bidResponse = { - requestId: vBid.impid, - ad: vPrxClientTool.getAM(), - cpm: vPrxClientTool.getBP() / 100, - width: vPrxClientTool.getW(), - height: vPrxClientTool.getH(), - creativeId: vBid.id, - currency: vPrxClientTool.getBC(), - ttl: 300, - netRevenue: true - }; - bidResponses.push(bidResponse); - this.png[vBid.ext.adUnitCode] = vPrxClientTool.getPingUrl('bidwon'); - } - } - } - return bidResponses; - }, - /** - * Register bidder specific code, which will execute if a bid from this bidder won the auction - * @param {Bid} The bid that won the auction - */ - onBidWon: function (bid) { - if (typeof this.png[bid.adUnitCode] !== 'string' || this.png[bid.adUnitCode] === '') return; - (new Image()).src = this.png[bid.adUnitCode]; - } -}; - -function ReloadClientTool(args) { - var that = this; - var _pcmClientVersion = '120'; - var _pcmFilePref = 'prx_root_'; - var _resFilePref = 'prx_pnws_'; - var _pcmInputObjVers = '120'; - var _instObj = null; - var _status = 'NA'; - var _message = ''; - var _log = ''; - var _memFile = _getMemFile(); - - if (_memFile.status !== 'ok') { - _log += 'WARNING: clnt-int mem file initialized\n'; - } - - that.getPCMObj = function () { - return { - thisVer: _pcmInputObjVers, - statStr: _memFile.statStr, - plcmData: _getPlcmData(), - clntData: _getClientData(args.wnd, args.rtop), - resultData: _getRD(), - gdprObj: _getGdpr(), - mediaObj: _getMediaObj(), - proxetString: null, - dboData: null, - plcmSett: null, - }; - }; - - that.setPCMObj = function (obj) { - if (obj.thisVer !== '100') { - _status = 'error'; - _message = 'incomp_output_obj_version'; - _log += ' ERROR incomp_output_obj_version'; - return; - } - - _status = obj.status; - _message = obj.message; - _log += ' ' + obj.log; - - if (obj.status !== 'ok') return; - - _saveMemFile(obj.statStr, obj.srvUrl); - _instObj = obj.instr; - }; - - that.getSrvUrl = function () { - var effSrvUrl = getBidServerUrl(0); - - if (isNaN(parseInt(args.bsrvID)) !== true) effSrvUrl = getBidServerUrl(parseInt(args.bsrvID)); - - if (typeof _memFile.srvUrl === 'string' && _memFile.srvUrl !== '') effSrvUrl = _memFile.srvUrl; - - return 'https://' + effSrvUrl + '/bid'; - - function getBidServerUrl (idx) { - return 'bidsrv' + getTwoDigitString(idx) + '.reload.net'; - - function getTwoDigitString (idx) { - if (idx >= 10) return '' + idx; - else return '0' + idx; - } - } - }; - - that.getMT = function () { - return _checkInstProp('mtype', 'dsp'); - }; - - that.getW = function () { - return _checkInstProp('width', 0); - }; - - that.getH = function () { - return _checkInstProp('height', 0); - }; - - that.getBP = function () { - return _checkInstProp('prc', 0); - }; - - that.getBC = function () { - return _checkInstProp('cur', 'USD'); - }; - - that.getAM = function () { - return _checkInstProp('am', null); - }; - - that.getPingUrl = function (pingName) { - var pingData = _checkInstProp('pingdata', {}); - if (pingData[pingName] !== 'undefined') return pingData[pingName]; - return ''; - }; - - that.setRD = function (data) { - return _setRD(data); - }; - - that.getStat = function () { - return _status; - }; - - that.getMsg = function () { - return _message; - }; - - that.getLog = function () { - return _log; - }; - - function _checkInstProp (key, def) { - if (_instObj === null) return def; - if (typeof _instObj === 'undefined') return def; - if (_instObj.go !== true) return def; - if (typeof _instObj[key] === 'undefined') return def; - return _instObj[key]; - } - - function _getPlcmData () { - return { - prxVer: args.prxVer, - prxType: args.prxType, - plcmID: args.plcmID, - partID: args.partID, - opdomID: args.opdomID, - bsrvID: args.bsrvID, - dmod: args.dmod, - lmod: args.lmod, - lplcmID: args.lplcmID, - }; - } - - function _getClientData (wnd, rtop) { - return { - version: 200, - locTime: Date.now(), - winInfo: _winInf(wnd), - envInfo: getEnvInfo(), - topw: rtop === true, - prot: wnd.document.location.protocol, - host: wnd.document.location.host, - title: wnd.document.title, - }; - - function _winInf (wnd) { - return { - phs: { - w: wnd.screen.width, - h: wnd.screen.height - }, - avl: { - w: wnd.screen.availWidth, - h: wnd.screen.availHeight - }, - inr: { - w: wnd.innerWidth, - h: wnd.innerHeight - }, - bdy: { - w: wnd.document.body.clientWidth, - h: wnd.document.body.clientHeight - } - }; - } - - function getEnvInfo() { - return { - userAgent: navigator.userAgent, - appName: navigator.appName, - appVersion: navigator.appVersion - }; - } - } - - function _getMemFile () { - try { - var memFileObj = _getItem(_getMemFileName()); - - if (memFileObj === null) throw { s: 'init' }; - - if (typeof memFileObj.statStr !== 'string') throw { s: 'error' }; - if (typeof memFileObj.srvUrl !== 'string') throw { s: 'error' }; - - memFileObj.status = 'ok'; - - return memFileObj; - } catch (err) { - var retObj = { - statStr: null, - srvUrl: null - }; - retObj.status = err.s; - - return retObj; - } - } - - function _saveMemFile (statStr, srvUrl) { - try { - var fileData = { - statStr: statStr, - srvUrl: srvUrl, - }; - _setItem(_getMemFileName(), fileData); - return true; - } catch (err) { - return false; - } - } - - function _getMemFileName () { - return _pcmFilePref + args.plcmID + '_' + args.partID; - } - - function _getRD () { - try { - return _getItem(_getResltStatusFileName()); - } catch (err) { - return null; - } - } - - function _setRD (fileData) { - try { - _setItem(_getResltStatusFileName(), fileData); - return true; - } catch (err) { - return false; - } - } - - function _getGdpr() { - return args.gdprObj; - } - - function _getMediaObj() { - return args.mediaObj; - } - - function _getResltStatusFileName () { - if (args.lmod === true) return _resFilePref + args.lplcmID + '_' + args.partID; - else return _resFilePref + args.plcmID + '_' + args.partID; - } - - function _setItem (name, data) { - var stgFileObj = { - ver: _pcmClientVersion, - ts: Date.now(), - }; - - if (typeof data === 'string') { - stgFileObj.objtype = false; - stgFileObj.memdata = data; - } else { - stgFileObj.objtype = true; - stgFileObj.memdata = JSON.stringify(data); - } - - var stgFileStr = JSON.stringify(stgFileObj); - - storage.setDataInLocalStorage(name, stgFileStr); - - return true; - } - - function _getItem (name) { - try { - var obStgFileStr = storage.getDataFromLocalStorage(name); - if (obStgFileStr === null) return null; - - var stgFileObj = JSON.parse(obStgFileStr); - - if (stgFileObj.ver !== _pcmClientVersion) throw { message: 'version_error' }; - - if (stgFileObj.objtype === true) return JSON.parse(stgFileObj.memdata); - else return '' + stgFileObj.memdata; - } catch (err) { - return null; - } - } -}; - -registerBidder(spec); diff --git a/modules/reloadBidAdapter.md b/modules/reloadBidAdapter.md deleted file mode 100644 index 42fe11b40b3..00000000000 --- a/modules/reloadBidAdapter.md +++ /dev/null @@ -1,48 +0,0 @@ -# Overview - -Module Name: Reload Bid Adapter - -Module Type: Bidder Adapter - -Maintainer: prebid@reload.net - -# Description - -Prebid module for connecting to Reload - -# Parameters -## Banner - -| Name | Scope | Description | Example | -| :------------ | :------- | :---------------------------------------------- | :--------------------------------- | -| `plcmID` | required | Placement ID (provided by Reload) | "4234897234" | -| `partID` | required | Partition ID (provided by Reload) | "part_01" | -| `opdomID` | required | Internal parameter (provided by Reload) | 0 | -| `bsrvID` | required | Internal parameter (provided by Reload) | 12 | -| `type` | optional | Internal parameter (provided by Reload) | "pcm" | - -# Example ad units -# Test Parameters -``` -var adUnits = [ - // Banner adUnit - { - code: 'banner-div', - mediaTypes: { - banner: { - sizes: [ - [300, 250] - ], - } - }, - bids: [{ - bidder: 'reload', - params: { - plcmID: 'prebid_check', - partID: 'part_4', - opdomID: '0', - bsrvID: 0, - type: 'pcm' - } - }] - }]; \ No newline at end of file diff --git a/modules/resultsmediaBidAdapter.js b/modules/resultsmediaBidAdapter.js deleted file mode 100644 index beb9991e1e2..00000000000 --- a/modules/resultsmediaBidAdapter.js +++ /dev/null @@ -1,269 +0,0 @@ -'use strict'; - -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; - -function ResultsmediaAdapter() { - this.code = 'resultsmedia'; - this.aliases = ['resultsmedia']; - this.supportedMediaTypes = [VIDEO, BANNER]; - - let SUPPORTED_VIDEO_PROTOCOLS = [2, 3, 5, 6]; - let SUPPORTED_VIDEO_MIMES = ['video/mp4']; - let SUPPORTED_VIDEO_PLAYBACK_METHODS = [1, 2, 3, 4]; - let SUPPORTED_VIDEO_DELIVERY = [1]; - let SUPPORTED_VIDEO_API = [1, 2, 5]; - let slotsToBids = {}; - let that = this; - let version = '2.1'; - - this.isBidRequestValid = function (bid) { - return !!(bid.params && bid.params.zoneId); - }; - - this.getUserSyncs = function (syncOptions, responses, gdprConsent) { - return []; - }; - - function frameImp(BRs, bidderRequest) { - var impList = []; - var isSecure = 0; - if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.stack.length) { - // clever trick to get the protocol - var el = document.createElement('a'); - el.href = bidderRequest.refererInfo.stack[0]; - isSecure = (el.protocol == 'https:') ? 1 : 0; - } - for (var i = 0; i < BRs.length; i++) { - slotsToBids[BRs[i].adUnitCode] = BRs[i]; - var impObj = {}; - impObj.id = BRs[i].adUnitCode; - impObj.secure = isSecure; - - if (utils.deepAccess(BRs[i], 'mediaTypes.banner') || utils.deepAccess(BRs[i], 'mediaType') === 'banner') { - let banner = frameBanner(BRs[i]); - if (banner) { - impObj.banner = banner; - } - } - if (utils.deepAccess(BRs[i], 'mediaTypes.video') || utils.deepAccess(BRs[i], 'mediaType') === 'video') { - impObj.video = frameVideo(BRs[i]); - } - if (!(impObj.banner || impObj.video)) { - continue; - } - impObj.ext = frameExt(BRs[i]); - impList.push(impObj); - } - return impList; - } - - function frameSite(bidderRequest) { - var site = { - domain: '', - page: '', - ref: '' - } - if (bidderRequest && bidderRequest.refererInfo) { - var ri = bidderRequest.refererInfo; - site.ref = ri.referer; - - if (ri.stack.length) { - site.page = ri.stack[ri.stack.length - 1]; - - // clever trick to get the domain - var el = document.createElement('a'); - el.href = ri.stack[0]; - site.domain = el.hostname; - } - } - return site; - } - - function frameDevice() { - return { - ua: navigator.userAgent, - ip: '', // Empty Ip string is required, server gets the ip from HTTP header - dnt: utils.getDNT() ? 1 : 0, - } - } - - function getValidSizeSet(dimensionList) { - let w = parseInt(dimensionList[0]); - let h = parseInt(dimensionList[1]); - // clever check for NaN - if (! (w !== w || h !== h)) { // eslint-disable-line - return [w, h]; - } - return false; - } - - function frameBanner(adUnit) { - // adUnit.sizes is scheduled to be deprecated, continue its support but prefer adUnit.mediaTypes.banner - var sizeList = adUnit.sizes; - if (adUnit.mediaTypes && adUnit.mediaTypes.banner) { - sizeList = adUnit.mediaTypes.banner.sizes; - } - var sizeStringList = utils.parseSizesInput(sizeList); - var format = []; - sizeStringList.forEach(function(size) { - if (size) { - var dimensionList = getValidSizeSet(size.split('x')); - if (dimensionList) { - format.push({ - 'w': dimensionList[0], - 'h': dimensionList[1], - }); - } - } - }); - if (format.length) { - return { - 'format': format - }; - } - - return false; - } - - function frameVideo(bid) { - var size = []; - if (utils.deepAccess(bid, 'mediaTypes.video.playerSize')) { - var dimensionSet = bid.mediaTypes.video.playerSize; - if (utils.isArray(bid.mediaTypes.video.playerSize[0])) { - dimensionSet = bid.mediaTypes.video.playerSize[0]; - } - var validSize = getValidSizeSet(dimensionSet) - if (validSize) { - size = validSize; - } - } - return { - mimes: utils.deepAccess(bid, 'mediaTypes.video.mimes') || SUPPORTED_VIDEO_MIMES, - protocols: utils.deepAccess(bid, 'mediaTypes.video.protocols') || SUPPORTED_VIDEO_PROTOCOLS, - w: size[0], - h: size[1], - startdelay: utils.deepAccess(bid, 'mediaTypes.video.startdelay') || 0, - skip: utils.deepAccess(bid, 'mediaTypes.video.skip') || 0, - playbackmethod: utils.deepAccess(bid, 'mediaTypes.video.playbackmethod') || SUPPORTED_VIDEO_PLAYBACK_METHODS, - delivery: utils.deepAccess(bid, 'mediaTypes.video.delivery') || SUPPORTED_VIDEO_DELIVERY, - api: utils.deepAccess(bid, 'mediaTypes.video.api') || SUPPORTED_VIDEO_API, - } - } - - function frameExt(bid) { - return { - bidder: { - zoneId: bid.params['zoneId'] - } - } - } - - function frameBid(BRs, bidderRequest) { - let bid = { - id: BRs[0].bidderRequestId, - imp: frameImp(BRs, bidderRequest), - site: frameSite(bidderRequest), - device: frameDevice(), - user: { - ext: { - consent: utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies') ? bidderRequest.gdprConsent.consentString : '' - } - }, - at: 1, - tmax: 1000, - regs: { - ext: { - gdpr: utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies') ? Boolean(bidderRequest.gdprConsent.gdprApplies & 1) : false - } - } - }; - if (BRs[0].schain) { - bid.source = { - 'ext': { - 'schain': BRs[0].schain - } - } - } - return bid; - } - - function getFirstParam(key, validBidRequests) { - for (let i = 0; i < validBidRequests.length; i++) { - if (validBidRequests[i].params && validBidRequests[i].params[key]) { - return validBidRequests[i].params[key]; - } - } - } - - this.buildRequests = function (BRs, bidderRequest) { - let fallbackZoneId = getFirstParam('zoneId', BRs); - if (fallbackZoneId === undefined || BRs.length < 1) { - return []; - } - - var uri = 'https://bid306.rtbsrv.com/bidder/?bid=3mhdom&zoneId=' + fallbackZoneId; - - var fat = /(^v|(\.0)+$)/gi; - var prebidVersion = '$prebid.version$'; - uri += '&hbv=' + prebidVersion.replace(fat, '') + ',' + version.replace(fat, ''); - - var bidRequest = frameBid(BRs, bidderRequest); - if (!bidRequest.imp.length) { - return {}; - } - - return { - method: 'POST', - url: uri, - data: JSON.stringify(bidRequest) - }; - }; - - this.interpretResponse = function (serverResponse) { - let responses = serverResponse.body || []; - let bids = []; - let i = 0; - - if (responses.seatbid) { - let temp = []; - for (i = 0; i < responses.seatbid.length; i++) { - for (let j = 0; j < responses.seatbid[i].bid.length; j++) { - temp.push(responses.seatbid[i].bid[j]); - } - } - responses = temp; - } - - for (i = 0; i < responses.length; i++) { - let bid = responses[i]; - let bidRequest = slotsToBids[bid.impid]; - let bidResponse = { - requestId: bidRequest.id, - bidderCode: that.code, - cpm: parseFloat(bid.price), - width: bid.w, - height: bid.h, - creativeId: bid.crid, - currency: 'USD', - netRevenue: true, - ttl: 350 - }; - - if (bidRequest.mediaTypes && bidRequest.mediaTypes.video) { - bidResponse.vastUrl = bid.adm; - bidResponse.mediaType = 'video'; - bidResponse.ttl = 600; - } else { - bidResponse.ad = bid.adm; - } - bids.push(bidResponse); - } - - return bids; - }; -} - -export const spec = new ResultsmediaAdapter(); -registerBidder(spec); diff --git a/modules/resultsmediaBidAdapter.md b/modules/resultsmediaBidAdapter.md deleted file mode 100644 index 0b65264c8e4..00000000000 --- a/modules/resultsmediaBidAdapter.md +++ /dev/null @@ -1,47 +0,0 @@ -# Overview - -``` -Module Name: ResultsMedia (resultsmedia.com) Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid@resultsmedia.COM -``` - -# Description - -Prebid adapter for ResultsMedia RTB. Requires approval and account setup. - -# Test Parameters - -## Web -``` - var adUnits = [{ - code: 'banner-ad-div', - mediaTypes: { - banner: { - sizes: [ - [300, 200] // banner sizes - ], - } - }, - bids: [{ - bidder: 'resultsmedia', - params: { - zoneId: 9999 - } - }] - }, { - code: 'video-ad-player', - mediaTypes: { - video: { - context: 'instream', // or 'outstream' - playerSize: [640, 480] // video player size - } - }, - bids: [{ - bidder: 'resultsmedia', - params: { - zoneId: 9999 - } - }] - }]; -``` \ No newline at end of file diff --git a/modules/revcontentBidAdapter.js b/modules/revcontentBidAdapter.js deleted file mode 100644 index b429f94eae0..00000000000 --- a/modules/revcontentBidAdapter.js +++ /dev/null @@ -1,275 +0,0 @@ -// jshint esversion: 6, es3: false, node: true -'use strict'; - -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import * as utils from '../src/utils.js'; - -const BIDDER_CODE = 'revcontent'; -const NATIVE_PARAMS = { - title: { - id: 0, - name: 'title' - }, - image: { - id: 3, - type: 3, - name: 'img' - }, - sponsoredBy: { - id: 5, - name: 'data', - type: 1 - } -}; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: ['native'], - isBidRequestValid: function (bid) { - return (typeof bid.params.apiKey !== 'undefined' && typeof bid.params.userId !== 'undefined' && bid.hasOwnProperty('nativeParams')); - }, - buildRequests: (validBidRequests, bidderRequest) => { - const userId = validBidRequests[0].params.userId; - const widgetId = validBidRequests[0].params.widgetId; - const apiKey = validBidRequests[0].params.apiKey; - var domain = validBidRequests[0].params.domain; - var host = validBidRequests[0].params.endpoint; - - if (typeof host === 'undefined') { - host = 'trends.revcontent.com'; - } - - let serverRequests = []; - var refererInfo; - if (bidderRequest && bidderRequest.refererInfo) { - refererInfo = bidderRequest.refererInfo.referer; - } - - if (typeof domain === 'undefined') { - domain = extractHostname(refererInfo); - } - - var endpoint = 'https://' + host + '/rtb?apiKey=' + apiKey + '&userId=' + userId; - - if (!isNaN(widgetId) && widgetId > 0) { - endpoint = endpoint + '&widgetId=' + widgetId; - } - - let bidfloor = 0.1; - if (!isNaN(validBidRequests[0].params.bidfloor) && validBidRequests[0].params.bidfloor > 0) { - bidfloor = validBidRequests[0].params.bidfloor; - } - - const imp = validBidRequests.map((bid, id) => { - if (bid.hasOwnProperty('nativeParams')) { - const assets = utils._map(bid.nativeParams, (bidParams, key) => { - const props = NATIVE_PARAMS[key]; - const asset = { - required: bidParams.required & 1 - }; - if (props) { - asset.id = props.id; - let wmin, hmin, w, h; - let aRatios = bidParams.aspect_ratios; - - if (aRatios && aRatios[0]) { - aRatios = aRatios[0]; - wmin = aRatios.min_width || 0; - hmin = aRatios.ratio_height * wmin / aRatios.ratio_width | 0; - } - - asset[props.name] = { - len: bidParams.len, - type: props.type, - wmin, - hmin, - w, - h - }; - - return asset; - } - }).filter(Boolean); - - return { - id: id + 1, - tagid: bid.params.mid, - bidderRequestId: bid.bidderRequestId, - auctionId: bid.auctionId, - transactionId: bid.transactionId, - native: { - request: { - ver: '1.1', - context: 2, - contextsubtype: 21, - plcmttype: 1, - plcmtcnt: 1, - assets: assets - }, - ver: '1.1', - battr: [1, 3, 8, 11, 17] - }, - instl: 0, - bidfloor: bidfloor, - secure: '1' - }; - } - }); - - let data = { - id: bidderRequest.auctionId, - imp: imp, - site: { - id: widgetId, - domain: domain, - page: refererInfo, - cat: ['IAB17'], - publisher: { - id: userId, - domain: domain - } - }, - device: { - ua: navigator.userAgent, - language: 'en' - }, - user: { - id: 1 - }, - at: 2, - bcat: [ - 'IAB24', - 'IAB25', - 'IAB25-1', - 'IAB25-2', - 'IAB25-3', - 'IAB25-4', - 'IAB25-5', - 'IAB25-6', - 'IAB25-7', - 'IAB26', - 'IAB26-1', - 'IAB26-2', - 'IAB26-3', - 'IAB26-4' - ] - }; - serverRequests.push({ - method: 'POST', - options: { - contentType: 'application/json' - }, - url: endpoint, - data: JSON.stringify(data), - bid: validBidRequests - }); - - return serverRequests; - }, - interpretResponse: function (serverResponse, originalBidRequest) { - if (!serverResponse.body) { - return; - } - const seatbid = serverResponse.body.seatbid[0]; - const bidResponses = []; - - for (var x in seatbid.bid) { - let adm = JSON.parse(seatbid.bid[x]['adm']); - let ad = { - clickUrl: adm.link.url - }; - - adm.assets.forEach(asset => { - switch (asset.id) { - case 3: - ad['image'] = { - url: asset.img.url, - height: 1, - width: 1 - }; - break; - case 0: - ad['title'] = asset.title.text; - break; - case 5: - ad['sponsoredBy'] = asset.data.value; - break; - } - }); - - var size = originalBidRequest.bid[0].params.size; - - const bidResponse = { - bidder: BIDDER_CODE, - requestId: originalBidRequest.bid[0].bidId, - cpm: seatbid.bid[x]['price'], - creativeId: seatbid.bid[x]['adid'], - currency: 'USD', - netRevenue: true, - ttl: 360, - nurl: seatbid.bid[x]['nurl'], - bidderCode: 'revcontent', - mediaType: 'native', - native: ad, - width: size.width, - height: size.height, - ad: displayNative(ad, getTemplate(size, originalBidRequest.bid[0].params.template)) - }; - - bidResponses.push(bidResponse); - } - - return bidResponses; - }, - onBidWon: function (bid) { - utils.triggerPixel(bid.nurl); - return true; - } -}; - -registerBidder(spec); - -function displayNative(ad, template) { - template = template.replace(/{image}/g, ad['image']['url']); - template = template.replace(/{title}/g, ad['title']); - template = template.replace(/{clickUrl}/g, ad['clickUrl']); - template = template.replace(/{sponsoredBy}/g, ad['sponsoredBy']); - return template; -} - -function getTemplate(size, customTemplate) { - if (typeof (customTemplate) !== 'undefined' && customTemplate !== '') { - return customTemplate; - } - - if (size.width == 300 && size.height == 250) { - return '

{title}

SEE MORE
'; - } - - if (size.width == 728 && size.height == 90) { - return '

{title}

>
'; - } - - if (size.width == 300 && size.height == 600) { - return '

{title}

>
'; - } - - return ''; -} - -function extractHostname(url) { - if (typeof url == 'undefined' || url == null) { - return ''; - } - var hostname; - if (url.indexOf('//') > -1) { - hostname = url.split('/')[2]; - } else { - hostname = url.split('/')[0]; - } - - hostname = hostname.split(':')[0]; - hostname = hostname.split('?')[0]; - - return hostname; -} diff --git a/modules/revcontentBidAdapter.md b/modules/revcontentBidAdapter.md deleted file mode 100644 index d9f44e8036c..00000000000 --- a/modules/revcontentBidAdapter.md +++ /dev/null @@ -1,68 +0,0 @@ -# Overview - -Module Name: Revcontent Adapater -Maintainer: aziz@revcontent.com - -# Description - -Revcontent Adpater - -# Test Parameters -``` - /* - Supported sizes: - ---------------- - 300x250 - Medium rectangle - 728x90 - Leaderboard - 300x600 - Half page or large skyscraper - */ - var size = {width: 300, height: 250}; - - var adUnits = [{ - code: '/19968336/header-bid-tag-1', - sizes: sizes, - mediaTypes: { - native: { - native: { - image: { - required: false, - sizes: sizes[0] - }, - title: { - required: false, - len: 140 - }, - clickUrl: { - required: false - }, - sponsoredBy: { - id: 5, - name: 'data', - type: 1 - } - } - } - }, - bids: [{ - bidder: 'revcontent', - params: { - size: size, - - /* -> Modify this section <- */ - apiKey: '8a33sdfsdfdsfsdfssss544f8sdfsdfsdfd3b1c', // Required - userId: 69565, // Required - widgetId: 599995, // Optional - domain: 'test.com', // Optional - Default referral hostname - endpoint: 'trends.revcontent.com' // Optional - Debug - Set different endpoint - bidfloor: 0.1, // Optional - BidFloor - Default 0.1 - /* - Optional - Set different template. Template variables: - {clickUrl} -> Target Url - {image} -> Image URL - {title} -> Ad Title - */ - template: '

{title}

SEE MORE
' - } - }] - }]; -``` diff --git a/modules/rexrtbBidAdapter.md b/modules/rexrtbBidAdapter.md deleted file mode 100644 index 1cb937b0a3d..00000000000 --- a/modules/rexrtbBidAdapter.md +++ /dev/null @@ -1,32 +0,0 @@ -# Overview - -Module Name: REXRTB Bidder Adapter - -Module Type: Bidder Adapter - -Maintainer: tech@rexrtb.com - - -# Description - -Module that connects to REXRTB's demand source - -# Test Parameters -```javascript - var adUnits = [ - { - code: 'test-ad', - sizes: [[728, 98]], - bids: [ - { - bidder: 'rexrtb', - params: { - id: 89, - token: '658f11a5efbbce2f9be3f1f146fcbc22', - source: 'prebidtest' - } - } - ] - }, - ]; -``` \ No newline at end of file diff --git a/modules/rhythmoneBidAdapter.js b/modules/rhythmoneBidAdapter.js deleted file mode 100644 index fa090044f05..00000000000 --- a/modules/rhythmoneBidAdapter.js +++ /dev/null @@ -1,280 +0,0 @@ -'use strict'; - -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; - -function RhythmOneBidAdapter() { - this.code = 'rhythmone'; - this.supportedMediaTypes = [VIDEO, BANNER]; - - let SUPPORTED_VIDEO_PROTOCOLS = [2, 3, 5, 6]; - let SUPPORTED_VIDEO_MIMES = ['video/mp4']; - let SUPPORTED_VIDEO_PLAYBACK_METHODS = [1, 2, 3, 4]; - let SUPPORTED_VIDEO_DELIVERY = [1]; - let SUPPORTED_VIDEO_API = [1, 2, 5]; - let slotsToBids = {}; - let that = this; - let version = '2.1'; - - this.isBidRequestValid = function (bid) { - return !!(bid.params && bid.params.placementId); - }; - - this.getUserSyncs = function (syncOptions, responses, gdprConsent) { - return []; - }; - - function frameImp(BRs, bidderRequest) { - var impList = []; - var isSecure = 0; - if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.stack.length) { - // clever trick to get the protocol - var el = document.createElement('a'); - el.href = bidderRequest.refererInfo.stack[0]; - isSecure = (el.protocol == 'https:') ? 1 : 0; - } - for (var i = 0; i < BRs.length; i++) { - slotsToBids[BRs[i].adUnitCode] = BRs[i]; - var impObj = {}; - impObj.id = BRs[i].adUnitCode; - impObj.bidfloor = parseFloat(utils.deepAccess(BRs[i], 'params.floor')) || 0; - impObj.secure = isSecure; - - if (utils.deepAccess(BRs[i], 'mediaTypes.banner') || utils.deepAccess(BRs[i], 'mediaType') === 'banner') { - let banner = frameBanner(BRs[i]); - if (banner) { - impObj.banner = banner; - } - } - if (utils.deepAccess(BRs[i], 'mediaTypes.video') || utils.deepAccess(BRs[i], 'mediaType') === 'video') { - impObj.video = frameVideo(BRs[i]); - } - if (!(impObj.banner || impObj.video)) { - continue; - } - impObj.ext = frameExt(BRs[i]); - impList.push(impObj); - } - return impList; - } - - function frameSite(bidderRequest) { - var site = { - domain: '', - page: '', - ref: '' - } - if (bidderRequest && bidderRequest.refererInfo) { - var ri = bidderRequest.refererInfo; - site.ref = ri.referer; - - if (ri.stack.length) { - site.page = ri.stack[ri.stack.length - 1]; - - // clever trick to get the domain - var el = document.createElement('a'); - el.href = ri.stack[0]; - site.domain = el.hostname; - } - } - return site; - } - - function frameDevice() { - return { - ua: navigator.userAgent, - ip: '', // Empty Ip string is required, server gets the ip from HTTP header - dnt: utils.getDNT() ? 1 : 0, - } - } - - function getValidSizeSet(dimensionList) { - let w = parseInt(dimensionList[0]); - let h = parseInt(dimensionList[1]); - // clever check for NaN - if (! (w !== w || h !== h)) { // eslint-disable-line - return [w, h]; - } - return false; - } - - function frameBanner(adUnit) { - // adUnit.sizes is scheduled to be deprecated, continue its support but prefer adUnit.mediaTypes.banner - var sizeList = adUnit.sizes; - if (adUnit.mediaTypes && adUnit.mediaTypes.banner) { - sizeList = adUnit.mediaTypes.banner.sizes; - } - var sizeStringList = utils.parseSizesInput(sizeList); - var format = []; - sizeStringList.forEach(function(size) { - if (size) { - var dimensionList = getValidSizeSet(size.split('x')); - if (dimensionList) { - format.push({ - 'w': dimensionList[0], - 'h': dimensionList[1], - }); - } - } - }); - if (format.length) { - return { - 'format': format - }; - } - - return false; - } - - function frameVideo(bid) { - var size = []; - if (utils.deepAccess(bid, 'mediaTypes.video.playerSize')) { - var dimensionSet = bid.mediaTypes.video.playerSize; - if (utils.isArray(bid.mediaTypes.video.playerSize[0])) { - dimensionSet = bid.mediaTypes.video.playerSize[0]; - } - var validSize = getValidSizeSet(dimensionSet) - if (validSize) { - size = validSize; - } - } - return { - mimes: utils.deepAccess(bid, 'mediaTypes.video.mimes') || SUPPORTED_VIDEO_MIMES, - protocols: utils.deepAccess(bid, 'mediaTypes.video.protocols') || SUPPORTED_VIDEO_PROTOCOLS, - w: size[0], - h: size[1], - startdelay: utils.deepAccess(bid, 'mediaTypes.video.startdelay') || 0, - skip: utils.deepAccess(bid, 'mediaTypes.video.skip') || 0, - playbackmethod: utils.deepAccess(bid, 'mediaTypes.video.playbackmethod') || SUPPORTED_VIDEO_PLAYBACK_METHODS, - delivery: utils.deepAccess(bid, 'mediaTypes.video.delivery') || SUPPORTED_VIDEO_DELIVERY, - api: utils.deepAccess(bid, 'mediaTypes.video.api') || SUPPORTED_VIDEO_API, - } - } - - function frameExt(bid) { - return { - bidder: { - placementId: bid.params['placementId'], - zone: (bid.params && bid.params['zone']) ? bid.params['zone'] : '1r', - path: (bid.params && bid.params['path']) ? bid.params['path'] : 'mvo' - } - } - } - - function frameBid(BRs, bidderRequest) { - let bid = { - id: BRs[0].bidderRequestId, - imp: frameImp(BRs, bidderRequest), - site: frameSite(bidderRequest), - device: frameDevice(), - user: { - ext: { - consent: utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies') ? bidderRequest.gdprConsent.consentString : '' - } - }, - at: 1, - tmax: 1000, - regs: { - ext: { - gdpr: utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies') ? Boolean(bidderRequest.gdprConsent.gdprApplies & 1) : false - } - } - }; - if (BRs[0].schain) { - bid.source = { - 'ext': { - 'schain': BRs[0].schain - } - } - } - return bid; - } - - function getFirstParam(key, validBidRequests) { - for (let i = 0; i < validBidRequests.length; i++) { - if (validBidRequests[i].params && validBidRequests[i].params[key]) { - return validBidRequests[i].params[key]; - } - } - } - - this.buildRequests = function (BRs, bidderRequest) { - let fallbackPlacementId = getFirstParam('placementId', BRs); - if (fallbackPlacementId === undefined || BRs.length < 1) { - return []; - } - - var rmpUrl = getFirstParam('endpoint', BRs) || 'https://tag.1rx.io/rmp/{placementId}/0/{path}?z={zone}'; - var defaultZone = getFirstParam('zone', BRs) || '1r'; - var defaultPath = getFirstParam('path', BRs) || 'mvo'; - - rmpUrl = rmpUrl.replace(/\{placementId\}/i, fallbackPlacementId); - rmpUrl = rmpUrl.replace(/\{zone\}/i, defaultZone); - rmpUrl = rmpUrl.replace(/\{path\}/i, defaultPath); - - var fat = /(^v|(\.0)+$)/gi; - var prebidVersion = '$prebid.version$'; - rmpUrl += '&hbv=' + prebidVersion.replace(fat, '') + ',' + version.replace(fat, ''); - - var bidRequest = frameBid(BRs, bidderRequest); - if (!bidRequest.imp.length) { - return {}; - } - - return { - method: 'POST', - url: rmpUrl, - data: JSON.stringify(bidRequest) - }; - }; - - this.interpretResponse = function (serverResponse) { - let responses = serverResponse.body || []; - let bids = []; - let i = 0; - - if (responses.seatbid) { - let temp = []; - for (i = 0; i < responses.seatbid.length; i++) { - for (let j = 0; j < responses.seatbid[i].bid.length; j++) { - temp.push(responses.seatbid[i].bid[j]); - } - } - responses = temp; - } - - for (i = 0; i < responses.length; i++) { - let bid = responses[i]; - let bidRequest = slotsToBids[bid.impid]; - let bidResponse = { - requestId: bidRequest.bidId, - bidderCode: that.code, - cpm: parseFloat(bid.price), - width: bid.w, - height: bid.h, - meta: { - advertiserDomains: bid.adomain - }, - creativeId: bid.crid, - currency: 'USD', - netRevenue: true, - ttl: 350 - }; - - if (bidRequest.mediaTypes && bidRequest.mediaTypes.video) { - bidResponse.vastUrl = bid.nurl; - bidResponse.mediaType = 'video'; - bidResponse.ttl = 600; - } else { - bidResponse.ad = bid.adm; - } - bids.push(bidResponse); - } - - return bids; - }; -} - -export const spec = new RhythmOneBidAdapter(); -registerBidder(spec); diff --git a/modules/rhythmoneBidAdapter.md b/modules/rhythmoneBidAdapter.md deleted file mode 100644 index df657ed2651..00000000000 --- a/modules/rhythmoneBidAdapter.md +++ /dev/null @@ -1,60 +0,0 @@ -# Overview - -``` -Module Name: RhythmOne Bidder Adapter -Module Type: Bidder Adapter -Maintainer: support@rhythmone.com -``` - -# Description - -This module relays Prebid bids from Rhythm Exchange, RhythmOne's ad exchange. - -# Test Parameters - -```js -const adUnits = [{ - code: 'adSlot-1', - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [300, 600] - ] - } - }, - bids: [ - { - bidder: 'rhythmone', - params: - { - placementId: '80184', // REQUIRED - zone: '1r', // OPTIONAL - path: 'mvo', // OPTIONAL - endpoint: "//tag.1rx.io/rmp/80184/0/mvo?z=1r" // OPTIONAL, only required for testing. this api guarantees no 204 responses - } - } - ] -}, -{ - code: 'adSlot-2', - mediaTypes: { - video: { - context: "instream", - playerSize: [640, 480] - } - }, - bids: [ - { - bidder: 'rhythmone', - params: - { - placementId: '80184', // REQUIRED - zone: '1r', // OPTIONAL - path: 'mvo', // OPTIONAL - endpoint: "//tag.1rx.io/rmp/80184/0/mvo?z=1r" // OPTIONAL, only required for testing. this api guarantees no 204 responses - } - } - ] -}]; -``` diff --git a/modules/richaudienceBidAdapter.js b/modules/richaudienceBidAdapter.js deleted file mode 100755 index 5e2a5e1bff5..00000000000 --- a/modules/richaudienceBidAdapter.js +++ /dev/null @@ -1,308 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; -import { Renderer } from '../src/Renderer.js'; - -const BIDDER_CODE = 'richaudience'; -let REFERER = ''; - -export const spec = { - code: BIDDER_CODE, - gvlid: 108, - aliases: ['ra'], - supportedMediaTypes: [BANNER, VIDEO], - - /*** - * Determines whether or not the given bid request is valid - * - * @param {bidRequest} bid The bid params to validate. - * @returns {boolean} True if this is a valid bid, and false otherwise - */ - isBidRequestValid: function (bid) { - return !!(bid.params && bid.params.pid && bid.params.supplyType); - }, - /*** - * Build a server request from the list of valid BidRequests - * @param {validBidRequests} is an array of the valid bids - * @param {bidderRequest} bidder request object - * @returns {ServerRequest} Info describing the request to the server - */ - buildRequests: function (validBidRequests, bidderRequest) { - return validBidRequests.map(bid => { - var payload = { - bidfloor: raiGetFloor(bid, config), - ifa: bid.params.ifa, - pid: bid.params.pid, - supplyType: bid.params.supplyType, - currencyCode: config.getConfig('currency.adServerCurrency'), - auctionId: bid.auctionId, - bidId: bid.bidId, - BidRequestsCount: bid.bidRequestsCount, - bidder: bid.bidder, - bidderRequestId: bid.bidderRequestId, - tagId: bid.adUnitCode, - sizes: raiGetSizes(bid), - referer: (typeof bidderRequest.refererInfo.referer != 'undefined' ? encodeURIComponent(bidderRequest.refererInfo.referer) : null), - numIframes: (typeof bidderRequest.refererInfo.numIframes != 'undefined' ? bidderRequest.refererInfo.numIframes : null), - transactionId: bid.transactionId, - timeout: config.getConfig('bidderTimeout'), - user: raiSetEids(bid), - demand: raiGetDemandType(bid), - videoData: raiGetVideoInfo(bid), - scr_rsl: raiGetResolution(), - cpuc: (typeof window.navigator != 'undefined' ? window.navigator.hardwareConcurrency : null), - kws: (!utils.isEmpty(bid.params.keywords) ? bid.params.keywords : null) - }; - - REFERER = (typeof bidderRequest.refererInfo.referer != 'undefined' ? encodeURIComponent(bidderRequest.refererInfo.referer) : null) - - payload.gdpr_consent = ''; - payload.gdpr = null; - - if (bidderRequest && bidderRequest.gdprConsent) { - payload.gdpr_consent = bidderRequest.gdprConsent.consentString; - payload.gdpr = bidderRequest.gdprConsent.gdprApplies; - } - - var payloadString = JSON.stringify(payload); - - var endpoint = 'https://shb.richaudience.com/hb/'; - - return { - method: 'POST', - url: endpoint, - data: payloadString, - }; - }); - }, - /*** - * Read the response from the server and build a list of bids - * @param {serverResponse} Response from the server. - * @param {bidRequest} Bid request object - * @returns {bidResponses} Array of bids which were nested inside the server - */ - interpretResponse: function (serverResponse, bidRequest) { - const bidResponses = []; - // try catch - var response = serverResponse.body; - if (response) { - var bidResponse = { - requestId: JSON.parse(bidRequest.data).bidId, - cpm: response.cpm, - width: response.width, - height: response.height, - creativeId: response.creative_id, - mediaType: response.media_type, - netRevenue: response.netRevenue, - currency: response.currency, - ttl: response.ttl, - dealId: response.dealId, - }; - - if (response.media_type === 'video') { - bidResponse.vastXml = response.vastXML; - try { - if (bidResponse.vastXml != null) { - if (JSON.parse(bidRequest.data).videoData.format == 'outstream' || JSON.parse(bidRequest.data).videoData.format == 'banner') { - bidResponse.renderer = Renderer.install({ - id: bidRequest.bidId, - adunitcode: bidRequest.tagId, - loaded: false, - config: response.media_type, - url: 'https://cdn3.richaudience.com/prebidVideo/player.js' - }); - } - bidResponse.renderer.setRender(renderer); - } - } catch (e) { - bidResponse.ad = response.adm; - } - } else { - bidResponse.ad = response.adm; - } - - bidResponses.push(bidResponse); - } - return bidResponses - }, - /*** - * User Syncs - * - * @param {syncOptions} Publisher prebid configuration - * @param {serverResponses} Response from the server - * @param {gdprConsent} GPDR consent object - * @returns {Array} - */ - getUserSyncs: function (syncOptions, serverResponses, gdprConsent) { - const syncs = []; - - var rand = Math.floor(Math.random() * 9999999999); - var syncUrl = ''; - var consent = ''; - - var raiSync = {}; - - raiSync = raiGetSyncInclude(config); - - if (gdprConsent && typeof gdprConsent.consentString === 'string' && typeof gdprConsent.consentString != 'undefined') { - consent = `consentString=${gdprConsent.consentString}` - } - - if (syncOptions.iframeEnabled && raiSync.raiIframe != 'exclude') { - syncUrl = 'https://sync.richaudience.com/dcf3528a0b8aa83634892d50e91c306e/?ord=' + rand - if (consent != '') { - syncUrl += `&${consent}` - } - syncs.push({ - type: 'iframe', - url: syncUrl - }); - } - - if (syncOptions.pixelEnabled && REFERER != null && syncs.length == 0 && raiSync.raiImage != 'exclude') { - syncUrl = `https://sync.richaudience.com/bf7c142f4339da0278e83698a02b0854/?referrer=${REFERER}`; - if (consent != '') { - syncUrl += `&${consent}` - } - syncs.push({ - type: 'image', - url: syncUrl - }); - } - return syncs - }, -}; - -registerBidder(spec); - -function raiGetSizes(bid) { - let raiNewSizes; - if (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) { - raiNewSizes = bid.mediaTypes.banner.sizes - } - if (raiNewSizes != null) { - return raiNewSizes.map(size => ({ - w: size[0], - h: size[1] - })); - } -} - -function raiGetDemandType(bid) { - let raiFormat = 'display'; - if (bid.mediaTypes != undefined) { - if (bid.mediaTypes.video != undefined) { - raiFormat = 'video'; - } - } - return raiFormat; -} - -function raiGetVideoInfo(bid) { - let videoData; - if (raiGetDemandType(bid) == 'video') { - videoData = { - format: bid.mediaTypes.video.context, - playerSize: bid.mediaTypes.video.playerSize, - mimes: bid.mediaTypes.video.mimes - }; - } else { - videoData = { - format: 'banner' - } - } - return videoData; -} - -function raiSetEids(bid) { - let eids = []; - - if (bid && bid.userId) { - raiSetUserId(bid, eids, 'id5-sync.com', utils.deepAccess(bid, `userId.id5id.uid`)); - raiSetUserId(bid, eids, 'pubcommon', utils.deepAccess(bid, `userId.pubcid`)); - raiSetUserId(bid, eids, 'criteo.com', utils.deepAccess(bid, `userId.criteoId`)); - raiSetUserId(bid, eids, 'liveramp.com', utils.deepAccess(bid, `userId.idl_env`)); - raiSetUserId(bid, eids, 'liveintent.com', utils.deepAccess(bid, `userId.lipb.lipbid`)); - raiSetUserId(bid, eids, 'adserver.org', utils.deepAccess(bid, `userId.tdid`)); - } - - return eids; -} - -function raiSetUserId(bid, eids, source, value) { - if (utils.isStr(value)) { - eids.push({ - userId: value, - source: source - }); - } -} - -function renderer(bid) { - bid.renderer.push(() => { - renderAd(bid) - }); -} - -function renderAd(bid) { - let raOutstreamHBPassback = `${bid.vastXml}`; - let raPlayerHB = { - config: bid.params[0].player != undefined ? { - end: bid.params[0].player.end != null ? bid.params[0].player.end : 'close', - init: bid.params[0].player.init != null ? bid.params[0].player.init : 'close', - skin: bid.params[0].player.skin != null ? bid.params[0].player.skin : 'light', - } : {end: 'close', init: 'close', skin: 'light'}, - pid: bid.params[0].pid, - adUnit: bid.adUnitCode - }; - - window.raParams(raPlayerHB, raOutstreamHBPassback, true); -} - -function raiGetResolution() { - let resolution = ''; - if (typeof window.screen != 'undefined') { - resolution = window.screen.width + 'x' + window.screen.height; - } - return resolution; -} - -function raiGetSyncInclude(config) { - try { - let raConfig = null; - let raiSync = {}; - if (config.getConfig('userSync').filterSettings != null && typeof config.getConfig('userSync').filterSettings != 'undefined') { - raConfig = config.getConfig('userSync').filterSettings - if (raConfig.iframe != null && typeof raConfig.iframe != 'undefined') { - raiSync.raiIframe = raConfig.iframe.bidders == 'richaudience' || raConfig.iframe.bidders == '*' ? raConfig.iframe.filter : 'exclude'; - } - if (raConfig.image != null && typeof raConfig.image != 'undefined') { - raiSync.raiImage = raConfig.image.bidders == 'richaudience' || raConfig.image.bidders == '*' ? raConfig.image.filter : 'exclude'; - } - } - return raiSync; - } catch (e) { - return null; - } -} - -function raiGetFloor(bid, config) { - try { - let raiFloor; - if (bid.params.bidfloor != null) { - raiFloor = bid.params.bidfloor; - } else if (typeof bid.getFloor == 'function') { - let floorSpec = bid.getFloor({ - currency: config.getConfig('currency.adServerCurrency'), - mediaType: bid.mediaType.banner ? 'banner' : 'video', - size: '*' - }) - - raiFloor = floorSpec.floor; - } - return raiFloor - } catch (e) { - return 0 - } -} diff --git a/modules/richaudienceBidAdapter.md b/modules/richaudienceBidAdapter.md deleted file mode 100644 index f888117b166..00000000000 --- a/modules/richaudienceBidAdapter.md +++ /dev/null @@ -1,134 +0,0 @@ -# Overview - -``` -Module Name: Rich Audience Bidder Adapter -Module Type: Bidder Adapter -Maintainer: cert@richaudience.com -``` - -# Description - -Connects to Rich Audience Marketplace for bids. This adapter supports Display and Video. - -The Rich Audience adapter requires setup and approval from the Rich Audience team. -Please reach out to your account manager for more information. - -# Test Parameters - -## Web - DISPLAY -``` - var adUnits = [ - { - code: 'test-div1', - sizes: [[300, 250],[300, 600]], - bids: [{ - bidder: 'richaudience', - params: { - "pid":"ADb1f40rmi", - "supplyType":"site", - "bidfloor":0.70, - } - }] - }, - { - code: 'test-div2', - sizes: [[728, 90],[970, 250]], - bids: [{ - bidder: 'richaudience', - params: { - "pid":"ADb1f40rmo", - "supplyType":"site", - "bidfloor":0.40, - "keywords": "key1=value1;key2=value2;key3=value3;" - } - }] - } - ]; -``` - -## Web - VIDEO -``` - var adUnits = [{ - code: 'video1', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [640, 480] - } - }, - - bids: [{ - bidder: 'richaudience', - params: { - pid: 'OjUW9KhuQV', - supplyType: 'site', - player: { - init: "open", - end: "close", - skin: "light" - } - } - }] - - }]; -``` - -## In-app -``` - var adUnits = [ - { - code: 'test-div1', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - bids: [{ - bidder: 'richaudience', - params: { - "pid":"ADb1f40rmi", - "supplyType":"app", - "ifa":"AAAAAAAAA-BBBB-CCCC-1111-222222220000", - "bidfloor":0.70, - } - }] - }, - { - code: 'test-div2', - sizes: [[728, 90],[970, 250]], - }, - bids: [{ - bidder: 'richaudience', - params: { - "pid":"ADb1f40rmo", - "supplyType":"app", - "ifa":"AAAAAAAAA-BBBB-CCCC-1111-222222220000", - "bidfloor":0.40, - } - }] - } - ]; -``` - -# Configuration -Add the following code to enable user syncing. By default, Prebid.js version 0.34.0+ turns off user syncing through iframes. -Rich Audience strongly recommends enabling user syncing through iframes. Be sure to call `pbjs.setConfig()` only once. - -```javascript -pbjs.setConfig({ - userSync: { - filterSettings: { - iframe: { - bidders: '*', - filter: 'include' - }, - image: { - bidders: '*', - filter: 'include' - } - }, - syncsPerBidder: 3, - syncDelay: 6000, - } -}); -``` diff --git a/modules/riseBidAdapter.js b/modules/riseBidAdapter.js deleted file mode 100644 index e3265ad5d3e..00000000000 --- a/modules/riseBidAdapter.js +++ /dev/null @@ -1,251 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import * as utils from '../src/utils.js'; -import {VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; - -const SUPPORTED_AD_TYPES = [VIDEO]; -const BIDDER_CODE = 'rise'; -const BIDDER_VERSION = '4.0.0'; -const TTL = 360; -const SELLER_ENDPOINT = 'https://hb.yellowblue.io/'; -const MODES = { - PRODUCTION: 'hb', - TEST: 'hb-test' -} -const SUPPORTED_SYNC_METHODS = { - IFRAME: 'iframe', - PIXEL: 'pixel' -} - -export const spec = { - code: BIDDER_CODE, - version: BIDDER_VERSION, - supportedMediaTypes: SUPPORTED_AD_TYPES, - isBidRequestValid: function(bidRequest) { - return !!(bidRequest.params.org); - }, - buildRequests: function (bidRequests, bidderRequest) { - if (bidRequests.length === 0) { - return []; - } - - const requests = []; - - bidRequests.forEach(bid => { - requests.push(buildVideoRequest(bid, bidderRequest)); - }); - - return requests; - }, - interpretResponse: function({body}) { - const bidResponses = []; - - const bidResponse = { - requestId: body.requestId, - cpm: body.cpm, - width: body.width, - height: body.height, - creativeId: body.requestId, - currency: body.currency, - netRevenue: body.netRevenue, - ttl: body.ttl || TTL, - vastXml: body.vastXml, - mediaType: VIDEO - }; - - bidResponses.push(bidResponse); - - return bidResponses; - }, - getUserSyncs: function(syncOptions, serverResponses) { - const syncs = []; - for (const response of serverResponses) { - if (syncOptions.iframeEnabled && response.body.userSyncURL) { - syncs.push({ - type: 'iframe', - url: response.body.userSyncURL - }); - } - if (syncOptions.pixelEnabled && utils.isArray(response.body.userSyncPixels)) { - const pixels = response.body.userSyncPixels.map(pixel => { - return { - type: 'image', - url: pixel - } - }) - syncs.push(...pixels) - } - } - return syncs; - } -}; - -registerBidder(spec); - -/** - * Build the video request - * @param bid {bid} - * @param bidderRequest {bidderRequest} - * @returns {Object} - */ -function buildVideoRequest(bid, bidderRequest) { - const sellerParams = generateParameters(bid, bidderRequest); - const {params} = bid; - return { - method: 'GET', - url: getEndpoint(params.testMode), - data: sellerParams - }; -} - -/** - * Get the the ad size from the bid - * @param bid {bid} - * @returns {Array} - */ -function getSizes(bid) { - if (utils.deepAccess(bid, 'mediaTypes.video.sizes')) { - return bid.mediaTypes.video.sizes[0]; - } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) { - return bid.sizes[0]; - } - return []; -} - -/** - * Get schain string value - * @param schainObject {Object} - * @returns {string} - */ -function getSupplyChain(schainObject) { - if (utils.isEmpty(schainObject)) { - return ''; - } - let scStr = `${schainObject.ver},${schainObject.complete}`; - schainObject.nodes.forEach((node) => { - scStr += '!'; - scStr += `${getEncodedValIfNotEmpty(node.asi)},`; - scStr += `${getEncodedValIfNotEmpty(node.sid)},`; - scStr += `${getEncodedValIfNotEmpty(node.hp)},`; - scStr += `${getEncodedValIfNotEmpty(node.rid)},`; - scStr += `${getEncodedValIfNotEmpty(node.name)},`; - scStr += `${getEncodedValIfNotEmpty(node.domain)}`; - }); - return scStr; -} - -/** - * Get encoded node value - * @param val {string} - * @returns {string} - */ -function getEncodedValIfNotEmpty(val) { - return !utils.isEmpty(val) ? encodeURIComponent(val) : ''; -} - -/** - * Get preferred user-sync method based on publisher configuration - * @param bidderCode {string} - * @returns {string} - */ -function getAllowedSyncMethod(filterSettings, bidderCode) { - const iframeConfigsToCheck = ['all', 'iframe']; - const pixelConfigToCheck = 'image'; - if (filterSettings && iframeConfigsToCheck.some(config => isSyncMethodAllowed(filterSettings[config], bidderCode))) { - return SUPPORTED_SYNC_METHODS.IFRAME; - } - if (!filterSettings || !filterSettings[pixelConfigToCheck] || isSyncMethodAllowed(filterSettings[pixelConfigToCheck], bidderCode)) { - return SUPPORTED_SYNC_METHODS.PIXEL; - } -} - -/** - * Check if sync rule is supported - * @param syncRule {Object} - * @param bidderCode {string} - * @returns {boolean} - */ -function isSyncMethodAllowed(syncRule, bidderCode) { - if (!syncRule) { - return false; - } - const isInclude = syncRule.filter === 'include'; - const bidders = utils.isArray(syncRule.bidders) ? syncRule.bidders : [bidderCode]; - return isInclude && utils.contains(bidders, bidderCode); -} - -/** - * Get the seller endpoint - * @param testMode {boolean} - * @returns {string} - */ -function getEndpoint(testMode) { - return testMode - ? SELLER_ENDPOINT + MODES.TEST - : SELLER_ENDPOINT + MODES.PRODUCTION; -} - -/** - * Generate query parameters for the request - * @param bid {bid} - * @param bidderRequest {bidderRequest} - * @returns {Object} - */ -function generateParameters(bid, bidderRequest) { - const timeout = config.getConfig('bidderTimeout'); - const { syncEnabled, filterSettings } = config.getConfig('userSync') || {}; - const [ width, height ] = getSizes(bid); - const { params } = bid; - const { bidderCode } = bidderRequest; - const domain = window.location.hostname; - - const requestParams = { - auction_start: utils.timestamp(), - ad_unit_code: utils.getBidIdParameter('adUnitCode', bid), - tmax: timeout, - width: width, - height: height, - publisher_id: params.org, - floor_price: params.floorPrice, - ua: navigator.userAgent, - bid_id: utils.getBidIdParameter('bidId', bid), - bidder_request_id: utils.getBidIdParameter('bidderRequestId', bid), - transaction_id: utils.getBidIdParameter('transactionId', bid), - session_id: params.sessionId || utils.getBidIdParameter('auctionId', bid), - is_wrapper: !!params.isWrapper, - publisher_name: domain, - site_domain: domain, - bidder_version: BIDDER_VERSION - }; - - if (syncEnabled) { - const allowedSyncMethod = getAllowedSyncMethod(filterSettings, bidderCode); - if (allowedSyncMethod) { - requestParams.cs_method = allowedSyncMethod; - } - } - - if (bidderRequest.uspConsent) { - requestParams.us_privacy = bidderRequest.uspConsent; - } - - if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) { - requestParams.gdpr = bidderRequest.gdprConsent.gdprApplies; - requestParams.gdpr_consent = bidderRequest.gdprConsent.consentString; - } - - if (params.ifa) { - requestParams.ifa = params.ifa; - } - - if (bid.schain) { - requestParams.schain = getSupplyChain(bid.schain); - } - - if (bidderRequest && bidderRequest.refererInfo) { - requestParams.referrer = utils.deepAccess(bidderRequest, 'refererInfo.referer'); - requestParams.page_url = config.getConfig('pageUrl') || utils.deepAccess(window, 'location.href'); - } - - return requestParams; -} diff --git a/modules/riseBidAdapter.md b/modules/riseBidAdapter.md deleted file mode 100644 index 67eeab18226..00000000000 --- a/modules/riseBidAdapter.md +++ /dev/null @@ -1,51 +0,0 @@ -#Overview - -Module Name: Rise Bidder Adapter - -Module Type: Bidder Adapter - -Maintainer: prebid-rise-engage@risecodes.com - - -# Description - -Module that connects to Rise's demand sources. - -The Rise adapter requires setup and approval from the Rise. Please reach out to prebid-rise-engage@risecodes.com to create an Rise account. - -The adapter supports Video(instream). For the integration, Rise returns content as vastXML and requires the publisher to define the cache url in config passed to Prebid for it to be valid in the auction. - -# Bid Parameters -## Video - -| Name | Scope | Type | Description | Example -| ---- | ----- | ---- | ----------- | ------- -| `org` | required | String | Rise publisher Id provided by your Rise representative | "56f91cd4d3e3660002000033" -| `floorPrice` | optional | Number | Minimum price in USD. Misuse of this parameter can impact revenue | 2.00 -| `ifa` | optional | String | The ID for advertisers (also referred to as "IDFA") | "XXX-XXX" -| `testMode` | optional | Boolean | This activates the test mode | false - -# Test Parameters -```javascript -var adUnits = [ - { - code: 'dfp-video-div', - sizes: [[640, 480]], - mediaTypes: { - video: { - playerSize: [[640, 480]], - context: 'instream' - } - }, - bids: [{ - bidder: 'rise', - params: { - org: '56f91cd4d3e3660002000033', // Required - floorPrice: 2.00, // Optional - ifa: 'XXX-XXX', // Optional - testMode: false // Optional - } - }] - } - ]; -``` diff --git a/modules/rivrAnalyticsAdapter.js b/modules/rivrAnalyticsAdapter.js deleted file mode 100644 index 279b1b13051..00000000000 --- a/modules/rivrAnalyticsAdapter.js +++ /dev/null @@ -1,33 +0,0 @@ -import {ajax} from '../src/ajax.js'; -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -import * as utils from '../src/utils.js'; - -const analyticsType = 'endpoint'; - -let 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); - window.rivraddon.analytics.trackPbjsEvent({ eventType, args }); - } - } -}); - -// save the base class function -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: $$PREBID_GLOBAL$$}); - rivrAnalytics.originEnableAnalytics(config); - } -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: rivrAnalytics, - code: 'rivr' -}); - -export default rivrAnalytics; diff --git a/modules/rivrAnalyticsAdapter.md b/modules/rivrAnalyticsAdapter.md deleted file mode 100644 index 787034e362e..00000000000 --- a/modules/rivrAnalyticsAdapter.md +++ /dev/null @@ -1,13 +0,0 @@ -# Overview - -Module Name: Rivr Analytics Adapter - -Module Type: Analytics Adapter - -Maintainer: rnd@simplaex.com - -# Description - -Analytics adapter for www.rivr.ai. - -Contact support@simplaex.com for information and support. diff --git a/modules/rockyouBidAdapter.md b/modules/rockyouBidAdapter.md deleted file mode 100644 index 1c6d2708b99..00000000000 --- a/modules/rockyouBidAdapter.md +++ /dev/null @@ -1,58 +0,0 @@ -# Overview - -``` -Module Name: RockYou Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid.adapter@rockyou.com -``` - -# Description - -Connects to the RockYou exchange for bids. - -The RockYou bid adapter supports Banner and Video. - -For publishers who wish to be set up on the RockYou Ad Network, please contact -publishers@rockyou.com. - -RockYou user syncing requires the `userSync.iframeEnabled` property be set to `true`. - -# Test PARAMETERS -``` -var adUnits = [ - - // Banner adUnit - { - code: 'banner-div', - mediaTypes: { - banner: { - sizes: [[720, 480]] - } - }, - - bids: [{ - bidder: 'rockyou', - params: { - placementId: '4954' - } - }] - }, - - // Video (outstream) - { - code: 'video-outstream', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [720, 480] - } - }, - bids: [{ - bidder: 'rockyou', - params: { - placementId: '4957' - } - }] - } -] -``` diff --git a/modules/roxotAnalyticsAdapter.js b/modules/roxotAnalyticsAdapter.js deleted file mode 100644 index b6857d69f45..00000000000 --- a/modules/roxotAnalyticsAdapter.js +++ /dev/null @@ -1,510 +0,0 @@ -import adapter from '../src/AnalyticsAdapter.js'; -import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import {ajaxBuilder} from '../src/ajax.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const storage = getStorageManager(); - -const utils = require('../src/utils.js'); -let ajax = ajaxBuilder(0); - -const DEFAULT_EVENT_URL = 'pa.rxthdr.com/v3'; -const DEFAULT_SERVER_CONFIG_URL = 'pa.rxthdr.com/v3'; -const analyticsType = 'endpoint'; - -const { - EVENTS: { - AUCTION_INIT, - AUCTION_END, - BID_REQUESTED, - BID_ADJUSTMENT, - BIDDER_DONE, - BID_WON - } -} = CONSTANTS; - -const AUCTION_STATUS = { - 'RUNNING': 'running', - 'FINISHED': 'finished' -}; -const BIDDER_STATUS = { - 'REQUESTED': 'requested', - 'BID': 'bid', - 'NO_BID': 'noBid', - 'TIMEOUT': 'timeout' -}; -const ROXOT_EVENTS = { - 'AUCTION': 'a', - 'IMPRESSION': 'i', - 'BID_AFTER_TIMEOUT': 'bat' -}; - -let initOptions = {}; - -let localStoragePrefix = 'roxot_analytics_'; - -let utmTags = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']; -let utmTtlKey = 'utm_ttl'; -let utmTtl = 60 * 60 * 1000; - -let isNewKey = 'is_new_flag'; -let isNewTtl = 60 * 60 * 1000; - -let auctionCache = {}; -let auctionTtl = 60 * 60 * 1000; - -let sendEventCache = []; -let sendEventTimeoutId = null; -let sendEventTimeoutTime = 1000; - -function detectDevice() { - if ((/ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle/i.test(navigator.userAgent.toLowerCase()))) { - return 'tablet'; - } - if ((/iphone|ipod|android|blackberry|opera|mini|windows\sce|palm|smartphone|iemobile/i.test(navigator.userAgent.toLowerCase()))) { - return 'mobile'; - } - return 'desktop'; -} - -function checkIsNewFlag() { - let key = buildLocalStorageKey(isNewKey); - let lastUpdate = Number(storage.getDataFromLocalStorage(key)); - storage.setDataInLocalStorage(key, Date.now()); - return Date.now() - lastUpdate > isNewTtl; -} - -function updateUtmTimeout() { - storage.setDataInLocalStorage(buildLocalStorageKey(utmTtlKey), Date.now()); -} - -function isUtmTimeoutExpired() { - let utmTimestamp = storage.getDataFromLocalStorage(buildLocalStorageKey(utmTtlKey)); - return (Date.now() - utmTimestamp) > utmTtl; -} - -function buildLocalStorageKey(key) { - return localStoragePrefix.concat(key); -} - -function isSupportedAdUnit(adUnit) { - if (!initOptions.adUnits.length) { - return true; - } - - return includes(initOptions.adUnits, adUnit); -} - -function deleteOldAuctions() { - for (let auctionId in auctionCache) { - let auction = auctionCache[auctionId]; - if (Date.now() - auction.start > auctionTtl) { - delete auctionCache[auctionId]; - } - } -} - -function buildAuctionEntity(args) { - return { - 'id': args.auctionId, - 'start': args.timestamp, - 'timeout': args.timeout, - 'adUnits': {} - }; -} - -function extractAdUnitCode(args) { - return args.adUnitCode.toLowerCase(); -} - -function extractBidder(args) { - return args.bidder.toLowerCase(); -} - -function buildAdUnitAuctionEntity(auction, bidRequest) { - return { - 'adUnit': extractAdUnitCode(bidRequest), - 'start': auction.start, - 'timeout': auction.timeout, - 'finish': 0, - 'status': AUCTION_STATUS.RUNNING, - 'bidders': {} - }; -} - -function buildBidderRequest(auction, bidRequest) { - return { - 'bidder': extractBidder(bidRequest), - 'isAfterTimeout': auction.status === AUCTION_STATUS.FINISHED ? 1 : 0, - 'start': bidRequest.startTime || Date.now(), - 'finish': 0, - 'status': BIDDER_STATUS.REQUESTED, - 'cpm': -1, - 'size': { - 'width': 0, - 'height': 0 - }, - 'mediaType': '-', - 'source': bidRequest.source || 'client' - }; -} - -function buildBidAfterTimeout(adUnitAuction, args) { - return { - 'auction': utils.deepClone(adUnitAuction), - 'adUnit': extractAdUnitCode(args), - 'bidder': extractBidder(args), - 'cpm': args.cpm, - 'size': { - 'width': args.width || 0, - 'height': args.height || 0 - }, - 'mediaType': args.mediaType || '-', - 'start': args.requestTimestamp, - 'finish': args.responseTimestamp, - }; -} - -function buildImpression(adUnitAuction, args) { - return { - 'isNew': checkIsNewFlag() ? 1 : 0, - 'auction': utils.deepClone(adUnitAuction), - 'adUnit': extractAdUnitCode(args), - 'bidder': extractBidder(args), - 'cpm': args.cpm, - 'size': { - 'width': args.width, - 'height': args.height - }, - 'mediaType': args.mediaType, - 'source': args.source || 'client' - }; -} - -function handleAuctionInit(args) { - auctionCache[args.auctionId] = buildAuctionEntity(args); - deleteOldAuctions(); -} - -function handleBidRequested(args) { - let auction = auctionCache[args.auctionId]; - args.bids.forEach(function (bidRequest) { - let adUnitCode = extractAdUnitCode(bidRequest); - let bidder = extractBidder(bidRequest); - if (!isSupportedAdUnit(adUnitCode)) { - return; - } - auction['adUnits'][adUnitCode] = auction['adUnits'][adUnitCode] || buildAdUnitAuctionEntity(auction, bidRequest); - let adUnitAuction = auction['adUnits'][adUnitCode]; - adUnitAuction['bidders'][bidder] = adUnitAuction['bidders'][bidder] || buildBidderRequest(auction, bidRequest); - }); -} - -function handleBidAdjustment(args) { - let adUnitCode = extractAdUnitCode(args); - let bidder = extractBidder(args); - if (!isSupportedAdUnit(adUnitCode)) { - return; - } - - let adUnitAuction = auctionCache[args.auctionId]['adUnits'][adUnitCode]; - if (adUnitAuction.status === AUCTION_STATUS.FINISHED) { - handleBidAfterTimeout(adUnitAuction, args); - return; - } - - let bidderRequest = adUnitAuction['bidders'][bidder]; - if (bidderRequest.cpm < args.cpm) { - bidderRequest.cpm = args.cpm; - bidderRequest.finish = args.responseTimestamp; - bidderRequest.status = args.cpm === 0 ? BIDDER_STATUS.NO_BID : BIDDER_STATUS.BID; - bidderRequest.size.width = args.width || 0; - bidderRequest.size.height = args.height || 0; - bidderRequest.mediaType = args.mediaType || '-'; - bidderRequest.source = args.source || 'client'; - } -} - -function handleBidAfterTimeout(adUnitAuction, args) { - let bidder = extractBidder(args); - let bidderRequest = adUnitAuction['bidders'][bidder]; - let bidAfterTimeout = buildBidAfterTimeout(adUnitAuction, args); - - if (bidAfterTimeout.cpm > bidderRequest.cpm) { - bidderRequest.cpm = bidAfterTimeout.cpm; - bidderRequest.isAfterTimeout = 1; - bidderRequest.finish = bidAfterTimeout.finish; - bidderRequest.size = bidAfterTimeout.size; - bidderRequest.mediaType = bidAfterTimeout.mediaType; - bidderRequest.status = bidAfterTimeout.cpm === 0 ? BIDDER_STATUS.NO_BID : BIDDER_STATUS.BID; - } - - registerEvent(ROXOT_EVENTS.BID_AFTER_TIMEOUT, 'Bid After Timeout', bidAfterTimeout); -} - -function handleBidderDone(args) { - let auction = auctionCache[args.auctionId]; - - args.bids.forEach(function (bidDone) { - let adUnitCode = extractAdUnitCode(bidDone); - let bidder = extractBidder(bidDone); - if (!isSupportedAdUnit(adUnitCode)) { - return; - } - - let adUnitAuction = auction['adUnits'][adUnitCode]; - if (adUnitAuction.status === AUCTION_STATUS.FINISHED) { - return; - } - let bidderRequest = adUnitAuction['bidders'][bidder]; - if (bidderRequest.status !== BIDDER_STATUS.REQUESTED) { - return; - } - - bidderRequest.finish = Date.now(); - bidderRequest.status = BIDDER_STATUS.NO_BID; - bidderRequest.cpm = 0; - }); -} - -function handleAuctionEnd(args) { - let auction = auctionCache[args.auctionId]; - if (!Object.keys(auction.adUnits).length) { - delete auctionCache[args.auctionId]; - } - - let finish = Date.now(); - auction.finish = finish; - for (let adUnit in auction.adUnits) { - let adUnitAuction = auction.adUnits[adUnit]; - adUnitAuction.finish = finish; - adUnitAuction.status = AUCTION_STATUS.FINISHED; - - for (let bidder in adUnitAuction.bidders) { - let bidderRequest = adUnitAuction.bidders[bidder]; - if (bidderRequest.status !== BIDDER_STATUS.REQUESTED) { - continue; - } - - bidderRequest.status = BIDDER_STATUS.TIMEOUT; - } - } - - registerEvent(ROXOT_EVENTS.AUCTION, 'Auction', auction); -} - -function handleBidWon(args) { - let adUnitCode = extractAdUnitCode(args); - if (!isSupportedAdUnit(adUnitCode)) { - return; - } - let adUnitAuction = auctionCache[args.auctionId]['adUnits'][adUnitCode]; - let impression = buildImpression(adUnitAuction, args); - registerEvent(ROXOT_EVENTS.IMPRESSION, 'Bid won', impression); -} - -function handleOtherEvents(eventType, args) { - registerEvent(eventType, eventType, args); -} - -let roxotAdapter = Object.assign(adapter({url: DEFAULT_EVENT_URL, analyticsType}), { - track({eventType, args}) { - switch (eventType) { - case AUCTION_INIT: - handleAuctionInit(args); - break; - case BID_REQUESTED: - handleBidRequested(args); - break; - case BID_ADJUSTMENT: - handleBidAdjustment(args); - break; - case BIDDER_DONE: - handleBidderDone(args); - break; - case AUCTION_END: - handleAuctionEnd(args); - break; - case BID_WON: - handleBidWon(args); - break; - default: - handleOtherEvents(eventType, args); - break; - } - }, - -}); - -roxotAdapter.originEnableAnalytics = roxotAdapter.enableAnalytics; - -roxotAdapter.enableAnalytics = function (config) { - if (this.initConfig(config)) { - logInfo('Analytics adapter enabled', initOptions); - roxotAdapter.originEnableAnalytics(config); - } -}; - -roxotAdapter.buildUtmTagData = function () { - let utmTagData = {}; - let utmTagsDetected = false; - utmTags.forEach(function (utmTagKey) { - let utmTagValue = utils.getParameterByName(utmTagKey); - if (utmTagValue !== '') { - utmTagsDetected = true; - } - utmTagData[utmTagKey] = utmTagValue; - }); - utmTags.forEach(function (utmTagKey) { - if (utmTagsDetected) { - storage.setDataInLocalStorage(buildLocalStorageKey(utmTagKey), utmTagData[utmTagKey]); - updateUtmTimeout(); - } else { - if (!isUtmTimeoutExpired()) { - utmTagData[utmTagKey] = storage.getDataFromLocalStorage(buildLocalStorageKey(utmTagKey)) ? storage.getDataFromLocalStorage(buildLocalStorageKey(utmTagKey)) : ''; - updateUtmTimeout(); - } - } - }); - return utmTagData; -}; - -roxotAdapter.initConfig = function (config) { - let isCorrectConfig = true; - initOptions = {}; - initOptions.options = utils.deepClone(config.options); - - initOptions.publisherId = initOptions.options.publisherId || (initOptions.options.publisherIds[0]) || null; - if (!initOptions.publisherId) { - logError('"options.publisherId" is empty'); - isCorrectConfig = false; - } - - initOptions.adUnits = initOptions.options.adUnits || []; - initOptions.adUnits = initOptions.adUnits.map(value => value.toLowerCase()); - initOptions.server = initOptions.options.server || DEFAULT_EVENT_URL; - initOptions.configServer = initOptions.options.configServer || (initOptions.options.server || DEFAULT_SERVER_CONFIG_URL); - initOptions.utmTagData = this.buildUtmTagData(); - initOptions.host = initOptions.options.host || window.location.hostname; - initOptions.device = detectDevice(); - - loadServerConfig(); - return isCorrectConfig; -}; - -roxotAdapter.getOptions = function () { - return initOptions; -}; - -function registerEvent(eventType, eventName, data) { - let eventData = { - eventType: eventType, - eventName: eventName, - data: data - }; - - sendEventCache.push(eventData); - - logInfo('Register event', eventData); - - (typeof initOptions.serverConfig === 'undefined') ? checkEventAfterTimeout() : checkSendEvent(); -} - -function checkSendEvent() { - if (sendEventTimeoutId) { - clearTimeout(sendEventTimeoutId); - sendEventTimeoutId = null; - } - - if (typeof initOptions.serverConfig === 'undefined') { - checkEventAfterTimeout(); - return; - } - - while (sendEventCache.length) { - let event = sendEventCache.shift(); - let isNeedSend = initOptions.serverConfig[event.eventType] || 0; - if (Number(isNeedSend) === 0) { - logInfo('Skip event ' + event.eventName, event); - continue; - } - sendEvent(event.eventType, event.eventName, event.data); - } -} - -function checkEventAfterTimeout() { - if (sendEventTimeoutId) { - return; - } - - sendEventTimeoutId = setTimeout(checkSendEvent, sendEventTimeoutTime); -} - -function sendEvent(eventType, eventName, data) { - let url = 'https://' + initOptions.server + '/' + eventType + '?publisherId=' + initOptions.publisherId + '&host=' + initOptions.host; - let eventData = { - 'event': eventType, - 'eventName': eventName, - 'options': initOptions, - 'data': data - }; - - ajax( - url, - function () { - logInfo(eventName + ' sent', eventData); - }, - JSON.stringify(eventData), - { - contentType: 'text/plain', - method: 'POST', - withCredentials: true - } - ); -} - -function loadServerConfig() { - let url = 'https://' + initOptions.configServer + '/c' + '?publisherId=' + initOptions.publisherId + '&host=' + initOptions.host; - ajax( - url, - { - 'success': function (data) { - initOptions.serverConfig = JSON.parse(data); - }, - 'error': function () { - initOptions.serverConfig = {}; - initOptions.serverConfig[ROXOT_EVENTS.AUCTION] = 1; - initOptions.serverConfig[ROXOT_EVENTS.IMPRESSION] = 1; - initOptions.serverConfig[ROXOT_EVENTS.BID_AFTER_TIMEOUT] = 1; - initOptions.serverConfig['isError'] = 1; - } - }, - null, - { - contentType: 'text/json', - method: 'GET', - withCredentials: true - } - ); -} - -function logInfo(message, meta) { - utils.logInfo(buildLogMessage(message), meta); -} - -function logError(message) { - utils.logError(buildLogMessage(message)); -} - -function buildLogMessage(message) { - return 'Roxot Prebid Analytics: ' + message; -} - -adapterManager.registerAnalyticsAdapter({ - adapter: roxotAdapter, - code: 'roxot' -}); - -export default roxotAdapter; diff --git a/modules/rtbdemandBidAdapter.js b/modules/rtbdemandBidAdapter.js deleted file mode 100644 index be5fb39f53a..00000000000 --- a/modules/rtbdemandBidAdapter.js +++ /dev/null @@ -1,123 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'rtbdemand'; -const BIDDER_SERVER = 'bidding.rtbdemand.com'; -export const spec = { - code: BIDDER_CODE, - isBidRequestValid: function(bid) { - return !!(bid && bid.params && bid.params.zoneid); - }, - buildRequests: function(validBidRequests, bidderRequest) { - return validBidRequests.map(bidRequest => { - var server = bidRequest.params.server || BIDDER_SERVER; - var parse = getSize(bidderRequest.bids[0].sizes); - const payload = { - from: 'hb', - v: '1.0', - request_id: bidRequest.bidderRequestId, - imp_id: bidRequest.bidId, - aff: bidRequest.params.zoneid, - bid_floor: parseFloat(bidRequest.params.floor) > 0 ? bidRequest.params.floor : 0, - charset: document.charSet || document.characterSet, - site_domain: document.location.hostname, - site_page: window.location.href, - subid: 'hb', - flashver: getFlashVersion(), - tmax: bidderRequest.timeout, - hb: '1', - name: document.location.hostname, - width: parse.width, - height: parse.height, - device_width: screen.width, - device_height: screen.height, - dnt: (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0, - secure: isSecure(), - make: navigator.vendor ? navigator.vendor : '', - }; - if (document.referrer) { - payload.referrer = document.referrer; - } - - return { - method: 'GET', - url: 'https://' + server + '/hb', - data: payload - }; - }); - }, - interpretResponse: function(serverResponse) { - serverResponse = serverResponse.body; - const bidResponses = []; - if (serverResponse && serverResponse.seatbid) { - serverResponse.seatbid.forEach(seatBid => seatBid.bid.forEach(bid => { - const bidResponse = { - requestId: bid.impid, - creativeId: bid.impid, - cpm: bid.price, - width: bid.w, - height: bid.h, - ad: bid.adm, - netRevenue: true, - currency: 'USD', - ttl: 360, - }; - - bidResponses.push(bidResponse); - })); - } - return bidResponses; - }, - getUserSyncs: function getUserSyncs(syncOptions) { - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: 'https://' + BIDDER_SERVER + '/delivery/matches.php?type=iframe', - }]; - } - } -} - -function getFlashVersion() { - var plugins, plugin, result; - - if (navigator.plugins && navigator.plugins.length > 0) { - plugins = navigator.plugins; - for (var i = 0; i < plugins.length && !result; i++) { - plugin = plugins[i]; - if (plugin.name.indexOf('Shockwave Flash') > -1) { - result = plugin.description.split('Shockwave Flash ')[1]; - } - } - } - return result || ''; -} - -/* Get parsed size from request size */ -function getSize(requestSizes) { - const parsed = {}; - const size = utils.parseSizesInput(requestSizes)[0]; - - if (typeof size !== 'string') { - return parsed; - } - - const parsedSize = size.toUpperCase().split('X'); - const width = parseInt(parsedSize[0], 10); - if (width) { - parsed.width = width; - } - - const height = parseInt(parsedSize[1], 10); - if (height) { - parsed.height = height; - } - - return parsed; -} - -function isSecure() { - return document.location.protocol === 'https:'; -} - -registerBidder(spec); diff --git a/modules/rtbdemandBidAdapter.md b/modules/rtbdemandBidAdapter.md deleted file mode 100644 index 2727d85e084..00000000000 --- a/modules/rtbdemandBidAdapter.md +++ /dev/null @@ -1,26 +0,0 @@ -# Overview - -**Module Name**: Rtbdemand Media fmxSSP Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: rtb@rtbdemand.com - -# Description - -Connects to Rtbdemand Media fmxSSP demand source to fetch bids. - -# Test Parameters -``` - var adUnits = [{ - code: 'banner-ad-div', - sizes: [[300, 250]], - bids: [{ - bidder: 'rtbdemand', - params: { - zoneid: '9999', - floor: 0.005, - server: 'bidding.rtbdemand.com' - } - }] - }]; - -``` diff --git a/modules/rtbdemandadkBidAdapter.md b/modules/rtbdemandadkBidAdapter.md deleted file mode 100644 index 96bd3f6c8d7..00000000000 --- a/modules/rtbdemandadkBidAdapter.md +++ /dev/null @@ -1,45 +0,0 @@ -# Overview - -``` -Module Name: Rtbdemandadk Bidder Adapter -Module Type: Bidder Adapter -Maintainer: shreyanschopra@rtbdemand.com -``` - -# Description - -Connects to Rtbdemandadk whitelabel platform. -Banner and video formats are supported. - - -# Test Parameters -``` - var adUnits = [ - { - code: 'banner-ad-div', - sizes: [[300, 250]], // banner size - bids: [ - { - bidder: 'rtbdemandadk', - params: { - zoneId: '30164', //required parameter - host: 'cpm.metaadserving.com' //required parameter - } - } - ] - }, { - code: 'video-ad-player', - sizes: [640, 480], // video player size - bids: [ - { - bidder: 'rtbdemandadk', - mediaType : 'video', - params: { - zoneId: '30164', //required parameter - host: 'cpm.metaadserving.com' //required parameter - } - } - ] - } - ]; -``` diff --git a/modules/rtbhouseBidAdapter.js b/modules/rtbhouseBidAdapter.js deleted file mode 100644 index 036bdfaebeb..00000000000 --- a/modules/rtbhouseBidAdapter.js +++ /dev/null @@ -1,405 +0,0 @@ -import * as utils from '../src/utils.js'; -import { BANNER, NATIVE } from '../src/mediaTypes.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -const BIDDER_CODE = 'rtbhouse'; -const REGIONS = ['prebid-eu', 'prebid-us', 'prebid-asia']; -const ENDPOINT_URL = 'creativecdn.com/bidder/prebid/bids'; -const DEFAULT_CURRENCY_ARR = ['USD']; // NOTE - USD is the only supported currency right now; Hardcoded for bids -const SUPPORTED_MEDIA_TYPES = [BANNER, NATIVE]; -const TTL = 55; - -// Codes defined by OpenRTB Native Ads 1.1 specification -export const OPENRTB = { - NATIVE: { - IMAGE_TYPE: { - ICON: 1, - MAIN: 3, - }, - ASSET_ID: { - TITLE: 1, - IMAGE: 2, - ICON: 3, - BODY: 4, - SPONSORED: 5, - CTA: 6 - }, - DATA_ASSET_TYPE: { - SPONSORED: 1, - DESC: 2, - CTA_TEXT: 12, - }, - } -}; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: SUPPORTED_MEDIA_TYPES, - - isBidRequestValid: function (bid) { - return !!(includes(REGIONS, bid.params.region) && bid.params.publisherId); - }, - buildRequests: function (validBidRequests, bidderRequest) { - const request = { - id: validBidRequests[0].auctionId, - imp: validBidRequests.map(slot => mapImpression(slot)), - site: mapSite(validBidRequests, bidderRequest), - cur: DEFAULT_CURRENCY_ARR, - test: validBidRequests[0].params.test || 0, - source: mapSource(validBidRequests[0]), - }; - if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) { - 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}}; - } - if (validBidRequests[0].schain) { - const schain = mapSchain(validBidRequests[0].schain); - if (schain) { - request.ext = { - schain: schain, - } - } - } - - if (validBidRequests[0].userIdAsEids) { - const eids = { eids: validBidRequests[0].userIdAsEids }; - if (request.user && request.user.ext) { - request.user.ext = { ...request.user.ext, ...eids }; - } else { - request.user = {ext: eids}; - } - } - - return { - method: 'POST', - url: 'https://' + validBidRequests[0].params.region + '.' + ENDPOINT_URL, - data: JSON.stringify(request) - }; - }, - interpretResponse: function (serverResponse, originalRequest) { - const responseBody = serverResponse.body; - if (!utils.isArray(responseBody)) { - return []; - } - - const bids = []; - responseBody.forEach(serverBid => { - if (serverBid.price === 0) { - return; - } - // try...catch would be risky cause JSON.parse throws SyntaxError - if (serverBid.adm.indexOf('{') === 0) { - bids.push(interpretNativeBid(serverBid)); - } else { - bids.push(interpretBannerBid(serverBid)); - } - }); - return bids; - } -}; -registerBidder(spec); - -/** - * @param {object} slot Ad Unit Params by Prebid - * @returns {int} floor by imp type - */ -function applyFloor(slot) { - const floors = []; - if (typeof slot.getFloor === 'function') { - Object.keys(slot.mediaTypes).forEach(type => { - if (includes(SUPPORTED_MEDIA_TYPES, type)) { - floors.push(slot.getFloor({ currency: DEFAULT_CURRENCY_ARR[0], mediaType: type, size: slot.sizes || '*' }).floor); - } - }); - } - return floors.length > 0 ? Math.max(...floors) : parseFloat(slot.params.bidfloor); -} - -/** - * @param {object} slot Ad Unit Params by Prebid - * @returns {object} Imp by OpenRTB 2.5 §3.2.4 - */ -function mapImpression(slot) { - const imp = { - id: slot.bidId, - banner: mapBanner(slot), - native: mapNative(slot), - tagid: slot.adUnitCode.toString() - }; - - const bidfloor = applyFloor(slot); - if (bidfloor) { - imp.bidfloor = bidfloor; - } - - return imp; -} - -/** - * @param {object} slot Ad Unit Params by Prebid - * @returns {object} Banner by OpenRTB 2.5 §3.2.6 - */ -function mapBanner(slot) { - if (slot.mediaType === 'banner' || - utils.deepAccess(slot, 'mediaTypes.banner') || - (!slot.mediaType && !slot.mediaTypes)) { - var sizes = slot.sizes || slot.mediaTypes.banner.sizes; - return { - w: sizes[0][0], - h: sizes[0][1], - format: sizes.map(size => ({ - w: size[0], - h: size[1] - })) - }; - } -} - -/** - * @param {object} slot Ad Unit Params by Prebid - * @param {object} bidderRequest by Prebid - * @returns {object} Site by OpenRTB 2.5 §3.2.13 - */ -function mapSite(slot, bidderRequest) { - const pubId = slot && slot.length > 0 - ? slot[0].params.publisherId - : 'unknown'; - return { - publisher: { - id: pubId.toString(), - }, - page: bidderRequest.refererInfo.referer, - name: utils.getOrigin() - } -} - -/** - * @param {object} slot Ad Unit Params by Prebid - * @returns {object} Source by OpenRTB 2.5 §3.2.2 - */ -function mapSource(slot) { - const source = { - tid: slot.transactionId, - }; - - return source; -} - -/** - * @param {object} schain object set by Publisher - * @returns {object} OpenRTB SupplyChain object - */ -function mapSchain(schain) { - if (!schain) { - return null; - } - if (!validateSchain(schain)) { - utils.logError('RTB House: required schain params missing'); - return null; - } - return schain; -} - -/** - * @param {object} schain object set by Publisher - * @returns {object} bool - */ -function validateSchain(schain) { - if (!schain.nodes) { - return false; - } - const requiredFields = ['asi', 'sid', 'hp']; - return schain.nodes.every(node => { - return requiredFields.every(field => node[field]); - }); -} - -/** - * @param {object} slot Ad Unit Params by Prebid - * @returns {object} Request by OpenRTB Native Ads 1.1 §4 - */ -function mapNative(slot) { - if (slot.mediaType === 'native' || utils.deepAccess(slot, 'mediaTypes.native')) { - return { - request: { - assets: mapNativeAssets(slot) - }, - ver: '1.1' - } - } -} - -/** - * @param {object} slot Slot config by Prebid - * @returns {array} Request Assets by OpenRTB Native Ads 1.1 §4.2 - */ -function mapNativeAssets(slot) { - const params = slot.nativeParams || utils.deepAccess(slot, 'mediaTypes.native'); - const assets = []; - if (params.title) { - assets.push({ - id: OPENRTB.NATIVE.ASSET_ID.TITLE, - required: params.title.required ? 1 : 0, - title: { - len: params.title.len || 25 - } - }) - } - if (params.image) { - assets.push({ - id: OPENRTB.NATIVE.ASSET_ID.IMAGE, - required: params.image.required ? 1 : 0, - img: mapNativeImage(params.image, OPENRTB.NATIVE.IMAGE_TYPE.MAIN) - }) - } - if (params.icon) { - assets.push({ - id: OPENRTB.NATIVE.ASSET_ID.ICON, - required: params.icon.required ? 1 : 0, - img: mapNativeImage(params.icon, OPENRTB.NATIVE.IMAGE_TYPE.ICON) - }) - } - if (params.sponsoredBy) { - assets.push({ - id: OPENRTB.NATIVE.ASSET_ID.SPONSORED, - required: params.sponsoredBy.required ? 1 : 0, - data: { - type: OPENRTB.NATIVE.DATA_ASSET_TYPE.SPONSORED, - len: params.sponsoredBy.len - } - }) - } - if (params.body) { - assets.push({ - id: OPENRTB.NATIVE.ASSET_ID.BODY, - required: params.body.request ? 1 : 0, - data: { - type: OPENRTB.NATIVE.DATA_ASSET_TYPE.DESC, - len: params.body.len - } - }) - } - if (params.cta) { - assets.push({ - id: OPENRTB.NATIVE.ASSET_ID.CTA, - required: params.cta.required ? 1 : 0, - data: { - type: OPENRTB.NATIVE.DATA_ASSET_TYPE.CTA_TEXT, - len: params.cta.len - } - }) - } - return assets; -} - -/** - * @param {object} image Prebid native.image/icon - * @param {int} type Image or icon code - * @returns {object} Request Image by OpenRTB Native Ads 1.1 §4.4 - */ -function mapNativeImage(image, type) { - const img = {type: type}; - if (image.aspect_ratios) { - const ratio = image.aspect_ratios[0]; - const minWidth = ratio.min_width || 100; - img.wmin = minWidth; - img.hmin = (minWidth / ratio.ratio_width * ratio.ratio_height); - } - if (image.sizes) { - const size = Array.isArray(image.sizes[0]) ? image.sizes[0] : image.sizes; - img.w = size[0]; - img.h = size[1]; - } - return img -} - -/** - * @param {object} serverBid Bid by OpenRTB 2.5 §4.2.3 - * @returns {object} Prebid banner bidObject - */ -function interpretBannerBid(serverBid) { - return { - requestId: serverBid.impid, - mediaType: BANNER, - cpm: serverBid.price, - creativeId: serverBid.adid, - ad: serverBid.adm, - width: serverBid.w, - height: serverBid.h, - ttl: TTL, - meta: { - advertiserDomains: serverBid.adomain - }, - netRevenue: true, - currency: 'USD' - } -} - -/** - * @param {object} serverBid Bid by OpenRTB 2.5 §4.2.3 - * @returns {object} Prebid native bidObject - */ -function interpretNativeBid(serverBid) { - return { - requestId: serverBid.impid, - mediaType: NATIVE, - cpm: serverBid.price, - creativeId: serverBid.adid, - width: 1, - height: 1, - ttl: TTL, - meta: { - advertiserDomains: serverBid.adomain - }, - netRevenue: true, - currency: 'USD', - native: interpretNativeAd(serverBid.adm), - } -} - -/** - * @param {string} adm JSON-encoded Request by OpenRTB Native Ads 1.1 §4.1 - * @returns {object} Prebid bidObject.native - */ -function interpretNativeAd(adm) { - const native = JSON.parse(adm).native; - const result = { - clickUrl: encodeURIComponent(native.link.url), - impressionTrackers: native.imptrackers - }; - native.assets.forEach(asset => { - switch (asset.id) { - case OPENRTB.NATIVE.ASSET_ID.TITLE: - result.title = asset.title.text; - break; - case OPENRTB.NATIVE.ASSET_ID.IMAGE: - result.image = { - url: encodeURIComponent(asset.img.url), - width: asset.img.w, - height: asset.img.h - }; - break; - case OPENRTB.NATIVE.ASSET_ID.ICON: - result.icon = { - url: encodeURIComponent(asset.img.url), - width: asset.img.w, - height: asset.img.h - }; - break; - case OPENRTB.NATIVE.ASSET_ID.BODY: - result.body = asset.data.value; - break; - case OPENRTB.NATIVE.ASSET_ID.SPONSORED: - result.sponsoredBy = asset.data.value; - break; - case OPENRTB.NATIVE.ASSET_ID.CTA: - result.cta = asset.data.value; - break; - } - }); - return result; -} diff --git a/modules/rtbhouseBidAdapter.md b/modules/rtbhouseBidAdapter.md deleted file mode 100644 index b8b59aa9edc..00000000000 --- a/modules/rtbhouseBidAdapter.md +++ /dev/null @@ -1,67 +0,0 @@ -# Overview - -Module Name: RTB House Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid@rtbhouse.com - -# Description - -Connects to RTB House unique demand. -Banner and native formats are supported. -Unique publisherId is required. -Please reach out to pmp@rtbhouse.com to receive your own - -# Test Parameters -``` - var adUnits = [ - // banner - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [ - { - bidder: "rtbhouse", - params: { - region: 'prebid-eu', - publisherId: 'PREBID_TEST_ID', - bidfloor: 0.01 // optional - } - } - ] - }, - // native - { - code: 'test-div', - mediaTypes: { - native: { - title: { - required: true, - len: 25 - }, - image: { - required: true, - sizes: [300, 250] - }, - body: { - required: true, - len: 90 - } - } - }, - bids: [ - { - bidder: "rtbhouse", - params: { - region: 'prebid-eu', - publisherId: 'PREBID_TEST_ID' - bidfloor: 0.01 // optional - } - } - ] - } - ]; -``` diff --git a/modules/rtbsapeBidAdapter.js b/modules/rtbsapeBidAdapter.js deleted file mode 100644 index 8473ef4dbb3..00000000000 --- a/modules/rtbsapeBidAdapter.js +++ /dev/null @@ -1,142 +0,0 @@ -import * as utils 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 {triggerPixel} from '../src/utils.js'; - -const BIDDER_CODE = 'rtbsape'; -const ENDPOINT = 'https://ssp-rtb.sape.ru/prebid'; -const RENDERER_SRC = 'https://cdn-rtb.sape.ru/js/player.js'; -const MATCH_SRC = 'https://www.acint.net/mc/?dp=141'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['sape'], - supportedMediaTypes: [BANNER, VIDEO], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return !!(bid && bid.mediaTypes && (bid.mediaTypes.banner || bid.mediaTypes.video) && bid.params && bid.params.placeId); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests an array of bids - * @param bidderRequest - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - let tz = (new Date()).getTimezoneOffset() - let padInt = (v) => (v < 10 ? '0' + v : '' + v); - - return { - url: ENDPOINT, - method: 'POST', - data: { - auctionId: bidderRequest.auctionId, - requestId: bidderRequest.bidderRequestId, - bids: validBidRequests, - timezone: (tz > 0 ? '-' : '+') + padInt(Math.floor(Math.abs(tz) / 60)) + ':' + padInt(Math.abs(tz) % 60), - refererInfo: bidderRequest.refererInfo - }, - } - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {ServerResponse} serverResponse A successful response from the server. - * @param {{data: {bids: [{mediaTypes: {banner: boolean}}]}}} bidRequest Info describing the request to the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function (serverResponse, bidRequest) { - if (!(serverResponse.body && Array.isArray(serverResponse.body.bids))) { - return []; - } - - let bids = {}; - bidRequest.data.bids.forEach(bid => bids[bid.bidId] = bid); - - return serverResponse.body.bids.map(bid => { - let requestBid = bids[bid.requestId]; - let context = utils.deepAccess(requestBid, 'mediaTypes.video.context'); - - if (context === OUTSTREAM && (bid.vastUrl || bid.vastXml)) { - let renderer = Renderer.install({ - id: bid.requestId, - url: RENDERER_SRC, - loaded: false - }); - - let muted = utils.deepAccess(requestBid, 'params.video.playerMuted'); - if (typeof muted === 'undefined') { - muted = true; - } - - bid.playerMuted = muted; - bid.renderer = renderer - - renderer.setRender(setOutstreamRenderer); - } - - return bid; - }); - }, - - /** - * Register the user sync pixels which should be dropped after the auction. - * - * @param {SyncOptions} syncOptions Which user syncs are allowed? - * @return {UserSync[]} The user syncs which should be dropped. - */ - getUserSyncs: function (syncOptions) { - const sync = []; - if (syncOptions.iframeEnabled) { - sync.push({ - type: 'iframe', - url: MATCH_SRC - }); - } - return sync; - }, - - /** - * Register bidder specific code, which will execute if a bid from this bidder won the auction - * @param {Bid} bid The bid that won the auction - */ - onBidWon: function(bid) { - if (bid.nurl) { - triggerPixel(bid.nurl); - } - } -} - -/** - * Initialize RtbSape outstream player - * - * @param bid - */ -function setOutstreamRenderer(bid) { - let props = {}; - if (bid.vastUrl) { - props.url = bid.vastUrl; - } - if (bid.vastXml) { - props.xml = bid.vastXml; - } - bid.renderer.push(() => { - let player = window.sapeRtbPlayerHandler(bid.adUnitCode, bid.width, bid.height, bid.playerMuted, {singleton: true}); - props.onComplete = () => player.destroy(); - props.onError = () => player.destroy(); - player.addSlot(props); - }); -} - -registerBidder(spec); diff --git a/modules/rtbsapeBidAdapter.md b/modules/rtbsapeBidAdapter.md deleted file mode 100644 index 6b1afe3867d..00000000000 --- a/modules/rtbsapeBidAdapter.md +++ /dev/null @@ -1,51 +0,0 @@ -# Overview - -``` -Module Name: RtbSape Bid Adapter -Module Type: Bidder Adapter -Maintainer: sergey@sape.ru -``` - -# Description -Our module makes it easy to integrate RtbSape demand sources into your website. - -Supported Ad format: -* Banner -* Video (instream and outstream) - -# Test Parameters -``` -var adUnits = [ - // Banner adUnit - { - code: 'banner-div', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [{ - bidder: 'rtbsape', - params: { - placeId: 553307 - } - }] - }, - // Video adUnit - { - code: 'video-div', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [600, 340] - } - }, - bids: [{ - bidder: 'rtbsape', - params: { - placeId: 553309 - } - }] - } -]; -``` diff --git a/modules/rtbsolutionsBidAdapter.js b/modules/rtbsolutionsBidAdapter.js deleted file mode 100644 index 244ab8a4eba..00000000000 --- a/modules/rtbsolutionsBidAdapter.js +++ /dev/null @@ -1,100 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import * as utils from '../src/utils.js'; -import { ajax } from '../src/ajax.js'; - -const BIDDER_CODE = 'rtbsolutions'; -const ENDPOINT_URL = 'https://dsp-eu-lb.rtbsolutions.pro/bid/hb'; - -export const spec = { - version: '1.0', - code: BIDDER_CODE, - aliases: ['rtbss'], // short code - nurls: {}, - isBidRequestValid: function(bid) { - return !!bid.params.blockId; - }, - buildRequests: function(validBidRequests, bidderRequest) { - let req = []; - - bidderRequest.bids.forEach(item => { - const width = item.sizes[0][0]; - const height = item.sizes[0][1]; - - let imp = { - referer: bidderRequest.refererInfo.referer, - ua: navigator.userAgent, - lang: this.getLanguage(), - domain: this.getDomain(), - width: width, - height: height, - type: 'banner', - }; - - if (item.params.s1 !== undefined) imp.s1 = item.params.s1; - if (item.params.s2 !== undefined) imp.s2 = item.params.s2; - if (item.params.s3 !== undefined) imp.s3 = item.params.s3; - if (item.params.s4 !== undefined) imp.s4 = item.params.s4; - - req.push({ - bid_id: item.bidId, - block_id: item.params.blockId, - ver: this.version, - imp - }); - }); - - return { - method: 'POST', - url: ENDPOINT_URL, - data: req, - options: { - contentType: 'application/json' - } - } - }, - interpretResponse: function(serverResponse, request) { - const bidResponses = []; - - serverResponse.body.forEach(item => { - this.nurls[item.bid_id] = item.nurl; - - const bidResponse = { - requestId: item.bid_id, - cpm: item.cpm, - width: item.width, - height: item.height, - creativeId: item.creative_id, - currency: item.currency, - netRevenue: true, - ttl: 360, - ad: item.ad, - }; - - bidResponses.push(bidResponse); - }); - - return bidResponses; - }, - onBidWon: function(bid) { - ajax(this.nurls[bid.requestId], null); - }, - - getLanguage() { - const language = navigator.language ? 'language' : 'userLanguage'; - const lang2 = navigator[language].split('-')[0]; - if (lang2.length === 2 || lang2.length === 3) { - return lang2; - } - return ''; - }, - getDomain() { - if (!utils.inIframe()) { - return window.location.hostname - } - let origins = window.document.location.ancestorOrigins; - if (origins && origins.length > 0) { - return origins[origins.length - 1] - } - } -}; -registerBidder(spec); diff --git a/modules/rtbsolutionsBidAdapter.md b/modules/rtbsolutionsBidAdapter.md deleted file mode 100644 index e671de306a0..00000000000 --- a/modules/rtbsolutionsBidAdapter.md +++ /dev/null @@ -1,128 +0,0 @@ -# Overview - -Module Name: Rtbsolutions Bidder Adapter -Module Type: Bidder Adapter -Maintainer: info@rtbsolutions.pro - -# Description - -You can use this adapter to get a bid from rtbsolutions. - -About us: http://rtbsolutions.pro - - -# Test Parameters -```javascript - var adUnits = [ - { - code: '/19968336/header-bid-tag-1', - mediaTypes: { - banner: { - sizes: sizes - } - }, - bids: [{ - bidder: 'rtbsolutions', - params: { - blockId: 777, - s1: 'sub_1', - s2: 'sub_2', - s3: 'sub_3', - s4: 'sub_4' - } - }] - }]; -``` - -Where: - -* blockId - Block ID from platform (required) -* s1..s4 - Sub Id (optional) - -# Example page - -```html - - - - - Prebid - - - - - -

Prebid

-
Div-1
-
- -
- - -``` diff --git a/modules/rtdModule/index.js b/modules/rtdModule/index.js deleted file mode 100644 index e235868f791..00000000000 --- a/modules/rtdModule/index.js +++ /dev/null @@ -1,359 +0,0 @@ -/** - * This module adds Real time data support to prebid.js - * @module modules/realTimeData - */ - -/** - * @interface UserConsentData - */ -/** - * @property - * @summary gdpr consent - * @name UserConsentData#gdpr - * @type {Object} - */ -/** - * @property - * @summary usp consent - * @name UserConsentData#usp - * @type {Object} - */ -/** - * @property - * @summary coppa - * @name UserConsentData#coppa - * @type {boolean} - */ - -/** - * @interface RtdSubmodule - */ - -/** - * @function? - * @summary return real time data - * @name RtdSubmodule#getTargetingData - * @param {string[]} adUnitsCodes - * @param {SubmoduleConfig} config - * @param {UserConsentData} userConsent - */ - -/** - * @function? - * @summary modify bid request data - * @name RtdSubmodule#getBidRequestData - * @param {SubmoduleConfig} config - * @param {UserConsentData} userConsent - * @param {Object} reqBidsConfigObj - * @param {function} callback - */ - -/** - * @property - * @summary used to link submodule with config - * @name RtdSubmodule#name - * @type {string} - */ - -/** - * @property - * @summary used to link submodule with config - * @name RtdSubmodule#config - * @type {Object} - */ - -/** - * @function - * @summary init sub module - * @name RtdSubmodule#init - * @param {SubmoduleConfig} config - * @param {UserConsentData} user consent - * @return {boolean} false to remove sub module - */ - -/** - * @function? - * @summary on auction init event - * @name RtdSubmodule#onAuctionInitEvent - * @param {Object} data - * @param {SubmoduleConfig} config - * @param {UserConsentData} userConsent - */ - -/** - * @function? - * @summary on auction end event - * @name RtdSubmodule#onAuctionEndEvent - * @param {Object} data - * @param {SubmoduleConfig} config - * @param {UserConsentData} userConsent - */ - -/** - * @function? - * @summary on bid response event - * @name RtdSubmodule#onBidResponseEvent - * @param {Object} data - * @param {SubmoduleConfig} config - * @param {UserConsentData} userConsent - */ - -/** - * @interface ModuleConfig - */ - -/** - * @property - * @summary auction delay - * @name ModuleConfig#auctionDelay - * @type {number} - */ - -/** - * @property - * @summary list of sub modules - * @name ModuleConfig#dataProviders - * @type {SubmoduleConfig[]} - */ - -/** - * @interface SubModuleConfig - */ - -/** - * @property - * @summary params for provide (sub module) - * @name SubModuleConfig#params - * @type {Object} - */ - -/** - * @property - * @summary name - * @name ModuleConfig#name - * @type {string} - */ - -/** - * @property - * @summary delay auction for this sub module - * @name ModuleConfig#waitForIt - * @type {boolean} - */ - -import {config} from '../../src/config.js'; -import {module} from '../../src/hook.js'; -import * as utils from '../../src/utils.js'; -import events from '../../src/events.js'; -import CONSTANTS from '../../src/constants.json'; -import {gdprDataHandler, uspDataHandler} from '../../src/adapterManager.js'; -import find from 'core-js-pure/features/array/find.js'; -import {getGlobal} from '../../src/prebidGlobal.js'; - -/** @type {string} */ -const MODULE_NAME = 'realTimeData'; -/** @type {RtdSubmodule[]} */ -let registeredSubModules = []; -/** @type {RtdSubmodule[]} */ -export let subModules = []; -/** @type {ModuleConfig} */ -let _moduleConfig; -/** @type {SubmoduleConfig[]} */ -let _dataProviders = []; -/** @type {UserConsentData} */ -let _userConsent; - -/** - * enable submodule in User ID - * @param {RtdSubmodule} submodule - */ -export function attachRealTimeDataProvider(submodule) { - registeredSubModules.push(submodule); -} - -export function init(config) { - const confListener = config.getConfig(MODULE_NAME, ({realTimeData}) => { - if (!realTimeData.dataProviders) { - utils.logError('missing parameters for real time module'); - return; - } - confListener(); // unsubscribe config listener - _moduleConfig = realTimeData; - _dataProviders = realTimeData.dataProviders; - setEventsListeners(); - getGlobal().requestBids.before(setBidRequestsData, 40); - initSubModules(); - }); -} - -function getConsentData() { - return { - gdpr: gdprDataHandler.getConsentData(), - usp: uspDataHandler.getConsentData(), - coppa: !!(config.getConfig('coppa')) - } -} - -/** - * call each sub module init function by config order - * if no init function / init return failure / module not configured - remove it from submodules list - */ -function initSubModules() { - _userConsent = getConsentData(); - let subModulesByOrder = []; - _dataProviders.forEach(provider => { - const sm = find(registeredSubModules, s => s.name === provider.name); - const initResponse = sm && sm.init && sm.init(provider, _userConsent); - if (initResponse) { - subModulesByOrder.push(Object.assign(sm, {config: provider})); - } - }); - subModules = subModulesByOrder; -} - -/** - * call each sub module event function by config order - */ -function setEventsListeners() { - events.on(CONSTANTS.EVENTS.AUCTION_INIT, (args) => { - subModules.forEach(sm => { sm.onAuctionInitEvent && sm.onAuctionInitEvent(args, sm.config, _userConsent) }) - }); - events.on(CONSTANTS.EVENTS.AUCTION_END, (args) => { - getAdUnitTargeting(args); - subModules.forEach(sm => { sm.onAuctionEndEvent && sm.onAuctionEndEvent(args, sm.config, _userConsent) }) - }); - events.on(CONSTANTS.EVENTS.BID_RESPONSE, (args) => { - subModules.forEach(sm => { sm.onBidResponseEvent && sm.onBidResponseEvent(args, sm.config, _userConsent) }) - }); -} - -/** - * loop through configured data providers If the data provider has registered getBidRequestData, - * call it, providing reqBidsConfigObj, consent data and module params - * this allows submodules to modify bidders - * @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.js - */ -export function setBidRequestsData(fn, reqBidsConfigObj) { - _userConsent = getConsentData(); - - const relevantSubModules = []; - const prioritySubModules = []; - subModules.forEach(sm => { - if (typeof sm.getBidRequestData !== 'function') { - return; - } - relevantSubModules.push(sm); - const config = sm.config; - if (config && config.waitForIt) { - prioritySubModules.push(sm); - } - }); - - const shouldDelayAuction = prioritySubModules.length && _moduleConfig.auctionDelay && _moduleConfig.auctionDelay > 0; - let callbacksExpected = prioritySubModules.length; - let isDone = false; - let waitTimeout; - - if (!relevantSubModules.length) { - return exitHook(); - } - - if (shouldDelayAuction) { - waitTimeout = setTimeout(exitHook, _moduleConfig.auctionDelay); - } - - relevantSubModules.forEach(sm => { - sm.getBidRequestData(reqBidsConfigObj, onGetBidRequestDataCallback.bind(sm), sm.config, _userConsent) - }); - - if (!shouldDelayAuction) { - return exitHook(); - } - - function onGetBidRequestDataCallback() { - if (isDone) { - return; - } - if (this.config && this.config.waitForIt) { - callbacksExpected--; - } - if (callbacksExpected <= 0) { - return exitHook(); - } - } - - function exitHook() { - isDone = true; - clearTimeout(waitTimeout); - fn.call(this, reqBidsConfigObj); - } -} - -/** - * loop through configured data providers If the data provider has registered getTargetingData, - * call it, providing ad unit codes, consent data and module params - * the sub mlodle will return data to set on the ad unit - * this function used to place key values on primary ad server per ad unit - * @param {Object} auction object received on auction end event - */ -export function getAdUnitTargeting(auction) { - const relevantSubModules = subModules.filter(sm => typeof sm.getTargetingData === 'function'); - if (!relevantSubModules.length) { - return; - } - - // get data - const adUnitCodes = auction.adUnitCodes; - if (!adUnitCodes) { - return; - } - let targeting = []; - for (let i = relevantSubModules.length - 1; i >= 0; i--) { - const smTargeting = relevantSubModules[i].getTargetingData(adUnitCodes, relevantSubModules[i].config, _userConsent); - if (smTargeting && typeof smTargeting === 'object') { - targeting.push(smTargeting); - } else { - utils.logWarn('invalid getTargetingData response for sub module', relevantSubModules[i].name); - } - } - // place data on auction adUnits - const mergedTargeting = deepMerge(targeting); - auction.adUnits.forEach(adUnit => { - const kv = adUnit.code && mergedTargeting[adUnit.code]; - if (!kv) { - return - } - adUnit[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING] = Object.assign(adUnit[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING] || {}, kv); - }); - return auction.adUnits; -} - -/** - * deep merge array of objects - * @param {array} arr - objects array - * @return {Object} merged object - */ -export function deepMerge(arr) { - if (!Array.isArray(arr) || !arr.length) { - return {}; - } - return arr.reduce((merged, obj) => { - for (let key in obj) { - if (obj.hasOwnProperty(key)) { - if (!merged.hasOwnProperty(key)) merged[key] = obj[key]; - else { - // duplicate key - merge values - const dp = obj[key]; - for (let dk in dp) { - if (dp.hasOwnProperty(dk)) merged[key][dk] = dp[dk]; - } - } - } - } - return merged; - }, {}); -} - -module('realTimeData', attachRealTimeDataProvider); -init(config); diff --git a/modules/rtdModule/provider.md b/modules/rtdModule/provider.md deleted file mode 100644 index 116db160238..00000000000 --- a/modules/rtdModule/provider.md +++ /dev/null @@ -1,33 +0,0 @@ -New provider must include the following: - -1. sub module object with the following keys: - -| param name | type | Scope | Description | Params | -| :------------ | :------------ | :------ | :------ | :------ | -| name | string | required | must match the name provided by the publisher in the on-page config | n/a | -| init | function | required | defines the function that does any auction-level initialization required | config, userConsent | -| getTargetingData | function | optional | defines a function that provides ad server targeting data to RTD-core | adUnitArray, config, userConsent | -| getBidRequestData | function | optional | defines a function that provides ad server targeting data to RTD-core | reqBidsConfigObj, callback, config, userConsent | -| onAuctionInitEvent | function | optional | listens to the AUCTION_INIT event and calls a sub-module function that lets it inspect and/or update the auction | auctionDetails, config, userConsent | -| onAuctionEndEvent | function |optional | listens to the AUCTION_END event and calls a sub-module function that lets it know when auction is done | auctionDetails, config, userConsent | -| onBidResponseEvent | function |optional | listens to the BID_RESPONSE event and calls a sub-module function that lets it know when a bid response has been collected | bidResponse, config, userConsent | - -2. `getTargetingData` function (if defined) should return ad unit targeting data according to the following structure: -```json -{ - "adUnitCode":{ - "key":"value", - "key2":"value" - }, - "adUnitCode2":{ - "dataKey":"dataValue" - } -} -``` - -3. Hook to Real Time Data module: -```javascript -submodule('realTimeData', subModuleName); -``` - -4. See detailed documentation [here](https://docs.prebid.org/dev-docs/add-rtd-submodule.html) diff --git a/modules/rubiconAnalyticsAdapter.js b/modules/rubiconAnalyticsAdapter.js deleted file mode 100644 index 3237facb2e7..00000000000 --- a/modules/rubiconAnalyticsAdapter.js +++ /dev/null @@ -1,795 +0,0 @@ -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -import CONSTANTS from '../src/constants.json'; -import { ajax } from '../src/ajax.js'; -import { config } from '../src/config.js'; -import * as utils from '../src/utils.js'; -import { getGlobal } from '../src/prebidGlobal.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const RUBICON_GVL_ID = 52; -export const storage = getStorageManager(RUBICON_GVL_ID, 'rubicon'); -const COOKIE_NAME = 'rpaSession'; -const LAST_SEEN_EXPIRE_TIME = 1800000; // 30 mins -const END_EXPIRE_TIME = 21600000; // 6 hours - -const pbsErrorMap = { - 1: 'timeout-error', - 2: 'input-error', - 3: 'connect-error', - 4: 'request-error', - 999: 'generic-error' -} - -let prebidGlobal = getGlobal(); -const { - EVENTS: { - AUCTION_INIT, - AUCTION_END, - BID_REQUESTED, - BID_RESPONSE, - BIDDER_DONE, - BID_TIMEOUT, - BID_WON, - SET_TARGETING - }, - STATUS: { - GOOD, - NO_BID - }, - BID_STATUS: { - BID_REJECTED - } -} = CONSTANTS; - -let serverConfig; -config.getConfig('s2sConfig', ({s2sConfig}) => { - serverConfig = s2sConfig; -}); - -export const SEND_TIMEOUT = 3000; -const DEFAULT_INTEGRATION = 'pbjs'; - -const cache = { - auctions: {}, - targeting: {}, - timeouts: {}, - gpt: {}, -}; - -const BID_REJECTED_IPF = 'rejected-ipf'; - -export let rubiConf = { - pvid: utils.generateUUID().slice(0, 8), - analyticsEventDelay: 0 -}; -// we are saving these as global to this module so that if a pub accidentally overwrites the entire -// rubicon object, then we do not lose other data -config.getConfig('rubicon', config => { - utils.mergeDeep(rubiConf, config.rubicon); - if (utils.deepAccess(config, 'rubicon.updatePageView') === true) { - rubiConf.pvid = utils.generateUUID().slice(0, 8) - } -}); - -export function getHostNameFromReferer(referer) { - try { - rubiconAdapter.referrerHostname = utils.parseUrl(referer, {noDecodeWholeURL: true}).hostname; - } catch (e) { - utils.logError('Rubicon Analytics: Unable to parse hostname from supplied url: ', referer, e); - rubiconAdapter.referrerHostname = ''; - } - return rubiconAdapter.referrerHostname -}; - -function stringProperties(obj) { - return Object.keys(obj).reduce((newObj, prop) => { - let value = obj[prop]; - if (typeof value === 'number') { - value = value.toFixed(3); - } else if (typeof value !== 'string') { - value = String(value); - } - newObj[prop] = value; - return newObj; - }, {}); -} - -function sizeToDimensions(size) { - return { - width: size.w || size[0], - height: size.h || size[1] - }; -} - -function validMediaType(type) { - return ['banner', 'native', 'video'].indexOf(type) !== -1; -} - -function formatSource(src) { - if (typeof src === 'undefined') { - src = 'client'; - } else if (src === 's2s') { - src = 'server'; - } - return src.toLowerCase(); -} - -function sendMessage(auctionId, bidWonId) { - function formatBid(bid) { - return utils.pick(bid, [ - 'bidder', - 'bidderDetail', - 'bidId', bidId => utils.deepAccess(bid, 'bidResponse.pbsBidId') || utils.deepAccess(bid, 'bidResponse.seatBidId') || bidId, - 'status', - 'error', - 'source', (source, bid) => { - if (source) { - return source; - } - return serverConfig && Array.isArray(serverConfig.bidders) && serverConfig.bidders.some(s2sBidder => s2sBidder.toLowerCase() === bid.bidder) !== -1 - ? 'server' : 'client' - }, - 'clientLatencyMillis', - 'serverLatencyMillis', - 'params', - 'bidResponse', bidResponse => bidResponse ? utils.pick(bidResponse, [ - 'bidPriceUSD', - 'dealId', - 'dimensions', - 'mediaType', - 'floorValue', - 'floorRuleValue', - 'floorRule', - 'adomains' - ]) : undefined - ]); - } - function formatBidWon(bid) { - return Object.assign(formatBid(bid), utils.pick(bid.adUnit, [ - 'adUnitCode', - 'transactionId', - 'videoAdFormat', () => bid.videoAdFormat, - 'mediaTypes' - ]), { - adserverTargeting: stringProperties(cache.targeting[bid.adUnit.adUnitCode] || {}), - bidwonStatus: 'success', // hard-coded for now - accountId, - siteId: bid.siteId, - zoneId: bid.zoneId, - samplingFactor - }); - } - let auctionCache = cache.auctions[auctionId]; - let referrer = config.getConfig('pageUrl') || (auctionCache && auctionCache.referrer); - let message = { - eventTimeMillis: Date.now(), - integration: rubiConf.int_type || DEFAULT_INTEGRATION, - version: '$prebid.version$', - referrerUri: referrer, - referrerHostname: rubiconAdapter.referrerHostname || getHostNameFromReferer(referrer), - channel: 'web', - }; - if (rubiConf.wrapperName) { - message.wrapper = { - name: rubiConf.wrapperName, - family: rubiConf.wrapperFamily, - rule: rubiConf.rule_name - } - } - if (auctionCache && !auctionCache.sent) { - let adUnitMap = Object.keys(auctionCache.bids).reduce((adUnits, bidId) => { - let bid = auctionCache.bids[bidId]; - let adUnit = adUnits[bid.adUnit.adUnitCode]; - if (!adUnit) { - adUnit = adUnits[bid.adUnit.adUnitCode] = utils.pick(bid.adUnit, [ - 'adUnitCode', - 'transactionId', - 'mediaTypes', - 'dimensions', - 'adserverTargeting', () => stringProperties(cache.targeting[bid.adUnit.adUnitCode] || {}), - 'gam', - 'pbAdSlot', - 'pattern' - ]); - adUnit.bids = []; - adUnit.status = 'no-bid'; // default it to be no bid - } - - // Add site and zone id if not there and if we found a rubicon bidder - if ((!adUnit.siteId || !adUnit.zoneId) && rubiconAliases.indexOf(bid.bidder) !== -1) { - if (utils.deepAccess(bid, 'params.accountId') == accountId) { - adUnit.accountId = parseInt(accountId); - adUnit.siteId = parseInt(utils.deepAccess(bid, 'params.siteId')); - adUnit.zoneId = parseInt(utils.deepAccess(bid, 'params.zoneId')); - } - } - - if (bid.videoAdFormat && !adUnit.videoAdFormat) { - adUnit.videoAdFormat = bid.videoAdFormat; - } - - // determine adUnit.status from its bid statuses. Use priority below to determine, higher index is better - let statusPriority = ['error', 'no-bid', 'success']; - if (statusPriority.indexOf(bid.status) > statusPriority.indexOf(adUnit.status)) { - adUnit.status = bid.status; - } - - adUnit.bids.push(formatBid(bid)); - - return adUnits; - }, {}); - - // We need to mark each cached bid response with its appropriate rubicon site-zone id - // This allows the bidWon events to have these params even in the case of a delayed render - Object.keys(auctionCache.bids).forEach(function (bidId) { - let adCode = auctionCache.bids[bidId].adUnit.adUnitCode; - Object.assign(auctionCache.bids[bidId], utils.pick(adUnitMap[adCode], ['accountId', 'siteId', 'zoneId'])); - }); - - let auction = { - clientTimeoutMillis: auctionCache.timeout, - samplingFactor, - accountId, - adUnits: Object.keys(adUnitMap).map(i => adUnitMap[i]), - requestId: auctionId - }; - - // pick our of top level floor data we want to send! - if (auctionCache.floorData) { - if (auctionCache.floorData.location === 'noData') { - auction.floors = utils.pick(auctionCache.floorData, [ - 'location', - 'fetchStatus', - 'floorProvider as provider' - ]); - } else { - auction.floors = utils.pick(auctionCache.floorData, [ - 'location', - 'modelVersion as modelName', - 'modelWeight', - 'modelTimestamp', - 'skipped', - 'enforcement', () => utils.deepAccess(auctionCache.floorData, 'enforcements.enforceJS'), - 'dealsEnforced', () => utils.deepAccess(auctionCache.floorData, 'enforcements.floorDeals'), - 'skipRate', - 'fetchStatus', - 'floorMin', - 'floorProvider as provider' - ]); - } - } - - // gather gdpr info - if (auctionCache.gdprConsent) { - auction.gdpr = utils.pick(auctionCache.gdprConsent, [ - 'gdprApplies as applies', - 'consentString', - 'apiVersion as version' - ]); - } - - // gather session info - if (auctionCache.session) { - message.session = utils.pick(auctionCache.session, [ - 'id', - 'pvid', - 'start', - 'expires' - ]); - if (!utils.isEmpty(auctionCache.session.fpkvs)) { - message.fpkvs = Object.keys(auctionCache.session.fpkvs).map(key => { - return { key, value: auctionCache.session.fpkvs[key] }; - }); - } - } - - if (serverConfig) { - auction.serverTimeoutMillis = serverConfig.timeout; - } - - message.auctions = [auction]; - - let bidsWon = Object.keys(auctionCache.bidsWon).reduce((memo, adUnitCode) => { - let bidId = auctionCache.bidsWon[adUnitCode]; - if (bidId) { - memo.push(formatBidWon(auctionCache.bids[bidId])); - } - return memo; - }, []); - - if (bidsWon.length > 0) { - message.bidsWon = bidsWon; - } - - auctionCache.sent = true; - } else if (bidWonId && auctionCache && auctionCache.bids[bidWonId]) { - message.bidsWon = [ - formatBidWon(auctionCache.bids[bidWonId]) - ]; - } - - ajax( - this.getUrl(), - null, - JSON.stringify(message), - { - contentType: 'application/json' - } - ); -} - -function getBidPrice(bid) { - // get the cpm from bidResponse - let cpm; - let currency; - if (bid.status === BID_REJECTED && utils.deepAccess(bid, 'floorData.cpmAfterAdjustments')) { - // if bid was rejected and bid.floorData.cpmAfterAdjustments use it - cpm = bid.floorData.cpmAfterAdjustments; - currency = bid.floorData.floorCurrency; - } else if (typeof bid.currency === 'string' && bid.currency.toUpperCase() === 'USD') { - // bid is in USD use it - return Number(bid.cpm); - } else { - // else grab cpm - cpm = bid.cpm; - currency = bid.currency; - } - // if after this it is still going and is USD then return it. - if (currency === 'USD') { - return Number(cpm); - } - // otherwise we convert and return - try { - return Number(prebidGlobal.convertCurrency(cpm, currency, 'USD')); - } catch (err) { - utils.logWarn('Rubicon Analytics Adapter: Could not determine the bidPriceUSD of the bid ', bid); - } -} - -export function parseBidResponse(bid, previousBidResponse, auctionFloorData) { - // The current bidResponse for this matching requestId/bidRequestId - let responsePrice = getBidPrice(bid) - // we need to compare it with the previous one (if there was one) - if (previousBidResponse && previousBidResponse.bidPriceUSD > responsePrice) { - return previousBidResponse; - } - return utils.pick(bid, [ - 'bidPriceUSD', () => responsePrice, - 'dealId', - 'status', - 'mediaType', - 'dimensions', () => { - const width = bid.width || bid.playerWidth; - const height = bid.height || bid.playerHeight; - return (width && height) ? {width, height} : undefined; - }, - // Handling use case where pbs sends back 0 or '0' bidIds - 'pbsBidId', pbsBidId => pbsBidId == 0 ? utils.generateUUID() : pbsBidId, - 'seatBidId', seatBidId => seatBidId == 0 ? utils.generateUUID() : seatBidId, - 'floorValue', () => utils.deepAccess(bid, 'floorData.floorValue'), - 'floorRuleValue', () => utils.deepAccess(bid, 'floorData.floorRuleValue'), - 'floorRule', () => utils.debugTurnedOn() ? utils.deepAccess(bid, 'floorData.floorRule') : undefined, - 'adomains', () => { - let adomains = utils.deepAccess(bid, 'meta.advertiserDomains'); - return Array.isArray(adomains) && adomains.length > 0 ? adomains.slice(0, 10) : undefined - } - ]); -} - -/* - Filters and converts URL Params into an object and returns only KVs that match the 'utm_KEY' format -*/ -function getUtmParams() { - let search; - - try { - search = utils.parseQS(utils.getWindowLocation().search); - } catch (e) { - search = {}; - } - - return Object.keys(search).reduce((accum, param) => { - if (param.match(/utm_/)) { - accum[param.replace(/utm_/, '')] = search[param]; - } - return accum; - }, {}); -} - -function getFpkvs() { - rubiConf.fpkvs = Object.assign((rubiConf.fpkvs || {}), getUtmParams()); - - // convert all values to strings - Object.keys(rubiConf.fpkvs).forEach(key => { - rubiConf.fpkvs[key] = rubiConf.fpkvs[key] + ''; - }); - - return rubiConf.fpkvs; -} - -let samplingFactor = 1; -let accountId; -// List of known rubicon aliases -// This gets updated on auction init to account for any custom aliases present -let rubiconAliases = ['rubicon']; - -/* - Checks the alias registry for any entries of the rubicon bid adapter. - adds to the rubiconAliases list if found -*/ -function setRubiconAliases(aliasRegistry) { - Object.keys(aliasRegistry).forEach(function (alias) { - if (aliasRegistry[alias] === 'rubicon') { - rubiconAliases.push(alias); - } - }); -} - -function getRpaCookie() { - let encodedCookie = storage.getDataFromLocalStorage(COOKIE_NAME); - if (encodedCookie) { - try { - return JSON.parse(window.atob(encodedCookie)); - } catch (e) { - utils.logError(`Rubicon Analytics: Unable to decode ${COOKIE_NAME} value: `, e); - } - } - return {}; -} - -function setRpaCookie(decodedCookie) { - try { - storage.setDataInLocalStorage(COOKIE_NAME, window.btoa(JSON.stringify(decodedCookie))); - } catch (e) { - utils.logError(`Rubicon Analytics: Unable to encode ${COOKIE_NAME} value: `, e); - } -} - -function updateRpaCookie() { - const currentTime = Date.now(); - let decodedRpaCookie = getRpaCookie(); - if ( - !Object.keys(decodedRpaCookie).length || - (currentTime - decodedRpaCookie.lastSeen) > LAST_SEEN_EXPIRE_TIME || - decodedRpaCookie.expires < currentTime - ) { - decodedRpaCookie = { - id: utils.generateUUID(), - start: currentTime, - expires: currentTime + END_EXPIRE_TIME, // six hours later, - } - } - // possible that decodedRpaCookie is undefined, and if it is, we probably are blocked by storage or some other exception - if (Object.keys(decodedRpaCookie).length) { - decodedRpaCookie.lastSeen = currentTime; - decodedRpaCookie.fpkvs = {...decodedRpaCookie.fpkvs, ...getFpkvs()}; - decodedRpaCookie.pvid = rubiConf.pvid; - setRpaCookie(decodedRpaCookie) - } - return decodedRpaCookie; -} - -function subscribeToGamSlots() { - window.googletag.pubads().addEventListener('slotRenderEnded', event => { - const isMatchingAdSlot = utils.isAdUnitCodeMatchingSlot(event.slot); - // loop through auctions and adUnits and mark the info - Object.keys(cache.auctions).forEach(auctionId => { - (Object.keys(cache.auctions[auctionId].bids) || []).forEach(bidId => { - let bid = cache.auctions[auctionId].bids[bidId]; - // if this slot matches this bids adUnit, add the adUnit info - if (isMatchingAdSlot(bid.adUnit.adUnitCode)) { - // mark this adUnit as having been rendered by gam - cache.auctions[auctionId].gamHasRendered[bid.adUnit.adUnitCode] = true; - - bid.adUnit.gam = utils.pick(event, [ - // these come in as `null` from Gpt, which when stringified does not get removed - // so set explicitly to undefined when not a number - 'advertiserId', advertiserId => utils.isNumber(advertiserId) ? advertiserId : undefined, - 'creativeId', creativeId => utils.isNumber(event.sourceAgnosticCreativeId) ? event.sourceAgnosticCreativeId : utils.isNumber(creativeId) ? creativeId : undefined, - 'lineItemId', lineItemId => utils.isNumber(event.sourceAgnosticLineItemId) ? event.sourceAgnosticLineItemId : utils.isNumber(lineItemId) ? lineItemId : undefined, - 'adSlot', () => event.slot.getAdUnitPath(), - 'isSlotEmpty', () => event.isEmpty || undefined - ]); - } - }); - // Now if all adUnits have gam rendered, send the payload - if (rubiConf.waitForGamSlots && !cache.auctions[auctionId].sent && Object.keys(cache.auctions[auctionId].gamHasRendered).every(adUnitCode => cache.auctions[auctionId].gamHasRendered[adUnitCode])) { - clearTimeout(cache.timeouts[auctionId]); - delete cache.timeouts[auctionId]; - if (rubiConf.analyticsEventDelay > 0) { - setTimeout(() => sendMessage.call(rubiconAdapter, auctionId), rubiConf.analyticsEventDelay) - } else { - sendMessage.call(rubiconAdapter, auctionId) - } - } - }); - }); -} - -let baseAdapter = adapter({analyticsType: 'endpoint'}); -let rubiconAdapter = Object.assign({}, baseAdapter, { - referrerHostname: '', - enableAnalytics(config = {}) { - let error = false; - samplingFactor = 1; - - if (typeof config.options === 'object') { - if (config.options.accountId) { - accountId = Number(config.options.accountId); - } - if (config.options.endpoint) { - this.getUrl = () => config.options.endpoint; - } else { - utils.logError('required endpoint missing from rubicon analytics'); - error = true; - } - if (typeof config.options.sampling !== 'undefined') { - samplingFactor = 1 / parseFloat(config.options.sampling); - } - if (typeof config.options.samplingFactor !== 'undefined') { - if (typeof config.options.sampling !== 'undefined') { - utils.logWarn('Both options.samplingFactor and options.sampling enabled in rubicon analytics, defaulting to samplingFactor'); - } - samplingFactor = parseFloat(config.options.samplingFactor); - config.options.sampling = 1 / samplingFactor; - } - } - - let validSamplingFactors = [1, 10, 20, 40, 100]; - if (validSamplingFactors.indexOf(samplingFactor) === -1) { - error = true; - utils.logError('invalid samplingFactor for rubicon analytics: ' + samplingFactor + ', must be one of ' + validSamplingFactors.join(', ')); - } else if (!accountId) { - error = true; - utils.logError('required accountId missing for rubicon analytics'); - } - - if (!error) { - baseAdapter.enableAnalytics.call(this, config); - } - }, - disableAnalytics() { - this.getUrl = baseAdapter.getUrl; - accountId = undefined; - rubiConf = {}; - cache.gpt.registered = false; - baseAdapter.disableAnalytics.apply(this, arguments); - }, - track({eventType, args}) { - switch (eventType) { - case AUCTION_INIT: - // set the rubicon aliases - setRubiconAliases(adapterManager.aliasRegistry); - let cacheEntry = utils.pick(args, [ - 'timestamp', - 'timeout' - ]); - cacheEntry.bids = {}; - cacheEntry.bidsWon = {}; - cacheEntry.gamHasRendered = {}; - cacheEntry.referrer = utils.deepAccess(args, 'bidderRequests.0.refererInfo.referer'); - const floorData = utils.deepAccess(args, 'bidderRequests.0.bids.0.floorData'); - if (floorData) { - cacheEntry.floorData = {...floorData}; - } - cacheEntry.gdprConsent = utils.deepAccess(args, 'bidderRequests.0.gdprConsent'); - cacheEntry.session = storage.localStorageIsEnabled() && updateRpaCookie(); - cache.auctions[args.auctionId] = cacheEntry; - // register to listen to gpt events if not done yet - if (!cache.gpt.registered && utils.isGptPubadsDefined()) { - subscribeToGamSlots(); - cache.gpt.registered = true; - } else if (!cache.gpt.registered) { - cache.gpt.registered = true; - window.googletag = window.googletag || {}; - window.googletag.cmd = window.googletag.cmd || []; - window.googletag.cmd.push(function() { - subscribeToGamSlots(); - }); - } - break; - case BID_REQUESTED: - Object.assign(cache.auctions[args.auctionId].bids, args.bids.reduce((memo, bid) => { - // mark adUnits we expect bidWon events for - cache.auctions[args.auctionId].bidsWon[bid.adUnitCode] = false; - - if (rubiConf.waitForGamSlots) { - cache.auctions[args.auctionId].gamHasRendered[bid.adUnitCode] = false; - } - - memo[bid.bidId] = utils.pick(bid, [ - 'bidder', bidder => bidder.toLowerCase(), - 'bidId', - 'status', () => 'no-bid', // default a bid to no-bid until response is recieved or bid is timed out - 'source', () => formatSource(bid.src), - 'params', (params, bid) => { - switch (bid.bidder) { - // specify bidder params we want here - case 'rubicon': - return utils.pick(params, [ - 'accountId', - 'siteId', - 'zoneId' - ]); - } - }, - 'videoAdFormat', (_, cachedBid) => { - if (cachedBid.bidder === 'rubicon') { - return ({ - 201: 'pre-roll', - 202: 'interstitial', - 203: 'outstream', - 204: 'mid-roll', - 205: 'post-roll', - 207: 'vertical' - })[utils.deepAccess(bid, 'params.video.size_id')]; - } else { - let startdelay = parseInt(utils.deepAccess(bid, 'params.video.startdelay'), 10); - if (!isNaN(startdelay)) { - if (startdelay > 0) { - return 'mid-roll'; - } - return ({ - '0': 'pre-roll', - '-1': 'mid-roll', - '-2': 'post-roll' - })[startdelay] - } - } - }, - 'adUnit', () => utils.pick(bid, [ - 'adUnitCode', - 'transactionId', - 'sizes as dimensions', sizes => sizes.map(sizeToDimensions), - 'mediaTypes', (types) => { - if (bid.mediaType && validMediaType(bid.mediaType)) { - return [bid.mediaType]; - } - if (Array.isArray(types)) { - return types.filter(validMediaType); - } - if (typeof types === 'object') { - if (!bid.sizes) { - bid.dimensions = []; - utils._each(types, (type) => - bid.dimensions = bid.dimensions.concat( - type.sizes.map(sizeToDimensions) - ) - ); - } - return Object.keys(types).filter(validMediaType); - } - return ['banner']; - }, - 'gam', () => { - if (utils.deepAccess(bid, 'ortb2Imp.ext.data.adserver.name') === 'gam') { - return {adSlot: bid.ortb2Imp.ext.data.adserver.adSlot} - } - }, - 'pbAdSlot', () => utils.deepAccess(bid, 'ortb2Imp.ext.data.pbadslot'), - 'pattern', () => utils.deepAccess(bid, 'ortb2Imp.ext.data.aupname') - ]) - ]); - return memo; - }, {})); - break; - case BID_RESPONSE: - let auctionEntry = cache.auctions[args.auctionId]; - - if (!auctionEntry.bids[args.requestId] && args.originalRequestId) { - auctionEntry.bids[args.requestId] = {...auctionEntry.bids[args.originalRequestId]}; - auctionEntry.bids[args.requestId].bidId = args.requestId; - auctionEntry.bids[args.requestId].bidderDetail = args.targetingBidder; - } - - let bid = auctionEntry.bids[args.requestId]; - // If floor resolved gptSlot but we have not yet, then update the adUnit to have the adSlot name - if (!utils.deepAccess(bid, 'adUnit.gam.adSlot') && utils.deepAccess(args, 'floorData.matchedFields.gptSlot')) { - utils.deepSetValue(bid, 'adUnit.gam.adSlot', args.floorData.matchedFields.gptSlot); - } - // if we have not set enforcements yet set it - if (!utils.deepAccess(auctionEntry, 'floorData.enforcements') && utils.deepAccess(args, 'floorData.enforcements')) { - auctionEntry.floorData.enforcements = {...args.floorData.enforcements}; - } - if (!bid) { - utils.logError('Rubicon Anlytics Adapter Error: Could not find associated bid request for bid response with requestId: ', args.requestId); - break; - } - bid.source = formatSource(bid.source || args.source); - switch (args.getStatusCode()) { - case GOOD: - bid.status = 'success'; - delete bid.error; // it's possible for this to be set by a previous timeout - break; - case NO_BID: - bid.status = args.status === BID_REJECTED ? BID_REJECTED_IPF : 'no-bid'; - delete bid.error; - break; - default: - bid.status = 'error'; - bid.error = { - code: 'request-error' - }; - } - bid.clientLatencyMillis = bid.timeToRespond || Date.now() - cache.auctions[args.auctionId].timestamp; - bid.bidResponse = parseBidResponse(args, bid.bidResponse); - break; - case BIDDER_DONE: - const serverError = utils.deepAccess(args, 'serverErrors.0'); - const serverResponseTimeMs = args.serverResponseTimeMs; - args.bids.forEach(bid => { - let cachedBid = cache.auctions[bid.auctionId].bids[bid.bidId || bid.requestId]; - if (typeof bid.serverResponseTimeMs !== 'undefined') { - cachedBid.serverLatencyMillis = bid.serverResponseTimeMs; - } else if (serverResponseTimeMs && bid.source === 's2s') { - cachedBid.serverLatencyMillis = serverResponseTimeMs; - } - // if PBS said we had an error, and this bid has not been processed by BID_RESPONSE YET - if (serverError && (!cachedBid.status || ['no-bid', 'error'].indexOf(cachedBid.status) !== -1)) { - cachedBid.status = 'error'; - cachedBid.error = { - code: pbsErrorMap[serverError.code] || pbsErrorMap[999], - description: serverError.message - } - } - if (!cachedBid.status) { - cachedBid.status = 'no-bid'; - } - if (!cachedBid.clientLatencyMillis) { - cachedBid.clientLatencyMillis = Date.now() - cache.auctions[bid.auctionId].timestamp; - } - }); - break; - case SET_TARGETING: - Object.assign(cache.targeting, args); - break; - case BID_WON: - let auctionCache = cache.auctions[args.auctionId]; - auctionCache.bidsWon[args.adUnitCode] = args.requestId; - - // check if this BID_WON missed the boat, if so send by itself - if (auctionCache.sent === true) { - sendMessage.call(this, args.auctionId, args.requestId); - } else if (!rubiConf.waitForGamSlots && Object.keys(auctionCache.bidsWon).reduce((memo, adUnitCode) => { - // only send if we've received bidWon events for all adUnits in auction - memo = memo && auctionCache.bidsWon[adUnitCode]; - return memo; - }, true)) { - clearTimeout(cache.timeouts[args.auctionId]); - delete cache.timeouts[args.auctionId]; - - sendMessage.call(this, args.auctionId); - } - break; - case AUCTION_END: - // start timer to send batched payload just in case we don't hear any BID_WON events - cache.timeouts[args.auctionId] = setTimeout(() => { - sendMessage.call(this, args.auctionId); - }, rubiConf.analyticsBatchTimeout || SEND_TIMEOUT); - break; - case BID_TIMEOUT: - args.forEach(badBid => { - let auctionCache = cache.auctions[badBid.auctionId]; - let bid = auctionCache.bids[badBid.bidId || badBid.requestId]; - // might be set already by bidder-done, so do not overwrite - if (bid.status !== 'error') { - bid.status = 'error'; - bid.error = { - code: 'timeout-error', - message: 'marked by prebid.js as timeout' // will help us diff if timeout was set by PBS or PBJS - }; - } - }); - break; - } - } -}); - -adapterManager.registerAnalyticsAdapter({ - adapter: rubiconAdapter, - code: 'rubicon', - gvlid: RUBICON_GVL_ID -}); - -export default rubiconAdapter; diff --git a/modules/rubiconBidAdapter.js b/modules/rubiconBidAdapter.js deleted file mode 100644 index 078b5404baf..00000000000 --- a/modules/rubiconBidAdapter.js +++ /dev/null @@ -1,1250 +0,0 @@ -import * as utils 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 find from 'core-js-pure/features/array/find.js'; -import { Renderer } from '../src/Renderer.js'; -import { getGlobal } from '../src/prebidGlobal.js'; - -const DEFAULT_INTEGRATION = 'pbjs_lite'; -const DEFAULT_PBS_INTEGRATION = 'pbjs'; -const DEFAULT_RENDERER_URL = 'https://video-outstream.rubiconproject.com/apex-2.0.0.js'; -// renderer code at https://github.com/rubicon-project/apex2 - -let rubiConf = {}; -// we are saving these as global to this module so that if a pub accidentally overwrites the entire -// rubicon object, then we do not lose other data -config.getConfig('rubicon', config => { - utils.mergeDeep(rubiConf, config.rubicon); -}); - -const GVLID = 52; - -var sizeMap = { - 1: '468x60', - 2: '728x90', - 5: '120x90', - 7: '125x125', - 8: '120x600', - 9: '160x600', - 10: '300x600', - 13: '200x200', - 14: '250x250', - 15: '300x250', - 16: '336x280', - 17: '240x400', - 19: '300x100', - 31: '980x120', - 32: '250x360', - 33: '180x500', - 35: '980x150', - 37: '468x400', - 38: '930x180', - 39: '750x100', - 40: '750x200', - 41: '750x300', - 42: '2x4', - 43: '320x50', - 44: '300x50', - 48: '300x300', - 53: '1024x768', - 54: '300x1050', - 55: '970x90', - 57: '970x250', - 58: '1000x90', - 59: '320x80', - 60: '320x150', - 61: '1000x1000', - 64: '580x500', - 65: '640x480', - 66: '930x600', - 67: '320x480', - 68: '1800x1000', - 72: '320x320', - 73: '320x160', - 78: '980x240', - 79: '980x300', - 80: '980x400', - 83: '480x300', - 85: '300x120', - 90: '548x150', - 94: '970x310', - 95: '970x100', - 96: '970x210', - 101: '480x320', - 102: '768x1024', - 103: '480x280', - 105: '250x800', - 108: '320x240', - 113: '1000x300', - 117: '320x100', - 125: '800x250', - 126: '200x600', - 144: '980x600', - 145: '980x150', - 152: '1000x250', - 156: '640x320', - 159: '320x250', - 179: '250x600', - 195: '600x300', - 198: '640x360', - 199: '640x200', - 213: '1030x590', - 214: '980x360', - 221: '1x1', - 229: '320x180', - 230: '2000x1400', - 232: '580x400', - 234: '6x6', - 251: '2x2', - 256: '480x820', - 257: '400x600', - 258: '500x200', - 259: '998x200', - 264: '970x1000', - 265: '1920x1080', - 274: '1800x200', - 278: '320x500', - 282: '320x400', - 288: '640x380', - 548: '500x1000', - 550: '980x480', - 552: '300x200', - 558: '640x640' -}; -utils._each(sizeMap, (item, key) => sizeMap[item] = key); - -export const spec = { - code: 'rubicon', - gvlid: GVLID, - supportedMediaTypes: [BANNER, VIDEO], - /** - * @param {object} bid - * @return boolean - */ - isBidRequestValid: function (bid) { - if (typeof bid.params !== 'object') { - return false; - } - // validate account, site, zone have numeric values - for (let i = 0, props = ['accountId', 'siteId', 'zoneId']; i < props.length; i++) { - bid.params[props[i]] = parseInt(bid.params[props[i]]) - if (isNaN(bid.params[props[i]])) { - utils.logError('Rubicon: wrong format of accountId or siteId or zoneId.') - return false - } - } - let bidFormat = bidType(bid, true); - // bidType is undefined? Return false - if (!bidFormat) { - return false; - } else if (bidFormat === 'video') { // bidType is video, make sure it has required params - return hasValidVideoParams(bid); - } - // bidType is banner? return true - return true; - }, - /** - * @param {BidRequest[]} bidRequests - * @param bidderRequest - * @return BidRequest[] - */ - buildRequests: function (bidRequests, bidderRequest) { - // separate video bids because the requests are structured differently - let requests = []; - const videoRequests = bidRequests.filter(bidRequest => bidType(bidRequest) === 'video').map(bidRequest => { - bidRequest.startTime = new Date().getTime(); - - const data = { - id: bidRequest.transactionId, - test: config.getConfig('debug') ? 1 : 0, - cur: ['USD'], - source: { - tid: bidRequest.transactionId - }, - tmax: bidderRequest.timeout, - imp: [{ - exp: config.getConfig('s2sConfig.defaultTtl'), - id: bidRequest.adUnitCode, - secure: 1, - ext: { - [bidRequest.bidder]: bidRequest.params - }, - video: utils.deepAccess(bidRequest, 'mediaTypes.video') || {} - }], - ext: { - prebid: { - channel: { - name: 'pbjs', - version: $$PREBID_GLOBAL$$.version - }, - cache: { - vastxml: { - returnCreative: rubiConf.returnVast === true - } - }, - targeting: { - includewinners: true, - // includebidderkeys always false for openrtb - includebidderkeys: false, - pricegranularity: getPriceGranularity(config) - }, - bidders: { - rubicon: { - integration: rubiConf.int_type || DEFAULT_PBS_INTEGRATION - } - } - } - } - } - - // Add alias if it is there - if (bidRequest.bidder !== 'rubicon') { - data.ext.prebid.aliases = { - [bidRequest.bidder]: 'rubicon' - } - } - - let modules = (getGlobal()).installedModules; - if (modules && (!modules.length || modules.indexOf('rubiconAnalyticsAdapter') !== -1)) { - utils.deepSetValue(data, 'ext.prebid.analytics', {'rubicon': {'client-analytics': true}}); - } - - let bidFloor; - if (typeof bidRequest.getFloor === 'function' && !rubiConf.disableFloors) { - let floorInfo; - try { - floorInfo = bidRequest.getFloor({ - currency: 'USD', - mediaType: 'video', - size: parseSizes(bidRequest, 'video') - }); - } catch (e) { - utils.logError('Rubicon: getFloor threw an error: ', e); - } - bidFloor = typeof floorInfo === 'object' && floorInfo.currency === 'USD' && !isNaN(parseInt(floorInfo.floor)) ? parseFloat(floorInfo.floor) : undefined; - } else { - bidFloor = parseFloat(utils.deepAccess(bidRequest, 'params.floor')); - } - if (!isNaN(bidFloor)) { - data.imp[0].bidfloor = bidFloor; - } - // if value is set, will overwrite with same value - data.imp[0].ext[bidRequest.bidder].video.size_id = determineRubiconVideoSizeId(bidRequest) - - appendSiteAppDevice(data, bidRequest, bidderRequest); - - addVideoParameters(data, bidRequest); - - if (bidderRequest.gdprConsent) { - // note - gdprApplies & consentString may be undefined in certain use-cases for consentManagement module - let gdprApplies; - if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') { - gdprApplies = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; - } - - utils.deepSetValue(data, 'regs.ext.gdpr', gdprApplies); - utils.deepSetValue(data, 'user.ext.consent', bidderRequest.gdprConsent.consentString); - } - - if (bidderRequest.uspConsent) { - utils.deepSetValue(data, 'regs.ext.us_privacy', bidderRequest.uspConsent); - } - - const eids = utils.deepAccess(bidderRequest, 'bids.0.userIdAsEids'); - if (eids && eids.length) { - utils.deepSetValue(data, 'user.ext.eids', eids); - } - - // set user.id value from config value - const configUserId = config.getConfig('user.id'); - if (configUserId) { - utils.deepSetValue(data, 'user.id', configUserId); - } - - if (config.getConfig('coppa') === true) { - utils.deepSetValue(data, 'regs.coppa', 1); - } - - if (bidRequest.schain && hasValidSupplyChainParams(bidRequest.schain)) { - utils.deepSetValue(data, 'source.ext.schain', bidRequest.schain); - } - - const multibid = config.getConfig('multibid'); - if (multibid) { - utils.deepSetValue(data, 'ext.prebid.multibid', multibid.reduce((result, i) => { - let obj = {}; - - Object.keys(i).forEach(key => { - obj[key.toLowerCase()] = i[key]; - }); - - result.push(obj); - - return result; - }, [])); - } - - applyFPD(bidRequest, VIDEO, data); - - // if storedAuctionResponse has been set, pass SRID - if (bidRequest.storedAuctionResponse) { - utils.deepSetValue(data.imp[0], 'ext.prebid.storedauctionresponse.id', bidRequest.storedAuctionResponse.toString()); - } - - // set ext.prebid.auctiontimestamp using auction time - utils.deepSetValue(data.imp[0], 'ext.prebid.auctiontimestamp', bidderRequest.auctionStart); - - return { - method: 'POST', - url: `https://${rubiConf.videoHost || 'prebid-server'}.rubiconproject.com/openrtb2/auction`, - data, - bidRequest - } - }); - - if (rubiConf.singleRequest !== true) { - // bids are not grouped if single request mode is not enabled - requests = videoRequests.concat(bidRequests.filter(bidRequest => bidType(bidRequest) === 'banner').map(bidRequest => { - const bidParams = spec.createSlotParams(bidRequest, bidderRequest); - return { - method: 'GET', - url: `https://${rubiConf.bannerHost || 'fastlane'}.rubiconproject.com/a/api/fastlane.json`, - data: spec.getOrderedParams(bidParams).reduce((paramString, key) => { - const propValue = bidParams[key]; - return ((utils.isStr(propValue) && propValue !== '') || utils.isNumber(propValue)) ? `${paramString}${encodeParam(key, propValue)}&` : paramString; - }, '') + `slots=1&rand=${Math.random()}`, - bidRequest - }; - })); - } else { - // single request requires bids to be grouped by site id into a single request - // note: utils.groupBy wasn't used because deep property access was needed - const nonVideoRequests = bidRequests.filter(bidRequest => bidType(bidRequest) === 'banner'); - const groupedBidRequests = nonVideoRequests.reduce((groupedBids, bid) => { - (groupedBids[bid.params['siteId']] = groupedBids[bid.params['siteId']] || []).push(bid); - return groupedBids; - }, {}); - - // fastlane SRA has a limit of 10 slots - const SRA_BID_LIMIT = 10; - - // multiple requests are used if bids groups have more than 10 bids - requests = videoRequests.concat(Object.keys(groupedBidRequests).reduce((aggregate, bidGroupKey) => { - // for each partioned bidGroup, append a bidRequest to requests list - partitionArray(groupedBidRequests[bidGroupKey], SRA_BID_LIMIT).forEach(bidsInGroup => { - const combinedSlotParams = spec.combineSlotUrlParams(bidsInGroup.map(bidRequest => { - return spec.createSlotParams(bidRequest, bidderRequest); - })); - - // SRA request returns grouped bidRequest arrays not a plain bidRequest - aggregate.push({ - method: 'GET', - url: `https://${rubiConf.bannerHost || 'fastlane'}.rubiconproject.com/a/api/fastlane.json`, - data: spec.getOrderedParams(combinedSlotParams).reduce((paramString, key) => { - const propValue = combinedSlotParams[key]; - return ((utils.isStr(propValue) && propValue !== '') || utils.isNumber(propValue)) ? `${paramString}${encodeParam(key, propValue)}&` : paramString; - }, '') + `slots=${bidsInGroup.length}&rand=${Math.random()}`, - bidRequest: bidsInGroup - }); - }); - return aggregate; - }, [])); - } - return requests; - }, - - getOrderedParams: function(params) { - const containsTgV = /^tg_v/ - const containsTgI = /^tg_i/ - const containsUId = /^eid_|^tpid_/ - - const orderedParams = [ - 'account_id', - 'site_id', - 'zone_id', - 'size_id', - 'alt_size_ids', - 'p_pos', - 'gdpr', - 'gdpr_consent', - 'us_privacy', - 'rp_schain', - ].concat(Object.keys(params).filter(item => containsUId.test(item))) - .concat([ - 'x_liverampidl', - 'ppuid', - 'rf', - 'p_geo.latitude', - 'p_geo.longitude', - 'kw' - ]).concat(Object.keys(params).filter(item => containsTgV.test(item))) - .concat(Object.keys(params).filter(item => containsTgI.test(item))) - .concat([ - 'tk_flint', - 'x_source.tid', - 'x_source.pchain', - 'p_screen_res', - 'rp_floor', - 'rp_secure', - 'tk_user_key' - ]); - - return orderedParams.concat(Object.keys(params).filter(item => (orderedParams.indexOf(item) === -1))); - }, - - /** - * @summary combines param values from an array of slots into a single semicolon delineated value - * or just one value if they are all the same. - * @param {Object[]} aSlotUrlParams - example [{p1: 'foo', p2: 'test'}, {p2: 'test'}, {p1: 'bar', p2: 'test'}] - * @return {Object} - example {p1: 'foo;;bar', p2: 'test'} - */ - combineSlotUrlParams: function(aSlotUrlParams) { - // if only have params for one slot, return those params - if (aSlotUrlParams.length === 1) { - return aSlotUrlParams[0]; - } - - // reduce param values from all slot objects into an array of values in a single object - const oCombinedSlotUrlParams = aSlotUrlParams.reduce(function(oCombinedParams, oSlotUrlParams, iIndex) { - Object.keys(oSlotUrlParams).forEach(function(param) { - if (!oCombinedParams.hasOwnProperty(param)) { - oCombinedParams[param] = new Array(aSlotUrlParams.length); // initialize array; - } - // insert into the proper element of the array - oCombinedParams[param].splice(iIndex, 1, oSlotUrlParams[param]); - }); - - return oCombinedParams; - }, {}); - - // convert arrays into semicolon delimited strings - const re = new RegExp('^([^;]*)(;\\1)+$'); // regex to test for duplication - - Object.keys(oCombinedSlotUrlParams).forEach(function(param) { - const sValues = oCombinedSlotUrlParams[param].join(';'); - // consolidate param values into one value if they are all the same - const match = sValues.match(re); - oCombinedSlotUrlParams[param] = match ? match[1] : sValues; - }); - - return oCombinedSlotUrlParams; - }, - - /** - * @param {BidRequest} bidRequest - * @param {Object} bidderRequest - * @returns {Object} - object key values named and formatted as slot params - */ - createSlotParams: function(bidRequest, bidderRequest) { - bidRequest.startTime = new Date().getTime(); - - const params = bidRequest.params; - - // use rubicon sizes if provided, otherwise adUnit.sizes - const parsedSizes = parseSizes(bidRequest, 'banner'); - - const [latitude, longitude] = params.latLong || []; - - const data = { - 'account_id': params.accountId, - 'site_id': params.siteId, - 'zone_id': params.zoneId, - 'size_id': parsedSizes[0], - 'alt_size_ids': parsedSizes.slice(1).join(',') || undefined, - 'rp_floor': (params.floor = parseFloat(params.floor)) >= 0.01 ? params.floor : undefined, - 'rp_secure': '1', - 'tk_flint': `${rubiConf.int_type || DEFAULT_INTEGRATION}_v$prebid.version$`, - 'x_source.tid': bidRequest.transactionId, - 'x_source.pchain': params.pchain, - 'p_screen_res': _getScreenResolution(), - 'tk_user_key': params.userId, - 'p_geo.latitude': isNaN(parseFloat(latitude)) ? undefined : parseFloat(latitude).toFixed(4), - 'p_geo.longitude': isNaN(parseFloat(longitude)) ? undefined : parseFloat(longitude).toFixed(4), - 'tg_fl.eid': bidRequest.code, - 'rf': _getPageUrl(bidRequest, bidderRequest) - }; - - // If floors module is enabled and we get USD floor back, send it in rp_hard_floor else undfined - if (typeof bidRequest.getFloor === 'function' && !rubiConf.disableFloors) { - let floorInfo; - try { - floorInfo = bidRequest.getFloor({ - currency: 'USD', - mediaType: 'banner', - size: '*' - }); - } catch (e) { - utils.logError('Rubicon: getFloor threw an error: ', e); - } - data['rp_hard_floor'] = typeof floorInfo === 'object' && floorInfo.currency === 'USD' && !isNaN(parseInt(floorInfo.floor)) ? floorInfo.floor : undefined; - } - - // 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 - data['p_pos'] = (params.position === 'atf' || params.position === 'btf') ? params.position : ''; - - // pass publisher provided userId if configured - const configUserId = config.getConfig('user.id'); - if (configUserId) { - data['ppuid'] = configUserId; - } - // loop through userIds and add to request - if (bidRequest.userIdAsEids) { - bidRequest.userIdAsEids.forEach(eid => { - try { - // special cases - if (eid.source === 'adserver.org') { - data['tpid_tdid'] = eid.uids[0].id; - data['eid_adserver.org'] = eid.uids[0].id; - } else if (eid.source === 'liveintent.com') { - data['tpid_liveintent.com'] = eid.uids[0].id; - data['eid_liveintent.com'] = eid.uids[0].id; - if (eid.ext && Array.isArray(eid.ext.segments) && eid.ext.segments.length) { - data['tg_v.LIseg'] = eid.ext.segments.join(','); - } - } else if (eid.source === 'liveramp.com') { - data['x_liverampidl'] = eid.uids[0].id; - } else if (eid.source === 'sharedid.org') { - data['eid_sharedid.org'] = `${eid.uids[0].id}^${eid.uids[0].atype}^${(eid.uids[0].ext && eid.uids[0].ext.third) || ''}`; - } else if (eid.source === 'id5-sync.com') { - data['eid_id5-sync.com'] = `${eid.uids[0].id}^${eid.uids[0].atype}^${(eid.uids[0].ext && eid.uids[0].ext.linkType) || ''}`; - } else { - // add anything else with this generic format - data[`eid_${eid.source}`] = `${eid.uids[0].id}^${eid.uids[0].atype || ''}`; - } - // send AE "ppuid" signal if exists, and hasn't already been sent - if (!data['ppuid']) { - // get the first eid.uids[*].ext.stype === 'ppuid', if one exists - const ppId = find(eid.uids, uid => uid.ext && uid.ext.stype === 'ppuid'); - if (ppId && ppId.id) { - data['ppuid'] = ppId.id; - } - } - } catch (e) { - utils.logWarn('Rubicon: error reading eid:', eid, e); - } - }); - } - - if (bidderRequest.gdprConsent) { - // add 'gdpr' only if 'gdprApplies' is defined - if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') { - data['gdpr'] = Number(bidderRequest.gdprConsent.gdprApplies); - } - data['gdpr_consent'] = bidderRequest.gdprConsent.consentString; - } - - if (bidderRequest.uspConsent) { - data['us_privacy'] = encodeURIComponent(bidderRequest.uspConsent); - } - - data['rp_maxbids'] = bidderRequest.bidLimit || 1; - - applyFPD(bidRequest, BANNER, data); - - if (config.getConfig('coppa') === true) { - data['coppa'] = 1; - } - - // if SupplyChain is supplied and contains all required fields - if (bidRequest.schain && hasValidSupplyChainParams(bidRequest.schain)) { - data.rp_schain = spec.serializeSupplyChain(bidRequest.schain); - } - - return data; - }, - - /** - * Serializes schain params according to OpenRTB requirements - * @param {Object} supplyChain - * @returns {String} - */ - serializeSupplyChain: function (supplyChain) { - const supplyChainIsValid = hasValidSupplyChainParams(supplyChain); - if (!supplyChainIsValid) return ''; - const { ver, complete, nodes } = supplyChain; - return `${ver},${complete}!${spec.serializeSupplyChainNodes(nodes)}`; - }, - - /** - * Properly sorts schain object params - * @param {Array} nodes - * @returns {String} - */ - serializeSupplyChainNodes: function (nodes) { - const nodePropOrder = ['asi', 'sid', 'hp', 'rid', 'name', 'domain']; - return nodes.map(node => { - return nodePropOrder.map(prop => encodeURIComponent(node[prop] || '')).join(','); - }).join('!'); - }, - - /** - * @param {*} responseObj - * @param {BidRequest|Object.} bidRequest - if request was SRA the bidRequest argument will be a keyed BidRequest array object, - * non-SRA responses return a plain BidRequest object - * @return {Bid[]} An array of bids which - */ - interpretResponse: function (responseObj, {bidRequest}) { - responseObj = responseObj.body; - - // check overall response - if (!responseObj || typeof responseObj !== 'object') { - return []; - } - - // video response from PBS Java openRTB - if (responseObj.seatbid) { - const responseErrors = utils.deepAccess(responseObj, 'ext.errors.rubicon'); - if (Array.isArray(responseErrors) && responseErrors.length > 0) { - utils.logWarn('Rubicon: Error in video response'); - } - const bids = []; - responseObj.seatbid.forEach(seatbid => { - (seatbid.bid || []).forEach(bid => { - let bidObject = { - requestId: bidRequest.bidId, - currency: responseObj.cur || 'USD', - creativeId: bid.crid, - cpm: bid.price || 0, - bidderCode: seatbid.seat, - ttl: 300, - netRevenue: rubiConf.netRevenue !== false, // If anything other than false, netRev is true - width: bid.w || utils.deepAccess(bidRequest, 'mediaTypes.video.w') || utils.deepAccess(bidRequest, 'params.video.playerWidth'), - height: bid.h || utils.deepAccess(bidRequest, 'mediaTypes.video.h') || utils.deepAccess(bidRequest, 'params.video.playerHeight'), - }; - - if (bid.id) { - bidObject.seatBidId = bid.id; - } - - if (bid.dealid) { - bidObject.dealId = bid.dealid; - } - - if (bid.adomain) { - utils.deepSetValue(bidObject, 'meta.advertiserDomains', Array.isArray(bid.adomain) ? bid.adomain : [bid.adomain]); - } - - if (utils.deepAccess(bid, 'ext.bidder.rp.advid')) { - utils.deepSetValue(bidObject, 'meta.advertiserId', bid.ext.bidder.rp.advid); - } - - let serverResponseTimeMs = utils.deepAccess(responseObj, 'ext.responsetimemillis.rubicon'); - if (bidRequest && serverResponseTimeMs) { - bidRequest.serverResponseTimeMs = serverResponseTimeMs; - } - - if (utils.deepAccess(bid, 'ext.prebid.type') === VIDEO) { - bidObject.mediaType = VIDEO; - utils.deepSetValue(bidObject, 'meta.mediaType', VIDEO); - const extPrebidTargeting = utils.deepAccess(bid, 'ext.prebid.targeting'); - - // If ext.prebid.targeting exists, add it as a property value named 'adserverTargeting' - if (extPrebidTargeting && typeof extPrebidTargeting === 'object') { - bidObject.adserverTargeting = extPrebidTargeting; - } - - // try to get cache values from 'response.ext.prebid.cache.js' - // else try 'bid.ext.prebid.targeting' as fallback - if (bid.ext.prebid.cache && typeof bid.ext.prebid.cache.vastXml === 'object' && bid.ext.prebid.cache.vastXml.cacheId && bid.ext.prebid.cache.vastXml.url) { - bidObject.videoCacheKey = bid.ext.prebid.cache.vastXml.cacheId; - bidObject.vastUrl = bid.ext.prebid.cache.vastXml.url; - } else if (extPrebidTargeting && extPrebidTargeting.hb_uuid && extPrebidTargeting.hb_cache_host && extPrebidTargeting.hb_cache_path) { - bidObject.videoCacheKey = extPrebidTargeting.hb_uuid; - // build url using key and cache host - bidObject.vastUrl = `https://${extPrebidTargeting.hb_cache_host}${extPrebidTargeting.hb_cache_path}?uuid=${extPrebidTargeting.hb_uuid}`; - } - - if (bid.adm) { bidObject.vastXml = bid.adm; } - if (bid.nurl) { bidObject.vastUrl = bid.nurl; } - if (!bidObject.vastUrl && bid.nurl) { bidObject.vastUrl = bid.nurl; } - - const videoContext = utils.deepAccess(bidRequest, 'mediaTypes.video.context'); - if (videoContext.toLowerCase() === 'outstream') { - bidObject.renderer = outstreamRenderer(bidObject); - } - } else { - utils.logWarn('Rubicon: video response received non-video media type'); - } - - bids.push(bidObject); - }); - }); - - return bids; - } - - let ads = responseObj.ads; - let lastImpId; - let multibid = 0; - - // video ads array is wrapped in an object - if (typeof bidRequest === 'object' && !Array.isArray(bidRequest) && bidType(bidRequest) === 'video' && typeof ads === 'object') { - ads = ads[bidRequest.adUnitCode]; - } - - // check the ad response - if (!Array.isArray(ads) || ads.length < 1) { - return []; - } - - return ads.reduce((bids, ad, i) => { - (ad.impression_id && lastImpId === ad.impression_id) ? multibid++ : lastImpId = ad.impression_id; - - if (ad.status !== 'ok') { - return bids; - } - - // associate bidRequests; assuming ads matches bidRequest - const associatedBidRequest = Array.isArray(bidRequest) ? bidRequest[i - multibid] : bidRequest; - - if (associatedBidRequest && typeof associatedBidRequest === 'object') { - let bid = { - requestId: associatedBidRequest.bidId, - currency: 'USD', - creativeId: ad.creative_id || `${ad.network || ''}-${ad.advertiser || ''}`, - cpm: ad.cpm || 0, - dealId: ad.deal, - ttl: 300, // 5 minutes - netRevenue: rubiConf.netRevenue !== false, // If anything other than false, netRev is true - rubicon: { - advertiserId: ad.advertiser, networkId: ad.network - }, - meta: { - advertiserId: ad.advertiser, networkId: ad.network, mediaType: BANNER - } - }; - - if (ad.creative_type) { - bid.mediaType = ad.creative_type; - } - - if (ad.adomain) { - bid.meta.advertiserDomains = Array.isArray(ad.adomain) ? ad.adomain : [ad.adomain]; - } - - if (ad.creative_type === VIDEO) { - bid.width = associatedBidRequest.params.video.playerWidth; - bid.height = associatedBidRequest.params.video.playerHeight; - bid.vastUrl = ad.creative_depot_url; - bid.impression_id = ad.impression_id; - bid.videoCacheKey = ad.impression_id; - } else { - bid.ad = _renderCreative(ad.script, ad.impression_id); - [bid.width, bid.height] = sizeMap[ad.size_id].split('x').map(num => Number(num)); - } - - // add server-side targeting - bid.rubiconTargeting = (Array.isArray(ad.targeting) ? ad.targeting : []) - .reduce((memo, item) => { - memo[item.key] = item.values[0]; - return memo; - }, {'rpfl_elemid': associatedBidRequest.adUnitCode}); - - bids.push(bid); - } else { - utils.logError(`Rubicon: bidRequest undefined at index position:${i}`, bidRequest, responseObj); - } - - return bids; - }, []).sort((adA, adB) => { - return (adB.cpm || 0.0) - (adA.cpm || 0.0); - }); - }, - getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent) { - if (!hasSynced && syncOptions.iframeEnabled) { - // data is only assigned if params are available to pass to syncEndpoint - let params = ''; - - if (gdprConsent && typeof gdprConsent.consentString === 'string') { - // add 'gdpr' only if 'gdprApplies' is defined - if (typeof gdprConsent.gdprApplies === 'boolean') { - params += `?gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - params += `?gdpr_consent=${gdprConsent.consentString}`; - } - } - - if (uspConsent) { - params += `${params ? '&' : '?'}us_privacy=${encodeURIComponent(uspConsent)}`; - } - - hasSynced = true; - return { - type: 'iframe', - url: `https://${rubiConf.syncHost || 'eus'}.rubiconproject.com/usync.html` + params - }; - } - }, - /** - * Covert bid param types for S2S - * @param {Object} params bid params - * @param {Boolean} isOpenRtb boolean to check openrtb2 protocol - * @return {Object} params bid params - */ - transformBidParams: function(params, isOpenRtb) { - return utils.convertTypes({ - 'accountId': 'number', - 'siteId': 'number', - 'zoneId': 'number' - }, params); - } -}; - -function _getScreenResolution() { - return [window.screen.width, window.screen.height].join('x'); -} - -/** - * @param {BidRequest} bidRequest - * @param bidderRequest - * @returns {string} - */ -function _getPageUrl(bidRequest, bidderRequest) { - let pageUrl = config.getConfig('pageUrl'); - if (bidRequest.params.referrer) { - pageUrl = bidRequest.params.referrer; - } else if (!pageUrl) { - pageUrl = bidderRequest.refererInfo.referer; - } - return bidRequest.params.secure ? pageUrl.replace(/^http:/i, 'https:') : pageUrl; -} - -function _renderCreative(script, impId) { - return ` - - - -
- -
- -`; -} - -function hideGoogleAdsDiv(adUnit) { - const el = adUnit.querySelector("div[id^='google_ads']"); - if (el) { - el.style.setProperty('display', 'none'); - } -} - -function hideSmartAdServerIframe(adUnit) { - const el = adUnit.querySelector("script[id^='sas_script']"); - const nextSibling = el && el.nextSibling; - if (nextSibling && nextSibling.localName === 'iframe') { - nextSibling.style.setProperty('display', 'none'); - } -} - -function renderBid(bid) { - // hide existing ad units - const adUnitElement = document.getElementById(bid.adUnitCode); - hideGoogleAdsDiv(adUnitElement); - hideSmartAdServerIframe(adUnitElement); - - // configure renderer - const config = bid.renderer.getConfig(); - bid.renderer.push(() => { - window.MagniteApex.renderAd({ - width: bid.width, - height: bid.height, - vastUrl: bid.vastUrl, - placement: { - attachTo: `#${bid.adUnitCode}`, - align: config.align || 'center', - position: config.position || 'append' - }, - closeButton: config.closeButton || false, - label: config.label || undefined, - collapse: config.collapse || true - }); - }); -} - -function outstreamRenderer(rtbBid) { - const renderer = Renderer.install({ - id: rtbBid.adId, - url: rubiConf.rendererUrl || DEFAULT_RENDERER_URL, - config: rubiConf.rendererConfig || {}, - loaded: false, - adUnitCode: rtbBid.adUnitCode - }); - - try { - renderer.setRender(renderBid); - } catch (err) { - utils.logWarn('Prebid Error calling setRender on renderer', err); - } - - return renderer; -} - -function parseSizes(bid, mediaType) { - let params = bid.params; - if (mediaType === 'video') { - let size = []; - if (params.video && params.video.playerWidth && params.video.playerHeight) { - size = [ - params.video.playerWidth, - params.video.playerHeight - ]; - } else if (Array.isArray(utils.deepAccess(bid, 'mediaTypes.video.playerSize')) && bid.mediaTypes.video.playerSize.length === 1) { - size = bid.mediaTypes.video.playerSize[0]; - } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0 && Array.isArray(bid.sizes[0]) && bid.sizes[0].length > 1) { - size = bid.sizes[0]; - } - return size; - } - - // deprecated: temp legacy support - let sizes = []; - if (Array.isArray(params.sizes)) { - sizes = params.sizes; - } else if (typeof utils.deepAccess(bid, 'mediaTypes.banner.sizes') !== 'undefined') { - sizes = mapSizes(bid.mediaTypes.banner.sizes); - } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) { - sizes = mapSizes(bid.sizes) - } else { - utils.logWarn('Rubicon: no sizes are setup or found'); - } - - return masSizeOrdering(sizes); -} - -/** - * @param {Object} data - * @param bidRequest - * @param bidderRequest - */ -function appendSiteAppDevice(data, bidRequest, bidderRequest) { - if (!data) return; - - // ORTB specifies app OR site - if (typeof config.getConfig('app') === 'object') { - data.app = config.getConfig('app'); - } else { - data.site = { - page: _getPageUrl(bidRequest, bidderRequest) - } - } - if (typeof config.getConfig('device') === 'object') { - data.device = config.getConfig('device'); - } - // Add language to site and device objects if there - if (bidRequest.params.video.language) { - ['site', 'device'].forEach(function(param) { - if (data[param]) { - data[param].content = Object.assign({language: bidRequest.params.video.language}, data[param].content) - } - }); - } -} - -/** - * @param {Object} data - * @param {BidRequest} bidRequest - */ -function addVideoParameters(data, bidRequest) { - if (typeof data.imp[0].video === 'object' && data.imp[0].video.skip === undefined) { - data.imp[0].video.skip = bidRequest.params.video.skip; - } - if (typeof data.imp[0].video === 'object' && data.imp[0].video.skipafter === undefined) { - data.imp[0].video.skipafter = bidRequest.params.video.skipdelay; - } - // video.pos can already be specified by adunit.mediatypes.video.pos. - // but if not, it might be specified in the params - if (typeof data.imp[0].video === 'object' && data.imp[0].video.pos === undefined) { - if (bidRequest.params.position === 'atf') { - data.imp[0].video.pos = 1; - } else if (bidRequest.params.position === 'btf') { - data.imp[0].video.pos = 3; - } - } - - const size = parseSizes(bidRequest, 'video') - data.imp[0].video.w = size[0] - data.imp[0].video.h = size[1] -} - -function applyFPD(bidRequest, mediaType, data) { - const BID_FPD = { - user: {ext: {data: {...bidRequest.params.visitor}}}, - site: {ext: {data: {...bidRequest.params.inventory}}} - }; - - if (bidRequest.params.keywords) BID_FPD.site.keywords = (utils.isArray(bidRequest.params.keywords)) ? bidRequest.params.keywords.join(',') : bidRequest.params.keywords; - - let fpd = utils.mergeDeep({}, config.getConfig('ortb2') || {}, BID_FPD); - let impData = utils.deepAccess(bidRequest.ortb2Imp, 'ext.data') || {}; - const SEGTAX = {user: [3], site: [1, 2]}; - 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 && utils.deepAccess(name, 'ext.segtax') && SEGTAX[parentName] && - SEGTAX[parentName].indexOf(utils.deepAccess(name, 'ext.segtax')) !== -1).map(value => { - let segments = value.segment.filter(obj => obj.id).reduce((result, obj) => { - result.push(obj.id); - return result; - }, []); - if (segments.length > 0) return segments.toString(); - }).toString(); - } else if (typeof prop === 'object' && !Array.isArray(prop)) { - utils.logWarn('Rubicon: Filtered FPD key: ', key, ': Expected value to be string, integer, or an array of strings/ints'); - } else if (typeof prop !== 'undefined') { - return (Array.isArray(prop)) ? prop.filter(value => { - if (typeof value !== 'object' && typeof value !== 'undefined') return value.toString(); - - utils.logWarn('Rubicon: Filtered value: ', value, 'for key', key, ': Expected value to be string, integer, or an array of strings/ints'); - }).toString() : prop.toString(); - } - }; - const addBannerData = function(obj, name, key, isParent = true) { - let val = validate(obj, key, name); - let loc = (MAP[key] && isParent) ? `${MAP[key]}` : (key === 'data') ? `${MAP[name]}iab` : `${MAP[name]}${key}`; - data[loc] = (data[loc]) ? data[loc].concat(',', val) : val; - } - - Object.keys(impData).forEach((key) => { - if (key === 'adserver') { - ['name', 'adslot'].forEach(prop => { - if (impData[key][prop]) impData[key][prop] = impData[key][prop].toString().replace(/^\/+/, ''); - }); - } else if (key === 'pbadslot') { - impData[key] = impData[key].toString().replace(/^\/+/, ''); - } - }); - - if (mediaType === BANNER) { - ['site', 'user'].forEach(name => { - Object.keys(fpd[name]).forEach((key) => { - if (name === 'site' && key === 'content' && fpd[name][key].data) { - addBannerData(fpd[name][key].data, name, 'data'); - } else if (key !== 'ext') { - addBannerData(fpd[name][key], name, key); - } else if (fpd[name][key].data) { - Object.keys(fpd[name].ext.data).forEach((key) => { - addBannerData(fpd[name].ext.data[key], name, key, false); - }); - } - }); - }); - Object.keys(impData).forEach((key) => { - (key === 'adserver') ? addBannerData(impData[key].adslot, name, key) : addBannerData(impData[key], 'site', key); - }); - } else { - if (Object.keys(impData).length) { - utils.mergeDeep(data.imp[0].ext, {data: impData}); - } - - utils.mergeDeep(data, fpd); - } -} - -/** - * @param sizes - * @returns {*} - */ -function mapSizes(sizes) { - return utils.parseSizesInput(sizes) - // map sizes while excluding non-matches - .reduce((result, size) => { - let mappedSize = parseInt(sizeMap[size], 10); - if (mappedSize) { - result.push(mappedSize); - } - return result; - }, []); -} - -/** - * Test if bid has mediaType or mediaTypes set for video. - * Also makes sure the video object is present in the rubicon bidder params - * @param {BidRequest} bidRequest - * @returns {boolean} - */ -export function hasVideoMediaType(bidRequest) { - if (typeof utils.deepAccess(bidRequest, 'params.video') !== 'object') { - return false; - } - return (typeof utils.deepAccess(bidRequest, `mediaTypes.${VIDEO}`) !== 'undefined'); -} - -/** - * Determine bidRequest mediaType - * @param bid the bid to test - * @param log whether we should log errors/warnings for invalid bids - * @returns {string|undefined} Returns 'video' or 'banner' if resolves to a type, or undefined otherwise (invalid). - */ -function bidType(bid, log = false) { - // Is it considered video ad unit by rubicon - if (hasVideoMediaType(bid)) { - // Removed legacy mediaType support. new way using mediaTypes.video object is now required - // We require either context as instream or outstream - if (['outstream', 'instream'].indexOf(utils.deepAccess(bid, `mediaTypes.${VIDEO}.context`)) === -1) { - if (log) { - utils.logError('Rubicon: mediaTypes.video.context must be outstream or instream'); - } - return; - } - - // we require playerWidth and playerHeight to come from one of params.playerWidth/playerHeight or mediaTypes.video.playerSize or adUnit.sizes - if (parseSizes(bid, 'video').length < 2) { - if (log) { - utils.logError('Rubicon: could not determine the playerSize of the video'); - } - return; - } - - if (log) { - utils.logMessage('Rubicon: making video request for adUnit', bid.adUnitCode); - } - return 'video'; - } else { - // we require banner sizes to come from one of params.sizes or mediaTypes.banner.sizes or adUnit.sizes, in that order - // if we cannot determine them, we reject it! - if (parseSizes(bid, 'banner').length === 0) { - if (log) { - utils.logError('Rubicon: could not determine the sizes for banner request'); - } - return; - } - - // everything looks good for banner so lets do it - if (log) { - utils.logMessage('Rubicon: making banner request for adUnit', bid.adUnitCode); - } - return 'banner'; - } -} - -export const resetRubiConf = () => rubiConf = {}; -export function masSizeOrdering(sizes) { - const MAS_SIZE_PRIORITY = [15, 2, 9]; - - return sizes.sort((first, second) => { - // sort by MAS_SIZE_PRIORITY priority order - const firstPriority = MAS_SIZE_PRIORITY.indexOf(first); - const secondPriority = MAS_SIZE_PRIORITY.indexOf(second); - - if (firstPriority > -1 || secondPriority > -1) { - if (firstPriority === -1) { - return 1; - } - if (secondPriority === -1) { - return -1; - } - return firstPriority - secondPriority; - } - - // and finally ascending order - return first - second; - }); -} - -export function determineRubiconVideoSizeId(bid) { - // If we have size_id in the bid then use it - let rubiconSizeId = parseInt(utils.deepAccess(bid, 'params.video.size_id')); - if (!isNaN(rubiconSizeId)) { - return rubiconSizeId; - } - // otherwise 203 for outstream and 201 for instream - // When this function is used we know it has to be one of outstream or instream - return utils.deepAccess(bid, `mediaTypes.${VIDEO}.context`) === 'outstream' ? 203 : 201; -} - -/** - * @param {PrebidConfig} config - * @returns {{ranges: {ranges: Object[]}}} - */ -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}], - 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} - ], - 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} - ], - custom: config.getConfig('customPriceBucket') && config.getConfig('customPriceBucket').buckets - }[config.getConfig('priceGranularity')] - }; -} - -// Function to validate the required video params -export function hasValidVideoParams(bid) { - let isValid = true; - // incase future javascript changes the string represenation of the array or number classes! - let arrayType = Object.prototype.toString.call([]); - let numberType = Object.prototype.toString.call(0); - // required params and their associated object type - var requiredParams = { - mimes: arrayType, - protocols: arrayType, - linearity: numberType, - api: arrayType - } - // loop through each param and verify it has the correct - Object.keys(requiredParams).forEach(function(param) { - if (Object.prototype.toString.call(utils.deepAccess(bid, 'mediaTypes.video.' + param)) !== requiredParams[param]) { - isValid = false; - utils.logError('Rubicon: mediaTypes.video.' + param + ' is required and must be of type: ' + requiredParams[param]); - } - }) - return isValid; -} - -/** - * Make sure the required params are present - * @param {Object} schain - * @param {Bool} - */ -export function hasValidSupplyChainParams(schain) { - let isValid = false; - const requiredFields = ['asi', 'sid', 'hp']; - if (!schain.nodes) return isValid; - isValid = schain.nodes.reduce((status, node) => { - if (!status) return status; - return requiredFields.every(field => node.hasOwnProperty(field)); - }, true); - if (!isValid) utils.logError('Rubicon: required schain params missing'); - return isValid; -} - -/** - * Creates a URL key value param, encoding the - * param unless the key is schain - * @param {String} key - * @param {String} param - * @returns {String} - */ -export function encodeParam(key, param) { - if (key === 'rp_schain') return `rp_schain=${param}`; - return `${key}=${encodeURIComponent(param)}`; -} - -/** - * split array into multiple arrays of defined size - * @param {Array} array - * @param {number} size - * @returns {Array} - */ -function partitionArray(array, size) { - return array.map((e, i) => (i % size === 0) ? array.slice(i, i + size) : null).filter((e) => e) -} - -var hasSynced = false; - -export function resetUserSync() { - hasSynced = false; -} - -registerBidder(spec); diff --git a/modules/rubiconBidAdapter.md b/modules/rubiconBidAdapter.md deleted file mode 100644 index 0ef22a81972..00000000000 --- a/modules/rubiconBidAdapter.md +++ /dev/null @@ -1,82 +0,0 @@ -# Overview - -``` -Module Name: Rubicon Project Bid Adapter -Module Type: Bidder Adapter -Maintainer: header-bidding@rubiconproject.com -``` - -# Description - -Connect to Rubicon Project's exchange for bids. - -The Rubicon Project adapter requires setup and approval from the -Rubicon Project team. Please reach out to your account team or -globalsupport@rubiconproject.com for more information. - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [ - { - bidder: "rubicon", - params: { - accountId: 14062, - siteId: 70608, - zoneId: 498816 - } - } - ] - },{ - code: 'test-native-size', - mediaTypes: { - banner: { - sizes: [[300, 50]] - } - }, - bids: [ - { - bidder: "rubicon", - params: { - accountId: 14062, - siteId: 70608, - zoneId: 498816 - } - } - ] - } - ]; - - var videoAdUnit = { - code: 'myVideoAdUnit', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480], - mimes: ['video/mp4', 'video/x-ms-wmv'], - protocols: [2,5], - maxduration:30, - linearity: 1, - api: [2] - } - }, - bids: [{ - bidder: 'rubicon', - params: { - accountId: 7780, - siteId: 87184, - zoneId: 412394, - video: { - language: 'en' - } - } - }] -}; -``` diff --git a/modules/s2sTesting.js b/modules/s2sTesting.js deleted file mode 100644 index 1f2bb473174..00000000000 --- a/modules/s2sTesting.js +++ /dev/null @@ -1,85 +0,0 @@ -import { setS2STestingModule } from '../src/adapterManager.js'; - -let s2sTesting = {}; - -const SERVER = 'server'; -const CLIENT = 'client'; - -s2sTesting.SERVER = SERVER; -s2sTesting.CLIENT = CLIENT; - -s2sTesting.bidSource = {}; // store bidder sources determined from s2sConfig bidderControl -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]: {}}; - - adUnits.forEach((adUnit) => { - // if any adUnit bidders specify a bidSource, include them - (adUnit.bids || []).forEach((bid) => { - // When a s2sConfig does not have testing=true and did not calc bid sources - if (allS2SBidders.indexOf(bid.bidder) > -1 && !s2sTesting.bidSource[bid.bidder]) { - s2sTesting.bidSource[bid.bidder] = SERVER; - } - // calculate the source once and store on bid object - bid.calcSource = bid.calcSource || s2sTesting.getSource(bid.bidSource); - // if no bidSource at bid level, default to bidSource from bidder - bid.finalSource = bid.calcSource || s2sTesting.bidSource[bid.bidder] || CLIENT; // default to client - // add bidder to sourceBidders data structure - sourceBidders[bid.finalSource][bid.bidder] = true; - }); - }); - - // make sure all bidders in bidSource are in sourceBidders - Object.keys(s2sTesting.bidSource).forEach((bidder) => { - sourceBidders[s2sTesting.bidSource[bidder]][bidder] = true; - }); - - // return map of source => array of bidders - return { - [SERVER]: Object.keys(sourceBidders[SERVER]), - [CLIENT]: Object.keys(sourceBidders[CLIENT]) - }; -}; - -/** - * @function calculateBidSources determines the source for each s2s bidder based on bidderControl weightings. these can be overridden at the adUnit level - * @param s2sConfigs server-to-server configuration - */ -s2sTesting.calculateBidSources = function(s2sConfig = {}) { - // calculate bid source (server/client) for each s2s bidder - - var bidderControl = s2sConfig.bidderControl || {}; - (s2sConfig.bidders || []).forEach((bidder) => { - s2sTesting.bidSource[bidder] = s2sTesting.getSource(bidderControl[bidder] && bidderControl[bidder].bidSource) || SERVER; // default to server - }); -}; - -/** - * @function getSource() gets a random source based on the given sourceWeights (export just for testing) - * @param sourceWeights mapping of relative weights of potential sources. for example {server: 1, client: 3} should do a server request 25% of the time and a client request 75% of the time. - * @param bidSources list of possible bid sources: "server", "client". In theory could get the sources from the sourceWeights keys, but this is publisher config defined, so bidSources let's us constrain that. - * @return the chosen source ("server" or "client"), or undefined if none chosen - */ -s2sTesting.getSource = function(sourceWeights = {}, bidSources = [SERVER, CLIENT]) { - var srcIncWeight = {}; // store incremental weights of each source - var totWeight = 0; - bidSources.forEach((source) => { - totWeight += (sourceWeights[source] || 0); - srcIncWeight[source] = totWeight; - }); - if (!totWeight) return; // bail if no source weights - // choose a source randomly based on weights - var rndWeight = s2sTesting.globalRand * totWeight; - for (var i = 0; i < bidSources.length; i++) { - let source = bidSources[i]; - // choose the first source with an incremental weight > random weight - if (rndWeight < srcIncWeight[source]) return source; - } -}; - -// inject the s2sTesting module into the adapterManager rather than importing it -// importing it causes the packager to include it even when it's not explicitly included in the build -setS2STestingModule(s2sTesting); - -export default s2sTesting; diff --git a/modules/saambaaBidAdapter.js b/modules/saambaaBidAdapter.js deleted file mode 100755 index 0e53d2a300d..00000000000 --- a/modules/saambaaBidAdapter.js +++ /dev/null @@ -1,401 +0,0 @@ -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { VIDEO, BANNER } from '../src/mediaTypes.js'; -import find from 'core-js-pure/features/array/find.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -const ADAPTER_VERSION = '1.0'; -const BIDDER_CODE = 'saambaa'; - -export const VIDEO_ENDPOINT = 'https://nep.advangelists.com/xp/get?pubid='; -export const BANNER_ENDPOINT = 'https://nep.advangelists.com/xp/get?pubid='; -export const OUTSTREAM_SRC = 'https://player-cdn.beachfrontmedia.com/playerapi/loader/outstream.js'; -export const VIDEO_TARGETING = ['mimes', 'playbackmethod', 'maxduration', 'skip']; -export const DEFAULT_MIMES = ['video/mp4', 'application/javascript']; - -let pubid = ''; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - - isBidRequestValid(bidRequest) { - if (typeof bidRequest != 'undefined') { - if (bidRequest.bidder !== BIDDER_CODE && typeof bidRequest.params === 'undefined') { return false; } - if (bidRequest === '' || bidRequest.params.placement === '' || bidRequest.params.pubid === '') { return false; } - return true; - } else { return false; } - }, - - buildRequests(bids, bidderRequest) { - let requests = []; - let videoBids = bids.filter(bid => isVideoBidValid(bid)); - let bannerBids = bids.filter(bid => isBannerBidValid(bid)); - videoBids.forEach(bid => { - pubid = getVideoBidParam(bid, 'pubid'); - requests.push({ - method: 'POST', - url: VIDEO_ENDPOINT + pubid, - data: createVideoRequestData(bid, bidderRequest), - bidRequest: bid - }); - }); - - bannerBids.forEach(bid => { - pubid = getBannerBidParam(bid, 'pubid'); - - requests.push({ - method: 'POST', - url: BANNER_ENDPOINT + pubid, - data: createBannerRequestData(bid, bidderRequest), - bidRequest: bid - }); - }); - return requests; - }, - - interpretResponse(serverResponse, {bidRequest}) { - let response = serverResponse.body; - if (response !== null && utils.isEmpty(response) == false) { - if (isVideoBid(bidRequest)) { - let bidResponse = { - requestId: response.id, - bidderCode: BIDDER_CODE, - cpm: response.seatbid[0].bid[0].price, - width: response.seatbid[0].bid[0].w, - height: response.seatbid[0].bid[0].h, - ttl: response.seatbid[0].bid[0].ttl || 60, - creativeId: response.seatbid[0].bid[0].crid, - currency: response.cur, - meta: { 'advertiserDomains': response.seatbid[0].bid[0].adomain }, - mediaType: VIDEO, - netRevenue: true - } - - if (response.seatbid[0].bid[0].adm) { - bidResponse.vastXml = response.seatbid[0].bid[0].adm; - bidResponse.adResponse = { - content: response.seatbid[0].bid[0].adm - }; - } else { - bidResponse.vastUrl = response.seatbid[0].bid[0].nurl; - } - - return bidResponse; - } else { - return { - requestId: response.id, - bidderCode: BIDDER_CODE, - cpm: response.seatbid[0].bid[0].price, - width: response.seatbid[0].bid[0].w, - height: response.seatbid[0].bid[0].h, - ad: response.seatbid[0].bid[0].adm, - ttl: response.seatbid[0].bid[0].ttl || 60, - creativeId: response.seatbid[0].bid[0].crid, - currency: response.cur, - meta: { 'advertiserDomains': response.seatbid[0].bid[0].adomain }, - mediaType: BANNER, - netRevenue: true - } - } - } - } -}; - -function isBannerBid(bid) { - return utils.deepAccess(bid, 'mediaTypes.banner') || !isVideoBid(bid); -} - -function isVideoBid(bid) { - return utils.deepAccess(bid, 'mediaTypes.video'); -} - -function isVideoBidValid(bid) { - return isVideoBid(bid) && getVideoBidParam(bid, 'pubid') && getVideoBidParam(bid, 'placement'); -} - -function isBannerBidValid(bid) { - return isBannerBid(bid) && getBannerBidParam(bid, 'pubid') && getBannerBidParam(bid, 'placement'); -} - -function getVideoBidParam(bid, key) { - return utils.deepAccess(bid, 'params.video.' + key) || utils.deepAccess(bid, 'params.' + key); -} - -function getBannerBidParam(bid, key) { - return utils.deepAccess(bid, 'params.banner.' + key) || utils.deepAccess(bid, 'params.' + key); -} - -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 getDoNotTrack() { - return navigator.doNotTrack === '1' || window.doNotTrack === '1' || navigator.msDoNoTrack === '1' || navigator.doNotTrack === 'yes'; -} - -function findAndFillParam(o, key, value) { - try { - if (typeof value === 'function') { - o[key] = value(); - } else { - o[key] = value; - } - } catch (ex) {} -} - -function getOsVersion() { - let clientStrings = [ - { s: 'Android', r: /Android/ }, - { s: 'iOS', r: /(iPhone|iPad|iPod)/ }, - { s: 'Mac OS X', r: /Mac OS X/ }, - { s: 'Mac OS', r: /(MacPPC|MacIntel|Mac_PowerPC|Macintosh)/ }, - { s: 'Linux', r: /(Linux|X11)/ }, - { s: 'Windows 10', r: /(Windows 10.0|Windows NT 10.0)/ }, - { s: 'Windows 8.1', r: /(Windows 8.1|Windows NT 6.3)/ }, - { s: 'Windows 8', r: /(Windows 8|Windows NT 6.2)/ }, - { s: 'Windows 7', r: /(Windows 7|Windows NT 6.1)/ }, - { s: 'Windows Vista', r: /Windows NT 6.0/ }, - { s: 'Windows Server 2003', r: /Windows NT 5.2/ }, - { s: 'Windows XP', r: /(Windows NT 5.1|Windows XP)/ }, - { s: 'UNIX', r: /UNIX/ }, - { s: 'Search Bot', r: /(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\/Teoma|ia_archiver)/ } - ]; - let cs = find(clientStrings, cs => cs.r.test(navigator.userAgent)); - return cs ? cs.s : 'unknown'; -} - -function getFirstSize(sizes) { - return (sizes && sizes.length) ? sizes[0] : { w: undefined, h: undefined }; -} - -function parseSizes(sizes) { - return utils.parseSizesInput(sizes).map(size => { - let [ width, height ] = size.split('x'); - return { - w: parseInt(width, 10) || undefined, - h: parseInt(height, 10) || undefined - }; - }); -} - -function getVideoSizes(bid) { - return parseSizes(utils.deepAccess(bid, 'mediaTypes.video.playerSize') || bid.sizes); -} - -function getBannerSizes(bid) { - return parseSizes(utils.deepAccess(bid, 'mediaTypes.banner.sizes') || bid.sizes); -} - -function getTopWindowReferrer() { - try { - return window.top.document.referrer; - } catch (e) { - return ''; - } -} - -function getVideoTargetingParams(bid) { - return Object.keys(Object(bid.params.video)) - .filter(param => includes(VIDEO_TARGETING, param)) - .reduce((obj, param) => { - obj[ param ] = bid.params.video[ param ]; - return obj; - }, {}); -} - -function createVideoRequestData(bid, bidderRequest) { - let topLocation = getTopWindowLocation(bidderRequest); - let topReferrer = getTopWindowReferrer(); - - // if size is explicitly given via adapter params - let paramSize = getVideoBidParam(bid, 'size'); - let sizes = []; - - if (typeof paramSize !== 'undefined' && paramSize != '') { - sizes = parseSizes(paramSize); - } else { - sizes = getVideoSizes(bid); - } - const firstSize = getFirstSize(sizes); - - let video = getVideoTargetingParams(bid); - const o = { - 'device': { - 'langauge': (global.navigator.language).split('-')[0], - 'dnt': (global.navigator.doNotTrack === 1 ? 1 : 0), - 'devicetype': isMobile() ? 4 : isConnectedTV() ? 3 : 2, - 'js': 1, - 'os': getOsVersion() - }, - 'at': 2, - 'site': {}, - 'tmax': 3000, - 'cur': ['USD'], - 'id': bid.bidId, - 'imp': [], - 'regs': { - 'ext': { - } - }, - 'user': { - 'ext': { - } - } - }; - - o.site['page'] = topLocation.href; - o.site['domain'] = topLocation.hostname; - o.site['search'] = topLocation.search; - o.site['domain'] = topLocation.hostname; - o.site['ref'] = topReferrer; - o.site['mobile'] = isMobile() ? 1 : 0; - const secure = topLocation.protocol.indexOf('https') === 0 ? 1 : 0; - - o.device['dnt'] = getDoNotTrack() ? 1 : 0; - - findAndFillParam(o.site, 'name', function() { - return global.top.document.title; - }); - - findAndFillParam(o.device, 'h', function() { - return global.screen.height; - }); - findAndFillParam(o.device, 'w', function() { - return global.screen.width; - }); - - let placement = getVideoBidParam(bid, 'placement'); - let floor = getVideoBidParam(bid, 'floor'); - if (floor == null) { floor = 0.5; } - - for (let j = 0; j < sizes.length; j++) { - o.imp.push({ - 'id': '' + j, - 'displaymanager': '' + BIDDER_CODE, - 'displaymanagerver': '' + ADAPTER_VERSION, - 'tagId': placement, - 'bidfloor': floor, - 'bidfloorcur': 'USD', - 'secure': secure, - 'video': Object.assign({ - 'id': utils.generateUUID(), - 'pos': 0, - 'w': firstSize.w, - 'h': firstSize.h, - 'mimes': DEFAULT_MIMES - }, video) - - }); - } - - if (bidderRequest && bidderRequest.gdprConsent) { - let { gdprApplies, consentString } = bidderRequest.gdprConsent; - o.regs.ext = {'gdpr': gdprApplies ? 1 : 0}; - o.user.ext = {'consent': consentString}; - } - - return o; -} - -function getTopWindowLocation(bidderRequest) { - let url = bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer; - return utils.parseUrl(config.getConfig('pageUrl') || url, { decodeSearchAsString: true }); -} - -function createBannerRequestData(bid, bidderRequest) { - let topLocation = getTopWindowLocation(bidderRequest); - let topReferrer = getTopWindowReferrer(); - - // if size is explicitly given via adapter params - - let paramSize = getBannerBidParam(bid, 'size'); - let sizes = []; - if (typeof paramSize !== 'undefined' && paramSize != '') { - sizes = parseSizes(paramSize); - } else { - sizes = getBannerSizes(bid); - } - - const o = { - 'device': { - 'langauge': (global.navigator.language).split('-')[0], - 'dnt': (global.navigator.doNotTrack === 1 ? 1 : 0), - 'devicetype': isMobile() ? 4 : isConnectedTV() ? 3 : 2, - 'js': 1 - }, - 'at': 2, - 'site': {}, - 'tmax': 3000, - 'cur': ['USD'], - 'id': bid.bidId, - 'imp': [], - 'regs': { - 'ext': { - } - }, - 'user': { - 'ext': { - } - } - }; - - o.site['page'] = topLocation.href; - o.site['domain'] = topLocation.hostname; - o.site['search'] = topLocation.search; - o.site['domain'] = topLocation.hostname; - o.site['ref'] = topReferrer; - o.site['mobile'] = isMobile() ? 1 : 0; - const secure = topLocation.protocol.indexOf('https') === 0 ? 1 : 0; - - o.device['dnt'] = getDoNotTrack() ? 1 : 0; - - findAndFillParam(o.site, 'name', function() { - return global.top.document.title; - }); - - findAndFillParam(o.device, 'h', function() { - return global.screen.height; - }); - findAndFillParam(o.device, 'w', function() { - return global.screen.width; - }); - - let placement = getBannerBidParam(bid, 'placement'); - for (let j = 0; j < sizes.length; j++) { - let size = sizes[j]; - - let floor = getBannerBidParam(bid, 'floor'); - if (floor == null) { floor = 0.1; } - - o.imp.push({ - 'id': '' + j, - 'displaymanager': '' + BIDDER_CODE, - 'displaymanagerver': '' + ADAPTER_VERSION, - 'tagId': placement, - 'bidfloor': floor, - 'bidfloorcur': 'USD', - 'secure': secure, - 'banner': { - 'id': utils.generateUUID(), - 'pos': 0, - 'w': size['w'], - 'h': size['h'] - } - }); - } - - if (bidderRequest && bidderRequest.gdprConsent) { - let { gdprApplies, consentString } = bidderRequest.gdprConsent; - o.regs.ext = {'gdpr': gdprApplies ? 1 : 0}; - o.user.ext = {'consent': consentString}; - } - - return o; -} -registerBidder(spec); diff --git a/modules/saambaaBidAdapter.md b/modules/saambaaBidAdapter.md deleted file mode 100755 index 2d391da7628..00000000000 --- a/modules/saambaaBidAdapter.md +++ /dev/null @@ -1,69 +0,0 @@ -# Overview - -``` -Module Name: Saambaa Bidder Adapter -Module Type: Bidder Adapter -Maintainer: matt.voigt@saambaa.com -``` - -# Description - -Connects to Saambaa exchange for bids. - -Saambaa bid adapter supports Banner and Video ads currently. - -For more informatio - -# Sample Display Ad Unit: For Publishers -```javascript - -var displayAdUnit = [ -{ - code: 'display', - mediaTypes: { - banner: { - sizes: [[300, 250],[320, 50]] - } - } - bids: [{ - bidder: 'saambaa', - params: { - pubid: '121ab139faf7ac67428a23f1d0a9a71b', - placement: 1234, - size: '320x50' - } - }] -}]; -``` - -# Sample Video Ad Unit: For Publishers -```javascript - -var videoAdUnit = { - code: 'video', - sizes: [320,480], - mediaTypes: { - video: { - playerSize : [[320, 480]], - context: 'instream' - } - }, - bids: [ - { - bidder: 'saambaa', - params: { - pubid: '121ab139faf7ac67428a23f1d0a9a71b', - placement: 1234, - size: "320x480", - video: { - id: 123, - skip: 1, - mimes : ['video/mp4', 'application/javascript'], - playbackmethod : [2,6], - maxduration: 30 - } - } - } - ] - }; -``` \ No newline at end of file diff --git a/modules/saraBidAdapter.md b/modules/saraBidAdapter.md deleted file mode 100644 index 65572528181..00000000000 --- a/modules/saraBidAdapter.md +++ /dev/null @@ -1,40 +0,0 @@ -# Overview - -Module Name: Sara Bidder Adapter -Module Type: Bidder Adapter -Maintainer: github@sara.media - -# Description - -Module that connects to Sara demand source to fetch bids. - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - sizes: [[300, 250]], - bids: [ - { - bidder: "sara", - params: { - uid: '5', - priceType: 'gross' // by default is 'net' - } - } - ] - },{ - code: 'test-div', - sizes: [[728, 90]], - bids: [ - { - bidder: "sara", - params: { - uid: 6, - priceType: 'gross' - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/scaleableAnalyticsAdapter.js b/modules/scaleableAnalyticsAdapter.js deleted file mode 100644 index 955a08c065a..00000000000 --- a/modules/scaleableAnalyticsAdapter.js +++ /dev/null @@ -1,203 +0,0 @@ -/* COPYRIGHT SCALEABLE LLC 2019 */ - -import { ajax } from '../src/ajax.js'; -import CONSTANTS from '../src/constants.json'; -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -import * as utils from '../src/utils.js'; - -// Object.entries polyfill -const entries = Object.entries || function(obj) { - const ownProps = Object.keys(obj); - let i = ownProps.length; - let resArray = new Array(i); // preallocate the Array - while (i--) { resArray[i] = [ownProps[i], obj[ownProps[i]]]; } - - return resArray; -}; - -const BID_TIMEOUT = CONSTANTS.EVENTS.BID_TIMEOUT; -const AUCTION_INIT = CONSTANTS.EVENTS.AUCTION_INIT; -const BID_WON = CONSTANTS.EVENTS.BID_WON; -const AUCTION_END = CONSTANTS.EVENTS.AUCTION_END; - -const URL = 'https://auction.scaleable.ai/'; -const ANALYTICS_TYPE = 'endpoint'; - -let auctionData = {}; - -let scaleableAnalytics = Object.assign({}, - adapter({ - URL, - ANALYTICS_TYPE - }), - { - // Override AnalyticsAdapter functions by supplying custom methods - track({ eventType, args }) { - switch (eventType) { - case AUCTION_INIT: - onAuctionInit(args); - break; - case AUCTION_END: - onAuctionEnd(args); - break; - case BID_WON: - onBidWon(args); - break; - case BID_TIMEOUT: - onBidTimeout(args); - break; - default: - break; - } - } - } -); - -scaleableAnalytics.config = {}; -scaleableAnalytics.originEnableAnalytics = scaleableAnalytics.enableAnalytics; -scaleableAnalytics.enableAnalytics = config => { - scaleableAnalytics.config = config; - - scaleableAnalytics.originEnableAnalytics(config); - - scaleableAnalytics.enableAnalytics = function _enable() { - return utils.logMessage(`Analytics adapter for "${global}" already enabled, unnecessary call to \`enableAnalytics\`.`); - }; -} - -scaleableAnalytics.getAuctionData = () => { - return auctionData; -}; - -const sendDataToServer = data => ajax(URL, () => {}, JSON.stringify(data)); - -// Track auction initiated -const onAuctionInit = args => { - const config = scaleableAnalytics.config || {options: {}}; - - let adunitObj = {}; - let adunits = []; - - // Loop through adunit codes first - args.adUnitCodes.forEach((code) => { - adunitObj[code] = [{ - bidder: 'scaleable_adunit_request' - }] - }); - - // Loop through bidder requests and bids - args.bidderRequests.forEach((bidderObj) => { - bidderObj.bids.forEach((bidObj) => { - adunitObj[bidObj.adUnitCode].push({ - bidder: bidObj.bidder, - params: bidObj.params - }) - }); - }); - - entries(adunitObj).forEach(([adunitCode, bidRequests]) => { - adunits.push({ - code: adunitCode, - bidRequests: bidRequests - }); - }); - - const data = { - event: 'request', - site: config.options.site, - adunits: adunits - } - - sendDataToServer(data); -} - -// Handle all events besides requests and wins -const onAuctionEnd = args => { - const config = scaleableAnalytics.config || {options: {}}; - - let adunitObj = {}; - let adunits = []; - - // Add Bids Received - args.bidsReceived.forEach((bidObj) => { - if (!adunitObj[bidObj.adUnitCode]) { adunitObj[bidObj.adUnitCode] = []; } - - adunitObj[bidObj.adUnitCode].push({ - bidder: bidObj.bidderCode || bidObj.bidder, - cpm: bidObj.cpm, - currency: bidObj.currency, - dealId: bidObj.dealId, - type: bidObj.mediaType, - ttr: bidObj.timeToRespond, - size: bidObj.size - }); - }); - - // Add in other data (timeouts) as we push to adunits - entries(adunitObj).forEach(([adunitCode, bidsReceived]) => { - const bidData = bidsReceived.concat(auctionData[adunitCode] || []); - adunits.push({ - code: adunitCode, - bidData: bidData - }); - - delete auctionData[adunitCode]; - }); - - // Add in any missed auction data - entries(auctionData).forEach(([adunitCode, bidData]) => { - adunits.push({ - code: adunitCode, - bidData: bidData - }) - }); - - const data = { - event: 'bids', - site: config.options.site, - adunits: adunits - } - - if (adunits.length) { sendDataToServer(data); } - - // Reset auctionData - auctionData = {} -} - -// Bid Win Events occur after auction end -const onBidWon = args => { - const config = scaleableAnalytics.config || {options: {}}; - - const data = { - event: 'win', - site: config.options.site, - adunit: args.adUnitCode, - code: args.bidderCode, - cpm: args.cpm, - ttr: args.timeToRespond, - params: args.params - }; - - sendDataToServer(data); -} - -const onBidTimeout = args => { - args.forEach(currObj => { - if (!auctionData[currObj.adUnitCode]) { - auctionData[currObj.adUnitCode] = [] - } - - auctionData[currObj.adUnitCode].push({ - timeouts: 1, - bidder: currObj.bidder - }); - }); -} - -adapterManager.registerAnalyticsAdapter({ - adapter: scaleableAnalytics, - code: 'scaleable' -}) - -export default scaleableAnalytics; diff --git a/modules/scaleableAnalyticsAdapter.md b/modules/scaleableAnalyticsAdapter.md deleted file mode 100644 index 0f6fbada55a..00000000000 --- a/modules/scaleableAnalyticsAdapter.md +++ /dev/null @@ -1,20 +0,0 @@ -# Overview - -Module Name: Scaleable Analytics Adapter -Module Type: Analytics Adapter -Maintainer: chris@scaleable.ai - -# Description - -Analytics adapter for scaleable.ai. Contact team@scaleable.ai for more information or to sign up for analytics. - -# Implementation Code - -``` -pbjs.enableAnalytics({ - provider: 'scaleable', - options: { - site: '' // Contact Scaleable to receive your unique site id - } -}); -``` diff --git a/modules/schain.js b/modules/schain.js deleted file mode 100644 index d409e74df48..00000000000 --- a/modules/schain.js +++ /dev/null @@ -1,183 +0,0 @@ -import { config } from '../src/config.js'; -import adapterManager from '../src/adapterManager.js'; -import { isNumber, isStr, isArray, isPlainObject, hasOwn, logError, isInteger, _each, logWarn } from '../src/utils.js'; - -// https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/supplychainobject.md - -const schainErrorPrefix = 'Invalid schain object found: '; -const shouldBeAString = ' should be a string'; -const shouldBeAnInteger = ' should be an Integer'; -const shouldBeAnObject = ' should be an object'; -const shouldBeAnArray = ' should be an Array'; -const MODE = { - STRICT: 'strict', - RELAXED: 'relaxed', - OFF: 'off' -}; -const MODES = []; // an array of modes -_each(MODE, mode => MODES.push(mode)); - -// validate the supply chain object -export function isSchainObjectValid(schainObject, returnOnError) { - let failPrefix = 'Detected something wrong within an schain config:' - let failMsg = ''; - - function appendFailMsg(msg) { - failMsg += '\n' + msg; - } - - function printFailMsg() { - if (returnOnError === true) { - logError(failPrefix, schainObject, failMsg); - } else { - logWarn(failPrefix, schainObject, failMsg); - } - } - - if (!isPlainObject(schainObject)) { - appendFailMsg(`schain.config` + shouldBeAnObject); - printFailMsg(); - if (returnOnError) return false; - } - - // complete: Integer - if (!isNumber(schainObject.complete) || !isInteger(schainObject.complete)) { - appendFailMsg(`schain.config.complete` + shouldBeAnInteger); - } - - // ver: String - if (!isStr(schainObject.ver)) { - appendFailMsg(`schain.config.ver` + shouldBeAString); - } - - // ext: Object [optional] - if (hasOwn(schainObject, 'ext')) { - if (!isPlainObject(schainObject.ext)) { - appendFailMsg(`schain.config.ext` + shouldBeAnObject); - } - } - - // nodes: Array of objects - if (!isArray(schainObject.nodes)) { - appendFailMsg(`schain.config.nodes` + shouldBeAnArray); - printFailMsg(); - if (returnOnError) return false; - } else { - schainObject.nodes.forEach((node, index) => { - // asi: String - if (!isStr(node.asi)) { - appendFailMsg(`schain.config.nodes[${index}].asi` + shouldBeAString); - } - - // sid: String - if (!isStr(node.sid)) { - appendFailMsg(`schain.config.nodes[${index}].sid` + shouldBeAString); - } - - // hp: Integer - if (!isNumber(node.hp) || !isInteger(node.hp)) { - appendFailMsg(`schain.config.nodes[${index}].hp` + shouldBeAnInteger); - } - - // rid: String [Optional] - if (hasOwn(node, 'rid')) { - if (!isStr(node.rid)) { - appendFailMsg(`schain.config.nodes[${index}].rid` + shouldBeAString); - } - } - - // name: String [Optional] - if (hasOwn(node, 'name')) { - if (!isStr(node.name)) { - appendFailMsg(`schain.config.nodes[${index}].name` + shouldBeAString); - } - } - - // domain: String [Optional] - if (hasOwn(node, 'domain')) { - if (!isStr(node.domain)) { - appendFailMsg(`schain.config.nodes[${index}].domain` + shouldBeAString); - } - } - - // ext: Object [Optional] - if (hasOwn(node, 'ext')) { - if (!isPlainObject(node.ext)) { - appendFailMsg(`schain.config.nodes[${index}].ext` + shouldBeAnObject); - } - } - }); - } - - if (failMsg.length > 0) { - printFailMsg(); - if (returnOnError) { - return false; - } - } - - return true; -} - -export function isValidSchainConfig(schainObject) { - if (schainObject === undefined) { - return false; - } - if (!isPlainObject(schainObject)) { - logError(schainErrorPrefix + 'the following schain config will not be used as schain is not an object.', schainObject); - return false; - } - return true; -} - -function resolveSchainConfig(schainObject, bidder) { - let mode = MODE.STRICT; - - if (isValidSchainConfig(schainObject)) { - if (isStr(schainObject.validation) && MODES.indexOf(schainObject.validation) != -1) { - mode = schainObject.validation; - } - if (mode === MODE.OFF) { - // no need to validate - return schainObject.config; - } else { - // if strict mode and config is invalid, reject config + throw error; otherwise allow config to go through - if (isSchainObjectValid(schainObject.config, !!(mode === MODE.STRICT))) { - return schainObject.config; - } else { - logError(schainErrorPrefix + `due to the 'strict' validation setting, this schain config will not be passed to bidder '${bidder}'. See above error for details.`); - } - } - } - return null; -} - -export function makeBidRequestsHook(fn, bidderRequests) { - function getSchainForBidder(bidder) { - let bidderSchain = bidderConfigs[bidder] && bidderConfigs[bidder].schain; - return bidderSchain || globalSchainConfig; - } - - const globalSchainConfig = config.getConfig('schain'); - const bidderConfigs = config.getBidderConfig(); - - bidderRequests.forEach(bidderRequest => { - let bidder = bidderRequest.bidderCode; - let schainConfig = getSchainForBidder(bidder); - - bidderRequest.bids.forEach(bid => { - let result = resolveSchainConfig(schainConfig, bidder); - if (result) { - bid.schain = result; - } - }); - }); - - fn(bidderRequests); -} - -export function init() { - adapterManager.makeBidRequests.after(makeBidRequestsHook); -} - -init() diff --git a/modules/schain.md b/modules/schain.md deleted file mode 100644 index f43cf0f0d07..00000000000 --- a/modules/schain.md +++ /dev/null @@ -1,51 +0,0 @@ -# schain module - -Aggregators who manage Prebid wrappers on behalf of multiple publishers and handle payment on behalf of the publishers -need to declare their intermediary status in the Supply Chain Object. As the Supply Chain Object spec prohibits SSPs from adding -upstream intermediaries, Prebid requests in this case need to come with the schain information. In this use case, it's cumbersome -to have every bidder in the wrapper separately configured the same schain information. - -Refer: -- https://iabtechlab.com/sellers-json/ -- https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/supplychainobject.md - -## Sample code for passing the schain object -``` -pbjs.setConfig( { - "schain": { - "validation": "strict", - "config": { - "ver":"1.0", - "complete": 1, - "nodes": [ - { - "asi":"indirectseller.com", - "sid":"00001", - "hp":1 - }, - - { - "asi":"indirectseller-2.com", - "sid":"00002", - "hp":1 - } - ] - } - } -}); -``` - -## Workflow -The schain module is not enabled by default as it may not be necessary for all publishers. -If required, schain module can be included as following -``` - $ gulp build --modules=schain,pubmaticBidAdapter,openxBidAdapter,rubiconBidAdapter,sovrnBidAdapter -``` -The schain module will validate the schain object passed using pbjs.setConfig API. -If the schain object is valid then it will be passed on to bidders/adapters in ```validBidRequests[].schain``` -You may refer pubmaticBidAdapter implementaion for the same. - -## Validation modes -- ```strict```: It is the default validation mode. In this mode, schain object will not be passed to adapters if it is invalid. Errors are thrown for invalid schain object. -- ```relaxed```: In this mode, errors are thrown for an invalid schain object but the invalid schain object is still passed to adapters. -- ```off```: In this mode, no validations are performed and schain object is passed as is to adapters. diff --git a/modules/seedingAllianceBidAdapter.js b/modules/seedingAllianceBidAdapter.js deleted file mode 100755 index d85ae856317..00000000000 --- a/modules/seedingAllianceBidAdapter.js +++ /dev/null @@ -1,225 +0,0 @@ -// jshint esversion: 6, es3: false, node: true -'use strict'; - -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { NATIVE } from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; - -const BIDDER_CODE = 'seedingAlliance'; -const DEFAULT_CUR = 'EUR'; -const ENDPOINT_URL = 'https://b.nativendo.de/cds/rtb/bid?format=openrtb2.5&ssp=nativendo'; - -const NATIVE_ASSET_IDS = {0: 'title', 1: 'body', 2: 'sponsoredBy', 3: 'image', 4: 'cta', 5: 'icon'}; - -const NATIVE_PARAMS = { - title: { - id: 0, - name: 'title' - }, - - body: { - id: 1, - name: 'data', - type: 2 - }, - - sponsoredBy: { - id: 2, - name: 'data', - type: 1 - }, - - image: { - id: 3, - type: 3, - name: 'img' - }, - - cta: { - id: 4, - type: 12, - name: 'data' - }, - - icon: { - id: 5, - type: 1, - name: 'img' - } -}; - -export const spec = { - code: BIDDER_CODE, - - supportedMediaTypes: [NATIVE], - - isBidRequestValid: function(bid) { - return !!bid.params.adUnitId; - }, - - buildRequests: (validBidRequests, bidderRequest) => { - const pt = setOnAny(validBidRequests, 'params.pt') || setOnAny(validBidRequests, 'params.priceType') || 'net'; - const tid = validBidRequests[0].transactionId; - const cur = [config.getConfig('currency.adServerCurrency') || DEFAULT_CUR]; - let url = bidderRequest.refererInfo.referer; - - const imp = validBidRequests.map((bid, id) => { - const assets = utils._map(bid.nativeParams, (bidParams, key) => { - const props = NATIVE_PARAMS[key]; - - const asset = { - required: bidParams.required & 1 - }; - - if (props) { - asset.id = props.id; - - let w, h; - - if (bidParams.sizes) { - w = bidParams.sizes[0]; - h = bidParams.sizes[1]; - } - - asset[props.name] = { - len: bidParams.len, - type: props.type, - w, - h - }; - - return asset; - } - }) - .filter(Boolean); - - if (bid.params.url) { - url = bid.params.url; - } - - return { - id: String(id + 1), - tagid: bid.params.adUnitId, - tid: tid, - pt: pt, - native: { - request: { - assets - } - } - }; - }); - - const request = { - id: bidderRequest.auctionId, - site: { - page: url - }, - device: { - ua: navigator.userAgent - }, - cur, - imp, - user: {}, - regs: { - ext: { - gdpr: 0 - } - } - }; - - if (bidderRequest && bidderRequest.gdprConsent) { - utils.deepSetValue(request, 'user.ext.consent', bidderRequest.gdprConsent.consentString); - utils.deepSetValue(request, 'regs.ext.gdpr', (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean' && bidderRequest.gdprConsent.gdprApplies) ? 1 : 0); - } - - return { - method: 'POST', - url: ENDPOINT_URL, - data: JSON.stringify(request), - options: { - contentType: 'application/json' - }, - bids: validBidRequests - }; - }, - - interpretResponse: function(serverResponse, { bids }) { - if (utils.isEmpty(serverResponse.body)) { - return []; - } - - const { seatbid, cur } = serverResponse.body; - - const bidResponses = flatten(seatbid.map(seat => seat.bid)).reduce((result, bid) => { - result[bid.impid - 1] = bid; - return result; - }, []); - - return bids - .map((bid, id) => { - const bidResponse = bidResponses[id]; - - if (bidResponse) { - return { - requestId: bid.bidId, - cpm: bidResponse.price, - creativeId: bidResponse.crid, - ttl: 1000, - netRevenue: bid.netRevenue === 'net', - currency: cur, - mediaType: NATIVE, - bidderCode: BIDDER_CODE, - native: parseNative(bidResponse) - }; - } - }) - .filter(Boolean); - } -}; - -registerBidder(spec); - -function parseNative(bid) { - const {assets, link, imptrackers} = bid.adm.native; - - link.clicktrackers.forEach(function (clicktracker, index) { - link.clicktrackers[index] = clicktracker.replace(/\$\{AUCTION_PRICE\}/, bid.price); - }); - - imptrackers.forEach(function (imptracker, index) { - imptrackers[index] = imptracker.replace(/\$\{AUCTION_PRICE\}/, bid.price); - }); - - const result = { - url: link.url, - clickUrl: link.url, - clickTrackers: link.clicktrackers || undefined, - impressionTrackers: imptrackers || undefined - }; - - assets.forEach(asset => { - const kind = NATIVE_ASSET_IDS[asset.id]; - const content = kind && asset[NATIVE_PARAMS[kind].name]; - - if (content) { - result[kind] = content.text || content.value || { url: content.url, width: content.w, height: content.h }; - } - }); - - return result; -} - -function setOnAny(collection, key) { - for (let i = 0, result; i < collection.length; i++) { - result = utils.deepAccess(collection[i], key); - if (result) { - return result; - } - } -} - -function flatten(arr) { - return [].concat(...arr); -} diff --git a/modules/seedingAllianceBidAdapter.md b/modules/seedingAllianceBidAdapter.md deleted file mode 100755 index c933e53695b..00000000000 --- a/modules/seedingAllianceBidAdapter.md +++ /dev/null @@ -1,45 +0,0 @@ -# Overview -Module Name: Seeding Alliance Bidder Adapter -Type: Seeding Alliance Adapter -Maintainer: tech@seeding-alliance.de - -# Description -Seeding Alliance Bidder Adapter for Prebid.js. - -# Test Parameters -``` -var adUnits = [{ - code: 'test-div', - - mediaTypes: { - native: { - title: { - required: true, - len: 50 - }, - body: { - required: true, - len: 350 - }, - url: { - required: true - }, - image: { - required: true, - sizes : [300, 175] - }, - sponsoredBy: { - required: true - } - } - }, - bids: [{ - bidder: 'seedingAlliance', - params: { - url : "https://mockup.seeding-alliance.de/ssp-testing/native.html", - adUnitId: "2sq2o" - } - }] -}]; -``` - diff --git a/modules/seedtagBidAdapter.js b/modules/seedtagBidAdapter.js deleted file mode 100644 index c25d833a71c..00000000000 --- a/modules/seedtagBidAdapter.js +++ /dev/null @@ -1,243 +0,0 @@ -import * as utils from '../src/utils.js' -import { registerBidder } from '../src/adapters/bidderFactory.js' -import { VIDEO, BANNER } from '../src/mediaTypes.js' - -const BIDDER_CODE = 'seedtag'; -const SEEDTAG_ALIAS = 'st'; -const SEEDTAG_SSP_ENDPOINT = 'https://s.seedtag.com/c/hb/bid'; -const SEEDTAG_SSP_ONTIMEOUT_ENDPOINT = 'https://s.seedtag.com/se/hb/timeout'; -const ALLOWED_PLACEMENTS = { - inImage: true, - inScreen: true, - inArticle: true, - banner: true, - video: true -} -const mediaTypesMap = { - [BANNER]: 'display', - [VIDEO]: 'video' -}; - -const deviceConnection = { - FIXED: 'fixed', - MOBILE: 'mobile', - UNKNOWN: 'unknown' -}; - -const getConnectionType = () => { - const connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection || {} - switch (connection.type || connection.effectiveType) { - case 'wifi': - case 'ethernet': - return deviceConnection.FIXED - case 'cellular': - case 'wimax': - return deviceConnection.MOBILE - default: - const isMobile = /iPad|iPhone|iPod/.test(navigator.userAgent) || /android/i.test(navigator.userAgent) - return isMobile ? deviceConnection.UNKNOWN : deviceConnection.FIXED - } -}; - -function mapMediaType(seedtagMediaType) { - if (seedtagMediaType === 'display') return BANNER; - if (seedtagMediaType === 'video') return VIDEO; - else return seedtagMediaType; -} - -function hasVideoMediaType(bid) { - return !!bid.mediaTypes && !!bid.mediaTypes.video -} - -function hasMandatoryParams(params) { - return ( - !!params.publisherId && - !!params.adUnitId && - !!params.placement && - !!ALLOWED_PLACEMENTS[params.placement] - ); -} - -function hasMandatoryVideoParams(mediaTypes) { - const isVideoInStream = - !!mediaTypes.video && mediaTypes.video.context === 'instream'; - const isPlayerSize = - !!utils.deepAccess(mediaTypes, 'video.playerSize') && - utils.isArray(utils.deepAccess(mediaTypes, 'video.playerSize')); - return isVideoInStream && isPlayerSize; -} - -function buildBidRequests(validBidRequests) { - return utils._map(validBidRequests, function(validBidRequest) { - const params = validBidRequest.params; - const mediaTypes = utils._map( - Object.keys(validBidRequest.mediaTypes), - function(pbjsType) { - return mediaTypesMap[pbjsType]; - } - ); - - const bidRequest = { - id: validBidRequest.bidId, - transactionId: validBidRequest.transactionId, - sizes: validBidRequest.sizes, - supplyTypes: mediaTypes, - adUnitId: params.adUnitId, - placement: params.placement, - }; - - if (params.adPosition) { - bidRequest.adPosition = params.adPosition; - } - - if (hasVideoMediaType(validBidRequest)) { - bidRequest.videoParams = params.video || {}; - bidRequest.videoParams.w = - validBidRequest.mediaTypes.video.playerSize[0][0]; - bidRequest.videoParams.h = - validBidRequest.mediaTypes.video.playerSize[0][1]; - } - - return bidRequest; - }) -} - -function buildBid(seedtagBid) { - const mediaType = mapMediaType(seedtagBid.mediaType); - const bid = { - requestId: seedtagBid.bidId, - cpm: seedtagBid.price, - width: seedtagBid.width, - height: seedtagBid.height, - creativeId: seedtagBid.creativeId, - currency: seedtagBid.currency, - netRevenue: true, - mediaType: mediaType, - ttl: seedtagBid.ttl, - nurl: seedtagBid.nurl - }; - - if (mediaType === VIDEO) { - bid.vastXml = seedtagBid.content; - } else { - bid.ad = seedtagBid.content; - } - return bid; -} - -export function getTimeoutUrl (data) { - let queryParams = ''; - if ( - utils.isArray(data) && data[0] && - utils.isArray(data[0].params) && data[0].params[0] - ) { - const params = data[0].params[0]; - queryParams = - '?publisherToken=' + params.publisherId + - '&adUnitId=' + params.adUnitId; - } - return SEEDTAG_SSP_ONTIMEOUT_ENDPOINT + queryParams; -} - -export const spec = { - code: BIDDER_CODE, - aliases: [SEEDTAG_ALIAS], - supportedMediaTypes: [BANNER, VIDEO], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid(bid) { - return hasVideoMediaType(bid) - ? hasMandatoryParams(bid.params) && hasMandatoryVideoParams(bid.mediaTypes) - : hasMandatoryParams(bid.params); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests(validBidRequests, bidderRequest) { - const payload = { - url: bidderRequest.refererInfo.referer, - publisherToken: validBidRequests[0].params.publisherId, - cmp: !!bidderRequest.gdprConsent, - timeout: bidderRequest.timeout, - version: '$prebid.version$', - connectionType: getConnectionType(), - bidRequests: buildBidRequests(validBidRequests) - }; - - if (payload.cmp) { - const gdprApplies = bidderRequest.gdprConsent.gdprApplies; - if (gdprApplies !== undefined) payload['ga'] = gdprApplies; - payload['cd'] = bidderRequest.gdprConsent.consentString; - } - - const payloadString = JSON.stringify(payload) - return { - method: 'POST', - url: SEEDTAG_SSP_ENDPOINT, - data: payloadString - } - }, - - /** - * Unpack the 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. - */ - interpretResponse: function(serverResponse) { - const serverBody = serverResponse.body; - if (serverBody && serverBody.bids && utils.isArray(serverBody.bids)) { - return utils._map(serverBody.bids, function(bid) { - return buildBid(bid); - }); - } else { - return []; - } - }, - - /** - * Register the user sync pixels which should be dropped after the auction. - * - * @param {SyncOptions} syncOptions Which user syncs are allowed? - * @param {ServerResponse[]} serverResponses List of server's responses. - * @return {UserSync[]} The user syncs which should be dropped. - */ - getUserSyncs(syncOptions, serverResponses) { - const serverResponse = serverResponses[0]; - if (syncOptions.iframeEnabled && serverResponse) { - const cookieSyncUrl = serverResponse.body.cookieSync; - return cookieSyncUrl ? [{ type: 'iframe', url: cookieSyncUrl }] : []; - } else { - return []; - } - }, - - /** - * Register bidder specific code, which will execute if bidder timed out after an auction - * @param {data} Containing timeout specific data - */ - onTimeout(data) { - const url = getTimeoutUrl(data); - utils.triggerPixel(url); - }, - - /** - * Function to call when the adapter wins the auction - * @param {bid} Bid information received from the server - */ - onBidWon: function (bid) { - if (bid && bid.nurl) { - utils.triggerPixel(bid.nurl); - } - } -} -registerBidder(spec); diff --git a/modules/seedtagBidAdapter.md b/modules/seedtagBidAdapter.md deleted file mode 100644 index 627ff8333ad..00000000000 --- a/modules/seedtagBidAdapter.md +++ /dev/null @@ -1,79 +0,0 @@ -# Overview - -``` -Module Name: Seedtag Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid@seedtag.com -``` - -# Description - -Module that connects to Seedtag demand sources to fetch bids. - -# Test Parameters - -## Sample Banner Ad Unit - -```js -const adUnits = [ - { - code: '/21804003197/prebid_test_300x250', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [ - { - bidder: 'seedtag', - params: { - publisherId: '0000-0000-01', // required - adUnitId: '0000', // required - placement: 'banner', // required - adPosition: 0 // optional - } - } - ] - } -] -``` - -## Sample inStream Video Ad Unit - -```js -var adUnits = [{ - code: 'video', - mediaTypes: { - video: { - context: 'instream', // required - playerSize: [600, 300] // required - } - }, - bids: [ - { - bidder: 'seedtag', - params: { - publisherId: '0000-0000-01', // required - adUnitId: '0000', // required - placement: 'video', // required - adPosition: 0, // optional - // Video object as specified in OpenRTB 2.5 - video: { - mimes: ['video/mp4'], // recommended - minduration: 5, // optional - maxduration: 60, // optional - boxingallowed: 1, // optional - skip: 1, // optional - startdelay: 1, // optional - linearity: 1, // optional - battr: [1, 2], // optional - maxbitrate: 10, // optional - playbackmethod: [1], // optional - delivery: [1], // optional - placement: 1, // optional - } - } - } - ] -}]; -``` diff --git a/modules/segmentoBidAdapter.js b/modules/segmentoBidAdapter.js deleted file mode 100644 index a042bdf4942..00000000000 --- a/modules/segmentoBidAdapter.js +++ /dev/null @@ -1,85 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'segmento'; -const URL = 'https://prebid-bidder.rutarget.ru/bid'; -const SYNC_IFRAME_URL = 'https://tag.rutarget.ru/tag?event=otherPage&check=true&response=syncframe&synconly=true'; -const SYNC_IMAGE_URL = 'https://tag.rutarget.ru/tag?event=otherPage&check=true&synconly=true'; -const RUB = 'RUB'; -const TIME_TO_LIVE = 0; - -export const spec = { - code: BIDDER_CODE, - isBidRequestValid: (bid) => { - return Boolean(bid && bid.params && !isNaN(bid.params.placementId)); - }, - buildRequests: (validBidRequests, bidderRequest) => { - const payload = { - places: [], - settings: { - currency: RUB, - referrer: bidderRequest.refererInfo && bidderRequest.refererInfo.referer - } - }; - - for (let i = 0; i < validBidRequests.length; i++) { - const bid = validBidRequests[i]; - - payload.places.push({ - id: bid.bidId, - placementId: bid.params.placementId, - sizes: bid.sizes - }); - } - - return { - method: 'POST', - url: URL, - data: payload - }; - }, - interpretResponse: (serverResponse) => { - const bids = serverResponse.body && serverResponse.body.bids; - if (!bids) { - return []; - } - - const bidResponses = []; - - for (let i = 0; i < bids.length; i++) { - const bid = bids[i]; - - bidResponses.push({ - requestId: bid.id, - cpm: bid.cpm, - width: bid.size.width, - height: bid.size.height, - creativeId: bid.creativeId, - currency: RUB, - netRevenue: true, - ttl: TIME_TO_LIVE, - adUrl: bid.displayUrl - }); - } - - return bidResponses; - }, - getUserSyncs: (syncOptions) => { - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: SYNC_IFRAME_URL - }]; - } - - if (syncOptions.pixelEnabled) { - return [{ - type: 'image', - url: SYNC_IMAGE_URL - }]; - } - - return []; - } -}; - -registerBidder(spec); diff --git a/modules/segmentoBidAdapter.md b/modules/segmentoBidAdapter.md deleted file mode 100644 index e64153195c5..00000000000 --- a/modules/segmentoBidAdapter.md +++ /dev/null @@ -1,33 +0,0 @@ -# Overview - -``` -Module Name: Segmento Bidder Adapter -Module Type: Bidder Adapter -Maintainer: ssp@segmento.ru -``` - -# Description - -Module that connects to Segmento's demand sources - -# Test Parameters -``` -var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[240,400],[160,600]], - } - }, - bids: [ - { - bidder: 'segmento', - params: { - placementId: -1 - } - } - ] - } -]; -``` diff --git a/modules/sekindoUMBidAdapter.js b/modules/sekindoUMBidAdapter.js deleted file mode 100644 index bea25173747..00000000000 --- a/modules/sekindoUMBidAdapter.js +++ /dev/null @@ -1,119 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -export const spec = { - code: 'sekindoUM', - supportedMediaTypes: ['banner', 'video'], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - if (bid.mediaType == 'video' || (typeof bid.mediaTypes == 'object' && typeof bid.mediaTypes.video == 'object')) { - if (typeof bid.params.video != 'object' || typeof bid.params.video.playerWidth == 'undefined' || typeof bid.params.video.playerHeight == 'undefined') { - return false; - } - } - return !!(bid.params.spaceId); - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests, bidderRequest) { - var pubUrl = null; - try { - if (window.top == window) { - pubUrl = window.location.href; - } else { - try { - pubUrl = window.top.location.href; - } catch (e2) { - pubUrl = document.referrer; - } - } - } catch (e1) {} - - return validBidRequests.map(bidRequest => { - var subId = utils.getBidIdParameter('subId', bidRequest.params); - var spaceId = utils.getBidIdParameter('spaceId', bidRequest.params); - var bidfloor = utils.getBidIdParameter('bidfloor', bidRequest.params); - var protocol = (document.location.protocol === 'https:' ? 's' : ''); - var queryString = ''; - - queryString = utils.tryAppendQueryString(queryString, 's', spaceId); - queryString = utils.tryAppendQueryString(queryString, 'subId', subId); - queryString = utils.tryAppendQueryString(queryString, 'pubUrl', pubUrl); - queryString = utils.tryAppendQueryString(queryString, 'hbTId', bidRequest.transactionId); - queryString = utils.tryAppendQueryString(queryString, 'hbBidId', bidRequest.bidId); - queryString = utils.tryAppendQueryString(queryString, 'hbver', '4'); - queryString = utils.tryAppendQueryString(queryString, 'hbcb', '1');/// legasy - queryString = utils.tryAppendQueryString(queryString, 'dcpmflr', bidfloor); - queryString = utils.tryAppendQueryString(queryString, 'protocol', protocol); - queryString = utils.tryAppendQueryString(queryString, 'x', bidRequest.params.width); - queryString = utils.tryAppendQueryString(queryString, 'y', bidRequest.params.height); - if (bidderRequest && bidderRequest.gdprConsent) { - queryString = utils.tryAppendQueryString(queryString, 'gdprConsent', bidderRequest.gdprConsent.consentString); - queryString = utils.tryAppendQueryString(queryString, 'gdpr', (bidderRequest.gdprConsent.gdprApplies) ? '1' : '0'); - } - if (bidRequest.mediaType === 'video' || (typeof bidRequest.mediaTypes == 'object' && typeof bidRequest.mediaTypes.video == 'object')) { - queryString = utils.tryAppendQueryString(queryString, 'x', bidRequest.params.playerWidth); - queryString = utils.tryAppendQueryString(queryString, 'y', bidRequest.params.playerHeight); - if (typeof vid_vastType != 'undefined') { // eslint-disable-line camelcase - queryString = utils.tryAppendQueryString(queryString, 'vid_vastType', bidRequest.params.vid_vastType); - } - if (typeof bidRequest.mediaTypes == 'object' && typeof bidRequest.mediaTypes.video == 'object' && typeof bidRequest.mediaTypes.video.context == 'string') { - queryString = utils.tryAppendQueryString(queryString, 'vid_context', bidRequest.mediaTypes.video.context); - } - } - - var endpointUrl = 'https' + '://hb.sekindo.com/live/liveView.php'; - - return { - method: 'GET', - url: endpointUrl, - data: queryString, - }; - }); - }, - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse, bidRequest) { - if (typeof serverResponse !== 'object') { - return []; - } - - let bidResponses = []; - var bidResponse = { - requestId: serverResponse.body.id, - bidderCode: spec.code, - cpm: serverResponse.body.cpm, - width: serverResponse.body.width, - height: serverResponse.body.height, - creativeId: serverResponse.body.creativeId, - currency: serverResponse.body.currency, - netRevenue: serverResponse.body.netRevenue, - ttl: serverResponse.body.ttl - }; - if (bidRequest.mediaType == 'video') { - if (typeof serverResponse.body.vastUrl != 'undefined') { - bidResponse.vastUrl = serverResponse.body.vastUrl; - } else { - bidResponse.vastXml = serverResponse.body.vastXml; - } - } else { - bidResponse.ad = serverResponse.body.ad; - } - - bidResponses.push(bidResponse); - return bidResponses; - } -} -registerBidder(spec); diff --git a/modules/sekindoUMBidAdapter.md b/modules/sekindoUMBidAdapter.md deleted file mode 100644 index eeffff928eb..00000000000 --- a/modules/sekindoUMBidAdapter.md +++ /dev/null @@ -1,43 +0,0 @@ -# Overview - -**Module Name**: sekindoUM Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: nissime@sekindo.com - -# Description - -Connects to Sekindo (part of UM) demand source to fetch bids. -Banner, Outstream and Native formats are supported. - - -# Test Parameters -``` - var adUnits = [{ - code: 'banner-ad-div', - sizes: [[300, 250]], - bids: [{ - bidder: 'sekindoUM', - params: { - spaceId: 14071 - width:300, ///optional - height:250, //optional - } - }] - }, - { - code: 'video-ad-div', - sizes: [[640, 480]], - bids: [{ - bidder: 'sekindoUM', - params: { - spaceId: 87812, - video:{ - playerWidth:640, - playerHeight:480, - vid_vastType: 5 //optional - } - } - }] - } - ]; -``` diff --git a/modules/sharedIdSystem.js b/modules/sharedIdSystem.js deleted file mode 100644 index defa8d22639..00000000000 --- a/modules/sharedIdSystem.js +++ /dev/null @@ -1,373 +0,0 @@ -/** - * This module adds Shared ID support to the User ID module - * The {@link module:modules/userId} module is required. - * @module modules/sharedIdSystem - * @requires module:modules/userId - */ - -import * as utils from '../src/utils.js' -import {ajax} from '../src/ajax.js'; -import {submodule} from '../src/hook.js'; -import { uspDataHandler, coppaDataHandler } from '../src/adapterManager.js'; - -const MODULE_NAME = 'sharedId'; -const ID_SVC = 'https://id.sharedid.org/id'; -const DEFAULT_24_HOURS = 86400; -const OPT_OUT_VALUE = '00000000000000000000000000'; -// These values should NEVER change. If -// they do, we're no longer making ulids! -const ENCODING = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'; // Crockford's Base32 -const ENCODING_LEN = ENCODING.length; -const TIME_MAX = Math.pow(2, 48) - 1; -const TIME_LEN = 10; -const RANDOM_LEN = 16; -const id = factory(); -const GVLID = 887; -/** - * Constructs cookie value - * @param value - * @param needsSync - * @returns {string} - */ -function constructCookieValue(value, needsSync) { - const cookieValue = {}; - cookieValue.id = value; - cookieValue.ts = utils.timestamp(); - if (needsSync) { - cookieValue.ns = true; - } - utils.logInfo('SharedId: cookie Value: ' + JSON.stringify(cookieValue)); - return cookieValue; -} - -/** - * Checks if id needs to be synced - * @param configParams - * @param storedId - * @returns {boolean} - */ -function isIdSynced(configParams, storedId) { - const needSync = storedId.ns; - if (needSync) { - return true; - } - if (!configParams || typeof configParams.syncTime !== 'number') { - utils.logInfo('SharedId: Sync time is not configured or is not a number'); - } - let syncTime = (!configParams || typeof configParams.syncTime !== 'number') ? DEFAULT_24_HOURS : configParams.syncTime; - if (syncTime > DEFAULT_24_HOURS) { - syncTime = DEFAULT_24_HOURS; - } - const cookieTimestamp = storedId.ts; - if (cookieTimestamp) { - var secondBetweenTwoDate = timeDifferenceInSeconds(utils.timestamp(), cookieTimestamp); - return secondBetweenTwoDate >= syncTime; - } - return false; -} - -/** - * Gets time difference in secounds - * @param date1 - * @param date2 - * @returns {number} - */ -function timeDifferenceInSeconds(date1, date2) { - const diff = (date1 - date2) / 1000; - return Math.abs(Math.round(diff)); -} - -/** - * id generation call back - * @param result - * @param callback - * @returns {{success: success, error: error}} - */ -function idGenerationCallback(callback) { - return { - success: function (responseBody) { - let value = {}; - if (responseBody) { - try { - let responseObj = JSON.parse(responseBody); - utils.logInfo('SharedId: Generated SharedId: ' + responseObj.sharedId); - value = constructCookieValue(responseObj.sharedId, false); - } catch (error) { - utils.logError(error); - } - } - callback(value); - }, - error: function (statusText, responseBody) { - const value = constructCookieValue(id(), true); - utils.logInfo('SharedId: Ulid Generated SharedId: ' + value.id); - callback(value); - } - } -} - -/** - * existing id generation call back - * @param result - * @param callback - * @returns {{success: success, error: error}} - */ -function existingIdCallback(storedId, callback) { - return { - success: function (responseBody) { - utils.logInfo('SharedId: id to be synced: ' + storedId.id); - if (responseBody) { - try { - let responseObj = JSON.parse(responseBody); - storedId = constructCookieValue(responseObj.sharedId, false); - utils.logInfo('SharedId: Older SharedId: ' + storedId.id); - } catch (error) { - utils.logError(error); - } - } - callback(storedId); - }, - error: function () { - utils.logInfo('SharedId: Sync error for id : ' + storedId.id); - callback(storedId); - } - } -} - -/** - * Encode the id - * @param value - * @returns {string|*} - */ -function encodeId(value) { - const result = {}; - const sharedId = (value && typeof value['id'] === 'string') ? value['id'] : undefined; - if (sharedId == OPT_OUT_VALUE) { - return undefined; - } - if (sharedId) { - const bidIds = { - id: sharedId, - } - const ns = (value && typeof value['ns'] === 'boolean') ? value['ns'] : undefined; - if (ns == undefined) { - bidIds.third = sharedId; - } - result.sharedid = bidIds; - utils.logInfo('SharedId: Decoded value ' + JSON.stringify(result)); - return result; - } - return sharedId; -} - -/** - * the factory to generate unique identifier based on time and current pseudorandom number - * @param {string} the current pseudorandom number generator - * @returns {function(*=): *} - */ -function factory(currPrng) { - if (!currPrng) { - currPrng = detectPrng(); - } - return function ulid(seedTime) { - if (isNaN(seedTime)) { - seedTime = Date.now(); - } - return encodeTime(seedTime, TIME_LEN) + encodeRandom(RANDOM_LEN, currPrng); - }; -} - -/** - * creates and logs the error message - * @function - * @param {string} error message - * @returns {Error} - */ -function createError(message) { - utils.logError(message); - const err = new Error(message); - err.source = 'sharedId'; - return err; -} - -/** - * gets a a random charcter from generated pseudorandom number - * @param {string} the generated pseudorandom number - * @returns {string} - */ -function randomChar(prng) { - let rand = Math.floor(prng() * ENCODING_LEN); - if (rand === ENCODING_LEN) { - rand = ENCODING_LEN - 1; - } - return ENCODING.charAt(rand); -} - -/** - * encodes the time based on the length - * @param now - * @param len - * @returns {string} encoded time. - */ -function encodeTime (now, len) { - if (isNaN(now)) { - throw new Error(now + ' must be a number'); - } - - if (Number.isInteger(now) === false) { - throw createError('time must be an integer'); - } - - if (now > TIME_MAX) { - throw createError('cannot encode time greater than ' + TIME_MAX); - } - if (now < 0) { - throw createError('time must be positive'); - } - - if (Number.isInteger(len) === false) { - throw createError('length must be an integer'); - } - if (len < 0) { - throw createError('length must be positive'); - } - - let mod; - let str = ''; - for (; len > 0; len--) { - mod = now % ENCODING_LEN; - str = ENCODING.charAt(mod) + str; - now = (now - mod) / ENCODING_LEN; - } - return str; -} - -/** - * encodes random character - * @param len - * @param prng - * @returns {string} - */ -function encodeRandom (len, prng) { - let str = ''; - for (; len > 0; len--) { - str = randomChar(prng) + str; - } - return str; -} - -/** - * detects the pseudorandom number generator and generates the random number - * @function - * @param {string} error message - * @returns {string} a random number - */ -function detectPrng(root) { - if (!root) { - root = typeof window !== 'undefined' ? window : null; - } - const browserCrypto = root && (root.crypto || root.msCrypto); - if (browserCrypto) { - return () => { - const buffer = new Uint8Array(1); - browserCrypto.getRandomValues(buffer); - return buffer[0] / 0xff; - }; - } - return () => Math.random(); -} - -/** - * Builds and returns the shared Id URL with attached consent data if applicable - * @param {Object} consentData - * @return {string} - */ -function sharedIdUrl(consentData) { - const usPrivacyString = uspDataHandler.getConsentData(); - let sharedIdUrl = ID_SVC; - if (usPrivacyString) { - sharedIdUrl = `${ID_SVC}?us_privacy=${usPrivacyString}`; - } - if (!consentData || typeof consentData.gdprApplies !== 'boolean' || !consentData.gdprApplies) return sharedIdUrl; - if (usPrivacyString) { - sharedIdUrl = `${sharedIdUrl}&gdpr=1&gdpr_consent=${consentData.consentString}` - return sharedIdUrl; - } - sharedIdUrl = `${ID_SVC}?gdpr=1&gdpr_consent=${consentData.consentString}`; - return sharedIdUrl -} - -/** @type {Submodule} */ -export const sharedIdSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: MODULE_NAME, - - /** - * Vendor id of Prebid - * @type {Number} - */ - gvlid: GVLID, - /** - * decode the stored id value for passing to bid requests - * @function - * @param {string} value - * @returns {{sharedid:{ id: string, third:string}} or undefined if value doesn't exists - */ - decode(value) { - return (value) ? encodeId(value) : undefined; - }, - - /** - * performs action to obtain id and return a value. - * @function - * @param {SubmoduleConfig} [config] - * @param {ConsentData|undefined} consentData - * @returns {sharedId} - */ - getId(config, consentData) { - const coppa = coppaDataHandler.getCoppa(); - if (coppa) { - utils.logInfo('SharedId: IDs not provided for coppa requests, exiting SharedId'); - return; - } - const resp = function (callback) { - utils.logInfo('SharedId: Sharedid doesnt exists, new cookie creation'); - ajax(sharedIdUrl(consentData), idGenerationCallback(callback), undefined, {method: 'GET', withCredentials: true}); - }; - return {callback: resp}; - }, - - /** - * performs actions even if the id exists and returns a value - * @param config - * @param consentData - * @param storedId - * @returns {{callback: *}} - */ - extendId(config, consentData, storedId) { - const coppa = coppaDataHandler.getCoppa(); - if (coppa) { - utils.logInfo('SharedId: IDs not provided for coppa requests, exiting SharedId'); - return; - } - const configParams = (config && config.params) || {}; - utils.logInfo('SharedId: Existing shared id ' + storedId.id); - const resp = function (callback) { - const needSync = isIdSynced(configParams, storedId); - if (needSync) { - utils.logInfo('SharedId: Existing shared id ' + storedId + ' is not synced'); - const sharedIdPayload = {}; - sharedIdPayload.sharedId = storedId.id; - const payloadString = JSON.stringify(sharedIdPayload); - ajax(sharedIdUrl(consentData), existingIdCallback(storedId, callback), payloadString, {method: 'POST', withCredentials: true}); - } - }; - return {callback: resp}; - } -}; - -// Register submodule for userId -submodule('userId', sharedIdSubmodule); diff --git a/modules/sharedIdSystem.md b/modules/sharedIdSystem.md deleted file mode 100644 index a4541c16c49..00000000000 --- a/modules/sharedIdSystem.md +++ /dev/null @@ -1,43 +0,0 @@ -## Shared ID User ID Submodule - -Shared ID User ID Module generates a UUID that can be utilized to improve user matching.This module enables timely synchronization which handles sharedId.org optout. This module does not require any registration. - -### Building Prebid with Shared Id Support -Your Prebid build must include the modules for both **userId** and **sharedId** submodule. Follow the build instructions for Prebid as -explained in the top level README.md file of the Prebid source tree. - -ex: $ gulp build --modules=userId,sharedIdSystem - -### Prebid Params - -Individual params may be set for the Shared ID User ID Submodule. -``` -pbjs.setConfig({ - userSync: { - userIds: [{ - name: 'sharedId', - params: { - syncTime: 60 // in seconds, default is 24 hours - }, - storage: { - name: 'sharedid', - type: 'cookie', - expires: 28 - }, - }] - } -}); -``` - -### Parameter Descriptions for the `usersync` Configuration Section -The below parameters apply only to the Shared ID User ID Module integration. - -| Params under usersync.userIds[]| Scope | Type | Description | Example | -| --- | --- | --- | --- | --- | -| name | Required | String | ID value for the Shared ID module - `"sharedId"` | `"sharedId"` | -| params | Optional | Object | Details for sharedId syncing. | | -| params.syncTime | Optional | Object | Configuration to define the frequency(in seconds) of id synchronization. By default id is synchronized every 24 hours | 60 | -| storage | Required | Object | The publisher must specify the local storage in which to store the results of the call to get the user ID. This can be either cookie or HTML5 storage. | | -| storage.type | Required | String | This is where the results of the user ID will be stored. The recommended method is `localStorage` by specifying `html5`. | `"html5"` | -| storage.name | Required | String | The name of the cookie or html5 local storage where the user ID will be stored. | `"sharedid"` | -| storage.expires | Optional | Integer | How long (in days) the user ID information will be stored. | `28` | diff --git a/modules/sharethroughAnalyticsAdapter.js b/modules/sharethroughAnalyticsAdapter.js deleted file mode 100644 index 5147b2a4275..00000000000 --- a/modules/sharethroughAnalyticsAdapter.js +++ /dev/null @@ -1,71 +0,0 @@ -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -const utils = require('../src/utils.js'); - -const emptyUrl = ''; -const analyticsType = 'endpoint'; -const STR_BIDDER_CODE = 'sharethrough'; -const STR_VERSION = '0.1.0'; - -var sharethroughAdapter = Object.assign(adapter( - { - emptyUrl, - analyticsType - } -), -{ - STR_BEACON_HOST: 'https://b.sharethrough.com/butler?', - placementCodeSet: {}, - - track({ eventType, args }) { - if (eventType === 'bidRequested' && args.bidderCode === 'sharethrough') { - var bids = args.bids; - var keys = Object.keys(bids); - for (var i = 0; i < keys.length; i++) { - this.placementCodeSet[bids[keys[i]].placementCode] = args.bids[keys[i]]; - } - } - - if (eventType === 'bidWon') { - this.bidWon(args); - } - }, - - bidWon(args) { - const curBidderCode = args.bidderCode; - - if (curBidderCode !== STR_BIDDER_CODE && (args.adUnitCode in this.placementCodeSet)) { - let strBid = this.placementCodeSet[args.adUnitCode]; - this.fireLoseBeacon(curBidderCode, args.cpm, strBid.adserverRequestId, 'headerBidLose'); - } - }, - - fireLoseBeacon(winningBidderCode, winningCPM, arid, type) { - let loseBeaconUrl = this.STR_BEACON_HOST; - loseBeaconUrl = utils.tryAppendQueryString(loseBeaconUrl, 'winnerBidderCode', winningBidderCode); - loseBeaconUrl = utils.tryAppendQueryString(loseBeaconUrl, 'winnerCpm', winningCPM); - loseBeaconUrl = utils.tryAppendQueryString(loseBeaconUrl, 'arid', arid); - loseBeaconUrl = utils.tryAppendQueryString(loseBeaconUrl, 'type', type); - loseBeaconUrl = this.appendEnvFields(loseBeaconUrl); - - this.fireBeacon(loseBeaconUrl); - }, - appendEnvFields(url) { - url = utils.tryAppendQueryString(url, 'hbVersion', '$prebid.version$'); - url = utils.tryAppendQueryString(url, 'strVersion', STR_VERSION); - url = utils.tryAppendQueryString(url, 'hbSource', 'prebid'); - - return url; - }, - fireBeacon(theUrl) { - const img = new Image(); - img.src = theUrl; - } -}); - -adapterManager.registerAnalyticsAdapter({ - adapter: sharethroughAdapter, - code: 'sharethrough' -}); - -export default sharethroughAdapter; diff --git a/modules/sharethroughBidAdapter.js b/modules/sharethroughBidAdapter.js deleted file mode 100644 index 68ccde0da46..00000000000 --- a/modules/sharethroughBidAdapter.js +++ /dev/null @@ -1,295 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; - -const VERSION = '3.3.2'; -const BIDDER_CODE = 'sharethrough'; -const STR_ENDPOINT = 'https://btlr.sharethrough.com/WYu2BXv1/v1'; -const DEFAULT_SIZE = [1, 1]; - -// this allows stubbing of utility function that is used internally by the sharethrough adapter -export const sharethroughInternal = { - b64EncodeUnicode, - handleIframe, - isLockedInFrame, - getProtocol -}; - -export const sharethroughAdapterSpec = { - code: BIDDER_CODE, - - isBidRequestValid: bid => !!bid.params.pkey && bid.bidder === BIDDER_CODE, - - buildRequests: (bidRequests, bidderRequest) => { - return bidRequests.map(bidRequest => { - let query = { - placement_key: bidRequest.params.pkey, - bidId: bidRequest.bidId, - consent_required: false, - instant_play_capable: canAutoPlayHTML5Video(), - hbSource: 'prebid', - hbVersion: '$prebid.version$', - strVersion: VERSION - }; - - Object.assign(query, handleUniversalIds(bidRequest)); - - const nonHttp = sharethroughInternal.getProtocol().indexOf('http') < 0; - query.secure = nonHttp || (sharethroughInternal.getProtocol().indexOf('https') > -1); - - if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.consentString) { - query.consent_string = bidderRequest.gdprConsent.consentString; - } - - if (bidderRequest && bidderRequest.gdprConsent) { - query.consent_required = !!bidderRequest.gdprConsent.gdprApplies; - } - - if (bidderRequest && bidderRequest.uspConsent) { - query.us_privacy = bidderRequest.uspConsent - } - - if (config.getConfig('coppa') === true) { - query.coppa = true - } - - if (bidRequest.schain) { - query.schain = JSON.stringify(bidRequest.schain); - } - - if (bidRequest.bidfloor) { - query.bidfloor = parseFloat(bidRequest.bidfloor); - } - - if (bidRequest.params.badv) { - query.badv = bidRequest.params.badv; - } - - if (bidRequest.params.bcat) { - query.bcat = bidRequest.params.bcat; - } - - // Data that does not need to go to the server, - // but we need as part of interpretResponse() - const strData = { - skipIframeBusting: bidRequest.params.iframe, - iframeSize: bidRequest.params.iframeSize, - sizes: bidRequest.sizes - }; - - return { - method: 'POST', - url: STR_ENDPOINT, - data: query, - strData: strData - }; - }) - }, - - interpretResponse: ({ body }, req) => { - if (!body || !body.creatives || !body.creatives.length) { - return []; - } - - const creative = body.creatives[0]; - let size = DEFAULT_SIZE; - if (req.strData.iframeSize || req.strData.sizes.length) { - size = req.strData.iframeSize - ? req.strData.iframeSize - : getLargestSize(req.strData.sizes); - } - - return [{ - requestId: req.data.bidId, - width: size[0], - height: size[1], - cpm: creative.cpm, - creativeId: creative.creative.creative_key, - dealId: creative.creative.deal_id, - currency: 'USD', - netRevenue: true, - ttl: 360, - meta: { advertiserDomains: creative.creative && creative.creative.adomain ? creative.creative.adomain : [] }, - ad: generateAd(body, req) - }]; - }, - - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - const syncParams = uspConsent ? `&us_privacy=${uspConsent}` : ''; - const syncs = []; - const shouldCookieSync = syncOptions.pixelEnabled && - serverResponses.length > 0 && - serverResponses[0].body && - serverResponses[0].body.cookieSyncUrls; - - if (shouldCookieSync) { - serverResponses[0].body.cookieSyncUrls.forEach(url => { - syncs.push({ type: 'image', url: url + syncParams }); - }); - } - - return syncs; - }, - - // Empty implementation for prebid core to be able to find it - onTimeout: (data) => {}, - - // Empty implementation for prebid core to be able to find it - onBidWon: (bid) => {}, - - // Empty implementation for prebid core to be able to find it - onSetTargeting: (bid) => {} -}; - -function handleUniversalIds(bidRequest) { - if (!bidRequest.userId) return {}; - - const universalIds = {}; - - const ttd = utils.deepAccess(bidRequest, 'userId.tdid'); - if (ttd) universalIds.ttduid = ttd; - - const pubc = utils.deepAccess(bidRequest, 'userId.pubcid') || utils.deepAccess(bidRequest, 'crumbs.pubcid'); - if (pubc) universalIds.pubcid = pubc; - - const idl = utils.deepAccess(bidRequest, 'userId.idl_env'); - if (idl) universalIds.idluid = idl; - - const id5 = utils.deepAccess(bidRequest, 'userId.id5id.uid'); - if (id5) { - universalIds.id5uid = { id: id5 }; - const id5link = utils.deepAccess(bidRequest, 'userId.id5id.ext.linkType'); - if (id5link) universalIds.id5uid.linkType = id5link; - } - - const lipb = utils.deepAccess(bidRequest, 'userId.lipb.lipbid'); - if (lipb) universalIds.liuid = lipb; - - const shd = utils.deepAccess(bidRequest, 'userId.sharedid'); - if (shd) universalIds.shduid = shd; // object with keys: id & third - - return universalIds; -} - -function getLargestSize(sizes) { - function area(size) { - return size[0] * size[1]; - } - - return sizes.reduce((prev, current) => { - if (area(current) > area(prev)) { - return current - } else { - return prev - } - }); -} - -function generateAd(body, req) { - const strRespId = `str_response_${req.data.bidId}`; - - let adMarkup = ` -
-
- - `; - - if (req.strData.skipIframeBusting) { - // Don't break out of iframe - adMarkup = adMarkup + ``; - } else { - // Add logic to the markup that detects whether or not in top level document is accessible - // this logic will deploy sfp.js and/or iframe buster script(s) as appropriate - adMarkup = adMarkup + ` - - `; - } - - return adMarkup; -} - -function handleIframe () { - // only load iframe buster JS if we can access the top level document - // if we are 'locked in' to this frame then no point trying to bust out: we may as well render in the frame instead - var iframeBusterLoaded = false; - if (!window.lockedInFrame) { - var sfpIframeBusterJs = document.createElement('script'); - sfpIframeBusterJs.src = 'https://native.sharethrough.com/assets/sfp-set-targeting.js'; - sfpIframeBusterJs.type = 'text/javascript'; - try { - window.document.getElementsByTagName('body')[0].appendChild(sfpIframeBusterJs); - iframeBusterLoaded = true; - } catch (e) { - utils.logError('Trouble writing frame buster script, error details:', e); - } - } - - var clientJsLoaded = (!iframeBusterLoaded) ? !!(window.STR && window.STR.Tag) : !!(window.top.STR && window.top.STR.Tag); - if (!clientJsLoaded) { - var sfpJs = document.createElement('script'); - sfpJs.src = 'https://native.sharethrough.com/assets/sfp.js'; - sfpJs.type = 'text/javascript'; - - // only add sfp js to window.top if iframe busting successfully loaded; otherwise, add to iframe - try { - if (iframeBusterLoaded) { - window.top.document.getElementsByTagName('body')[0].appendChild(sfpJs); - } else { - window.document.getElementsByTagName('body')[0].appendChild(sfpJs); - } - } catch (e) { - utils.logError('Trouble writing sfp script, error details:', e); - } - } -} - -// determines if we are capable of busting out of the iframe we are in -// if we catch a DOMException when trying to access top-level document, it means we're stuck in the frame we're in -function isLockedInFrame () { - window.lockedInFrame = false; - try { - window.lockedInFrame = !window.top.document; - } catch (e) { - window.lockedInFrame = (e instanceof DOMException); - } -} - -// See https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#The_Unicode_Problem -function b64EncodeUnicode(str) { - return btoa( - encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, - function toSolidBytes(match, p1) { - return String.fromCharCode('0x' + p1); - })); -} - -function canAutoPlayHTML5Video() { - const userAgent = navigator.userAgent; - if (!userAgent) return false; - - const isAndroid = /Android/i.test(userAgent); - const isiOS = /iPhone|iPad|iPod/i.test(userAgent); - const chromeVersion = parseInt((/Chrome\/([0-9]+)/.exec(userAgent) || [0, 0])[1]); - const chromeiOSVersion = parseInt((/CriOS\/([0-9]+)/.exec(userAgent) || [0, 0])[1]); - const safariVersion = parseInt((/Version\/([0-9]+)/.exec(userAgent) || [0, 0])[1]); - - if ( - (isAndroid && chromeVersion >= 53) || - (isiOS && (safariVersion >= 10 || chromeiOSVersion >= 53)) || - !(isAndroid || isiOS) - ) { - return true; - } else { - return false; - } -} - -function getProtocol() { - return document.location.protocol; -} - -registerBidder(sharethroughAdapterSpec); diff --git a/modules/sharethroughBidAdapter.md b/modules/sharethroughBidAdapter.md deleted file mode 100644 index 396b8164577..00000000000 --- a/modules/sharethroughBidAdapter.md +++ /dev/null @@ -1,44 +0,0 @@ -# Overview - -``` -Module Name: Sharethrough Bidder Adapter -Module Type: Bidder Adapter -Maintainer: pubgrowth.engineering@sharethrough.com -``` - -# Description - -Module that connects to Sharethrough's demand sources - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - sizes: [[300,250], [1, 1]], - bids: [ - { - bidder: "sharethrough", - params: { - // REQUIRED - The placement key - pkey: 'LuB3vxGGFrBZJa6tifXW4xgK', - - // OPTIONAL - Render Sharethrough creative in an iframe, defaults to false - iframe: true, - - // OPTIONAL - If iframeSize is provided, we'll use this size for the iframe - // otherwise we'll grab the largest size from the sizes array - // This is ignored if iframe: false - iframeSize: [250, 250], - - // OPTIONAL - Blocked Advertiser Domains - badv: ['domain1.com', 'domain2.com'], - - // OPTIONAL - Blocked Categories (IAB codes) - bcat: ['IAB1-1', 'IAB1-2'], - } - } - ] - } - ]; -``` diff --git a/modules/shinezBidAdapter.js b/modules/shinezBidAdapter.js deleted file mode 100644 index d5734d23fdc..00000000000 --- a/modules/shinezBidAdapter.js +++ /dev/null @@ -1,83 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'shinez'; -const BIDDER_SHORT_CODE = 'shz'; -const ADAPTER_VERSION = '1.0.0'; - -const TARGET_URL = 'https://shinez-ssp.shinez.workers.dev/prebid'; - -export const spec = { - code: BIDDER_CODE, - version: ADAPTER_VERSION, - aliases: { - code: BIDDER_SHORT_CODE - }, - supportedMediaTypes: [ BANNER ], - isBidRequestValid: isBidRequestValid, - buildRequests: buildRequests, - interpretResponse: interpretResponse, -}; - -export const internal = { - TARGET_URL -} - -function isBidRequestValid(bid) { - return !!(bid && bid.params && - bid.params.placementId && typeof bid.params.placementId === 'string' && - (bid.params.unit == null || (typeof bid.params.unit === 'string' && bid.params.unit.length > 0)) - ); -} - -function buildRequests(validBidRequests, bidderRequest) { - const utcOffset = (new Date()).getTimezoneOffset(); - const data = []; - validBidRequests.forEach(function(bidRequest) { - data.push(_buildServerBidRequest(bidRequest, bidderRequest, utcOffset)); - }); - const request = { - method: 'POST', - url: TARGET_URL, - data: data - }; - return request; -} - -function interpretResponse(serverResponse, request) { - const bids = []; - serverResponse.body.forEach(function(serverBid) { - bids.push(_convertServerBid(serverBid)); - }); - return bids; -} - -function _buildServerBidRequest(bidRequest, bidderRequest, utcOffset) { - return { - bidId: bidRequest.bidId, - transactionId: bidRequest.transactionId, - crumbs: bidRequest.crumbs, - mediaTypes: bidRequest.mediaTypes, - refererInfo: bidderRequest.refererInfo, - placementId: bidRequest.params.placementId, - utcOffset: utcOffset, - adUnitCode: bidRequest.adUnitCode, - unit: bidRequest.params.unit - } -} - -function _convertServerBid(response) { - return { - requestId: response.bidId, - cpm: response.cpm, - currency: response.currency, - width: response.width, - height: response.height, - ad: response.ad, - ttl: response.ttl, - creativeId: response.creativeId, - netRevenue: response.netRevenue - }; -} - -registerBidder(spec); diff --git a/modules/shinezBidAdapter.md b/modules/shinezBidAdapter.md deleted file mode 100644 index e040cfbf36b..00000000000 --- a/modules/shinezBidAdapter.md +++ /dev/null @@ -1,33 +0,0 @@ -# Overview - -``` -Module Name: Shinez Bidder Adapter -Module Type: Bidder Adapter -Maintainer: tech-team@shinez.io -``` - -# Description - -Connects to shinez.io demand sources. - -The Shinez adapter requires setup and approval from the Shinez team. -Please reach out to tech-team@shinez.io for more information. - -# Test Parameters - -```javascript -var adUnits = [{ - code: "test-div", - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [{ - bidder: "shinez", - params: { - placementId: "00654321" - } - }] -}]; -``` \ No newline at end of file diff --git a/modules/showheroes-bsBidAdapter.js b/modules/showheroes-bsBidAdapter.js deleted file mode 100644 index d0eb8c6a589..00000000000 --- a/modules/showheroes-bsBidAdapter.js +++ /dev/null @@ -1,289 +0,0 @@ -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; -import { Renderer } from '../src/Renderer.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { VIDEO, BANNER } from '../src/mediaTypes.js'; -import { loadExternalScript } from '../src/adloader.js'; - -const PROD_ENDPOINT = 'https://bs.showheroes.com/api/v1/bid'; -const STAGE_ENDPOINT = 'https://bid-service.stage.showheroes.com/api/v1/bid'; -const PROD_PUBLISHER_TAG = 'https://static.showheroes.com/publishertag.js'; -const STAGE_PUBLISHER_TAG = 'https://pubtag.stage.showheroes.com/publishertag.js'; -const PROD_VL = 'https://video-library.showheroes.com'; -const STAGE_VL = 'https://video-library.stage.showheroes.com'; -const BIDDER_CODE = 'showheroes-bs'; -const TTL = 300; - -function getEnvURLs(isStage) { - return { - pubTag: isStage ? STAGE_PUBLISHER_TAG : PROD_PUBLISHER_TAG, - vlHost: isStage ? STAGE_VL : PROD_VL - } -} - -export const spec = { - code: BIDDER_CODE, - aliases: ['showheroesBs'], - supportedMediaTypes: [VIDEO, BANNER], - isBidRequestValid: function(bid) { - return !!bid.params.playerId; - }, - buildRequests: function(validBidRequests, bidderRequest) { - let adUnits = []; - const pageURL = validBidRequests[0].params.contentPageUrl || bidderRequest.refererInfo.referer; - const isStage = !!validBidRequests[0].params.stage; - const isOutstream = utils.deepAccess(validBidRequests[0], 'mediaTypes.video.context') === 'outstream'; - const isCustomRender = utils.deepAccess(validBidRequests[0], 'params.outstreamOptions.customRender'); - const isNodeRender = utils.deepAccess(validBidRequests[0], 'params.outstreamOptions.slot') || utils.deepAccess(validBidRequests[0], 'params.outstreamOptions.iframe'); - const isNativeRender = utils.deepAccess(validBidRequests[0], 'renderer'); - const outstreamOptions = utils.deepAccess(validBidRequests[0], 'params.outstreamOptions'); - const isBanner = !!validBidRequests[0].mediaTypes.banner || (isOutstream && !(isCustomRender || isNativeRender || isNodeRender)); - const defaultSchain = validBidRequests[0].schain || {}; - - validBidRequests.forEach((bid) => { - const videoSizes = getVideoSizes(bid); - const bannerSizes = getBannerSizes(bid); - const vpaidMode = utils.getBidIdParameter('vpaidMode', bid.params); - - const makeBids = (type, size) => { - let context = ''; - let streamType = 2; - - if (type === BANNER) { - streamType = 5; - } else { - context = utils.deepAccess(bid, 'mediaTypes.video.context'); - if (vpaidMode && context === 'instream') { - streamType = 1; - } - if (context === 'outstream') { - streamType = 5; - } - } - - return { - type: streamType, - bidId: bid.bidId, - mediaType: type, - context: context, - playerId: utils.getBidIdParameter('playerId', bid.params), - auctionId: bidderRequest.auctionId, - bidderCode: BIDDER_CODE, - gdprConsent: bidderRequest.gdprConsent, - start: +new Date(), - timeout: 3000, - size: { - width: size[0], - height: size[1] - }, - params: bid.params, - schain: bid.schain || defaultSchain, - }; - }; - - videoSizes.forEach((size) => { - adUnits.push(makeBids(VIDEO, size)); - }); - - bannerSizes.forEach((size) => { - adUnits.push(makeBids(BANNER, size)); - }); - }); - - return { - url: isStage ? STAGE_ENDPOINT : PROD_ENDPOINT, - method: 'POST', - options: {contentType: 'application/json', accept: 'application/json'}, - data: { - 'user': [], - 'meta': { - 'adapterVersion': 2, - 'pageURL': encodeURIComponent(pageURL), - 'vastCacheEnabled': (!!config.getConfig('cache') && !isBanner && !outstreamOptions) || false, - 'isDesktop': utils.getWindowTop().document.documentElement.clientWidth > 700, - 'xmlAndTag': !!(isOutstream && isCustomRender) || false, - 'stage': isStage || undefined - }, - 'requests': adUnits, - 'debug': validBidRequests[0].params.debug || false, - } - }; - }, - interpretResponse: function(response, request) { - return createBids(response.body, request.data); - }, - getUserSyncs: function(syncOptions, serverResponses) { - const syncs = []; - - if (!serverResponses.length || !serverResponses[0].body.userSync) { - return syncs; - } - - const userSync = serverResponses[0].body.userSync; - - if (syncOptions.iframeEnabled) { - (userSync.iframes || []).forEach(url => { - syncs.push({ - type: 'iframe', - url - }); - }); - } - - if (syncOptions.pixelEnabled) { - (userSync.pixels || []).forEach(url => { - syncs.push({ - type: 'image', - url - }); - }); - } - return syncs; - }, -}; - -function createBids(bidRes, reqData) { - if (bidRes && (!Array.isArray(bidRes.bids) || bidRes.bids.length < 1)) { - return []; - } - - const bids = []; - const bidMap = {}; - (reqData.requests || []).forEach((bid) => { - bidMap[bid.bidId] = bid; - }); - - bidRes.bids.forEach(function (bid) { - const reqBid = bidMap[bid.bidId]; - const currentBidParams = reqBid.params; - let bidUnit = {}; - bidUnit.cpm = bid.cpm; - bidUnit.requestId = bid.bidId; - bidUnit.currency = bid.currency; - bidUnit.mediaType = bid.mediaType || VIDEO; - bidUnit.ttl = TTL; - bidUnit.creativeId = 'c_' + bid.bidId; - bidUnit.netRevenue = true; - bidUnit.width = bid.size.width; - bidUnit.height = bid.size.height; - if (bid.vastXml) { - bidUnit.vastXml = bid.vastXml; - bidUnit.adResponse = { - content: bid.vastXml, - }; - } - if (bid.vastTag) { - bidUnit.vastUrl = bid.vastTag; - } - if (bid.mediaType === BANNER) { - bidUnit.ad = getBannerHtml(bid, reqBid, reqData); - } else if (bid.context === 'outstream') { - const renderer = Renderer.install({ - id: bid.bidId, - url: '//', - config: { - playerId: reqBid.playerId, - width: bid.size.width, - height: bid.size.height, - vastUrl: bid.vastTag, - vastXml: bid.vastXml, - debug: reqData.debug, - isStage: !!reqData.meta.stage, - customRender: utils.getBidIdParameter('customRender', currentBidParams.outstreamOptions), - slot: utils.getBidIdParameter('slot', currentBidParams.outstreamOptions), - iframe: utils.getBidIdParameter('iframe', currentBidParams.outstreamOptions), - } - }); - renderer.setRender(outstreamRender); - bidUnit.renderer = renderer; - } - bids.push(bidUnit); - }); - - return bids; -} - -function outstreamRender(bid) { - const embedCode = createOutstreamEmbedCode(bid); - if (typeof bid.renderer.config.customRender === 'function') { - bid.renderer.config.customRender(bid, embedCode); - } else { - try { - const inIframe = utils.getBidIdParameter('iframe', bid.renderer.config); - if (inIframe && window.document.getElementById(inIframe).nodeName === 'IFRAME') { - const iframe = window.document.getElementById(inIframe); - let framedoc = iframe.contentDocument || (iframe.contentWindow && iframe.contentWindow.document); - framedoc.body.appendChild(embedCode); - return; - } - - const slot = utils.getBidIdParameter('slot', bid.renderer.config) || bid.adUnitCode; - if (slot && window.document.getElementById(slot)) { - window.document.getElementById(slot).appendChild(embedCode); - } else if (slot) { - utils.logError('[ShowHeroes][renderer] Error: spot not found'); - } - } catch (err) { - utils.logError('[ShowHeroes][renderer] Error:' + err.message) - } - } -} - -function createOutstreamEmbedCode(bid) { - const isStage = utils.getBidIdParameter('isStage', bid.renderer.config); - const urls = getEnvURLs(isStage); - - const fragment = window.document.createDocumentFragment(); - - let script = loadExternalScript(urls.pubTag, 'outstream', function () { - window.ShowheroesTag = this; - }); - script.setAttribute('data-player-host', urls.vlHost); - - const spot = window.document.createElement('div'); - spot.setAttribute('class', 'showheroes-spot'); - spot.setAttribute('data-player', utils.getBidIdParameter('playerId', bid.renderer.config)); - spot.setAttribute('data-debug', utils.getBidIdParameter('debug', bid.renderer.config)); - spot.setAttribute('data-ad-vast-tag', utils.getBidIdParameter('vastUrl', bid.renderer.config)); - spot.setAttribute('data-stream-type', 'outstream'); - - fragment.appendChild(spot); - fragment.appendChild(script); - return fragment; -} - -function getBannerHtml (bid, reqBid, reqData) { - const isStage = !!reqData.meta.stage; - const urls = getEnvURLs(isStage); - return ` - - - -
- - `; -} - -function getVideoSizes(bidRequest) { - return formatSizes(utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize') || []); -} - -function getBannerSizes(bidRequest) { - return formatSizes(utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes') || []); -} - -function formatSizes(sizes) { - if (!sizes || !sizes.length) { - return [] - } - return Array.isArray(sizes[0]) ? sizes : [sizes]; -} - -registerBidder(spec); diff --git a/modules/showheroes-bsBidAdapter.md b/modules/showheroes-bsBidAdapter.md deleted file mode 100644 index cde652e9d83..00000000000 --- a/modules/showheroes-bsBidAdapter.md +++ /dev/null @@ -1,127 +0,0 @@ -# Overview - -Module Name: ShowHeroes Bidder Adapter - -Module Type: Bidder Adapter - -Alias: showheroesBs - -Maintainer: tech@showheroes.com - -# Description - -Module that connects to ShowHeroes demand source to fetch bids. - -# Test Parameters -``` - var adUnits = [ - { - code: 'video', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'instream', - } - }, - bids: [ - { - bidder: "showheroes-bs", - params: { - playerId: '0151f985-fb1a-4f37-bb26-cfc62e43ec05', - vpaidMode: true // by default is 'false' - } - } - ] - }, - { - // if you have adSlot renderer or oustream should be returned as banner - code: 'video', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'outstream', - } - }, - bids: [ - { - bidder: "showheroes-bs", - params: { - playerId: '0151f985-fb1a-4f37-bb26-cfc62e43ec05', - } - } - ] - }, - { - code: 'video', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'outstream', - } - }, - bids: [ - { - bidder: "showheroes-bs", - params: { - playerId: '0151f985-fb1a-4f37-bb26-cfc62e43ec05', - - outstreamOptions: { - // Required for the outstream renderer to exact node, one of - iframe: 'iframe_id', - // or - slot: 'slot_id' - } - } - } - ] - }, - { - code: 'video', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'outstream', - } - }, - bids: [ - { - bidder: "showheroes-bs", - params: { - playerId: '0151f985-fb1a-4f37-bb26-cfc62e43ec05', - - outstreamOptions: { - // Custom outstream rendering function - customRender: function(bid, embedCode) { - // Example with embedCode - someContainer.appendChild(embedCode); - - // bid config data - var vastUrl = bid.renderer.config.vastUrl; - var vastXML = bid.renderer.config.vastXML; - var videoWidth = bid.renderer.config.width; - var videoHeight = bid.renderer.config.height; - var playerId = bid.renderer.config.playerId; - }, - } - } - } - ] - }, - { - code: 'banner', - mediaTypes: { - banner: { - sizes: [[640, 480]], - } - }, - bids: [ - { - bidder: "showheroes-bs", - params: { - playerId: '0151f985-fb1a-4f37-bb26-cfc62e43ec05', - } - } - ] - } - ]; -``` diff --git a/modules/sigmoidAnalyticsAdapter.js b/modules/sigmoidAnalyticsAdapter.js deleted file mode 100644 index 303fbbc8995..00000000000 --- a/modules/sigmoidAnalyticsAdapter.js +++ /dev/null @@ -1,292 +0,0 @@ -/* Sigmoid Analytics Adapter for prebid.js v1.1.0-pre -Updated : 2018-03-28 */ -import includes from 'core-js-pure/features/array/includes.js'; -import adapter from '../src/AnalyticsAdapter.js'; -import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const storage = getStorageManager(); - -const utils = require('../src/utils.js'); - -const url = 'https://kinesis.us-east-1.amazonaws.com/'; -const analyticsType = 'endpoint'; - -const auctionInitConst = CONSTANTS.EVENTS.AUCTION_INIT; -const auctionEndConst = CONSTANTS.EVENTS.AUCTION_END; -const bidWonConst = CONSTANTS.EVENTS.BID_WON; -const bidRequestConst = CONSTANTS.EVENTS.BID_REQUESTED; -const bidAdjustmentConst = CONSTANTS.EVENTS.BID_ADJUSTMENT; -const bidResponseConst = CONSTANTS.EVENTS.BID_RESPONSE; - -let initOptions = { publisherIds: [], utmTagData: [], adUnits: [] }; -let bidWon = {options: {}, events: []}; -let eventStack = {options: {}, events: []}; - -let auctionStatus = 'not_started'; - -let localStoragePrefix = 'sigmoid_analytics_'; -let utmTags = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']; -let utmTimeoutKey = 'utm_timeout'; -let utmTimeout = 60 * 60 * 1000; -let sessionTimeout = 60 * 60 * 1000; -let sessionIdStorageKey = 'session_id'; -let sessionTimeoutKey = 'session_timeout'; - -function getParameterByName(param) { - let vars = {}; - window.location.href.replace(location.hash, '').replace( - /[?&]+([^=&]+)=?([^&]*)?/gi, - function(m, key, value) { - vars[key] = value !== undefined ? value : ''; - } - ); - - return vars[param] ? vars[param] : ''; -} - -function buildSessionIdLocalStorageKey() { - return localStoragePrefix.concat(sessionIdStorageKey); -} - -function buildSessionIdTimeoutLocalStorageKey() { - return localStoragePrefix.concat(sessionTimeoutKey); -} - -function updateSessionId() { - if (isSessionIdTimeoutExpired()) { - let newSessionId = utils.generateUUID(); - storage.setDataInLocalStorage(buildSessionIdLocalStorageKey(), newSessionId); - } - initOptions.sessionId = getSessionId(); - updateSessionIdTimeout(); -} - -function updateSessionIdTimeout() { - storage.setDataInLocalStorage(buildSessionIdTimeoutLocalStorageKey(), Date.now()); -} - -function isSessionIdTimeoutExpired() { - let cpmSessionTimestamp = storage.getDataFromLocalStorage(buildSessionIdTimeoutLocalStorageKey()); - return Date.now() - cpmSessionTimestamp > sessionTimeout; -} - -function getSessionId() { - return storage.getDataFromLocalStorage(buildSessionIdLocalStorageKey()) ? storage.getDataFromLocalStorage(buildSessionIdLocalStorageKey()) : ''; -} - -function updateUtmTimeout() { - storage.setDataInLocalStorage(buildUtmLocalStorageTimeoutKey(), Date.now()); -} - -function isUtmTimeoutExpired() { - let utmTimestamp = storage.getDataFromLocalStorage(buildUtmLocalStorageTimeoutKey()); - return (Date.now() - utmTimestamp) > utmTimeout; -} - -function buildUtmLocalStorageTimeoutKey() { - return localStoragePrefix.concat(utmTimeoutKey); -} - -function buildUtmLocalStorageKey(utmMarkKey) { - return localStoragePrefix.concat(utmMarkKey); -} - -function checkOptions() { - if (typeof initOptions.publisherIds === 'undefined') { - return false; - } - - return initOptions.publisherIds.length > 0; -} - -function checkAdUnitConfig() { - if (typeof initOptions.adUnits === 'undefined') { - return false; - } - - return initOptions.adUnits.length > 0; -} - -function buildBidWon(eventType, args) { - bidWon.options = initOptions; - if (checkAdUnitConfig()) { - if (includes(initOptions.adUnits, args.adUnitCode)) { - bidWon.events = [{ args: args, eventType: eventType }]; - } - } else { - bidWon.events = [{ args: args, eventType: eventType }]; - } -} - -function buildEventStack() { - eventStack.options = initOptions; -} - -function filterBidsByAdUnit(bids) { - var filteredBids = []; - bids.forEach(function (bid) { - if (includes(initOptions.adUnits, bid.placementCode)) { - filteredBids.push(bid); - } - }); - return filteredBids; -} - -function isValidEvent(eventType, adUnitCode) { - if (checkAdUnitConfig()) { - let validationEvents = [bidAdjustmentConst, bidResponseConst, bidWonConst]; - if (!includes(initOptions.adUnits, adUnitCode) && includes(validationEvents, eventType)) { - return false; - } - } - return true; -} - -function isValidEventStack() { - if (eventStack.events.length > 0) { - return eventStack.events.some(function(event) { - return bidRequestConst === event.eventType || bidWonConst === event.eventType; - }); - } - return false; -} - -function isValidBidWon() { - return bidWon.events.length > 0; -} - -function flushEventStack() { - eventStack.events = []; -} - -let sigmoidAdapter = Object.assign(adapter({url, analyticsType}), - { - track({eventType, args}) { - if (!checkOptions()) { - return; - } - - let info = Object.assign({}, args); - - if (info && info.ad) { - info.ad = ''; - } - - if (eventType === auctionInitConst) { - auctionStatus = 'started'; - } - - if (eventType === bidWonConst && auctionStatus === 'not_started') { - updateSessionId(); - buildBidWon(eventType, info); - if (isValidBidWon()) { - send(eventType, bidWon, 'bidWon'); - } - return; - } - - if (eventType === auctionEndConst) { - updateSessionId(); - buildEventStack(); - if (isValidEventStack()) { - send(eventType, eventStack, 'eventStack'); - } - auctionStatus = 'not_started'; - } else { - pushEvent(eventType, info); - } - }, - - }); - -sigmoidAdapter.originEnableAnalytics = sigmoidAdapter.enableAnalytics; - -sigmoidAdapter.enableAnalytics = function (config) { - initOptions = config.options; - initOptions.utmTagData = this.buildUtmTagData(); - utils.logInfo('Sigmoid Analytics enabled with config', initOptions); - sigmoidAdapter.originEnableAnalytics(config); -}; - -sigmoidAdapter.buildUtmTagData = function () { - let utmTagData = {}; - let utmTagsDetected = false; - utmTags.forEach(function(utmTagKey) { - let utmTagValue = getParameterByName(utmTagKey); - if (utmTagValue !== '') { - utmTagsDetected = true; - } - utmTagData[utmTagKey] = utmTagValue; - }); - utmTags.forEach(function(utmTagKey) { - if (utmTagsDetected) { - storage.setDataInLocalStorage(buildUtmLocalStorageKey(utmTagKey), utmTagData[utmTagKey]); - updateUtmTimeout(); - } else { - if (!isUtmTimeoutExpired()) { - utmTagData[utmTagKey] = storage.getDataFromLocalStorage(buildUtmLocalStorageKey(utmTagKey)) ? storage.getDataFromLocalStorage(buildUtmLocalStorageKey(utmTagKey)) : ''; - updateUtmTimeout(); - } - } - }); - return utmTagData; -}; - -function send(eventType, data, sendDataType) { - // eslint-disable-next-line no-undef - AWS.config.credentials = new AWS.Credentials({ - accessKeyId: 'accesskey', secretAccessKey: 'secretkey' - }); - - // eslint-disable-next-line no-undef - AWS.config.region = 'us-east-1'; - // eslint-disable-next-line no-undef - AWS.config.credentials.get(function(err) { - // attach event listener - if (err) { - utils.logError(err); - return; - } - // create kinesis service object - // eslint-disable-next-line no-undef - var kinesis = new AWS.Kinesis({ - apiVersion: '2013-12-02' - }); - var dataList = []; - var jsonData = {}; - jsonData['Data'] = JSON.stringify(data) + '\n'; - jsonData['PartitionKey'] = 'partition-' + Math.random().toString(36).substring(7); - dataList.push(jsonData); - kinesis.putRecords({ - Records: dataList, - StreamName: 'sample-stream' - }); - if (sendDataType === 'eventStack') { - flushEventStack(); - } - }); -}; - -function pushEvent(eventType, args) { - if (eventType === bidRequestConst) { - if (checkAdUnitConfig()) { - args.bids = filterBidsByAdUnit(args.bids); - } - if (args.bids.length > 0) { - eventStack.events.push({ eventType: eventType, args: args }); - } - } else { - if (isValidEvent(eventType, args.adUnitCode)) { - eventStack.events.push({ eventType: eventType, args: args }); - } - } -} - -adapterManager.registerAnalyticsAdapter({ - adapter: sigmoidAdapter, - code: 'sigmoid' -}); - -export default sigmoidAdapter; diff --git a/modules/sigmoidAnalyticsAdapter.md b/modules/sigmoidAnalyticsAdapter.md deleted file mode 100644 index 8ff46c7f2be..00000000000 --- a/modules/sigmoidAnalyticsAdapter.md +++ /dev/null @@ -1,23 +0,0 @@ -# Overview -Module Name: Sigmoid Analytics Adapter - -Module Type: Analytics Adapter - -Maintainer: ramees@sigmoidanalytics.com - -# Description - -Analytics adapter for Sigmoid. We are an advanced analytical solutions company. -https://www.sigmoid.com/ - -# Test Parameters - -``` -{ - provider: 'sigmoid', - options : { - publisherIds: ["3gxdf18d32"] - } -} - -``` diff --git a/modules/sirdataRtdProvider.js b/modules/sirdataRtdProvider.js deleted file mode 100644 index 373468b2f14..00000000000 --- a/modules/sirdataRtdProvider.js +++ /dev/null @@ -1,402 +0,0 @@ -/** - * This module adds Sirdata provider to the real time data module - * The {@link module:modules/realTimeData} module is required - * The module will fetch segments (user-centric) and categories (page-centric) from Sirdata server - * The module will automatically handle user's privacy and choice in California (IAB TL CCPA Framework) and in Europe (IAB EU TCF FOR GDPR) - * @module modules/sirdataRtdProvider - * @requires module:modules/realTimeData - */ -import {getGlobal} from '../src/prebidGlobal.js'; -import * as utils from '../src/utils.js'; -import {submodule} from '../src/hook.js'; -import {ajax} from '../src/ajax.js'; -import findIndex from 'core-js-pure/features/array/find-index.js'; -import { getRefererInfo } from '../src/refererDetection.js'; -import { config } from '../src/config.js'; - -/** @type {string} */ -const MODULE_NAME = 'realTimeData'; -const SUBMODULE_NAME = 'SirdataRTDModule'; - -export function getSegmentsAndCategories(reqBidsConfigObj, onDone, moduleConfig, userConsent) { - const adUnits = reqBidsConfigObj.adUnits || getGlobal().adUnits; - moduleConfig.params = moduleConfig.params || {}; - - var tcString = (userConsent && userConsent.gdpr && userConsent.gdpr.consentString ? userConsent.gdpr.consentString : ''); - var gdprApplies = (userConsent && userConsent.gdpr && userConsent.gdpr.gdprApplies ? userConsent.gdpr.gdprApplies : ''); - - moduleConfig.params.partnerId = moduleConfig.params.partnerId ? moduleConfig.params.partnerId : 1; - moduleConfig.params.key = moduleConfig.params.key ? moduleConfig.params.key : 1; - - var sirdataDomain; - var sendWithCredentials; - - if (userConsent.coppa || (userConsent.usp && (userConsent.usp[0] == '1' && (userConsent.usp[1] == 'N' || userConsent.usp[2] == 'Y')))) { - // if children or "Do not Sell" management in California, no segments, page categories only whatever TCF signal - sirdataDomain = 'cookieless-data.com'; - sendWithCredentials = false; - gdprApplies = null; - tcString = ''; - } else if (getGlobal().getConfig('consentManagement.gdpr')) { - // Default endpoint is cookieless if gdpr management is set. Needed because the cookie-based endpoint will fail and return error if user is located in Europe and no consent has been given - sirdataDomain = 'cookieless-data.com'; - sendWithCredentials = false; - } - - // default global endpoint is cookie-based if no rules falls into cookieless or consent has been given or GDPR doesn't apply - if (!sirdataDomain || !gdprApplies || (utils.deepAccess(userConsent, 'gdpr.vendorData.vendor.consents') && userConsent.gdpr.vendorData.vendor.consents[53] && userConsent.gdpr.vendorData.purpose.consents[1] && userConsent.gdpr.vendorData.purpose.consents[4])) { - sirdataDomain = 'sddan.com'; - sendWithCredentials = true; - } - - var actualUrl = moduleConfig.params.actualUrl || getRefererInfo().referer; - - const url = 'https://kvt.' + sirdataDomain + '/api/v1/public/p/' + moduleConfig.params.partnerId + '/d/' + moduleConfig.params.key + '/s?callback=&gdpr=' + gdprApplies + '&gdpr_consent=' + tcString + (actualUrl ? '&url=' + actualUrl : ''); - ajax(url, { - success: function (response, req) { - if (req.status === 200) { - try { - const data = JSON.parse(response); - if (data && data.segments) { - addSegmentData(adUnits, data, moduleConfig, onDone); - } else { - onDone(); - } - } catch (e) { - onDone(); - utils.logError('unable to parse Sirdata data' + e); - } - } else if (req.status === 204) { - onDone(); - } - }, - error: function () { - onDone(); - utils.logError('unable to get Sirdata data'); - } - }, - null, - { - contentType: 'text/plain', - method: 'GET', - withCredentials: sendWithCredentials, - referrerPolicy: 'unsafe-url', - crossOrigin: true - }); -} - -export function setGlobalOrtb2(segments, categories) { - try { - let addOrtb2 = {}; - let testGlobal = getGlobal().getConfig('ortb2') || {}; - if (!utils.deepAccess(testGlobal, 'user.ext.data.sd_rtd') || !utils.deepEqual(testGlobal.user.ext.data.sd_rtd, segments)) { - utils.deepSetValue(addOrtb2, 'user.ext.data.sd_rtd', segments || {}); - } - if (!utils.deepAccess(testGlobal, 'site.ext.data.sd_rtd') || !utils.deepEqual(testGlobal.site.ext.data.sd_rtd, categories)) { - utils.deepSetValue(addOrtb2, 'site.ext.data.sd_rtd', categories || {}); - } - if (!utils.isEmpty(addOrtb2)) { - let ortb2 = {ortb2: utils.mergeDeep({}, testGlobal, addOrtb2)}; - getGlobal().setConfig(ortb2); - } - } catch (e) { - utils.logError(e) - } - - return true; -} - -export function setBidderOrtb2(bidder, segments, categories) { - try { - let addOrtb2 = {}; - let testBidder = utils.deepAccess(config.getBidderConfig(), bidder + '.ortb2') || {}; - if (!utils.deepAccess(testBidder, 'user.ext.data.sd_rtd') || !utils.deepEqual(testBidder.user.ext.data.sd_rtd, segments)) { - utils.deepSetValue(addOrtb2, 'user.ext.data.sd_rtd', segments || {}); - } - if (!utils.deepAccess(testBidder, 'site.ext.data.sd_rtd') || !utils.deepEqual(testBidder.site.ext.data.sd_rtd, categories)) { - utils.deepSetValue(addOrtb2, 'site.ext.data.sd_rtd', categories || {}); - } - if (!utils.isEmpty(addOrtb2)) { - let ortb2 = {ortb2: utils.mergeDeep({}, testBidder, addOrtb2)}; - getGlobal().setBidderConfig({ bidders: [bidder], config: ortb2 }); - } - } catch (e) { - utils.logError(e) - } - - return true; -} - -export function loadCustomFunction (todo, adUnit, list, data, bid) { - try { - if (typeof todo == 'function') { - todo(adUnit, list, data, bid); - } - } catch (e) { utils.logError(e); } - return true; -} - -export function getSegAndCatsArray(data, minScore) { - var sirdataData = {'segments': [], 'categories': []}; - minScore = minScore && typeof minScore == 'number' ? minScore : 30; - try { - if (data && data.contextual_categories) { - for (let catId in data.contextual_categories) { - let value = data.contextual_categories[catId]; - if (value >= minScore && sirdataData.categories.indexOf(catId) === -1) { - sirdataData.categories.push(catId.toString()); - } - } - } - } catch (e) { utils.logError(e); } - try { - if (data && data.segments) { - for (let segId in data.segments) { - sirdataData.segments.push(data.segments[segId].toString()); - } - } - } catch (e) { utils.logError(e); } - return sirdataData; -} - -export function addSegmentData(adUnits, data, moduleConfig, onDone) { - moduleConfig = moduleConfig || {}; - moduleConfig.params = moduleConfig.params || {}; - const globalMinScore = moduleConfig.params.hasOwnProperty('contextualMinRelevancyScore') ? moduleConfig.params.contextualMinRelevancyScore : 30; - var sirdataData = getSegAndCatsArray(data, globalMinScore); - - if (!sirdataData || (sirdataData.segments.length < 1 && sirdataData.categories.length < 1)) { utils.logError('no cats'); onDone(); return adUnits; } - - const sirdataList = sirdataData.segments.concat(sirdataData.categories); - - var curationData = {'segments': [], 'categories': []}; - var curationId = '1'; - const biddersParamsExist = (!!(moduleConfig.params && moduleConfig.params.bidders)); - - // Global ortb2 - if (!biddersParamsExist) { - setGlobalOrtb2(sirdataData.segments, sirdataData.categories); - } - - // Google targeting - if (typeof window.googletag !== 'undefined' && (moduleConfig.params.setGptKeyValues || !moduleConfig.params.hasOwnProperty('setGptKeyValues'))) { - try { - // For curation Google is pid 27449 - curationId = (moduleConfig.params.gptCurationId ? moduleConfig.params.gptCurationId : '27449'); - if (data.shared_taxonomy && data.shared_taxonomy[curationId]) { - curationData = getSegAndCatsArray(data.shared_taxonomy[curationId], globalMinScore); - } - window.googletag.pubads().getSlots().forEach(function(n) { - if (typeof n.setTargeting !== 'undefined') { - n.setTargeting('sd_rtd', sirdataList.concat(curationData.segments).concat(curationData.categories)); - } - }) - } catch (e) { utils.logError(e); } - } - - // Bid targeting level for FPD non-generic biders - var bidderIndex = ''; - var indexFound = false; - - adUnits.forEach(adUnit => { - if (!biddersParamsExist && !utils.deepAccess(adUnit, 'ortb2Imp.ext.data.sd_rtd')) { - utils.deepSetValue(adUnit, 'ortb2Imp.ext.data.sd_rtd', sirdataList); - } - - adUnit.hasOwnProperty('bids') && adUnit.bids.forEach(bid => { - bidderIndex = (moduleConfig.params.hasOwnProperty('bidders') ? findIndex(moduleConfig.params.bidders, function(i) { return i.bidder === bid.bidder; }) : false); - indexFound = (!!(typeof bidderIndex == 'number' && bidderIndex >= 0)); - try { - curationData = {'segments': [], 'categories': []}; - let minScore = (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('contextualMinRelevancyScore') ? moduleConfig.params.bidders[bidderIndex].contextualMinRelevancyScore : globalMinScore) - - if (!biddersParamsExist || (indexFound && (!moduleConfig.params.bidders[bidderIndex].hasOwnProperty('adUnitCodes') || moduleConfig.params.bidders[bidderIndex].adUnitCodes.indexOf(adUnit.code) !== -1))) { - switch (bid.bidder) { - case 'appnexus': - case 'appnexusAst': - case 'brealtime': - case 'emxdigital': - case 'pagescience': - case 'gourmetads': - case 'matomy': - case 'featureforward': - case 'oftmedia': - case 'districtm': - case 'adasta': - case 'beintoo': - case 'gravity': - case 'msq_classic': - case 'msq_max': - case '366_apx': - // For curation Xandr is pid 27446 - curationId = (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('curationId') ? moduleConfig.params.bidders[bidderIndex].curationId : '27446'); - if (data.shared_taxonomy && data.shared_taxonomy[curationId]) { - curationData = getSegAndCatsArray(data.shared_taxonomy[curationId], minScore); - } - if (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('customFunction')) { - loadCustomFunction(moduleConfig.params.bidders[bidderIndex].customFunction, adUnit, sirdataList.concat(curationData.segments).concat(curationData.categories), data, bid); - } else { - utils.deepSetValue(bid, 'params.keywords.sd_rtd', sirdataList.concat(curationData.segments).concat(curationData.categories)); - } - break; - - case 'smartadserver': - case 'smart': - var target = []; - if (bid.hasOwnProperty('params') && bid.params.hasOwnProperty('target')) { - target.push(bid.params.target); - } - // For curation Smart is pid 27440 - curationId = (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('curationId') ? moduleConfig.params.bidders[bidderIndex].curationId : '27440'); - if (data.shared_taxonomy && data.shared_taxonomy[curationId]) { - curationData = getSegAndCatsArray(data.shared_taxonomy[curationId], minScore); - } - if (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('customFunction')) { - loadCustomFunction(moduleConfig.params.bidders[bidderIndex].customFunction, adUnit, sirdataList.concat(curationData.segments).concat(curationData.categories), data, bid); - } else { - sirdataList.concat(curationData.segments).concat(curationData.categories).forEach(function(entry) { - if (target.indexOf('sd_rtd=' + entry) === -1) { - target.push('sd_rtd=' + entry); - } - }); - utils.deepSetValue(bid, 'params.target', target.join(';')); - } - break; - - case 'rubicon': - // For curation Magnite is pid 27518 - curationId = (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('curationId') ? moduleConfig.params.bidders[bidderIndex].curationId : '27452'); - if (data.shared_taxonomy && data.shared_taxonomy[curationId]) { - curationData = getSegAndCatsArray(data.shared_taxonomy[curationId], minScore); - } - if (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('customFunction')) { - loadCustomFunction(moduleConfig.params.bidders[bidderIndex].customFunction, adUnit, sirdataList.concat(curationData.segments).concat(curationData.categories), data, bid); - } else { - setBidderOrtb2(bid.bidder, data.segments.concat(curationData.segments), sirdataList.concat(curationData.segments).concat(curationData.categories)); - } - break; - - case 'ix': - var ixConfig = getGlobal().getConfig('ix.firstPartyData.sd_rtd'); - if (!ixConfig) { - // For curation index is pid 27248 - curationId = (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('curationId') ? moduleConfig.params.bidders[bidderIndex].curationId : '27248'); - if (data.shared_taxonomy && data.shared_taxonomy[curationId]) { - curationData = getSegAndCatsArray(data.shared_taxonomy[curationId], minScore); - } - if (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('customFunction')) { - loadCustomFunction(moduleConfig.params.bidders[bidderIndex].customFunction, adUnit, sirdataList.concat(curationData.segments).concat(curationData.categories), data, bid); - } else { - var cappIxCategories = []; - var ixLength = 0; - var ixLimit = (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('sizeLimit') ? moduleConfig.params.bidders[bidderIndex].sizeLimit : 1000); - // Push ids For publisher use and for curation if exists but limit size because the bidder uses GET parameters - sirdataList.concat(curationData.segments).concat(curationData.categories).forEach(function(entry) { - if (ixLength < ixLimit) { - cappIxCategories.push(entry); - ixLength += entry.toString().length; - } - }); - getGlobal().setConfig({ix: {firstPartyData: {sd_rtd: cappIxCategories}}}); - } - } - break; - - case 'proxistore': - // For curation Proxistore is pid 27484 - curationId = (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('curationId') ? moduleConfig.params.bidders[bidderIndex].curationId : '27484'); - if (data.shared_taxonomy && data.shared_taxonomy[curationId]) { - curationData = getSegAndCatsArray(data.shared_taxonomy[curationId], minScore); - } else { - data.shared_taxonomy[curationId] = {contextual_categories: {}}; - } - if (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('customFunction')) { - loadCustomFunction(moduleConfig.params.bidders[bidderIndex].customFunction, adUnit, sirdataList.concat(curationData.segments).concat(curationData.categories), data, bid); - } else { - utils.deepSetValue(bid, 'ortb2.user.ext.data', {segments: sirdataData.segments.concat(curationData.segments), contextual_categories: {...data.contextual_categories, ...data.shared_taxonomy[curationId].contextual_categories}}); - } - break; - - case 'criteo': - // For curation Smart is pid 27443 - curationId = (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('curationId') ? moduleConfig.params.bidders[bidderIndex].curationId : '27443'); - if (data.shared_taxonomy && data.shared_taxonomy[curationId]) { - curationData = getSegAndCatsArray(data.shared_taxonomy[curationId], minScore); - } - if (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('customFunction')) { - loadCustomFunction(moduleConfig.params.bidders[bidderIndex].customFunction, adUnit, sirdataList.concat(curationData.segments).concat(curationData.categories), data, bid); - } else { - setBidderOrtb2(bid.bidder, sirdataList.concat(curationData.segments).concat(curationData.categories), sirdataList.concat(curationData.segments).concat(curationData.categories)); - } - break; - - case 'triplelift': - // For curation Triplelift is pid 27518 - curationId = (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('curationId') ? moduleConfig.params.bidders[bidderIndex].curationId : '27518'); - if (data.shared_taxonomy && data.shared_taxonomy[curationId]) { - curationData = getSegAndCatsArray(data.shared_taxonomy[curationId], minScore); - } - if (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('customFunction')) { - loadCustomFunction(moduleConfig.params.bidders[bidderIndex].customFunction, adUnit, sirdataList.concat(curationData.segments).concat(curationData.categories), data, bid); - } else { - setBidderOrtb2(bid.bidder, data.segments.concat(curationData.segments), sirdataList.concat(curationData.segments).concat(curationData.categories)); - } - break; - - case 'avct': - case 'avocet': - // For curation Avocet is pid 27522 - curationId = (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('curationId') ? moduleConfig.params.bidders[bidderIndex].curationId : '27522'); - if (data.shared_taxonomy && data.shared_taxonomy[curationId]) { - curationData = getSegAndCatsArray(data.shared_taxonomy[curationId], minScore); - } - if (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('customFunction')) { - loadCustomFunction(moduleConfig.params.bidders[bidderIndex].customFunction, adUnit, sirdataList.concat(curationData.segments).concat(curationData.categories), data, bid); - } else { - setBidderOrtb2(bid.bidder, data.segments.concat(curationData.segments), sirdataList.concat(curationData.segments).concat(curationData.categories)); - } - break; - - case 'smaato': - // For curation Smaato is pid 27520 - curationId = (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('curationId') ? moduleConfig.params.bidders[bidderIndex].curationId : '27520'); - if (data.shared_taxonomy && data.shared_taxonomy[curationId]) { - curationData = getSegAndCatsArray(data.shared_taxonomy[curationId], minScore); - } - if (indexFound && moduleConfig.params.bidders[bidderIndex].hasOwnProperty('customFunction')) { - loadCustomFunction(moduleConfig.params.bidders[bidderIndex].customFunction, adUnit, sirdataList.concat(curationData.segments).concat(curationData.categories), data, bid); - } else { - setBidderOrtb2(bid.bidder, data.segments.concat(curationData.segments), sirdataList.concat(curationData.segments).concat(curationData.categories)); - } - break; - - default: - if (!biddersParamsExist || indexFound) { - if (!utils.deepAccess(bid, 'ortb2.site.ext.data.sd_rtd')) { - utils.deepSetValue(bid, 'ortb2.site.ext.data.sd_rtd', sirdataData.categories); - } - if (!utils.deepAccess(bid, 'ortb2.user.ext.data.sd_rtd')) { - utils.deepSetValue(bid, 'ortb2.user.ext.data.sd_rtd', sirdataData.segments); - } - } - } - } - } catch (e) { utils.logError(e) } - }) - }); - - onDone(); - return adUnits; -} - -export function init(config) { - return true; -} - -export const sirdataSubmodule = { - name: SUBMODULE_NAME, - init: init, - getBidRequestData: getSegmentsAndCategories -}; - -submodule(MODULE_NAME, sirdataSubmodule); diff --git a/modules/sirdataRtdProvider.md b/modules/sirdataRtdProvider.md deleted file mode 100644 index f67e34db43a..00000000000 --- a/modules/sirdataRtdProvider.md +++ /dev/null @@ -1,169 +0,0 @@ -# Sirdata Real-Time Data Submodule - -Module Name: Sirdata Rtd Provider -Module Type: Rtd Provider -Maintainer: bob@sirdata.com - -# Description - -Sirdata provides a disruptive API that allows its partners to leverage its -cutting-edge contextualization technology and its audience segments based on -cookies and consent or without cookies nor consent! - -User-based segments and page-level automatic contextual categories will be -attached to bid request objects sent to different SSPs in order to optimize -targeting. - -Automatic integration with Google Ad Manager and major bidders like Xandr/Appnexus, -Smartadserver, Index Exchange, Proxistore, Magnite/Rubicon or Triplelift ! - -User's country and choice management are included in the module, so it's 100% -compliant with local and regional laws like GDPR and CCPA/CPRA. - -ORTB2 compliant and FPD support for Prebid versions < 4.29 - -Contact bob@sirdata.com for information. - -### Publisher Usage - -Compile the Sirdata RTD module into your Prebid build: - -`gulp build --modules=rtdModule,sirdataRtdProvider` - -Add the Sirdata RTD provider to your Prebid config. - -Segments ids (user-centric) and category ids (page-centric) will be provided -salted and hashed : you can use them with a dedicated and private matching table. -Should you want to allow a SSP or a partner to curate your media and operate -cross-publishers campaigns with our data, please ask Sirdata (bob@sirdata.com) to -open it for you account. - -``` -pbjs.setConfig( - ... - realTimeData: { - auctionDelay: 1000, - dataProviders: [ - { - name: "SirdataRTDModule", - waitForIt: true, - params: { - partnerId: 1, - key: 1, - setGptKeyValues: true, - contextualMinRelevancyScore: 50, //Min score to filter contextual category globally (0-100 scale) - actualUrl: actual_url, //top location url, for contextual categories - bidders: [{ - bidder: 'appnexus', - adUnitCodes: ['adUnit-1','adUnit-2'], - customFunction: overrideAppnexus, - curationId: '111', - },{ - bidder: 'ix', - sizeLimit: 1200 //specific to Index Exchange, - contextualMinRelevancyScore: 50, //Min score to filter contextual category for curation in the bidder (0-100 scale) - }] - } - } - ] - } - ... -} -``` - -### Parameter Descriptions for the Sirdata Configuration Section - -| Name |Type | Description | Notes | -| :------------ | :------------ | :------------ |:------------ | -| name | String | Real time data module name | Mandatory. Always 'SirdataRTDModule' | -| waitForIt | Boolean | Mandatory. Required to ensure that the auction is delayed until prefetch is complete | Optional. Defaults to false but recommended to true | -| params | Object | | Optional | -| params.partnerId | Integer | Partner ID, required to get results and provided by Sirdata. Use 1 for tests and get one running at bob@sirdata.com | Mandatory. Defaults 1. | -| params.key | Integer | Key linked to Partner ID, required to get results and provided by Sirdata. Use 1 for tests and get one running at bob@sirdata.com | Mandatory. Defaults 1. | -| params.setGptKeyValues | Boolean | This parameter Sirdata to set Targeting for GPT/GAM | Optional. Defaults to true. | -| params.contextualMinRelevancyScore | Integer | Min score to keep filter category in the bidders (0-100 scale). Optional. Defaults to 30. | -| params.bidders | Object | Dictionary of bidders you would like to supply Sirdata data for. | Optional. In case no bidder is specified Sirdata will atend to ad data custom and ortb2 to all bidders, adUnits & Globalconfig | - -Bidders can receive common setting : -| Name |Type | Description | Notes | -| :------------ | :------------ | :------------ |:------------ | -| bidder | String | Bidder name | Mandatory if params.bidders are specified | -| adUnitCodes | Array of String | Use if you want to limit data injection to specified adUnits for the bidder | Optional. Default is false and data shared with the bidder isn't filtered | -| customFunction | Function | Use it to override the way data is shared with a bidder | Optional. Default is false | -| curationId | String | Specify the curation ID of the bidder. Provided by Sirdata, request it at bob@sirdata.com | Optional. Default curation ids are specified for main bidders | -| contextualMinRelevancyScore | Integer | Min score to filter contextual categories for curation in the bidder (0-100 scale). Optional. Defaults to 30 or global params.contextualMinRelevancyScore if exits. | -| sizeLimit | Integer | used only for bidder 'ix' to limit the size of the get parameter in Index Exchange ad call | Optional. Default is 1000 | - - -### Overriding data sharing function -As indicated above, it is possible to provide your own bid augmentation -functions. This is useful if you know a bid adapter's API supports segment -fields which aren't specifically being added to request objects in the Prebid -bid adapter. - -Please see the following example, which provides a function to modify bids for -a bid adapter called ix and overrides the appnexus. - -data Object format for usage in this kind of function : -{ - "segments":[111111,222222], - "contextual_categories":{"333333":100}, - "shared_taxonomy":{ - "27446":{ //CurationId - "segments":[444444,555555], - "contextual_categories":{"666666":100} - } - } -} - -``` -function overrideAppnexus (adUnit, segmentsArray, dataObject, bid) { - for (var i = 0; i < segmentsArray.length; i++) { - if (segmentsArray[i]) { - bid.params.user.segments.push(segmentsArray[i]); - } - } -} - -pbjs.setConfig( - ... - realTimeData: { - auctionDelay: 1000, - dataProviders: [ - { - name: "SirdataRTDModule", - waitForIt: true, - params: { - partnerId: 1, - key: 1, - setGptKeyValues: true, - contextualMinRelevancyScore: 50, //Min score to keep contextual category in the bidders (0-100 scale) - actualUrl: actual_url, //top location url, for contextual categories - bidders: [{ - bidder: 'appnexus', - customFunction: overrideAppnexus, - curationId: '111' - },{ - bidder: 'ix', - sizeLimit: 1200, //specific to Index Exchange - customFunction: function(adUnit, segmentsArray, dataObject, bid) { - bid.params.contextual.push(dataObject.contextual_categories); - }, - }] - } - } - ] - } - ... -} -``` - -### Testing - -To view an example of available segments returned by Sirdata's backends: - -`gulp serve --modules=rtdModule,sirdataRtdProvider,appnexusBidAdapter` - -and then point your browser at: - -`http://localhost:9999/integrationExamples/gpt/sirdataRtdProvider_example.html` \ No newline at end of file diff --git a/modules/sizeMappingV2.js b/modules/sizeMappingV2.js deleted file mode 100644 index ffd242e57ac..00000000000 --- a/modules/sizeMappingV2.js +++ /dev/null @@ -1,601 +0,0 @@ -/** - * This module adds support for the new size mapping spec, Advanced Size Mapping. It's documented here. https://github.com/prebid/Prebid.js/issues/4129 - * The implementation is an alternative to global sizeConfig. It introduces 'Ad Unit' & 'Bidder' level sizeConfigs and also supports 'labels' for conditional - * rendering. Read full API documentation on Prebid.org, http://prebid.org/dev-docs/modules/sizeMappingV2.html - */ - -import * as utils from '../src/utils.js'; -import { processNativeAdUnitParams } from '../src/native.js'; -import { adunitCounter } from '../src/adUnits.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import { getHook } from '../src/hook.js'; -import { adUnitSetupChecks } from '../src/prebid.js'; - -// Allows for stubbing of these functions while writing unit tests. -export const internal = { - checkBidderSizeConfigFormat, - getActiveSizeBucket, - getFilteredMediaTypes, - getAdUnitDetail, - getRelevantMediaTypesForBidder, - isLabelActivated -}; - -/* - 'sizeMappingInternalStore' contains information on, whether a particular auction is using size mapping V2 (the new size mapping spec), - and it also contains additional information on each adUnit, such as, mediaTypes, activeViewport, etc. This information is required by - the 'getBids' function. -*/ - -export const sizeMappingInternalStore = createSizeMappingInternalStore(); - -function createSizeMappingInternalStore() { - const sizeMappingInternalStore = {}; - - return { - initializeStore: function (auctionId, isUsingSizeMappingBool) { - sizeMappingInternalStore[auctionId] = { - usingSizeMappingV2: isUsingSizeMappingBool, - adUnits: [] - }; - }, - getAuctionDetail: function (auctionId) { - return sizeMappingInternalStore[auctionId]; - }, - setAuctionDetail: function (auctionId, adUnitDetail) { - sizeMappingInternalStore[auctionId].adUnits.push(adUnitDetail); - } - } -} - -/* - Returns "true" if at least one of the adUnits in the adUnits array is using an Ad Unit and/or Bidder level sizeConfig, - otherwise, returns "false." -*/ -export function isUsingNewSizeMapping(adUnits) { - let isUsingSizeMappingBool = false; - adUnits.forEach(adUnit => { - if (adUnit.mediaTypes) { - // checks for the presence of sizeConfig property at the adUnit.mediaTypes object - Object.keys(adUnit.mediaTypes).forEach(mediaType => { - if (adUnit.mediaTypes[mediaType].sizeConfig) { - if (isUsingSizeMappingBool === false) { - isUsingSizeMappingBool = true; - } - } - }); - - // checks for the presence of sizeConfig property at the adUnit.bids[].bidder object - adUnit.bids && utils.isArray(adUnit.bids) && adUnit.bids.forEach(bidder => { - if (bidder.sizeConfig) { - if (isUsingSizeMappingBool === false) { - isUsingSizeMappingBool = true; - } - } - }); - } - }); - return isUsingSizeMappingBool; -} - -/** - This hooked function executes before the function 'checkAdUnitSetup', that is defined in /src/prebid.js. It's necessary to run this funtion before - because it applies a series of checks in order to determine the correctness of the 'sizeConfig' array, which, the original 'checkAdUnitSetup' function - does not recognize. - @params {Array} adUnits - @returns {Array} validateAdUnits - Unrecognized properties are deleted. -*/ -export function checkAdUnitSetupHook(adUnits) { - const validateSizeConfig = function (mediaType, sizeConfig, adUnitCode) { - let isValid = true; - const associatedProperty = { - banner: 'sizes', - video: 'playerSize', - native: 'active' - } - const propertyName = associatedProperty[mediaType]; - const conditionalLogMessages = { - banner: 'Removing mediaTypes.banner from ad unit.', - video: 'Removing mediaTypes.video.sizeConfig from ad unit.', - native: 'Removing mediaTypes.native.sizeConfig from ad unit.' - } - if (Array.isArray(sizeConfig)) { - sizeConfig.forEach((config, index) => { - const keys = Object.keys(config); - /* - Check #1 (Applies to 'banner', 'video' and 'native' media types.) - Verify that all config objects include 'minViewPort' and 'sizes' property. - If they do not, return 'false'. - */ - if (!(includes(keys, 'minViewPort') && includes(keys, propertyName))) { - utils.logError(`Ad unit ${adUnitCode}: Missing required property 'minViewPort' or 'sizes' from 'mediaTypes.${mediaType}.sizeConfig[${index}]'. ${conditionalLogMessages[mediaType]}`); - isValid = false; - return; - } - /* - Check #2 (Applies to 'banner', 'video' and 'native' media types.) - Verify that 'config.minViewPort' property is in [width, height] format. - If not, return false. - */ - if (!utils.isArrayOfNums(config.minViewPort, 2)) { - utils.logError(`Ad unit ${adUnitCode}: Invalid declaration of 'minViewPort' in 'mediaTypes.${mediaType}.sizeConfig[${index}]'. ${conditionalLogMessages[mediaType]}`); - isValid = false - return; - } - /* - Check #3 (Applies only to 'banner' and 'video' media types.) - Verify that 'config.sizes' (in case of banner) or 'config.playerSize' (in case of video) - property is in [width, height] format. If not, return 'false'. - */ - if (mediaType === 'banner' || mediaType === 'video') { - let showError = false; - if (Array.isArray(config[propertyName])) { - const validatedSizes = adUnitSetupChecks.validateSizes(config[propertyName]); - if (config[propertyName].length > 0 && validatedSizes.length === 0) { - isValid = false; - showError = true; - } - } else { - // Either 'sizes' or 'playerSize' is not declared as an array, which makes it invalid by default. - isValid = false; - showError = true; - } - if (showError) { - utils.logError(`Ad unit ${adUnitCode}: Invalid declaration of '${propertyName}' in 'mediaTypes.${mediaType}.sizeConfig[${index}]'. ${conditionalLogMessages[mediaType]}`); - return; - } - } - /* - Check #4 (Applies only to 'native' media type) - Verify that 'config.active' is a 'boolean'. - If not, return 'false'. - */ - if (mediaType === 'native') { - if (typeof config[propertyName] !== 'boolean') { - utils.logError(`Ad unit ${adUnitCode}: Invalid declaration of 'active' in 'mediaTypes.${mediaType}.sizeConfig[${index}]'. ${conditionalLogMessages[mediaType]}`); - isValid = false; - } - } - }); - } else { - utils.logError(`Ad unit ${adUnitCode}: Invalid declaration of 'sizeConfig' in 'mediaTypes.${mediaType}.sizeConfig'. ${conditionalLogMessages[mediaType]}`); - isValid = false; - return isValid; - } - - // If all checks have passed, isValid should equal 'true' - return isValid; - } - const validatedAdUnits = []; - adUnits.forEach(adUnit => { - const bids = adUnit.bids; - const mediaTypes = adUnit.mediaTypes; - let validatedBanner, validatedVideo, validatedNative; - - if (!bids || !utils.isArray(bids)) { - utils.logError(`Detected adUnit.code '${adUnit.code}' did not have 'adUnit.bids' defined or 'adUnit.bids' is not an array. Removing adUnit from auction.`); - return; - } - - if (!mediaTypes || Object.keys(mediaTypes).length === 0) { - utils.logError(`Detected adUnit.code '${adUnit.code}' did not have a 'mediaTypes' object defined. This is a required field for the auction, so this adUnit has been removed.`); - return; - } - if (mediaTypes.banner) { - if (mediaTypes.banner.sizes) { - // Ad unit is using 'mediaTypes.banner.sizes' instead of the new property 'sizeConfig'. Apply the old checks! - validatedBanner = adUnitSetupChecks.validateBannerMediaType(adUnit); - } else if (mediaTypes.banner.sizeConfig) { - // Ad unit is using the 'sizeConfig' property, 'mediaTypes.banner.sizeConfig'. Apply the new checks! - validatedBanner = utils.deepClone(adUnit); - const isBannerValid = validateSizeConfig('banner', mediaTypes.banner.sizeConfig, adUnit.code); - if (!isBannerValid) { - delete validatedBanner.mediaTypes.banner; - } else { - /* - Make sure 'sizes' field is always an array of arrays. If not, make it so. - For example, [] becomes [[]], and [360, 400] becomes [[360, 400]] - */ - validatedBanner.mediaTypes.banner.sizeConfig.forEach(config => { - if (!Array.isArray(config.sizes[0])) { - config.sizes = [config.sizes]; - } - }); - } - } else { - // Ad unit is invalid since it's mediaType property does not have either 'sizes' or 'sizeConfig' declared. - utils.logError(`Ad unit ${adUnit.code}: 'mediaTypes.banner' does not contain either 'sizes' or 'sizeConfig' property. Removing 'mediaTypes.banner' from ad unit.`); - validatedBanner = utils.deepClone(adUnit); - delete validatedBanner.mediaTypes.banner; - } - } - - if (mediaTypes.video) { - if (mediaTypes.video.playerSize) { - // Ad unit is using 'mediaTypes.video.playerSize' instead of the new property 'sizeConfig'. Apply the old checks! - validatedVideo = validatedBanner ? adUnitSetupChecks.validateVideoMediaType(validatedBanner) : adUnitSetupChecks.validateVideoMediaType(adUnit); - } else if (mediaTypes.video.sizeConfig) { - // Ad unit is using the 'sizeConfig' property, 'mediaTypes.video.sizeConfig'. Apply the new checks! - validatedVideo = validatedBanner || utils.deepClone(adUnit); - const isVideoValid = validateSizeConfig('video', mediaTypes.video.sizeConfig, adUnit.code); - if (!isVideoValid) { - delete validatedVideo.mediaTypes.video.sizeConfig; - } else { - /* - Make sure 'playerSize' field is always an array of arrays. If not, make it so. - For example, [] becomes [[]], and [640, 400] becomes [[640, 400]] - */ - validatedVideo.mediaTypes.video.sizeConfig.forEach(config => { - if (!Array.isArray(config.playerSize[0])) { - config.playerSize = [config.playerSize]; - } - }); - } - } - } - - if (mediaTypes.native) { - // Apply the old native checks - validatedNative = validatedVideo ? adUnitSetupChecks.validateNativeMediaType(validatedVideo) : validatedBanner ? adUnitSetupChecks.validateNativeMediaType(validatedBanner) : adUnitSetupChecks.validateNativeMediaType(adUnit); - - // Apply the new checks if 'mediaTypes.native.sizeConfig' detected - if (mediaTypes.native.sizeConfig) { - const isNativeValid = validateSizeConfig('native', mediaTypes.native.sizeConfig, adUnit.code); - if (!isNativeValid) { - delete validatedNative.mediaTypes.native.sizeConfig; - } - } - } - - const validatedAdUnit = Object.assign({}, validatedBanner, validatedVideo, validatedNative); - validatedAdUnits.push(validatedAdUnit); - }); - return validatedAdUnits; -} - -getHook('checkAdUnitSetup').before(function (fn, adUnits) { - const usingNewSizeMapping = isUsingNewSizeMapping(adUnits); - if (usingNewSizeMapping) { - // if adUnits are found using the sizeMappingV2 spec, we run additional checks on them for checking the validity of sizeConfig object - // in addition to running the base checks on the mediaType object and return the adUnit without calling the base function. - adUnits = checkAdUnitSetupHook(adUnits); - return fn.bail(adUnits); - } else { - // if presence of sizeMappingV2 spec is not detected on adUnits, we default back to the original checks defined in the base function. - return fn.call(this, adUnits); - } -}); - -// checks if the sizeConfig object declared at the Bidder level is in the right format or not. -export function checkBidderSizeConfigFormat(sizeConfig) { - let didCheckPass = true; - if (Array.isArray(sizeConfig) && sizeConfig.length > 0) { - sizeConfig.forEach(config => { - const keys = Object.keys(config); - if ((includes(keys, 'minViewPort') && - includes(keys, 'relevantMediaTypes')) && - utils.isArrayOfNums(config.minViewPort, 2) && - Array.isArray(config.relevantMediaTypes) && - config.relevantMediaTypes.length > 0 && - (config.relevantMediaTypes.length > 1 ? (config.relevantMediaTypes.every(mt => (includes(['banner', 'video', 'native'], mt)))) - : (['none', 'banner', 'video', 'native'].indexOf(config.relevantMediaTypes[0]) > -1))) { - didCheckPass = didCheckPass && true; - } else { - didCheckPass = false; - } - }); - } else { - didCheckPass = false; - } - return didCheckPass; -} - -getHook('getBids').before(function (fn, bidderInfo) { - // check if the adUnit is using sizeMappingV2 specs and store the result in _sizeMappingUsageMap. - if (typeof sizeMappingInternalStore.getAuctionDetail(bidderInfo.auctionId) === 'undefined') { - const isUsingSizeMappingBool = isUsingNewSizeMapping(bidderInfo.adUnits); - - // initialize sizeMappingInternalStore for the first time for a particular auction - sizeMappingInternalStore.initializeStore(bidderInfo.auctionId, isUsingSizeMappingBool); - } - if (sizeMappingInternalStore.getAuctionDetail(bidderInfo.auctionId).usingSizeMappingV2) { - // if adUnit is found using sizeMappingV2 specs, run the getBids function which processes the sizeConfig object - // and returns the bids array for a particular bidder. - - const bids = getBids(bidderInfo); - return fn.bail(bids); - } else { - // if not using sizeMappingV2, default back to the getBids function defined in adapterManager. - return fn.call(this, bidderInfo); - } -}); - -/** - * Given an Ad Unit or a Bid as an input, returns a boolean telling if the Ad Unit/ Bid is active based on label checks - * @param {Object} bidOrAdUnit - Either the Ad Unit object or the Bid object - * @param {Array} activeLabels - List of active labels passed as an argument to pbjs.requestBids function - * @param {string} adUnitCode - Unique string identifier for an Ad Unit. - * @param {number} adUnitInstance - Instance count of an 'Identical' ad unit. - * @returns {boolean} Represents if the Ad Unit or the Bid is active or not - */ -export function isLabelActivated(bidOrAdUnit, activeLabels, adUnitCode, adUnitInstance) { - let labelOperator; - const labelsFound = Object.keys(bidOrAdUnit).filter(prop => prop === 'labelAny' || prop === 'labelAll'); - if (labelsFound && labelsFound.length > 1) { - utils.logWarn(`Size Mapping V2:: ${(bidOrAdUnit.code) - ? (`Ad Unit: ${bidOrAdUnit.code}(${adUnitInstance}) => Ad unit has multiple label operators. Using the first declared operator: ${labelsFound[0]}`) - : (`Ad Unit: ${adUnitCode}(${adUnitInstance}), Bidder: ${bidOrAdUnit.bidder} => Bidder has multiple label operators. Using the first declared operator: ${labelsFound[0]}`)}`); - } - labelOperator = labelsFound[0]; - - if (labelOperator && !activeLabels) { - utils.logWarn(`Size Mapping V2:: ${(bidOrAdUnit.code) - ? (`Ad Unit: ${bidOrAdUnit.code}(${adUnitInstance}) => Found '${labelOperator}' on ad unit, but 'labels' is not set. Did you pass 'labels' to pbjs.requestBids() ?`) - : (`Ad Unit: ${adUnitCode}(${adUnitInstance}), Bidder: ${bidOrAdUnit.bidder} => Found '${labelOperator}' on bidder, but 'labels' is not set. Did you pass 'labels' to pbjs.requestBids() ?`)}`); - return true; - } - - if (labelOperator === 'labelAll' && Array.isArray(bidOrAdUnit[labelOperator])) { - if (bidOrAdUnit.labelAll.length === 0) { - utils.logWarn(`Size Mapping V2:: Ad Unit: ${bidOrAdUnit.code}(${adUnitInstance}) => Ad unit has declared property 'labelAll' with an empty array.`); - return true; - } - return bidOrAdUnit.labelAll.every(label => includes(activeLabels, label)); - } else if (labelOperator === 'labelAny' && Array.isArray(bidOrAdUnit[labelOperator])) { - if (bidOrAdUnit.labelAny.length === 0) { - utils.logWarn(`Size Mapping V2:: Ad Unit: ${bidOrAdUnit.code}(${adUnitInstance}) => Ad unit has declared property 'labelAny' with an empty array.`); - return true; - } - return bidOrAdUnit.labelAny.some(label => includes(activeLabels, label)); - } - return true; -} - -/** - * Processes the MediaTypes object and calculates the active size buckets for each Media Type. Uses `window.innerWidth` and `window.innerHeight` - * to calculate the width and height of the active Viewport. - * @param {MediaTypes} mediaTypes Contains information about supported media types for an Ad Unit and size information for each of those types - * @returns {FilteredMediaTypes} Filtered mediaTypes object with relevant media types filtered by size buckets based on activeViewPort size - */ -export function getFilteredMediaTypes(mediaTypes) { - let - activeViewportWidth, - activeViewportHeight, - transformedMediaTypes; - - transformedMediaTypes = utils.deepClone(mediaTypes); - - let activeSizeBucket = { - banner: undefined, - video: undefined, - native: undefined - } - - try { - activeViewportWidth = utils.getWindowTop().innerWidth; - activeViewportHeight = utils.getWindowTop().innerHeight; - } catch (e) { - utils.logWarn(`SizeMappingv2:: Unfriendly iframe blocks viewport size to be evaluated correctly`); - activeViewportWidth = window.innerWidth; - activeViewportHeight = window.innerHeight; - } - const activeViewport = [activeViewportWidth, activeViewportHeight]; - Object.keys(mediaTypes).map(mediaType => { - const sizeConfig = mediaTypes[mediaType].sizeConfig; - if (sizeConfig) { - activeSizeBucket[mediaType] = getActiveSizeBucket(sizeConfig, activeViewport); - const filteredSizeConfig = sizeConfig.filter(config => config.minViewPort === activeSizeBucket[mediaType] && isSizeConfigActivated(mediaType, config)); - transformedMediaTypes[mediaType] = Object.assign({ filteredSizeConfig }, mediaTypes[mediaType]); - - // transform mediaTypes object - const config = { - banner: 'sizes', - video: 'playerSize' - }; - - if (transformedMediaTypes[mediaType].filteredSizeConfig.length > 0) { - // map sizes or playerSize property in filteredSizeConfig object to transformedMediaTypes.banner.sizes if mediaType is banner - // or transformedMediaTypes.video.playerSize if the mediaType in video. - // doesn't apply to native mediaType since native doesn't have any property defining 'sizes' or 'playerSize'. - if (mediaType !== 'native') { - transformedMediaTypes[mediaType][config[mediaType]] = transformedMediaTypes[mediaType].filteredSizeConfig[0][config[mediaType]]; - } - } else { - delete transformedMediaTypes[mediaType]; - } - } - }) - - // filter out 'undefined' values from activeSizeBucket object and attach sizes/playerSize information against the active size bucket. - const sizeBucketToSizeMap = Object - .keys(activeSizeBucket) - .filter(mediaType => activeSizeBucket[mediaType] !== undefined) - .reduce((sizeBucketToSizeMap, mediaType) => { - sizeBucketToSizeMap[mediaType] = { - activeSizeBucket: activeSizeBucket[mediaType], - activeSizeDimensions: (mediaType === 'banner') ? ( - // banner mediaType gets deleted incase no sizes are specified for a given size bucket, that's why this check is necessary - (transformedMediaTypes.banner) ? (transformedMediaTypes.banner.sizes) : ([]) - ) : ((mediaType === 'video') ? ( - // video mediaType gets deleted incase no playerSize is specified for a given size bucket, that's why this check is necessary - (transformedMediaTypes.video) ? (transformedMediaTypes.video.playerSize) : ([]) - ) : ('NA')) - }; - return sizeBucketToSizeMap; - }, {}); - - return { mediaTypes, sizeBucketToSizeMap, activeViewport, transformedMediaTypes }; -}; - -/** - * Evaluates the given sizeConfig object and checks for various properties to determine if the sizeConfig is active or not. For example, - * let's suppose the sizeConfig is for a Banner media type. Then, if the sizes property is found empty, it returns false, else returns true. - * In case of a Video media type, it checks the playerSize property. If found empty, returns false, else returns true. - * In case of a Native media type, it checks the active property. If found false, returns false, if found true, returns true. - * @param {string} mediaType It can be 'banner', 'native' or 'video' - * @param {Object} sizeConfig Represents the sizeConfig object which is active based on the current viewport size - * @returns {boolean} Represents if the size config is active or not - */ -export function isSizeConfigActivated(mediaType, sizeConfig) { - switch (mediaType) { - case 'banner': - // we need this check, sizeConfig.sizes[0].length > 0, in place because a sizeBucket can have sizes: [], - // gets converted to sizes: [[]] in the checkAdUnitSetupHook function - return sizeConfig.sizes && sizeConfig.sizes.length > 0 && sizeConfig.sizes[0].length > 0; - case 'video': - // for why we need the last check, read the above comment - return sizeConfig.playerSize && sizeConfig.playerSize.length > 0 && sizeConfig.playerSize[0].length > 0; - case 'native': - return sizeConfig.active; - default: - return false; - } -} - -/** - * Returns the active size bucket for a given media type - * @param {Array} sizeConfig SizeConfig defines the characteristics of an Ad Unit categorised into multiple size buckets per media type - * @param {Array} activeViewport Viewport size of the browser in the form [w, h] (w -> width, h -> height) - * Calculated at the time of making call to pbjs.requestBids function - * @returns {Array} The active size bucket matching the activeViewPort, for example: [750, 0] - */ -export function getActiveSizeBucket(sizeConfig, activeViewport) { - let activeSizeBucket = []; - sizeConfig - .sort((a, b) => a.minViewPort[0] - b.minViewPort[0]) - .forEach(config => { - if (activeViewport[0] >= config.minViewPort[0]) { - if (activeViewport[1] >= config.minViewPort[1]) { - activeSizeBucket = config.minViewPort; - } else { - activeSizeBucket = []; - } - } - }) - return activeSizeBucket; -} - -export function getRelevantMediaTypesForBidder(sizeConfig, activeViewport) { - if (internal.checkBidderSizeConfigFormat(sizeConfig)) { - const activeSizeBucket = internal.getActiveSizeBucket(sizeConfig, activeViewport); - return sizeConfig.filter(config => config.minViewPort === activeSizeBucket)[0]['relevantMediaTypes']; - } - return []; -} - -// sets sizeMappingInternalStore for a given auctionId with relevant adUnit information returned from the call to 'getFilteredMediaTypes' function -// returns adUnit details object. -export function getAdUnitDetail(auctionId, adUnit, labels) { - // fetch all adUnits for an auction from the sizeMappingInternalStore - const adUnitsForAuction = sizeMappingInternalStore.getAuctionDetail(auctionId).adUnits; - - // check if the adUnit exists already in the sizeMappingInterStore (check for equivalence of 'code' && 'mediaTypes' properties) - const adUnitDetail = adUnitsForAuction.filter(adUnitDetail => adUnitDetail.adUnitCode === adUnit.code && utils.deepEqual(adUnitDetail.mediaTypes, adUnit.mediaTypes)); - - if (adUnitDetail.length > 0) { - adUnitDetail[0].cacheHits++; - return adUnitDetail[0]; - } else { - const identicalAdUnit = adUnitsForAuction.filter(adUnitDetail => adUnitDetail.adUnitCode === adUnit.code); - const adUnitInstance = identicalAdUnit.length > 0 && typeof identicalAdUnit[0].instance === 'number' ? identicalAdUnit[identicalAdUnit.length - 1].instance + 1 : 1; - const isLabelActivated = internal.isLabelActivated(adUnit, labels, adUnit.code, adUnitInstance); - const { mediaTypes = adUnit.mediaTypes, sizeBucketToSizeMap, activeViewport, transformedMediaTypes } = isLabelActivated && internal.getFilteredMediaTypes(adUnit.mediaTypes); - - const adUnitDetail = { - adUnitCode: adUnit.code, - mediaTypes, - sizeBucketToSizeMap, - activeViewport, - transformedMediaTypes, - instance: adUnitInstance, - isLabelActivated, - cacheHits: 0 - }; - - // set adUnitDetail in sizeMappingInternalStore against the correct 'auctionId'. - sizeMappingInternalStore.setAuctionDetail(auctionId, adUnitDetail); - isLabelActivated && utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${adUnitInstance}) => Active size buckets after filtration: `, sizeBucketToSizeMap); - - return adUnitDetail; - } -} - -export function getBids({ bidderCode, auctionId, bidderRequestId, adUnits, labels, src }) { - return adUnits.reduce((result, adUnit) => { - if (adUnit.mediaTypes && utils.isValidMediaTypes(adUnit.mediaTypes)) { - const { activeViewport, transformedMediaTypes, instance: adUnitInstance, isLabelActivated, cacheHits } = internal.getAdUnitDetail(auctionId, adUnit, labels); - if (isLabelActivated) { - // check if adUnit has any active media types remaining, if not drop the adUnit from auction, - // else proceed to evaluate the bids object. - if (Object.keys(transformedMediaTypes).length === 0) { - cacheHits === 0 && utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${adUnitInstance}) => Ad unit disabled since there are no active media types after sizeConfig filtration.`); - return result; - } - result - .push(adUnit.bids.filter(bid => bid.bidder === bidderCode) - .reduce((bids, bid) => { - if (internal.isLabelActivated(bid, labels, adUnit.code, adUnitInstance)) { - // handle native params - const nativeParams = adUnit.nativeParams || utils.deepAccess(adUnit, 'mediaTypes.native'); - if (nativeParams) { - bid = Object.assign({}, bid, { - nativeParams: processNativeAdUnitParams(nativeParams) - }); - } - - bid = Object.assign({}, bid, utils.getDefinedParams(adUnit, ['mediaType', 'renderer'])); - - if (bid.sizeConfig) { - const relevantMediaTypes = internal.getRelevantMediaTypesForBidder(bid.sizeConfig, activeViewport); - if (relevantMediaTypes.length === 0) { - utils.logError(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${adUnitInstance}), Bidder: ${bidderCode} => 'sizeConfig' is not configured properly. This bidder won't be eligible for sizeConfig checks and will remail active.`); - bid = Object.assign({}, bid); - } else if (relevantMediaTypes[0] !== 'none') { - const bidderMediaTypes = Object - .keys(transformedMediaTypes) - .filter(mt => relevantMediaTypes.indexOf(mt) > -1) - .reduce((mediaTypes, mediaType) => { - mediaTypes[mediaType] = transformedMediaTypes[mediaType]; - return mediaTypes; - }, {}); - - if (Object.keys(bidderMediaTypes).length > 0) { - bid = Object.assign({}, bid, { mediaTypes: bidderMediaTypes }); - } else { - utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${adUnitInstance}), Bidder: ${bid.bidder} => 'relevantMediaTypes' does not match with any of the active mediaTypes at the Ad Unit level. This bidder is disabled.`); - return bids; - } - } else { - utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${adUnitInstance}), Bidder: ${bid.bidder} => 'relevantMediaTypes' is set to 'none' in sizeConfig for current viewport size. This bidder is disabled.`); - return bids; - } - } - bids.push(Object.assign({}, bid, { - adUnitCode: adUnit.code, - transactionId: adUnit.transactionId, - sizes: utils.deepAccess(transformedMediaTypes, 'banner.sizes') || utils.deepAccess(transformedMediaTypes, 'video.playerSize') || [], - mediaTypes: bid.mediaTypes || transformedMediaTypes, - bidId: bid.bid_id || utils.getUniqueIdentifierStr(), - bidderRequestId, - auctionId, - src, - bidRequestsCount: adunitCounter.getRequestsCounter(adUnit.code), - bidderRequestsCount: adunitCounter.getBidderRequestsCounter(adUnit.code, bid.bidder), - bidderWinsCount: adunitCounter.getBidderWinsCounter(adUnit.code, bid.bidder) - })); - return bids; - } else { - utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${adUnitInstance}), Bidder: ${bid.bidder} => Label check for this bidder has failed. This bidder is disabled.`); - return bids; - } - }, [])); - } else { - cacheHits === 0 && utils.logInfo(`Size Mapping V2:: Ad Unit: ${adUnit.code}(${adUnitInstance}) => Ad unit is disabled due to failing label check.`); - } - } else { - utils.logWarn(`Size Mapping V2:: Ad Unit: ${adUnit.code} => Ad unit has declared invalid 'mediaTypes' or has not declared a 'mediaTypes' property`); - return result; - } - return result; - }, []).reduce(utils.flatten, []).filter(val => val !== ''); -} diff --git a/modules/slimcutBidAdapter.js b/modules/slimcutBidAdapter.js deleted file mode 100644 index d717f3a88bd..00000000000 --- a/modules/slimcutBidAdapter.js +++ /dev/null @@ -1,128 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { ajax } from '../src/ajax.js'; - -const BIDDER_CODE = 'slimcut'; -const ENDPOINT_URL = 'https://sb.freeskreen.com/pbr'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['scm'], - supportedMediaTypes: ['video', 'banner'], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - let isValid = false; - if (typeof bid.params !== 'undefined' && !isNaN(parseInt(utils.getValue(bid.params, 'placementId'))) && parseInt(utils.getValue(bid.params, 'placementId')) > 0) { - isValid = true; - } - return isValid; - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests, bidderRequest) { - const bids = validBidRequests.map(buildRequestObject); - const payload = { - referrer: getReferrerInfo(bidderRequest), - data: bids, - deviceWidth: screen.width - }; - - let gdpr = bidderRequest.gdprConsent; - if (bidderRequest && gdpr) { - let isCmp = (typeof gdpr.gdprApplies === 'boolean') - let isConsentString = (typeof gdpr.consentString === 'string') - payload.gdpr_iab = { - consent: isConsentString ? gdpr.consentString : '', - status: isCmp ? gdpr.gdprApplies : -1 - }; - } - - const payloadString = JSON.stringify(payload); - return { - method: 'POST', - url: ENDPOINT_URL, - data: payloadString, - }; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse, request) { - const bidResponses = []; - serverResponse = serverResponse.body; - - if (serverResponse.responses) { - serverResponse.responses.forEach(function (bid) { - const bidResponse = { - cpm: bid.cpm, - width: bid.width, - height: bid.height, - currency: bid.currency, - netRevenue: bid.netRevenue, - ttl: bid.ttl, - ad: bid.ad, - requestId: bid.requestId, - creativeId: bid.creativeId, - transactionId: bid.tranactionId, - winUrl: bid.winUrl - }; - bidResponses.push(bidResponse); - }); - } - return bidResponses; - }, - - getUserSyncs: function(syncOptions, serverResponses) { - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: 'https://sb.freeskreen.com/async_usersync.html' - }]; - } - return []; - }, - - onBidWon: function(bid) { - ajax(bid.winUrl + bid.cpm, null); - } -} - -function buildRequestObject(bid) { - const reqObj = {}; - let placementId = utils.getValue(bid.params, 'placementId'); - - reqObj.sizes = utils.parseSizesInput(bid.sizes); - reqObj.bidId = utils.getBidIdParameter('bidId', bid); - reqObj.bidderRequestId = utils.getBidIdParameter('bidderRequestId', bid); - reqObj.placementId = parseInt(placementId); - reqObj.adUnitCode = utils.getBidIdParameter('adUnitCode', bid); - reqObj.auctionId = utils.getBidIdParameter('auctionId', bid); - reqObj.transactionId = utils.getBidIdParameter('transactionId', bid); - - return reqObj; -} - -function getReferrerInfo(bidderRequest) { - let ref = window.location.href; - if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { - ref = bidderRequest.refererInfo.referer; - } - return ref; -} - -registerBidder(spec); diff --git a/modules/slimcutBidAdapter.md b/modules/slimcutBidAdapter.md deleted file mode 100644 index 1d83c8cae6f..00000000000 --- a/modules/slimcutBidAdapter.md +++ /dev/null @@ -1,45 +0,0 @@ -# Overview - -**Module Name**: Slimcut Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: support@slimcut.com - -# Description - -Use `slimcut` as bidder. - -`placementId` is required and must be integer. - -The Slimcut adapter requires setup and approval from the Slimcut team. -Please reach out to your account manager for more information. - -# Test Parameters - -``` - var adUnits = [ - { - code: 'test-div', - sizes: [[640, 480]], - bids: [ - { - bidder: "slimcut", - params: { - placementId: 1234 - } - } - ] - } - ]; -``` - -## UserSync example - -``` -pbjs.setConfig({ - userSync: { - iframeEnabled: true, - syncEnabled: true, - syncDelay: 1 - } -}); -``` diff --git a/modules/smaatoBidAdapter.js b/modules/smaatoBidAdapter.js deleted file mode 100644 index fbb4c14e5f8..00000000000 --- a/modules/smaatoBidAdapter.js +++ /dev/null @@ -1,282 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { config } from '../src/config.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'smaato'; -const SMAATO_ENDPOINT = 'https://prebid.ad.smaato.net/oapi/prebid'; -const CLIENT = 'prebid_js_$prebid.version$_1.1' - -/** -* Transform BidRequest to OpenRTB-formatted BidRequest Object -* @param {Array} validBidRequests -* @param {any} bidderRequest -* @returns {string} -*/ -const buildOpenRtbBidRequestPayload = (validBidRequests, bidderRequest) => { - /** - * Turn incoming prebid sizes into openRtb format mapping. - * @param {*} sizes in format [[10, 10], [20, 20]] - * @returns array of openRtb format mappings [{w: 10, h: 10}, {w: 20, h: 20}] - */ - const parseSizes = (sizes) => { - return sizes.map((size) => { - return {w: size[0], h: size[1]}; - }) - } - - const imp = validBidRequests.map(br => { - const bannerMediaType = utils.deepAccess(br, 'mediaTypes.banner'); - const videoMediaType = utils.deepAccess(br, 'mediaTypes.video'); - let result = { - id: br.bidId, - tagid: utils.deepAccess(br, 'params.adspaceId') - } - - if (bannerMediaType) { - const sizes = parseSizes(utils.getAdUnitSizes(br)); - result.banner = { - w: sizes[0].w, - h: sizes[0].h, - format: sizes - } - } - - if (videoMediaType) { - result.video = { - mimes: videoMediaType.mimes, - minduration: videoMediaType.minduration, - startdelay: videoMediaType.startdelay, - linearity: videoMediaType.linearity, - w: videoMediaType.playerSize[0][0], - h: videoMediaType.playerSize[0][1], - maxduration: videoMediaType.maxduration, - skip: videoMediaType.skip, - protocols: videoMediaType.protocols, - ext: { - rewarded: videoMediaType.ext && videoMediaType.ext.rewarded ? videoMediaType.ext.rewarded : 0 - }, - skipmin: videoMediaType.skipmin, - api: videoMediaType.api - } - } - - return result; - }); - - const request = { - id: bidderRequest.auctionId, - at: 1, - imp, - cur: ['USD'], - tmax: bidderRequest.timeout, - site: { - id: window.location.hostname, - publisher: { - id: utils.deepAccess(validBidRequests[0], 'params.publisherId') - }, - domain: window.location.hostname, - page: window.location.href, - ref: bidderRequest.refererInfo.referer - }, - device: { - language: (navigator && navigator.language) ? navigator.language.split('-')[0] : '', - ua: navigator.userAgent, - dnt: utils.getDNT() ? 1 : 0, - h: screen.height, - w: screen.width - }, - regs: { - coppa: config.getConfig('coppa') === true ? 1 : 0, - ext: {} - }, - user: { - ext: {} - }, - ext: { - client: CLIENT - } - }; - - let ortb2 = config.getConfig('ortb2') || {}; - - Object.assign(request.user, ortb2.user); - Object.assign(request.site, ortb2.site); - - if (bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies === true) { - utils.deepSetValue(request, 'regs.ext.gdpr', bidderRequest.gdprConsent.gdprApplies ? 1 : 0); - utils.deepSetValue(request, 'user.ext.consent', bidderRequest.gdprConsent.consentString); - } - - if (bidderRequest.uspConsent !== undefined) { - utils.deepSetValue(request, 'regs.ext.us_privacy', bidderRequest.uspConsent); - } - - if (utils.deepAccess(validBidRequests[0], 'params.app')) { - const geo = utils.deepAccess(validBidRequests[0], 'params.app.geo'); - utils.deepSetValue(request, 'device.geo', geo); - const ifa = utils.deepAccess(validBidRequests[0], 'params.app.ifa') - utils.deepSetValue(request, 'device.ifa', ifa); - } - - const eids = utils.deepAccess(validBidRequests[0], 'userIdAsEids'); - if (eids && eids.length) { - utils.deepSetValue(request, 'user.ext.eids', eids); - } - - utils.logInfo('[SMAATO] OpenRTB Request:', request); - return JSON.stringify(request); -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: (bid) => { - return typeof bid.params === 'object' && - typeof bid.params.publisherId === 'string' && - typeof bid.params.adspaceId === 'string'; - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: (validBidRequests, bidderRequest) => { - utils.logInfo('[SMAATO] Client version:', CLIENT); - return { - method: 'POST', - url: validBidRequests[0].params.endpoint || SMAATO_ENDPOINT, - data: buildOpenRtbBidRequestPayload(validBidRequests, bidderRequest), - options: { - withCredentials: true, - crossOrigin: true, - } - }; - }, - /** - * Unpack the 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. - */ - interpretResponse: (serverResponse, bidRequest) => { - // response is empty (HTTP 204) - if (utils.isEmpty(serverResponse.body)) { - utils.logInfo('[SMAATO] Empty response body HTTP 204, no bids'); - return []; // no bids - } - - let serverResponseHeaders = serverResponse.headers; - const smtAdType = serverResponseHeaders.get('X-SMT-ADTYPE'); - - const smtExpires = serverResponseHeaders.get('X-SMT-Expires'); - let ttlSec = 300; - utils.logInfo('[SMAATO] Expires:', smtExpires); - if (smtExpires) { - ttlSec = Math.floor((smtExpires - Date.now()) / 1000); - } - - const res = serverResponse.body; - utils.logInfo('[SMAATO] OpenRTB Response:', res); - - var bids = []; - res.seatbid.forEach(sb => { - sb.bid.forEach(b => { - let resultingBid = { - requestId: b.impid, - cpm: b.price || 0, - width: b.w, - height: b.h, - ttl: ttlSec, - creativeId: b.crid, - dealId: b.dealid || null, - netRevenue: utils.deepAccess(b, 'ext.net', true), - currency: res.cur, - meta: { - advertiserDomains: b.adomain, - networkName: b.bidderName, - agencyId: sb.seat - } - }; - - switch (smtAdType) { - case 'Img': - resultingBid.ad = createImgAd(b.adm); - resultingBid.meta.mediaType = BANNER; - bids.push(resultingBid); - break; - case 'Richmedia': - resultingBid.ad = createRichmediaAd(b.adm); - resultingBid.meta.mediaType = BANNER; - bids.push(resultingBid); - break; - case 'Video': - resultingBid.vastXml = b.adm; - resultingBid.meta.mediaType = VIDEO; - bids.push(resultingBid); - break; - default: - utils.logInfo('[SMAATO] Invalid ad type:', smtAdType); - } - }); - }); - - utils.logInfo('[SMAATO] Prebid bids:', bids); - return bids; - }, - - /** - * Register the user sync pixels which should be dropped after the auction. - * - * @param {SyncOptions} syncOptions Which user syncs are allowed? - * @param {ServerResponse[]} serverResponses List of server's responses. - * @return {UserSync[]} The user syncs which should be dropped. - */ - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - const syncs = [] - return syncs; - } -} -registerBidder(spec); - -const createImgAd = (adm) => { - const image = JSON.parse(adm).image; - - let clickEvent = ''; - image.clicktrackers.forEach(src => { - clickEvent += `fetch(decodeURIComponent('${encodeURIComponent(src)}'), {cache: 'no-cache'});`; - }) - - let markup = `
`; - - image.impressiontrackers.forEach(src => { - markup += ``; - }); - - return markup + '
'; -}; - -const createRichmediaAd = (adm) => { - const rich = JSON.parse(adm).richmedia; - let clickEvent = ''; - rich.clicktrackers.forEach(src => { - clickEvent += `fetch(decodeURIComponent('${encodeURIComponent(src)}'), {cache: 'no-cache'});`; - }) - - let markup = `
${rich.mediadata.content}`; - - rich.impressiontrackers.forEach(src => { - markup += ``; - }); - - return markup + '
'; -}; diff --git a/modules/smaatoBidAdapter.md b/modules/smaatoBidAdapter.md deleted file mode 100644 index d26d7ecf64e..00000000000 --- a/modules/smaatoBidAdapter.md +++ /dev/null @@ -1,64 +0,0 @@ -# Overview - -``` -Module Name: Smaato Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid@smaato.com -``` - -# Description - -The Smaato adapter requires setup and approval from the Smaato team, even for existing Smaato publishers. Please reach out to your account team or prebid@smaato.com for more information. - -# Test Parameters - -For banner adunits: - -``` -var adUnits = [{ - "code": "banner-unit", - "mediaTypes": { - "banner": { - "sizes": [320, 50] - } - }, - "bids": [{ - "bidder": "smaato", - "params": { - "publisherId": "1100042525", - "adspaceId": "130563103" - } - }] -}]; -``` - -For video adunits: - -``` -var adUnits = [{ - "code": "video unit", - "mediaTypes": { - "video": { - "context": "instream", - "playerSize": [640, 480], - "mimes": ["video/mp4"], - "minduration": 5, - "maxduration": 30, - "startdelay": 0, - "linearity": 1, - "protocols": [7], - "skip": 1, - "skipmin": 5, - "api": [7], - "ext": {"rewarded": 0} - } - }, - "bids": [{ - "bidder": "smaato", - "params": { - "publisherId": "1100042525", - "adspaceId": "130563103" - } - }] -}]; -``` \ No newline at end of file diff --git a/modules/smartadserverBidAdapter.js b/modules/smartadserverBidAdapter.js deleted file mode 100644 index bb9364c72c3..00000000000 --- a/modules/smartadserverBidAdapter.js +++ /dev/null @@ -1,198 +0,0 @@ -import * as utils from '../src/utils.js'; -import { - BANNER, - VIDEO -} from '../src/mediaTypes.js'; -import { - config -} from '../src/config.js'; -import { - registerBidder -} from '../src/adapters/bidderFactory.js'; -import { - createEidsArray -} from './userId/eids.js'; -const BIDDER_CODE = 'smartadserver'; -const GVL_ID = 45; -export const spec = { - code: BIDDER_CODE, - gvlid: GVL_ID, - aliases: ['smart'], // short code - supportedMediaTypes: [BANNER, VIDEO], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return !!(bid.params && bid.params.siteId && bid.params.pageId && bid.params.formatId); - }, - - /** - * Serialize a supply chain object to a string uri encoded - * - * @param {*} schain object - */ - serializeSupplyChain: function(schain) { - if (!schain || !schain.nodes) return null; - const nodesProperties = ['asi', 'sid', 'hp', 'rid', 'name', 'domain']; - return `${schain.ver},${schain.complete}!` + - schain.nodes.map(node => nodesProperties.map(prop => - node[prop] ? encodeURIComponent(node[prop]) : '') - .join(',')) - .join('!'); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests an array of bids - * @param {BidderRequest} bidderRequest bidder request object - * @return {ServerRequest[]} Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - // use bidderRequest.bids[] to get bidder-dependent request info - // if your bidder supports multiple currencies, use config.getConfig(currency) - // to find which one the ad server needs - - // pull requested transaction ID from bidderRequest.bids[].transactionId - return validBidRequests.map(bid => { - // Common bid request attributes for banner, outstream and instream. - let payload = { - siteid: bid.params.siteId, - pageid: bid.params.pageId, - formatid: bid.params.formatId, - currencyCode: config.getConfig('currency.adServerCurrency'), - bidfloor: bid.params.bidfloor || 0.0, - targeting: bid.params.target && bid.params.target !== '' ? bid.params.target : undefined, - buid: bid.params.buId && bid.params.buId !== '' ? bid.params.buId : undefined, - appname: bid.params.appName && bid.params.appName !== '' ? bid.params.appName : undefined, - ckid: bid.params.ckId || 0, - tagId: bid.adUnitCode, - pageDomain: bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer ? bidderRequest.refererInfo.referer : undefined, - transactionId: bid.transactionId, - timeout: config.getConfig('bidderTimeout'), - bidId: bid.bidId, - prebidVersion: '$prebid.version$', - schain: spec.serializeSupplyChain(bid.schain) - }; - - const videoMediaType = utils.deepAccess(bid, 'mediaTypes.video'); - if (!videoMediaType) { - const bannerMediaType = utils.deepAccess(bid, 'mediaTypes.banner'); - payload.sizes = bannerMediaType.sizes.map(size => ({ - w: size[0], - h: size[1] - })); - } else if (videoMediaType && (videoMediaType.context === 'instream' || videoMediaType.context === 'outstream')) { - // Specific attributes for instream. - let playerSize = videoMediaType.playerSize[0]; - payload.isVideo = videoMediaType.context === 'instream'; - payload.mediaType = VIDEO; - payload.videoData = { - videoProtocol: bid.params.video.protocol, - playerWidth: playerSize[0], - playerHeight: playerSize[1], - adBreak: bid.params.video.startDelay || 1 - }; - } else { - return {}; - } - - if (bidderRequest && bidderRequest.gdprConsent) { - payload.addtl_consent = bidderRequest.gdprConsent.addtlConsent; - payload.gdpr_consent = bidderRequest.gdprConsent.consentString; - payload.gdpr = bidderRequest.gdprConsent.gdprApplies; // we're handling the undefined case server side - } - - if (bid && bid.userId) { - payload.eids = createEidsArray(bid.userId); - } - - if (bidderRequest && bidderRequest.uspConsent) { - payload.us_privacy = bidderRequest.uspConsent; - } - - var payloadString = JSON.stringify(payload); - - return { - method: 'POST', - url: (bid.params.domain !== undefined ? bid.params.domain : 'https://prg.smartadserver.com') + '/prebid/v1', - data: payloadString, - }; - }); - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @param {*} bidRequestString - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function (serverResponse, bidRequestString) { - const bidResponses = []; - let response = serverResponse.body; - try { - if (response && !response.isNoAd) { - const bidRequest = JSON.parse(bidRequestString.data); - - let bidResponse = { - requestId: bidRequest.bidId, - cpm: response.cpm, - width: response.width, - height: response.height, - creativeId: response.creativeId, - dealId: response.dealId, - currency: response.currency, - netRevenue: response.isNetCpm, - ttl: response.ttl, - dspPixels: response.dspPixels - }; - - if (bidRequest.mediaType === VIDEO) { - bidResponse.mediaType = VIDEO; - bidResponse.vastUrl = response.adUrl; - bidResponse.vastXml = response.ad; - bidResponse.content = response.ad; - } else { - bidResponse.adUrl = response.adUrl; - bidResponse.ad = response.ad; - } - - bidResponses.push(bidResponse); - } - } catch (error) { - utils.logError('Error while parsing smart server response', error); - } - return bidResponses; - }, - - /** - * User syncs. - * - * @param {*} syncOptions Publisher prebid configuration. - * @param {*} serverResponses A successful response from the server. - * @return {syncs[]} An array of syncs that should be executed. - */ - getUserSyncs: function (syncOptions, serverResponses) { - const syncs = []; - if (syncOptions.iframeEnabled && serverResponses.length > 0) { - syncs.push({ - type: 'iframe', - url: serverResponses[0].body.cSyncUrl - }); - } else if (syncOptions.pixelEnabled && serverResponses.length > 0 && serverResponses[0].body.dspPixels !== undefined) { - serverResponses[0].body.dspPixels.forEach(function(pixel) { - syncs.push({ - type: 'image', - url: pixel - }); - }); - } - return syncs; - } -}; - -registerBidder(spec); diff --git a/modules/smartadserverBidAdapter.md b/modules/smartadserverBidAdapter.md deleted file mode 100644 index 05e29359fd2..00000000000 --- a/modules/smartadserverBidAdapter.md +++ /dev/null @@ -1,136 +0,0 @@ -# Overview - -``` -Module Name: Smart Ad Server Bidder Adapter -Module Type: Bidder Adapter -Maintainer: support@smartadserver.com -``` - -# Description - -Connect to Smart for bids. - -The Smart adapter requires setup and approval from the Smart team. -Please reach out to your Technical account manager for more information. - -# Test Parameters - -## Web -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [ - { - bidder: "smart", - params: { - domain: 'https://prg.smartadserver.com', - siteId: 207435, - pageId: 896536, - formatId: 62913, - ckId: 1122334455 // optional - } - } - ] - } - ]; -``` - -## In-app -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [ - { - bidder: "smart", - params: { - domain: 'https://prg.smartadserver.com', - siteId: 207435, - pageId: 896536, - formatId: 65906, - buId: "com.smartadserver.android.dashboard", // in-app only - appName: "Smart AdServer Preview", // in-app only - ckId: 1122334455 // optional - } - } - ] - } - ]; -``` - -## Instream Video -``` - var videoAdUnit = { - code: 'test-div', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480] - } - }, - bids: [{ - bidder: "smart", - params: { - domain: 'https://prg.smartadserver.com', - siteId: 326147, - pageId: 1153895, - formatId: 55710, - bidfloor: 5, - video: { - protocol: 6, - startDelay: 1 - } - } - }] - }; -``` - -## Outstream Video - -``` - var outstreamVideoAdUnit = { - code: 'test-div', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [640, 480] - } - }, - renderer: { - url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', - render: function (bid) { - bid.renderer.push(() => { - ANOutstreamVideo.renderAd({ - targetId: bid.adUnitCode, - adResponse: bid - }); - }); - } - }, - bids: [{ - bidder: "smart", - params: { - domain: 'https://prg.smartadserver.com', - siteId: 207435, - pageId: 896536, - formatId: 85089, - bidfloor: 5, - video: { - protocol: 6, - startDelay: 1 - } - } - }] - }; -``` \ No newline at end of file diff --git a/modules/smarticoBidAdapter.js b/modules/smarticoBidAdapter.js deleted file mode 100644 index 9107ce5f908..00000000000 --- a/modules/smarticoBidAdapter.js +++ /dev/null @@ -1,116 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; -import find from 'core-js-pure/features/array/find.js'; - -const SMARTICO_CONFIG = { - bidRequestUrl: 'https://trmads.eu/preBidRequest', - widgetUrl: 'https://trmads.eu/get', - method: 'POST' -} - -const BIDDER_CODE = 'smartico'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - isBidRequestValid: function (bid) { - return !!(bid && bid.params && bid.params.token && bid.params.placementId); - }, - buildRequests: function (validBidRequests, bidderRequest) { - var i - var j - var bid - var bidParam - var bidParams = [] - var sizes - var frameWidth = Math.round(window.screen.width) - var frameHeight = Math.round(window.screen.height) - for (i = 0; i < validBidRequests.length; i++) { - bid = validBidRequests[i] - if (bid.sizes) { - sizes = bid.sizes - } else if (typeof (BANNER) != 'undefined' && bid.mediaTypes && bid.mediaTypes[BANNER] && bid.mediaTypes[BANNER].sizes) { - sizes = bid.mediaTypes[BANNER].sizes - } else if (frameWidth && frameHeight) { - sizes = [[frameWidth, frameHeight]] - } else { - sizes = [] - } - for (j = 0; j < sizes.length; j++) { - bidParam = { - token: bid.params.token || '', - bidId: bid.bidId, - 'banner-format-width': sizes[j][0], - 'banner-format-height': sizes[j][1] - } - if (bid.params.bannerFormat) { - bidParam['banner-format'] = bid.params.bannerFormat - } - if (bid.params.language) { - bidParam.language = bid.params.language - } - if (bid.params.region) { - bidParam.region = bid.params.region - } - if (bid.params.regions && (bid.params.regions instanceof String || (bid.params.regions instanceof Array && bid.params.regions.length))) { - bidParam.regions = bid.params.regions - if (bidParam.regions instanceof Array) { - bidParam.regions = bidParam.regions.join(',') - } - } - bidParams.push(bidParam) - } - } - - var ServerRequestObjects = { - method: SMARTICO_CONFIG.method, - url: SMARTICO_CONFIG.bidRequestUrl, - bids: validBidRequests, - data: {bidParams: bidParams, auctionId: bidderRequest.auctionId, origin: window.location.origin} - } - - return ServerRequestObjects; - }, - interpretResponse: function (serverResponse, bidRequest) { - var i - var bid - var bidObject - var url - var html - var ad - var token - var language - var scriptId - var bidResponses = [] - - for (i = 0; i < serverResponse.length; i++) { - ad = serverResponse[i]; - bid = find(bidRequest.bids, bid => bid.bidId === ad.bidId) - if (bid) { - token = bid.params.token || '' - - language = bid.params.language || SMARTICO_CONFIG.language || '' - - scriptId = encodeURIComponent('smartico-widget-' + bid.params.placementId + '-' + i) - - url = SMARTICO_CONFIG.widgetUrl + '?token=' + encodeURIComponent(token) + '&auction-id=' + encodeURIComponent(bid.auctionId) + '&from-auction-buffer=1&own_session=1&ad=' + encodeURIComponent(ad.id) + '&scriptid=' + scriptId + (ad.bannerFormatAlias ? '&banner-format=' + encodeURIComponent(ad.bannerFormatAlias) : '') + (language ? '&language=' + encodeURIComponent(language) : '') - - html = ''; -}; - -function _videoCreative(sbiDc, sbiAid, referer) { - return `https://${sbiDc}apex.go.sonobi.com/vast.xml?vid=${sbiAid}&ref=${encodeURIComponent(referer)}` -} - -function _getBidIdFromTrinityKey (key) { - return key.split('|').slice(-1)[0] -} - -/** - * @param context - the window to determine the innerWidth from. This is purely for test purposes as it should always be the current window - */ -export const _isInbounds = (context = window) => (lowerBound = 0, upperBound = Number.MAX_SAFE_INTEGER) => context.innerWidth >= lowerBound && context.innerWidth < upperBound; - -/** - * @param context - the window to determine the innerWidth from. This is purely for test purposes as it should always be the current window - */ -export function _getPlatform(context = window) { - const isInBounds = _isInbounds(context); - const MOBILE_VIEWPORT = { - lt: 768 - }; - const TABLET_VIEWPORT = { - lt: 992, - ge: 768 - }; - if (isInBounds(0, MOBILE_VIEWPORT.lt)) { - return 'mobile' - } - if (isInBounds(TABLET_VIEWPORT.ge, TABLET_VIEWPORT.lt)) { - return 'tablet' - } - return 'desktop'; -} - -function newRenderer(adUnitCode, bid, rendererOptions = {}) { - const renderer = Renderer.install({ - id: bid.aid, - url: OUTSTREAM_REDNERER_URL, - config: rendererOptions, - loaded: false, - adUnitCode - }); - - try { - renderer.setRender(outstreamRender); - } catch (err) { - logWarn('Prebid Error calling setRender on renderer', err); - } - - renderer.setEventHandlers({ - impression: () => logMessage('Sonobi outstream video impression event'), - loaded: () => logMessage('Sonobi outstream video loaded event'), - ended: () => { - logMessage('Sonobi outstream renderer video event'); - // document.querySelector(`#${adUnitCode}`).style.display = 'none'; - } - }); - return renderer; -} - -function outstreamRender(bid) { - // push to render queue because SbiOutstreamRenderer may not be loaded yet - bid.renderer.push(() => { - const [ - width, - height - ] = bid.getSize().split('x'); - const renderer = new window.SbiOutstreamRenderer(); - renderer.init({ - vastUrl: bid.vastUrl, - height, - width, - }); - renderer.setRootElement(bid.adUnitCode); - }); -} - -function _iframeAllowed() { - return userSync.canBidderRegisterSync('iframe', BIDDER_CODE); -} - -registerBidder(spec); diff --git a/modules/sonobiBidAdapter.md b/modules/sonobiBidAdapter.md deleted file mode 100644 index cc4dd8733d4..00000000000 --- a/modules/sonobiBidAdapter.md +++ /dev/null @@ -1,70 +0,0 @@ -# Overview - -``` -Module Name: Sonobi Bidder Adapter -Module Type: Bidder Adapter -Maintainer: apex.prebid@sonobi.com -``` - -# Description - -Module that connects to Sonobi's demand sources. - -# Test Parameters -``` - var adUnits = [ - { - code: 'adUnit_af', - sizes: [[300, 250], [300, 600]], // a display size - bids: [ - { - bidder: 'sonobi', - params: { - ad_unit: '/7780971/sparks_prebid_MR', - placement_id: '1a2b3c4d5e6f1a2b3c4d', // ad_unit and placement_id are mutually exclusive - sizes: [[300, 250], [300, 600]], - floor: 1 // optional - } - } - ] - } - ]; -``` - -# Video Test Parameters -``` - var videoAdUnit = { - code: 'adUnit_af', - sizes: [640,480], - mediaTypes: { - video: {context: 'instream'} - }, - bids: [ - { - bidder: 'sonobi', - params: { - placement_id: '92e95368e86639dbd86d', - } - } - ] - }; -``` - -Example bidsBackHandler for video bids -``` -pbjs.requestBids({ - timeout : 700, - bidsBackHandler : function(bids) { - var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ - adUnit: videoAdUnit, - params: { - cust_params: { - hb_vid: bids.adUnit_af.bids[0].creativeId - }, - iu: '/7780971/apex_jwplayer_video' - } - }); - invokeVideoPlayer(videoUrl); - } - }); -``` diff --git a/modules/sortableAnalyticsAdapter.js b/modules/sortableAnalyticsAdapter.js deleted file mode 100644 index 73ce1393c23..00000000000 --- a/modules/sortableAnalyticsAdapter.js +++ /dev/null @@ -1,534 +0,0 @@ -import adapter from '../src/AnalyticsAdapter.js'; -import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager.js'; -import * as utils from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import { config } from '../src/config.js'; - -const DEFAULT_PROTOCOL = 'https'; -const DEFAULT_HOST = 'pa.deployads.com'; -const DEFAULT_URL = `${DEFAULT_PROTOCOL}://${DEFAULT_HOST}/pae`; -const ANALYTICS_TYPE = 'endpoint'; -const UTM_STORE_KEY = 'sortable_utm'; - -export const DEFAULT_PBID_TIMEOUT = 1000; -export const TIMEOUT_FOR_REGISTRY = 250; - -const settings = {}; -const { - EVENTS: { - AUCTION_INIT, - AUCTION_END, - BID_REQUESTED, - BID_ADJUSTMENT, - BID_WON, - BID_TIMEOUT, - } -} = CONSTANTS; - -const minsToMillis = mins => mins * 60 * 1000; -const UTM_TTL = minsToMillis(30); - -const SORTABLE_EVENTS = { - BID_WON: 'pbrw', - BID_TIMEOUT: 'pbto', - ERROR: 'pber', - PB_BID: 'pbid' -}; - -const UTM_PARAMS = [ - 'utm_campaign', - 'utm_source', - 'utm_medium', - 'utm_content', - 'utm_term' -]; - -const EVENT_KEYS_SHORT_NAMES = { - 'auctionId': 'ai', - 'adUnitCode': 'ac', - 'adId': 'adi', - 'bidderAlias': 'bs', - 'bidFactor': 'bif', - 'bidId': 'bid', - 'bidRequestCount': 'brc', - 'bidderRequestId': 'brid', - 'bidRequestedSizes': 'rs', - 'bidTopCpm': 'btcp', - 'bidTopCpmCurrency': 'btcc', - 'bidTopIsNetRevenue': 'btin', - 'bidTopFactor': 'btif', - 'bidTopSrc': 'btsrc', - 'cpm': 'c', - 'currency': 'cc', - 'dealId': 'did', - 'isNetRevenue': 'inr', - 'isTop': 'it', - 'isWinner': 'iw', - 'isTimeout': 'ito', - 'mediaType': 'mt', - 'reachedTop': 'rtp', - 'numIframes': 'nif', - 'size': 'siz', - 'start': 'st', - 'tagId': 'tgid', - 'transactionId': 'trid', - 'ttl': 'ttl', - 'ttr': 'ttr', - 'url': 'u', - 'utm_campaign': 'uc', - 'utm_source': 'us', - 'utm_medium': 'um', - 'utm_content': 'un', - 'utm_term': 'ut' -}; - -const auctionCache = {}; - -let bidderFactors = null; - -let timeoutId = null; -let eventsToBeSent = []; - -function getStorage() { - try { - return window['sessionStorage']; - } catch (e) { - return null; - } -} - -function putParams(k, v) { - try { - const storage = getStorage(); - if (!storage) { - return false; - } - if (v === null) { - storage.removeItem(k); - } else { - storage.setItem(k, JSON.stringify(v)); - } - return true; - } catch (e) { - return false; - } -} - -function getParams(k) { - try { - let storage = getStorage(); - if (!storage) { - return null; - } - let value = storage.getItem(k); - return value === null ? null : JSON.parse(value); - } catch (e) { - return null; - } -} - -function storeParams(key, paramsToSave) { - if (!settings.disableSessionTracking) { - for (let property in paramsToSave) { - if (paramsToSave.hasOwnProperty(property)) { - putParams(key, paramsToSave); - break; - } - } - } -} - -function getSiteKey(options) { - const sortableConfig = config.getConfig('sortable') || {}; - const globalSiteId = sortableConfig.siteId; - return globalSiteId || options.siteId; -} - -function generateRandomId() { - let s = (+new Date()).toString(36); - for (let i = 0; i < 6; ++i) { s += (Math.random() * 36 | 0).toString(36); } - return s; -} - -function getSessionParams() { - const stillValid = paramsFromStorage => (paramsFromStorage.created) < (+new Date() + UTM_TTL); - let sessionParams = null; - if (!settings.disableSessionTracking) { - const paramsFromStorage = getParams(UTM_STORE_KEY); - sessionParams = paramsFromStorage && stillValid(paramsFromStorage) ? paramsFromStorage : null; - } - sessionParams = sessionParams || {'created': +new Date(), 'sessionId': generateRandomId()}; - const urlParams = UTM_PARAMS.map(utils.getParameterByName); - if (UTM_PARAMS.every(key => !sessionParams[key])) { - UTM_PARAMS.forEach((v, i) => sessionParams[v] = urlParams[i] || sessionParams[v]); - sessionParams.created = +new Date(); - storeParams(UTM_STORE_KEY, sessionParams); - } - return sessionParams; -} - -function getPrebidVersion() { - return getGlobal().version; -} - -function getFactor(bidder) { - if (bidder && bidder.bidCpmAdjustment) { - return bidder.bidCpmAdjustment(1.0); - } else { - return null; - } -} - -function getBiddersFactors() { - const pb = getGlobal(); - const result = {}; - if (pb && pb.bidderSettings) { - Object.keys(pb.bidderSettings).forEach(bidderKey => { - const bidder = pb.bidderSettings[bidderKey]; - const factor = getFactor(bidder); - if (factor !== null) { - result[bidderKey] = factor; - } - }); - } - return result; -} - -function getBaseEvent(auctionId, adUnitCode, bidderCode) { - const event = {}; - event.s = settings.key; - event.ai = auctionId; - event.ac = adUnitCode; - event.bs = bidderCode; - return event; -} - -function getBidBaseEvent(auctionId, adUnitCode, bidderCode) { - const sessionParams = getSessionParams(); - const prebidVersion = getPrebidVersion(); - const event = getBaseEvent(auctionId, adUnitCode, bidderCode); - event.sid = sessionParams.sessionId; - event.pv = settings.pageviewId; - event.to = auctionCache[auctionId].timeout; - event.pbv = prebidVersion; - UTM_PARAMS.filter(k => sessionParams[k]).forEach(k => event[EVENT_KEYS_SHORT_NAMES[k]] = sessionParams[k]); - return event; -} - -function createPBBidEvent(bid) { - const event = getBidBaseEvent(bid.auctionId, bid.adUnitCode, bid.bidderAlias); - Object.keys(bid).forEach(k => { - const shortName = EVENT_KEYS_SHORT_NAMES[k]; - if (shortName) { - event[shortName] = bid[k]; - } - }); - event._type = SORTABLE_EVENTS.PB_BID; - return event; -} - -function getBidFactor(bidderAlias) { - if (!bidderFactors) { - bidderFactors = getBiddersFactors(); - } - const factor = bidderFactors[bidderAlias]; - return typeof factor !== 'undefined' ? factor : 1.0; -} - -function createPrebidBidWonEvent({auctionId, adUnitCode, bidderAlias, cpm, currency, isNetRevenue}) { - const bidFactor = getBidFactor(bidderAlias); - const event = getBaseEvent(auctionId, adUnitCode, bidderAlias); - event.bif = bidFactor; - bidderFactors = null; - event.c = cpm; - event.cc = currency; - event.inr = isNetRevenue; - event._type = SORTABLE_EVENTS.BID_WON; - return event; -} - -function createPrebidTimeoutEvent({auctionId, adUnitCode, bidderAlias}) { - const event = getBaseEvent(auctionId, adUnitCode, bidderAlias); - event._type = SORTABLE_EVENTS.BID_TIMEOUT; - return event; -} - -function getDistinct(arr) { - return arr.filter((v, i, a) => a.indexOf(v) === i); -} - -function groupBy(list, keyGetterFn) { - const map = {}; - list.forEach(item => { - const key = keyGetterFn(item); - map[key] = map[key] ? map[key].concat(item) : [item]; - }); - return map; -} - -function mergeAndCompressEventsByType(events, type) { - if (!events.length) { - return {}; - } - const allKeys = getDistinct(events.map(ev => Object.keys(ev)).reduce((prev, curr) => prev.concat(curr), [])); - const eventsAsMap = {}; - allKeys.forEach(k => { - events.forEach(ev => eventsAsMap[k] = eventsAsMap[k] ? eventsAsMap[k].concat(ev[k]) : [ev[k]]); - }); - const allSame = arr => arr.every(el => arr[0] === el); - Object.keys(eventsAsMap) - .forEach(k => eventsAsMap[k] = (eventsAsMap[k].length && allSame(eventsAsMap[k])) ? eventsAsMap[k][0] : eventsAsMap[k]); - eventsAsMap._count = events.length; - const result = {}; - result[type] = eventsAsMap; - return result; -} - -function mergeAndCompressEvents(events) { - const types = getDistinct(events.map(e => e._type)); - const groupedEvents = groupBy(events, e => e._type); - const results = types.map(t => groupedEvents[t]) - .map(events => mergeAndCompressEventsByType(events, events[0]._type)); - return results.reduce((prev, eventMap) => { - const key = Object.keys(eventMap)[0]; - prev[key] = eventMap[key]; - return prev; - }, {}); -} - -function registerEvents(events) { - eventsToBeSent = eventsToBeSent.concat(events); - if (!timeoutId) { - timeoutId = setTimeout(() => { - const _eventsToBeSent = eventsToBeSent.slice(); - eventsToBeSent = []; - sendEvents(_eventsToBeSent); - timeoutId = null; - }, TIMEOUT_FOR_REGISTRY); - } -} - -function sendEvents(events) { - const url = settings.url; - const mergedEvents = mergeAndCompressEvents(events); - const options = { - 'contentType': 'text/plain', - 'method': 'POST', - 'withCredentials': true - }; - const onSend = () => utils.logInfo('Sortable Analytics data sent'); - ajax(url, onSend, JSON.stringify(mergedEvents), options); -} - -// converts [[300, 250], [728, 90]] to '300x250,728x90' -function sizesToString(sizes) { - return sizes.map(s => s.join('x')).join(','); -} - -function dimsToSizeString(width, height) { - return `${width}x${height}`; -} - -function handleBidRequested(event) { - const refererInfo = event.refererInfo; - const url = refererInfo.referer; - const reachedTop = refererInfo.reachedTop; - const numIframes = refererInfo.numIframes; - event.bids.forEach(bid => { - const auctionId = bid.auctionId; - const adUnitCode = bid.adUnitCode; - const tagId = bid.bidder === 'sortable' ? bid.params.tagId : ''; - if (!auctionCache[auctionId].adUnits[adUnitCode]) { - auctionCache[auctionId].adUnits[adUnitCode] = {bids: {}}; - } - const adUnit = auctionCache[auctionId].adUnits[adUnitCode]; - const bids = adUnit.bids; - const newBid = { - adUnitCode: bid.adUnitCode, - auctionId: event.auctionId, - bidderAlias: bid.bidder, - bidId: bid.bidId, - bidderRequestId: bid.bidderRequestId, - bidRequestCount: bid.bidRequestsCount, - bidRequestedSizes: sizesToString(bid.sizes), - currency: bid.currency, - cpm: 0.0, - isTimeout: false, - isTop: false, - isWinner: false, - numIframes: numIframes, - start: event.start, - tagId: tagId, - transactionId: bid.transactionId, - reachedTop: reachedTop, - url: encodeURI(url) - }; - bids[newBid.bidderAlias] = newBid; - }); -} - -function handleBidAdjustment(event) { - const auctionId = event.auctionId; - const adUnitCode = event.adUnitCode; - const adUnit = auctionCache[auctionId].adUnits[adUnitCode]; - const bid = adUnit.bids[event.bidderCode]; - const bidFactor = getBidFactor(event.bidderCode); - bid.adId = event.adId; - bid.adUnitCode = event.adUnitCode; - bid.auctionId = event.auctionId; - bid.bidderAlias = event.bidderCode; - bid.bidFactor = bidFactor; - bid.cpm = event.cpm; - bid.currency = event.currency; - bid.dealId = event.dealId; - bid.isNetRevenue = event.netRevenue; - bid.mediaType = event.mediaType; - bid.responseTimestamp = event.responseTimestamp; - bid.size = dimsToSizeString(event.width, event.height); - bid.ttl = event.ttl; - bid.ttr = event.timeToRespond; -} - -function handleBidWon(event) { - const auctionId = event.auctionId; - const auction = auctionCache[auctionId]; - if (auction) { - const adUnitCode = event.adUnitCode; - const adUnit = auction.adUnits[adUnitCode]; - Object.keys(adUnit.bids).forEach(bidderCode => { - const bidFromUnit = adUnit.bids[bidderCode]; - bidFromUnit.isWinner = event.bidderCode === bidderCode; - }); - } else { - const ev = createPrebidBidWonEvent({ - adUnitCode: event.adUnitCode, - auctionId: event.auctionId, - bidderAlias: event.bidderCode, - currency: event.currency, - cpm: event.cpm, - isNetRevenue: event.netRevenue, - }); - registerEvents([ev]); - } -} - -function handleBidTimeout(event) { - event.forEach(timeout => { - const auctionId = timeout.auctionId; - const adUnitCode = timeout.adUnitCode; - const bidderAlias = timeout.bidder; - const auction = auctionCache[auctionId]; - if (auction) { - const adUnit = auction.adUnits[adUnitCode]; - const bid = adUnit.bids[bidderAlias]; - bid.isTimeout = true; - } else { - const prebidTimeoutEvent = createPrebidTimeoutEvent({auctionId, adUnitCode, bidderAlias}); - registerEvents([prebidTimeoutEvent]); - } - }); -} - -function handleAuctionInit(event) { - const auctionId = event.auctionId; - const timeout = event.timeout; - auctionCache[auctionId] = {timeout: timeout, auctionId: auctionId, adUnits: {}}; -} - -function handleAuctionEnd(event) { - const auction = auctionCache[event.auctionId]; - const adUnits = auction.adUnits; - setTimeout(() => { - const events = Object.keys(adUnits).map(adUnitCode => { - const bidderKeys = Object.keys(auction.adUnits[adUnitCode].bids); - const bids = bidderKeys.map(bidderCode => auction.adUnits[adUnitCode].bids[bidderCode]); - const highestBid = bids.length ? bids.reduce(utils.getOldestHighestCpmBid) : null; - return bidderKeys.map(bidderCode => { - const bid = auction.adUnits[adUnitCode].bids[bidderCode]; - if (highestBid && highestBid.cpm) { - bid.isTop = highestBid.bidderAlias === bid.bidderAlias; - bid.bidTopFactor = getBidFactor(highestBid.bidderAlias); - bid.bidTopCpm = highestBid.cpm; - bid.bidTopCpmCurrency = highestBid.currency; - bid.bidTopIsNetRevenue = highestBid.isNetRevenue; - bid.bidTopSrc = highestBid.bidderAlias; - } - return createPBBidEvent(bid); - }); - }).reduce((prev, curr) => prev.concat(curr), []); - bidderFactors = null; - sendEvents(events); - delete auctionCache[event.auctionId]; - }, settings.timeoutForPbid); -} - -function handleError(eventType, event, e) { - const ev = {}; - ev.s = settings.key; - ev.ti = eventType; - ev.args = JSON.stringify(event); - ev.msg = e.message; - ev._type = SORTABLE_EVENTS.ERROR; - registerEvents([ev]); -} - -const sortableAnalyticsAdapter = Object.assign(adapter({url: DEFAULT_URL, ANALYTICS_TYPE}), { - track({eventType, args}) { - try { - switch (eventType) { - case AUCTION_INIT: - handleAuctionInit(args); - break; - case AUCTION_END: - handleAuctionEnd(args); - break; - case BID_REQUESTED: - handleBidRequested(args); - break; - case BID_ADJUSTMENT: - handleBidAdjustment(args); - break; - case BID_WON: - handleBidWon(args); - break; - case BID_TIMEOUT: - handleBidTimeout(args); - break; - } - } catch (e) { - handleError(eventType, args, e); - } - } -}); - -sortableAnalyticsAdapter.originEnableAnalytics = sortableAnalyticsAdapter.enableAnalytics; - -sortableAnalyticsAdapter.enableAnalytics = function (setupConfig) { - if (this.initConfig(setupConfig)) { - utils.logInfo('Sortable Analytics adapter enabled'); - sortableAnalyticsAdapter.originEnableAnalytics(setupConfig); - } -}; - -sortableAnalyticsAdapter.initConfig = function (setupConfig) { - settings.disableSessionTracking = setupConfig.disableSessionTracking === undefined ? false : setupConfig.disableSessionTracking; - settings.key = getSiteKey(setupConfig.options); - settings.protocol = setupConfig.options.protocol || DEFAULT_PROTOCOL; - settings.url = `${settings.protocol}://${setupConfig.options.eventHost || DEFAULT_HOST}/pae/${settings.key}`; - settings.pageviewId = generateRandomId(); - settings.timeoutForPbid = setupConfig.timeoutForPbid ? Math.max(setupConfig.timeoutForPbid, 0) : DEFAULT_PBID_TIMEOUT; - return !!settings.key; -}; - -sortableAnalyticsAdapter.getOptions = function () { - return settings; -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: sortableAnalyticsAdapter, - code: 'sortable' -}); - -export default sortableAnalyticsAdapter; diff --git a/modules/sortableAnalyticsAdapter.md b/modules/sortableAnalyticsAdapter.md deleted file mode 100644 index a4aa8019031..00000000000 --- a/modules/sortableAnalyticsAdapter.md +++ /dev/null @@ -1,9 +0,0 @@ -# Overview - -Module Name: Sortable Analytics Adapter -Module Type: Analytics Adapter -Maintainer: prebid@sortable.com - -# Description - -Analytics adapter for Sortable. Contact prebid@sortable.com for information. diff --git a/modules/sortableBidAdapter.js b/modules/sortableBidAdapter.js deleted file mode 100644 index 6989abff143..00000000000 --- a/modules/sortableBidAdapter.js +++ /dev/null @@ -1,351 +0,0 @@ -import * as utils 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 { createEidsArray } from './userId/eids.js'; - -const BIDDER_CODE = 'sortable'; -const SERVER_URL = 'https://c.deployads.com'; - -function setAssetRequired(native, asset) { - if (native.required) { - asset.required = 1; - } - return asset; -} - -function buildNativeRequest(nativeMediaType) { - const assets = []; - const title = nativeMediaType.title; - if (title) { - assets.push(setAssetRequired(title, { - title: {len: title.len} - })); - } - const img = nativeMediaType.image; - if (img) { - assets.push(setAssetRequired(img, { - img: { - type: 3, // Main - wmin: 1, - hmin: 1 - } - })); - } - const icon = nativeMediaType.icon; - if (icon) { - assets.push(setAssetRequired(icon, { - img: { - type: 1, // Icon - wmin: 1, - hmin: 1 - } - })); - } - const body = nativeMediaType.body; - if (body) { - assets.push(setAssetRequired(body, {data: {type: 2}})); - } - const cta = nativeMediaType.cta; - if (cta) { - assets.push(setAssetRequired(cta, {data: {type: 12}})); - } - const sponsoredBy = nativeMediaType.sponsoredBy; - if (sponsoredBy) { - assets.push(setAssetRequired(sponsoredBy, {data: {type: 1}})); - } - - utils._each(assets, (asset, id) => asset.id = id); - return { - ver: '1', - request: JSON.stringify({ - ver: '1', - assets - }) - }; -} - -function tryParseNativeResponse(adm) { - let native = null; - try { - native = JSON.parse(adm); - } catch (e) { - utils.logError('Sortable bid adapter unable to parse native bid response:\n\n' + e); - } - return native && native.native; -} - -function createImgObject(img) { - if (img.w || img.h) { - return { - url: img.url, - width: img.w, - height: img.h - }; - } else { - return img.url; - } -} - -function interpretNativeResponse(response) { - const native = {}; - if (response.link) { - native.clickUrl = response.link.url; - } - utils._each(response.assets, asset => { - switch (asset.id) { - case 1: - native.title = asset.title.text; - break; - case 2: - native.image = createImgObject(asset.img); - break; - case 3: - native.icon = createImgObject(asset.img); - break; - case 4: - native.body = asset.data.value; - break; - case 5: - native.cta = asset.data.value; - break; - case 6: - native.sponsoredBy = asset.data.value; - break; - } - }); - return native; -} - -function transformSyncs(responses, type, syncs) { - utils._each(responses, res => { - if (res.body && res.body.ext && res.body.ext.sync_dsps && res.body.ext.sync_dsps.length) { - utils._each(res.body.ext.sync_dsps, sync => { - if (sync[0] === type && sync[1]) { - syncs.push({type, url: sync[1]}); - } - }); - } - }); -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, NATIVE, VIDEO], - - isBidRequestValid: function(bid) { - const sortableConfig = config.getConfig('sortable'); - const haveSiteId = (sortableConfig && !!sortableConfig.siteId) || bid.params.siteId; - const validFloor = !bid.params.floor || utils.isNumber(bid.params.floor); - const validSize = /\d+x\d+/; - const validFloorSizeMap = !bid.params.floorSizeMap || - (utils.isPlainObject(bid.params.floorSizeMap) && - Object.keys(bid.params.floorSizeMap).every(size => - size.match(validSize) && utils.isNumber(bid.params.floorSizeMap[size]) - )) - const validKeywords = !bid.params.keywords || - (utils.isPlainObject(bid.params.keywords) && - Object.keys(bid.params.keywords).every(key => - utils.isStr(key) && utils.isStr(bid.params.keywords[key]) - )) - const isBanner = !bid.mediaTypes || bid.mediaTypes[BANNER] || !(bid.mediaTypes[NATIVE] || bid.mediaTypes[VIDEO]); - const bannerSizes = isBanner ? utils.deepAccess(bid, `mediaType.${BANNER}.sizes`) || bid.sizes : null; - return !!(bid.params.tagId && haveSiteId && validFloor && validFloorSizeMap && validKeywords && (!isBanner || - (bannerSizes && bannerSizes.length > 0 && bannerSizes.every(sizeArr => sizeArr.length == 2 && sizeArr.every(num => utils.isNumber(num)))))); - }, - - buildRequests: function(validBidReqs, bidderRequest) { - const sortableConfig = config.getConfig('sortable') || {}; - const globalSiteId = sortableConfig.siteId; - let loc = utils.parseUrl(bidderRequest.refererInfo.referer); - - const sortableImps = utils._map(validBidReqs, bid => { - const rv = { - id: bid.bidId, - tagid: bid.params.tagId, - ext: {} - }; - const bannerMediaType = utils.deepAccess(bid, `mediaTypes.${BANNER}`); - const nativeMediaType = utils.deepAccess(bid, `mediaTypes.${NATIVE}`); - const videoMediaType = utils.deepAccess(bid, `mediaTypes.${VIDEO}`); - if (bannerMediaType || !(nativeMediaType || videoMediaType)) { - const bannerSizes = (bannerMediaType && bannerMediaType.sizes) || bid.sizes; - rv.banner = { - format: utils._map(bannerSizes, ([width, height]) => ({w: width, h: height})) - }; - } - if (nativeMediaType) { - rv.native = buildNativeRequest(nativeMediaType); - } - if (videoMediaType && videoMediaType.context === 'instream') { - const video = {placement: 1}; - video.mimes = videoMediaType.mimes || []; - video.minduration = utils.deepAccess(bid, 'params.video.minduration') || 10; - video.maxduration = utils.deepAccess(bid, 'params.video.maxduration') || 60; - const startDelay = utils.deepAccess(bid, 'params.video.startdelay'); - if (startDelay != null) { - video.startdelay = startDelay; - } - if (videoMediaType.playerSize && videoMediaType.playerSize.length) { - const size = videoMediaType.playerSize[0]; - video.w = size[0]; - video.h = size[1]; - } - if (videoMediaType.api) { - video.api = videoMediaType.api; - } - if (videoMediaType.protocols) { - video.protocols = videoMediaType.protocols; - } - if (videoMediaType.playbackmethod) { - video.playbackmethod = videoMediaType.playbackmethod; - } - rv.video = video; - } - if (bid.params.floor) { - rv.bidfloor = bid.params.floor; - } - if (bid.params.keywords) { - rv.ext.keywords = bid.params.keywords; - } - if (bid.params.bidderParams) { - utils._each(bid.params.bidderParams, (params, partner) => { - rv.ext[partner] = params; - }); - } - if (bid.params.floorSizeMap) { - rv.ext.floorSizeMap = bid.params.floorSizeMap; - } - return rv; - }); - const gdprConsent = bidderRequest && bidderRequest.gdprConsent; - const bidUserId = validBidReqs[0].userId; - const eids = createEidsArray(bidUserId); - const sortableBidReq = { - id: utils.getUniqueIdentifierStr(), - imp: sortableImps, - source: { - ext: { - schain: validBidReqs[0].schain - } - }, - regs: { - ext: {} - }, - site: { - domain: loc.hostname, - page: loc.href, - ref: loc.href, - publisher: { - id: globalSiteId || validBidReqs[0].params.siteId, - }, - device: { - w: screen.width, - h: screen.height - }, - }, - user: { - ext: {} - } - }; - if (bidderRequest && bidderRequest.timeout > 0) { - sortableBidReq.tmax = bidderRequest.timeout; - } - if (gdprConsent) { - sortableBidReq.user = { - ext: { - consent: gdprConsent.consentString - } - }; - if (typeof gdprConsent.gdprApplies == 'boolean') { - sortableBidReq.regs.ext.gdpr = gdprConsent.gdprApplies ? 1 : 0 - } - } - if (eids.length) { - sortableBidReq.user.ext.eids = eids; - } - if (bidderRequest.uspConsent) { - sortableBidReq.regs.ext.us_privacy = bidderRequest.uspConsent; - } - return { - method: 'POST', - url: `${SERVER_URL}/openrtb2/auction?src=$$REPO_AND_VERSION$$&host=${loc.hostname}`, - data: JSON.stringify(sortableBidReq), - options: {contentType: 'text/plain'} - }; - }, - - interpretResponse: function(serverResponse) { - const { body: {id, seatbid} } = serverResponse; - const sortableBids = []; - if (id && seatbid) { - utils._each(seatbid, seatbid => { - utils._each(seatbid.bid, bid => { - const bidObj = { - requestId: bid.impid, - cpm: parseFloat(bid.price), - width: parseInt(bid.w), - height: parseInt(bid.h), - creativeId: bid.crid || bid.id, - dealId: bid.dealid || null, - currency: 'USD', - netRevenue: true, - mediaType: BANNER, - ttl: 60 - }; - if (bid.adm) { - const adFormat = utils.deepAccess(bid, 'ext.ad_format') - if (adFormat === 'native') { - let native = tryParseNativeResponse(bid.adm); - if (!native) { - return; - } - bidObj.mediaType = NATIVE; - bidObj.native = interpretNativeResponse(native); - } else if (adFormat === 'instream') { - bidObj.mediaType = VIDEO; - bidObj.vastXml = bid.adm; - } else { - bidObj.mediaType = BANNER; - bidObj.ad = bid.adm; - if (bid.nurl) { - bidObj.ad += utils.createTrackPixelHtml(decodeURIComponent(bid.nurl)); - } - } - } else if (bid.nurl) { - bidObj.adUrl = bid.nurl; - } - if (bid.ext) { - bidObj[BIDDER_CODE] = bid.ext; - } - sortableBids.push(bidObj); - }); - }); - } - return sortableBids; - }, - - getUserSyncs: (syncOptions, responses) => { - const syncs = []; - if (syncOptions.iframeEnabled) { - transformSyncs(responses, 'iframe', syncs); - } - if (syncOptions.pixelEnabled) { - transformSyncs(responses, 'image', syncs); - } - return syncs; - }, - - onTimeout(details) { - fetch(`${SERVER_URL}/prebid/timeout`, { - method: 'POST', - body: JSON.stringify(details), - mode: 'no-cors', - headers: new Headers({ - 'Content-Type': 'text/plain' - }) - }); - } -}; - -registerBidder(spec); diff --git a/modules/sortableBidAdapter.md b/modules/sortableBidAdapter.md deleted file mode 100644 index c24ad85b752..00000000000 --- a/modules/sortableBidAdapter.md +++ /dev/null @@ -1,109 +0,0 @@ -# Overview - -``` -Module Name: Sortable Bid Adapter -Module Type: Bidder Adapter -Maintainer: prebid@sortable.com -``` - -# Description - -Sortable's adapter integration to the Prebid library. Posts plain-text JSON to the /openrtb2/auction endpoint. - -# Test Parameters - -``` -var adUnits = [ - { - code: 'test-pb-leaderboard', - mediaTypes: { - banner: { - sizes: [[728, 90]], - } - }, - bids: [{ - bidder: 'sortable', - params: { - tagId: 'test-pb-leaderboard', - siteId: 'prebid.example.com', - 'keywords': { - 'key1': 'val1', - 'key2': 'val2' - } - } - }] - }, { - code: 'test-pb-banner', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [{ - bidder: 'sortable', - params: { - tagId: 'test-pb-banner', - siteId: 'prebid.example.com' - } - }] - }, { - code: 'test-pb-sidebar', - mediaTypes: { - banner: { - sizes: [[160, 600]], - } - }, - bids: [{ - bidder: 'sortable', - params: { - tagId: 'test-pb-sidebar', - siteId: 'prebid.example.com', - 'keywords': { - 'keyA': 'valA' - } - } - }] - }, { - code: 'test-pb-native', - mediaTypes: { - native: { - title: { - required: true, - len: 800 - }, - image: { - required: true, - sizes: [790, 294], - }, - sponsoredBy: { - required: true - } - } - }, - bids: [{ - bidder: 'sortable', - params: { - tagId: 'test-pb-native', - siteId: 'prebid.example.com' - } - }] - }, { - code: 'test-pb-video', - mediaTypes: { - video: { - playerSize: [640,480], - context: 'instream' - } - }, - bids: [ - { - bidder: 'sortable', - params: { - tagId: 'test-pb-video', - siteId: 'prebid.example.com' - } - } - ] - } -] -``` diff --git a/modules/sovrnAnalyticsAdapter.js b/modules/sovrnAnalyticsAdapter.js deleted file mode 100644 index 0d2576edb05..00000000000 --- a/modules/sovrnAnalyticsAdapter.js +++ /dev/null @@ -1,327 +0,0 @@ -import adapter from '../src/AnalyticsAdapter.js' -import adaptermanager from '../src/adapterManager.js' -import CONSTANTS from '../src/constants.json' -import {ajaxBuilder} from '../src/ajax.js' -import * as utils from '../src/utils.js' -import {config} from '../src/config.js' -import find from 'core-js-pure/features/array/find.js' -import includes from 'core-js-pure/features/array/includes.js' - -const ajax = ajaxBuilder(0) - -const { - EVENTS: { - AUCTION_END, - BID_REQUESTED, - BID_ADJUSTMENT, - BID_RESPONSE, - BID_WON - } -} = CONSTANTS - -let pbaUrl = 'https://pba.aws.lijit.com/analytics' -let currentAuctions = {}; -const analyticsType = 'endpoint' - -const getClosestTop = () => { - let topFrame = window; - let err = false; - try { - while (topFrame.parent.document !== topFrame.document) { - if (topFrame.parent.document) { - topFrame = topFrame.parent; - } else { - throw new Error(); - } - } - } catch (e) { - // bException = true; - } - - return { - topFrame, - err - }; -}; - -const getBestPageUrl = ({err: crossDomainError, topFrame}) => { - let sBestPageUrl = ''; - - if (!crossDomainError) { - // easy case- we can get top frame location - sBestPageUrl = topFrame.location.href; - } else { - try { - try { - sBestPageUrl = window.top.location.href; - } catch (e) { - let aOrigins = window.location.ancestorOrigins; - sBestPageUrl = aOrigins[aOrigins.length - 1]; - } - } catch (e) { - sBestPageUrl = topFrame.document.referrer; - } - } - - return sBestPageUrl; -}; -const rootURL = getBestPageUrl(getClosestTop()) - -let sovrnAnalyticsAdapter = Object.assign(adapter({url: pbaUrl, analyticsType}), { - track({ eventType, args }) { - try { - if (eventType === BID_WON) { - new BidWinner(this.sovrnId, args).send(); - return - } - if (args && args.auctionId && currentAuctions[args.auctionId] && currentAuctions[args.auctionId].status === 'complete') { - throw new Error('Event Received after Auction Close Auction Id ' + args.auctionId) - } - if (args && args.auctionId && currentAuctions[args.auctionId] === undefined) { - currentAuctions[args.auctionId] = new AuctionData(this.sovrnId, args.auctionId) - } - switch (eventType) { - case BID_REQUESTED: - currentAuctions[args.auctionId].bidRequested(args) - break - case BID_ADJUSTMENT: - currentAuctions[args.auctionId].originalBid(args) - break - case BID_RESPONSE: - currentAuctions[args.auctionId].adjustedBid(args) - break - case AUCTION_END: - currentAuctions[args.auctionId].send(); - break - } - } catch (e) { - new LogError(e, this.sovrnId, {eventType, args}).send() - } - }, -}) - -sovrnAnalyticsAdapter.getAuctions = function () { - return currentAuctions; -}; - -sovrnAnalyticsAdapter.originEnableAnalytics = sovrnAnalyticsAdapter.enableAnalytics; - -// override enableAnalytics so we can get access to the config passed in from the page -sovrnAnalyticsAdapter.enableAnalytics = function (config) { - let sovrnId = '' - if (config && config.options && (config.options.sovrnId || config.options.affiliateId)) { - sovrnId = config.options.sovrnId || config.options.affiliateId; - } else { - utils.logError('Need Sovrn Id to log auction results. Please contact a Sovrn representative if you do not know your Sovrn Id.') - return - } - sovrnAnalyticsAdapter.sovrnId = sovrnId; - if (config.options.pbaUrl) { - pbaUrl = config.options.pbaUrl; - } - sovrnAnalyticsAdapter.originEnableAnalytics(config) // call the base class function -}; - -adaptermanager.registerAnalyticsAdapter({ - adapter: sovrnAnalyticsAdapter, - code: 'sovrn' -}); - -/** Class Representing a Winning Bid */ -class BidWinner { - /** - * Creates a new bid winner - * @param {string} sovrnId - the affiliate id from the analytics config - * @param {*} event - the args object from the auction event - */ - constructor(sovrnId, event) { - this.body = {} - // eslint-disable-next-line no-undef - this.body.prebidVersion = $$REPO_AND_VERSION$$ - this.body.sovrnId = sovrnId - this.body.winningBid = JSON.parse(JSON.stringify(event)) - this.body.url = rootURL - this.body.payload = 'winner' - delete this.body.winningBid.ad - } - - /** - * Sends the auction to the the ingest server - */ - send() { - this.body.ts = utils.timestamp() - ajax( - pbaUrl, - null, - JSON.stringify(this.body), - { - contentType: 'application/json', - method: 'POST', - } - ) - } -} - -/** Class representing an Auction */ -class AuctionData { - /** - * Create a new auction data collector - * @param {string} sovrnId - the affiliate id from the analytics config - * @param {string} auctionId - the auction id from the auction event - */ - constructor(sovrnId, auctionId) { - this.auction = {} - // eslint-disable-next-line no-undef - this.auction.prebidVersion = $$REPO_AND_VERSION$$ - this.auction.sovrnId = sovrnId - this.auction.auctionId = auctionId - this.auction.payload = 'auction' - this.auction.timeouts = { - buffer: config.getConfig('timeoutBuffer'), - bidder: config.getConfig('bidderTimeout'), - } - this.auction.priceGranularity = config.getConfig('priceGranularity') - this.auction.url = rootURL - this.auction.requests = [] - this.auction.unsynced = [] - this.dropBidFields = ['auctionId', 'ad', 'requestId', 'bidderCode'] - - setTimeout(function(id) { - delete currentAuctions[id] - }, 300000, this.auction.auctionId) - } - - /** - * Record a bid request event - * @param {*} event - the args object from the auction event - */ - bidRequested(event) { - const eventCopy = JSON.parse(JSON.stringify(event)) - delete eventCopy.doneCbCallCount - delete eventCopy.auctionId - this.auction.requests.push(eventCopy) - } - - /** - * Finds the bid from the auction that the event is associated with - * @param {*} event - the args object from the auction event - * @return {*} - the bid - */ - findBid(event) { - const bidder = find(this.auction.requests, r => (r.bidderCode === event.bidderCode)) - if (!bidder) { - this.auction.unsynced.push(JSON.parse(JSON.stringify(event))) - } - let bid = find(bidder.bids, b => (b.bidId === event.requestId)) - - if (!bid) { - event.unmatched = true - bidder.bids.push(JSON.parse(JSON.stringify(event))) - } - return bid - } - - /** - * Records the original bid before any adjustments have been made - * @param {*} event - the args object from the auction event - * NOTE: the bid adjustment occurs before the bid response - * the bid adjustment seems to be the bid ready to be adjusted - */ - originalBid(event) { - let bid = this.findBid(event) - if (bid) { - Object.assign(bid, JSON.parse(JSON.stringify(event))) - this.dropBidFields.forEach((f) => delete bid[f]) - } - } - - /** - * Replaces original values with adjusted values and records the original values for changed values - * in bid.originalValues - * @param {*} event - the args object from the auction event - */ - adjustedBid(event) { - let bid = this.findBid(event) - if (bid) { - bid.originalValues = Object.keys(event).reduce((o, k) => { - if (JSON.stringify(bid[k]) !== JSON.stringify(event[k]) && !includes(this.dropBidFields, k)) { - o[k] = bid[k] - bid[k] = event[k] - } - return o - }, {}) - } - } - - /** - * Sends the auction to the the ingest server - */ - send() { - let maxBids = {} - this.auction.requests.forEach(request => { - request.bids.forEach(bid => { - maxBids[bid.adUnitCode] = maxBids[bid.adUnitCode] || {cpm: 0} - if (bid.cpm > maxBids[bid.adUnitCode].cpm) { - maxBids[bid.adUnitCode] = bid - } - }) - }) - Object.keys(maxBids).forEach(unit => { - maxBids[unit].isAuctionWinner = true - }) - this.auction.ts = utils.timestamp() - ajax( - pbaUrl, - () => { - currentAuctions[this.auction.auctionId] = {status: 'complete', auctionId: this.auction.auctionId} - }, - JSON.stringify(this.auction), - { - contentType: 'application/json', - method: 'POST', - } - ) - } -} -class LogError { - constructor(e, sovrnId, data) { - this.error = {} - this.error.payload = 'error' - this.error.message = e.message - this.error.stack = e.stack - this.error.data = data - // eslint-disable-next-line no-undef - this.error.prebidVersion = $$REPO_AND_VERSION$$ - this.error.sovrnId = sovrnId - this.error.url = rootURL - this.error.userAgent = navigator.userAgent - } - send() { - if (this.error.data && this.error.data.requests) { - this.error.data.requests.forEach(request => { - if (request.bids) { - request.bids.forEach(bid => { - if (bid.ad) { - delete bid.ad - } - }) - } - }) - } - if (ErrorEvent.data && this.error.data.ad) { - delete this.error.data.ad - } - this.error.ts = utils.timestamp() - ajax( - pbaUrl, - null, - JSON.stringify(this.error), - { - contentType: 'application/json', - method: 'POST', - } - ) - } -} - -export default sovrnAnalyticsAdapter; diff --git a/modules/sovrnAnalyticsAdapter.md b/modules/sovrnAnalyticsAdapter.md deleted file mode 100644 index 80bc6d7f6b1..00000000000 --- a/modules/sovrnAnalyticsAdapter.md +++ /dev/null @@ -1,23 +0,0 @@ -# Overview - -``` -Module Name: Sovrn Analytics Adapter -Module Type: Analytics Adapter -Maintainer: jrosendahl@sovrn.com -``` - -# Description - -Sovrn's analytics adaptor allows you to view detailed auction information in Meridian. - -For more information, visit Sovrn.com. - -# Test Parameters -``` -{ - provider: 'sovrn', - options: { - sovrnId: 'xxxxx', // Sovrn ID (required) you can get this by contacting Sovrn support. - } -} -``` diff --git a/modules/sovrnBidAdapter.js b/modules/sovrnBidAdapter.js deleted file mode 100644 index cba90e7d434..00000000000 --- a/modules/sovrnBidAdapter.js +++ /dev/null @@ -1,212 +0,0 @@ -import * as utils from '../src/utils.js' -import { registerBidder } from '../src/adapters/bidderFactory.js' -import { BANNER } from '../src/mediaTypes.js' -import { createEidsArray } from './userId/eids.js'; -import {config} from '../src/config.js'; - -export const spec = { - code: 'sovrn', - supportedMediaTypes: [BANNER], - gvlid: 13, - - /** - * Check if the bid is a valid zone ID in either number or string form - * @param {object} bid the Sovrn bid to validate - * @return boolean for whether or not a bid is valid - */ - isBidRequestValid: function(bid) { - return !!(bid.params.tagid && !isNaN(parseFloat(bid.params.tagid)) && isFinite(bid.params.tagid)) - }, - - /** - * Format the bid request object for our endpoint - * @param {BidRequest[]} bidRequests Array of Sovrn bidders - * @return object of parameters for Prebid AJAX request - */ - buildRequests: function(bidReqs, bidderRequest) { - try { - let sovrnImps = []; - let iv; - let schain; - let eids; - let tpid = [] - let criteoId; - - utils._each(bidReqs, function (bid) { - if (!eids && bid.userId) { - eids = createEidsArray(bid.userId) - eids.forEach(function (id) { - if (id.uids && id.uids[0]) { - if (id.source === 'criteo.com') { - criteoId = id.uids[0].id - } - tpid.push({source: id.source, uid: id.uids[0].id}) - } - }) - } - - if (bid.schain) { - schain = schain || bid.schain - } - iv = iv || utils.getBidIdParameter('iv', bid.params) - - let bidSizes = (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) || bid.sizes - bidSizes = ((utils.isArray(bidSizes) && utils.isArray(bidSizes[0])) ? bidSizes : [bidSizes]) - bidSizes = bidSizes.filter(size => utils.isArray(size)) - const processedSizes = bidSizes.map(size => ({w: parseInt(size[0], 10), h: parseInt(size[1], 10)})) - const floorInfo = (bid.getFloor && typeof bid.getFloor === 'function') ? bid.getFloor({ - currency: 'USD', - mediaType: 'banner', - size: '*' - }) : {} - floorInfo.floor = floorInfo.floor || utils.getBidIdParameter('bidfloor', bid.params) - - const imp = { - adunitcode: bid.adUnitCode, - id: bid.bidId, - banner: { - format: processedSizes, - w: 1, - h: 1, - }, - tagid: String(utils.getBidIdParameter('tagid', bid.params)), - bidfloor: floorInfo.floor - } - - imp.ext = utils.getBidIdParameter('ext', bid.ortb2Imp) || undefined - - const segmentsString = utils.getBidIdParameter('segments', bid.params) - if (segmentsString) { - imp.ext = imp.ext || {} - imp.ext.deals = segmentsString.split(',').map(deal => deal.trim()) - } - sovrnImps.push(imp) - }) - - const fpd = config.getConfig('ortb2') || {} - - const site = fpd.site || {} - site.page = bidderRequest.refererInfo.referer - // clever trick to get the domain - site.domain = utils.parseUrl(site.page).hostname - - const sovrnBidReq = { - id: utils.getUniqueIdentifierStr(), - imp: sovrnImps, - site: site, - user: fpd.user || {} - } - - if (schain) { - sovrnBidReq.source = { - ext: { - schain - } - }; - } - - if (bidderRequest.gdprConsent) { - utils.deepSetValue(sovrnBidReq, 'regs.ext.gdpr', +bidderRequest.gdprConsent.gdprApplies); - utils.deepSetValue(sovrnBidReq, 'user.ext.consent', bidderRequest.gdprConsent.consentString) - } - if (bidderRequest.uspConsent) { - utils.deepSetValue(sovrnBidReq, 'regs.ext.us_privacy', bidderRequest.uspConsent); - } - - if (eids) { - utils.deepSetValue(sovrnBidReq, 'user.ext.eids', eids) - utils.deepSetValue(sovrnBidReq, 'user.ext.tpid', tpid) - if (criteoId) { - utils.deepSetValue(sovrnBidReq, 'user.ext.prebid_criteoid', criteoId) - } - } - - let url = `https://ap.lijit.com/rtb/bid?src=$$REPO_AND_VERSION$$`; - if (iv) url += `&iv=${iv}`; - - return { - method: 'POST', - url: url, - data: JSON.stringify(sovrnBidReq), - options: {contentType: 'text/plain'} - } - } catch (e) { - utils.logError('Could not build bidrequest, error deatils:', e); - } - }, - - /** - * Format Sovrn responses as Prebid bid responses - * @param {id, seatbid} sovrnResponse A successful response from Sovrn. - * @return {Bid[]} An array of formatted bids. - */ - interpretResponse: function({ body: {id, seatbid} }) { - try { - let sovrnBidResponses = []; - if (id && - seatbid && - seatbid.length > 0 && - seatbid[0].bid && - seatbid[0].bid.length > 0) { - seatbid[0].bid.map(sovrnBid => { - sovrnBidResponses.push({ - requestId: sovrnBid.impid, - cpm: parseFloat(sovrnBid.price), - width: parseInt(sovrnBid.w), - height: parseInt(sovrnBid.h), - creativeId: sovrnBid.crid || sovrnBid.id, - dealId: sovrnBid.dealid || null, - currency: 'USD', - netRevenue: true, - mediaType: BANNER, - ad: decodeURIComponent(`${sovrnBid.adm}`), - ttl: sovrnBid.ext ? (sovrnBid.ext.ttl || 90) : 90, - meta: { advertiserDomains: sovrnBid && sovrnBid.adomain ? sovrnBid.adomain : [] } - }); - }); - } - return sovrnBidResponses - } catch (e) { - utils.logError('Could not intrepret bidresponse, error deatils:', e); - } - }, - - getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) { - try { - const tracks = [] - if (serverResponses && serverResponses.length !== 0) { - if (syncOptions.iframeEnabled) { - const iidArr = serverResponses.filter(resp => utils.deepAccess(resp, 'body.ext.iid')) - .map(resp => resp.body.ext.iid); - const params = []; - if (gdprConsent && gdprConsent.gdprApplies && typeof gdprConsent.consentString === 'string') { - params.push(['gdpr_consent', gdprConsent.consentString]); - } - if (uspConsent) { - params.push(['us_privacy', uspConsent]); - } - - if (iidArr[0]) { - params.push(['informer', iidArr[0]]); - tracks.push({ - type: 'iframe', - url: 'https://ap.lijit.com/beacon?' + params.map(p => p.join('=')).join('&') - }); - } - } - - if (syncOptions.pixelEnabled) { - serverResponses.filter(resp => utils.deepAccess(resp, 'body.ext.sync.pixels')) - .reduce((acc, resp) => acc.concat(resp.body.ext.sync.pixels), []) - .map(pixel => pixel.url) - .forEach(url => tracks.push({ type: 'image', url })) - } - } - return tracks - } catch (e) { - return [] - } - }, -} - -registerBidder(spec); diff --git a/modules/sovrnBidAdapter.md b/modules/sovrnBidAdapter.md deleted file mode 100644 index 2b5d21d5515..00000000000 --- a/modules/sovrnBidAdapter.md +++ /dev/null @@ -1,47 +0,0 @@ -# Overview - -``` -Module Name: Sovrn Bid Adapter -Module Type: Bidder Adapter -Maintainer: jrosendahl@sovrn.com -``` - -# Description - -Sovrn's adapter integration to the Prebid library. Posts plain-text JSON to the /rtb/bid endpoint. - -# Test Parameters - -``` -var adUnits = [ - { - code: 'test-leaderboard', - sizes: [[728, 90]], - bids: [{ - bidder: 'sovrn', - params: { - tagid: '403370', - bidfloor: 0.01 - } - }] - }, { - code: 'test-banner', - sizes: [[300, 250]], - bids: [{ - bidder: 'sovrn', - params: { - tagid: '403401' - } - }] - }, { - code: 'test-sidebar', - size: [[160, 600]], - bids: [{ - bidder: 'sovrn', - params: { - tagid: '531000' - } - }] - } -] -``` diff --git a/modules/spotxBidAdapter.js b/modules/spotxBidAdapter.js deleted file mode 100644 index b60d25db4d6..00000000000 --- a/modules/spotxBidAdapter.js +++ /dev/null @@ -1,507 +0,0 @@ -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; -import { Renderer } from '../src/Renderer.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { VIDEO } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'spotx'; -const URL = 'https://search.spotxchange.com/openrtb/2.3/dados/'; -const ORTB_VERSION = '2.3'; -export const GOOGLE_CONSENT = { consented_providers: ['3', '7', '11', '12', '15', '20', '22', '35', '43', '46', '48', '55', '57', '61', '62', '66', '70', '80', '83', '85', '86', '89', '93', '108', '122', '124', '125', '126', '131', '134', '135', '136', '143', '144', '147', '149', '153', '154', '159', '161', '162', '165', '167', '171', '178', '184', '188', '192', '195', '196', '202', '209', '211', '218', '221', '228', '229', '230', '236', '239', '241', '253', '255', '259', '266', '271', '272', '274', '286', '291', '294', '303', '308', '310', '311', '313', '314', '316', '317', '322', '323', '327', '336', '338', '340', '348', '350', '358', '359', '363', '367', '370', '371', '384', '385', '389', '393', '394', '397', '398', '407', '414', '415', '424', '429', '430', '432', '436', '438', '440', '442', '443', '445', '448', '449', '453', '459', '479', '482', '486', '491', '492', '494', '495', '503', '505', '510', '522', '523', '528', '537', '540', '550', '559', '560', '568', '571', '574', '575', '576', '584', '585', '587', '588', '590', '591', '592', '595', '609', '621', '624', '723', '725', '733', '737', '776', '780', '782', '787', '797', '798', '802', '803', '814', '817', '820', '821', '827', '829', '839', '853', '864', '867', '874', '899', '904', '922', '926', '931', '932', '933', '938', '955', '973', '976', '979', '981', '985', '987', '991', '1003', '1024', '1025', '1027', '1028', '1029', '1033', '1034', '1040', '1047', '1048', '1051', '1052', '1053', '1054', '1062', '1063', '1067', '1072', '1085', '1092', '1095', '1097', '1099', '1100', '1107', '1126', '1127', '1143', '1149', '1152', '1162', '1166', '1167', '1170', '1171', '1172', '1188', '1192', '1199', '1201', '1204', '1205', '1211', '1212', '1215', '1220', '1225', '1226', '1227', '1230', '1232', '1236', '1241', '1248', '1250', '1252', '1268', '1275', '1276', '1284', '1286', '1298', '1301', '1307', '1312', '1313', '1317', '1329', '1336', '1344', '1345', '1356', '1362', '1365', '1375', '1403', '1409', '1411', '1415', '1416', '1419', '1423', '1440', '1442', '1449', '1451', '1455', '1456', '1468', '1496', '1503', '1509', '1512', '1514', '1517', '1520', '1525', '1540', '1547', '1548', '1555', '1558', '1570', '1575', '1577', '1579', '1583', '1584', '1591', '1598', '1603', '1608', '1613', '1616', '1626', '1631', '1633', '1638', '1642', '1648', '1651', '1652', '1653', '1660', '1665', '1667', '1669', '1671', '1674', '1677', '1678', '1682', '1684', '1697', '1703', '1705', '1716', '1720', '1721', '1722', '1725', '1732', '1733', '1735', '1739', '1741', '1745', '1750', '1753', '1760', '1765', '1769', '1776', '1780', '1782', '1786', '1791', '1794', '1799', '1800', '1801', '1810', '1827', '1831', '1832', '1834', '1837', '1840', '1843', '1844', '1845', '1858', '1859', '1863', '1866', '1870', '1872', '1875', '1878', '1880', '1882', '1883', '1889', '1892', '1896', '1898', '1899', '1902', '1905', '1911', '1922', '1928', '1929', '1934', '1942', '1943', '1944', '1945', '1958', '1960', '1962', '1963', '1964', '1967', '1968', '1978', '1985', '1986', '1987', '1998', '2003', '2007', '2012', '2013', '2027', '2035', '2038', '2039', '2044', '2047', '2052', '2056', '2059', '2062', '2064', '2068', '2070', '2072', '2078', '2079', '2084', '2088', '2090', '2095', '2100', '2103', '2107', '2109', '2113', '2115', '2121', '2127', '2130', '2133', '2137', '2140', '2141', '2145', '2147', '2150', '2156', '2166', '2170', '2171', '2176', '2177', '2179', '2183', '2186', '2192', '2198', '2202', '2205', '2214', '2216', '2219', '2220', '2222', '2223', '2224', '2225', '2227', '2228', '2234', '2238', '2247', '2251', '2253', '2262', '2264', '2271', '2276', '2278', '2279', '2282', '2290', '2292', '2295', '2299', '2305', '2306', '2310', '2311', '2312', '2315', '2320', '2325', '2328', '2331', '2334', '2335', '2336', '2337', '2343', '2346', '2354', '2357', '2358', '2359', '2366', '2370', '2373', '2376', '2377', '2380', '2382', '2387', '2389', '2392', '2394', '2400', '2403', '2405', '2406', '2407', '2410', '2411', '2413', '2414', '2415', '2416', '2418', '2422', '2425', '2427', '2435', '2437', '2440', '2441', '2447', '2453', '2459', '2461', '2462', '2464', '2467', '2468', '2472', '2477', '2481', '2484', '2486', '2492', '2493', '2496', '2497', '2498', '2499', '2504', '2506', '2510', '2511', '2512', '2517', '2526', '2527', '2531', '2532', '2534', '2542', '2544', '2552', '2555', '2559', '2563', '2564', '2567', '2568', '2569', '2571', '2572', '2573', '2575', '2577', '2579', '2583', '2584', '2586', '2589', '2595', '2596', '2597', '2601', '2604', '2605', '2609', '2610', '2612', '2614', '2621', '2622', '2624', '2628', '2629', '2632', '2634', '2636', '2639', '2643', '2645', '2646', '2647', '2649', '2650', '2651', '2652', '2656', '2657', '2658', '2660', '2661', '2662', '2663', '2664', '2669', '2670', '2673', '2676', '2677', '2678', '2681', '2682', '2684', '2685', '2686', '2689', '2690', '2691', '2695', '2698', '2699', '2702', '2704', '2705', '2706', '2707', '2709', '2710', '2713', '2714', '2727', '2729', '2739', '2758', '2765', '2766', '2767', '2768', '2770', '2771', '2772', '2776', '2777', '2778', '2779', '2780', '2783', '2784', '2786', '2787', '2791', '2792', '2793', '2797', '2798', '2801', '2802', '2803', '2805', '2808', '2809', '2810', '2811', '2812', '2813', '2814', '2817', '2818', '2824', '2826', '2827', '2829', '2830', '2831', '2832', '2834', '2836', '2838', '2840', '2842', '2843', '2844', '2850', '2851', '2852', '2854', '2858', '2860', '2862', '2864', '2865', '2866', '2867', '2868', '2869', '2871'] }; - -export const spec = { - code: BIDDER_CODE, - gvlid: 165, - aliases: ['spotx'], - supportedMediaTypes: [VIDEO], - - /** - * Determines whether or not the given bid request is valid. - * From Prebid.js: isBidRequestValid - Verify the the AdUnits.bids, respond with true (valid) or false (invalid). - * - * @param {object} bid The bid to validate. - * @return {boolean} True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - if (bid && typeof bid.params !== 'object') { - utils.logError(BIDDER_CODE + ': params is not defined or is incorrect in the bidder settings.'); - return false; - } - - if (!utils.deepAccess(bid, 'mediaTypes.video')) { - utils.logError(BIDDER_CODE + ': mediaTypes.video is not present in the bidder settings.'); - return false; - } - - const playerSize = utils.deepAccess(bid, 'mediaTypes.video.playerSize'); - if (!playerSize || !utils.isArray(playerSize)) { - utils.logError(BIDDER_CODE + ': mediaTypes.video.playerSize is not defined in the bidder settings.'); - return false; - } - - if (!utils.getBidIdParameter('channel_id', bid.params)) { - utils.logError(BIDDER_CODE + ': channel_id is not present in bidder params'); - return false; - } - - if (utils.deepAccess(bid, 'mediaTypes.video.context') == 'outstream' || utils.deepAccess(bid, 'params.ad_unit') == 'outstream') { - if (!utils.getBidIdParameter('outstream_function', bid.params)) { - if (!utils.getBidIdParameter('outstream_options', bid.params)) { - utils.logError(BIDDER_CODE + ': please define outstream_options parameter or override the default SpotX outstream rendering by defining your own Outstream function using field outstream_function.'); - return false; - } - if (!utils.getBidIdParameter('slot', bid.params.outstream_options)) { - utils.logError(BIDDER_CODE + ': please define parameter slot in outstream_options object in the configuration.'); - return false; - } - } - } - - return true; - }, - - /** - * Make a server request from the list of BidRequests. - * from Prebid.js: buildRequests - Takes an array of valid bid requests, all of which are guaranteed to have passed the isBidRequestValid() test. - * - * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server. - * @param {object} bidderRequest - The master bidRequest object. - * @return {ServerRequest} Info describing the request to the server. - */ - buildRequests: function(bidRequests, bidderRequest) { - const referer = bidderRequest.refererInfo.referer; - const isPageSecure = !!referer.match(/^https:/); - - const siteId = ''; - const spotxRequests = bidRequests.map(function(bid) { - let page; - if (utils.getBidIdParameter('page', bid.params)) { - page = utils.getBidIdParameter('page', bid.params); - } else if (config.getConfig('pageUrl')) { - page = config.getConfig('pageUrl'); - } else { - page = referer; - } - - const channelId = utils.getBidIdParameter('channel_id', bid.params); - let pubcid = null; - - const playerSize = utils.deepAccess(bid, 'mediaTypes.video.playerSize'); - const contentWidth = playerSize[0][0]; - const contentHeight = playerSize[0][1]; - - const secure = isPageSecure || (utils.getBidIdParameter('secure', bid.params) ? 1 : 0); - - const ext = { - sdk_name: 'Prebid 1+', - versionOrtb: ORTB_VERSION - }; - - if (utils.getBidIdParameter('hide_skin', bid.params) != '') { - ext.hide_skin = +!!utils.getBidIdParameter('hide_skin', bid.params); - } - - if (utils.getBidIdParameter('ad_volume', bid.params) != '') { - ext.ad_volume = utils.getBidIdParameter('ad_volume', bid.params); - } - - if (utils.getBidIdParameter('ad_unit', bid.params) != '') { - ext.ad_unit = utils.getBidIdParameter('ad_unit', bid.params); - } - - if (utils.getBidIdParameter('outstream_options', bid.params) != '') { - ext.outstream_options = utils.getBidIdParameter('outstream_options', bid.params); - } - - if (utils.getBidIdParameter('outstream_function', bid.params) != '') { - ext.outstream_function = utils.getBidIdParameter('outstream_function', bid.params); - } - - if (utils.getBidIdParameter('custom', bid.params) != '') { - ext.custom = utils.getBidIdParameter('custom', bid.params); - } - - if (utils.getBidIdParameter('pre_market_bids', bid.params) != '' && utils.isArray(utils.getBidIdParameter('pre_market_bids', bid.params))) { - const preMarketBids = utils.getBidIdParameter('pre_market_bids', bid.params); - ext.pre_market_bids = []; - for (let i in preMarketBids) { - const preMarketBid = preMarketBids[i]; - let vastStr = ''; - if (preMarketBid['vast_url']) { - vastStr = '' + preMarketBid['vast_url'] + ''; - } else if (preMarketBid['vast_string']) { - vastStr = preMarketBid['vast_string']; - } - ext.pre_market_bids.push({ - id: preMarketBid['deal_id'], - seatbid: [{ - bid: [{ - impid: Date.now(), - dealid: preMarketBid['deal_id'], - price: preMarketBid['price'], - adm: vastStr - }] - }], - cur: preMarketBid['currency'], - ext: { - event_log: [{}] - } - }); - } - } - - const mimes = utils.getBidIdParameter('mimes', bid.params) || ['application/javascript', 'video/mp4', 'video/webm']; - - const spotxReq = { - id: bid.bidId, - secure: secure, - video: { - w: contentWidth, - h: contentHeight, - ext: ext, - mimes: mimes - } - }; - - if (utils.getBidIdParameter('price_floor', bid.params) != '') { - spotxReq.bidfloor = utils.getBidIdParameter('price_floor', bid.params); - } - - if (utils.getBidIdParameter('start_delay', bid.params) != '') { - spotxReq.video.startdelay = 0 + Boolean(utils.getBidIdParameter('start_delay', bid.params)); - } - - if (utils.getBidIdParameter('min_duration', bid.params) != '') { - spotxReq.video.minduration = utils.getBidIdParameter('min_duration', bid.params); - } - - if (utils.getBidIdParameter('max_duration', bid.params) != '') { - spotxReq.video.maxduration = utils.getBidIdParameter('max_duration', bid.params); - } - - if (utils.getBidIdParameter('placement_type', bid.params) != '') { - spotxReq.video.ext.placement = utils.getBidIdParameter('placement_type', bid.params); - } - - if (utils.getBidIdParameter('position', bid.params) != '') { - spotxReq.video.ext.pos = utils.getBidIdParameter('position', bid.params); - } - - if (bid.crumbs && bid.crumbs.pubcid) { - pubcid = bid.crumbs.pubcid; - } - - const language = navigator.language ? 'language' : 'userLanguage'; - const device = { - h: screen.height, - w: screen.width, - dnt: utils.getDNT() ? 1 : 0, - language: navigator[language].split('-')[0], - make: navigator.vendor ? navigator.vendor : '', - ua: navigator.userAgent - }; - - const requestPayload = { - id: channelId, - imp: spotxReq, - site: { - id: siteId, - page: page, - content: 'content', - }, - device: device, - ext: { - wrap_response: 1 - } - }; - - // If the publisher asks to ignore the bidder cache key we need to return the full vast xml - // so that it can be cached on the publishes specified server. - if (!!config.getConfig('cache') && !!config.getConfig('cache.url') && (config.getConfig('cache.ignoreBidderCacheKey') === true)) { - requestPayload['ext']['wrap_response'] = 0; - } - - if (utils.getBidIdParameter('number_of_ads', bid.params)) { - requestPayload['ext']['number_of_ads'] = utils.getBidIdParameter('number_of_ads', bid.params); - } - - const userExt = {}; - - if (utils.getBidIdParameter('spotx_all_google_consent', bid.params) == 1) { - userExt['consented_providers_settings'] = GOOGLE_CONSENT; - } - - // Add GDPR flag and consent string - if (bidderRequest && bidderRequest.gdprConsent) { - userExt.consent = bidderRequest.gdprConsent.consentString; - - if (typeof bidderRequest.gdprConsent.gdprApplies !== 'undefined') { - utils.deepSetValue(requestPayload, 'regs.ext.gdpr', (bidderRequest.gdprConsent.gdprApplies ? 1 : 0)); - } - } - - if (bidderRequest && bidderRequest.uspConsent) { - utils.deepSetValue(requestPayload, 'regs.ext.us_privacy', bidderRequest.uspConsent); - } - - // ID5 fied - if (utils.deepAccess(bid, 'userId.id5id.uid')) { - userExt.eids = userExt.eids || []; - userExt.eids.push( - { - source: 'id5-sync.com', - uids: [{ - id: bid.userId.id5id.uid, - ext: bid.userId.id5id.ext || {} - }] - } - ) - } - - // Add common id if available - if (pubcid) { - userExt.fpc = pubcid; - } - - // Add schain object if it is present - if (bid && bid.schain) { - requestPayload['source'] = { - ext: { - schain: bid.schain - } - }; - } - - if (bid && bid.userId && bid.userId.tdid) { - userExt.eids = userExt.eids || []; - userExt.eids.push( - { - source: 'adserver.org', - uids: [{ - id: bid.userId.tdid, - ext: { - rtiPartner: 'TDID' - } - }] - } - ) - } - - // Only add the user object if it's not empty - if (!utils.isEmpty(userExt)) { - requestPayload.user = { ext: userExt }; - } - const urlQueryParams = 'src_sys=prebid' - return { - method: 'POST', - url: URL + channelId + '?' + urlQueryParams, - data: requestPayload, - bidRequest: bidderRequest - }; - }); - - return spotxRequests; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse, bidderRequest) { - const bidResponses = []; - const serverResponseBody = serverResponse.body; - - if (serverResponseBody && utils.isArray(serverResponseBody.seatbid)) { - utils._each(serverResponseBody.seatbid, function(bids) { - utils._each(bids.bid, function(spotxBid) { - let currentBidRequest = {}; - for (let i in bidderRequest.bidRequest.bids) { - if (spotxBid.impid == bidderRequest.bidRequest.bids[i].bidId) { - currentBidRequest = bidderRequest.bidRequest.bids[i]; - } - } - - /** - * Make sure currency and price are the right ones - * TODO: what about the pre_market_bid partners sizes? - */ - utils._each(currentBidRequest.params.pre_market_bids, function(pmb) { - if (pmb.deal_id == spotxBid.id) { - spotxBid.price = pmb.price; - serverResponseBody.cur = pmb.currency; - } - }); - - const bid = { - requestId: currentBidRequest.bidId, - currency: serverResponseBody.cur || 'USD', - cpm: spotxBid.price, - creativeId: spotxBid.crid || '', - dealId: spotxBid.dealid || '', - ttl: 360, - netRevenue: true, - channel_id: serverResponseBody.id, - mediaType: VIDEO, - width: spotxBid.w, - height: spotxBid.h - }; - - if (!!config.getConfig('cache') && !!config.getConfig('cache.url') && (config.getConfig('cache.ignoreBidderCacheKey') === true)) { - bid.vastXml = spotxBid.adm; - } else { - bid.cache_key = spotxBid.ext.cache_key; - bid.vastUrl = 'https://search.spotxchange.com/ad/vast.html?key=' + spotxBid.ext.cache_key - bid.videoCacheKey = spotxBid.ext.cache_key; - } - - bid.meta = bid.meta || {}; - if (spotxBid && spotxBid.adomain && spotxBid.adomain.length > 0) { - bid.meta.advertiserDomains = spotxBid.adomain; - } - - const context1 = utils.deepAccess(currentBidRequest, 'mediaTypes.video.context'); - const context2 = utils.deepAccess(currentBidRequest, 'params.ad_unit'); - if (context1 == 'outstream' || context2 == 'outstream') { - const playersize = utils.deepAccess(currentBidRequest, 'mediaTypes.video.playerSize'); - const renderer = Renderer.install({ - id: 0, - url: '/', - config: { - adText: 'SpotX Outstream Video Ad via Prebid.js', - player_width: playersize[0][0], - player_height: playersize[0][1], - content_page_url: utils.deepAccess(bidderRequest, 'data.site.page'), - ad_mute: +!!utils.deepAccess(currentBidRequest, 'params.ad_mute'), - hide_skin: +!!utils.deepAccess(currentBidRequest, 'params.hide_skin'), - outstream_options: utils.deepAccess(currentBidRequest, 'params.outstream_options'), - outstream_function: utils.deepAccess(currentBidRequest, 'params.outstream_function') - } - }); - - try { - renderer.setRender(outstreamRender); - renderer.setEventHandlers({ - impression: function impression() { - return utils.logMessage('SpotX outstream video impression event'); - }, - loaded: function loaded() { - return utils.logMessage('SpotX outstream video loaded event'); - }, - ended: function ended() { - utils.logMessage('SpotX outstream renderer video event'); - } - }); - } catch (err) { - utils.logWarn('Prebid Error calling setRender or setEventHandlers on renderer', err); - } - bid.renderer = renderer; - } - - bidResponses.push(bid); - }) - }); - } - - return bidResponses; - } -} - -function createOutstreamScript(bid) { - const slot = utils.getBidIdParameter('slot', bid.renderer.config.outstream_options); - utils.logMessage('[SPOTX][renderer] Handle SpotX outstream renderer'); - const script = window.document.createElement('script'); - script.type = 'text/javascript'; - script.src = 'https://js.spotx.tv/easi/v1/' + bid.channel_id + '.js'; - let dataSpotXParams = {}; - dataSpotXParams['data-spotx_channel_id'] = '' + bid.channel_id; - dataSpotXParams['data-spotx_vast_url'] = '' + bid.vastUrl; - dataSpotXParams['data-spotx_content_page_url'] = bid.renderer.config.content_page_url; - dataSpotXParams['data-spotx_ad_unit'] = 'incontent'; - - utils.logMessage('[SPOTX][renderer] Default behavior'); - if (utils.getBidIdParameter('ad_mute', bid.renderer.config.outstream_options)) { - dataSpotXParams['data-spotx_ad_mute'] = '1'; - } - dataSpotXParams['data-spotx_collapse'] = '0'; - dataSpotXParams['data-spotx_autoplay'] = '1'; - dataSpotXParams['data-spotx_blocked_autoplay_override_mode'] = '1'; - dataSpotXParams['data-spotx_video_slot_can_autoplay'] = '1'; - - const playersizeAutoAdapt = utils.getBidIdParameter('playersize_auto_adapt', bid.renderer.config.outstream_options); - if (playersizeAutoAdapt && utils.isBoolean(playersizeAutoAdapt) && playersizeAutoAdapt === true) { - const ratio = bid.width && utils.isNumber(bid.width) && bid.height && utils.isNumber(bid.height) ? bid.width / bid.height : 4 / 3; - const slotClientWidth = window.document.getElementById(slot).clientWidth; - let playerWidth = bid.renderer.config.player_width; - let playerHeight = bid.renderer.config.player_height; - let contentWidth = 0; - let contentHeight = 0; - if (slotClientWidth < playerWidth) { - playerWidth = slotClientWidth; - playerHeight = playerWidth / ratio; - } - if (ratio <= 1) { - contentWidth = Math.round(playerHeight * ratio); - contentHeight = playerHeight; - } else { - contentWidth = playerWidth; - contentHeight = Math.round(playerWidth / ratio); - } - - dataSpotXParams['data-spotx_content_width'] = '' + contentWidth; - dataSpotXParams['data-spotx_content_height'] = '' + contentHeight; - } - - const customOverride = utils.getBidIdParameter('custom_override', bid.renderer.config.outstream_options); - if (customOverride && utils.isPlainObject(customOverride)) { - utils.logMessage('[SPOTX][renderer] Custom behavior.'); - for (let name in customOverride) { - if (customOverride.hasOwnProperty(name)) { - if (name === 'channel_id' || name === 'vast_url' || name === 'content_page_url' || name === 'ad_unit') { - utils.logWarn('[SPOTX][renderer] Custom behavior: following option cannot be overridden: ' + name); - } else { - dataSpotXParams['data-spotx_' + name] = customOverride[name]; - } - } - } - } - - for (let key in dataSpotXParams) { - if (dataSpotXParams.hasOwnProperty(key)) { - script.setAttribute(key, dataSpotXParams[key]); - } - } - - return script; -} - -function outstreamRender(bid) { - const script = createOutstreamScript(bid); - if (bid.renderer.config.outstream_function != null && typeof bid.renderer.config.outstream_function === 'function') { - bid.renderer.config.outstream_function(bid, script); - } else { - try { - const inIframe = utils.getBidIdParameter('in_iframe', bid.renderer.config.outstream_options); - if (inIframe && window.document.getElementById(inIframe).nodeName == 'IFRAME') { - const rawframe = window.document.getElementById(inIframe); - let framedoc = rawframe.contentDocument; - if (!framedoc && rawframe.contentWindow) { - framedoc = rawframe.contentWindow.document; - } - framedoc.body.appendChild(script); - } else { - const slot = utils.getBidIdParameter('slot', bid.renderer.config.outstream_options); - if (slot && window.document.getElementById(slot)) { - window.document.getElementById(slot).appendChild(script); - } else { - window.document.getElementsByTagName('head')[0].appendChild(script); - } - } - } catch (err) { - utils.logError('[SPOTX][renderer] Error:' + err.message) - } - } -} - -registerBidder(spec); diff --git a/modules/spotxBidAdapter.md b/modules/spotxBidAdapter.md deleted file mode 100644 index 0bd1cf71aa1..00000000000 --- a/modules/spotxBidAdapter.md +++ /dev/null @@ -1,136 +0,0 @@ -# Overview - -``` -Module Name: SpotX Bidder Adapter -Module Type: Bidder Adapter -Maintainer: teameighties@spotx.tv -``` - -# Description - -Connect to SpotX for bids. - -This adapter requires setup and approval from the SpotX team. - -# Test Parameters - Use case #1 - outstream with default rendering options -``` - var adUnits = [{ - code: 'something', - mediaTypes: { - video: { - context: 'outstream', // 'instream' or 'outstream' - playerSize: [640, 480] - } - }, - bids: [{ - bidder: 'spotx', - params: { - channel_id: 85394, - ad_unit: 'outstream', - outstream_options: { // Needed for the default outstream renderer - fields video_slot/content_width/content_height are mandatory - slot: 'adSlot1', - content_width: 300, - content_height: 250 - } - } - }] - }]; -``` - -# Test Parameters - Use case #2 - outstream with default rendering options + some other options -``` - var adUnits = [{ - code: 'something', - mediaTypes: { - video: { - context: 'outstream', // 'instream' or 'outstream' - playerSize: [640, 480] - } - }, - bids: [{ - bidder: 'spotx', - params: { - channel_id: 85394, - ad_unit: 'outstream', - outstream_options: { - slot: 'adSlot1', - custom_override: { // This option is not mandatory though used to override default renderer parameters using EASI player options in here: https://developer.spotxchange.com/content/local/docs/sdkDocs/EASI/README.md - content_width: 300, - content_height: 250, - collapse: '1', - hide_fullscreen: '1', - unmute_on_mouse: '1', - continue_out_of_view: '1', - ad_volume: '100', - content_container_id: 'video1', - hide_skin: '1', - spotx_all_google_consent: '1' - } - } - } - }] - }]; -``` - -# Test Parameters - Use case #3 - outstream with your own outstream redering function -``` - var adUnits = [{ - code: 'something', - mediaTypes: { - video: { - context: 'outstream', // 'instream' or 'outstream' - playerSize: [640, 480] - } - }, - bids: [{ - bidder: 'spotx', - params: { - channel_id: 79391, - ad_unit: 'outstream', - outstream_function: myOutstreamFunction // Override the default outstream renderer by this referenced function - } - }] - }]; -``` - -# Sample of a custom outstream rendering function -``` -function myOutstreamFunction(bid) { - const videoDiv = 'video1'; - const playerWidth = 300; - const playerHeight = 250; - - window.console.log('[SPOTX][renderer] Handle SpotX custom outstream renderer'); - let script = window.document.createElement('script'); - script.type = 'text/javascript'; - script.src = '//js.spotx.tv/easi/v1/' + bid.channel_id + '.js'; - script.setAttribute('data-spotx_channel_id', '' + bid.channel_id); - script.setAttribute('data-spotx_vast_url', '' + bid.vastUrl); - script.setAttribute('data-spotx_content_width', playerWidth); - script.setAttribute('data-spotx_content_height', playerHeight); - script.setAttribute('data-spotx_content_page_url', bid.renderer.config.content_page_url); - if (bid.renderer.config.ad_mute) { - script.setAttribute('data-spotx_ad_mute', '0'); - } - script.setAttribute('data-spotx_ad_unit', 'incontent'); - script.setAttribute('data-spotx_collapse', '0'); - script.setAttribute('data-spotx_hide_fullscreen', '1'); - script.setAttribute('data-spotx_autoplay', '1'); - script.setAttribute('data-spotx_blocked_autoplay_override_mode', '1'); - script.setAttribute('data-spotx_video_slot_can_autoplay', '1'); - script.setAttribute('data-spotx_unmute_on_mouse', '1'); - script.setAttribute('data-spotx_click_to_replay', '1'); - script.setAttribute('data-spotx_continue_out_of_view', '1'); - script.setAttribute('data-spotx_ad_volume', '100'); - if (bid.renderer.config.inIframe && window.document.getElementById(bid.renderer.config.inIframe).nodeName == 'IFRAME') { - let rawframe = window.document.getElementById(bid.renderer.config.inIframe); - let framedoc = rawframe.contentDocument; - if (!framedoc && rawframe.contentWindow) { - framedoc = rawframe.contentWindow.document; - } - framedoc.body.appendChild(script); - } else { - window.document.getElementById(videoDiv).appendChild(script); - } -}; -``` diff --git a/modules/sspBCBidAdapter.js b/modules/sspBCBidAdapter.js deleted file mode 100644 index 391f3a05721..00000000000 --- a/modules/sspBCBidAdapter.js +++ /dev/null @@ -1,419 +0,0 @@ -import * as utils from '../src/utils.js'; -import { ajax } from '../src/ajax.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; -import strIncludes from 'core-js-pure/features/string/includes.js'; - -const BIDDER_CODE = 'sspBC'; -const BIDDER_URL = 'https://ssp.wp.pl/bidder/'; -const SYNC_URL = 'https://ssp.wp.pl/bidder/usersync'; -const NOTIFY_URL = 'https://ssp.wp.pl/bidder/notify'; -const TMAX = 450; -const BIDDER_VERSION = '4.8'; -const W = window; -const { navigator } = W; -const oneCodeDetection = {}; -var consentApiVersion; - -/** - * Get bid parameters for notification - * @param {*} bidData - bid (bidWon), or array of bids (timeout) - */ -const getNotificationPayload = bidData => { - if (bidData) { - const bids = utils.isArray(bidData) ? bidData : [bidData]; - if (bids.length > 0) { - const result = { - requestId: undefined, - siteId: [], - adUnit: [], - slotId: [], - } - bids.forEach(bid => { - let params = utils.isArray(bid.params) ? bid.params[0] : bid.params; - params = params || {}; - - // check for stored detection - if (oneCodeDetection[bid.requestId]) { - params.siteId = oneCodeDetection[bid.requestId][0]; - params.id = oneCodeDetection[bid.requestId][1]; - } - - if (params.siteId) { - result.siteId.push(params.siteId); - } - if (params.id) { - result.slotId.push(params.id); - } - if (bid.cpm) { - const meta = bid.meta || {}; - result.cpm = bid.cpm; - result.creativeId = bid.creativeId; - result.adomain = meta.advertiserDomains && meta.advertiserDomains[0]; - result.networkName = meta.networkName; - } - result.adUnit.push(bid.adUnitCode) - result.requestId = bid.auctionId || result.requestId; - result.timeout = bid.timeout || result.timeout; - }) - return result; - } - } -} - -const cookieSupport = () => { - const isSafari = /^((?!chrome|android|crios|fxios).)*safari/i.test(navigator.userAgent); - const useCookies = navigator.cookieEnabled || !!document.cookie.length; - - return !isSafari && useCookies; -}; - -const applyClientHints = ortbRequest => { - const connection = navigator.connection || false; - const viewport = W.visualViewport || false; - const segments = []; - const hints = { - 'CH-Ect': connection.effectiveType, - 'CH-Rtt': connection.rtt, - 'CH-SaveData': connection.saveData, - 'CH-Downlink': connection.downlink, - 'CH-DeviceMemory': navigator.deviceMemory, - 'CH-Dpr': W.devicePixelRatio, - 'CH-ViewportWidth': viewport.width, - }; - - Object.keys(hints).forEach(key => { - const hint = hints[key]; - - if (hint) { - segments.push({ - name: key, - value: hint.toString(), - }); - } - }); - const data = [ - { - id: '12', - name: 'NetInfo', - segment: segments, - }]; - - ortbRequest.user = Object.assign(ortbRequest.user, { data }); -}; - -function applyGdpr(bidderRequest, ortbRequest) { - if (bidderRequest && bidderRequest.gdprConsent) { - consentApiVersion = bidderRequest.gdprConsent.apiVersion; - ortbRequest.regs = Object.assign(ortbRequest.regs, { '[ortb_extensions.gdpr]': bidderRequest.gdprConsent.gdprApplies ? 1 : 0 }); - ortbRequest.user = Object.assign(ortbRequest.user, { '[ortb_extensions.consent]': bidderRequest.gdprConsent.consentString }); - } -} - -function setOnAny(collection, key) { - for (let i = 0, result; i < collection.length; i++) { - result = utils.deepAccess(collection[i], key); - - if (result) { - return result; - } - } -} - -function sendNotification(payload) { - ajax(NOTIFY_URL, null, JSON.stringify(payload), { - withCredentials: false, - method: 'POST', - crossOrigin: true - }); -} - -/** - * @param {object} slot Ad Unit Params by Prebid - * @returns {object} Banner by OpenRTB 2.5 §3.2.6 - */ -function mapBanner(slot) { - if (slot.mediaType === 'banner' || - utils.deepAccess(slot, 'mediaTypes.banner') || - (!slot.mediaType && !slot.mediaTypes)) { - const format = slot.sizes.map(size => ({ - w: size[0], - h: size[1], - })); - - // override - tylko 1szy wymiar - // format = format.slice(0, 1); - return { - format, - id: slot.bidId, - }; - } -} - -function mapImpression(slot) { - const { adUnitCode, bidId, params } = slot; - const { id, siteId } = params || {}; - const imp = { - id: id && siteId ? id : 'bidid-' + bidId, - banner: mapBanner(slot), - /* native: mapNative(slot), */ - tagid: adUnitCode, - }; - - const bidfloor = (slot.params && slot.params.bidFloor) ? parseFloat(slot.params.bidFloor) : undefined; - - if (bidfloor) { - imp.bidfloor = bidfloor; - } - - return imp; -} - -function renderCreative(site, auctionId, bid, seat, request) { - let gam; - - const mcad = { - id: auctionId, - seat, - seatbid: [{ - bid: [bid], - }], - }; - - const mcbase = btoa(encodeURI(JSON.stringify(mcad))); - - if (bid.adm) { - // parse adm for gam config - try { - gam = JSON.parse(bid.adm).gam; - - if (!gam || !Object.keys(gam).length) { - gam = undefined; - } else { - gam.namedSizes = ['fluid']; - gam.div = 'div-gpt-ad-x01'; - gam.targeting = Object.assign(gam.targeting || {}, { - OAS_retarg: '0', - PREBID_ON: '1', - emptygaf: '0', - }); - } - - if (gam && !gam.targeting) { - gam.targeting = {}; - } - } catch (err) { - utils.logWarn('Could not parse adm data', bid.adm); - } - } - - let adcode = ` - - - - - - - -
- - - `; - - return adcode; -} - -const spec = { - code: BIDDER_CODE, - aliases: [], - supportedMediaTypes: [BANNER], - isBidRequestValid(bid) { - // as per OneCode integration, bids without params are valid - return true; - }, - buildRequests(validBidRequests, bidderRequest) { - if ((!validBidRequests) || (validBidRequests.length < 1)) { - return false; - } - - const siteId = setOnAny(validBidRequests, 'params.siteId'); - const publisherId = setOnAny(validBidRequests, 'params.publisherId'); - const page = setOnAny(validBidRequests, 'params.page') || bidderRequest.refererInfo.referer; - const domain = setOnAny(validBidRequests, 'params.domain') || utils.parseUrl(page).hostname; - const tmax = setOnAny(validBidRequests, 'params.tmax') ? parseInt(setOnAny(validBidRequests, 'params.tmax'), 10) : TMAX; - const pbver = '$prebid.version$'; - const testMode = setOnAny(validBidRequests, 'params.test') ? 1 : undefined; - - let ref; - - try { - if (W.self === W.top && document.referrer) { ref = document.referrer; } - } catch (e) { - } - - const payload = { - id: bidderRequest.auctionId, - site: { - id: siteId, - publisher: publisherId ? { id: publisherId } : undefined, - page, - domain, - ref - }, - imp: validBidRequests.map(slot => mapImpression(slot)), - tmax, - user: {}, - regs: {}, - test: testMode, - }; - - applyGdpr(bidderRequest, payload); - applyClientHints(payload); - - return { - method: 'POST', - url: BIDDER_URL + '?cs=' + cookieSupport() + '&bdver=' + BIDDER_VERSION + '&pbver=' + pbver + '&inver=0', - data: JSON.stringify(payload), - bidderRequest, - }; - }, - - interpretResponse(serverResponse, request) { - const { bidderRequest } = request; - const response = serverResponse.body; - const bids = []; - const site = JSON.parse(request.data).site; // get page and referer data from request - site.sn = response.sn || 'mc_adapter'; // WPM site name (wp_sn) - let seat; - - if (response.seatbid !== undefined) { - /* - Match response to request, by comparing bid id's - 'bidid-' prefix indicates oneCode (parameterless) request and response - */ - response.seatbid.forEach(seatbid => { - seat = seatbid.seat; - seatbid.bid.forEach(serverBid => { - // get data from bid response - const { adomain, crid, impid, exp, ext, price, w, h } = serverBid; - - const bidRequest = bidderRequest.bids.filter(b => { - const { bidId, params } = b; - const { id, siteId } = params || {}; - const currentBidId = id && siteId ? id : 'bidid-' + bidId; - return currentBidId === impid; - })[0]; - - // get data from linked bidRequest - const { bidId, params } = bidRequest || {}; - - // get slot id for current bid - site.slot = params && params.id; - - if (ext) { - /* - bid response might include ext object containing siteId / slotId, as detected by OneCode - update site / slot data in this case - */ - const { siteid, slotid } = ext; - site.id = siteid || site.id; - site.slot = slotid || site.slot; - } - - if (bidRequest && site.id && !strIncludes(site.id, 'bidid')) { - // found a matching request; add this bid - - // store site data for future notification - oneCodeDetection[bidId] = [site.id, site.slot]; - - const bid = { - requestId: bidId, - creativeId: crid || 'mcad_' + bidderRequest.auctionId + '_' + site.slot, - cpm: price, - currency: response.cur, - ttl: exp || 300, - width: w, - height: h, - bidderCode: BIDDER_CODE, - mediaType: 'banner', - meta: { - advertiserDomains: adomain, - networkName: seat, - }, - netRevenue: true, - ad: renderCreative(site, response.id, serverBid, seat, bidderRequest), - }; - - if (bid.cpm > 0) { - // check bidFloor (if present in params) - const { bidFloor } = params || {}; - - if (!bidFloor || bid.cpm >= bidFloor) { - bids.push(bid); - } else { - utils.logWarn('Discarding bid due to bidFloor setting', bid.cpm, bidFloor); - } - } - } else { - utils.logWarn('Discarding response - no matching request / site id', serverBid.impid); - } - }); - }); - } - - return bids; - }, - getUserSyncs(syncOptions) { - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: SYNC_URL + '?tcf=' + consentApiVersion, - }]; - } - utils.logWarn('sspBC adapter requires iframe based user sync.'); - }, - - onTimeout(timeoutData) { - const payload = getNotificationPayload(timeoutData); - if (payload) { - payload.event = 'timeout'; - sendNotification(payload); - return payload; - } - }, - - onBidWon(bid) { - const payload = getNotificationPayload(bid); - if (payload) { - payload.event = 'bidWon'; - sendNotification(payload); - return payload; - } - }, -}; - -registerBidder(spec); - -export { - spec, -}; diff --git a/modules/sspBCBidAdapter.md b/modules/sspBCBidAdapter.md deleted file mode 100644 index f22e8e6c458..00000000000 --- a/modules/sspBCBidAdapter.md +++ /dev/null @@ -1,47 +0,0 @@ -# Overview - -Module Name: sspBC Bidder Adapter -Module Type: Bidder Adapter -Maintainer: wojciech.bialy@grupawp.pl - -# Description - -Module that connects to Wirtualna Polska Media header bidding endpoint to fetch bids. -Only banner format is supported. -Supported currencies: USD, EUR, PLN - -Required parameters: -- none - -Optional parameters: -- site id -- adslot id -- publisher id -- domain -- page -- tmax -- bidFloor -- test - -# Test Parameters -``` -var adUnits = [ - // Banner adUnit - { - code: 'banner-div', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [{ - bidder: 'sspBC', - params: { - id: "006", - siteId: "235911", - test: 1 - } - }] - } -]; -``` diff --git a/modules/staqAnalyticsAdapter.js b/modules/staqAnalyticsAdapter.js deleted file mode 100644 index 4e3914bccdd..00000000000 --- a/modules/staqAnalyticsAdapter.js +++ /dev/null @@ -1,430 +0,0 @@ -import adapter from '../src/AnalyticsAdapter.js'; -import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager.js'; -import { getRefererInfo } from '../src/refererDetection.js'; -import * as utils from '../src/utils.js'; -import { ajax } from '../src/ajax.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const storageObj = getStorageManager(); - -const ANALYTICS_VERSION = '1.0.0'; -const DEFAULT_QUEUE_TIMEOUT = 4000; -const DEFAULT_HOST = 'tag.staq.com'; - -let staqAdapterRefWin; - -const STAQ_EVENTS = { - AUCTION_INIT: 'auctionInit', - BID_REQUEST: 'bidRequested', - BID_RESPONSE: 'bidResponse', - BID_WON: 'bidWon', - AUCTION_END: 'auctionEnd', - TIMEOUT: 'adapterTimedOut' -} - -function buildRequestTemplate(connId) { - const url = staqAdapterRefWin.referer; - const ref = staqAdapterRefWin.referer; - const topLocation = staqAdapterRefWin.referer; - - return { - ver: ANALYTICS_VERSION, - domain: topLocation.hostname, - path: topLocation.pathname, - userAgent: navigator.userAgent, - connId: connId, - env: { - screen: { - w: window.screen.width, - h: window.screen.height - }, - lang: navigator.language - }, - src: getUmtSource(url, ref) - } -} - -let analyticsAdapter = Object.assign(adapter({ analyticsType: 'endpoint' }), { - track({ eventType, args }) { - if (!analyticsAdapter.context) { - return; - } - let handler = null; - switch (eventType) { - case CONSTANTS.EVENTS.AUCTION_INIT: - if (analyticsAdapter.context.queue) { - analyticsAdapter.context.queue.init(); - } - handler = trackAuctionInit; - break; - case CONSTANTS.EVENTS.BID_REQUESTED: - handler = trackBidRequest; - break; - case CONSTANTS.EVENTS.BID_RESPONSE: - handler = trackBidResponse; - break; - case CONSTANTS.EVENTS.BID_WON: - handler = trackBidWon; - break; - case CONSTANTS.EVENTS.BID_TIMEOUT: - handler = trackBidTimeout; - break; - case CONSTANTS.EVENTS.AUCTION_END: - handler = trackAuctionEnd; - break; - } - if (handler) { - let events = handler(args); - if (analyticsAdapter.context.queue) { - analyticsAdapter.context.queue.push(events); - if (eventType === CONSTANTS.EVENTS.BID_WON) { - analyticsAdapter.context.queue.updateWithWins(events); - } - } - if (eventType === CONSTANTS.EVENTS.AUCTION_END) { - sendAll(); - } - } - } -}); - -analyticsAdapter.context = {}; - -analyticsAdapter.originEnableAnalytics = analyticsAdapter.enableAnalytics; - -analyticsAdapter.enableAnalytics = (config) => { - utils.logInfo('Enabling STAQ Adapter'); - staqAdapterRefWin = getRefererInfo(window); - if (!config.options.connId) { - utils.logError('ConnId is not defined. STAQ Analytics won\'t work'); - return; - } - if (!config.options.url) { - utils.logError('URL is not defined. STAQ Analytics won\'t work'); - return; - } - analyticsAdapter.context = { - host: config.options.host || DEFAULT_HOST, - url: config.options.url, - connectionId: config.options.connId, - requestTemplate: buildRequestTemplate(config.options.connId), - queue: new ExpiringQueue(sendAll, config.options.queueTimeout || DEFAULT_QUEUE_TIMEOUT) - }; - analyticsAdapter.originEnableAnalytics(config); -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: analyticsAdapter, - code: 'staq' -}); - -export default analyticsAdapter; - -function sendAll() { - let events = analyticsAdapter.context.queue.popAll(); - if (events.length !== 0) { - let req = analyticsAdapter.context.requestTemplate; - req.auctionId = analyticsAdapter.context.auctionId; - req.events = events - - analyticsAdapter.ajaxCall(JSON.stringify(req)); - } -} - -analyticsAdapter.ajaxCall = function ajaxCall(data) { - utils.logInfo('SENDING DATA: ' + data); - ajax(`https://${analyticsAdapter.context.url}/prebid/${analyticsAdapter.context.connectionId}`, () => {}, data, { contentType: 'text/plain' }); -}; - -function trackAuctionInit(args) { - analyticsAdapter.context.auctionTimeStart = Date.now(); - analyticsAdapter.context.auctionId = args.auctionId; - const event = createHbEvent(args.auctionId, undefined, STAQ_EVENTS.AUCTION_INIT); - return [event]; -} - -function trackBidRequest(args) { - return args.bids.map(bid => - createHbEvent(args.auctionId, args.bidderCode, STAQ_EVENTS.BID_REQUEST, bid.adUnitCode)); -} - -function trackBidResponse(args) { - const event = createHbEvent(args.auctionId, args.bidderCode, STAQ_EVENTS.BID_RESPONSE, - args.adUnitCode, args.cpm, args.timeToRespond / 1000, false, args); - return [event]; -} - -function trackBidWon(args) { - const event = createHbEvent(args.auctionId, args.bidderCode, STAQ_EVENTS.BID_WON, args.adUnitCode, args.cpm, undefined, true, args); - return [event]; -} - -function trackAuctionEnd(args) { - const event = createHbEvent(args.auctionId, undefined, STAQ_EVENTS.AUCTION_END, undefined, - undefined, (Date.now() - analyticsAdapter.context.auctionTimeStart) / 1000); - return [event]; -} - -function trackBidTimeout(args) { - return args.map(arg => createHbEvent(arg.auctionId, arg.bidderCode, STAQ_EVENTS.TIMEOUT)); -} - -function createHbEvent(auctionId, adapter, event, adUnitCode = undefined, value = 0, time = 0, bidWon = undefined, eventArgs) { - let ev = { event: event }; - if (adapter) { - ev.adapter = adapter; - ev.bidderName = adapter; - } - if (adUnitCode) { - ev.adUnitCode = adUnitCode; - } - if (value) { - ev.cpm = value; - } - if (time) { - ev.timeToRespond = time; - } - if (typeof bidWon !== 'undefined') { - ev.bidWon = bidWon; - } else if (event === 'bidResponse') { - ev.bidWon = false; - } - ev.auctionId = auctionId; - - if (eventArgs) { - if (STAQ_EVENTS.BID_RESPONSE == event || STAQ_EVENTS.BID_WON == event) { - ev.width = eventArgs.width; - ev.height = eventArgs.height; - - ev.adId = eventArgs.adId; - } - } - - return ev; -} - -const UTM_TAGS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', - 'utm_c1', 'utm_c2', 'utm_c3', 'utm_c4', 'utm_c5' -]; -const STAQ_PREBID_KEY = 'staq_analytics'; -const DIRECT = '(direct)'; -const REFERRAL = '(referral)'; -const ORGANIC = '(organic)'; - -export let storage = { - getItem: (name) => { - return storageObj.getDataFromLocalStorage(name); - }, - setItem: (name, value) => { - storageObj.setDataInLocalStorage(name, value); - } -}; - -export function getUmtSource(pageUrl, referrer) { - let prevUtm = getPreviousTrafficSource(); - let currUtm = getCurrentTrafficSource(pageUrl, referrer); - let [updated, actual] = chooseActualUtm(prevUtm, currUtm); - if (updated) { - storeUtm(actual); - } - return actual; - - function getPreviousTrafficSource() { - let val = storage.getItem(STAQ_PREBID_KEY); - if (!val) { - return getDirect(); - } - return JSON.parse(val); - } - - function getCurrentTrafficSource(pageUrl, referrer) { - var source = getUTM(pageUrl); - if (source) { - return source; - } - if (referrer) { - let se = getSearchEngine(referrer); - if (se) { - return asUtm(se, ORGANIC, ORGANIC); - } - let parsedUrl = utils.parseUrl(pageUrl); - let [refHost, refPath] = getReferrer(referrer); - if (refHost && refHost !== parsedUrl.hostname) { - return asUtm(refHost, REFERRAL, REFERRAL, '', refPath); - } - } - return getDirect(); - } - - function getSearchEngine(pageUrl) { - let engines = { - 'google': /^https?\:\/\/(?:www\.)?(?:google\.(?:com?\.)?(?:com|cat|[a-z]{2})|g.cn)\//i, - 'yandex': /^https?\:\/\/(?:www\.)?ya(?:ndex\.(?:com|net)?\.?(?:asia|mobi|org|[a-z]{2})?|\.ru)\//i, - 'bing': /^https?\:\/\/(?:www\.)?bing\.com\//i, - 'duckduckgo': /^https?\:\/\/(?:www\.)?duckduckgo\.com\//i, - 'ask': /^https?\:\/\/(?:www\.)?ask\.com\//i, - 'yahoo': /^https?\:\/\/(?:[-a-z]+\.)?(?:search\.)?yahoo\.com\//i - }; - - for (let engine in engines) { - if (engines.hasOwnProperty(engine) && engines[engine].test(pageUrl)) { - return engine; - } - } - } - - function getReferrer(referrer) { - let ref = utils.parseUrl(referrer); - return [ref.hostname, ref.pathname]; - } - - function getUTM(pageUrl) { - let urlParameters = utils.parseUrl(pageUrl).search; - if (!urlParameters['utm_campaign'] || !urlParameters['utm_source']) { - return; - } - let utmArgs = []; - utils._each(UTM_TAGS, (utmTagName) => { - let utmValue = urlParameters[utmTagName] || ''; - utmArgs.push(utmValue); - }); - return asUtm.apply(this, utmArgs); - } - - function getDirect() { - return asUtm(DIRECT, DIRECT, DIRECT); - } - - function storeUtm(utm) { - let val = JSON.stringify(utm); - storage.setItem(STAQ_PREBID_KEY, val); - } - - function asUtm(source, medium, campaign, term = '', content = '', c1 = '', c2 = '', c3 = '', c4 = '', c5 = '') { - let result = { - source: source, - medium: medium, - campaign: campaign - }; - if (term) { - result.term = term; - } - if (content) { - result.content = content; - } - if (c1) { - result.c1 = c1; - } - if (c2) { - result.c2 = c2; - } - if (c3) { - result.c3 = c3; - } - if (c4) { - result.c4 = c4; - } - if (c5) { - result.c5 = c5; - } - return result; - } - - function chooseActualUtm(prev, curr) { - if (ord(prev) < ord(curr)) { - return [true, curr]; - } - if (ord(prev) > ord(curr)) { - return [false, prev]; - } else { - if (prev.campaign === REFERRAL && prev.content !== curr.content) { - return [true, curr]; - } else if (prev.campaign === ORGANIC && prev.source !== curr.source) { - return [true, curr]; - } else if (isCampaignTraffic(prev) && (prev.campaign !== curr.campaign || prev.source !== curr.source)) { - return [true, curr]; - } - } - return [false, prev]; - } - - function ord(utm) { - switch (utm.campaign) { - case DIRECT: - return 0; - case ORGANIC: - return 1; - case REFERRAL: - return 2; - default: - return 3; - } - } - - function isCampaignTraffic(utm) { - return [DIRECT, REFERRAL, ORGANIC].indexOf(utm.campaign) === -1; - } -} - -/** - * Expiring queue implementation. Fires callback on elapsed timeout since last last update or creation. - * @param callback - * @param ttl - * @constructor - */ -export function ExpiringQueue(callback, ttl) { - let queue = []; - let timeoutId; - - this.push = (event) => { - if (event instanceof Array) { - queue.push.apply(queue, event); - } else { - queue.push(event); - } - reset(); - }; - - this.updateWithWins = (winEvents) => { - winEvents.forEach(winEvent => { - queue.forEach(prevEvent => { - if (prevEvent.event === 'bidResponse' && - prevEvent.auctionId == winEvent.auctionId && - prevEvent.adUnitCode == winEvent.adUnitCode && - prevEvent.adId == winEvent.adId && - prevEvent.adapter == winEvent.adapter) { - prevEvent.bidWon = true; - } - }); - }); - } - - this.popAll = () => { - let result = queue; - queue = []; - reset(); - return result; - }; - - /** - * For test/debug purposes only - * @return {Array} - */ - this.peekAll = () => { - return queue; - }; - - this.init = reset; - - function reset() { - if (timeoutId) { - clearTimeout(timeoutId); - } - timeoutId = setTimeout(() => { - if (queue.length) { - callback(); - } - }, ttl); - } -} diff --git a/modules/staqAnalyticsAdapter.md b/modules/staqAnalyticsAdapter.md deleted file mode 100644 index c3d2e9ce3a8..00000000000 --- a/modules/staqAnalyticsAdapter.md +++ /dev/null @@ -1,23 +0,0 @@ -# Overview -Module Name: STAQ Analytics Adapter - -Module Type: Analytics Adapter - -Maintainer: dev@staq.com - -# Description - -Analytics adapter for STAQ. Contact support@staq.com for information. - -# Test Parameters - -``` -{ - provider: 'staq', - options: { - host: , // HOST URL of site. Optional. Only required for whitelisting. - url: 'localhost:3000', // REQUIRED host URL for delivery of information to STAQ - connId: '5678' // REQUIRED STAQ connection ID - } -} -``` diff --git a/modules/stroeerCoreBidAdapter.js b/modules/stroeerCoreBidAdapter.js deleted file mode 100644 index ec442f5125a..00000000000 --- a/modules/stroeerCoreBidAdapter.js +++ /dev/null @@ -1,196 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; - -const GVL_ID = 136; -const BIDDER_CODE = 'stroeerCore'; -const DEFAULT_HOST = 'hb.adscale.de'; -const DEFAULT_PATH = '/dsh'; -const DEFAULT_PORT = ''; -const FIVE_MINUTES_IN_SECONDS = 300; -const USER_SYNC_IFRAME_URL = 'https://js.adscale.de/pbsync.html'; - -const isSecureWindow = () => utils.getWindowSelf().location.protocol === 'https:'; -const isMainPageAccessible = () => getMostAccessibleTopWindow() === utils.getWindowTop(); - -function getTopWindowReferrer() { - try { - return utils.getWindowTop().document.referrer; - } catch (e) { - return utils.getWindowSelf().referrer; - } -} - -function getMostAccessibleTopWindow() { - let res = utils.getWindowSelf(); - - try { - while (utils.getWindowTop().top !== res && res.parent.location.href.length) { - res = res.parent; - } - } catch (ignore) { - } - - return res; -} - -function elementInView(elementId) { - const resolveElement = (elId) => { - const win = utils.getWindowSelf(); - - return win.document.getElementById(elId); - }; - - const visibleInWindow = (el, win) => { - const rect = el.getBoundingClientRect(); - const inView = (rect.top + rect.height >= 0) && (rect.top <= win.innerHeight); - - if (win !== win.parent) { - return inView && visibleInWindow(win.frameElement, win.parent); - } - - return inView; - }; - - try { - return visibleInWindow(resolveElement(elementId), utils.getWindowSelf()); - } catch (e) { - // old browser, element not found, cross-origin etc. - } - return undefined; -} - -function buildUrl({host: hostname = DEFAULT_HOST, port = DEFAULT_PORT, securePort, path: pathname = DEFAULT_PATH}) { - if (securePort) { - port = securePort; - } - - return utils.buildUrl({protocol: 'https', hostname, port, pathname}); -} - -function getGdprParams(gdprConsent) { - if (gdprConsent) { - const consentString = encodeURIComponent(gdprConsent.consentString || '') - const isGdpr = gdprConsent.gdprApplies ? 1 : 0; - - return `?gdpr=${isGdpr}&gdpr_consent=${consentString}` - } else { - return ''; - } -} - -export const spec = { - code: BIDDER_CODE, - gvlid: GVL_ID, - supportedMediaTypes: [BANNER], - - isBidRequestValid: (function () { - const validators = []; - - const createValidator = (checkFn, errorMsgFn) => { - return (bidRequest) => { - if (checkFn(bidRequest)) { - return true; - } else { - utils.logError(`invalid bid: ${errorMsgFn(bidRequest)}`, 'ERROR'); - return false; - } - } - }; - - function isBanner(bidReq) { - return (!bidReq.mediaTypes && !bidReq.mediaType) || - (bidReq.mediaTypes && bidReq.mediaTypes.banner) || - bidReq.mediaType === BANNER; - } - - validators.push(createValidator((bidReq) => isBanner(bidReq), - bidReq => `bid request ${bidReq.bidId} is not a banner`)); - validators.push(createValidator((bidReq) => typeof bidReq.params === 'object', - bidReq => `bid request ${bidReq.bidId} does not have custom params`)); - validators.push(createValidator((bidReq) => utils.isStr(bidReq.params.sid), - bidReq => `bid request ${bidReq.bidId} does not have a sid string field`)); - - return function (bidRequest) { - return validators.every(f => f(bidRequest)); - } - }()), - - buildRequests: function (validBidRequests = [], bidderRequest) { - const anyBid = bidderRequest.bids[0]; - - const payload = { - id: bidderRequest.auctionId, - bids: [], - ref: getTopWindowReferrer(), - ssl: isSecureWindow(), - mpa: isMainPageAccessible(), - timeout: bidderRequest.timeout - (Date.now() - bidderRequest.auctionStart) - }; - - const userIds = anyBid.userId; - - if (!utils.isEmpty(userIds)) { - payload.user = { - euids: userIds - }; - } - - const gdprConsent = bidderRequest.gdprConsent; - - if (gdprConsent && gdprConsent.consentString != null && gdprConsent.gdprApplies != null) { - payload.gdpr = { - consent: bidderRequest.gdprConsent.consentString, applies: bidderRequest.gdprConsent.gdprApplies - }; - } - - function bidSizes(bid) { - return utils.deepAccess(bid, 'mediaTypes.banner.sizes') || bid.sizes /* for prebid < 3 */ || []; - } - - validBidRequests.forEach(bid => { - payload.bids.push({ - bid: bid.bidId, sid: bid.params.sid, siz: bidSizes(bid), viz: elementInView(bid.adUnitCode) - }); - }); - - return { - method: 'POST', url: buildUrl(anyBid.params), data: payload - } - }, - - interpretResponse: function (serverResponse) { - const bids = []; - - if (serverResponse.body && typeof serverResponse.body === 'object') { - serverResponse.body.bids.forEach(bidResponse => { - bids.push({ - requestId: bidResponse.bidId, - cpm: bidResponse.cpm || 0, - width: bidResponse.width || 0, - height: bidResponse.height || 0, - ad: bidResponse.ad, - ttl: FIVE_MINUTES_IN_SECONDS, - currency: 'EUR', - netRevenue: true, - creativeId: '', - }); - }); - } - - return bids; - }, - - getUserSyncs: function (syncOptions, serverResponses, gdprConsent) { - if (serverResponses.length > 0 && syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: USER_SYNC_IFRAME_URL + getGdprParams(gdprConsent) - }]; - } - - return []; - } -}; - -registerBidder(spec); diff --git a/modules/stroeerCoreBidAdapter.md b/modules/stroeerCoreBidAdapter.md deleted file mode 100644 index fe6e92057c6..00000000000 --- a/modules/stroeerCoreBidAdapter.md +++ /dev/null @@ -1,31 +0,0 @@ -## Overview - -``` -Module Name: Stroeer Bidder Adapter -Module Type: Bidder Adapter -Maintainer: help@cz.stroeer-labs.com -``` - - -## Ad unit configuration for publishers - -```javascript -const adUnits = [{ - code: 'div-gpt-ad-1460505748561-0', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [{ - bidder: 'stroeerCore', - params: { - sid: "06b782cc-091b-4f53-9cd2-0291679aa1ac" - } - }] -}]; -``` -### Config Notes - -* Slot id (`sid`) is required. The adapter will ignore bid requests from prebid if `sid` is not provided. This must be in the decoded form. For example, "1234" as opposed to "MTM0ODA=". -* The server ignores dimensions that are not supported by the slot or by the platform (such as 987x123). diff --git a/modules/stvBidAdapter.js b/modules/stvBidAdapter.js deleted file mode 100644 index 2200e01b089..00000000000 --- a/modules/stvBidAdapter.js +++ /dev/null @@ -1,150 +0,0 @@ - -import * as utils from '../src/utils.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'stv'; -const VADS_ENDPOINT_URL = 'https://ads.smartstream.tv/r/'; -const DEFAULT_VIDEO_SOURCE = 'vads'; -const DEFAULT_BANNER_FORMAT = 'vast2'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['vads'], - supportedMediaTypes: [BANNER, VIDEO], - isBidRequestValid: function(bid) { - return !!(bid.params.placement); - }, - buildRequests: function(validBidRequests, bidderRequest) { - return validBidRequests.map(bidRequest => { - const params = bidRequest.params; - - const videoData = utils.deepAccess(bidRequest, 'mediaTypes.video') || {}; - const sizes = utils.parseSizesInput(videoData.playerSize || bidRequest.sizes)[0]; - const width = sizes.split('x')[0]; - const height = sizes.split('x')[1]; - - const placementId = params.placement; - - const rnd = Math.floor(Math.random() * 99999999999); - const referrer = bidderRequest.refererInfo.referer; - const bidId = bidRequest.bidId; - let endpoint = VADS_ENDPOINT_URL; - - let payload = {}; - if (isVideoRequest(bidRequest)) { - const source = params.source || DEFAULT_VIDEO_SOURCE; - if (source === 'vads') { - payload = { - _f: 'vast2', - alternative: 'prebid_js', - _ps: placementId, - srw: width, - srh: height, - idt: 100, - rnd: rnd, - ref: referrer, - bid_id: bidId, - }; - endpoint = VADS_ENDPOINT_URL; - } - } else { - const outputFormat = params.format || DEFAULT_BANNER_FORMAT; - payload = { - _f: outputFormat, - alternative: 'prebid_js', - inventory_item_id: placementId, - srw: width, - srh: height, - idt: 100, - rnd: rnd, - ref: referrer, - bid_id: bidId, - }; - } - prepareExtraParams(params, payload); - - return { - method: 'GET', - url: endpoint, - data: objectToQueryString(payload), - } - }); - }, - interpretResponse: function(serverResponse, bidRequest) { - const bidResponses = []; - const response = serverResponse.body; - const crid = response.crid || 0; - const cpm = response.cpm / 1000000 || 0; - if (cpm !== 0 && crid !== 0) { - const dealId = response.dealid || ''; - const currency = response.currency || 'EUR'; - const netRevenue = (response.netRevenue === undefined) ? true : response.netRevenue; - const bidResponse = { - requestId: response.bid_id, - cpm: cpm, - width: response.width, - height: response.height, - creativeId: crid, - dealId: dealId, - currency: currency, - netRevenue: netRevenue, - ttl: config.getConfig('_bidderTimeout') - }; - - if (response.vastXml) { - bidResponse.vastXml = response.vastXml; - bidResponse.mediaType = 'video'; - } else { - bidResponse.ad = response.adTag; - } - - bidResponses.push(bidResponse); - } - return bidResponses; - } -} - -function objectToQueryString(obj, prefix) { - let str = []; - let p; - for (p in obj) { - if (obj.hasOwnProperty(p)) { - let k = prefix ? prefix + '[' + p + ']' : p; - let v = obj[p]; - str.push((v !== null && typeof v === 'object') - ? objectToQueryString(v, k) - : encodeURIComponent(k) + '=' + (k == '_ps' ? v : encodeURIComponent(v))); - } - } - return str.join('&'); -} - -/** - * Check if it's a video bid request - * - * @param {BidRequest} bid - Bid request generated from ad slots - * @returns {boolean} True if it's a video bid - */ -function isVideoRequest(bid) { - return bid.mediaType === 'video' || !!utils.deepAccess(bid, 'mediaTypes.video'); -} - -function prepareExtraParams(params, payload) { - if (params.pfilter !== undefined) { - payload.pfilter = params.pfilter; - } - if (params.bcat !== undefined) { - payload.bcat = params.bcat; - } - if (params.noskip !== undefined) { - payload.noskip = params.noskip; - } - - if (params.dvt !== undefined) { - payload.dvt = params.dvt; - } -} - -registerBidder(spec); diff --git a/modules/stvBidAdapter.md b/modules/stvBidAdapter.md deleted file mode 100644 index 79e958c3bba..00000000000 --- a/modules/stvBidAdapter.md +++ /dev/null @@ -1,43 +0,0 @@ -# Overview - -``` -Module Name: STV Video Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid@dspx.tv -``` - -# Description - -STV video adapter for Prebid.js 1.x - -# Parameters -``` - var adUnits = [ - { - // video settings - code: 'video-obj', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480] - } - }, - bids: [ - { - bidder: "stv", - params: { - placement: "", // placement ID of inventory with STV - noskip: 1, // 0 or 1 - pfilter: {/* - min_duration: 10, // min duration - max_duration: 30, // max duration - min_bitrate: 300, // min bitrate - max_bitrate: 1600, // max bitrate - */} - } - } - ] - } - ]; -``` - diff --git a/modules/sublimeBidAdapter.js b/modules/sublimeBidAdapter.js deleted file mode 100644 index 41fdb72e76e..00000000000 --- a/modules/sublimeBidAdapter.js +++ /dev/null @@ -1,246 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { config } from '../src/config.js'; -import * as utils from '../src/utils.js'; - -const BIDDER_CODE = 'sublime'; -const BIDDER_GVLID = 114; -const DEFAULT_BID_HOST = 'pbjs.sskzlabs.com'; -const DEFAULT_CURRENCY = 'EUR'; -const DEFAULT_PROTOCOL = 'https'; -const DEFAULT_TTL = 600; -const SUBLIME_ANTENNA = 'antenna.ayads.co'; -const SUBLIME_VERSION = '0.7.1'; - -/** - * Identify the current device type - * @returns {string} - */ -function detectDevice() { - const isMobile = /(?:phone|windowss+phone|ipod|blackberry|Galaxy Nexus|SM-G892A|(?:android|bbd+|meego|silk|googlebot) .+?mobile|palm|windowss+ce|opera mini|avantgo|docomo)/i; - - const isTablet = /(?:ipad|playbook|Tablet|(?:android|bb\\d+|meego|silk)(?! .+? mobile))/i; - - return ( - (isMobile.test(navigator.userAgent) && 'm') || // mobile - (isTablet.test(navigator.userAgent) && 't') || // tablet - 'd' // desktop - ); -} - -/** - * Debug log message - * @param {String} msg - * @param {Object=} obj - */ -export function log(msg, obj) { - utils.logInfo('SublimeBidAdapter - ' + msg, obj); -} - -// Default state -export const state = { - zoneId: '', - transactionId: '', - notifyId: '' -}; - -/** - * Set a new state - * @param {Object} value - */ -export function setState(value) { - Object.assign(state, value); - log('State has been updated :', state); -} - -/** - * Send pixel to our debug endpoint - * @param {string} eventName - Event name that will be send in the e= query string - * @param {string} [sspName] - The optionnal name of the AD provider - */ -export function sendEvent(eventName, sspName) { - const ts = Date.now(); - const eventObject = { - t: ts, - tse: ts, - z: state.zoneId, - e: eventName, - src: 'pa', - puid: state.transactionId || state.notifyId, - trId: state.transactionId || state.notifyId, - pbav: SUBLIME_VERSION, - pubtimeout: config.getConfig('bidderTimeout'), - pubpbv: '$prebid.version$', - device: detectDevice(), - }; - - if (eventName === 'bidwon') { - eventObject.sspname = sspName || ''; - } - - log('Sending pixel for event: ' + eventName, eventObject); - - const queryString = utils.formatQS(eventObject); - utils.triggerPixel('https://' + SUBLIME_ANTENNA + '/?' + queryString); -} - -/** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return {Boolean} True if this is a valid bid, and false otherwise. - */ -function isBidRequestValid(bid) { - return !!Number(bid.params.zoneId); -} - -/** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests - An array of bids - * @param {Object} bidderRequest - Info describing the request to the server. - * @return {ServerRequest|ServerRequest[]} - Info describing the request to the server. - */ -function buildRequests(validBidRequests, bidderRequest) { - const commonPayload = { - pbav: SUBLIME_VERSION, - // Current Prebid params - prebidVersion: '$prebid.version$', - currencyCode: config.getConfig('currency.adServerCurrency') || DEFAULT_CURRENCY, - timeout: (typeof bidderRequest === 'object' && !!bidderRequest) ? bidderRequest.timeout : config.getConfig('bidderTimeout'), - }; - - // RefererInfo - if (bidderRequest && bidderRequest.refererInfo) { - commonPayload.referer = bidderRequest.refererInfo.referer; - commonPayload.numIframes = bidderRequest.refererInfo.numIframes; - } - // GDPR handling - if (bidderRequest && bidderRequest.gdprConsent) { - commonPayload.gdprConsent = bidderRequest.gdprConsent.consentString; - commonPayload.gdpr = bidderRequest.gdprConsent.gdprApplies; // we're handling the undefined case server side - } - - return validBidRequests.map(bid => { - const bidHost = bid.params.bidHost || DEFAULT_BID_HOST; - const protocol = bid.params.protocol || DEFAULT_PROTOCOL; - - setState({ - transactionId: bid.transactionId, - notifyId: bid.params.notifyId, - zoneId: bid.params.zoneId, - debug: bid.params.debug || false, - }); - - const bidPayload = { - adUnitCode: bid.adUnitCode, - auctionId: bid.auctionId, - bidder: bid.bidder, - bidderRequestId: bid.bidderRequestId, - bidRequestsCount: bid.bidRequestsCount, - requestId: bid.bidId, - sizes: bid.sizes.map(size => ({ - w: size[0], - h: size[1], - })), - transactionId: bid.transactionId, - notifyId: bid.params.notifyId, - zoneId: bid.params.zoneId, - }; - - const payload = Object.assign({}, commonPayload, bidPayload); - - return { - method: 'POST', - url: protocol + '://' + bidHost + '/bid', - data: JSON.stringify(payload), - options: { - contentType: 'text/plain', - withCredentials: false - }, - } - }); -} - -/** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @param {*} bidRequest An object with bid request informations - * @return {Bid[]} An array of bids which were nested inside the server. - */ -function interpretResponse(serverResponse, bidRequest) { - const bidResponses = []; - const response = serverResponse.body; - - if (response) { - if (response.timeout || !response.ad || //gmi.test(response.ad)) { - return bidResponses; - } - - // Setting our returned sizes object to default values - let returnedSizes = { - width: 1800, - height: 1000 - }; - - // Verifying Banner sizes - if (bidRequest && bidRequest.data && bidRequest.data.w === 1 && bidRequest.data.h === 1) { - // If banner sizes are 1x1 we set our default size object to 1x1 - returnedSizes = { - width: 1, - height: 1 - }; - } - - const bidResponse = { - requestId: response.requestId || '', - cpm: response.cpm || 0, - width: response.width || returnedSizes.width, - height: response.height || returnedSizes.height, - creativeId: response.creativeId || 1, - dealId: response.dealId || 1, - currency: response.currency || DEFAULT_CURRENCY, - netRevenue: response.netRevenue || true, - ttl: response.ttl || DEFAULT_TTL, - ad: response.ad, - pbav: SUBLIME_VERSION, - sspname: response.sspname || null - }; - - bidResponses.push(bidResponse); - } - - return bidResponses; -} - -/** - * Send pixel when bidWon event is triggered - * @param {Object} timeoutData - */ -function onBidWon(bid) { - log('Bid won', bid); - sendEvent('bidwon', bid.sspname); -} - -/** - * Send debug when we timeout - * @param {Object} timeoutData - */ -function onTimeout(timeoutData) { - log('Timeout from adapter', timeoutData); - sendEvent('bidtimeout'); -} - -export const spec = { - code: BIDDER_CODE, - gvlid: BIDDER_GVLID, - aliases: [], - sendEvent: sendEvent, - isBidRequestValid: isBidRequestValid, - buildRequests: buildRequests, - interpretResponse: interpretResponse, - onBidWon: onBidWon, - onTimeout: onTimeout, -}; - -registerBidder(spec); diff --git a/modules/sublimeBidAdapter.md b/modules/sublimeBidAdapter.md deleted file mode 100644 index 5cd1c95b682..00000000000 --- a/modules/sublimeBidAdapter.md +++ /dev/null @@ -1,65 +0,0 @@ -# Overview - -``` -Module Name: Sublime Bid Adapter -Module Type: Bidder Adapter -Maintainer: pbjs@sublimeskinz.com -``` - -# Description - -Connects to Sublime for bids. -Sublime bid adapter supports Skinz. - -# Nota Bene - -Our prebid adapter is unusable with SafeFrame. - -# Build - -You can build your version of prebid.js, execute: - -```shell -gulp build --modules=sublimeBidAdapter -``` - -Or to build with multiple adapters - -```shell -gulp build --modules=sublimeBidAdapter,secondAdapter,thirdAdapter -``` - -More details in the root [README](../README.md#Build) - -## To build from you own repository - -- copy `/modules/sublimeBidAdapter.js` to your `/modules/` directory -- copy `/modules/sublimeBidAdapter.md` to your `/modules/` directory -- copy `/test/spec/modules/sublimeBidAdapter_spec.js` to your `/test/spec/modules/` directory - -Then build - - -# Invocation Parameters - -```js -var adUnits = [{ - code: 'sublime', - mediaTypes: { - banner: { - sizes: [1800, 1000] - } - }, - bids: [{ - bidder: 'sublime', - params: { - zoneId: , - notifyId: - } - }] -}]; -``` - -Where you replace: -- `` by your Sublime Zone id; -- `` by your Sublime Notify id diff --git a/modules/supply2BidAdapter.md b/modules/supply2BidAdapter.md deleted file mode 100644 index 3d86f065abf..00000000000 --- a/modules/supply2BidAdapter.md +++ /dev/null @@ -1,40 +0,0 @@ -# Overview - -Module Name: Supply2 Bidder Adapter -Module Type: Bidder Adapter -Maintainer: vishal@mediadonuts.com - -# Description - -Module that connects to Media Donuts demand source to fetch bids. - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - sizes: [[300, 250]], - bids: [ - { - bidder: "supply2", - params: { - uid: '23', - priceType: 'gross' // by default is 'net' - } - } - ] - },{ - code: 'test-div', - sizes: [[728, 90]], - bids: [ - { - bidder: "supply2", - params: { - uid: 24, - priceType: 'gross' - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/synacormediaBidAdapter.js b/modules/synacormediaBidAdapter.js deleted file mode 100644 index aaff637c790..00000000000 --- a/modules/synacormediaBidAdapter.js +++ /dev/null @@ -1,266 +0,0 @@ -'use strict'; - -import { getAdUnitSizes, logWarn, deepSetValue } from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import {config} from '../src/config.js'; - -const BID_SCHEME = 'https://'; -const BID_DOMAIN = 'technoratimedia.com'; -const USER_SYNC_HOST = 'https://ad-cdn.technoratimedia.com'; -const VIDEO_PARAMS = [ 'minduration', 'maxduration', 'startdelay', 'placement', 'linearity', 'mimes', 'protocols', 'api' ]; -const BLOCKED_AD_SIZES = [ - '1x1', - '1x2' -]; -export const spec = { - code: 'synacormedia', - supportedMediaTypes: [ BANNER, VIDEO ], - sizeMap: {}, - - isVideoBid: function(bid) { - return bid.mediaTypes !== undefined && - bid.mediaTypes.hasOwnProperty('video'); - }, - isBidRequestValid: function(bid) { - const hasRequiredParams = bid && bid.params && (bid.params.hasOwnProperty('placementId') || bid.params.hasOwnProperty('tagId')) && bid.params.hasOwnProperty('seatId'); - const hasAdSizes = bid && getAdUnitSizes(bid).filter(size => BLOCKED_AD_SIZES.indexOf(size.join('x')) === -1).length > 0 - return !!(hasRequiredParams && hasAdSizes); - }, - - buildRequests: function(validBidReqs, bidderRequest) { - if (!validBidReqs || !validBidReqs.length || !bidderRequest) { - return; - } - const refererInfo = bidderRequest.refererInfo; - const openRtbBidRequest = { - id: bidderRequest.auctionId, - site: { - domain: config.getConfig('publisherDomain') || location.hostname, - page: refererInfo.referer, - ref: document.referrer - }, - device: { - ua: navigator.userAgent - }, - imp: [] - }; - - const schain = validBidReqs[0].schain; - if (schain) { - openRtbBidRequest.source = { ext: { schain } }; - } - - let seatId = null; - - validBidReqs.forEach((bid, i) => { - if (seatId && seatId !== bid.params.seatId) { - logWarn(`Synacormedia: there is an inconsistent seatId: ${bid.params.seatId} but only sending bid requests for ${seatId}, you should double check your configuration`); - return; - } else { - seatId = bid.params.seatId; - } - const tagIdOrplacementId = bid.params.tagId || bid.params.placementId; - const bidFloor = bid.params.bidfloor ? parseFloat(bid.params.bidfloor) : null; - if (isNaN(bidFloor)) { - logWarn(`Synacormedia: there is an invalid bid floor: ${bid.params.bidfloor}`); - } - let pos = parseInt(bid.params.pos, 10); - if (isNaN(pos)) { - logWarn(`Synacormedia: there is an invalid POS: ${bid.params.pos}`); - pos = 0; - } - const videoOrBannerKey = this.isVideoBid(bid) ? 'video' : 'banner'; - const adSizes = getAdUnitSizes(bid) - .filter(size => BLOCKED_AD_SIZES.indexOf(size.join('x')) === -1); - - let imps = []; - if (videoOrBannerKey === 'banner') { - imps = this.buildBannerImpressions(adSizes, bid, tagIdOrplacementId, pos, bidFloor, videoOrBannerKey); - } else if (videoOrBannerKey === 'video') { - imps = this.buildVideoImpressions(adSizes, bid, tagIdOrplacementId, pos, bidFloor, videoOrBannerKey); - } - if (imps.length > 0) { - imps.forEach(i => openRtbBidRequest.imp.push(i)); - } - }); - - // CCPA - if (bidderRequest && bidderRequest.uspConsent) { - deepSetValue(openRtbBidRequest, 'regs.ext.us_privacy', bidderRequest.uspConsent); - } - - if (openRtbBidRequest.imp.length && seatId) { - return { - method: 'POST', - url: `${BID_SCHEME}${seatId}.${BID_DOMAIN}/openrtb/bids/${seatId}?src=$$REPO_AND_VERSION$$`, - data: openRtbBidRequest, - options: { - contentType: 'application/json', - withCredentials: true - } - }; - } - }, - - buildBannerImpressions: function (adSizes, bid, tagIdOrPlacementId, pos, bidFloor, videoOrBannerKey) { - let format = []; - let imps = []; - adSizes.forEach((size, i) => { - if (!size || size.length !== 2) { - return; - } - - format.push({ - w: size[0], - h: size[1], - }); - }); - - if (format.length > 0) { - const imp = { - id: `${videoOrBannerKey.substring(0, 1)}${bid.bidId}`, - banner: { - format, - pos - }, - tagid: tagIdOrPlacementId, - }; - if (bidFloor !== null && !isNaN(bidFloor)) { - imp.bidfloor = bidFloor; - } - imps.push(imp); - } - return imps; - }, - - buildVideoImpressions: function(adSizes, bid, tagIdOrPlacementId, pos, bidFloor, videoOrBannerKey) { - let imps = []; - adSizes.forEach((size, i) => { - if (!size || size.length != 2) { - return; - } - const size0 = size[0]; - const size1 = size[1]; - const imp = { - id: `${videoOrBannerKey.substring(0, 1)}${bid.bidId}-${size0}x${size1}`, - tagid: tagIdOrPlacementId - }; - if (bidFloor !== null && !isNaN(bidFloor)) { - imp.bidfloor = bidFloor; - } - - const videoOrBannerValue = { - w: size0, - h: size1, - pos - }; - if (bid.mediaTypes.video) { - if (!bid.params.video) { - bid.params.video = {}; - } - this.setValidVideoParams(bid.mediaTypes.video, bid.params.video); - } - if (bid.params.video) { - this.setValidVideoParams(bid.params.video, videoOrBannerValue); - } - imp[videoOrBannerKey] = videoOrBannerValue; - imps.push(imp); - }); - return imps; - }, - - setValidVideoParams: function (sourceObj, destObj) { - Object.keys(sourceObj) - .filter(param => includes(VIDEO_PARAMS, param) && sourceObj[param] !== null && (!isNaN(parseInt(sourceObj[param], 10)) || !(sourceObj[param].length < 1))) - .forEach(param => destObj[param] = Array.isArray(sourceObj[param]) ? sourceObj[param] : parseInt(sourceObj[param], 10)); - }, - interpretResponse: function(serverResponse, bidRequest) { - const updateMacros = (bid, r) => { - return r ? r.replace(/\${AUCTION_PRICE}/g, bid.price) : r; - }; - - if (!serverResponse.body || typeof serverResponse.body != 'object') { - logWarn('Synacormedia: server returned empty/non-json response: ' + JSON.stringify(serverResponse.body)); - return; - } - const {id, seatbid: seatbids} = serverResponse.body; - let bids = []; - if (id && seatbids) { - seatbids.forEach(seatbid => { - seatbid.bid.forEach(bid => { - const creative = updateMacros(bid, bid.adm); - const nurl = updateMacros(bid, bid.nurl); - const [, impType, impid] = bid.impid.match(/^([vb])([\w\d]+)/); - let height = bid.h; - let width = bid.w; - const isVideo = impType === 'v'; - const isBanner = impType === 'b'; - if ((!height || !width) && bidRequest.data && bidRequest.data.imp && bidRequest.data.imp.length > 0) { - bidRequest.data.imp.forEach(req => { - if (bid.impid === req.id) { - if (isVideo) { - height = req.video.h; - width = req.video.w; - } else if (isBanner) { - let bannerHeight = 1; - let bannerWidth = 1; - if (req.banner.format && req.banner.format.length > 0) { - bannerHeight = req.banner.format[0].h; - bannerWidth = req.banner.format[0].w; - } - height = bannerHeight; - width = bannerWidth; - } else { - height = 1; - width = 1; - } - } - }); - } - const bidObj = { - requestId: impid, - cpm: parseFloat(bid.price), - width: parseInt(width, 10), - height: parseInt(height, 10), - creativeId: `${seatbid.seat}_${bid.crid}`, - currency: 'USD', - netRevenue: true, - mediaType: isVideo ? VIDEO : BANNER, - ad: creative, - ttl: 60 - }; - - if (bid.adomain != undefined || bid.adomain != null) { - bidObj.meta = { advertiserDomains: bid.adomain }; - } - - if (isVideo) { - const [, uuid] = nurl.match(/ID=([^&]*)&?/); - if (!config.getConfig('cache.url')) { - bidObj.videoCacheKey = encodeURIComponent(uuid); - } - bidObj.vastUrl = nurl; - } - bids.push(bidObj); - }); - }); - } - return bids; - }, - getUserSyncs: function (syncOptions, serverResponses) { - const syncs = []; - if (syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: `${USER_SYNC_HOST}/html/usersync.html?src=$$REPO_AND_VERSION$$` - }); - } else { - logWarn('Synacormedia: Please enable iframe based user sync.'); - } - return syncs; - } -}; - -registerBidder(spec); diff --git a/modules/synacormediaBidAdapter.md b/modules/synacormediaBidAdapter.md deleted file mode 100644 index 523c66fd1d9..00000000000 --- a/modules/synacormediaBidAdapter.md +++ /dev/null @@ -1,67 +0,0 @@ -# Overview - -``` -Module Name: Synacor Media Bidder Adapter -Module Type: Bidder Adapter -Maintainer: eng-demand@synacor.com -``` - -# Description - -The Synacor Media adapter requires setup and approval from Synacor. -Please reach out to your account manager for more information. - -### DFP Video Creative -To use video, setup a `VAST redirect` creative within Google AdManager (DFP) with the following VAST tag URL: - -``` -https://track.technoratimedia.com/openrtb/tags?ID=%%PATTERN:hb_cache_id_synacorm%%&AUCTION_PRICE=%%PATTERN:hb_pb_synacormedia%% -``` - -# Test Parameters - -## Web -``` - var adUnits = [{ - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [{ - bidder: "synacormedia", - params: { - seatId: "prebid", - tagId: "demo1", - bidfloor: 0.10, - pos: 1 - } - }] - },{ - code: 'test-div2', - mediaTypes: { - video: { - context: 'instream', - playerSize: [ - [300, 250] - ], - } - }, - bids: [{ - bidder: "synacormedia", - params: { - seatId: "prebid", - tagId: "demo1", - bidfloor: 0.20, - pos: 1, - video: { - minduration: 15, - maxduration: 30, - startdelay: 1, - linearity: 1 - } - } - }] - }]; -``` diff --git a/modules/tapadIdSystem.js b/modules/tapadIdSystem.js deleted file mode 100644 index a49d62897ad..00000000000 --- a/modules/tapadIdSystem.js +++ /dev/null @@ -1,61 +0,0 @@ -import { uspDataHandler } from '../src/adapterManager.js'; -import { submodule } from '../src/hook.js'; -import * as ajax from '../src/ajax.js' -import * as utils from '../src/utils.js'; - -export const graphUrl = 'https://rtga.tapad.com/v1/graph'; - -export const tapadIdSubmodule = { - name: 'tapadId', - /** - * decode the stored id value for passing to bid requests - * @function - * @returns {{tapadId: string} | undefined} - */ - decode(id) { - return { tapadId: id }; - }, - /* - * @function - * @summary initiate Real Time Graph - * @param {SubmoduleParams} [configParams] - * @param {ConsentData} [consentData] - * @returns {IdResponse }} - */ - getId(config) { - const uspData = uspDataHandler.getConsentData(); - if (uspData && uspData !== '1---') { - return { id: undefined }; - } - const configParams = config.params || {}; - - if (configParams.companyId == null || isNaN(Number(configParams.companyId))) { - utils.logMessage('Please provide a valid Company Id. Contact prebid@tapad.com for assistance.'); - } - - return { - callback: (complete) => { - ajax.ajaxBuilder(10000)( - `${graphUrl}?company_id=${configParams.companyId}&tapad_id_type=TAPAD_ID`, - { - success: (response) => { - const responseJson = JSON.parse(response); - if (responseJson.hasOwnProperty('tapadId')) { - complete(responseJson.tapadId); - } - }, - error: (_, e) => { - if (e.status === 404) { - complete(undefined); - } - if (e.status === 403) { - utils.logMessage('Invalid Company Id. Contact prebid@tapad.com for assistance.'); - } - } - } - ); - } - } - } -} -submodule('userId', tapadIdSubmodule); diff --git a/modules/tapadIdSystem.md b/modules/tapadIdSystem.md deleted file mode 100644 index 4bab1b4689d..00000000000 --- a/modules/tapadIdSystem.md +++ /dev/null @@ -1,43 +0,0 @@ -### Tapad ID - -Tapad's ID module provides access to a universal identifier that publishers, ad tech platforms and advertisers can use for data collection and collation without reliance on third-party cookies. -Tapad's ID module is free to use and promotes collaboration across the industry by facilitating interoperability between DSPs, SSPs and publishers. - -To register as an authorized user of the Tapad ID module, or for more information, documentation and access to Tapad’s Terms and Conditions please contact [prebid@tapad.com](mailto:prebid@tapad.com). - -Tapad’s Privacy landing page containing links to region-specific Privacy Notices may be found here: [https://tapad.com/privacy.html](https://tapad.com/privacy.html). - -Add it to your Prebid.js package with: - - -`gulp build --modules=userId,tapadIdSystem` - -#### Tapad ID Configuration - -| Param under userSync.userIds[] | Scope | Type | Description | Example | -| --- | --- | --- | --- | --- | -| name | Required | String | `"tapadId"` | `"tapadId"` | -| params | Required | Object | Details for Tapad initialization. | | -| params.company_id | Required | Number | Tapad Company Id provided by Tapad | 1234567890 | - -#### Tapad ID Example - -```js -pbjs.setConfig({ - userSync: { - userIds: [ - { - name: "tapadId", - params: { - companyId: 1234567890 - }, - storage: { - type: "cookie", - name: "tapad_id", - expires: 1 - } - } - ] - } -}); -``` diff --git a/modules/taphypeBidAdapter.js b/modules/taphypeBidAdapter.js deleted file mode 100644 index 65c5a728127..00000000000 --- a/modules/taphypeBidAdapter.js +++ /dev/null @@ -1,45 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; - -export const spec = { - code: 'taphype', - isBidRequestValid: function (bid) { - return !!bid.params.placementId; - }, - buildRequests: function (bidRequests) { - const requests = bidRequests.map(function (bid) { - const params = { - placementId: bid.params.placementId, - url: encodeURIComponent(window.location.href), - size: bid.sizes[0][0] + 'x' + bid.sizes[0][1], - rnd: Math.random(), - bidId: bid.bidId, - }; - - return {method: 'GET', url: 'https://us-central1-taphype-internal.cloudfunctions.net/th-prebid', data: params, options: {withCredentials: false}} - }); - - return requests; - }, - interpretResponse: function (serverResponse, bidRequest) { - if (!serverResponse || !serverResponse.body || !serverResponse.body.ad) { - return []; - } - - const bid = serverResponse.body; - const sizes = bid.size.split(','); - - return [{ - requestId: bidRequest.data.bidId, - cpm: bid.price, - width: sizes[0], - height: sizes[1], - creativeId: bidRequest.data.bidId, - currency: bid.currency || 'USD', - netRevenue: true, - ad: bid.ad, - ttl: 360 - }]; - }, -}; - -registerBidder(spec); diff --git a/modules/taphypeBidAdapter.md b/modules/taphypeBidAdapter.md deleted file mode 100644 index c6ff40a42ba..00000000000 --- a/modules/taphypeBidAdapter.md +++ /dev/null @@ -1,32 +0,0 @@ -# Overview - -Module Name: TapHype Bidder Adapter -Module Type: Bidder Adapter -Maintainer: admin@taphype.com - -# Description - -You can use this adapter to get a bid from taphype.com. - - -# Test Parameters -```javascript - var adUnits = [ - { - code: 'div-taphype-example', - sizes: [[300, 250]], - bids: [ - { - bidder: "taphype", - params: { - placementId: 12345 - } - } - ] - } - ]; -``` - -Where: - -* placementId - TapHype Placement ID diff --git a/modules/tappxBidAdapter.js b/modules/tappxBidAdapter.js deleted file mode 100644 index 566795a204b..00000000000 --- a/modules/tappxBidAdapter.js +++ /dev/null @@ -1,417 +0,0 @@ -'use strict'; - -import * as utils 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 BIDDER_CODE = 'tappx'; -const TTL = 360; -const CUR = 'USD'; -const TAPPX_BIDDER_VERSION = '0.1.10514'; -const TYPE_CNN = 'prebidjs'; -const VIDEO_SUPPORT = ['instream']; - -var hostDomain; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - return validBasic(bid) && validMediaType(bid) - }, - - /** - * Takes an array of valid bid requests, all of which are guaranteed to have passed the isBidRequestValid() test. - * Make a server request from the list of BidRequests. - * - * @param {*} validBidRequests - * @param {*} bidderRequest - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests, bidderRequest) { - let requests = []; - validBidRequests.forEach(oneValidRequest => { - requests.push(buildOneRequest(oneValidRequest, bidderRequest)); - }); - return requests; - }, - - /** - * Parse the response and generate one or more bid objects. - * - * @param {*} serverResponse - * @param {*} originalRequest - */ - interpretResponse: function(serverResponse, originalRequest) { - const responseBody = serverResponse.body; - if (!serverResponse.body) { - utils.logWarn('[TAPPX]: Empty response body HTTP 204, no bids'); - return []; - } - - const bids = []; - responseBody.seatbid.forEach(serverSeatBid => { - serverSeatBid.bid.forEach(serverBid => { - bids.push(interpretBid(serverBid, originalRequest)); - }); - }); - - return bids; - }, - - /** - * If the publisher allows user-sync activity, the platform will call this function and the adapter may register pixels and/or iframe user syncs. - * - * @param {*} syncOptions - * @param {*} serverResponses - * @param {*} gdprConsent - */ - getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { - let url = `https://${hostDomain}/cs/usersync.php?`; - - // GDPR & CCPA - if (gdprConsent) { - url += '&gdpr=' + (gdprConsent.gdprApplies ? 1 : 0); - url += '&gdpr_consent=' + encodeURIComponent(gdprConsent.consentString || ''); - } - if (uspConsent) { - url += '&us_privacy=' + encodeURIComponent(uspConsent); - } - - // SyncOptions - if (syncOptions.iframeEnabled) { - url += '&type=iframe' - return [{ - type: 'iframe', - url: url - }]; - } else { - url += '&type=img' - return [{ - type: 'image', - url: url - }]; - } - } -} - -function validBasic(bid) { - if (bid.params == null) { - utils.logWarn(`[TAPPX]: Please review the mandatory Tappx parameters.`); - return false; - } - - if (bid.params.tappxkey == null) { - utils.logWarn(`[TAPPX]: Please review the mandatory Tappxkey parameter.`); - return false; - } - - if (bid.params.host == null) { - utils.logWarn(`[TAPPX]: Please review the mandatory Host parameter.`); - return false; - } - - let classicEndpoint = true - if ((new RegExp(`^(vz.*|zz.*)\.*$`, 'i')).test(bid.params.host)) { - classicEndpoint = false - } - - if (classicEndpoint && bid.params.endpoint == null) { - utils.logWarn(`[TAPPX]: Please review the mandatory endpoint Tappx parameters.`); - return false; - } - - return true; -} - -function validMediaType(bid) { - const video = utils.deepAccess(bid, 'mediaTypes.video'); - - // Video validations - if (typeof video != 'undefined') { - if (VIDEO_SUPPORT.indexOf(video.context) === -1) { - utils.logWarn(`[TAPPX]: Please review the mandatory Tappx parameters for Video. Only "instream" is suported.`); - return false; - } - } - - return true; -} - -/** - * Parse the response and generate one bid object. - * - * @param {object} serverBid Bid by OpenRTB 2.5 - * @returns {object} Prebid banner bidObject - */ -function interpretBid(serverBid, request) { - let bidReturned = { - requestId: request.bids.bidId, - cpm: serverBid.price, - currency: serverBid.cur ? serverBid.cur : CUR, - width: serverBid.w, - height: serverBid.h, - ttl: TTL, - creativeId: serverBid.crid, - netRevenue: true, - } - - if (typeof serverBid.dealId != 'undefined') { bidReturned.dealId = serverBid.dealId } - - if (typeof request.bids.mediaTypes != 'undefined' && typeof request.bids.mediaTypes.video != 'undefined') { - bidReturned.vastXml = serverBid.adm; - bidReturned.vastUrl = serverBid.lurl; - bidReturned.ad = serverBid.adm; - bidReturned.mediaType = VIDEO; - } else { - bidReturned.ad = serverBid.adm; - bidReturned.mediaType = BANNER; - } - - if (typeof bidReturned.adomain != 'undefined' || bidReturned.adomain != null) { - bidReturned.meta = { advertiserDomains: request.bids.adomain }; - } - - return bidReturned; -} - -/** -* Build and makes the request -* -* @param {*} validBidRequests -* @param {*} bidderRequest -* @return response ad -*/ -function buildOneRequest(validBidRequests, bidderRequest) { - let hostInfo = getHostInfo(validBidRequests); - const ENDPOINT = hostInfo.endpoint; - hostDomain = hostInfo.domain; - - const TAPPXKEY = utils.deepAccess(validBidRequests, 'params.tappxkey'); - const BIDFLOOR = utils.deepAccess(validBidRequests, 'params.bidfloor'); - const BIDEXTRA = utils.deepAccess(validBidRequests, 'params.ext'); - const bannerMediaType = utils.deepAccess(validBidRequests, 'mediaTypes.banner'); - const videoMediaType = utils.deepAccess(validBidRequests, 'mediaTypes.video'); - const { refererInfo } = bidderRequest; - - // let requests = []; - let payload = {}; - let publisher = {}; - let tagid; - let api = {}; - - // > App/Site object - if (utils.deepAccess(validBidRequests, 'params.app')) { - let app = {}; - app.name = utils.deepAccess(validBidRequests, 'params.app.name'); - app.bundle = utils.deepAccess(validBidRequests, 'params.app.bundle'); - app.domain = utils.deepAccess(validBidRequests, 'params.app.domain'); - publisher.name = utils.deepAccess(validBidRequests, 'params.app.publisher.name'); - publisher.domain = utils.deepAccess(validBidRequests, 'params.app.publisher.domain'); - tagid = `${app.name}_typeAdBanVid_${getOs()}`; - payload.app = app; - api[0] = utils.deepAccess(validBidRequests, 'params.api') ? utils.deepAccess(validBidRequests, 'params.api') : [3, 5]; - } else { - let site = {}; - site.name = (bidderRequest && refererInfo) ? utils.parseUrl(refererInfo.referer).hostname : window.location.hostname; - site.bundle = (bidderRequest && refererInfo) ? utils.parseUrl(refererInfo.referer).hostname : window.location.hostname; - site.domain = (bidderRequest && refererInfo) ? utils.parseUrl(refererInfo.referer).hostname : window.location.hostname; - publisher.name = (bidderRequest && refererInfo) ? utils.parseUrl(refererInfo.referer).hostname : window.location.hostname; - publisher.domain = (bidderRequest && refererInfo) ? utils.parseUrl(refererInfo.referer).hostname : window.location.hostname; - tagid = `${site.name}_typeAdBanVid_${getOs()}`; - payload.site = site; - } - // < App/Site object - - // > Imp object - let imp = {}; - let w; - let h; - - if (bannerMediaType) { - let banner = {}; - w = bannerMediaType.sizes[0][0]; - h = bannerMediaType.sizes[0][1]; - banner.w = w; - banner.h = h; - if ( - ((bannerMediaType.sizes[0].indexOf(480) >= 0) && (bannerMediaType.sizes[0].indexOf(320) >= 0)) || - ((bannerMediaType.sizes[0].indexOf(768) >= 0) && (bannerMediaType.sizes[0].indexOf(1024) >= 0))) { - banner.pos = 7 - } else { - banner.pos = 4 - } - - banner.api = api; - - let format = {}; - format[0] = {}; - format[0].w = w; - format[0].h = h; - banner.format = format; - - imp.banner = banner; - } - - if (videoMediaType) { - let video = {}; - w = videoMediaType.playerSize[0][0]; - h = videoMediaType.playerSize[0][1]; - video.w = w; - video.h = h; - - video.mimes = videoMediaType.mimes; - - imp.video = video; - } - - imp.id = validBidRequests.bidId; - imp.tagid = tagid; - imp.secure = 1; - - imp.bidfloor = utils.deepAccess(validBidRequests, 'params.bidfloor'); - if (utils.isFn(validBidRequests.getFloor)) { - try { - let floor = validBidRequests.getFloor({ - currency: CUR, - mediaType: '*', - size: '*' - }); - if (utils.isPlainObject(floor) && !isNaN(floor.floor) && floor.currency === 'USD') { - imp.bidfloor = floor.floor; - } else { - utils.logWarn('[TAPPX]: ', 'Currency not valid. Use only USD with Tappx.'); - } - } catch (e) { - utils.logWarn('[TAPPX]: ', e); - imp.bidfloor = utils.deepAccess(validBidRequests, 'params.bidfloor'); // Be sure that we have an imp.bidfloor - } - } - - let bidder = {}; - bidder.tappxkey = TAPPXKEY; - bidder.endpoint = ENDPOINT; - bidder.host = hostInfo.url; - bidder.bidfloor = BIDFLOOR; - bidder.ext = (typeof BIDEXTRA == 'object') ? BIDEXTRA : undefined; - - imp.ext = {}; - imp.ext.bidder = bidder; - // < Imp object - - // > Device object - let device = {}; - // Mandatory - device.os = getOs(); - device.ip = 'peer'; - device.ua = navigator.userAgent; - device.ifa = validBidRequests.ifa; - - // Optional - device.h = screen.height; - device.w = screen.width; - device.dnt = utils.getDNT() ? 1 : 0; - device.language = getLanguage(); - device.make = navigator.vendor ? navigator.vendor : ''; - - let geo = {}; - geo.country = utils.deepAccess(validBidRequests, 'params.geo.country'); - // < Device object - - // > Params - let params = {}; - params.host = 'tappx.com'; - params.bidfloor = BIDFLOOR; - // < Params - - // > GDPR - let regs = {}; - regs.gdpr = 0; - if (!(bidderRequest.gdprConsent == null)) { - if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') { regs.gdpr = bidderRequest.gdprConsent.gdprApplies; } - if (regs.gdpr) { regs.consent = bidderRequest.gdprConsent.consentString; } - } - - // CCPA - regs.ext = {}; - if (!(bidderRequest.uspConsent == null)) { - regs.ext.us_privacy = bidderRequest.uspConsent; - } - - // COPPA compliance - if (config.getConfig('coppa') === true) { - regs.coppa = config.getConfig('coppa') === true ? 1 : 0; - } - - // Universal ID - const eidsArr = utils.deepAccess(validBidRequests, 'userIdAsEids'); - payload.user = { - ext: { - eids: eidsArr - } - }; - // < GDPR - - // > Payload - payload.id = validBidRequests.auctionId; - payload.test = utils.deepAccess(validBidRequests, 'params.test') ? 1 : 0; - payload.at = 1; - payload.tmax = bidderRequest.timeout ? bidderRequest.timeout : 600; - payload.bidder = BIDDER_CODE; - payload.imp = [imp]; - - payload.device = device; - payload.params = params; - payload.regs = regs; - // < Payload - - return { - method: 'POST', - url: `${hostInfo.url}?type_cnn=${TYPE_CNN}&v=${TAPPX_BIDDER_VERSION}`, - data: JSON.stringify(payload), - bids: validBidRequests - }; -} - -function getLanguage() { - const language = navigator.language ? 'language' : 'userLanguage'; - return navigator[language].split('-')[0]; -} - -function getOs() { - let ua = navigator.userAgent; - if (ua == null) { return 'unknown'; } else if (ua.match(/(iPhone|iPod|iPad)/)) { return 'ios'; } else if (ua.match(/Android/)) { return 'android'; } else if (ua.match(/Window/)) { return 'windows'; } else { return 'unknown'; } -} - -function getHostInfo(validBidRequests) { - let domainInfo = {}; - let endpoint = utils.deepAccess(validBidRequests, 'params.endpoint'); - let hostParam = utils.deepAccess(validBidRequests, 'params.host'); - - domainInfo.domain = hostParam.split('/', 1)[0]; - - let regexNewEndpoints = new RegExp(`^(vz.*|zz.*)\.pub\.tappx\.com$`, 'i'); - let regexClassicEndpoints = new RegExp(`^([a-z]{3}|testing)\.[a-z]{3}\.tappx\.com$`, 'i'); - - if (regexNewEndpoints.test(domainInfo.domain)) { - domainInfo.newEndpoint = true; - domainInfo.endpoint = domainInfo.domain.split('.', 1)[0] - domainInfo.url = `https://${hostParam}` - } else if (regexClassicEndpoints.test(domainInfo.domain)) { - domainInfo.newEndpoint = false; - domainInfo.endpoint = endpoint - domainInfo.url = `https://${hostParam}${endpoint}` - } - - return domainInfo; -} - -registerBidder(spec); diff --git a/modules/tappxBidAdapter.md b/modules/tappxBidAdapter.md deleted file mode 100644 index 776b24bb07c..00000000000 --- a/modules/tappxBidAdapter.md +++ /dev/null @@ -1,70 +0,0 @@ -# Overview -``` -Module Name: Tappx Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid@tappx.com -``` - -# Description -Module that connects to :tappx demand sources. -Suppots Banner and Instream Video. -Please use ```tappx``` as the bidder code. -Ads sizes available: [300,250], [320,50], [320,480], [480,320], [728,90], [768,1024], [1024,768] - -# Banner Test Parameters -``` - var adUnits = [ - { - code: 'banner-ad-div', - mediaTypes: { - banner: { - sizes: [[320,50]] - } - }, - bids: [ - { - bidder: "tappx", - params: { - host: "testing.ssp.tappx.com/rtb/v2/", - tappxkey: "pub-1234-android-1234", - endpoint: "ZZ1234PBJS", - bidfloor: 0.005, - test: true // Optional for testing purposes - } - } - ] - } - ]; -``` - - -# Video Test Parameters -``` - var adUnits = [ - { - code: 'video-ad-div', - renderer: { - options: { - text: "Tappx instream Video" - } - }, - mediaTypes: { - video: { - context: "instream", - mimes : [ "video/mp4", "application/javascript" ], - playerSize: [320, 250] - } - }, - bids: [{ - bidder: 'tappx', - params: { - host: "testing.ssp.tappx.com/rtb/v2/", - tappxkey: "pub-1234-desktop-1234", - endpoint: "VZ12TESTCTV", - bidfloor: 0.005, - test: true - } - }] - } - ]; -``` diff --git a/modules/teadsBidAdapter.js b/modules/teadsBidAdapter.js deleted file mode 100644 index 32be7e62bbd..00000000000 --- a/modules/teadsBidAdapter.js +++ /dev/null @@ -1,224 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -const utils = require('../src/utils.js'); -const BIDDER_CODE = 'teads'; -const GVL_ID = 132; -const ENDPOINT_URL = 'https://a.teads.tv/hb/bid-request'; -const gdprStatus = { - GDPR_APPLIES_PUBLISHER: 12, - GDPR_APPLIES_GLOBAL: 11, - GDPR_DOESNT_APPLY: 0, - CMP_NOT_FOUND_OR_ERROR: 22 -} - -export const spec = { - code: BIDDER_CODE, - gvlid: GVL_ID, - supportedMediaTypes: ['video', 'banner'], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - let isValid = false; - if (typeof bid.params !== 'undefined') { - let isValidPlacementId = _validateId(utils.getValue(bid.params, 'placementId')); - let isValidPageId = _validateId(utils.getValue(bid.params, 'pageId')); - isValid = isValidPlacementId && isValidPageId; - } - - if (!isValid) { - utils.logError('Teads placementId and pageId parameters are required. Bid aborted.'); - } - return isValid; - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests, bidderRequest) { - const bids = validBidRequests.map(buildRequestObject); - const payload = { - referrer: getReferrerInfo(bidderRequest), - pageReferrer: document.referrer, - networkBandwidth: getConnectionDownLink(window.navigator), - timeToFirstByte: getTimeToFirstByte(window), - data: bids, - deviceWidth: screen.width, - hb_version: '$prebid.version$' - }; - - if (validBidRequests[0].schain) { - payload.schain = validBidRequests[0].schain; - } - - let gdpr = bidderRequest.gdprConsent; - if (bidderRequest && gdpr) { - let isCmp = (typeof gdpr.gdprApplies === 'boolean') - let isConsentString = (typeof gdpr.consentString === 'string') - let status = isCmp - ? findGdprStatus(gdpr.gdprApplies, gdpr.vendorData, gdpr.apiVersion) - : gdprStatus.CMP_NOT_FOUND_OR_ERROR - payload.gdpr_iab = { - consent: isConsentString ? gdpr.consentString : '', - status: status, - apiVersion: gdpr.apiVersion - }; - } - - if (bidderRequest && bidderRequest.uspConsent) { - payload.us_privacy = bidderRequest.uspConsent - } - - const payloadString = JSON.stringify(payload); - return { - method: 'POST', - url: ENDPOINT_URL, - data: payloadString, - }; - }, - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse, bidderRequest) { - const bidResponses = []; - serverResponse = serverResponse.body; - - if (serverResponse.responses) { - serverResponse.responses.forEach(function (bid) { - const bidResponse = { - cpm: bid.cpm, - width: bid.width, - height: bid.height, - currency: bid.currency, - netRevenue: true, - ttl: bid.ttl, - meta: { - advertiserDomains: bid && bid.adomain ? bid.adomain : [] - }, - ad: bid.ad, - requestId: bid.bidId, - creativeId: bid.creativeId, - placementId: bid.placementId - }; - if (bid.dealId) { - bidResponse.dealId = bid.dealId - } - bidResponses.push(bidResponse); - }); - } - return bidResponses; - }, -}; - -function getReferrerInfo(bidderRequest) { - let ref = ''; - if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { - ref = bidderRequest.refererInfo.referer; - } - return ref; -} - -function getConnectionDownLink(nav) { - return nav && nav.connection && nav.connection.downlink >= 0 ? nav.connection.downlink.toString() : ''; -} - -function getTimeToFirstByte(win) { - const performance = win.performance || win.webkitPerformance || win.msPerformance || win.mozPerformance; - - const ttfbWithTimingV2 = performance && - typeof performance.getEntriesByType === 'function' && - Object.prototype.toString.call(performance.getEntriesByType) === '[object Function]' && - performance.getEntriesByType('navigation')[0] && - performance.getEntriesByType('navigation')[0].responseStart && - performance.getEntriesByType('navigation')[0].requestStart && - performance.getEntriesByType('navigation')[0].responseStart > 0 && - performance.getEntriesByType('navigation')[0].requestStart > 0 && - Math.round( - performance.getEntriesByType('navigation')[0].responseStart - performance.getEntriesByType('navigation')[0].requestStart - ); - - if (ttfbWithTimingV2) { - return ttfbWithTimingV2.toString(); - } - - const ttfbWithTimingV1 = performance && - performance.timing.responseStart && - performance.timing.requestStart && - performance.timing.responseStart > 0 && - performance.timing.requestStart > 0 && - performance.timing.responseStart - performance.timing.requestStart; - - return ttfbWithTimingV1 ? ttfbWithTimingV1.toString() : ''; -} - -function findGdprStatus(gdprApplies, gdprData, apiVersion) { - let status = gdprStatus.GDPR_APPLIES_PUBLISHER - if (gdprApplies) { - if (isGlobalConsent(gdprData, apiVersion)) status = gdprStatus.GDPR_APPLIES_GLOBAL - } else status = gdprStatus.GDPR_DOESNT_APPLY - return status; -} - -function isGlobalConsent(gdprData, apiVersion) { - return gdprData && apiVersion === 1 - ? (gdprData.hasGlobalScope || gdprData.hasGlobalConsent) - : gdprData && apiVersion === 2 - ? !gdprData.isServiceSpecific - : false -} - -function buildRequestObject(bid) { - const reqObj = {}; - let placementId = utils.getValue(bid.params, 'placementId'); - let pageId = utils.getValue(bid.params, 'pageId'); - - reqObj.sizes = getSizes(bid); - reqObj.bidId = utils.getBidIdParameter('bidId', bid); - reqObj.bidderRequestId = utils.getBidIdParameter('bidderRequestId', bid); - reqObj.placementId = parseInt(placementId, 10); - reqObj.pageId = parseInt(pageId, 10); - reqObj.adUnitCode = utils.getBidIdParameter('adUnitCode', bid); - reqObj.auctionId = utils.getBidIdParameter('auctionId', bid); - reqObj.transactionId = utils.getBidIdParameter('transactionId', bid); - return reqObj; -} - -function getSizes(bid) { - return utils.parseSizesInput(concatSizes(bid)); -} - -function concatSizes(bid) { - let playerSize = utils.deepAccess(bid, 'mediaTypes.video.playerSize'); - let videoSizes = utils.deepAccess(bid, 'mediaTypes.video.sizes'); - let bannerSizes = utils.deepAccess(bid, 'mediaTypes.banner.sizes'); - - if (utils.isArray(bannerSizes) || utils.isArray(playerSize) || utils.isArray(videoSizes)) { - let mediaTypesSizes = [bannerSizes, videoSizes, playerSize]; - return mediaTypesSizes - .reduce(function(acc, currSize) { - if (utils.isArray(currSize)) { - if (utils.isArray(currSize[0])) { - currSize.forEach(function (childSize) { acc.push(childSize) }) - } else { - acc.push(currSize); - } - } - return acc; - }, []) - } else { - return bid.sizes; - } -} - -function _validateId(id) { - return (parseInt(id) > 0); -} - -registerBidder(spec); diff --git a/modules/teadsBidAdapter.md b/modules/teadsBidAdapter.md deleted file mode 100644 index ded9323540b..00000000000 --- a/modules/teadsBidAdapter.md +++ /dev/null @@ -1,48 +0,0 @@ -# Overview - -**Module Name**: Teads Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: innov-ssp@teads.tv - -# Description - -Use `teads` as bidder. - -`placementId` & `pageId` are required and must be integers. - -## AdUnits configuration example -``` - var adUnits = [{ - code: 'your-slot_1-div', //use exactly the same code as your slot div id. - sizes: [[300, 250]], - bids: [{ - bidder: 'teads', - params: { - placementId: 12345, - pageId: 1234 - } - }] - },{ - code: 'your-slot_2-div', //use exactly the same code as your slot div id. - sizes: [[600, 800]], - bids: [{ - bidder: 'teads', - params: { - placementId: 12345, - pageId: 1234 - } - }] - }]; -``` - -## UserSync example - -``` -pbjs.setConfig({ - userSync: { - iframeEnabled: true, - syncEnabled: true, - syncDelay: 1 - } -}); -``` diff --git a/modules/telariaBidAdapter.js b/modules/telariaBidAdapter.js deleted file mode 100644 index b2904045144..00000000000 --- a/modules/telariaBidAdapter.js +++ /dev/null @@ -1,294 +0,0 @@ -import * as utils from '../src/utils.js'; -import {createBid as createBidFactory} from '../src/bidfactory.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {VIDEO} from '../src/mediaTypes.js'; -import {STATUS} from '../src/constants.json'; - -const BIDDER_CODE = 'telaria'; -const DOMAIN = 'tremorhub.com'; -const TAG_ENDPOINT = `ads.${DOMAIN}/ad/tag`; -const EVENTS_ENDPOINT = `events.${DOMAIN}/diag`; - -export const spec = { - code: BIDDER_CODE, - aliases: ['tremor', 'tremorvideo'], - supportedMediaTypes: [VIDEO], - /** - * Determines if the request is valid - * @param bid - * @returns {*|string} - */ - isBidRequestValid: function (bid) { - return !!(bid && bid.params && bid.params.adCode && bid.params.supplyCode); - }, - - /** - * Make a server request from the list of BidRequests. - * @param validBidRequests list of valid bid requests that have passed isBidRequestValid check - * @param bidderRequest - * @returns {Array} of url objects - */ - buildRequests: function (validBidRequests, bidderRequest) { - let requests = []; - - validBidRequests.forEach(bid => { - let url = generateUrl(bid, bidderRequest); - if (url) { - requests.push({ - method: 'GET', - url: url, - bidId: bid.bidId, - vastUrl: url.split('&fmt=json')[0] - }); - } - }); - - return requests; - }, - - /** - * convert the server response into a list of BidObjects that prebid accepts - * http://prebid.org/dev-docs/bidder-adaptor.html#interpreting-the-response - * @param serverResponse - * @param bidderRequest - * @returns {Array} - */ - interpretResponse: function (serverResponse, bidderRequest) { - let bidResult; - let width, height; - - let bids = []; - - try { - bidResult = serverResponse.body; - - bidderRequest.url.split('&').forEach(param => { - let lower = param.toLowerCase(); - if (lower.indexOf('player') > -1) { - if (lower.indexOf('width') > -1) { - width = param.split('=')[1]; - } else if (lower.indexOf('height') > -1) { - height = param.split('=')[1]; - } - } - }); - } catch (error) { - utils.logError(error); - width = 0; - height = 0; - } - - if (!bidResult || bidResult.error) { - let errorMessage = `in response for ${bidderRequest.bidderCode} adapter`; - if (bidResult && bidResult.error) { - errorMessage += `: ${bidResult.error}`; - } - utils.logError(errorMessage); - } else if (!utils.isEmpty(bidResult.seatbid)) { - bidResult.seatbid[0].bid.forEach(tag => { - bids.push(createBid(STATUS.GOOD, bidderRequest, tag, width, height, BIDDER_CODE)); - }); - } - - return bids; - }, - /** - * We support pixel syncing only at the moment. Telaria ad server returns 'ext' - * as an optional parameter if the tag has 'incIdSync' parameter set to true - * @param syncOptions - * @param serverResponses - * @returns {Array} - */ - getUserSyncs: function (syncOptions, serverResponses) { - const syncs = []; - if (syncOptions.pixelEnabled && serverResponses.length) { - (utils.deepAccess(serverResponses, '0.body.ext.telaria.userSync') || []).forEach(url => syncs.push({type: 'image', url: url})); - } - return syncs; - }, - - /** - * See http://prebid.org/dev-docs/bidder-adaptor.html#registering-on-timeout for detailed semantic. - * @param timeoutData bidRequest - */ - onTimeout: function (timeoutData) { - let url = getTimeoutUrl(timeoutData); - if (url) { - utils.triggerPixel(url); - } - } -}; - -function getDefaultSrcPageUrl() { - return encodeURIComponent(document.location.href); -} - -function getEncodedValIfNotEmpty(val) { - return (val !== '' && val !== undefined) ? encodeURIComponent(val) : ''; -} - -/** - * Converts the schain object to a url param value. Please refer to - * https://github.com/InteractiveAdvertisingBureau/openrtb/blob/master/supplychainobject.md - * (schain for non ORTB section) for more information - * @param schainObject - * @returns {string} - */ -function getSupplyChainAsUrlParam(schainObject) { - if (utils.isEmpty(schainObject)) { - return ''; - } - - let scStr = `&schain=${schainObject.ver},${schainObject.complete}`; - - schainObject.nodes.forEach((node) => { - scStr += '!'; - scStr += `${getEncodedValIfNotEmpty(node.asi)},`; - scStr += `${getEncodedValIfNotEmpty(node.sid)},`; - scStr += `${getEncodedValIfNotEmpty(node.hp)},`; - scStr += `${getEncodedValIfNotEmpty(node.rid)},`; - scStr += `${getEncodedValIfNotEmpty(node.name)},`; - scStr += `${getEncodedValIfNotEmpty(node.domain)}`; - }); - - return scStr; -} - -function getUrlParams(params, schainFromBidRequest) { - let urlSuffix = ''; - - if (!utils.isEmpty(params)) { - for (let key in params) { - if (key !== 'schain' && params.hasOwnProperty(key) && !utils.isEmpty(params[key])) { - urlSuffix += `&${key}=${params[key]}`; - } - } - urlSuffix += getSupplyChainAsUrlParam(!utils.isEmpty(schainFromBidRequest) ? schainFromBidRequest : params['schain']); - } - - return urlSuffix; -} - -export const getTimeoutUrl = function(timeoutData) { - let params = utils.deepAccess(timeoutData, '0.params.0'); - - if (!utils.isEmpty(params)) { - let url = `https://${EVENTS_ENDPOINT}`; - - params = Object.assign({ - srcPageUrl: getDefaultSrcPageUrl() - }, params); - - url += `${getUrlParams(params)}`; - - url += '&hb=1&evt=TO'; - - return url; - } -}; - -/** - * Generates the url based on the parameters given. Sizes, supplyCode & adCode are required. - * The format is: [L,W] or [[L1,W1],...] - * @param bid - * @param bidderRequest - * @returns {string} - */ -function generateUrl(bid, bidderRequest) { - let playerSize = utils.deepAccess(bid, 'mediaTypes.video.playerSize'); - if (!playerSize) { - utils.logWarn(`Although player size isn't required it is highly recommended`); - } - - let width, height; - if (playerSize) { - if (utils.isArray(playerSize) && (playerSize.length === 2) && (!isNaN(playerSize[0]) && !isNaN(playerSize[1]))) { - width = playerSize[0]; - height = playerSize[1]; - } else if (typeof playerSize === 'object') { - width = playerSize[0][0]; - height = playerSize[0][1]; - } - } - - let supplyCode = utils.deepAccess(bid, 'params.supplyCode'); - let adCode = utils.deepAccess(bid, 'params.adCode'); - - if (supplyCode && adCode) { - let url = `https://${supplyCode}.${TAG_ENDPOINT}?adCode=${adCode}`; - - if (width) { - url += (`&playerWidth=${width}`); - } - if (height) { - url += (`&playerHeight=${height}`); - } - - const params = Object.assign({ - srcPageUrl: getDefaultSrcPageUrl() - }, bid.params); - delete params.adCode; - - url += `${getUrlParams(params, bid.schain)}`; - - url += (`&transactionId=${bid.transactionId}`); - - if (bidderRequest) { - if (bidderRequest.gdprConsent) { - if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') { - url += (`&gdpr=${(bidderRequest.gdprConsent.gdprApplies ? 1 : 0)}`); - } - if (bidderRequest.gdprConsent.consentString) { - url += (`&gdpr_consent=${bidderRequest.gdprConsent.consentString}`); - } - } - - if (bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { - url += (`&referrer=${encodeURIComponent(bidderRequest.refererInfo.referer)}`); - } - } - - return (url + '&hb=1&fmt=json'); - } -} - -/** - * Create and return a bid object based on status and tag - * @param status - * @param reqBid - * @param response - * @param width - * @param height - * @param bidderCode - */ -function createBid(status, reqBid, response, width, height, bidderCode) { - let bid = createBidFactory(status, reqBid); - - // TTL 5 mins by default, future support for extended imp wait time - if (response) { - Object.assign(bid, { - requestId: reqBid.bidId, - cpm: response.price, - creativeId: response.crid || '-1', - vastXml: response.adm, - vastUrl: reqBid.vastUrl, - mediaType: 'video', - width: width, - height: height, - bidderCode: bidderCode, - currency: 'USD', - netRevenue: true, - ttl: 300, - ad: response.adm - }); - } - - bid.meta = bid.meta || {}; - if (response && response.adomain && response.adomain.length > 0) { - bid.meta.advertiserDomains = response.adomain; - } - - return bid; -} - -registerBidder(spec); diff --git a/modules/telariaBidAdapter.md b/modules/telariaBidAdapter.md deleted file mode 100644 index 6a5e24e9a5e..00000000000 --- a/modules/telariaBidAdapter.md +++ /dev/null @@ -1,37 +0,0 @@ -# Overview - -``` -Module Name: Telaria Bid Adapter -Module Type: Bidder Adapter -Maintainer: github@telaria.com -``` - -# Description - -Connects to Telaria's exchange. - -Telaria bid adapter supports insteream Video. - -# Test Parameters -``` -{ - code: 'video1', - mediaTypes: { - 'video': { - playerSize: [640, 480], - context: 'instream' - } - }, - bids: [{ - bidder: 'telaria', - params: { - supplyCode: 'ssp-demo-rm6rh', - adCode: 'ssp-!demo!-lufip', - videoId: 'MyCoolVideo' - } - }] -} -``` - -# Example: -https://console.telaria.com/examples/hb/headerbidding.jsp diff --git a/modules/temedyaBidAdapter.js b/modules/temedyaBidAdapter.js deleted file mode 100644 index 4577fb295cd..00000000000 --- a/modules/temedyaBidAdapter.js +++ /dev/null @@ -1,144 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'temedya'; -const ENDPOINT_URL = 'https://adm.vidyome.com/'; -const ENDPOINT_METHOD = 'GET'; -const CURRENCY = 'TRY'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, NATIVE], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return !!(bid.params.widgetId); - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - return validBidRequests.map(req => { - const mediaType = this._isBannerRequest(req) ? 'display' : NATIVE; - const data = { - wid: req.params.widgetId, - type: mediaType, - count: (req.params.count > 6 ? 6 : req.params.count) || 1, - mediaType: mediaType, - requestid: req.bidId - }; - if (mediaType === 'display') { - data.sizes = utils.parseSizesInput( - req.mediaTypes && req.mediaTypes.banner && req.mediaTypes.banner.sizes - ).join('|') - } - /** @type {ServerRequest} */ - return { - method: ENDPOINT_METHOD, - url: ENDPOINT_URL, - data: utils.parseQueryStringParameters(data), - options: { withCredentials: false, requestId: req.bidId, mediaType: mediaType } - }; - }); - }, - /** - * Unpack the 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. - */ - interpretResponse: function (serverResponse, bidRequest) { - try { - const bidResponse = serverResponse.body; - const bidResponses = []; - if (bidResponse && bidRequest.options.mediaType == NATIVE) { - bidResponse.ads.forEach(function(ad) { - bidResponses.push({ - requestId: bidRequest.options.requestId, - cpm: parseFloat(ad.assets.cpm) || 1, - width: 320, - height: 240, - creativeId: ad.assets.id, - currency: ad.currency || CURRENCY, - netRevenue: false, - mediaType: NATIVE, - ttl: 360, - native: { - title: ad.assets.title, - body: ad.assets.body || '', - icon: { - url: ad.assets.files[0], - width: 320, - height: 240 - }, - image: { - url: ad.assets.files[0], - width: 320, - height: 240 - }, - privacyLink: '', - clickUrl: ad.assets.click_url, - displayUrl: ad.assets.click_url, - cta: '', - sponsoredBy: ad.assets.sponsor || '', - impressionTrackers: [bidResponse.base.widget.impression + '&ids=' + ad.id + ':' + ad.assets.id], - }, - }); - }); - } else if (bidResponse && bidRequest.options.mediaType == 'display') { - bidResponse.ads.forEach(function(ad) { - let w = ad.assets.width || 300; - let h = ad.assets.height || 250; - let htmlTag = ''; - htmlTag += ''; - bidResponses.push({ - requestId: bidRequest.options.requestId, - cpm: parseFloat(ad.assets.cpm) || 1, - width: w, - height: h, - creativeId: ad.assets.id, - currency: ad.currency || CURRENCY, - netRevenue: false, - ttl: 360, - mediaType: BANNER, - ad: htmlTag - }); - }); - } - return bidResponses; - } catch (err) { - utils.logError(err); - return []; - } - }, - /** - * @param {BidRequest} req - * @return {boolean} - * @private - */ - _isBannerRequest(req) { - return !!(req.mediaTypes && req.mediaTypes.banner); - } -} -registerBidder(spec); diff --git a/modules/temedyaBidAdapter.md b/modules/temedyaBidAdapter.md deleted file mode 100644 index 31ac4f3689b..00000000000 --- a/modules/temedyaBidAdapter.md +++ /dev/null @@ -1,64 +0,0 @@ -# Overview - -Module Name: TE Medya Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid@temedya.com - -# Description - -Module that connects to TE Medya's demand sources. - -TE Medya supports Native and Banner. - - -# Test Parameters -# Native -``` - - var adUnits = [ - { - code:'tme_div_id', - mediaTypes:{ - native: { - title: { - required: true - } - } - }, - bids:[ - { - bidder: 'temedya', - params: { - widgetId: 753497, - count: 1 - } - } - ] - } - ]; -``` -# Test Parameters -# Banner -``` - - var adUnits = [ - { - code:'tme_div_id', - mediaTypes:{ - banner: { - banner: { - sizes:[300, 250] - } - } - }, - bids:[ - { - bidder: 'temedya', - params: { - widgetId: 753497 - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/terceptAnalyticsAdapter.js b/modules/terceptAnalyticsAdapter.js deleted file mode 100644 index 54da2bd06d2..00000000000 --- a/modules/terceptAnalyticsAdapter.js +++ /dev/null @@ -1,144 +0,0 @@ -import { ajax } from '../src/ajax.js'; -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -import CONSTANTS from '../src/constants.json'; -import * as utils from '../src/utils.js'; - -const emptyUrl = ''; -const analyticsType = 'endpoint'; -const terceptAnalyticsVersion = 'v1.0.0'; -const defaultHostName = 'us-central1-quikr-ebay.cloudfunctions.net'; -const defaultPathName = '/prebid-analytics'; - -let initOptions; -let auctionTimestamp; -let events = { - bids: [] -}; - -var terceptAnalyticsAdapter = Object.assign(adapter( - { - emptyUrl, - analyticsType - }), { - track({ eventType, args }) { - if (typeof args !== 'undefined') { - if (eventType === CONSTANTS.EVENTS.BID_TIMEOUT) { - args.forEach(item => { mapBidResponse(item, 'timeout'); }); - } else if (eventType === CONSTANTS.EVENTS.AUCTION_INIT) { - events.auctionInit = args; - auctionTimestamp = args.timestamp; - } else if (eventType === CONSTANTS.EVENTS.BID_REQUESTED) { - mapBidRequests(args).forEach(item => { events.bids.push(item) }); - } else if (eventType === CONSTANTS.EVENTS.BID_RESPONSE) { - mapBidResponse(args, 'response'); - } else if (eventType === CONSTANTS.EVENTS.BID_WON) { - send({ - bidWon: mapBidResponse(args, 'win') - }, 'won'); - } - } - - if (eventType === CONSTANTS.EVENTS.AUCTION_END) { - send(events, 'auctionEnd'); - } - } -}); - -function mapBidRequests(params) { - let arr = []; - if (typeof params.bids !== 'undefined' && params.bids.length) { - params.bids.forEach(function (bid) { - arr.push({ - bidderCode: bid.bidder, - bidId: bid.bidId, - adUnitCode: bid.adUnitCode, - requestId: bid.bidderRequestId, - auctionId: bid.auctionId, - transactionId: bid.transactionId, - sizes: utils.parseSizesInput(bid.mediaTypes.banner.sizes).toString(), - renderStatus: 1, - requestTimestamp: params.auctionStart - }); - }); - } - return arr; -} - -function mapBidResponse(bidResponse, status) { - if (status !== 'win') { - let bid = events.bids.filter(o => o.bidId === bidResponse.bidId || o.bidId === bidResponse.requestId)[0]; - Object.assign(bid, { - bidderCode: bidResponse.bidder, - bidId: status === 'timeout' ? bidResponse.bidId : bidResponse.requestId, - adUnitCode: bidResponse.adUnitCode, - auctionId: bidResponse.auctionId, - creativeId: bidResponse.creativeId, - transactionId: bidResponse.transactionId, - currency: bidResponse.currency, - cpm: bidResponse.cpm, - netRevenue: bidResponse.netRevenue, - mediaType: bidResponse.mediaType, - statusMessage: bidResponse.statusMessage, - status: bidResponse.status, - renderStatus: status === 'timeout' ? 3 : 2, - timeToRespond: bidResponse.timeToRespond, - requestTimestamp: bidResponse.requestTimestamp, - responseTimestamp: bidResponse.responseTimestamp - }); - } else { - return { - bidderCode: bidResponse.bidder, - bidId: bidResponse.requestId, - adUnitCode: bidResponse.adUnitCode, - auctionId: bidResponse.auctionId, - creativeId: bidResponse.creativeId, - transactionId: bidResponse.transactionId, - currency: bidResponse.currency, - cpm: bidResponse.cpm, - netRevenue: bidResponse.netRevenue, - renderedSize: bidResponse.size, - mediaType: bidResponse.mediaType, - statusMessage: bidResponse.statusMessage, - status: bidResponse.status, - renderStatus: 4, - timeToRespond: bidResponse.timeToRespond, - requestTimestamp: bidResponse.requestTimestamp, - responseTimestamp: bidResponse.responseTimestamp - } - } -} - -function send(data, status) { - let location = utils.getWindowLocation(); - if (typeof data !== 'undefined' && typeof data.auctionInit !== 'undefined') { - Object.assign(data.auctionInit, { host: location.host, path: location.pathname, search: location.search }); - } - data.initOptions = initOptions; - - let terceptAnalyticsRequestUrl = utils.buildUrl({ - protocol: 'https', - hostname: (initOptions && initOptions.hostName) || defaultHostName, - pathname: (initOptions && initOptions.pathName) || defaultPathName, - search: { - auctionTimestamp: auctionTimestamp, - terceptAnalyticsVersion: terceptAnalyticsVersion, - prebidVersion: $$PREBID_GLOBAL$$.version - } - }); - - ajax(terceptAnalyticsRequestUrl, undefined, JSON.stringify(data), { method: 'POST', contentType: 'text/plain' }); -} - -terceptAnalyticsAdapter.originEnableAnalytics = terceptAnalyticsAdapter.enableAnalytics; -terceptAnalyticsAdapter.enableAnalytics = function (config) { - initOptions = config.options; - terceptAnalyticsAdapter.originEnableAnalytics(config); -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: terceptAnalyticsAdapter, - code: 'tercept' -}); - -export default terceptAnalyticsAdapter; diff --git a/modules/terceptAnalyticsAdapter.md b/modules/terceptAnalyticsAdapter.md deleted file mode 100644 index 39578d06730..00000000000 --- a/modules/terceptAnalyticsAdapter.md +++ /dev/null @@ -1,22 +0,0 @@ -# Overview -Module Name: Tercept Analytics Adapter -Module Type: Analytics Adapter -Maintainer: gourav.chindlur@tercept.com - -# Description - -Analytics adapter for prebid provided by Tercept. Contact gourav.chindlur@tercept.com for information. - -# Test Parameters - -``` -{ - provider: 'Tercept', - options : { - pubId : 50357 //id provided by Tercept - pubKey: 'xxx' //key provided by Tercept - hostName: 'us-central1-quikr-ebay.cloudfunctions.net' //Tercept endpoint host - pathName: '/prebid-analytics' //Tercept endpoint path - } -} -``` diff --git a/modules/theAdxBidAdapter.js b/modules/theAdxBidAdapter.js deleted file mode 100644 index 91e36077e88..00000000000 --- a/modules/theAdxBidAdapter.js +++ /dev/null @@ -1,495 +0,0 @@ -import * as utils from '../src/utils.js'; -import { - BANNER, - NATIVE, - VIDEO -} from '../src/mediaTypes.js'; -import { - registerBidder -} from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'theadx'; -const ENDPOINT_URL = 'https://ssp.theadx.com/request'; - -const NATIVEASSETNAMES = { - 0: 'title', - 1: 'cta', - 2: 'icon', - 3: 'image', - 4: 'body', - 5: 'sponsoredBy', - 6: 'body2', - 7: 'phone', - 8: 'privacyLink', - 9: 'displayurl', - 10: 'rating', - 11: 'address', - 12: 'downloads', - 13: 'likes', - 14: 'price', - 15: 'saleprice', - -}; -const NATIVEPROBS = { - title: { - id: 0, - name: 'title' - }, - body: { - id: 4, - name: 'data', - type: 2 - }, - body2: { - id: 6, - name: 'data', - type: 10 - }, - privacyLink: { - id: 8, - name: 'data', - type: 501 - }, - sponsoredBy: { - id: 5, - name: 'data', - type: 1 - }, - image: { - id: 3, - type: 3, - name: 'img' - }, - icon: { - id: 2, - type: 1, - name: 'img' - }, - displayurl: { - id: 9, - name: 'data', - type: 11 - }, - cta: { - id: 1, - type: 12, - name: 'data' - }, - rating: { - id: 7, - name: 'data', - type: 3 - }, - address: { - id: 11, - name: 'data', - type: 5 - }, - downloads: { - id: 12, - name: 'data', - type: 5 - }, - likes: { - id: 13, - name: 'data', - type: 4 - }, - phone: { - id: 7, - name: 'data', - type: 8 - }, - price: { - id: 14, - name: 'data', - type: 6 - }, - saleprice: { - id: 15, - name: 'data', - type: 7 - }, - -}; - -export const spec = { - code: BIDDER_CODE, - aliases: ['theadx'], // short code - supportedMediaTypes: [BANNER, VIDEO, NATIVE], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - utils.logInfo('theadx.isBidRequestValid', bid); - let res = false; - if (bid && bid.params) { - res = !!(bid.params.pid && bid.params.tagId); - } - - return res; - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - utils.logInfo('theadx.buildRequests', 'validBidRequests', validBidRequests, 'bidderRequest', bidderRequest); - let results = []; - const requestType = 'POST'; - if (!utils.isEmpty(validBidRequests)) { - results = validBidRequests.map( - bidRequest => { - return { - method: requestType, - type: requestType, - url: `${ENDPOINT_URL}?tagid=${bidRequest.params.tagId}`, - options: { - withCredentials: true, - }, - bidder: 'theadx', - referrer: encodeURIComponent(bidderRequest.refererInfo.referer), - data: generatePayload(bidRequest, bidderRequest), - mediaTypes: bidRequest['mediaTypes'], - requestId: bidderRequest.bidderRequestId, - bidId: bidRequest.bidId, - adUnitCode: bidRequest['adUnitCode'], - auctionId: bidRequest['auctionId'], - }; - } - ); - } - return results; - }, - - /** - * Unpack the 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. - */ - interpretResponse: (serverResponse, request) => { - utils.logInfo('theadx.interpretResponse', 'serverResponse', serverResponse, ' request', request); - - let responses = []; - - if (serverResponse.body) { - let responseBody = serverResponse.body; - - let seatBids = responseBody.seatbid; - - if (!(utils.isEmpty(seatBids) || - utils.isEmpty(seatBids[0].bid))) { - let seatBid = seatBids[0]; - let bid = seatBid.bid[0]; - - // handle any values that may end up undefined - let nullify = (value) => typeof value === 'undefined' ? null : parseInt(value); - - let ttl = null; - if (bid.ext) { - ttl = nullify(bid.ext.ttl) ? nullify(bid.ext.ttl) : 2000; - } - - let bidWidth = nullify(bid.w); - let bidHeight = nullify(bid.h); - - let creative = null - let videoXml = null; - let mediaType = null; - let native = null; - - if (request.mediaTypes && request.mediaTypes.video) { - videoXml = bid.ext.vast_url; - mediaType = VIDEO; - } else if (request.mediaTypes && request.mediaTypes.banner) { - mediaType = BANNER; - creative = bid.adm; - } else if (request.mediaTypes && request.mediaTypes.native) { - mediaType = NATIVE; - const { - assets, - link, - imptrackers, - jstracker - } = bid.ext.native; - native = { - clickUrl: link.url, - clickTrackers: link.clicktrackers || bid.ext.cliu ? [] : undefined, - impressionTrackers: imptrackers || bid.nurl ? [] : undefined, - javascriptTrackers: jstracker ? [jstracker] : undefined - }; - if (bid.nurl) { - native.impressionTrackers.unshift(bid.ext.impu); - native.impressionTrackers.unshift(bid.nurl); - if (native.clickTrackers) { - native.clickTrackers.unshift(bid.ext.cliu); - } - } - - assets.forEach(asset => { - const kind = NATIVEASSETNAMES[asset.id]; - const content = kind && asset[NATIVEPROBS[kind].name]; - if (content) { - native[kind] = content.text || content.value || { - url: content.url, - width: content.w, - height: content.h - }; - } - }); - } - - let response = { - bidderCode: BIDDER_CODE, - requestId: request.bidId, - cpm: bid.price, - width: bidWidth | 0, - height: bidHeight | 0, - ad: creative, - ttl: ttl || 3000, - creativeId: bid.crid, - netRevenue: true, - currency: responseBody.cur, - mediaType: mediaType, - native: native, - }; - if (mediaType == VIDEO && videoXml) { - response.vastUrl = videoXml; - response.videoCacheKey = bid.ext.rid; - } - - responses.push(response); - } - } - return responses; - }, - - /** - * Register the user sync pixels which should be dropped after the auction. - * - * @param {SyncOptions} syncOptions Which user syncs are allowed? - * @param {ServerResponse[]} serverResponses List of server's responses. - * @return {UserSync[]} The user syncs which should be dropped. - */ - getUserSyncs: function (syncOptions, serverResponses) { - utils.logInfo('theadx.getUserSyncs', 'syncOptions', syncOptions, 'serverResponses', serverResponses) - const syncs = []; - - if (!syncOptions.iframeEnabled && !syncOptions.pixelEnabled) { - return syncs; - } - - serverResponses.forEach(resp => { - const syncIframeUrls = utils.deepAccess(resp, 'body.ext.sync.iframe'); - const syncImageUrls = utils.deepAccess(resp, 'body.ext.sync.image'); - if (syncOptions.iframeEnabled && syncIframeUrls) { - syncIframeUrls.forEach(syncIframeUrl => { - syncs.push({ - type: 'iframe', - url: syncIframeUrl - }); - }); - } - if (syncOptions.pixelEnabled && syncImageUrls) { - syncImageUrls.forEach(syncImageUrl => { - syncs.push({ - type: 'image', - url: syncImageUrl - }); - }); - } - }); - - return syncs; - }, - -} - -let buildSiteComponent = (bidRequest, bidderRequest) => { - let loc = utils.parseUrl(bidderRequest.refererInfo.referer, { - decodeSearchAsString: true - }); - - let site = { - domain: loc.hostname, - page: loc.href, - id: bidRequest.params.wid, - publisher: { - id: bidRequest.params.pid, - } - }; - if (loc.search) { - site.search = loc.search; - } - if (document) { - let keywords = document.getElementsByTagName('meta')['keywords']; - if (keywords && keywords.content) { - site.keywords = keywords.content; - } - } - - return site; -} - -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); -} - -let buildDeviceComponent = (bidRequest, bidderRequest) => { - let device = { - js: 1, - language: ('language' in navigator) ? navigator.language : null, - ua: ('userAgent' in navigator) ? navigator.userAgent : null, - devicetype: isMobile() ? 1 : isConnectedTV() ? 3 : 2, - dnt: utils.getDNT() ? 1 : 0, - }; - // Include connection info if available - const CONNECTION = navigator.connection || navigator.webkitConnection; - if (CONNECTION && CONNECTION.type) { - device['connectiontype'] = CONNECTION.type; - if (CONNECTION.downlinkMax) { - device['connectionDownlinkMax'] = CONNECTION.downlinkMax; - } - } - - return device; -}; - -let determineOptimalRequestId = (bidRequest, bidderRequest) => { - return bidRequest.bidId; -} - -let extractValidSize = (bidRequest, bidderRequest) => { - let width = null; - let height = null; - - let requestedSizes = []; - let mediaTypes = bidRequest.mediaTypes; - if (mediaTypes && ((mediaTypes.banner && mediaTypes.banner.sizes) || (mediaTypes.video && mediaTypes.video.sizes))) { - if (mediaTypes.banner) { - requestedSizes = mediaTypes.banner.sizes; - } else { - requestedSizes = mediaTypes.video.sizes; - } - } else if (!utils.isEmpty(bidRequest.sizes)) { - requestedSizes = bidRequest.sizes - } - - // Ensure the size array is normalized - let conformingSize = utils.parseSizesInput(requestedSizes); - - if (!utils.isEmpty(conformingSize) && conformingSize[0] != null) { - // Currently only the first size is utilized - let splitSizes = conformingSize[0].split('x'); - - width = parseInt(splitSizes[0]); - height = parseInt(splitSizes[1]); - } - - return { - w: width, - h: height - }; -}; - -let generateVideoComponent = (bidRequest, bidderRequest) => { - let impSize = extractValidSize(bidRequest); - - return { - w: impSize.w, - h: impSize.h - } -} - -let generateBannerComponent = (bidRequest, bidderRequest) => { - let impSize = extractValidSize(bidRequest); - - return { - w: impSize.w, - h: impSize.h - } -} - -let generateNativeComponent = (bidRequest, bidderRequest) => { - const assets = utils._map(bidRequest.mediaTypes.native, (bidParams, key) => { - const props = NATIVEPROBS[key]; - const asset = { - required: bidParams.required & 1, - }; - if (props) { - asset.id = props.id; - asset[props.name] = { - len: bidParams.len, - wmin: bidParams.sizes && bidParams.sizes[0], - hmin: bidParams.sizes && bidParams.sizes[1], - type: props.type - }; - - return asset; - } - }).filter(Boolean); - return { - request: { - assets - } - } -} - -let generateImpBody = (bidRequest, bidderRequest) => { - let mediaTypes = bidRequest.mediaTypes; - - let banner = null; - let video = null; - let native = null; - - if (mediaTypes && mediaTypes.video) { - video = generateVideoComponent(bidRequest, bidderRequest); - } else if (mediaTypes && mediaTypes.banner) { - banner = generateBannerComponent(bidRequest, bidderRequest); - } else if (mediaTypes && mediaTypes.native) { - native = generateNativeComponent(bidRequest, bidderRequest); - } - - const result = { - id: bidRequest.index, - tagid: bidRequest.params.tagId + '', - }; - if (banner) { - result['banner'] = banner; - } - if (video) { - result['video'] = video; - } - if (native) { - result['native'] = native; - } - - return result; -} - -let generatePayload = (bidRequest, bidderRequest) => { - // Generate the expected OpenRTB payload - - let payload = { - id: determineOptimalRequestId(bidRequest, bidderRequest), - site: buildSiteComponent(bidRequest, bidderRequest), - device: buildDeviceComponent(bidRequest, bidderRequest), - imp: [generateImpBody(bidRequest, bidderRequest)], - }; - // return payload; - return JSON.stringify(payload); -}; - -registerBidder(spec); diff --git a/modules/theAdxBidAdapter.md b/modules/theAdxBidAdapter.md deleted file mode 100644 index 2392bfaa819..00000000000 --- a/modules/theAdxBidAdapter.md +++ /dev/null @@ -1,91 +0,0 @@ -# Overview - -``` -Module Name: TheAdx Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid@theadx.com -``` - -# Description - -Module that connects to TheAdx demand sources - -# Test Parameters - -``` - var adUnits = [ - { - code: 'test-div', - sizes: [640,480], - mediaTypes: { - video: { - sizes: [[640, 480]], - } - }, - bids: [ - { - bidder: "theadx", - params: { - pid: 1000, // publisher id - wid: 2000, //website id - tagId: 5000, //zone id - } - } - ] - },{ - code: 'test-div2', - mediaTypes: { - banner: { - sizes: [[320, 50]], - }, - }, - bids: [ - { - bidder: "theadx", - params: { - pid: 1000, // publisher id - wid: 2000, //website id - tagId: 5000, //zone id - } - } - ] - },{ - code: 'test-div3', - mediaTypes: { - native: { - image: { - required: false, - sizes: [100, 50] - }, - title: { - required: false, - len: 140 - }, - sponsoredBy: { - required: false - }, - clickUrl: { - required: false - }, - body: { - required: false - }, - icon: { - required: false, - sizes: [50, 50] - } - }, - }, - bids: [ - { - bidder: "theadx", - params: { - pid: 1000, // publisher id - wid: 2000, //website id - tagId: 5000, //zone id - } - } - ] - } - ]; -``` diff --git a/modules/timBidAdapter.js b/modules/timBidAdapter.js deleted file mode 100644 index 68c711f9935..00000000000 --- a/modules/timBidAdapter.js +++ /dev/null @@ -1,177 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import * as bidfactory from '../src/bidfactory.js'; -var CONSTANTS = require('../src/constants.json'); -const BIDDER_CODE = 'tim'; - -function parseBidRequest(bidRequest) { - let params = bidRequest.url.split('?')[1]; - var obj = {}; - var pairs = params.split('&'); - try { - for (var i in pairs) { - var split = pairs[i].split('='); - obj[decodeURIComponent(split[0])] = decodeURIComponent(split[1]); - } - } catch (e) { - utils.logError(e); - } - - return JSON.parse(obj.br); -} - -function formatAdMarkup(bid) { - var adm = bid.adm; - if ('nurl' in bid) { - adm += createTrackPixelHtml(bid.nurl); - } - return `${adm}`; -} - -function createTrackPixelHtml(url) { - if (!url) { - return ''; - } - let img = '
'; - img += '
'; - return img; -} - -export const spec = { - code: BIDDER_CODE, - aliases: ['timmedia'], - - isBidRequestValid: function(bid) { - if (bid.params && bid.params.publisherid && bid.params.placementCode) { - return true; - } if (!bid.params) { - utils.logError('bid not valid: params were not provided'); - } else if (!bid.params.publisherid) { - utils.logError('bid not valid: publisherid was not provided'); - } else if (!bid.params.placementCode) { - utils.logError('bid not valid: placementCode was not provided'); - } return false; - }, - - buildRequests: function(validBidRequests, bidderRequest) { - var requests = []; - for (var i = 0; i < validBidRequests.length; i++) { - requests.push(this.createRTBRequestURL(validBidRequests[i])); - } - return requests; - }, - - createRTBRequestURL: function(bidReq) { - // build bid request object - var domain = window.location.host; - var page = window.location.href; - var publisherid = bidReq.params.publisherid; - var bidFloor = bidReq.params.bidfloor; - var placementCode = bidReq.params.placementCode; - - var adW = bidReq.mediaTypes.banner.sizes[0][0]; - var adH = bidReq.mediaTypes.banner.sizes[0][1]; - - // build bid request with impressions - var bidRequest = { - id: utils.getUniqueIdentifierStr(), - imp: [{ - id: bidReq.bidId, - banner: { - w: adW, - h: adH - }, - tagid: placementCode, - bidfloor: bidFloor - }], - site: { - domain: domain, - page: page, - publisher: { - id: publisherid - } - }, - device: { - 'language': this.getLanguage(), - 'w': adW, - 'h': adH, - 'js': 1, - 'ua': navigator.userAgent - } - }; - if (!bidFloor) { - delete bidRequest.imp['bidfloor']; - } - - bidRequest.bidId = bidReq.bidId; - var url = 'https://hb.timmedia-hb.com/api/v2/services/prebid/' + publisherid + '/' + placementCode + '?' + 'br=' + encodeURIComponent(JSON.stringify(bidRequest)); - return { - method: 'GET', - url: url, - data: '', - options: {withCredentials: false} - }; - }, - - interpretResponse: function(serverResponse, bidRequest) { - bidRequest = parseBidRequest(bidRequest); - var bidResp = serverResponse.body; - const bidResponses = []; - if ((!bidResp || !bidResp.id) || - (!bidResp.seatbid || bidResp.seatbid.length === 0 || !bidResp.seatbid[0].bid || bidResp.seatbid[0].bid.length === 0)) { - return []; - } - bidResp.seatbid[0].bid.forEach(function (bidderBid) { - var responseCPM; - var placementCode = ''; - if (bidRequest) { - var bidResponse = bidfactory.createBid(1); - placementCode = bidRequest.placementCode; - bidRequest.status = CONSTANTS.STATUS.GOOD; - responseCPM = parseFloat(bidderBid.price); - if (responseCPM === 0) { - var bid = bidfactory.createBid(2); - bid.bidderCode = BIDDER_CODE; - bidResponses.push(bid); - return bidResponses; - } - bidResponse.placementCode = placementCode; - bidResponse.size = bidRequest.sizes; - bidResponse.creativeId = bidderBid.id; - bidResponse.bidderCode = BIDDER_CODE; - bidResponse.cpm = responseCPM; - bidResponse.ad = formatAdMarkup(bidderBid); - bidResponse.width = parseInt(bidderBid.w); - bidResponse.height = parseInt(bidderBid.h); - bidResponse.currency = bidResp.cur; - bidResponse.netRevenue = true; - bidResponse.requestId = bidRequest.bidId; - bidResponse.ttl = 180; - bidResponses.push(bidResponse); - } - }); - return bidResponses; - }, - getLanguage: function() { - const language = navigator.language ? 'language' : 'userLanguage'; - return navigator[language].split('-')[0]; - }, - - getUserSyncs: function(syncOptions, serverResponses) { - const syncs = [] - return syncs; - }, - - onTimeout: function(data) { - // Bidder specifc code - }, - - onBidWon: function(bid) { - // Bidder specific code - }, - - onSetTargeting: function(bid) { - // Bidder specific code - }, -} -registerBidder(spec); diff --git a/modules/timBidAdapter.md b/modules/timBidAdapter.md deleted file mode 100644 index 684f2e5f7c4..00000000000 --- a/modules/timBidAdapter.md +++ /dev/null @@ -1,26 +0,0 @@ -# Overview - -``` -Module Name: tim Bidder Adapter -Module Type: Bidder Adapter -Maintainer: boris@thetimmedia.com -``` - -# Description - -Module that connects to tim's demand sources - -# Test Parameters -``` - var adUnits = [{ - "code":"99", - "sizes":[[300,250]], - "bids":[{"bidder":"tim", - "params":{ - "placementCode":"testPlacementCode", - "publisherid":"testpublisherid" - } - }] - }] -``` - diff --git a/modules/topRTBBidAdapter.js b/modules/topRTBBidAdapter.js deleted file mode 100644 index c93bd8ccaac..00000000000 --- a/modules/topRTBBidAdapter.js +++ /dev/null @@ -1,65 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'topRTB'; -const ENDPOINT_URL = 'https://ssp.toprtb.com/ssp/rest/ReqAd?ref=www.google.com&hbid=0&adUnitId='; -var adName = ''; -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - isBidRequestValid: function (bid) { - if (utils.deepAccess(bid, 'mediaTypes.banner')) { - adName = 'banner'; - return bid.params && !!bid.params.adUnitId; - } - if (utils.deepAccess(bid, 'mediaTypes.video')) { - adName = 'video'; - return bid.params && !!bid.params.adUnitId; - } - }, - - buildRequests: function (validBidRequests, bidderRequest) { - let adunitid = []; - utils._each(validBidRequests, function (bid) { - adunitid.push(bid.params.adUnitId + '_' + bid.bidId); - }); - - return { - method: 'GET', - url: ENDPOINT_URL + adunitid.toString() - }; - }, - - interpretResponse: function(serverResponses, request) { - const bidResponses = []; - utils._each(serverResponses.body, function(response) { - if (response.cpm > 0) { - const bidResponse = { - requestId: response.bidId, - cpm: response.cpm, - width: response.width, - height: response.height, - ad: response.mediadata, - ttl: response.ttl, - creativeId: response.id, - netRevenue: true, - currency: response.currency, - tracking: response.tracking, - impression: response.impression - }; - if (adName == 'video') { - bidResponse.vastXml = response.mediadata; - bidResponse.mediaType = 'video'; - } else { - bidResponse.ad = response.mediadata; - bidResponse.mediaType = 'banner'; - } - bidResponses.push(bidResponse); - } - }); - return bidResponses; - } -}; - -registerBidder(spec); diff --git a/modules/topRTBBidAdapter.md b/modules/topRTBBidAdapter.md deleted file mode 100644 index d1930c928e4..00000000000 --- a/modules/topRTBBidAdapter.md +++ /dev/null @@ -1,30 +0,0 @@ -# Overview - -``` -Module Name: topRTB Bidder Adapter -Module Type: Bidder Adapter -Maintainer: karthikeyan.d@djaxtech.com -``` - -# Description - -topRTB Bidder Adapter for Prebid.js. -Only Banner & video format is supported. - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div-0', - sizes: [[728, 90]], // a display size - bids: [ - { - bidder: 'topRTB', - params: { - adUnitId: 'c5c06f77430c4c33814a0577cb4cc978' - } - } - ] - } - ]; -``` diff --git a/modules/tpmnBidAdapter.js b/modules/tpmnBidAdapter.js deleted file mode 100644 index ec9d30c0e29..00000000000 --- a/modules/tpmnBidAdapter.js +++ /dev/null @@ -1,119 +0,0 @@ -/* eslint-disable no-tabs */ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import * as utils from '../src/utils.js'; -import { BANNER } from '../src/mediaTypes.js'; - -export const ADAPTER_VERSION = '1'; -const SUPPORTED_AD_TYPES = [BANNER]; - -const BIDDER_CODE = 'tpmn'; -const URL = 'https://ad.tpmn.co.kr/prebidhb.tpmn'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: SUPPORTED_AD_TYPES, - /** - *Determines whether or not the given bid request is valid. - * - * @param {object} bid The bid to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - return 'params' in bid && - 'inventoryId' in bid.params && - 'publisherId' in bid.params && - !isNaN(Number(bid.params.inventoryId)) && - bid.params.inventoryId > 0 && - (typeof bid.mediaTypes.banner.sizes != 'undefined'); // only accepting appropriate sizes - }, - - /** - * @param {BidRequest[]} bidRequests - * @param {*} bidderRequest - * @return {ServerRequest} - */ - buildRequests: (bidRequests, bidderRequest) => { - if (bidRequests.length === 0) { - return []; - } - const bids = bidRequests.map(bidToRequest); - const bidderApiUrl = URL; - const payload = { - 'bids': [...bids], - 'site': createSite(bidderRequest.refererInfo) - }; - return [{ - method: 'POST', - url: bidderApiUrl, - data: payload - }]; - }, - /** - * Unpack the 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. - */ - interpretResponse: function (serverResponse, serverRequest) { - if (!Array.isArray(serverResponse.body)) { - return []; - } - // server response body is an array of bid results - const bidResults = serverResponse.body; - // our server directly returns the format needed by prebid.js so no more - // transformation is needed here. - return bidResults; - } -}; - -registerBidder(spec); - -/** - * Creates site description object - */ -function createSite(refInfo) { - let url = utils.parseUrl(refInfo.referer); - let site = { - 'domain': url.hostname, - 'page': url.protocol + '://' + url.hostname + url.pathname - }; - if (self === top && document.referrer) { - site.ref = document.referrer; - } - let keywords = document.getElementsByTagName('meta')['keywords']; - if (keywords && keywords.content) { - site.keywords = keywords.content; - } - return site; -} - -function parseSize(size) { - let sizeObj = {} - sizeObj.width = parseInt(size[0], 10); - sizeObj.height = parseInt(size[1], 10); - return sizeObj; -} - -function parseSizes(sizes) { - if (Array.isArray(sizes[0])) { // is there several sizes ? (ie. [[728,90],[200,300]]) - return sizes.map(size => parseSize(size)); - } - return [parseSize(sizes)]; // or a single one ? (ie. [728,90]) -} - -function getBannerSizes(bidRequest) { - return parseSizes(utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes') || bidRequest.sizes); -} - -function bidToRequest(bid) { - const bidObj = {}; - bidObj.sizes = getBannerSizes(bid); - - bidObj.inventoryId = bid.params.inventoryId; - bidObj.publisherId = bid.params.publisherId; - bidObj.bidId = bid.bidId; - bidObj.adUnitCode = bid.adUnitCode; - bidObj.auctionId = bid.auctionId; - - return bidObj; -} diff --git a/modules/tpmnBidAdapter.md b/modules/tpmnBidAdapter.md deleted file mode 100644 index 8387528bb0f..00000000000 --- a/modules/tpmnBidAdapter.md +++ /dev/null @@ -1,37 +0,0 @@ -# Overview - -``` -Module Name: TPMN Bid Adapter -Module Type: Bidder Adapter -Maintainer: develop@tpmn.co.kr -``` - -# Description - -Connects to TPMN exchange for bids. - -NOTE: -- TPMN bid adapter only supports Banner at the moment. -- Multi-currency is not supported. - -# Sample Ad Unit Config -``` - var adUnits = [{ - // Banner adUnit - code: 'banner-div', - mediaTypes: { - banner: { - sizes: [[300, 250], [320, 50]], // banner size - } - }, - bids: [ - { - bidder: 'tpmn', - params: { - inventoryId: '1', - publisherId: 'TPMN' - } - } - ] - }]; -``` \ No newline at end of file diff --git a/modules/trafficrootsBidAdapter.md b/modules/trafficrootsBidAdapter.md deleted file mode 100644 index 2aceb0c866b..00000000000 --- a/modules/trafficrootsBidAdapter.md +++ /dev/null @@ -1,37 +0,0 @@ -# Overview - -Module Name: Trafficroots Bid Adapter - -Module Type: Bidder Adapter - -Maintainer: cary@trafficroots.com - -# Description - -Module that connects to Trafficroots demand sources - -# Test Parameters -```javascript - - var adUnits = [ - { - code: 'test-div', - sizes: [[300, 250],[300,600]], // a display size - bids: [ - { - bidder: 'trafficroots', - params: { - zoneId: 'aa0444af31', - deliveryUrl: location.protocol + '//service.trafficroots.com/prebid' - } - },{ - bidder: 'trafficroots', - params: { - zoneId: '8f527a4835', - deliveryUrl: location.protocol + '//service.trafficroots.com/prebid' - } - } - ] - } - ]; -``` diff --git a/modules/trendqubeBidAdapter.js b/modules/trendqubeBidAdapter.js deleted file mode 100644 index d0364b4acec..00000000000 --- a/modules/trendqubeBidAdapter.js +++ /dev/null @@ -1,102 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import * as utils from '../src/utils.js'; - -const BIDDER_CODE = 'trendqube'; -const AD_URL = 'https://ads.trendqube.com/?c=o&m=multi'; - -function isBidResponseValid(bid) { - if (!bid.requestId || !bid.cpm || !bid.creativeId || - !bid.ttl || !bid.currency) { - return false; - } - switch (bid.mediaType) { - case BANNER: - return Boolean(bid.width && bid.height && bid.ad); - case VIDEO: - return Boolean(bid.vastUrl); - case NATIVE: - return Boolean(bid.native && bid.native.title && bid.native.image && bid.native.impressionTrackers); - default: - return false; - } -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO, NATIVE], - - isBidRequestValid: (bid) => { - return Boolean(bid.bidId && bid.params && !isNaN(parseInt(bid.params.placementId))); - }, - - buildRequests: (validBidRequests = [], bidderRequest) => { - let winTop = window; - let location; - try { - location = new URL(bidderRequest.refererInfo.referer) - winTop = window.top; - } catch (e) { - location = winTop.location; - utils.logMessage(e); - }; - let placements = []; - let request = { - 'deviceWidth': winTop.screen.width, - 'deviceHeight': winTop.screen.height, - 'language': (navigator && navigator.language) ? navigator.language.split('-')[0] : '', - 'secure': 1, - 'host': location.host, - 'page': location.pathname, - 'placements': placements - }; - if (bidderRequest) { - if (bidderRequest.uspConsent) { - request.ccpa = bidderRequest.uspConsent; - } - if (bidderRequest.gdprConsent) { - request.gdpr = bidderRequest.gdprConsent - } - } - const len = validBidRequests.length; - - for (let i = 0; i < len; i++) { - let bid = validBidRequests[i]; - let sizes - if (bid.mediaTypes) { - if (bid.mediaTypes[BANNER] && bid.mediaTypes[BANNER].sizes) { - sizes = bid.mediaTypes[BANNER].sizes - } else if (bid.mediaTypes[VIDEO] && bid.mediaTypes[VIDEO].playerSize) { - sizes = bid.mediaTypes[VIDEO].playerSize - } - } - placements.push({ - placementId: bid.params.placementId, - bidId: bid.bidId, - sizes: sizes || [], - wPlayer: sizes ? sizes[0] : 0, - hPlayer: sizes ? sizes[1] : 0, - traffic: bid.params.traffic || BANNER, - schain: bid.schain || {} - }); - } - return { - method: 'POST', - url: AD_URL, - data: request - }; - }, - - interpretResponse: (serverResponse) => { - let response = []; - for (let i = 0; i < serverResponse.body.length; i++) { - let resItem = serverResponse.body[i]; - if (isBidResponseValid(resItem)) { - response.push(resItem); - } - } - return response; - }, -}; - -registerBidder(spec); diff --git a/modules/trendqubeBidAdapter.md b/modules/trendqubeBidAdapter.md deleted file mode 100644 index 8b72c225575..00000000000 --- a/modules/trendqubeBidAdapter.md +++ /dev/null @@ -1,53 +0,0 @@ -# Overview - -``` -Module Name: trendqube Bidder Adapter -Module Type: trendqube Bidder Adapter -``` - -# Description - -Module that connects to trendqube demand sources - -# Test Parameters -``` - var adUnits = [ - // Will return static test banner - { - code: 'placementId_0', - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - bids: [ - { - bidder: 'trendqube', - params: { - placementId: 0, - traffic: 'banner' - } - } - ] - }, - // Will return test vast xml. All video params are stored under placement in publishers UI - { - code: 'placementId_0', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'instream' - } - }, - bids: [ - { - bidder: 'trendqube', - params: { - placementId: 0, - traffic: 'video' - } - } - ] - } - ]; -``` diff --git a/modules/tribeosBidAdapter.js b/modules/tribeosBidAdapter.js deleted file mode 100644 index 80361aa3fdb..00000000000 --- a/modules/tribeosBidAdapter.js +++ /dev/null @@ -1,165 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import * as bidfactory from '../src/bidfactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -var CONSTANTS = require('../src/constants.json'); - -const BIDDER_CODE = 'tribeos'; -const ENDPOINT_URL = 'https://bidder.tribeos.tech/prebid/'; -const LOG_PREFIX = 'TRIBEOS: '; -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} - * bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - if (utils.isEmpty(bid.params.placementId)) { - utils.logError(LOG_PREFIX, 'placementId is required, please contact tribeOS for placementId. Bid details: ', JSON.stringify(bid)); - return false; - } - return true; - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - - * an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests) { - var requests = []; - for (var i = 0; i < validBidRequests.length; i++) { - requests.push(this.buidRTBRequest(validBidRequests[i])); - } - return requests; - }, - buidRTBRequest: function(bidReq) { - // build bid request object - - var placementId = bidReq.params.placementId; - var bidFloor = bidReq.params.bidfloor; - var placementCode = bidReq.params.placementCode; - - var adWidth = bidReq.mediaTypes.banner.sizes[0][0]; - var adHeight = bidReq.mediaTypes.banner.sizes[0][1]; - - // build bid request with impressions - var bidRequest = { - id: utils.getUniqueIdentifierStr(), - imp: [{ - id: bidReq.bidId, - banner: { - w: adWidth, - h: adHeight - }, - tagid: placementCode, - bidfloor: bidFloor - }], - site: { - domain: window.location.host, - page: window.location.href, - publisher: { - id: placementId - } - }, - device: { - 'language': (navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage), - 'w': adWidth, - 'h': adHeight, - 'js': 1, - 'ua': navigator.userAgent - } - }; - - // apply gdpr - if (bidReq.gdprConsent) { - bidRequest.regs = {ext: {gdpr: bidReq.gdprConsent.gdprApplies ? 1 : 0}}; - bidRequest.user = {ext: {consent: bidReq.gdprConsent.consentString}}; - } - - bidRequest.bidId = bidReq.bidId; - var url = ENDPOINT_URL + placementId + '/requests'; - if (!utils.isEmpty(bidReq.params.endpointUrl)) { - url = bidReq.params.endpointUrl + placementId + '/requests'; - } - - return { - method: 'POST', - url: url, - data: JSON.stringify(bidRequest), - options: { withCredentials: true, contentType: 'application/json' }, - }; - }, - /** - * Unpack the 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. - */ - interpretResponse: function(serverResponse, bidRequest) { - const responseBody = serverResponse.body; - - utils.logInfo(LOG_PREFIX, 'response body: ', JSON.stringify(serverResponse)); - - if ((!responseBody || !responseBody.id)) { - return []; - } - const bidResponses = []; - responseBody.seatbid[0].bid.forEach(function(bidderBid) { - var responsePrice; - var placementCode = ''; - if (bidRequest) { - var bidResponse = bidfactory.createBid(1); - placementCode = bidRequest.placementCode; - bidRequest.status = CONSTANTS.STATUS.GOOD; - responsePrice = parseFloat(bidderBid.price); - if (responsePrice === 0) { - var bid = bidfactory.createBid(2); - bid.bidderCode = BIDDER_CODE; - bidResponses.push(bid); - - utils.logInfo(LOG_PREFIX, 'response price is zero. Response data: ', JSON.stringify(bidRequest)); - - return bidResponses; - } - bidResponse.placementCode = placementCode; - bidResponse.size = bidRequest.sizes; - bidResponse.creativeId = bidderBid.crid; - bidResponse.bidderCode = BIDDER_CODE; - bidResponse.cpm = responsePrice; - bidResponse.ad = bidderBid.adm; - bidResponse.width = parseInt(bidderBid.w); - bidResponse.height = parseInt(bidderBid.h); - bidResponse.currency = responseBody.cur; - bidResponse.netRevenue = true; - bidResponse.requestId = bidderBid.impid; - bidResponse.ttl = 180; - - utils.logInfo(LOG_PREFIX, 'bid response data: ', JSON.stringify(bidResponse)); - utils.logInfo(LOG_PREFIX, 'bid request data: ', JSON.stringify(bidRequest)); - - bidResponses.push(bidResponse); - } - }); - return bidResponses; - }, - /** - * Register bidder specific code, which will execute if a bid from this - * bidder won the auction - * - * @param {Bid} - * The bid that won the auction - */ -// onBidWon: function(bid) { -// ajax(this.nurls[bid.requestId], null); -// } - -} -registerBidder(spec); diff --git a/modules/tribeosBidAdapter.md b/modules/tribeosBidAdapter.md deleted file mode 100644 index 670810abec9..00000000000 --- a/modules/tribeosBidAdapter.md +++ /dev/null @@ -1,31 +0,0 @@ -# Overview - -``` -Module Name: tribeOS Bidder Adapter -Module Type: Bidder Adapter -Maintainer: dev@tribeos.io -``` - -# Description - -tribeOS adapter - -# Test Parameters -``` - var adUnits = [{ - code: 'test-tribeos', - mediaTypes: { - banner: { - sizes: [ - [300, 250] - ], - } - }, - bids: [{ - bidder: "tribeos", - params: { - placementId: '12345' // REQUIRED - } - }] - }]; -``` diff --git a/modules/trionBidAdapter.js b/modules/trionBidAdapter.js deleted file mode 100644 index 37d54e60cd2..00000000000 --- a/modules/trionBidAdapter.js +++ /dev/null @@ -1,208 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const storage = getStorageManager(); - -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_'; - -export const spec = { - code: BIDDER_CODE, - isBidRequestValid: function (bid) { - return !!(bid && bid.params && bid.params.pubId && bid.params.sectionId); - }, - buildRequests: function (validBidRequests, bidderRequest) { - var bidRequests = []; - - for (var i = 0; i < validBidRequests.length; i++) { - var bid = validBidRequests[i]; - - var trionUrlParams = buildTrionUrlParams(bid, bidderRequest); - - bidRequests.push({ - method: 'GET', - url: BID_REQUEST_BASE_URL, - bidRequest: bid, - data: trionUrlParams - }); - } - return bidRequests; - }, - - interpretResponse: function (trionResponseObj, request) { - var bid = {}; - var bidResponses = []; - var bidRequest = request.bidRequest; - var responseBody = trionResponseObj ? trionResponseObj.body : {}; - - if (responseBody && responseBody.bidId && bidRequest) { - var result = responseBody.result; - - if (result && result.cpm && result.placeBid && result.ad) { - var cpm = parseInt(result.cpm, 10) / 100; - - bid.requestId = bidRequest.bidId; - bid.cpm = cpm; - bid.ad = result.ad; - bid.width = result.width; - bid.height = result.height; - bid.ttl = result.ttl; - bid.creativeId = result.creativeId; - bid.currency = result.currency; - bid.netRevenue = result.netRevenue; - bidResponses.push(bid); - } - } - - return bidResponses; - }, - getUserSyncs: function getUserSyncs(syncOptions, serverResponses, gdprConsent, usPrivacy) { - if (syncOptions.iframeEnabled) { - handlePostMessage(); - return [{ - type: 'iframe', - url: getSyncUrl(gdprConsent, usPrivacy) - }]; - } - } - -}; -registerBidder(spec); - -function getSyncUrl(gdprConsent, usPrivacy) { - var unParsedPubAndSection = getStorageData(BASE_KEY + 'lps') || ':'; - var pubSectionArray = unParsedPubAndSection.split(':') || []; - var pubId = pubSectionArray[0] || -1; - var sectionId = pubSectionArray[1] || -1; - var url = getPublisherUrl(); - var consentParams = ''; - if (gdprConsent) { - if (gdprConsent.consentString) { - consentParams += '&gc=' + encodeURIComponent(gdprConsent.consentString); - } - consentParams += '&g=' + (gdprConsent.gdprApplies ? 1 : 0); - } - if (usPrivacy) { - consentParams = '&up=' + encodeURIComponent(usPrivacy); - } - return USER_SYNC_URL + `?p=${pubId}&s=${sectionId}${consentParams}&u=${url}`; -} - -function getPublisherUrl() { - var url = ''; - try { - if (window.top == window) { - url = window.location.href; - } else { - try { - url = window.top.location.href; - } catch (e) { - url = document.referrer; - } - } - } catch (e) { - } - return url -} - -function buildTrionUrlParams(bid, bidderRequest) { - var pubId = utils.getBidIdParameter('pubId', bid.params); - var sectionId = utils.getBidIdParameter('sectionId', bid.params); - var url = getPublisherUrl(); - var bidSizes = getBidSizesFromBidRequest(bid); - var sizes = utils.parseSizesInput(bidSizes).join(','); - var isAutomated = (navigator && navigator.webdriver) ? '1' : '0'; - var isHidden = (document.hidden) ? '1' : '0'; - var visibilityState = encodeURIComponent(document.visibilityState); - - var intT = window.TR_INT_T && window.TR_INT_T != -1 ? window.TR_INT_T : null; - if (!intT) { - intT = getStorageData(BASE_KEY + 'int_t'); - } - if (intT) { - setStorageData(BASE_KEY + 'int_t', intT) - } - setStorageData(BASE_KEY + 'lps', pubId + ':' + sectionId); - var trionUrl = ''; - - trionUrl = utils.tryAppendQueryString(trionUrl, 'bidId', bid.bidId); - trionUrl = utils.tryAppendQueryString(trionUrl, 'pubId', pubId); - trionUrl = utils.tryAppendQueryString(trionUrl, 'sectionId', sectionId); - trionUrl = utils.tryAppendQueryString(trionUrl, 'vers', '$prebid.version$'); - if (url) { - trionUrl += 'url=' + url + '&'; - } - if (sizes) { - trionUrl += 'sizes=' + sizes + '&'; - } - if (intT) { - trionUrl = utils.tryAppendQueryString(trionUrl, 'int_t', encodeURIComponent(intT)); - } - trionUrl = utils.tryAppendQueryString(trionUrl, 'tr_wd', isAutomated); - trionUrl = utils.tryAppendQueryString(trionUrl, 'tr_hd', isHidden); - trionUrl = utils.tryAppendQueryString(trionUrl, 'tr_vs', visibilityState); - if (bidderRequest && bidderRequest.gdprConsent) { - var gdpr = bidderRequest.gdprConsent; - if (gdpr) { - if (gdpr.consentString) { - trionUrl = utils.tryAppendQueryString(trionUrl, 'gdprc', encodeURIComponent(gdpr.consentString)); - } - trionUrl = utils.tryAppendQueryString(trionUrl, 'gdpr', (gdpr.gdprApplies ? 1 : 0)); - } - } - if (bidderRequest && bidderRequest.uspConsent) { - trionUrl = utils.tryAppendQueryString(trionUrl, 'usp', encodeURIComponent(bidderRequest.uspConsent)); - } - // remove the trailing "&" - if (trionUrl.lastIndexOf('&') === trionUrl.length - 1) { - trionUrl = trionUrl.substring(0, trionUrl.length - 1); - } - return trionUrl; -} - -function getBidSizesFromBidRequest(bid) { - return (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) ? bid.mediaTypes.banner.sizes : bid.sizes; -} - -function handlePostMessage() { - try { - if (window.addEventListener) { - window.addEventListener('message', acceptPostMessage); - } - } catch (e) { - } -} - -export function getStorageData(key) { - var item = null; - try { - if (storage.hasLocalStorage()) { - item = storage.getDataFromLocalStorage(key); - } - } catch (e) { - } - return item; -} - -export function setStorageData(key, item) { - try { - if (storage.hasLocalStorage()) { - storage.setDataInLocalStorage(key, item); - } - } catch (e) { - } -} - -export function acceptPostMessage(e) { - var message = e.data || ''; - if (!message.indexOf || !message.split || message.indexOf(BASE_KEY + 'userId') !== 0) { - return; - } - var intT = message.split(BASE_KEY + 'userId=')[1]; - if (intT) { - setStorageData(BASE_KEY + 'int_t', intT); - } -} diff --git a/modules/trionBidAdapter.md b/modules/trionBidAdapter.md deleted file mode 100644 index ac21a407144..00000000000 --- a/modules/trionBidAdapter.md +++ /dev/null @@ -1,33 +0,0 @@ -# Overview - -**Module Name**: Trion Interactive Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: mgroh@trioninteractive.com -**Publisher Contact**: publishers@trioninteractive.com - -# Description - -This module connects to Trion's demand sources. It supports display, outstream, and rich media formats. -Trion will provide ``pubId`` and ``sectionId`` that are specific to your ad type. -Please reach out to ``publishers@trioninteractive.com`` to set up a trion account and above ids. -Use bidder code ```trion``` for all Trion traffic. - -# Test Parameters -``` - var adUnits = [ - { - code: 'ad-div', - sizes: [[300, 250]], // a display size - bids: [ - { - bidder: 'trion', - params: { - pubId: '12345', - sectionId: '1', - re : 'http://clicktrackingurl.com?re='// optional - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/tripleliftBidAdapter.js b/modules/tripleliftBidAdapter.js deleted file mode 100644 index e8d248eea03..00000000000 --- a/modules/tripleliftBidAdapter.js +++ /dev/null @@ -1,343 +0,0 @@ -import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; - -const GVLID = 28; -const BIDDER_CODE = 'triplelift'; -const STR_ENDPOINT = 'https://tlx.3lift.com/header/auction?'; -let gdprApplies = true; -let consentString = null; - -export const tripleliftAdapterSpec = { - gvlid: GVLID, - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - isBidRequestValid: function (bid) { - return typeof bid.params.inventoryCode !== 'undefined'; - }, - - buildRequests: function(bidRequests, bidderRequest) { - let tlCall = STR_ENDPOINT; - let data = _buildPostBody(bidRequests); - - tlCall = utils.tryAppendQueryString(tlCall, 'lib', 'prebid'); - tlCall = utils.tryAppendQueryString(tlCall, 'v', '$prebid.version$'); - - if (bidderRequest && bidderRequest.refererInfo) { - let referrer = bidderRequest.refererInfo.referer; - tlCall = utils.tryAppendQueryString(tlCall, 'referrer', referrer); - } - - if (bidderRequest && bidderRequest.timeout) { - tlCall = utils.tryAppendQueryString(tlCall, 'tmax', bidderRequest.timeout); - } - - if (bidderRequest && bidderRequest.gdprConsent) { - if (typeof bidderRequest.gdprConsent.gdprApplies !== 'undefined') { - gdprApplies = bidderRequest.gdprConsent.gdprApplies; - tlCall = utils.tryAppendQueryString(tlCall, 'gdpr', gdprApplies.toString()); - } - if (typeof bidderRequest.gdprConsent.consentString !== 'undefined') { - consentString = bidderRequest.gdprConsent.consentString; - tlCall = utils.tryAppendQueryString(tlCall, 'cmp_cs', consentString); - } - } - - if (bidderRequest && bidderRequest.uspConsent) { - tlCall = utils.tryAppendQueryString(tlCall, 'us_privacy', bidderRequest.uspConsent); - } - - if (config.getConfig('coppa') === true) { - tlCall = utils.tryAppendQueryString(tlCall, 'coppa', true); - } - - if (tlCall.lastIndexOf('&') === tlCall.length - 1) { - tlCall = tlCall.substring(0, tlCall.length - 1); - } - utils.logMessage('tlCall request built: ' + tlCall); - - return { - method: 'POST', - url: tlCall, - data, - bidderRequest - }; - }, - - interpretResponse: function(serverResponse, {bidderRequest}) { - let bids = serverResponse.body.bids || []; - return bids.map(function(bid) { - return _buildResponseObject(bidderRequest, bid); - }); - }, - - getUserSyncs: function(syncOptions, responses, gdprConsent, usPrivacy) { - let syncType = _getSyncType(syncOptions); - if (!syncType) return; - - let syncEndpoint = 'https://eb2.3lift.com/sync?'; - - if (syncType === 'image') { - syncEndpoint = utils.tryAppendQueryString(syncEndpoint, 'px', 1); - syncEndpoint = utils.tryAppendQueryString(syncEndpoint, 'src', 'prebid'); - } - - if (consentString !== null) { - syncEndpoint = utils.tryAppendQueryString(syncEndpoint, 'gdpr', gdprApplies); - syncEndpoint = utils.tryAppendQueryString(syncEndpoint, 'cmp_cs', consentString); - } - - if (usPrivacy) { - syncEndpoint = utils.tryAppendQueryString(syncEndpoint, 'us_privacy', usPrivacy); - } - - return [{ - type: syncType, - url: syncEndpoint - }]; - } -} - -function _getSyncType(syncOptions) { - if (!syncOptions) return; - if (syncOptions.iframeEnabled) return 'iframe'; - if (syncOptions.pixelEnabled) return 'image'; -} - -function _buildPostBody(bidRequests) { - let data = {}; - let { schain } = bidRequests[0]; - const globalFpd = _getGlobalFpd(); - - data.imp = bidRequests.map(function(bidRequest, index) { - let imp = { - id: index, - tagid: bidRequest.params.inventoryCode, - floor: _getFloor(bidRequest) - }; - // remove the else to support multi-imp - if (_isInstreamBidRequest(bidRequest)) { - imp.video = _getORTBVideo(bidRequest); - } else if (bidRequest.mediaTypes.banner) { - imp.banner = { format: _sizes(bidRequest.sizes) }; - }; - if (!utils.isEmpty(bidRequest.ortb2Imp)) { - imp.fpd = _getAdUnitFpd(bidRequest.ortb2Imp); - } - return imp; - }); - - let eids = [ - ...getUnifiedIdEids([bidRequests[0]]), - ...getIdentityLinkEids([bidRequests[0]]), - ...getCriteoEids([bidRequests[0]]), - ...getPubCommonEids([bidRequests[0]]) - ]; - - if (eids.length > 0) { - data.user = { - ext: {eids} - }; - } - - let ext = _getExt(schain, globalFpd); - - if (!utils.isEmpty(ext)) { - data.ext = ext; - } - return data; -} - -function _isInstreamBidRequest(bidRequest) { - if (!bidRequest.mediaTypes.video) return false; - if (!bidRequest.mediaTypes.video.context) return false; - if (bidRequest.mediaTypes.video.context.toLowerCase() === 'instream') { - return true; - } else { - return false; - } -} - -function _getORTBVideo(bidRequest) { - // give precedent to mediaTypes.video - let video = { ...bidRequest.params.video, ...bidRequest.mediaTypes.video }; - if (!video.w) video.w = video.playerSize[0][0]; - if (!video.h) video.h = video.playerSize[0][1]; - if (video.context === 'instream') video.placement = 1; - // clean up oRTB object - delete video.playerSize; - return video; -} - -function _getFloor (bid) { - let floor = null; - if (typeof bid.getFloor === 'function') { - const floorInfo = bid.getFloor({ - currency: 'USD', - mediaType: _isInstreamBidRequest(bid) ? 'video' : 'banner', - size: '*' - }); - if (typeof floorInfo === 'object' && - floorInfo.currency === 'USD' && !isNaN(parseFloat(floorInfo.floor))) { - floor = parseFloat(floorInfo.floor); - } - } - return floor !== null ? floor : bid.params.floor; -} - -function _getGlobalFpd() { - const fpd = {}; - const context = {} - const user = {}; - const ortbData = config.getLegacyFpd(config.getConfig('ortb2')) || {}; - - const fpdContext = Object.assign({}, ortbData.context); - const fpdUser = Object.assign({}, ortbData.user); - - _addEntries(context, fpdContext); - _addEntries(user, fpdUser); - - if (!utils.isEmpty(context)) { - fpd.context = context; - } - if (!utils.isEmpty(user)) { - fpd.user = user; - } - return fpd; -} - -function _getAdUnitFpd(adUnitFpd) { - const fpd = {}; - const context = {}; - - _addEntries(context, adUnitFpd.ext); - - if (!utils.isEmpty(context)) { - fpd.context = context; - } - - return fpd; -} - -function _addEntries(target, source) { - if (!utils.isEmpty(source)) { - Object.keys(source).forEach(key => { - if (source[key] != null) { - target[key] = source[key]; - } - }); - } -} - -function _getExt(schain, fpd) { - let ext = {}; - if (!utils.isEmpty(schain)) { - ext.schain = { ...schain }; - } - if (!utils.isEmpty(fpd)) { - ext.fpd = { ...fpd }; - } - return ext; -} - -function getUnifiedIdEids(bidRequest) { - return getEids(bidRequest, 'tdid', 'adserver.org', 'TDID'); -} - -function getIdentityLinkEids(bidRequest) { - return getEids(bidRequest, 'idl_env', 'liveramp.com', 'idl'); -} - -function getCriteoEids(bidRequest) { - return getEids(bidRequest, 'criteoId', 'criteo.com', 'criteoId'); -} - -function getPubCommonEids(bidRequest) { - return getEids(bidRequest, 'pubcid', 'pubcid.org', 'pubcid'); -} - -function getEids(bidRequest, type, source, rtiPartner) { - return bidRequest - .map(getUserId(type)) // bids -> userIds of a certain type - .filter((x) => !!x) // filter out null userIds - .map(formatEid(source, rtiPartner)); // userIds -> eid objects -} - -function getUserId(type) { - return (bid) => (bid && bid.userId && bid.userId[type]); -} - -function formatEid(source, rtiPartner) { - return (id) => ({ - source, - uids: [{ - id, - ext: { rtiPartner } - }] - }); -} - -function _sizes(sizeArray) { - let sizes = sizeArray.filter(_isValidSize); - return sizes.map(function(size) { - return { - w: size[0], - h: size[1] - }; - }); -} - -function _isValidSize(size) { - return (size.length === 2 && typeof size[0] === 'number' && typeof size[1] === 'number'); -} - -function _buildResponseObject(bidderRequest, bid) { - let bidResponse = {}; - let width = bid.width || 1; - let height = bid.height || 1; - let dealId = bid.deal_id || ''; - let creativeId = bid.crid || ''; - let breq = bidderRequest.bids[bid.imp_id]; - - if (bid.cpm != 0 && bid.ad) { - bidResponse = { - requestId: breq.bidId, - cpm: bid.cpm, - width: width, - height: height, - netRevenue: true, - ad: bid.ad, - creativeId: creativeId, - dealId: dealId, - currency: 'USD', - ttl: 300, - tl_source: bid.tl_source, - meta: {} - }; - - if (_isInstreamBidRequest(breq)) { - bidResponse.vastXml = bid.ad; - bidResponse.mediaType = 'video'; - }; - - if (bid.advertiser_name) { - bidResponse.meta.advertiserName = bid.advertiser_name; - } - - if (bid.adomain && bid.adomain.length) { - bidResponse.meta.advertiserDomains = bid.adomain; - } - - if (bid.tl_source && bid.tl_source == 'hdx') { - bidResponse.meta.mediaType = 'banner'; - } - - if (bid.tl_source && bid.tl_source == 'tlx') { - bidResponse.meta.mediaType = 'native'; - } - }; - return bidResponse; -} - -registerBidder(tripleliftAdapterSpec); diff --git a/modules/tripleliftBidAdapter.md b/modules/tripleliftBidAdapter.md deleted file mode 100644 index 03dcee3b980..00000000000 --- a/modules/tripleliftBidAdapter.md +++ /dev/null @@ -1,82 +0,0 @@ -# Overview - -``` -Module Name: Triplelift Bid Adapter -Module Type: Bidder Adapter -Maintainer: prebid@triplelift.com -``` - -# Description - -Connects to Triplelift Exchange for bids. -Triplelift bid adapter supports Banner format only. - -# Test Parameters -``` -var adUnits = [{ - code: 'banner-div', - mediaTypes: { - banner: { - sizes: [[300, 600], [300, 250], [320, 90]], - } - }, - bids: [ - { - bidder: 'triplelift', - params: { - inventoryCode: 'forbes_main', - floor: 1.009 - } - }] -}, { - code: 'banner-div-2', - mediaTypes: { - banner: { - sizes: [[300, 300]], - } - }, - bids: [ - { - bidder: 'triplelift', - params: { - inventoryCode: 'foodgawker', - floor: 0.00 - } - }] -}, { - code: 'banner-div-3', - mediaTypes: { - banner: { - sizes: [[300, 600], [300, 250]], - } - }, - bids: [ - { - bidder: 'triplelift', - params: { - inventoryCode: 'forbes_main', - floor: 0 - } - }] -}, { - code: 'instream-div-1', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'instream', - } - }, - bids: [ - { - bidder: 'triplelift', - params: { - inventoryCode: 'instream_test', - video: { - mimes: ['video/mp4'], - w: 640, - h: 480, - }, - } - }] -}]; -``` diff --git a/modules/truereachBidAdapter.js b/modules/truereachBidAdapter.js deleted file mode 100755 index 92f9cc9951e..00000000000 --- a/modules/truereachBidAdapter.js +++ /dev/null @@ -1,148 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { config } from '../src/config.js'; -import { BANNER } from '../src/mediaTypes.js'; - -const SUPPORTED_AD_TYPES = [BANNER]; -const BIDDER_CODE = 'truereach'; -const BIDDER_URL = 'https://ads.momagic.com/exchange/openrtb25/'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: SUPPORTED_AD_TYPES, - - isBidRequestValid: function (bidRequest) { - return (bidRequest.params.site_id && bidRequest.params.bidfloor && - utils.deepAccess(bidRequest, 'mediaTypes.banner') && (utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes.length') > 0)); - }, - - buildRequests: function (validBidRequests, bidderRequest) { - if (validBidRequests.length === 0) { - return []; - } - - let queryParams = buildCommonQueryParamsFromBids(validBidRequests, bidderRequest); - - let siteId = utils.deepAccess(validBidRequests[0], 'params.site_id'); - - let url = BIDDER_URL + siteId + '?hb=1&transactionId=' + validBidRequests[0].transactionId; - - return { - method: 'POST', - url: url, - data: queryParams, - options: { withCredentials: true } - }; - }, - - interpretResponse: function ({ body: serverResponse }, serverRequest) { - const bidResponses = []; - - if ((!serverResponse || !serverResponse.id) || - (!serverResponse.seatbid || serverResponse.seatbid.length === 0 || !serverResponse.seatbid[0].bid || serverResponse.seatbid[0].bid.length === 0)) { - return bidResponses; - } - - let adUnits = serverResponse.seatbid[0].bid; - let bidderBid = adUnits[0]; - - let responseCPM = parseFloat(bidderBid.price); - if (responseCPM === 0) { - return bidResponses; - } - - let responseAd = bidderBid.adm; - - if (bidderBid.nurl) { - let responseNurl = ''; - responseAd += responseNurl; - } - - const bidResponse = { - requestId: bidderBid.impid, - cpm: responseCPM, - currency: serverResponse.cur || 'USD', - width: parseInt(bidderBid.w), - height: parseInt(bidderBid.h), - ad: decodeURIComponent(responseAd), - ttl: 180, - creativeId: bidderBid.crid, - netRevenue: false - }; - if (bidderBid.adomain && bidderBid.adomain.length) { - bidResponse.meta = { - advertiserDomains: bidderBid.adomain, - }; - } - - bidResponses.push(bidResponse); - - return bidResponses; - }, - getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) { - const syncs = [] - - var gdprParams = ''; - if (gdprConsent) { - if (typeof gdprConsent.gdprApplies === 'boolean') { - gdprParams = `?gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - gdprParams = `?gdpr_consent=${gdprConsent.consentString}`; - } - } - - if (syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: 'http://ads.momagic.com/jsp/usersync.jsp' + gdprParams - }); - } - return syncs; - } - -}; - -function buildCommonQueryParamsFromBids(validBidRequests, bidderRequest) { - let adW = 0; - let adH = 0; - let adSizes = Array.isArray(validBidRequests[0].params.sizes) ? validBidRequests[0].params.sizes : validBidRequests[0].sizes; - let sizeArrayLength = adSizes.length; - if (sizeArrayLength === 2 && typeof adSizes[0] === 'number' && typeof adSizes[1] === 'number') { - adW = adSizes[0]; - adH = adSizes[1]; - } else { - adW = adSizes[0][0]; - adH = adSizes[0][1]; - } - - let bidFloor = Number(utils.deepAccess(validBidRequests[0], 'params.bidfloor')); - - let domain = window.location.host; - let page = window.location.host + window.location.pathname + location.search + location.hash; - - let defaultParams = { - id: utils.getUniqueIdentifierStr(), - imp: [ - { - id: validBidRequests[0].bidId, - banner: { - w: adW, - h: adH - }, - bidfloor: bidFloor - } - ], - site: { - domain: domain, - page: page - }, - device: { - ua: window.navigator.userAgent - }, - tmax: config.getConfig('bidderTimeout') - }; - - return defaultParams; -} - -registerBidder(spec); diff --git a/modules/truereachBidAdapter.md b/modules/truereachBidAdapter.md deleted file mode 100644 index 8a926565092..00000000000 --- a/modules/truereachBidAdapter.md +++ /dev/null @@ -1,44 +0,0 @@ -# Overview - -``` -Module Name: TrueReach Bidder Adapter -Module Type: Bidder Adapter -Maintainer: mm.github@momagic.com -``` - -# Description - -Module that connects to TrueReach's demand sources - -# Test Parameters -``` - var adUnits = [{ - code: 'test-banner', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [{ - bidder: 'truereach', - params: { - site_id: '0142010a-8400-1b01-72cb-a553b9000009', - bidfloor: 0.1 - } - }] - }]; -``` - -# Bid Parameters - -`mediaTypes -> banner -> sizes` must be `defined`. - -Also, the following parameters are `required` to be set- - -| Name | Type | Description -| ---- | ---- | ----------- -| `site_id` | String | TrueReach provided site ID -| `bidfloor` | Number | Minimum price (CPM) in USD. Must be greater than 0. - -# Additional Details -[TrueReach Ads](http://doc.truereach.co.in/docs/prebid/js-bidder-adapter.html) diff --git a/modules/trustxBidAdapter.js b/modules/trustxBidAdapter.js deleted file mode 100644 index 9f8de30a0d4..00000000000 --- a/modules/trustxBidAdapter.js +++ /dev/null @@ -1,588 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { Renderer } from '../src/Renderer.js'; -import { VIDEO, BANNER } from '../src/mediaTypes.js'; -import { config } from '../src/config.js'; - -const BIDDER_CODE = 'trustx'; -const ENDPOINT_URL = 'https://sofia.trustx.org/hb'; -const NEW_ENDPOINT_URL = 'https://grid.bidswitch.net/hbjson?sp=trustx'; -const ADDITIONAL_SYNC_URL = 'https://x.bidswitch.net/sync?ssp=themediagrid'; -const TIME_TO_LIVE = 360; -const ADAPTER_SYNC_URL = 'https://sofia.trustx.org/push_sync'; -const RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js'; - -const LOG_ERROR_MESS = { - noAuid: 'Bid from response has no auid parameter - ', - noAdm: 'Bid from response has no adm parameter - ', - noBid: 'Array of bid objects is empty', - noPlacementCode: 'Can\'t find in requested bids the bid with auid - ', - emptyUids: 'Uids should be not empty', - emptySeatbid: 'Seatbid array from response has empty item', - emptyResponse: 'Response is empty', - hasEmptySeatbidArray: 'Response has empty seatbid array', - hasNoArrayOfBids: 'Seatbid from response has no array of bid objects - ' -}; -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [ BANNER, VIDEO ], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - return !!bid.params.uid; - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests - an array of bids - * @param {bidderRequest} - bidder request object - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests, bidderRequest) { - const bids = validBidRequests || []; - const newFormatBids = []; - const oldFormatBids = []; - const requests = []; - bids.forEach(bid => { - if (bid.params.useNewFormat) { - newFormatBids.push(bid); - } else { - oldFormatBids.push(bid); - } - }); - if (newFormatBids.length) { - const newFormatRequests = newFormatRequest(newFormatBids, bidderRequest); - if (newFormatRequests) { - requests.push(newFormatRequests); - } - } - if (oldFormatBids.length) { - const oldFormatRequests = oldFormatRequest(oldFormatBids, bidderRequest); - if (oldFormatRequests) { - requests.push(oldFormatRequests); - } - } - return requests; - }, - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @param {*} bidRequest - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse, bidRequest, RendererConst = Renderer) { - serverResponse = serverResponse && serverResponse.body; - const bidResponses = []; - - let errorMessage; - - if (!serverResponse) errorMessage = LOG_ERROR_MESS.emptyResponse; - else if (serverResponse.seatbid && !serverResponse.seatbid.length) { - errorMessage = LOG_ERROR_MESS.hasEmptySeatbidArray; - } - - if (!errorMessage && serverResponse.seatbid) { - serverResponse.seatbid.forEach(respItem => { - _addBidResponse(_getBidFromResponse(respItem), bidRequest, bidResponses, RendererConst); - }); - } - if (errorMessage) utils.logError(errorMessage); - return bidResponses; - }, - getUserSyncs: function(syncOptions, responses, gdprConsent, uspConsent) { - if (syncOptions.pixelEnabled) { - const syncsPerBidder = config.getConfig('userSync.syncsPerBidder'); - let params = []; - if (gdprConsent && typeof gdprConsent.consentString === 'string') { - if (typeof gdprConsent.gdprApplies === 'boolean') { - params.push(`gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`); - } else { - params.push(`gdpr_consent=${gdprConsent.consentString}`); - } - } - if (uspConsent) { - params.push(`us_privacy=${uspConsent}`); - } - const stringParams = params.join('&'); - const syncs = [{ - type: 'image', - url: ADAPTER_SYNC_URL + (stringParams ? `?${stringParams}` : '') - }]; - if (syncsPerBidder > 1) { - syncs.push({ - type: 'image', - url: ADDITIONAL_SYNC_URL + (stringParams ? `&${stringParams}` : '') - }); - } - return syncs; - } - } -} - -function isPopulatedArray(arr) { - return !!(utils.isArray(arr) && arr.length > 0); -} - -function deleteValues(keyPairObj) { - if (isPopulatedArray(keyPairObj.value) && keyPairObj.value[0] === '') { - delete keyPairObj.value; - } -} - -function _getBidFromResponse(respItem) { - if (!respItem) { - utils.logError(LOG_ERROR_MESS.emptySeatbid); - } else if (!respItem.bid) { - utils.logError(LOG_ERROR_MESS.hasNoArrayOfBids + JSON.stringify(respItem)); - } else if (!respItem.bid[0]) { - utils.logError(LOG_ERROR_MESS.noBid); - } - return respItem && respItem.bid && respItem.bid[0]; -} - -function _addBidResponse(serverBid, bidRequest, bidResponses, RendererConst) { - if (!serverBid) return; - let errorMessage; - if (!serverBid.auid) errorMessage = LOG_ERROR_MESS.noAuid + JSON.stringify(serverBid); - if (!serverBid.adm) errorMessage = LOG_ERROR_MESS.noAdm + JSON.stringify(serverBid); - else { - const { bidsMap, priceType, newFormat } = bidRequest; - let bid; - let slot; - if (newFormat) { - bid = bidsMap[serverBid.impid]; - } else { - const awaitingBids = bidsMap[serverBid.auid]; - if (awaitingBids) { - const sizeId = `${serverBid.w}x${serverBid.h}`; - if (awaitingBids[sizeId]) { - slot = awaitingBids[sizeId][0]; - bid = slot.bids.shift(); - } - } else { - errorMessage = LOG_ERROR_MESS.noPlacementCode + serverBid.auid; - } - } - - if (!errorMessage && bid) { - const bidResponse = { - requestId: bid.bidId, // bid.bidderRequestId, - cpm: serverBid.price, - width: serverBid.w, - height: serverBid.h, - creativeId: serverBid.auid, // bid.bidId, - currency: 'USD', - netRevenue: newFormat ? false : priceType !== 'gross', - ttl: TIME_TO_LIVE, - dealId: serverBid.dealid - }; - if (serverBid.content_type === 'video') { - bidResponse.vastXml = serverBid.adm; - bidResponse.mediaType = VIDEO; - bidResponse.adResponse = { - content: bidResponse.vastXml - }; - if (!bid.renderer && (!bid.mediaTypes || !bid.mediaTypes.video || bid.mediaTypes.video.context === 'outstream')) { - bidResponse.renderer = createRenderer(bidResponse, { - id: bid.bidId, - url: RENDERER_URL - }, RendererConst); - } - } else { - bidResponse.ad = serverBid.adm; - bidResponse.mediaType = BANNER; - } - - bidResponses.push(bidResponse); - } - - if (slot && !slot.bids.length) { - slot.parents.forEach(({parent, key, uid}) => { - const index = parent[key].indexOf(slot); - if (index > -1) { - parent[key].splice(index, 1); - } - if (!parent[key].length) { - delete parent[key]; - if (!utils.getKeys(parent).length) { - delete bidsMap[uid]; - } - } - }); - } - } - if (errorMessage) { - utils.logError(errorMessage); - } -} - -function outstreamRender (bid) { - bid.renderer.push(() => { - window.ANOutstreamVideo.renderAd({ - targetId: bid.adUnitCode, - adResponse: bid.adResponse - }); - }); -} - -function createRenderer (bid, rendererParams, RendererConst) { - const rendererInst = RendererConst.install({ - id: rendererParams.id, - url: rendererParams.url, - loaded: false - }); - - try { - rendererInst.setRender(outstreamRender); - } catch (err) { - utils.logWarn('Prebid Error calling setRender on renderer', err); - } - - return rendererInst; -} - -function createVideoRequest(bid, mediaType) { - const {playerSize, mimes, durationRangeSec, protocols} = mediaType; - const size = (playerSize || bid.sizes || [])[0]; - if (!size) return; - - let result = utils.parseGPTSingleSizeArrayToRtbSize(size); - - if (mimes) { - result.mimes = mimes; - } - - if (durationRangeSec && durationRangeSec.length === 2) { - result.minduration = durationRangeSec[0]; - result.maxduration = durationRangeSec[1]; - } - - if (protocols && protocols.length) { - result.protocols = protocols; - } - - return result; -} - -function createBannerRequest(bid, mediaType) { - const sizes = mediaType.sizes || bid.sizes; - if (!sizes || !sizes.length) return; - - let format = sizes.map((size) => utils.parseGPTSingleSizeArrayToRtbSize(size)); - let result = utils.parseGPTSingleSizeArrayToRtbSize(sizes[0]); - - if (format.length) { - result.format = format - } - return result; -} - -/** - * Gets bidfloor - * @param {Object} mediaTypes - * @param {Object} bid - * @returns {Number} floor - */ -function _getFloor (mediaTypes, bid) { - const curMediaType = mediaTypes.video ? 'video' : 'banner'; - let floor = bid.params.bidFloor || 0; - - if (typeof bid.getFloor === 'function') { - const floorInfo = bid.getFloor({ - currency: 'USD', - mediaType: curMediaType, - size: bid.sizes.map(([w, h]) => ({w, h})) - }); - - if (typeof floorInfo === 'object' && - floorInfo.currency === 'USD' && - !isNaN(parseFloat(floorInfo.floor))) { - floor = Math.max(floor, parseFloat(floorInfo.floor)); - } - } - - return floor; -} - -function newFormatRequest(validBidRequests, bidderRequest) { - if (!validBidRequests.length) { - return null; - } - let pageKeywords = null; - let jwpseg = null; - let content = null; - let schain = null; - let userId = null; - let userIdAsEids = null; - let user = null; - let userExt = null; - let {bidderRequestId, auctionId, gdprConsent, uspConsent, timeout, refererInfo} = bidderRequest || {}; - - const referer = refererInfo ? encodeURIComponent(refererInfo.referer) : ''; - const imp = []; - const bidsMap = {}; - - validBidRequests.forEach((bid) => { - if (!bidderRequestId) { - bidderRequestId = bid.bidderRequestId; - } - if (!auctionId) { - auctionId = bid.auctionId; - } - if (!schain) { - schain = bid.schain; - } - if (!userId) { - userId = bid.userId; - } - if (!userIdAsEids) { - userIdAsEids = bid.userIdAsEids; - } - const {params: {uid, keywords}, mediaTypes, bidId, adUnitCode, rtd} = bid; - bidsMap[bidId] = bid; - if (!pageKeywords && !utils.isEmpty(keywords)) { - pageKeywords = utils.transformBidderParamKeywords(keywords); - } - const bidFloor = _getFloor(mediaTypes || {}, bid); - const jwTargeting = rtd && rtd.jwplayer && rtd.jwplayer.targeting; - if (jwTargeting) { - if (!jwpseg && jwTargeting.segments) { - jwpseg = jwTargeting.segments; - } - if (!content && jwTargeting.content) { - content = jwTargeting.content; - } - } - let impObj = { - id: bidId, - tagid: uid.toString(), - ext: { - divid: adUnitCode - } - }; - - if (bidFloor) { - impObj.bidfloor = bidFloor; - } - - if (!mediaTypes || mediaTypes[BANNER]) { - const banner = createBannerRequest(bid, mediaTypes ? mediaTypes[BANNER] : {}); - if (banner) { - impObj.banner = banner; - } - } - if (mediaTypes && mediaTypes[VIDEO]) { - const video = createVideoRequest(bid, mediaTypes[VIDEO]); - if (video) { - impObj.video = video; - } - } - - if (impObj.banner || impObj.video) { - imp.push(impObj); - } - }); - - const source = { - tid: auctionId, - ext: { - wrapper: 'Prebid_js', - wrapper_version: '$prebid.version$' - } - }; - - if (schain) { - source.ext.schain = schain; - } - - const bidderTimeout = config.getConfig('bidderTimeout') || timeout; - const tmax = timeout ? Math.min(bidderTimeout, timeout) : bidderTimeout; - - let request = { - id: bidderRequestId, - site: { - page: referer - }, - tmax, - source, - imp - }; - - if (content) { - request.site.content = content; - } - - if (jwpseg && jwpseg.length) { - user = { - data: [{ - name: 'iow_labs_pub_data', - segment: jwpseg.map((seg) => { - return {name: 'jwpseg', value: seg}; - }) - }] - }; - } - - if (gdprConsent && gdprConsent.consentString) { - userExt = {consent: gdprConsent.consentString}; - } - - if (userIdAsEids && userIdAsEids.length) { - userExt = userExt || {}; - userExt.eids = [...userIdAsEids]; - } - - if (userExt && Object.keys(userExt).length) { - user = user || {}; - user.ext = userExt; - } - - if (user) { - request.user = user; - } - - const configKeywords = utils.transformBidderParamKeywords({ - 'user': utils.deepAccess(config.getConfig('ortb2.user'), 'keywords') || null, - 'context': utils.deepAccess(config.getConfig('ortb2.site'), 'keywords') || null - }); - - if (configKeywords.length) { - pageKeywords = (pageKeywords || []).concat(configKeywords); - } - - if (pageKeywords && pageKeywords.length > 0) { - pageKeywords.forEach(deleteValues); - } - - if (pageKeywords) { - request.ext = { - keywords: pageKeywords - }; - } - - if (gdprConsent && gdprConsent.gdprApplies) { - request.regs = { - ext: { - gdpr: gdprConsent.gdprApplies ? 1 : 0 - } - } - } - - if (uspConsent) { - if (!request.regs) { - request.regs = {ext: {}}; - } - request.regs.ext.us_privacy = uspConsent; - } - - return { - method: 'POST', - url: NEW_ENDPOINT_URL, - data: JSON.stringify(request), - newFormat: true, - bidsMap - }; -} - -function oldFormatRequest(validBidRequests, bidderRequest) { - const auids = []; - const bidsMap = {}; - const slotsMapByUid = {}; - const sizeMap = {}; - const bids = validBidRequests || []; - let priceType = 'net'; - let pageKeywords; - let reqId; - - bids.forEach(bid => { - if (bid.params.priceType === 'gross') { - priceType = 'gross'; - } - reqId = bid.bidderRequestId; - const {params: {uid}, adUnitCode} = bid; - auids.push(uid); - const sizesId = utils.parseSizesInput(bid.sizes); - - if (!pageKeywords && !utils.isEmpty(bid.params.keywords)) { - const keywords = utils.transformBidderParamKeywords(bid.params.keywords); - - if (keywords.length > 0) { - keywords.forEach(deleteValues); - } - pageKeywords = keywords; - } - - if (!slotsMapByUid[uid]) { - slotsMapByUid[uid] = {}; - } - const slotsMap = slotsMapByUid[uid]; - if (!slotsMap[adUnitCode]) { - slotsMap[adUnitCode] = {adUnitCode, bids: [bid], parents: []}; - } else { - slotsMap[adUnitCode].bids.push(bid); - } - const slot = slotsMap[adUnitCode]; - - sizesId.forEach((sizeId) => { - sizeMap[sizeId] = true; - if (!bidsMap[uid]) { - bidsMap[uid] = {}; - } - - if (!bidsMap[uid][sizeId]) { - bidsMap[uid][sizeId] = [slot]; - } else { - bidsMap[uid][sizeId].push(slot); - } - slot.parents.push({parent: bidsMap[uid], key: sizeId, uid}); - }); - }); - - const payload = { - pt: priceType, - auids: auids.join(','), - sizes: utils.getKeys(sizeMap).join(','), - r: reqId, - wrapperType: 'Prebid_js', - wrapperVersion: '$prebid.version$' - }; - - if (pageKeywords) { - payload.keywords = JSON.stringify(pageKeywords); - } - - if (bidderRequest) { - if (bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { - payload.u = bidderRequest.refererInfo.referer; - } - if (bidderRequest.timeout) { - payload.wtimeout = bidderRequest.timeout; - } - if (bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.consentString) { - payload.gdpr_consent = bidderRequest.gdprConsent.consentString; - } - payload.gdpr_applies = - (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') - ? Number(bidderRequest.gdprConsent.gdprApplies) : 1; - } - if (bidderRequest.uspConsent) { - payload.us_privacy = bidderRequest.uspConsent; - } - } - - return { - method: 'GET', - url: ENDPOINT_URL, - data: utils.parseQueryStringParameters(payload).replace(/\&$/, ''), - bidsMap, - priceType - }; -} - -registerBidder(spec); diff --git a/modules/trustxBidAdapter.md b/modules/trustxBidAdapter.md deleted file mode 100644 index e891df8f161..00000000000 --- a/modules/trustxBidAdapter.md +++ /dev/null @@ -1,69 +0,0 @@ -# Overview - -Module Name: TrustX Bidder Adapter -Module Type: Bidder Adapter -Maintainer: paul@trustx.org - -# Description - -Module that connects to TrustX demand source to fetch bids. -TrustX Bid Adapter supports Banner and Video (instream and outstream). - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - sizes: [[300, 250]], - bids: [ - { - bidder: "trustx", - params: { - uid: '44', - priceType: 'gross' // by default is 'net' - } - } - ] - },{ - code: 'test-div', - sizes: [[728, 90]], - bids: [ - { - bidder: "trustx", - params: { - uid: 45, - priceType: 'gross', - keywords: { - brandsafety: ['disaster'], - topic: ['stress', 'fear'] - } - } - } - ] - },{ - code: 'test-div', - sizes: [[640, 360]], - mediaTypes: { video: {} }, - bids: [ - { - bidder: "trustx", - params: { - uid: 7697 - } - } - ] - },{ - code: 'test-div', - sizes: [[300, 250]], - bids: [ - { - bidder: "trustx", - params: { - uid: '58851', - useNewFormat: true - } - } - ] - } - ]; -``` diff --git a/modules/turktelekomBidAdapter.js b/modules/turktelekomBidAdapter.js deleted file mode 100644 index 852e557290c..00000000000 --- a/modules/turktelekomBidAdapter.js +++ /dev/null @@ -1,261 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { Renderer } from '../src/Renderer.js'; -import { VIDEO, BANNER } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'turktelekom'; -const ENDPOINT_URL = 'https://ssp.programattik.com/hb'; -const TIME_TO_LIVE = 360; -const ADAPTER_SYNC_URL = 'https://ssp.programattik.com/sync'; -const RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js'; - -const LOG_ERROR_MESS = { - noAuid: 'Bid from response has no auid parameter - ', - noAdm: 'Bid from response has no adm parameter - ', - noBid: 'Array of bid objects is empty', - noPlacementCode: 'Can\'t find in requested bids the bid with auid - ', - emptyUids: 'Uids should be not empty', - emptySeatbid: 'Seatbid array from response has empty item', - emptyResponse: 'Response is empty', - hasEmptySeatbidArray: 'Response has empty seatbid array', - hasNoArrayOfBids: 'Seatbid from response has no array of bid objects - ' -}; -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [ BANNER, VIDEO ], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - return !!bid.params.uid; - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} validBidRequests - an array of bids - * @param {bidderRequest} - bidder request object - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests, bidderRequest) { - const auids = []; - const bidsMap = {}; - const slotsMapByUid = {}; - const sizeMap = {}; - const bids = validBidRequests || []; - let priceType = 'net'; - let reqId; - - bids.forEach(bid => { - if (bid.params.priceType === 'gross') { - priceType = 'gross'; - } - reqId = bid.bidderRequestId; - const {params: {uid}, adUnitCode} = bid; - auids.push(uid); - const sizesId = utils.parseSizesInput(bid.sizes); - - if (!slotsMapByUid[uid]) { - slotsMapByUid[uid] = {}; - } - const slotsMap = slotsMapByUid[uid]; - if (!slotsMap[adUnitCode]) { - slotsMap[adUnitCode] = {adUnitCode, bids: [bid], parents: []}; - } else { - slotsMap[adUnitCode].bids.push(bid); - } - const slot = slotsMap[adUnitCode]; - - sizesId.forEach((sizeId) => { - sizeMap[sizeId] = true; - if (!bidsMap[uid]) { - bidsMap[uid] = {}; - } - - if (!bidsMap[uid][sizeId]) { - bidsMap[uid][sizeId] = [slot]; - } else { - bidsMap[uid][sizeId].push(slot); - } - slot.parents.push({parent: bidsMap[uid], key: sizeId, uid}); - }); - }); - - const payload = { - pt: priceType, - auids: auids.join(','), - sizes: utils.getKeys(sizeMap).join(','), - r: reqId, - wrapperType: 'Prebid_js', - wrapperVersion: '$prebid.version$' - }; - - if (bidderRequest) { - if (bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { - payload.u = bidderRequest.refererInfo.referer; - } - if (bidderRequest.timeout) { - payload.wtimeout = bidderRequest.timeout; - } - if (bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.consentString) { - payload.gdpr_consent = bidderRequest.gdprConsent.consentString; - } - payload.gdpr_applies = - (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') - ? Number(bidderRequest.gdprConsent.gdprApplies) : 1; - } - } - - return { - method: 'GET', - url: ENDPOINT_URL, - data: utils.parseQueryStringParameters(payload).replace(/\&$/, ''), - bidsMap: bidsMap, - }; - }, - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @param {*} bidRequest - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse, bidRequest, RendererConst = Renderer) { - serverResponse = serverResponse && serverResponse.body; - const bidResponses = []; - const bidsMap = bidRequest.bidsMap; - const priceType = bidRequest.data.pt; - - let errorMessage; - - if (!serverResponse) errorMessage = LOG_ERROR_MESS.emptyResponse; - else if (serverResponse.seatbid && !serverResponse.seatbid.length) { - errorMessage = LOG_ERROR_MESS.hasEmptySeatbidArray; - } - - if (!errorMessage && serverResponse.seatbid) { - serverResponse.seatbid.forEach(respItem => { - _addBidResponse(_getBidFromResponse(respItem), bidsMap, priceType, bidResponses, RendererConst); - }); - } - if (errorMessage) utils.logError(errorMessage); - return bidResponses; - }, - getUserSyncs: function(syncOptions) { - if (syncOptions.pixelEnabled) { - return [{ - type: 'image', - url: ADAPTER_SYNC_URL - }]; - } - } -} - -function _getBidFromResponse(respItem) { - if (!respItem) { - utils.logError(LOG_ERROR_MESS.emptySeatbid); - } else if (!respItem.bid) { - utils.logError(LOG_ERROR_MESS.hasNoArrayOfBids + JSON.stringify(respItem)); - } else if (!respItem.bid[0]) { - utils.logError(LOG_ERROR_MESS.noBid); - } - return respItem && respItem.bid && respItem.bid[0]; -} - -function _addBidResponse(serverBid, bidsMap, priceType, bidResponses, RendererConst) { - if (!serverBid) return; - let errorMessage; - if (!serverBid.auid) errorMessage = LOG_ERROR_MESS.noAuid + JSON.stringify(serverBid); - if (!serverBid.adm) errorMessage = LOG_ERROR_MESS.noAdm + JSON.stringify(serverBid); - else { - const awaitingBids = bidsMap[serverBid.auid]; - if (awaitingBids) { - const sizeId = `${serverBid.w}x${serverBid.h}`; - if (awaitingBids[sizeId]) { - const slot = awaitingBids[sizeId][0]; - - const bid = slot.bids.shift(); - const bidResponse = { - requestId: bid.bidId, // bid.bidderRequestId, - bidderCode: spec.code, - cpm: serverBid.price, - width: serverBid.w, - height: serverBid.h, - creativeId: serverBid.auid, // bid.bidId, - currency: 'TRY', - netRevenue: priceType !== 'gross', - ttl: TIME_TO_LIVE, - dealId: serverBid.dealid - }; - if (serverBid.content_type === 'video') { - bidResponse.vastXml = serverBid.adm; - bidResponse.mediaType = VIDEO; - bidResponse.adResponse = { - content: bidResponse.vastXml - }; - if (!bid.renderer && (!bid.mediaTypes || !bid.mediaTypes.video || bid.mediaTypes.video.context === 'outstream')) { - bidResponse.renderer = createRenderer(bidResponse, { - id: bid.bidId, - url: RENDERER_URL - }, RendererConst); - } - } else { - bidResponse.ad = serverBid.adm; - bidResponse.mediaType = BANNER; - } - - bidResponses.push(bidResponse); - - if (!slot.bids.length) { - slot.parents.forEach(({parent, key, uid}) => { - const index = parent[key].indexOf(slot); - if (index > -1) { - parent[key].splice(index, 1); - } - if (!parent[key].length) { - delete parent[key]; - if (!utils.getKeys(parent).length) { - delete bidsMap[uid]; - } - } - }); - } - } - } else { - errorMessage = LOG_ERROR_MESS.noPlacementCode + serverBid.auid; - } - } - if (errorMessage) { - utils.logError(errorMessage); - } -} - -function outstreamRender (bid) { - bid.renderer.push(() => { - window.ANOutstreamVideo.renderAd({ - targetId: bid.adUnitCode, - adResponse: bid.adResponse - }); - }); -} - -function createRenderer (bid, rendererParams, RendererConst) { - const rendererInst = RendererConst.install({ - id: rendererParams.id, - url: rendererParams.url, - loaded: false - }); - - try { - rendererInst.setRender(outstreamRender); - } catch (err) { - utils.logWarn('Prebid Error calling setRender on renderer', err); - } - - return rendererInst; -} - -registerBidder(spec); diff --git a/modules/turktelekomBidAdapter.md b/modules/turktelekomBidAdapter.md deleted file mode 100644 index 360e7f95230..00000000000 --- a/modules/turktelekomBidAdapter.md +++ /dev/null @@ -1,49 +0,0 @@ -# Overview - -Module Name: Türk Telekom Bidder Adapter -Module Type: Bidder Adapter -Maintainer: turktelssp@gmail.com - -# Description - -Module that connects to Türk Telekom demand source to fetch bids. -Türk Telekom Bid Adapter supports Banner and Video (instream and outstream). - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]] - } - }, - bids: [ - { - bidder: "turktelekom", - params: { - uid: 17, - priceType: 'gross' // by default is 'net' - } - } - ] - },{ - code: 'test-div', - mediaTypes: { - video: { - playerSize: [[640, 360]], - context: 'instream' - } - }, - bids: [ - { - bidder: "turktelekom", - params: { - uid: 19 - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/ucfunnelAnalyticsAdapter.js b/modules/ucfunnelAnalyticsAdapter.js deleted file mode 100644 index 7a471a1d3b4..00000000000 --- a/modules/ucfunnelAnalyticsAdapter.js +++ /dev/null @@ -1,199 +0,0 @@ -import {ajax} from '../src/ajax.js'; -import adapter from '../src/AnalyticsAdapter.js'; -import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import {logError, logInfo, deepClone} from '../src/utils.js'; - -const analyticsType = 'endpoint'; - -export const ANALYTICS_VERSION = '1.0.0'; - -const ANALYTICS_SERVER = 'https://hbwa.aralego.com'; - -const { - EVENTS: { - AUCTION_END, - BID_WON, - BID_TIMEOUT - } -} = CONSTANTS; - -export const BIDDER_STATUS = { - BID: 'bid', - NO_BID: 'noBid', - BID_WON: 'bidWon', - TIMEOUT: 'timeout' -}; - -const analyticsOptions = {}; - -export const parseBidderCode = function (bid) { - let bidderCode = bid.bidderCode || bid.bidder; - return bidderCode.toLowerCase(); -}; - -export const parseAdUnitCode = function (bidResponse) { - return bidResponse.adUnitCode.toLowerCase(); -}; - -export const ucfunnelAnalyticsAdapter = Object.assign(adapter({ANALYTICS_SERVER, analyticsType}), { - - cachedAuctions: {}, - - initConfig(config) { - /** - * Required option: pbuid - * Required option: adid - * @type {boolean} - */ - analyticsOptions.options = deepClone(config.options); - if (typeof config.options.pbuid !== 'string' || config.options.pbuid.length < 1) { - logError('"options.pbuid" is required.'); - return false; - } - if (typeof config.options.adid !== 'string' || config.options.adid.length < 1) { - logError('"options.adid" is required.'); - return false; - } - analyticsOptions.sampled = true; - if (typeof config.options.sampling === 'number') { - analyticsOptions.sampled = Math.random() < parseFloat(config.options.sampling); - } - - analyticsOptions.pbuid = config.options.pbuid - analyticsOptions.adid = config.options.adid - analyticsOptions.server = ANALYTICS_SERVER; - return true; - }, - sendEventMessage(endPoint, data) { - logInfo(`AJAX: ${endPoint}: ` + JSON.stringify(data)); - - ajax(`${analyticsOptions.server}/${endPoint}`, null, JSON.stringify(data), { - contentType: 'application/json', - withCredentials: true - }); - }, - createCommonMessage(auctionId) { - return { - version: ANALYTICS_VERSION, - auctionId: auctionId, - referrer: window.location.href, - sampling: analyticsOptions.options.sampling, - prebid: '$prebid.version$', - adid: analyticsOptions.adid, - pbuid: analyticsOptions.pbuid, - adUnits: {}, - }; - }, - serializeBidResponse(bid, status) { - const result = { - prebidWon: (status === BIDDER_STATUS.BID_WON), - isTimeout: (status === BIDDER_STATUS.TIMEOUT), - status: status, - }; - if (status === BIDDER_STATUS.BID || status === BIDDER_STATUS.BID_WON) { - Object.assign(result, { - time: bid.timeToRespond, - cpm: bid.cpm, - currency: bid.currency, - }); - } - return result; - }, - addBidResponseToMessage(message, bid, status) { - const adUnitCode = parseAdUnitCode(bid); - message.adUnits[adUnitCode] = message.adUnits[adUnitCode] || {}; - const bidder = parseBidderCode(bid); - const bidResponse = this.serializeBidResponse(bid, status); - message.adUnits[adUnitCode][bidder] = bidResponse; - }, - createBidMessage(auctionEndArgs, winningBids, timeoutBids) { - const {auctionId, timestamp, auctionEnd, adUnitCodes, bidsReceived, noBids} = auctionEndArgs; - const message = this.createCommonMessage(auctionId); - - message.auctionElapsed = (auctionEnd - timestamp); - - adUnitCodes.forEach((adUnitCode) => { - message.adUnits[adUnitCode] = {}; - }); - - // In this situation, the bid exists in both noBids and bids arrays. - noBids.forEach(bid => this.addBidResponseToMessage(message, bid, BIDDER_STATUS.NO_BID)); - - // This array may contain some timeout bids (responses come back after auction timeout) - bidsReceived.forEach(bid => this.addBidResponseToMessage(message, bid, BIDDER_STATUS.BID)); - - // We handle timeout after bids since it's possible that a bid has a response, but the response comes back - // after auction end. In this case, the bid exists in both bidsReceived and timeoutBids arrays. - timeoutBids.forEach(bid => this.addBidResponseToMessage(message, bid, BIDDER_STATUS.TIMEOUT)); - - // mark the winning bids with prebidWon = true - winningBids.forEach(bid => { - const adUnitCode = parseAdUnitCode(bid); - const bidder = parseBidderCode(bid); - message.adUnits[adUnitCode][bidder].prebidWon = true; - }); - return message; - }, - createImpressionMessage(bid) { - const message = this.createCommonMessage(bid.auctionId); - this.addBidResponseToMessage(message, bid, BIDDER_STATUS.BID_WON); - return message; - }, - getCachedAuction(auctionId) { - this.cachedAuctions[auctionId] = this.cachedAuctions[auctionId] || { - timeoutBids: [], - }; - return this.cachedAuctions[auctionId]; - }, - handleAuctionEnd(auctionEndArgs) { - const cachedAuction = this.getCachedAuction(auctionEndArgs.auctionId); - const highestCpmBids = getGlobal().getHighestCpmBids(); - this.sendEventMessage('bid', - this.createBidMessage(auctionEndArgs, highestCpmBids, cachedAuction.timeoutBids) - ); - }, - handleBidTimeout(timeoutBids) { - timeoutBids.forEach((bid) => { - const cachedAuction = this.getCachedAuction(bid.auctionId); - cachedAuction.timeoutBids.push(bid); - }); - }, - handleBidWon(bidWonArgs) { - this.sendEventMessage('imp', this.createImpressionMessage(bidWonArgs)); - }, - track({eventType, args}) { - if (analyticsOptions.sampled) { - switch (eventType) { - case BID_WON: - this.handleBidWon(args); - break; - case BID_TIMEOUT: - this.handleBidTimeout(args); - break; - case AUCTION_END: - this.handleAuctionEnd(args); - break; - } - } - }, - getAnalyticsOptions() { - return analyticsOptions; - }, -}); - -// save the base class function -ucfunnelAnalyticsAdapter.originEnableAnalytics = ucfunnelAnalyticsAdapter.enableAnalytics; - -// override enableAnalytics so we can get access to the config passed in from the page -ucfunnelAnalyticsAdapter.enableAnalytics = function (config) { - if (this.initConfig(config)) { - ucfunnelAnalyticsAdapter.originEnableAnalytics(config); // call the base class function - } -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: ucfunnelAnalyticsAdapter, - code: 'ucfunnelAnalytics' -}); diff --git a/modules/ucfunnelAnalyticsAdapter.md b/modules/ucfunnelAnalyticsAdapter.md deleted file mode 100644 index be15e307332..00000000000 --- a/modules/ucfunnelAnalyticsAdapter.md +++ /dev/null @@ -1,23 +0,0 @@ -# Overview - -``` -Module Name: ucfunnel Analytics Adapter -Module Type: Analytics Adapter -Maintainer: cliff.liu@ucfunnel.com -``` - -# Description - -Analytics adapter for ucfunnel - -# Test Parameters - -``` -{ - provider: 'ucfunnelAnalytics', - options: { - pbuid: "PBUID_FROM_UCFUNNEL" - adid: "BIDDING_ADID_FROM_UCFUNNEL" - } -} -``` diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js deleted file mode 100644 index 734aba97789..00000000000 --- a/modules/ucfunnelBidAdapter.js +++ /dev/null @@ -1,361 +0,0 @@ -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 * as utils from '../src/utils.js'; -const storage = getStorageManager(); -const COOKIE_NAME = 'ucf_uid'; -const VER = 'ADGENT_PREBID-2018011501'; -const BIDDER_CODE = 'ucfunnel'; -const GVLID = 607; -const VIDEO_CONTEXT = { - INSTREAM: 0, - OUSTREAM: 2 -} - -export const spec = { - code: BIDDER_CODE, - gvlid: GVLID, - ENDPOINT: 'https://hb.aralego.com/header', - supportedMediaTypes: [BANNER, VIDEO, NATIVE], - /** - * Check if the bid is a valid zone ID in either number or string form - * @param {object} bid the ucfunnel bid to validate - * @return boolean for whether or not a bid is valid - */ - isBidRequestValid: function(bid) { - const isVideoMediaType = (bid.mediaTypes && bid.mediaTypes.video != null); - const videoContext = (bid.mediaTypes && bid.mediaTypes.video != null) ? bid.mediaTypes.video.videoContext : ''; - - if (typeof bid.params !== 'object' || typeof bid.params.adid != 'string') { - return false; - } - - if (isVideoMediaType && videoContext === 'outstream') { - return false; - } - - return true; - }, - - /** - * @param {BidRequest[]} bidRequests - * @param {*} bidderRequest - * @return {ServerRequest} - */ - buildRequests: function(bids, bidderRequest) { - return bids.map(bid => { - return { - method: 'GET', - url: spec.ENDPOINT, - data: getRequestData(bid, bidderRequest), - bidRequest: bid - } - }); - }, - - /** - * Format ucfunnel responses as Prebid bid responses - * @param {ucfunnelResponseObj} ucfunnelResponse A successful response from ucfunnel. - * @return {Bid[]} An array of formatted bids. - */ - interpretResponse: function (ucfunnelResponseObj, request) { - const bidRequest = request.bidRequest; - const ad = ucfunnelResponseObj ? ucfunnelResponseObj.body : {}; - const videoPlayerSize = parseSizes(bidRequest); - - let bid = { - requestId: bidRequest.bidId, - cpm: ad.cpm || 0, - creativeId: ad.crid || ad.ad_id || bidRequest.params.adid, - dealId: ad.deal || null, - currency: ad.currency || 'USD', - netRevenue: true, - ttl: 1800, - meta: {} - }; - - if (bidRequest.params && bidRequest.params.bidfloor && ad.cpm && ad.cpm < bidRequest.params.bidfloor) { - bid.cpm = 0; - } - if (ad.creative_type) { - bid.mediaType = ad.creative_type; - bid.meta.mediaType = ad.creative_type; - } - if (ad.adomain) { - bid.meta.advertiserDomains = ad.adomain; - } - - switch (ad.creative_type) { - case NATIVE: - let nativeAd = ad.native; - Object.assign(bid, { - width: 1, - height: 1, - native: { - title: nativeAd.title, - body: nativeAd.desc, - cta: nativeAd.ctatext, - sponsoredBy: nativeAd.sponsored, - image: nativeAd.image || nativeAd.image.url, - icon: nativeAd.icon || nativeAd.icon.url, - clickUrl: nativeAd.clickUrl, - clickTrackers: (nativeAd.clicktrackers) ? nativeAd.clicktrackers : [], - impressionTrackers: nativeAd.impressionTrackers, - } - }); - break; - case VIDEO: - Object.assign(bid, { - vastUrl: ad.vastUrl, - vastXml: ad.vastXml - }); - - if (videoPlayerSize && videoPlayerSize.length === 2) { - Object.assign(bid, { - width: videoPlayerSize[0], - height: videoPlayerSize[1] - }); - } - break; - case BANNER: - default: - var size = parseSizes(bidRequest); - Object.assign(bid, { - width: ad.width || size[0], - height: ad.height || size[1], - ad: ad.adm || '' - }); - } - - return [bid]; - }, - - getUserSyncs: function(syncOptions, serverResponses, gdprConsent = {}, uspConsent) { - let gdprApplies = (gdprConsent && gdprConsent.gdprApplies) ? '1' : ''; - let apiVersion = (gdprConsent) ? gdprConsent.apiVersion : ''; - let consentString = (gdprConsent) ? gdprConsent.consentString : ''; - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: 'https://cdn.aralego.net/ucfad/cookie/sync.html' + getCookieSyncParameter(gdprApplies, apiVersion, consentString, uspConsent) - }]; - } else if (syncOptions.pixelEnabled) { - return [{ - type: 'image', - url: 'https://sync.aralego.com/idSync' + getCookieSyncParameter(gdprApplies, apiVersion, consentString, uspConsent) - }]; - } - } -}; -registerBidder(spec); - -function transformSizes(requestSizes) { - if (typeof requestSizes === 'object' && requestSizes.length) { - return requestSizes[0]; - } -} - -function getCookieSyncParameter(gdprApplies, apiVersion, consentString, uspConsent) { - let param = '?'; - if (gdprApplies == '1') { - param = param + 'gdpr=1&'; - } - if (apiVersion == 1) { - param = param + 'euconsent=' + consentString + '&'; - } else if (apiVersion == 2) { - param = param + 'euconsent-v2=' + consentString + '&'; - } - if (uspConsent) { - param = param + 'usprivacy=' + uspConsent; - } - return (param == '?') ? '' : param; -} - -function parseSizes(bid) { - let params = bid.params; - if (bid.mediaType === VIDEO) { - let size = []; - if (params.video && params.video.playerWidth && params.video.playerHeight) { - size = [ - params.video.playerWidth, - params.video.playerHeight - ]; - return size; - } - } - - return transformSizes(bid.sizes); -} - -function getSupplyChain(schain) { - var supplyChain = ''; - if (schain != null && schain.nodes) { - supplyChain = schain.ver + ',' + schain.complete; - for (let i = 0; i < schain.nodes.length; i++) { - supplyChain += '!'; - supplyChain += (schain.nodes[i].asi) ? encodeURIComponent(schain.nodes[i].asi) : ''; - supplyChain += ','; - supplyChain += (schain.nodes[i].sid) ? encodeURIComponent(schain.nodes[i].sid) : ''; - supplyChain += ','; - supplyChain += (schain.nodes[i].hp) ? encodeURIComponent(schain.nodes[i].hp) : ''; - supplyChain += ','; - supplyChain += (schain.nodes[i].rid) ? encodeURIComponent(schain.nodes[i].rid) : ''; - supplyChain += ','; - supplyChain += (schain.nodes[i].name) ? encodeURIComponent(schain.nodes[i].name) : ''; - supplyChain += ','; - supplyChain += (schain.nodes[i].domain) ? encodeURIComponent(schain.nodes[i].domain) : ''; - } - } - return supplyChain; -} - -function getRequestData(bid, bidderRequest) { - const size = parseSizes(bid); - const language = navigator.language; - const dnt = (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0; - const userIdTdid = (bid.userId && bid.userId.tdid) ? bid.userId.tdid : ''; - const supplyChain = getSupplyChain(bid.schain); - // general bid data - let bidData = { - ver: VER, - ifr: 0, - bl: language, - je: 1, - dnt: dnt, - adid: bid.params.adid, - tdid: userIdTdid, - schain: supplyChain, - fp: bid.params.bidfloor - }; - addUserId(bidData, bid.userId); - try { - bidData.host = window.top.location.hostname; - bidData.u = config.getConfig('publisherDomain') || window.top.location.href; - bidData.xr = 0; - } catch (e) { - bidData.host = window.location.hostname; - bidData.u = config.getConfig('publisherDomain') || bidderRequest.refererInfo.referrer || document.referrer || window.location.href; - bidData.xr = 1; - } - - if (window.location.ancestorOrigins && window.location.ancestorOrigins.length > 0) { - bidData.ao = window.location.ancestorOrigins[window.location.ancestorOrigins.length - 1]; - } - - if (storage.cookiesAreEnabled()) { - let ucfUid = ''; - if (storage.getCookie(COOKIE_NAME) != undefined) { - ucfUid = storage.getCookie(COOKIE_NAME); - bidData.ucfUid = ucfUid; - } else { - ucfUid = utils.generateUUID(); - bidData.ucfUid = ucfUid; - storage.setCookie(COOKIE_NAME, ucfUid); - } - } - - if (size != undefined && size.length == 2) { - bidData.w = size[0]; - bidData.h = size[1]; - } - - if (bidderRequest && bidderRequest.uspConsent) { - Object.assign(bidData, { - usprivacy: bidderRequest.uspConsent - }); - } - if (bid.mediaTypes && bid.mediaTypes.video != null) { - const videoContext = bid.mediaTypes.video.context; - switch (videoContext) { - case 'outstream': - bidData.atype = VIDEO_CONTEXT.OUSTREAM; - break; - case 'instream': - default: - bidData.atype = VIDEO_CONTEXT.INSTREAM; - break; - } - } - - if (bidderRequest && bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.apiVersion == 1) { - Object.assign(bidData, { - gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0, - euconsent: bidderRequest.gdprConsent.consentString - }); - } else if (bidderRequest.gdprConsent.apiVersion == 2) { - Object.assign(bidData, { - gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0, - 'euconsent-v2': bidderRequest.gdprConsent.consentString - }); - } - } - - if (config.getConfig('coppa')) { - bidData.coppa = true; - } - - return bidData; -} - -function addUserId(bidData, userId) { - bidData['eids'] = ''; - utils._each(userId, (userIdObjectOrValue, userIdProviderKey) => { - switch (userIdProviderKey) { - case 'sharedid': - if (userIdObjectOrValue.id) { - bidData[userIdProviderKey + '_id'] = userIdObjectOrValue.id; - } - if (userIdObjectOrValue.third) { - bidData[userIdProviderKey + '_third'] = userIdObjectOrValue.third; - } - break; - case 'haloId': - if (userIdObjectOrValue.haloId) { - bidData[userIdProviderKey + 'haloId'] = userIdObjectOrValue.haloId; - } - if (userIdObjectOrValue.auSeg) { - bidData[userIdProviderKey + '_auSeg'] = userIdObjectOrValue.auSeg; - } - break; - case 'parrableId': - if (userIdObjectOrValue.eid) { - bidData[userIdProviderKey + '_eid'] = userIdObjectOrValue.eid; - } - break; - case 'id5id': - if (userIdObjectOrValue.uid) { - bidData[userIdProviderKey + '_uid'] = userIdObjectOrValue.uid; - } - if (userIdObjectOrValue.ext && userIdObjectOrValue.ext.linkType) { - bidData[userIdProviderKey + '_linkType'] = userIdObjectOrValue.ext.linkType; - } - break; - case 'uid2': - if (userIdObjectOrValue.id) { - bidData['eids'] = (bidData['eids'].length > 0) - ? (bidData['eids'] + '!' + userIdProviderKey + ',' + userIdObjectOrValue.id) - : (userIdProviderKey + ',' + userIdObjectOrValue.id); - } - break; - case 'connectid': - if (userIdObjectOrValue) { - bidData['eids'] = (bidData['eids'].length > 0) - ? (bidData['eids'] + '!verizonMediaId,' + userIdObjectOrValue) - : ('verizonMediaId,' + userIdObjectOrValue); - } - break; - case 'flocId': - if (userIdObjectOrValue.id) { - bidData['cid'] = userIdObjectOrValue.id; - } - break; - default: - bidData[userIdProviderKey] = userIdObjectOrValue; - break; - } - }); - - return bidData; -} diff --git a/modules/ucfunnelBidAdapter.md b/modules/ucfunnelBidAdapter.md deleted file mode 100644 index 717d2a0089c..00000000000 --- a/modules/ucfunnelBidAdapter.md +++ /dev/null @@ -1,30 +0,0 @@ -# Overview - -``` -Module Name: ucfunnel Bid Adapter -Module Type: Bidder Adapter -Maintainer: ryan.chou@ucfunnel.com -``` - -# Description - -This module connects to ucfunnel's demand sources. It supports display, and rich media formats. -ucfunnel will provide ``adid`` that are specific to your ad type. -Please reach out to ``pr@ucfunnel.com`` to set up an ucfunnel account and above ids. -Use bidder code ```ucfunnel``` for all ucfunnel traffic. - -# Test Parameters - -``` - var adUnits = [ - { - code: 'test-LERC', - sizes: [[300, 250]], - bids: [{ - bidder: 'ucfunnel', - params: { - adid: "test-ad-83444226E44368D1E32E49EEBE6D29" //String - required - } - } - ]; -``` \ No newline at end of file diff --git a/modules/uid2IdSystem.js b/modules/uid2IdSystem.js deleted file mode 100644 index 053b57cb76d..00000000000 --- a/modules/uid2IdSystem.js +++ /dev/null @@ -1,97 +0,0 @@ -/** - * This module adds uid2 ID support to the User ID module - * The {@link module:modules/userId} module is required. - * @module modules/uid2IdSystem - * @requires module:modules/userId - */ - -import * as utils from '../src/utils.js' -import {submodule} from '../src/hook.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const MODULE_NAME = 'uid2'; -const GVLID = 887; -const LOG_PRE_FIX = 'UID2: '; -const ADVERTISING_COOKIE = '__uid2_advertising_token'; - -function readCookie() { - return storage.cookiesAreEnabled() ? storage.getCookie(ADVERTISING_COOKIE) : null; -} - -function readFromLocalStorage() { - return storage.localStorageIsEnabled() ? storage.getDataFromLocalStorage(ADVERTISING_COOKIE) : null; -} - -function getStorage() { - return getStorageManager(GVLID, MODULE_NAME); -} - -const storage = getStorage(); - -const logInfo = createLogInfo(LOG_PRE_FIX); - -function createLogInfo(prefix) { - return function (...strings) { - utils.logInfo(prefix + ' ', ...strings); - } -} - -/** - * Encode the id - * @param value - * @returns {string|*} - */ -function encodeId(value) { - const result = {}; - if (value) { - const bidIds = { - id: value - } - result.uid2 = bidIds; - logInfo('Decoded value ' + JSON.stringify(result)); - return result; - } - return undefined; -} - -/** @type {Submodule} */ -export const uid2IdSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: MODULE_NAME, - - /** - * Vendor id of Prebid - * @type {Number} - */ - gvlid: GVLID, - /** - * decode the stored id value for passing to bid requests - * @function - * @param {string} value - * @returns {{uid2:{ id: string }} or undefined if value doesn't exists - */ - decode(value) { - return (value) ? encodeId(value) : undefined; - }, - - /** - * performs action to obtain id and return a value. - * @function - * @param {SubmoduleConfig} [config] - * @param {ConsentData|undefined} consentData - * @returns {uid2Id} - */ - getId(config, consentData) { - logInfo('Creating UID 2.0'); - let value = readCookie() || readFromLocalStorage(); - logInfo('The advertising token: ' + value); - return {id: value} - }, - -}; - -// Register submodule for userId -submodule('userId', uid2IdSubmodule); diff --git a/modules/uid2IdSystem.md b/modules/uid2IdSystem.md deleted file mode 100644 index fa596b17584..00000000000 --- a/modules/uid2IdSystem.md +++ /dev/null @@ -1,24 +0,0 @@ -## UID 2.0 User ID Submodule - -UID 2.0 ID Module. - -### Prebid Params - -Individual params may be set for the UID 2.0 Submodule. At least one identifier must be set in the params. - -``` -pbjs.setConfig({ - userSync: { - userIds: [{ - name: 'uid2' - }] - } -}); -``` -## Parameter Descriptions for the `usersync` Configuration Section -The below parameters apply only to the UID 2.0 User ID Module integration. - -| Param under userSync.userIds[] | Scope | Type | Description | Example | -| --- | --- | --- | --- | --- | -| name | Required | String | ID value for the UID20 module - `"uid2"` | `"uid2"` | -| value | Optional | Object | Used only if the page has a separate mechanism for storing the UID 2.0 ID. The value is an object containing the values to be sent to the adapters. In this scenario, no URL is called and nothing is added to local storage | `{"uid2": { "id": "eb33b0cb-8d35-4722-b9c0-1a31d4064888"}}` | diff --git a/modules/underdogmediaBidAdapter.js b/modules/underdogmediaBidAdapter.js deleted file mode 100644 index 8368077a627..00000000000 --- a/modules/underdogmediaBidAdapter.js +++ /dev/null @@ -1,179 +0,0 @@ -import * as utils from '../src/utils.js'; -import { config } from '../src/config.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -const BIDDER_CODE = 'underdogmedia'; -const UDM_ADAPTER_VERSION = '3.5V'; -const UDM_VENDOR_ID = '159'; -const prebidVersion = '$prebid.version$'; -let USER_SYNCED = false; - -utils.logMessage(`Initializing UDM Adapter. PBJS Version: ${prebidVersion} with adapter version: ${UDM_ADAPTER_VERSION} Updated 20191028`); - -// helper function for testing user syncs -export function resetUserSync() { - USER_SYNCED = false; -} - -export const spec = { - code: BIDDER_CODE, - bidParams: [], - - isBidRequestValid: function (bid) { - const bidSizes = bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes ? bid.mediaTypes.banner.sizes : bid.sizes; - return !!((bid.params && bid.params.siteId) && (bidSizes && bidSizes.length > 0)); - }, - - buildRequests: function (validBidRequests, bidderRequest) { - var sizes = []; - var siteId = 0; - - validBidRequests.forEach(bidParam => { - let bidParamSizes = bidParam.mediaTypes && bidParam.mediaTypes.banner && bidParam.mediaTypes.banner.sizes ? bidParam.mediaTypes.banner.sizes : bidParam.sizes; - sizes = utils.flatten(sizes, utils.parseSizesInput(bidParamSizes)); - siteId = bidParam.params.siteId; - }); - - let data = { - tid: 1, - dt: 10, - sid: siteId, - sizes: sizes.join(','), - version: UDM_ADAPTER_VERSION - } - - if (bidderRequest && bidderRequest.gdprConsent) { - if (typeof bidderRequest.gdprConsent.gdprApplies !== 'undefined') { - data.gdprApplies = !!(bidderRequest.gdprConsent.gdprApplies); - } - if (bidderRequest.gdprConsent.vendorData && bidderRequest.gdprConsent.vendorData.vendorConsents && - typeof bidderRequest.gdprConsent.vendorData.vendorConsents[UDM_VENDOR_ID] !== 'undefined') { - data.consentGiven = !!(bidderRequest.gdprConsent.vendorData.vendorConsents[UDM_VENDOR_ID]); - } - if (typeof bidderRequest.gdprConsent.consentString !== 'undefined') { - data.consentData = bidderRequest.gdprConsent.consentString; - } - } - - if (bidderRequest.uspConsent) { - data.uspConsent = bidderRequest.uspConsent; - } - - if (!data.gdprApplies || data.consentGiven) { - return { - method: 'GET', - url: 'https://udmserve.net/udm/img.fetch', - data: data, - bidParams: validBidRequests - }; - } - }, - - getUserSyncs: function (syncOptions, serverResponses) { - if (!USER_SYNCED && serverResponses.length > 0 && serverResponses[0].body && serverResponses[0].body.userSyncs && serverResponses[0].body.userSyncs.length > 0) { - USER_SYNCED = true; - const userSyncs = serverResponses[0].body.userSyncs; - const syncs = userSyncs.filter(sync => { - const {type} = sync; - if (syncOptions.iframeEnabled && type === 'iframe') { - return true - } - if (syncOptions.pixelEnabled && type === 'image') { - return true - } - }) - return syncs; - } - }, - - interpretResponse: function (serverResponse, bidRequest) { - const bidResponses = []; - bidRequest.bidParams.forEach(bidParam => { - serverResponse.body.mids.forEach(mid => { - if (mid.useCount > 0) { - return; - } - - if (!mid.useCount) { - mid.useCount = 0; - } - - var sizeNotFound = true; - const bidParamSizes = bidParam.mediaTypes && bidParam.mediaTypes.banner && bidParam.mediaTypes.banner.sizes ? bidParam.mediaTypes.banner.sizes : bidParam.sizes - utils.parseSizesInput(bidParamSizes).forEach(size => { - if (size === mid.width + 'x' + mid.height) { - sizeNotFound = false; - } - }); - - if (sizeNotFound) { - return; - } - - const bidResponse = { - requestId: bidParam.bidId, - bidderCode: spec.code, - cpm: parseFloat(mid.cpm), - width: mid.width, - height: mid.height, - ad: mid.ad_code_html, - creativeId: mid.mid, - currency: 'USD', - netRevenue: false, - ttl: mid.ttl || 60, - }; - - if (bidResponse.cpm <= 0) { - return; - } - if (bidResponse.ad.length <= 0) { - return; - } - - mid.useCount++; - - bidResponse.ad += makeNotification(bidResponse, mid, bidParam); - - bidResponses.push(bidResponse); - }); - }); - - return bidResponses; - }, -}; - -function makeNotification(bid, mid, bidParam) { - let url = mid.notification_url; - - const versionIndex = url.indexOf(';version=') - if (versionIndex + 1) { - url = url.substring(0, versionIndex) - } - - url += `;version=${UDM_ADAPTER_VERSION}`; - url += ';cb=' + Math.random(); - url += ';qqq=' + (1 / bid.cpm); - url += ';hbt=' + config.getConfig('_bidderTimeout'); - url += ';style=adapter'; - url += ';vis=' + encodeURIComponent(document.visibilityState); - - url += ';traffic_info=' + encodeURIComponent(JSON.stringify(getUrlVars())); - if (bidParam.params.subId) { - url += ';subid=' + encodeURIComponent(bidParam.params.subId); - } - return ''; -} - -function getUrlVars() { - var vars = {}; - var hash; - var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'); - for (var i = 0; i < hashes.length; i++) { - hash = hashes[i].split('='); - if (hash[0].match(/^utm_/)) { - vars[hash[0]] = hash[1].substr(0, 150); - } - } - return vars; -} - -registerBidder(spec); diff --git a/modules/underdogmediaBidAdapter.md b/modules/underdogmediaBidAdapter.md deleted file mode 100644 index ac7434da482..00000000000 --- a/modules/underdogmediaBidAdapter.md +++ /dev/null @@ -1,31 +0,0 @@ -# Overview - -**Module Name**: Underdog Media Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: jake@underdogmedia.com - -# Description - -Module that connects to Underdog Media's servers to fetch bids. - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 250]], // a display size - } - }, - bids: [ - { - bidder: "underdogmedia", - params: { - siteId: '12143' - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/undertoneBidAdapter.js b/modules/undertoneBidAdapter.js deleted file mode 100644 index 14a765206b6..00000000000 --- a/modules/undertoneBidAdapter.js +++ /dev/null @@ -1,216 +0,0 @@ -/** - * Adapter to send bids to Undertone - */ - -import { deepAccess, parseUrl } from '../src/utils.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'; -const FRAME_USER_SYNC = 'https://cdn.undertone.com/js/usersync.html'; -const PIXEL_USER_SYNC_1 = 'https://usr.undertone.com/userPixel/syncOne?id=1&of=2'; -const PIXEL_USER_SYNC_2 = 'https://usr.undertone.com/userPixel/syncOne?id=2&of=2'; - -function getCanonicalUrl() { - try { - let doc = window.top.document; - let element = doc.querySelector("link[rel='canonical']"); - if (element !== null) { - return element.href; - } - } catch (e) { - } - return null; -} - -function extractDomainFromHost(pageHost) { - let domain = null; - try { - let domains = /[-\w]+\.([-\w]+|[-\w]{3,}|[-\w]{1,3}\.[-\w]{2})$/i.exec(pageHost); - if (domains != null && domains.length > 0) { - domain = domains[0]; - for (let i = 1; i < domains.length; i++) { - if (domains[i].length > domain.length) { - domain = domains[i]; - } - } - } - } catch (e) { - domain = null; - } - return domain; -} - -function getGdprQueryParams(gdprConsent) { - if (!gdprConsent) { - return null; - } - - let gdpr = gdprConsent.gdprApplies ? '1' : '0'; - let gdprstr = gdprConsent.consentString ? gdprConsent.consentString : ''; - return `gdpr=${gdpr}&gdprstr=${gdprstr}`; -} - -function getBannerCoords(id) { - let element = document.getElementById(id); - let left = -1; - let top = -1; - if (element) { - left = element.offsetLeft; - top = element.offsetTop; - - let parent = element.offsetParent; - if (parent) { - left += parent.offsetLeft; - top += parent.offsetTop; - } - - return [left, top]; - } else { - return null; - } -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - isBidRequestValid: function(bid) { - if (bid && bid.params && bid.params.publisherId) { - bid.params.publisherId = parseInt(bid.params.publisherId); - return true; - } - }, - buildRequests: function(validBidRequests, bidderRequest) { - const vw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); - const vh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); - const pageSizeArray = vw == 0 || vh == 0 ? null : [vw, vh]; - const payload = { - 'x-ut-hb-params': [], - 'commons': { - 'adapterVersion': '$prebid.version$', - 'uids': validBidRequests[0].userId, - 'pageSize': pageSizeArray - } - }; - const referer = bidderRequest.refererInfo.referer; - const hostname = parseUrl(referer).hostname; - let domain = extractDomainFromHost(hostname); - const pageUrl = getCanonicalUrl() || referer; - - const pubid = validBidRequests[0].params.publisherId; - let reqUrl = `${URL}?pid=${pubid}&domain=${domain}`; - - let gdprParams = getGdprQueryParams(bidderRequest.gdprConsent); - if (gdprParams) { - reqUrl += `&${gdprParams}`; - } - - if (bidderRequest.uspConsent) { - reqUrl += `&ccpa=${bidderRequest.uspConsent}`; - } - - validBidRequests.map(bidReq => { - const bid = { - bidRequestId: bidReq.bidId, - coordinates: getBannerCoords(bidReq.adUnitCode), - hbadaptor: 'prebid', - url: pageUrl, - domain: domain, - placementId: bidReq.params.placementId != undefined ? bidReq.params.placementId : null, - publisherId: bidReq.params.publisherId, - sizes: bidReq.sizes, - params: bidReq.params - }; - const videoMediaType = deepAccess(bidReq, 'mediaTypes.video'); - if (videoMediaType) { - bid.video = { - playerSize: deepAccess(bidReq, 'mediaTypes.video.playerSize') || null, - streamType: deepAccess(bidReq, 'mediaTypes.video.context') || null, - playbackMethod: deepAccess(bidReq, 'params.video.playbackMethod') || null, - maxDuration: deepAccess(bidReq, 'params.video.maxDuration') || null, - skippable: deepAccess(bidReq, 'params.video.skippable') || null - }; - bid.mediaType = 'video'; - } - payload['x-ut-hb-params'].push(bid); - }); - - return { - method: 'POST', - url: reqUrl, - withCredentials: true, - data: JSON.stringify(payload) - }; - }, - interpretResponse: function(serverResponse, request) { - const bids = []; - const body = serverResponse.body; - - if (body && Array.isArray(body) && body.length > 0) { - body.forEach((bidRes) => { - if (bidRes.ad && bidRes.cpm > 0) { - const bid = { - requestId: bidRes.bidRequestId, - cpm: bidRes.cpm, - width: bidRes.width, - height: bidRes.height, - creativeId: bidRes.adId, - currency: bidRes.currency, - netRevenue: bidRes.netRevenue, - ttl: bidRes.ttl || 360, - meta: { advertiserDomains: bidRes.adomain ? bidRes.adomain : [] } - }; - if (bidRes.mediaType && bidRes.mediaType === 'video') { - bid.vastXml = bidRes.ad; - bid.mediaType = bidRes.mediaType; - } else { - bid.ad = bidRes.ad - } - bids.push(bid); - } - }); - } - return bids; - }, - getUserSyncs: function(syncOptions, serverResponses, gdprConsent, usPrivacy) { - const syncs = []; - - let gdprParams = getGdprQueryParams(gdprConsent); - let iframePrivacyParams = ''; - let pixelPrivacyParams = ''; - - if (gdprParams) { - iframePrivacyParams += `?${gdprParams}`; - pixelPrivacyParams += `&${gdprParams}`; - } - - if (usPrivacy) { - if (iframePrivacyParams != '') { - iframePrivacyParams += '&' - } else { - iframePrivacyParams += '?' - } - iframePrivacyParams += `ccpa=${usPrivacy}`; - pixelPrivacyParams += `&ccpa=${usPrivacy}`; - } - - if (syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: FRAME_USER_SYNC + iframePrivacyParams - }); - } else if (syncOptions.pixelEnabled) { - syncs.push({ - type: 'image', - url: PIXEL_USER_SYNC_1 + pixelPrivacyParams - }, - { - type: 'image', - url: PIXEL_USER_SYNC_2 + pixelPrivacyParams - }); - } - return syncs; - } -}; -registerBidder(spec); diff --git a/modules/undertoneBidAdapter.md b/modules/undertoneBidAdapter.md deleted file mode 100644 index 8ac84b77bd8..00000000000 --- a/modules/undertoneBidAdapter.md +++ /dev/null @@ -1,29 +0,0 @@ -# Overview - -``` -Module Name: Example Bidder Adapter -Module Type: Bidder Adapter -Maintainer: RampProgrammatic@perion.com -``` -# Description - -Module that connects to Undertone's demand sources - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - sizes: [[300, 250]], - bids: [ - { - bidder: "undertone", - params: { - placementId: '10433394', - publisherId: 12345 - } - } - ] - } - ]; -``` diff --git a/modules/unicornBidAdapter.js b/modules/unicornBidAdapter.js deleted file mode 100644 index 2d4b5b53966..00000000000 --- a/modules/unicornBidAdapter.js +++ /dev/null @@ -1,160 +0,0 @@ -import * as utils from '../src/utils.js'; -import { BANNER } from '../src/mediaTypes.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const storage = getStorageManager(); -const BIDDER_CODE = 'unicorn'; -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.0'; - -/** - * Placement ID and Account ID are required. - * @param {BidRequest} bidRequest - * @returns {boolean} - */ -const isBidRequestValid = bidRequest => { - return !!bidRequest.adUnitCode && !!bidRequest.params.accountId; -}; - -/** - * @param {Array} validBidRequests - * @param {any} bidderRequest - * @returns {ServerRequest} - */ -export const buildRequests = (validBidRequests, bidderRequest) => { - return { - method: 'POST', - url: UNICORN_ENDPOINT, - data: buildOpenRtbBidRequestPayload(validBidRequests, bidderRequest) - }; -}; - -/** - * Transform BidRequest to OpenRTB-formatted BidRequest Object - * @param {Array} validBidRequests - * @param {any} bidderRequest - * @returns {string} - */ -function buildOpenRtbBidRequestPayload(validBidRequests, bidderRequest) { - utils.logInfo( - '[UNICORN] buildOpenRtbBidRequestPayload.validBidRequests:', - validBidRequests - ); - utils.logInfo( - '[UNICORN] buildOpenRtbBidRequestPayload.bidderRequest:', - bidderRequest - ); - const imp = validBidRequests.map(br => { - return { - id: br.bidId, - banner: { - format: makeFormat(br.sizes), - w: br.sizes[0][0], - h: br.sizes[0][1], - }, - tagid: utils.deepAccess(br, 'params.placementId') || br.adUnitCode, - secure: 1, - bidfloor: parseFloat(utils.deepAccess(br, 'params.bidfloorCpm') || 0) - }; - }); - const request = { - id: bidderRequest.auctionId, - at: 1, - imp, - cur: UNICORN_DEFAULT_CURRENCY, - site: { - id: utils.deepAccess(validBidRequests[0], 'params.mediaId') || '', - publisher: { - id: utils.deepAccess(validBidRequests[0], 'params.publisherId') || 0 - }, - domain: window.location.hostname, - page: window.location.href, - ref: bidderRequest.refererInfo.referer - }, - device: { - language: navigator.language, - ua: navigator.userAgent - }, - user: { - id: getUid() - }, - bcat: utils.deepAccess(validBidRequests[0], 'params.bcat') || [], - source: { - ext: { - stype: 'prebid_uncn', - bidder: BIDDER_CODE, - prebid_version: UNICORN_PB_VERSION - } - }, - ext: { - accountId: utils.deepAccess(validBidRequests[0], 'params.accountId') - } - }; - utils.logInfo('[UNICORN] OpenRTB Formatted Request:', request); - return JSON.stringify(request); -} - -const interpretResponse = (serverResponse, request) => { - utils.logInfo('[UNICORN] interpretResponse.serverResponse:', serverResponse); - utils.logInfo('[UNICORN] interpretResponse.request:', request); - const res = serverResponse.body; - var bids = [] - if (res) { - res.seatbid.forEach(sb => { - sb.bid.forEach(b => { - bids.push({ - requestId: b.impid, - cpm: b.price || 0, - width: b.w, - height: b.h, - ad: b.adm, - ttl: 1000, - creativeId: b.crid, - netRevenue: false, - currency: res.cur - }) - }) - }); - } - utils.logInfo('[UNICORN] interpretResponse bids:', bids); - return bids; -}; - -/** - * Get or Create Uid for First Party Cookie - */ -const getUid = () => { - const ck = storage.getCookie(UNICORN_PB_COOKIE_KEY); - if (ck) { - return JSON.parse(ck)['uid']; - } else { - const newCk = { - uid: utils.generateUUID() - }; - const expireIn = new Date(Date.now() + 24 * 60 * 60 * 10000).toUTCString(); - storage.setCookie(UNICORN_PB_COOKIE_KEY, JSON.stringify(newCk), expireIn); - return newCk.uid; - } -}; - -/** - * Make imp.banner.format - * @param {Array} arr - */ -const makeFormat = arr => arr.map((s) => { - return { w: s[0], h: s[1] }; -}); - -export const spec = { - code: BIDDER_CODE, - aliases: ['uncn'], - supportedMediaTypes: [BANNER], - isBidRequestValid, - buildRequests, - interpretResponse, -}; - -registerBidder(spec); diff --git a/modules/unicornBidAdapter.md b/modules/unicornBidAdapter.md deleted file mode 100644 index 5b8c8268bcf..00000000000 --- a/modules/unicornBidAdapter.md +++ /dev/null @@ -1,33 +0,0 @@ -# Overview - -**Module Name**: UNICORN Bid Adapter -**Module Type**: Bidder Adapter -**Maintainer**: service+prebid.js@bulbit.jp - -# Description - -Module that connects to UNICORN. - -# Test Parameters - -```js - const adUnits = [{ - code: 'test-adunit1', // REQUIRED: adunit code - mediaTypes: { - banner: { - sizes: [[300, 250]] // a banner size - } - }, - bids: [{ - bidder: 'unicorn', - params: { - placementId: 'rectangle-ad-1', // OPTIONAL: If placementId is empty, adunit code will be used as placementId. - bidfloorCpm: 0.2, // OPTIONAL: Floor CPM (JPY) defaults to 0 - publisherId: 99999 // OPTIONAL: Account specific publisher id - mediaId: "uc" // OPTIONAL: Publisher specific media id - accountId: 12345, // REQUIRED: Account ID for charge request - bcat: ['IAB-1', 'IAB-2'] // OPTIONAL: blocked IAB categories - } - }] - }]; -``` diff --git a/modules/unifiedIdSystem.js b/modules/unifiedIdSystem.js deleted file mode 100644 index bc033f37992..00000000000 --- a/modules/unifiedIdSystem.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * This module adds UnifiedId to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/unifiedIdSystem - * @requires module:modules/userId - */ - -import * as utils from '../src/utils.js' -import {ajax} from '../src/ajax.js'; -import {submodule} from '../src/hook.js' - -const MODULE_NAME = 'unifiedId'; - -/** @type {Submodule} */ -export const unifiedIdSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: MODULE_NAME, - /** - * required for the gdpr enforcement module - */ - gvlid: 21, - /** - * decode the stored id value for passing to bid requests - * @function - * @param {{TDID:string}} value - * @returns {{tdid:Object}} - */ - decode(value) { - return (value && typeof value['TDID'] === 'string') ? { 'tdid': value['TDID'] } : undefined; - }, - /** - * performs action to obtain id and return a value in the callback's response argument - * @function - * @param {SubmoduleConfig} [config] - * @returns {IdResponse|undefined} - */ - getId(config) { - const configParams = (config && config.params) || {}; - if (!configParams || (typeof configParams.partner !== 'string' && typeof configParams.url !== 'string')) { - utils.logError('User ID - unifiedId submodule requires either partner or url to be defined'); - return; - } - // use protocol relative urls for http or https - const url = configParams.url || `https://match.adsrvr.org/track/rid?ttd_pid=${configParams.partner}&fmt=json`; - - const resp = function (callback) { - const callbacks = { - success: response => { - let responseObj; - if (response) { - try { - responseObj = JSON.parse(response); - } catch (error) { - utils.logError(error); - } - } - callback(responseObj); - }, - error: error => { - utils.logError(`${MODULE_NAME}: ID fetch encountered an error`, error); - callback(); - } - }; - ajax(url, callbacks, undefined, {method: 'GET', withCredentials: true}); - }; - return {callback: resp}; - } -}; - -submodule('userId', unifiedIdSubmodule); diff --git a/modules/unrulyBidAdapter.js b/modules/unrulyBidAdapter.js deleted file mode 100644 index 36a156d5c66..00000000000 --- a/modules/unrulyBidAdapter.js +++ /dev/null @@ -1,138 +0,0 @@ -import * as utils from '../src/utils.js' -import { Renderer } from '../src/Renderer.js' -import { registerBidder } from '../src/adapters/bidderFactory.js' -import { VIDEO } from '../src/mediaTypes.js' - -function configureUniversalTag (exchangeRenderer) { - if (!exchangeRenderer.config) throw new Error('UnrulyBidAdapter: Missing renderer config.') - if (!exchangeRenderer.config.siteId) throw new Error('UnrulyBidAdapter: Missing renderer siteId.') - - parent.window.unruly = parent.window.unruly || {}; - parent.window.unruly['native'] = parent.window.unruly['native'] || {}; - parent.window.unruly['native'].siteId = parent.window.unruly['native'].siteId || exchangeRenderer.config.siteId; - parent.window.unruly['native'].supplyMode = 'prebid'; -} - -function configureRendererQueue () { - parent.window.unruly['native'].prebid = parent.window.unruly['native'].prebid || {}; - parent.window.unruly['native'].prebid.uq = parent.window.unruly['native'].prebid.uq || []; -} - -function notifyRenderer (bidResponseBid) { - parent.window.unruly['native'].prebid.uq.push(['render', bidResponseBid]); -} - -const serverResponseToBid = (bid, rendererInstance) => ({ - requestId: bid.bidId, - cpm: bid.cpm, - width: bid.width, - height: bid.height, - vastUrl: bid.vastUrl, - netRevenue: true, - creativeId: bid.bidId, - ttl: 360, - meta: { advertiserDomains: bid && bid.adomain ? bid.adomain : [] }, - currency: 'USD', - renderer: rendererInstance, - mediaType: VIDEO -}); - -const buildPrebidResponseAndInstallRenderer = bids => - bids - .filter(serverBid => { - const hasConfig = !!utils.deepAccess(serverBid, 'ext.renderer.config'); - const hasSiteId = !!utils.deepAccess(serverBid, 'ext.renderer.config.siteId'); - - if (!hasConfig) utils.logError(new Error('UnrulyBidAdapter: Missing renderer config.')); - if (!hasSiteId) utils.logError(new Error('UnrulyBidAdapter: Missing renderer siteId.')); - - return hasSiteId - }) - .map(serverBid => { - const exchangeRenderer = utils.deepAccess(serverBid, 'ext.renderer'); - - configureUniversalTag(exchangeRenderer); - configureRendererQueue(); - - const rendererInstance = Renderer.install(Object.assign({}, exchangeRenderer, { callback: () => {} })); - return { rendererInstance, serverBid }; - }) - .map( - ({rendererInstance, serverBid}) => { - const prebidBid = serverResponseToBid(serverBid, rendererInstance); - - const rendererConfig = Object.assign( - {}, - prebidBid, - { - renderer: rendererInstance, - adUnitCode: serverBid.ext.adUnitCode - } - ); - - rendererInstance.setRender(() => { notifyRenderer(rendererConfig) }); - - return prebidBid; - } - ); - -export const adapter = { - code: 'unruly', - supportedMediaTypes: [ VIDEO ], - isBidRequestValid: function(bid) { - if (!bid) return false; - - const context = utils.deepAccess(bid, 'mediaTypes.video.context'); - - return bid.mediaType === 'video' || context === 'outstream'; - }, - - buildRequests: function(validBidRequests, bidderRequest) { - const url = 'https://targeting.unrulymedia.com/prebid'; - const method = 'POST'; - const data = { - bidRequests: validBidRequests, - bidderRequest - }; - const options = { contentType: 'text/plain' }; - - return { - url, - method, - data, - options - }; - }, - - interpretResponse: function(serverResponse = {}) { - const serverResponseBody = serverResponse.body; - const noBidsResponse = []; - const isInvalidResponse = !serverResponseBody || !serverResponseBody.bids; - - return isInvalidResponse - ? noBidsResponse - : buildPrebidResponseAndInstallRenderer(serverResponseBody.bids); - }, - - getUserSyncs: function(syncOptions, response, gdprConsent) { - let params = ''; - if (gdprConsent && 'gdprApplies' in gdprConsent) { - if (gdprConsent.gdprApplies && typeof gdprConsent.consentString === 'string') { - params += `?gdpr=1&gdpr_consent=${gdprConsent.consentString}`; - } else { - params += `?gdpr=0`; - } - } - - const syncs = [] - if (syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: 'https://video.unrulymedia.com/iframes/third-party-iframes.html' + params - }); - } - return syncs; - } -}; - -registerBidder(adapter); diff --git a/modules/unrulyBidAdapter.md b/modules/unrulyBidAdapter.md deleted file mode 100644 index fc3c6c264be..00000000000 --- a/modules/unrulyBidAdapter.md +++ /dev/null @@ -1,31 +0,0 @@ -# Overview - -**Module Name**: Unruly Bid Adapter -**Module Type**: Bidder Adapter -**Maintainer**: prodev@unrulymedia.com - -# Description - -Module that connects to UnrulyX for bids. - -# Test Parameters - -```js - const adUnits = [{ - code: 'ad-slot', - sizes: [[728, 90], [300, 250]], - mediaTypes: { - video: { - context: 'outstream' - } - }, - bids: [{ - bidder: 'unruly', - params: { - targetingUUID: '6f15e139-5f18-49a1-b52f-87e5e69ee65e', - siteId: 1081534 - } - } - ] - }]; -``` diff --git a/modules/uolBidAdapter.md b/modules/uolBidAdapter.md deleted file mode 100644 index 1d465c9a9c5..00000000000 --- a/modules/uolBidAdapter.md +++ /dev/null @@ -1,51 +0,0 @@ -# Overview - -``` -Module Name: UOL Project Bid Adapter -Module Type: Bidder Adapter -Maintainer: l-prebid@uolinc.com -``` - -# Description - -Connect to UOL Project's exchange for bids. - -For proper setup, please contact UOL Project's team at l-prebid@uolinc.com - -# Test Parameters -``` - var adUnits = [ - { - code: '/19968336/header-bid-tag-0', - mediaTypes: { - banner: { - sizes: [[300, 250],[300, 600]] - } - }, - bids: [{ - bidder: 'uol', - params: { - placementId: 1231244, - test: true, - cpmFactor: 2 - } - } - ] - }, - { - code: '/19968336/header-bid-tag-1', - mediaTypes: { - banner: { - sizes: [[970, 250],[728, 90]] - } - }, - bids: [{ - bidder: 'uol', - params: { - placementId: 1231242, - test: false - } - }] - } - ]; -``` diff --git a/modules/userId/eids.js b/modules/userId/eids.js deleted file mode 100644 index 4012079ab6e..00000000000 --- a/modules/userId/eids.js +++ /dev/null @@ -1,297 +0,0 @@ -import * as utils from '../../src/utils.js'; - -// Each user-id sub-module is expected to mention respective config here -const USER_IDS_CONFIG = { - - // key-name : {config} - - // intentIqId - 'intentIqId': { - source: 'intentiq.com', - atype: 1 - }, - - // pubCommonId - 'pubcid': { - source: 'pubcid.org', - atype: 1 - }, - - // unifiedId - 'tdid': { - source: 'adserver.org', - atype: 1, - getUidExt: function() { - return { - rtiPartner: 'TDID' - }; - } - }, - - // id5Id - 'id5id': { - getValue: function(data) { - return data.uid - }, - source: 'id5-sync.com', - atype: 1, - getUidExt: function(data) { - if (data.ext) { - return data.ext; - } - } - }, - - // parrableId - 'parrableId': { - source: 'parrable.com', - atype: 1, - getValue: function(parrableId) { - if (parrableId.eid) { - return parrableId.eid; - } - if (parrableId.ccpaOptout) { - // If the EID was suppressed due to a non consenting ccpa optout then - // we still wish to provide this as a reason to the adapters - return ''; - } - return null; - }, - getUidExt: function(parrableId) { - const extendedData = utils.pick(parrableId, [ - 'ibaOptout', - 'ccpaOptout' - ]); - if (Object.keys(extendedData).length) { - return extendedData; - } - } - }, - - // identityLink - 'idl_env': { - source: 'liveramp.com', - atype: 3 - }, - - // liveIntentId - 'lipb': { - getValue: function(data) { - return data.lipbid; - }, - source: 'liveintent.com', - atype: 3, - getEidExt: function(data) { - if (Array.isArray(data.segments) && data.segments.length) { - return { - segments: data.segments - }; - } - } - }, - - // britepoolId - 'britepoolid': { - source: 'britepool.com', - atype: 3 - }, - - // dmdId - 'dmdId': { - source: 'hcn.health', - atype: 3 - }, - - // lotamePanoramaId - lotamePanoramaId: { - source: 'crwdcntrl.net', - atype: 1, - }, - - // criteo - 'criteoId': { - source: 'criteo.com', - atype: 1 - }, - - // merkleId - 'merkleId': { - source: 'merkleinc.com', - atype: 3, - getValue: function(data) { - return data.id; - }, - getUidExt: function(data) { - return (data && data.keyID) ? { - keyID: data.keyID - } : undefined; - } - }, - - // NetId - 'netId': { - source: 'netid.de', - atype: 1 - }, - - // sharedid - 'sharedid': { - source: 'sharedid.org', - atype: 1, - getValue: function(data) { - return data.id; - }, - getUidExt: function(data) { - return (data && data.third) ? { - third: data.third - } : undefined; - } - }, - - // zeotapIdPlus - 'IDP': { - source: 'zeotap.com', - atype: 1 - }, - - // haloId - 'haloId': { - source: 'audigent.com', - atype: 1 - }, - - // quantcastId - 'quantcastId': { - source: 'quantcast.com', - atype: 1 - }, - - // nextroll - 'nextrollId': { - source: 'nextroll.com', - atype: 1 - }, - - // IDx - 'idx': { - source: 'idx.lat', - atype: 1 - }, - - // Verizon Media ConnectID - 'connectid': { - source: 'verizonmedia.com', - atype: 3 - }, - - // Neustar Fabrick - 'fabrickId': { - source: 'neustar.biz', - atype: 1 - }, - // MediaWallah OpenLink - 'mwOpenLinkId': { - source: 'mediawallahscript.com', - atype: 1 - }, - 'tapadId': { - source: 'tapad.com', - atype: 1 - }, - // Novatiq Snowflake - 'novatiq': { - getValue: function(data) { - return data.snowflake - }, - source: 'novatiq.com', - atype: 1 - }, - 'uid2': { - source: 'uidapi.com', - atype: 3, - getValue: function(data) { - return data.id; - } - }, - 'deepintentId': { - source: 'deepintent.com', - atype: 3 - }, - // Admixer Id - 'admixerId': { - source: 'admixer.net', - atype: 3 - } -}; - -// this function will create an eid object for the given UserId sub-module -function createEidObject(userIdData, subModuleKey) { - const conf = USER_IDS_CONFIG[subModuleKey]; - if (conf && userIdData) { - let eid = {}; - eid.source = conf['source']; - const value = utils.isFn(conf['getValue']) ? conf['getValue'](userIdData) : userIdData; - if (utils.isStr(value)) { - const uid = { id: value, atype: conf['atype'] }; - // getUidExt - if (utils.isFn(conf['getUidExt'])) { - const uidExt = conf['getUidExt'](userIdData); - if (uidExt) { - uid.ext = uidExt; - } - } - eid.uids = [uid]; - // getEidExt - if (utils.isFn(conf['getEidExt'])) { - const eidExt = conf['getEidExt'](userIdData); - if (eidExt) { - eid.ext = eidExt; - } - } - return eid; - } - } - return null; -} - -// this function will generate eids array for all available IDs in bidRequest.userId -// this function will be called by userId module -// if any adapter does not want any particular userId to be passed then adapter can use Array.filter(e => e.source != 'tdid') -export function createEidsArray(bidRequestUserId) { - let eids = []; - for (const subModuleKey in bidRequestUserId) { - if (bidRequestUserId.hasOwnProperty(subModuleKey)) { - if (subModuleKey === 'pubProvidedId') { - eids = eids.concat(bidRequestUserId['pubProvidedId']); - } else { - const eid = createEidObject(bidRequestUserId[subModuleKey], subModuleKey); - if (eid) { - eids.push(eid); - } - } - } - } - return eids; -} - -/** - * @param {SubmoduleContainer[]} submodules - */ -export function buildEidPermissions(submodules) { - let eidPermissions = []; - submodules.filter(i => utils.isPlainObject(i.idObj) && Object.keys(i.idObj).length) - .forEach(i => { - Object.keys(i.idObj).forEach(key => { - if (utils.deepAccess(i, 'config.bidders') && Array.isArray(i.config.bidders) && - utils.deepAccess(USER_IDS_CONFIG, key + '.source')) { - eidPermissions.push( - { - source: USER_IDS_CONFIG[key].source, - bidders: i.config.bidders - } - ); - } - }); - }); - return eidPermissions; -} diff --git a/modules/userId/eids.md b/modules/userId/eids.md deleted file mode 100644 index 32aa6b3c0d9..00000000000 --- a/modules/userId/eids.md +++ /dev/null @@ -1,204 +0,0 @@ -## Example of eids array generated by UserId Module. - -``` -userIdAsEids = [ - { - source: 'pubcid.org', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - - { - source: 'adserver.org', - uids: [{ - id: 'some-random-id-value', - atype: 1, - ext: { - rtiPartner: 'TDID' - } - }] - }, - - { - source: 'neustar.biz', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - - { - source: 'id5-sync.com', - uids: [{ - id: 'some-random-id-value', - atype: 1, - ext: { - linkType: 2, - abTestingControlGroup: false - } - }] - }, - - { - source: 'parrable.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - - { - source: 'liveramp.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - - { - source: 'liveintent.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }], - ext: { - segments: ['s1', 's2'] - } - }, - - { - source: 'merkleinc.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - - { - source: 'britepool.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - - { - source: 'hcn.health', - uids: [{ - id: 'some-random-id-value', - atype: 3 - }] - }, - - { - source: 'criteo.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - - { - source: 'netid.de', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - - { - source: 'sharedid.org', - uids: [{ - id: 'some-random-id-value', - atype: 1, - ext: { - third: 'some-random-id-value' - } - }] - }, - - { - source: 'zeotap.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - - { - source: 'nextroll.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - - { - source: 'audigent.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - - { - source: 'quantcast.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - - { - source: 'verizonmedia.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - { - source: 'mediawallahscript.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - { - source: 'tapad.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - { - source: 'novatiq.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - { - source: 'uidapi.com', - uids: [{ - id: 'some-random-id-value', - atype: 3 - }] - }, - { - source: 'admixer.net', - uids: [{ - id: 'some-random-id-value', - atype: 3 - }] - }, - { - source: 'deepintent.com', - uids: [{ - id: 'some-random-id-value', - atype: 3 - }] - } -] -``` diff --git a/modules/userId/index.js b/modules/userId/index.js deleted file mode 100644 index 199934f4cdb..00000000000 --- a/modules/userId/index.js +++ /dev/null @@ -1,838 +0,0 @@ -/** - * This module adds User ID support to prebid.js - * @module modules/userId - */ - -/** - * @interface Submodule - */ - -/** - * @function - * @summary performs action to obtain id and return a value in the callback's response argument. - * If IdResponse#id is defined, then it will be written to the current active storage. - * If IdResponse#callback is defined, then it'll called at the end of auction. - * It's permissible to return neither, one, or both fields. - * @name Submodule#getId - * @param {SubmoduleConfig} config - * @param {ConsentData|undefined} consentData - * @param {(Object|undefined)} cacheIdObj - * @return {(IdResponse|undefined)} A response object that contains id and/or callback. - */ - -/** - * @function - * @summary Similar to Submodule#getId, this optional method returns response to for id that exists already. - * If IdResponse#id is defined, then it will be written to the current active storage even if it exists already. - * If IdResponse#callback is defined, then it'll called at the end of auction. - * It's permissible to return neither, one, or both fields. - * @name Submodule#extendId - * @param {SubmoduleConfig} config - * @param {ConsentData|undefined} consentData - * @param {Object} storedId - existing id, if any - * @return {(IdResponse|function(callback:function))} A response object that contains id and/or callback. - */ - -/** - * @function - * @summary decode a stored value for passing to bid requests - * @name Submodule#decode - * @param {Object|string} value - * @param {SubmoduleConfig|undefined} config - * @return {(Object|undefined)} - */ - -/** - * @property - * @summary used to link submodule with config - * @name Submodule#name - * @type {string} - */ - -/** - * @property - * @summary use a predefined domain override for cookies or provide your own - * @name Submodule#domainOverride - * @type {(undefined|function)} - */ - -/** - * @function - * @summary Returns the root domain - * @name Submodule#findRootDomain - * @returns {string} - */ - -/** - * @typedef {Object} SubmoduleConfig - * @property {string} name - the User ID submodule name (used to link submodule with config) - * @property {(SubmoduleStorage|undefined)} storage - browser storage config - * @property {(SubmoduleParams|undefined)} params - params config for use by the submodule.getId function - * @property {(Object|undefined)} value - if not empty, this value is added to bid requests for access in adapters - */ - -/** - * @typedef {Object} SubmoduleStorage - * @property {string} type - browser storage type (html5 or cookie) - * @property {string} name - key name to use when saving/reading to local storage or cookies - * @property {number} expires - time to live for browser storage in days - * @property {(number|undefined)} refreshInSeconds - if not empty, this value defines the maximum time span in seconds before refreshing user ID stored in browser - */ - -/** - * @typedef {Object} LiveIntentCollectConfig - * @property {(string|undefined)} fpiStorageStrategy - defines whether the first party identifiers that LiveConnect creates and updates are stored in a cookie jar, local storage, or not created at all - * @property {(number|undefined)} fpiExpirationDays - the expiration time of an identifier created and updated by LiveConnect - * @property {(string|undefined)} collectorUrl - defines where the LiveIntentId signal pixels are pointing to - * @property {(string|undefined)} appId - the unique identifier of the application in question - */ - -/** - * @typedef {Object} SubmoduleParams - * @property {(string|undefined)} partner - partner url param value - * @property {(string|undefined)} url - webservice request url used to load Id data - * @property {(string|undefined)} pixelUrl - publisher pixel to extend/modify cookies - * @property {(boolean|undefined)} create - create id if missing. default is true. - * @property {(boolean|undefined)} extend - extend expiration time on each access. default is false. - * @property {(string|undefined)} pid - placement id url param value - * @property {(string|undefined)} publisherId - the unique identifier of the publisher in question - * @property {(string|undefined)} ajaxTimeout - the number of milliseconds a resolution request can take before automatically being terminated - * @property {(array|undefined)} identifiersToResolve - the identifiers from either ls|cookie to be attached to the getId query - * @property {(LiveIntentCollectConfig|undefined)} liCollectConfig - the config for LiveIntent's collect requests - * @property {(string|undefined)} pd - publisher provided data for reconciling ID5 IDs - * @property {(string|undefined)} emailHash - if provided, the hashed email address of a user - * @property {(string|undefined)} notUse3P - use to retrieve envelope from 3p endpoint - */ - -/** - * @typedef {Object} SubmoduleContainer - * @property {Submodule} submodule - * @property {SubmoduleConfig} config - * @property {(Object|undefined)} idObj - cache decoded id value (this is copied to every adUnit bid) - * @property {(function|undefined)} callback - holds reference to submodule.getId() result if it returned a function. Will be set to undefined after callback executes - */ - -/** - * @typedef {Object} ConsentData - * @property {(string|undefined)} consentString - * @property {(Object|undefined)} vendorData - * @property {(boolean|undefined)} gdprApplies - */ - -/** - * @typedef {Object} IdResponse - * @property {(Object|undefined)} id - id data - * @property {(function|undefined)} callback - function that will return an id - */ - -/** - * @typedef {Object} RefreshUserIdsOptions - * @property {(string[]|undefined)} submoduleNames - submodules to refresh - */ - -import find from 'core-js-pure/features/array/find.js'; -import { config } from '../../src/config.js'; -import events from '../../src/events.js'; -import * as utils from '../../src/utils.js'; -import { getGlobal } from '../../src/prebidGlobal.js'; -import { gdprDataHandler } from '../../src/adapterManager.js'; -import CONSTANTS from '../../src/constants.json'; -import { module, hook } from '../../src/hook.js'; -import { createEidsArray, buildEidPermissions } from './eids.js'; -import { getCoreStorageManager } from '../../src/storageManager.js'; -import {getPrebidInternal} from '../../src/utils.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -const MODULE_NAME = 'User ID'; -const COOKIE = 'cookie'; -const LOCAL_STORAGE = 'html5'; -const DEFAULT_SYNC_DELAY = 500; -const NO_AUCTION_DELAY = 0; -const CONSENT_DATA_COOKIE_STORAGE_CONFIG = { - name: '_pbjs_userid_consent_data', - expires: 30 // 30 days expiration, which should match how often consent is refreshed by CMPs -}; -export const PBJS_USER_ID_OPTOUT_NAME = '_pbjs_id_optout'; -export const coreStorage = getCoreStorageManager('userid'); - -/** @type {string[]} */ -let validStorageTypes = []; - -/** @type {boolean} */ -let addedUserIdHook = false; - -/** @type {SubmoduleContainer[]} */ -let submodules = []; - -/** @type {SubmoduleContainer[]} */ -let initializedSubmodules; - -/** @type {SubmoduleConfig[]} */ -let configRegistry = []; - -/** @type {Submodule[]} */ -let submoduleRegistry = []; - -/** @type {(number|undefined)} */ -let timeoutID; - -/** @type {(number|undefined)} */ -export let syncDelay; - -/** @type {(number|undefined)} */ -export let auctionDelay; - -/** @param {Submodule[]} submodules */ -export function setSubmoduleRegistry(submodules) { - submoduleRegistry = submodules; -} - -/** - * @param {SubmoduleContainer} submodule - * @param {(Object|string)} value - */ -export function setStoredValue(submodule, value) { - /** - * @type {SubmoduleStorage} - */ - const storage = submodule.config.storage; - const domainOverride = (typeof submodule.submodule.domainOverride === 'function') ? submodule.submodule.domainOverride() : null; - - try { - const valueStr = utils.isPlainObject(value) ? JSON.stringify(value) : value; - const expiresStr = (new Date(Date.now() + (storage.expires * (60 * 60 * 24 * 1000)))).toUTCString(); - if (storage.type === COOKIE) { - coreStorage.setCookie(storage.name, valueStr, expiresStr, 'Lax', domainOverride); - if (typeof storage.refreshInSeconds === 'number') { - coreStorage.setCookie(`${storage.name}_last`, new Date().toUTCString(), expiresStr, 'Lax', domainOverride); - } - } else if (storage.type === LOCAL_STORAGE) { - coreStorage.setDataInLocalStorage(`${storage.name}_exp`, expiresStr); - coreStorage.setDataInLocalStorage(storage.name, encodeURIComponent(valueStr)); - if (typeof storage.refreshInSeconds === 'number') { - coreStorage.setDataInLocalStorage(`${storage.name}_last`, new Date().toUTCString()); - } - } - } catch (error) { - utils.logError(error); - } -} - -function setPrebidServerEidPermissions(initializedSubmodules) { - let setEidPermissions = getPrebidInternal().setEidPermissions; - if (typeof setEidPermissions === 'function' && utils.isArray(initializedSubmodules)) { - setEidPermissions(buildEidPermissions(initializedSubmodules)); - } -} - -/** -/** - * @param {SubmoduleStorage} storage - * @param {String|undefined} key optional key of the value - * @returns {string} - */ -function getStoredValue(storage, key = undefined) { - const storedKey = key ? `${storage.name}_${key}` : storage.name; - let storedValue; - try { - if (storage.type === COOKIE) { - storedValue = coreStorage.getCookie(storedKey); - } else if (storage.type === LOCAL_STORAGE) { - const storedValueExp = coreStorage.getDataFromLocalStorage(`${storage.name}_exp`); - // empty string means no expiration set - if (storedValueExp === '') { - storedValue = coreStorage.getDataFromLocalStorage(storedKey); - } else if (storedValueExp) { - if ((new Date(storedValueExp)).getTime() - Date.now() > 0) { - storedValue = decodeURIComponent(coreStorage.getDataFromLocalStorage(storedKey)); - } - } - } - // support storing a string or a stringified object - if (typeof storedValue === 'string' && storedValue.trim().charAt(0) === '{') { - storedValue = JSON.parse(storedValue); - } - } catch (e) { - utils.logError(e); - } - return storedValue; -} - -/** - * makes an object that can be stored with only the keys we need to check. - * excluding the vendorConsents object since the consentString is enough to know - * if consent has changed without needing to have all the details in an object - * @param consentData - * @returns {{apiVersion: number, gdprApplies: boolean, consentString: string}} - */ -function makeStoredConsentDataHash(consentData) { - const storedConsentData = { - consentString: '', - gdprApplies: false, - apiVersion: 0 - }; - - if (consentData) { - storedConsentData.consentString = consentData.consentString; - storedConsentData.gdprApplies = consentData.gdprApplies; - storedConsentData.apiVersion = consentData.apiVersion; - } - return utils.cyrb53Hash(JSON.stringify(storedConsentData)); -} - -/** - * puts the current consent data into cookie storage - * @param consentData - */ -export function setStoredConsentData(consentData) { - try { - const expiresStr = (new Date(Date.now() + (CONSENT_DATA_COOKIE_STORAGE_CONFIG.expires * (60 * 60 * 24 * 1000)))).toUTCString(); - coreStorage.setCookie(CONSENT_DATA_COOKIE_STORAGE_CONFIG.name, makeStoredConsentDataHash(consentData), expiresStr, 'Lax'); - } catch (error) { - utils.logError(error); - } -} - -/** - * get the stored consent data from local storage, if any - * @returns {string} - */ -function getStoredConsentData() { - try { - return coreStorage.getCookie(CONSENT_DATA_COOKIE_STORAGE_CONFIG.name); - } catch (e) { - utils.logError(e); - } -} - -/** - * test if the consent object stored locally matches the current consent data. - * if there is nothing in storage, return true and we'll do an actual comparison next time. - * this way, we don't force a refresh for every user when this code rolls out - * @param storedConsentData - * @param consentData - * @returns {boolean} - */ -function storedConsentDataMatchesConsentData(storedConsentData, consentData) { - return ( - typeof storedConsentData === 'undefined' || - storedConsentData === null || - storedConsentData === makeStoredConsentDataHash(consentData) - ); -} - -/** - * test if consent module is present, applies, and is valid for local storage or cookies (purpose 1) - * @param {ConsentData} consentData - * @returns {boolean} - */ -function hasGDPRConsent(consentData) { - if (consentData && typeof consentData.gdprApplies === 'boolean' && consentData.gdprApplies) { - if (!consentData.consentString) { - return false; - } - if (consentData.apiVersion === 1 && utils.deepAccess(consentData, 'vendorData.purposeConsents.1') === false) { - return false; - } - if (consentData.apiVersion === 2 && utils.deepAccess(consentData, 'vendorData.purpose.consents.1') === false) { - return false; - } - } - return true; -} - -/** - * Find the root domain - * @param {string|undefined} fullDomain - * @return {string} - */ -export function findRootDomain(fullDomain = window.location.hostname) { - if (!coreStorage.cookiesAreEnabled()) { - return fullDomain; - } - - const domainParts = fullDomain.split('.'); - if (domainParts.length == 2) { - return fullDomain; - } - let rootDomain; - let continueSearching; - let startIndex = -2; - const TEST_COOKIE_NAME = `_rdc${Date.now()}`; - const TEST_COOKIE_VALUE = 'writeable'; - do { - rootDomain = domainParts.slice(startIndex).join('.'); - let expirationDate = new Date(utils.timestamp() + 10 * 1000).toUTCString(); - - // Write a test cookie - coreStorage.setCookie( - TEST_COOKIE_NAME, - TEST_COOKIE_VALUE, - expirationDate, - 'Lax', - rootDomain, - undefined - ); - - // See if the write was successful - const value = coreStorage.getCookie(TEST_COOKIE_NAME, undefined); - if (value === TEST_COOKIE_VALUE) { - continueSearching = false; - // Delete our test cookie - coreStorage.setCookie( - TEST_COOKIE_NAME, - '', - 'Thu, 01 Jan 1970 00:00:01 GMT', - undefined, - rootDomain, - undefined - ); - } else { - startIndex += -1; - continueSearching = Math.abs(startIndex) <= domainParts.length; - } - } while (continueSearching); - return rootDomain; -} - -/** - * @param {SubmoduleContainer[]} submodules - * @param {function} cb - callback for after processing is done. - */ -function processSubmoduleCallbacks(submodules, cb) { - let done = () => {}; - if (cb) { - done = utils.delayExecution(() => { - clearTimeout(timeoutID); - cb(); - }, submodules.length); - } - submodules.forEach(function (submodule) { - submodule.callback(function callbackCompleted(idObj) { - // if valid, id data should be saved to cookie/html storage - if (idObj) { - if (submodule.config.storage) { - setStoredValue(submodule, idObj); - } - // cache decoded value (this is copied to every adUnit bid) - submodule.idObj = submodule.submodule.decode(idObj, submodule.config); - } else { - utils.logInfo(`${MODULE_NAME}: ${submodule.submodule.name} - request id responded with an empty value`); - } - done(); - }); - - // clear callback, this prop is used to test if all submodule callbacks are complete below - submodule.callback = undefined; - }); -} - -/** - * This function will create a combined object for all subModule Ids - * @param {SubmoduleContainer[]} submodules - */ -function getCombinedSubmoduleIds(submodules) { - if (!Array.isArray(submodules) || !submodules.length) { - return {}; - } - const combinedSubmoduleIds = submodules.filter(i => utils.isPlainObject(i.idObj) && Object.keys(i.idObj).length).reduce((carry, i) => { - Object.keys(i.idObj).forEach(key => { - carry[key] = i.idObj[key]; - }); - return carry; - }, {}); - - return combinedSubmoduleIds; -} - -/** - * This function will create a combined object for bidder with allowed subModule Ids - * @param {SubmoduleContainer[]} submodules - * @param {string} bidder - */ -function getCombinedSubmoduleIdsForBidder(submodules, bidder) { - if (!Array.isArray(submodules) || !submodules.length || !bidder) { - return {}; - } - return submodules - .filter(i => !i.config.bidders || !utils.isArray(i.config.bidders) || includes(i.config.bidders, bidder)) - .filter(i => utils.isPlainObject(i.idObj) && Object.keys(i.idObj).length) - .reduce((carry, i) => { - Object.keys(i.idObj).forEach(key => { - carry[key] = i.idObj[key]; - }); - return carry; - }, {}); -} - -/** - * @param {AdUnit[]} adUnits - * @param {SubmoduleContainer[]} submodules - */ -function addIdDataToAdUnitBids(adUnits, submodules) { - if ([adUnits].some(i => !Array.isArray(i) || !i.length)) { - return; - } - adUnits.forEach(adUnit => { - if (adUnit.bids && utils.isArray(adUnit.bids)) { - adUnit.bids.forEach(bid => { - const combinedSubmoduleIds = getCombinedSubmoduleIdsForBidder(submodules, bid.bidder); - if (Object.keys(combinedSubmoduleIds).length) { - // create a User ID object on the bid, - bid.userId = combinedSubmoduleIds; - bid.userIdAsEids = createEidsArray(combinedSubmoduleIds); - } - }); - } - }); -} - -/** - * This is a common function that will initialize subModules if not already done and it will also execute subModule callbacks - */ -function initializeSubmodulesAndExecuteCallbacks(continueAuction) { - let delayed = false; - - // initialize submodules only when undefined - if (typeof initializedSubmodules === 'undefined') { - initializedSubmodules = initSubmodules(submodules, gdprDataHandler.getConsentData()); - if (initializedSubmodules.length) { - setPrebidServerEidPermissions(initializedSubmodules); - // list of submodules that have callbacks that need to be executed - const submodulesWithCallbacks = initializedSubmodules.filter(item => utils.isFn(item.callback)); - - if (submodulesWithCallbacks.length) { - if (continueAuction && auctionDelay > 0) { - // delay auction until ids are available - delayed = true; - let continued = false; - const continueCallback = function () { - if (!continued) { - continued = true; - continueAuction(); - } - } - utils.logInfo(`${MODULE_NAME} - auction delayed by ${auctionDelay} at most to fetch ids`); - - timeoutID = setTimeout(continueCallback, auctionDelay); - processSubmoduleCallbacks(submodulesWithCallbacks, continueCallback); - } else { - // wait for auction complete before processing submodule callbacks - events.on(CONSTANTS.EVENTS.AUCTION_END, function auctionEndHandler() { - events.off(CONSTANTS.EVENTS.AUCTION_END, auctionEndHandler); - - // when syncDelay is zero, process callbacks now, otherwise delay process with a setTimeout - if (syncDelay > 0) { - setTimeout(function () { - processSubmoduleCallbacks(submodulesWithCallbacks); - }, syncDelay); - } else { - processSubmoduleCallbacks(submodulesWithCallbacks); - } - }); - } - } - } - } - - if (continueAuction && !delayed) { - continueAuction(); - } -} - -/** - * Hook is executed before adapters, but after consentManagement. Consent data is requied because - * this module requires GDPR consent with Purpose #1 to save data locally. - * The two main actions handled by the hook are: - * 1. check gdpr consentData and handle submodule initialization. - * 2. append user id data (loaded from cookied/html or from the getId method) to bids to be accessed in adapters. - * @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.js - */ -export function requestBidsHook(fn, reqBidsConfigObj) { - // initialize submodules only when undefined - initializeSubmodulesAndExecuteCallbacks(function () { - // pass available user id data to bid adapters - addIdDataToAdUnitBids(reqBidsConfigObj.adUnits || getGlobal().adUnits, initializedSubmodules); - // calling fn allows prebid to continue processing - fn.call(this, reqBidsConfigObj); - }); -} - -/** - * This function will be exposed in global-name-space so that userIds stored by Prebid UserId module can be used by external codes as well. - * Simple use case will be passing these UserIds to A9 wrapper solution - */ -function getUserIds() { - // initialize submodules only when undefined - initializeSubmodulesAndExecuteCallbacks(); - return getCombinedSubmoduleIds(initializedSubmodules); -} - -/** - * This function will be exposed in global-name-space so that userIds stored by Prebid UserId module can be used by external codes as well. - * Simple use case will be passing these UserIds to A9 wrapper solution - */ -function getUserIdsAsEids() { - // initialize submodules only when undefined - initializeSubmodulesAndExecuteCallbacks(); - return createEidsArray(getCombinedSubmoduleIds(initializedSubmodules)); -} - -/** -* This function will be exposed in the global-name-space so that userIds can be refreshed after initialization. -* @param {RefreshUserIdsOptions} options -*/ -function refreshUserIds(options, callback) { - let submoduleNames = options ? options.submoduleNames : null; - if (!submoduleNames) { - submoduleNames = []; - } - - initializeSubmodulesAndExecuteCallbacks(function() { - let consentData = gdprDataHandler.getConsentData() - - // gdpr consent with purpose one is required, otherwise exit immediately - let {userIdModules, hasValidated} = validateGdprEnforcement(submodules, consentData); - if (!hasValidated && !hasGDPRConsent(consentData)) { - utils.logWarn(`${MODULE_NAME} - gdpr permission not valid for local storage or cookies, exit module`); - return; - } - - // we always want the latest consentData stored, even if we don't execute any submodules - const storedConsentData = getStoredConsentData(); - setStoredConsentData(consentData); - - let callbackSubmodules = []; - for (let submodule of userIdModules) { - if (submoduleNames.length > 0 && - submoduleNames.indexOf(submodule.submodule.name) === -1) { - continue; - } - - utils.logInfo(`${MODULE_NAME} - refreshing ${submodule.submodule.name}`); - populateSubmoduleId(submodule, consentData, storedConsentData, true); - - if (utils.isFn(submodule.callback)) { - callbackSubmodules.push(submodule); - } - } - - if (callbackSubmodules.length > 0) { - processSubmoduleCallbacks(callbackSubmodules); - } - - if (callback) { - callback(); - } - }); -} - -/** - * This hook returns updated list of submodules which are allowed to do get user id based on TCF 2 enforcement rules configured - */ -export const validateGdprEnforcement = hook('sync', function (submodules, consentData) { - return { userIdModules: submodules, hasValidated: consentData && consentData.hasValidated }; -}, 'validateGdprEnforcement'); - -function populateSubmoduleId(submodule, consentData, storedConsentData, forceRefresh) { - // There are two submodule configuration types to handle: storage or value - // 1. storage: retrieve user id data from cookie/html storage or with the submodule's getId method - // 2. value: pass directly to bids - if (submodule.config.storage) { - let storedId = getStoredValue(submodule.config.storage); - let response; - - let refreshNeeded = false; - if (typeof submodule.config.storage.refreshInSeconds === 'number') { - const storedDate = new Date(getStoredValue(submodule.config.storage, 'last')); - refreshNeeded = storedDate && (Date.now() - storedDate.getTime() > submodule.config.storage.refreshInSeconds * 1000); - } - - if (!storedId || refreshNeeded || forceRefresh || !storedConsentDataMatchesConsentData(storedConsentData, consentData)) { - // No id previously saved, or a refresh is needed, or consent has changed. Request a new id from the submodule. - response = submodule.submodule.getId(submodule.config, consentData, storedId); - } else if (typeof submodule.submodule.extendId === 'function') { - // If the id exists already, give submodule a chance to decide additional actions that need to be taken - response = submodule.submodule.extendId(submodule.config, consentData, storedId); - } - - if (utils.isPlainObject(response)) { - if (response.id) { - // A getId/extendId result assumed to be valid user id data, which should be saved to users local storage or cookies - setStoredValue(submodule, response.id); - storedId = response.id; - } - - if (typeof response.callback === 'function') { - // Save async callback to be invoked after auction - submodule.callback = response.callback; - } - } - - if (storedId) { - // cache decoded value (this is copied to every adUnit bid) - submodule.idObj = submodule.submodule.decode(storedId, submodule.config); - } - } else if (submodule.config.value) { - // cache decoded value (this is copied to every adUnit bid) - submodule.idObj = submodule.config.value; - } else { - const response = submodule.submodule.getId(submodule.config, consentData, undefined); - if (utils.isPlainObject(response)) { - if (typeof response.callback === 'function') { submodule.callback = response.callback; } - if (response.id) { submodule.idObj = submodule.submodule.decode(response.id, submodule.config); } - } - } -} - -/** - * @param {SubmoduleContainer[]} submodules - * @param {ConsentData} consentData - * @returns {SubmoduleContainer[]} initialized submodules - */ -function initSubmodules(submodules, consentData) { - // gdpr consent with purpose one is required, otherwise exit immediately - let { userIdModules, hasValidated } = validateGdprEnforcement(submodules, consentData); - if (!hasValidated && !hasGDPRConsent(consentData)) { - utils.logWarn(`${MODULE_NAME} - gdpr permission not valid for local storage or cookies, exit module`); - return []; - } - - // we always want the latest consentData stored, even if we don't execute any submodules - const storedConsentData = getStoredConsentData(); - setStoredConsentData(consentData); - - return userIdModules.reduce((carry, submodule) => { - populateSubmoduleId(submodule, consentData, storedConsentData, false); - carry.push(submodule); - return carry; - }, []); -} - -/** - * list of submodule configurations with valid 'storage' or 'value' obj definitions - * * storage config: contains values for storing/retrieving User ID data in browser storage - * * value config: object properties that are copied to bids (without saving to storage) - * @param {SubmoduleConfig[]} configRegistry - * @param {Submodule[]} submoduleRegistry - * @param {string[]} activeStorageTypes - * @returns {SubmoduleConfig[]} - */ -function getValidSubmoduleConfigs(configRegistry, submoduleRegistry, activeStorageTypes) { - if (!Array.isArray(configRegistry)) { - return []; - } - return configRegistry.reduce((carry, config) => { - // every submodule config obj must contain a valid 'name' - if (!config || utils.isEmptyStr(config.name)) { - return carry; - } - // Validate storage config contains 'type' and 'name' properties with non-empty string values - // 'type' must be a value currently enabled in the browser - if (config.storage && - !utils.isEmptyStr(config.storage.type) && - !utils.isEmptyStr(config.storage.name) && - activeStorageTypes.indexOf(config.storage.type) !== -1) { - carry.push(config); - } else if (utils.isPlainObject(config.value)) { - carry.push(config); - } else if (!config.storage && !config.value) { - carry.push(config); - } - return carry; - }, []); -} - -/** - * update submodules by validating against existing configs and storage types - */ -function updateSubmodules() { - const configs = getValidSubmoduleConfigs(configRegistry, submoduleRegistry, validStorageTypes); - if (!configs.length) { - return; - } - // do this to avoid reprocessing submodules - const addedSubmodules = submoduleRegistry.filter(i => !find(submodules, j => j.name === i.name)); - - // find submodule and the matching configuration, if found create and append a SubmoduleContainer - submodules = addedSubmodules.map(i => { - const submoduleConfig = find(configs, j => j.name && j.name.toLowerCase() === i.name.toLowerCase()); - if (submoduleConfig && i.name !== submoduleConfig.name) submoduleConfig.name = i.name; - i.findRootDomain = findRootDomain; - return submoduleConfig ? { - submodule: i, - config: submoduleConfig, - callback: undefined, - idObj: undefined - } : null; - }).filter(submodule => submodule !== null); - - if (!addedUserIdHook && submodules.length) { - // priority value 40 will load after consentManagement with a priority of 50 - getGlobal().requestBids.before(requestBidsHook, 40); - utils.logInfo(`${MODULE_NAME} - usersync config updated for ${submodules.length} submodules: `, submodules.map(a => a.submodule.name)); - addedUserIdHook = true; - } -} - -/** - * enable submodule in User ID - * @param {Submodule} submodule - */ -export function attachIdSystem(submodule) { - if (!find(submoduleRegistry, i => i.name === submodule.name)) { - submoduleRegistry.push(submodule); - updateSubmodules(); - } -} - -/** - * test browser support for storage config types (local storage or cookie), initializes submodules but consentManagement is required, - * so a callback is added to fire after the consentManagement module. - * @param {{getConfig:function}} config - */ -export function init(config) { - submodules = []; - configRegistry = []; - addedUserIdHook = false; - initializedSubmodules = undefined; - - // list of browser enabled storage types - validStorageTypes = [ - coreStorage.localStorageIsEnabled() ? LOCAL_STORAGE : null, - coreStorage.cookiesAreEnabled() ? COOKIE : null - ].filter(i => i !== null); - - // exit immediately if opt out cookie or local storage keys exists. - if (validStorageTypes.indexOf(COOKIE) !== -1 && coreStorage.getCookie(PBJS_USER_ID_OPTOUT_NAME)) { - utils.logInfo(`${MODULE_NAME} - opt-out cookie found, exit module`); - return; - } - if (validStorageTypes.indexOf(LOCAL_STORAGE) !== -1 && coreStorage.getDataFromLocalStorage(PBJS_USER_ID_OPTOUT_NAME)) { - utils.logInfo(`${MODULE_NAME} - opt-out localStorage found, exit module`); - return; - } - - // listen for config userSyncs to be set - config.getConfig(conf => { - // Note: support for 'usersync' was dropped as part of Prebid.js 4.0 - const userSync = conf.userSync; - if (userSync && userSync.userIds) { - configRegistry = userSync.userIds; - syncDelay = utils.isNumber(userSync.syncDelay) ? userSync.syncDelay : DEFAULT_SYNC_DELAY; - auctionDelay = utils.isNumber(userSync.auctionDelay) ? userSync.auctionDelay : NO_AUCTION_DELAY; - updateSubmodules(); - } - }); - - // exposing getUserIds function in global-name-space so that userIds stored in Prebid can be used by external codes. - (getGlobal()).getUserIds = getUserIds; - (getGlobal()).getUserIdsAsEids = getUserIdsAsEids; - (getGlobal()).refreshUserIds = refreshUserIds; -} - -// init config update listener to start the application -init(config); - -module('userId', attachIdSystem); diff --git a/modules/userId/userId.md b/modules/userId/userId.md deleted file mode 100644 index 5d78a447572..00000000000 --- a/modules/userId/userId.md +++ /dev/null @@ -1,294 +0,0 @@ -## User ID Example Configuration - -Example showing `cookie` storage for user id data for each of the submodules -``` -pbjs.setConfig({ - userSync: { - userIds: [{ - name: "pubCommonId", - storage: { - type: "cookie", - name: "_pubcid", - expires: 60 - } - }, { - name: 'dmdId', - storage: { - name: 'dmd-dgid', - type: 'cookie', - expires: 30 - }, - params: { - api_key: '3fdbe297-3690-4f5c-9e11-ee9186a6d77c', // provided by DMD - } - }, { - name: "unifiedId", - params: { - partner: "prebid", - url: "//match.adsrvr.org/track/rid?ttd_pid=prebid&fmt=json" - }, - storage: { - type: "cookie", - name: "unifiedid", - expires: 60 - } - }, { - name: "id5Id", - params: { - partner: 173, // Set your real ID5 partner ID here for production, please ask for one at https://id5.io/universal-id - pd: "some-pd-string" // See https://wiki.id5.io/x/BIAZ for details - }, - storage: { - type: "html5", // ID5 requires html5 - name: "id5id", - expires: 90, // Expiration in days - refreshInSeconds: 8*3600 // User Id cache lifetime in seconds, defaulting to 'expires' - }, - }, { - name: 'parrableId', - params: { - // Replace partner with comma-separated (if more than one) Parrable Partner Client ID(s) for Parrable-aware bid adapters in use - partner: "30182847-e426-4ff9-b2b5-9ca1324ea09b" - } - }, { - name: 'identityLink', - params: { - pid: '999', // Set your real identityLink placement ID here - // notUse3P: true // true/false - If you do not want to use 3P endpoint to retrieve envelope. If you do not set this property to true, 3p endpoint will be fired. By default this property is undefined and 3p request will be fired. - }, - storage: { - type: 'cookie', - name: 'idl_env', - expires: 30 - } - }, { - name: 'liveIntentId', - params: { - publisherId: '7798696' // Set an identifier of a publisher know to your systems - }, - storage: { - type: 'cookie', - name: '_li_pbid', - expires: 60 - } - }, { - name: 'sharedId', - params: { - syncTime: 60 // in seconds, default is 24 hours - }, - storage: { - type: 'cookie', - name: 'sharedid', - expires: 28 - } - }, { - name: 'criteo', - storage: { // It is best not to specify this parameter since the module needs to be called as many times as possible - type: 'cookie', - name: '_criteoId', - expires: 1 - } - }, { - name: 'mwOpenLinkId', - params: { - accountId: 0000, - partnerId: 0000, - uid: '12345xyz' - } - },{ - name: "merkleId", - params: { - vendor:'sdfg', - sv_cid:'dfg', - sv_pubid:'xcv', - sv_domain:'zxv' - }, - storage: { - type: "cookie", - name: "merkleId", - expires: 30 - } - },{ - name: 'uid2' - } - }, { - name: 'admixerId', - params: { - pid: "4D393FAC-B6BB-4E19-8396-0A4813607316", // example id - e: "3d400b57e069c993babea0bd9efa79e5dc698e16c042686569faae20391fd7ea", // example hashed email (sha256) - p: "05de6c07eb3ea4bce45adca4e0182e771d80fbb99e12401416ca84ddf94c3eb9" //example hashed phone (sha256) - }, - storage: { - type: 'cookie', - name: '__adm__admixer', - expires: 30 - } - },{ - name: 'flocId', - params: { - token: "Registered token or default sharedid.org token" // Default sharedid.org token: "A3dHTSoNUMjjERBLlrvJSelNnwWUCwVQhZ5tNQ+sll7y+LkPPVZXtB77u2y7CweRIxiYaGwGXNlW1/dFp8VMEgIAAAB+eyJvcmlnaW4iOiJodHRwczovL3NoYXJlZGlkLm9yZzo0NDMiLCJmZWF0dXJlIjoiSW50ZXJlc3RDb2hvcnRBUEkiLCJleHBpcnkiOjE2MjYyMjA3OTksImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9" - } - }], - syncDelay: 5000, - auctionDelay: 1000 - } -}); -``` - -Example showing `localStorage` for user id data for some submodules -``` -pbjs.setConfig({ - userSync: { - userIds: [{ - name: "unifiedId", - params: { - partner: "prebid", - url: "http://match.adsrvr.org/track/rid?ttd_pid=prebid&fmt=json" - }, - storage: { - type: "html5", - name: "unifiedid", - expires: 60 - } - }, { - name: "pubCommonId", - storage: { - type: "html5", - name: "pubcid", - expires: 60 - } - }, { - name: 'identityLink', - params: { - pid: '999', // Set your real identityLink placement ID here - // notUse3P: true // true/false - If you do not want to use 3P endpoint to retrieve envelope. If you do not set this property to true, 3p endpoint will be fired. By default this property is undefined and 3p request will be fired. - }, - storage: { - type: 'html5', - name: 'idl_env', - expires: 30 - } - }, { - name: 'liveIntentId', - params: { - publisherId: '7798696' // Set an identifier of a publisher know to your systems - }, - storage: { - type: 'html5', - name: '_li_pbid', - expires: 60 - } - }, { - name: 'sharedId', - params: { - syncTime: 60 // in seconds, default is 24 hours - }, - storage: { - type: 'html5', - name: 'sharedid', - expires: 28 - } - }, { - name: 'id5Id', - params: { - partner: 173, // Set your real ID5 partner ID here for production, please ask for one at https://id5.io/universal-id - pd: 'some-pd-string' // See https://wiki.id5.io/x/BIAZ for details - }, - storage: { - type: 'html5', - name: 'id5id', - expires: 90, // Expiration in days - refreshInSeconds: 8*3600 // User Id cache lifetime in seconds, defaulting to 'expires' - }, - }, { - name: 'nextrollId', - params: { - partnerId: "1009", // Set your real NextRoll partner ID here for production - } - }, { - name: 'criteo', - storage: { // It is best not to specify this parameter since the module needs to be called as many times as possible - type: 'html5', - name: '_criteoId', - expires: 1 - } - },{ - name: "merkleId", - params: { - vendor:'sdfg', - sv_cid:'dfg', - sv_pubid:'xcv', - sv_domain:'zxv' - }, - storage: { - type: "html5", - name: "merkleId", - expires: 30 - } - }, { - name: 'admixerId', - params: { - pid: "4D393FAC-B6BB-4E19-8396-0A4813607316", // example id - e: "3d400b57e069c993babea0bd9efa79e5dc698e16c042686569faae20391fd7ea", // example hashed email (sha256) - p: "05de6c07eb3ea4bce45adca4e0182e771d80fbb99e12401416ca84ddf94c3eb9" //example hashed phone (sha256) - }, - storage: { - type: 'html5', - name: 'admixerId', - expires: 30 - } - },{ - name: 'flocId', - params: { - token: "Registered token or default sharedid.org token" // Default sharedid.org token: "A3dHTSoNUMjjERBLlrvJSelNnwWUCwVQhZ5tNQ+sll7y+LkPPVZXtB77u2y7CweRIxiYaGwGXNlW1/dFp8VMEgIAAAB+eyJvcmlnaW4iOiJodHRwczovL3NoYXJlZGlkLm9yZzo0NDMiLCJmZWF0dXJlIjoiSW50ZXJlc3RDb2hvcnRBUEkiLCJleHBpcnkiOjE2MjYyMjA3OTksImlzU3ViZG9tYWluIjp0cnVlLCJpc1RoaXJkUGFydHkiOnRydWV9" - } - },{ - name: "deepintentId", - storage: { - type: "html5", - name: "_dpes_id", - expires: 90 - } - },{ - name: "deepintentId", - storage: { - type: "cookie", - name: "_dpes_id", - expires: 90 - } - }], - syncDelay: 5000 - } -}); -``` - -Example showing how to configure a `value` object to pass directly to bid adapters -``` -pbjs.setConfig({ - userSync: { - userIds: [{ - name: "pubCommonId", - value: { - "providedPubCommonId": "1234567890" - } - }, - { - name: "id5Id", - value: { "id5id": "ID5-abcdef" } - }, - { - name: "netId", - value: { "netId": "fH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg" } - }, - { - name: "criteo", - value: { "criteoId": "wK-fkF8zaEIlMkZMbHl3eFo4NEtoNmZaeXJtYkFjZlVuWjBhcjJMaTRYd3pZNSUyQnlKRHNGRXlpdzdjd3pjVzhjcSUyQmY4eTFzN3VSZjV1ZyUyRlA0U2ZiR0UwN2I4bDZRJTNEJTNE" } - }, - { - name: "novatiq", - value: { "snowflake": "81b001ec-8914-488c-a96e-8c220d4ee08895ef" } - }], - syncDelay: 5000 - } -}); -``` diff --git a/modules/userIdTargeting.js b/modules/userIdTargeting.js deleted file mode 100644 index e15c9ddaca2..00000000000 --- a/modules/userIdTargeting.js +++ /dev/null @@ -1,63 +0,0 @@ -import {config} from '../src/config.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import CONSTANTS from '../src/constants.json'; -import events from '../src/events.js'; -import { isStr, isPlainObject, isBoolean, isFn, hasOwn, logInfo } from '../src/utils.js'; - -const MODULE_NAME = 'userIdTargeting'; -const GAM = 'GAM'; -const GAM_KEYS_CONFIG = 'GAM_KEYS'; - -export function userIdTargeting(userIds, config) { - if (!isPlainObject(config)) { - logInfo(MODULE_NAME + ': Invalid config found, not sharing userIds externally.'); - return; - } - - const PUB_GAM_KEYS = isPlainObject(config[GAM_KEYS_CONFIG]) ? config[GAM_KEYS_CONFIG] : {}; - let SHARE_WITH_GAM = isBoolean(config[GAM]) ? config[GAM] : false; - let GAM_API; - - if (!SHARE_WITH_GAM) { - logInfo(MODULE_NAME + ': Not enabled for ' + GAM); - } else if (window.googletag && isFn(window.googletag.pubads) && hasOwn(window.googletag.pubads(), 'setTargeting') && isFn(window.googletag.pubads().setTargeting)) { - GAM_API = window.googletag.pubads().setTargeting; - } else { - window.googletag = window.googletag || {}; - window.googletag.cmd = window.googletag.cmd || []; - GAM_API = function (key, value) { - window.googletag.cmd.push(function () { - window.googletag.pubads().setTargeting(key, value); - }); - }; - } - - Object.keys(userIds).forEach(function(key) { - if (userIds[key]) { - // PUB_GAM_KEYS: { "tdid": '' } means the publisher does not want to send the tdid to GAM - if (SHARE_WITH_GAM && PUB_GAM_KEYS[key] !== '') { - let uidStr; - if (isStr(userIds[key])) { - uidStr = userIds[key]; - } else if (isPlainObject(userIds[key])) { - uidStr = JSON.stringify(userIds[key]) - } else { - logInfo(MODULE_NAME + ': ' + key + ' User ID is not an object or a string.'); - return; - } - GAM_API( - (hasOwn(PUB_GAM_KEYS, key) ? PUB_GAM_KEYS[key] : key), - [ uidStr ] - ); - } - } - }); -} - -export function init(config) { - events.on(CONSTANTS.EVENTS.AUCTION_END, function() { - userIdTargeting((getGlobal()).getUserIds(), config.getConfig(MODULE_NAME)); - }) -} - -init(config) diff --git a/modules/userIdTargeting.md b/modules/userIdTargeting.md deleted file mode 100644 index 340c1b6abf2..00000000000 --- a/modules/userIdTargeting.md +++ /dev/null @@ -1,37 +0,0 @@ -## userIdTargeting Module -- This module works with userId module. -- This module is used to pass userIds to GAM in targeting so that user ids can be used to pass in Google Exchange Bidding or can be used for targeting in GAM. - -## Sample config -``` -pbjs.setConfig({ - - // your existing userIds config - - userSync: { - userIds: [{...}, ...] - }, - - // new userIdTargeting config - - userIdTargeting: { - "GAM": true, - "GAM_KEYS": { - "tdid": "TTD_ID" // send tdid as TTD_ID - } - } -}); -``` - -## Config options -- GAM: is required to be set to true if a publisher wants to send UserIds as targeting in GAM call. This module uses ``` googletag.pubads().setTargeting('key-name', ['value']) ``` API to set GAM targeting. -- GAM_KEYS: is an optional config object to be used with ``` "GAM": true ```. If not passed then all UserIds are passed with respective key-name used in UserIds object. -If a publisher wants to pass ```UserId.tdid``` as TTD_ID in targeting then set ``` GAM_KEYS: { "tdid": "TTD_ID" }``` -If a publisher does not wants to pass ```UserId.tdid``` but wants to pass other Ids in UserId tthen set ``` GAM_KEYS: { "tdid": "" }``` - -## Including this module in Prebid -``` $ gulp build --modules=userId,userIdTargeting,pubmaticBidAdapter ``` - -## Notes -- We can add support for other external systems like GAM in future -- We have not added support for A9/APSTag as it is called in parallel with Prebid. This module executes when ```pbjs.requestBids``` is called, in practice, call to A9 is expected to execute in paralle to Prebid thus we have not covered A9 here. For sending Uids in A9, one will need to set those Ids in params key in the object passed to ```apstag.init```, ```pbjs.getUserIds``` can be used for the same. diff --git a/modules/validationFpdModule/config.js b/modules/validationFpdModule/config.js deleted file mode 100644 index f6adfea70eb..00000000000 --- a/modules/validationFpdModule/config.js +++ /dev/null @@ -1,125 +0,0 @@ -/** - * Data type map - */ -const TYPES = { - string: 'string', - object: 'object', - number: 'number', -}; - -/** - * Template to define what ortb2 attributes should be validated - * Accepted fields: - * -- invalid - {Boolean} if true, field is not valid - * -- type - {String} valid data type of field - * -- isArray - {Boolean} if true, field must be an array - * -- childType - {String} used in conjuction with isArray: true, defines valid type of array indices - * -- children - {Object} defines child properties needed to be validated (used only if type: object) - * -- required - {Array} array of strings defining any required properties for object (used only if type: object) - * -- optoutApplies - {Boolean} if true, optout logic will filter if applicable (currently only applies to user object) - */ -export const ORTB_MAP = { - imp: { - invalid: true - }, - cur: { - type: TYPES.object, - isArray: true, - childType: TYPES.string - }, - device: { - type: TYPES.object, - children: { - w: { type: TYPES.number }, - h: { type: TYPES.number } - } - }, - site: { - type: TYPES.object, - children: { - name: { type: TYPES.string }, - domain: { type: TYPES.string }, - page: { type: TYPES.string }, - ref: { type: TYPES.string }, - keywords: { type: TYPES.string }, - search: { type: TYPES.string }, - cat: { - type: TYPES.object, - isArray: true, - childType: TYPES.string - }, - sectioncat: { - type: TYPES.object, - isArray: true, - childType: TYPES.string - }, - pagecat: { - type: TYPES.object, - isArray: true, - childType: TYPES.string - }, - content: { - type: TYPES.object, - isArray: false, - children: { - data: { - type: TYPES.object, - isArray: true, - childType: TYPES.object, - required: ['name', 'segment'], - children: { - segment: { - type: TYPES.object, - isArray: true, - childType: TYPES.object, - required: ['id'], - children: { - id: { type: TYPES.string } - } - }, - name: { type: TYPES.string }, - ext: { type: TYPES.object }, - } - } - } - }, - publisher: { - type: TYPES.object, - isArray: false - }, - } - }, - user: { - type: TYPES.object, - children: { - yob: { - type: TYPES.number, - optoutApplies: true - }, - gender: { - type: TYPES.string, - optoutApplies: true - }, - keywords: { type: TYPES.string }, - data: { - type: TYPES.object, - isArray: true, - childType: TYPES.object, - required: ['name', 'segment'], - children: { - segment: { - type: TYPES.object, - isArray: true, - childType: TYPES.object, - required: ['id'], - children: { - id: { type: TYPES.string } - } - }, - name: { type: TYPES.string }, - ext: { type: TYPES.object }, - } - } - } - } -} diff --git a/modules/validationFpdModule/index.js b/modules/validationFpdModule/index.js deleted file mode 100644 index c23f7e09316..00000000000 --- a/modules/validationFpdModule/index.js +++ /dev/null @@ -1,232 +0,0 @@ -/** - * This module sets default values and validates ortb2 first part data - * @module modules/firstPartyData - */ -import { config } from '../../src/config.js'; -import * as utils from '../../src/utils.js'; -import { ORTB_MAP } from './config.js'; -import { submodule } from '../../src/hook.js'; -import { getStorageManager } from '../../src/storageManager.js'; - -const STORAGE = getStorageManager(); -let optout; - -/** - * Check if data passed is empty - * @param {*} value to test against - * @returns {Boolean} is value empty - */ -function isEmptyData(data) { - let check = true; - - if (typeof data === 'object' && !utils.isEmpty(data)) { - check = false; - } else if (typeof data !== 'object' && (utils.isNumber(data) || data)) { - check = false; - } - - return check; -} - -/** - * Check if required keys exist in data object - * @param {Object} data object - * @param {Array} array of required keys - * @param {String} object path (for printing warning) - * @param {Number} index of object value in the data array (for printing warning) - * @returns {Boolean} is requirements fulfilled - */ -function getRequiredData(obj, required, parent, i) { - let check = true; - - required.forEach(key => { - if (!obj[key] || isEmptyData(obj[key])) { - check = false; - utils.logWarn(`Filtered ${parent}[] value at index ${i} in ortb2 data: missing required property ${key}`); - } - }); - - return check; -} - -/** - * Check if data type is valid - * @param {*} value to test against - * @param {Object} object containing type definition and if should be array bool - * @returns {Boolean} is type fulfilled - */ -function typeValidation(data, mapping) { - let check = false; - - switch (mapping.type) { - case 'string': - if (typeof data === 'string') check = true; - break; - case 'number': - if (typeof data === 'number' && isFinite(data)) check = true; - break; - case 'object': - if (typeof data === 'object') { - if ((Array.isArray(data) && mapping.isArray) || (!Array.isArray(data) && !mapping.isArray)) check = true; - } - break; - } - - return check; -} - -/** - * Validates ortb2 data arrays and filters out invalid data - * @param {Array} ortb2 data array - * @param {Object} object defining child type and if array - * @param {String} config path of data array - * @param {String} parent path for logging warnings - * @returns {Array} validated/filtered data - */ -export function filterArrayData(arr, child, path, parent) { - arr = arr.filter((index, i) => { - let check = typeValidation(index, {type: child.type, isArray: child.isArray}); - - if (check && Array.isArray(index) === Boolean(child.isArray)) { - return true; - } - - utils.logWarn(`Filtered ${parent}[] value at index ${i} in ortb2 data: expected type ${child.type}`); - }).filter((index, i) => { - let requiredCheck = true; - let mapping = utils.deepAccess(ORTB_MAP, path); - - if (mapping && mapping.required) requiredCheck = getRequiredData(index, mapping.required, parent, i); - - if (requiredCheck) return true; - }).reduce((result, value, i) => { - let typeBool = false; - let mapping = utils.deepAccess(ORTB_MAP, path); - - switch (child.type) { - case 'string': - result.push(value); - break; - case 'object': - if (mapping && mapping.children) { - let validObject = validateFpd(value, path + '.children.', parent + '.'); - if (Object.keys(validObject).length) { - let requiredCheck = getRequiredData(validObject, mapping.required, parent, i); - - if (requiredCheck) { - result.push(validObject); - typeBool = true; - } - } - } else { - result.push(value); - typeBool = true; - } - break; - } - - if (!typeBool) utils.logWarn(`Filtered ${parent}[] value at index ${i} in ortb2 data: expected type ${child.type}`); - - return result; - }, []); - - return arr; -} - -/** - * Validates ortb2 object and filters out invalid data - * @param {Object} ortb2 object - * @param {String} config path of data array - * @param {String} parent path for logging warnings - * @returns {Object} validated/filtered data - */ -export function validateFpd(fpd, path = '', parent = '') { - if (!fpd) return {}; - - // Filter out imp property if exists - let validObject = Object.assign({}, Object.keys(fpd).filter(key => { - let mapping = utils.deepAccess(ORTB_MAP, path + key); - - if (!mapping || !mapping.invalid) return key; - - utils.logWarn(`Filtered ${parent}${key} property in ortb2 data: invalid property`); - }).filter(key => { - let mapping = utils.deepAccess(ORTB_MAP, path + key); - // let typeBool = false; - let typeBool = (mapping) ? typeValidation(fpd[key], {type: mapping.type, isArray: mapping.isArray}) : true; - - if (typeBool || !mapping) return key; - - utils.logWarn(`Filtered ${parent}${key} property in ortb2 data: expected type ${(mapping.isArray) ? 'array' : mapping.type}`); - }).reduce((result, key) => { - let mapping = utils.deepAccess(ORTB_MAP, path + key); - let modified = {}; - - if (mapping) { - if (mapping.optoutApplies && optout) { - utils.logWarn(`Filtered ${parent}${key} data: pubcid optout found`); - return result; - } - - modified = (mapping.type === 'object' && !mapping.isArray) - ? validateFpd(fpd[key], path + key + '.children.', parent + key + '.') - : (mapping.isArray && mapping.childType) - ? filterArrayData(fpd[key], { type: mapping.childType, isArray: mapping.childisArray }, path + key, parent + key) : fpd[key]; - - // Check if modified data has data and return - (!isEmptyData(modified)) ? result[key] = modified - : utils.logWarn(`Filtered ${parent}${key} property in ortb2 data: empty data found`); - } else { - result[key] = fpd[key]; - } - - return result; - }, {})); - - // Return validated data - return validObject; -} - -/** - * Run validation on global and bidder config data for ortb2 - */ -function runValidations(data) { - let conf = validateFpd(data); - - let bidderDuplicate = { ...config.getBidderConfig() }; - - Object.keys(bidderDuplicate).forEach(bidder => { - let modConf = Object.keys(bidderDuplicate[bidder]).reduce((res, key) => { - let valid = (key !== 'ortb2') ? bidderDuplicate[bidder][key] : validateFpd(bidderDuplicate[bidder][key]); - - if (valid) res[key] = valid; - - return res; - }, {}); - - if (Object.keys(modConf).length) config.setBidderConfig({ bidders: [bidder], config: modConf }); - }); - - return conf; -} - -/** - * Sets default values to ortb2 if exists and adds currency and ortb2 setConfig callbacks on init - */ -export function initSubmodule(fpdConf, data) { - // Checks for existsnece of pubcid optout cookie/storage - // if exists, filters user data out - optout = (STORAGE.cookiesAreEnabled() && STORAGE.getCookie('_pubcid_optout')) || - (STORAGE.hasLocalStorage() && STORAGE.getDataFromLocalStorage('_pubcid_optout')); - - return (!fpdConf.skipValidations) ? runValidations(data) : data; -} - -/** @type {firstPartyDataSubmodule} */ -export const validationSubmodule = { - name: 'validation', - queue: 1, - init: initSubmodule -} - -submodule('firstPartyData', validationSubmodule) diff --git a/modules/vdoaiBidAdapter.js b/modules/vdoaiBidAdapter.js deleted file mode 100644 index 92d665887a5..00000000000 --- a/modules/vdoaiBidAdapter.js +++ /dev/null @@ -1,125 +0,0 @@ -import * as utils from '../src/utils.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'vdoai'; -const ENDPOINT_URL = 'https://prebid.vdo.ai/auction'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return !!(bid.params.placementId); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @return Array Info describing the request to the server. - * @param validBidRequests - * @param bidderRequest - */ - buildRequests: function (validBidRequests, bidderRequest) { - if (validBidRequests.length === 0) { - return []; - } - - return validBidRequests.map(bidRequest => { - const sizes = utils.getAdUnitSizes(bidRequest); - const payload = { - placementId: bidRequest.params.placementId, - sizes: sizes, - bidId: bidRequest.bidId, - referer: bidderRequest.refererInfo.referer, - id: bidRequest.auctionId, - mediaType: bidRequest.mediaTypes.video ? 'video' : 'banner' - }; - bidRequest.params.bidFloor && (payload['bidFloor'] = bidRequest.params.bidFloor); - return { - method: 'POST', - url: ENDPOINT_URL, - data: payload - }; - }); - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {ServerResponse} serverResponse A successful response from the server. - * @param bidRequest - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function (serverResponse, bidRequest) { - const bidResponses = []; - const response = serverResponse.body; - const creativeId = response.adid || 0; - // const width = response.w || 0; - const width = response.width; - // const height = response.h || 0; - const height = response.height; - const cpm = response.price || 0; - - response.rWidth = width; - response.rHeight = height; - - const adCreative = response.vdoCreative; - - if (width !== 0 && height !== 0 && cpm !== 0 && creativeId !== 0) { - // const dealId = response.dealid || ''; - const currency = response.cur || 'USD'; - const netRevenue = true; - // const referrer = bidRequest.data.referer; - const bidResponse = { - requestId: response.bidId, - cpm: cpm, - width: width, - height: height, - creativeId: creativeId, - // dealId: dealId, - currency: currency, - netRevenue: netRevenue, - ttl: config.getConfig('_bidderTimeout'), - // referrer: referrer, - // ad: response.adm - // ad: adCreative, - mediaType: response.mediaType - }; - - if (response.mediaType == 'video') { - bidResponse.vastXml = adCreative; - } else { - bidResponse.ad = adCreative; - } - bidResponses.push(bidResponse); - } - return bidResponses; - }, - - getUserSyncs: function(syncOptions, serverResponse) { - let syncUrls = serverResponse[0] && serverResponse[0].body && serverResponse[0].body.cookiesync && serverResponse[0].body.cookiesync.bidder_status; - - if (syncOptions.iframeEnabled && syncUrls && syncUrls.length > 0) { - let prebidSyncUrls = syncUrls.map(syncObj => { - return { - url: syncObj.usersync.url, - type: 'iframe' - } - }) - return prebidSyncUrls; - } - return []; - }, - - onTImeout: function(data) {}, - onBidWon: function(bid) {}, - onSetTargeting: function(bid) {} -}; -registerBidder(spec); diff --git a/modules/vdoaiBidAdapter.md b/modules/vdoaiBidAdapter.md deleted file mode 100644 index 04200cc9be0..00000000000 --- a/modules/vdoaiBidAdapter.md +++ /dev/null @@ -1,57 +0,0 @@ -# Overview - -``` -Module Name: VDO.AI Bidder Adapter -Module Type: Bidder Adapter -Maintainer: arjit@z1media.com -``` - -# Description - -Module that connects to VDO.AI's demand sources - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - mediaTypes: { - banner: { - sizes: [[300, 250]] // a display size - } - }, - bids: [ - { - bidder: "vdoai", - params: { - placementId: 'newsdv77', - bidFloor: 0.01 // Optional - } - } - ] - } - ]; -``` - - -# Video Test Parameters -``` -var videoAdUnit = { - code: 'test-div', - sizes: [[640, 480]], - mediaTypes: { - video: { - playerSize: [[640, 480]], - context: 'instream' - }, - }, - bids: [ - { - bidder: "vdoai", - params: { - placementId: 'newsdv77' - } - } - ] -}; -``` \ No newline at end of file diff --git a/modules/verizonMediaIdSystem.js b/modules/verizonMediaIdSystem.js deleted file mode 100644 index ca395087d2d..00000000000 --- a/modules/verizonMediaIdSystem.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * This module adds verizonMediaId to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/verizonMediaIdSystem - * @requires module:modules/userId - */ - -import {ajax} from '../src/ajax.js'; -import {submodule} from '../src/hook.js'; -import * as utils from '../src/utils.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -const MODULE_NAME = 'verizonMediaId'; -const VENDOR_ID = 25; -const PLACEHOLDER = '__PIXEL_ID__'; -const VMCID_ENDPOINT = `https://ups.analytics.yahoo.com/ups/${PLACEHOLDER}/fed`; - -function isEUConsentRequired(consentData) { - return !!(consentData && consentData.gdpr && consentData.gdpr.gdprApplies); -} - -/** @type {Submodule} */ -export const verizonMediaIdSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: MODULE_NAME, - /** - * Vendor id of Verizon Media EMEA Limited - * @type {Number} - */ - gvlid: VENDOR_ID, - /** - * decode the stored id value for passing to bid requests - * @function - * @returns {{connectid: string} | undefined} - */ - decode(value) { - return (typeof value === 'object' && (value.connectid || value.vmuid)) - ? {connectid: value.connectid || value.vmuid} : undefined; - }, - /** - * Gets the Verizon Media Connect ID - * @function - * @param {SubmoduleConfig} [config] - * @param {ConsentData} [consentData] - * @returns {IdResponse|undefined} - */ - getId(config, consentData) { - const params = config.params || {}; - if (!params || typeof params.he !== 'string' || - (typeof params.pixelId === 'undefined' && typeof params.endpoint === 'undefined')) { - utils.logError('The verizonMediaId submodule requires the \'he\' and \'pixelId\' parameters to be defined.'); - return; - } - - const data = { - '1p': includes([1, '1', true], params['1p']) ? '1' : '0', - he: params.he, - gdpr: isEUConsentRequired(consentData) ? '1' : '0', - gdpr_consent: isEUConsentRequired(consentData) ? consentData.gdpr.consentString : '', - us_privacy: consentData && consentData.uspConsent ? consentData.uspConsent : '' - }; - - if (params.pixelId) { - data.pixelId = params.pixelId - } - - const resp = function (callback) { - const callbacks = { - success: response => { - let responseObj; - if (response) { - try { - responseObj = JSON.parse(response); - } catch (error) { - utils.logError(error); - } - } - callback(responseObj); - }, - error: error => { - utils.logError(`${MODULE_NAME}: ID fetch encountered an error`, error); - callback(); - } - }; - const endpoint = VMCID_ENDPOINT.replace(PLACEHOLDER, params.pixelId); - let url = `${params.endpoint || endpoint}?${utils.formatQS(data)}`; - verizonMediaIdSubmodule.getAjaxFn()(url, callbacks, null, {method: 'GET', withCredentials: true}); - }; - return {callback: resp}; - }, - - /** - * Return the function used to perform XHR calls. - * Utilised for each of testing. - * @returns {Function} - */ - getAjaxFn() { - return ajax; - } -}; - -submodule('userId', verizonMediaIdSubmodule); diff --git a/modules/verizonMediaSystemId.md b/modules/verizonMediaSystemId.md deleted file mode 100644 index c0d315dc754..00000000000 --- a/modules/verizonMediaSystemId.md +++ /dev/null @@ -1,33 +0,0 @@ -## Verizon Media User ID Submodule - -Verizon Media User ID Module. - -### Prebid Params - -``` -pbjs.setConfig({ - userSync: { - userIds: [{ - name: 'verizonMediaId', - storage: { - name: 'vmcid', - type: 'html5', - expires: 15 - }, - params: { - pixelId: 58776, - he: '0bef996248d63cea1529cb86de31e9547a712d9f380146e98bbd39beec70355a' - } - }] - } -}); -``` -## Parameter Descriptions for the `usersync` Configuration Section -The below parameters apply only to the Verizon Media User ID Module integration. - -| Param under usersync.userIds[] | Scope | Type | Description | Example | -| --- | --- | --- | --- | --- | -| name | Required | String | ID value for the Verizon Media module - `"verizonMediaId"` | `"verizonMediaId"` | -| params | Required | Object | Data for Verizon Media ID initialization. | | -| params.pixelId | Required | Number | The Verizon Media supplied publisher specific pixel Id | `8976` | -| params.he | Required | String | The SHA-256 hashed user email address | `"529cb86de31e9547a712d9f380146e98bbd39beec"` | diff --git a/modules/vertamediaBidAdapter.md b/modules/vertamediaBidAdapter.md deleted file mode 100644 index 6b1265fa792..00000000000 --- a/modules/vertamediaBidAdapter.md +++ /dev/null @@ -1,65 +0,0 @@ -# Overview - -**Module Name**: VertaMedia Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: support@verta.media - -# Description - -Get access to multiple demand partners across VertaMedia AdExchange and maximize your yield with VertaMedia header bidding adapter. - -VertaMedia header bidding adapter connects with VertaMedia demand sources in order to fetch bids. -This adapter provides a solution for accessing Video demand and display demand - - -# Test Parameters -``` - var adUnits = [ - - // Video instream adUnit - { - code: 'div-test-div', - sizes: [[640, 480]], - mediaTypes: { - video: { - context: 'instream' - } - }, - bids: [{ - bidder: 'vertamedia', - params: { - aid: 331133 - } - }] - }, - - // Video outstream adUnit - { - code: 'outstream-test-div', - sizes: [[640, 480]], - mediaTypes: { - video: { - context: 'outstream' - } - }, - bids: [{ - bidder: 'vertamedia', - params: { - aid: 331133 - } - }] - }, - - // Banner adUnit - { - code: 'div-test-div', - sizes: [[300, 250]], - bids: [{ - bidder: 'vertamedia', - params: { - aid: 350975 - } - }] - } - ]; -``` diff --git a/modules/vertozBidAdapter.md b/modules/vertozBidAdapter.md deleted file mode 100644 index 100492da58b..00000000000 --- a/modules/vertozBidAdapter.md +++ /dev/null @@ -1,31 +0,0 @@ -# Overview - -``` -Module Name: Vertoz Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebid-team@vertoz.com -``` - -# Description - -Connects to Vertoz exchange for bids. -Vertoz Bidder adapter supports Banner ads. -Use bidder code ```vertoz``` for all Vertoz traffic. - -# Test Parameters -``` -var adUnits = [ - // Banner adUnit - { - code: 'banner-div', - sizes: [[300, 250], [300,600]], // a display size(s) - bids: [{ - bidder: 'vertoz', - params: { - placementId: 'VZ-HB-B784382V6C6G3C' - } - }] - }, -]; -``` - diff --git a/modules/viBidAdapter.js b/modules/viBidAdapter.js deleted file mode 100644 index 4a09a2d2fc1..00000000000 --- a/modules/viBidAdapter.js +++ /dev/null @@ -1,393 +0,0 @@ -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import * as mediaTypes from '../src/mediaTypes.js'; - -export function get(path, obj, notFound) { - path = typeof path === 'string' ? path.split('.') : path; - - while (path.length) { - const [key] = path; - if (!(obj instanceof Object) || !(key in obj)) return notFound; - obj = obj[key]; - path = path.slice(1); - } - - return obj; -} - -export function merge(a, b, fn = a => a) { - const res = {}; - - for (const key in a) { - if (key in b) { - res[key] = fn(a[key], b[key]); - } else { - res[key] = a[key]; - } - } - - for (const key in b) { - if (!(key in a)) res[key] = b[key]; - } - - return res; -} - -export function ratioToPercentageCeil(x) { - return Math.ceil(x * 100); -} - -export function getDocumentHeight(curDocument = document) { - return Math.max( - get('body.clientHeight', curDocument, 0), - get('body.scrollHeight', curDocument, 0), - get('body.offsetHeight', curDocument, 0), - get('documentElement.clientHeight', curDocument, 0), - get('documentElement.scrollHeight', curDocument, 0), - get('documentElement.offsetHeight', curDocument, 0) - ); -} - -export function getOffset(element) { - const rect = element.getBoundingClientRect(); - const elementWindow = getElementWindow(element); - if (!elementWindow) throw new Error('cannot get element window'); - const scrollLeft = - elementWindow.pageXOffset || get('documentElement.scrollLeft', document, 0); - const scrollTop = - elementWindow.pageYOffset || get('documentElement.scrollTop', document, 0); - return { - top: rect.top + scrollTop, - right: rect.right + scrollLeft, - bottom: rect.bottom + scrollTop, - left: rect.left + scrollLeft - }; -} - -var IframeType; - -(function(IframeType) { - IframeType['safeframe'] = 'safeframe'; - IframeType['friendly'] = 'friendly'; - IframeType['nonfriendly'] = 'nonfriendly'; -})(IframeType || (IframeType = {})); - -export function getWindowParents(curWindow = window) { - const parents = []; - - while (curWindow && curWindow.parent && curWindow !== curWindow.parent) { - parents.push(curWindow.parent); - curWindow = curWindow.parent; - } - - return parents; -} - -export function getTopmostReachableWindow(curWindow = window) { - const parents = getWindowParents(curWindow); - return parents.length ? parents[parents.length - 1] : curWindow; -} - -export function topDocumentIsReachable(curWindow = window) { - if (!isInsideIframe(curWindow)) return true; - const windowParents = getWindowParents(curWindow); - - try { - const topWindow = windowParents[windowParents.length - 1]; - - return topWindow === curWindow.top && !!curWindow.top.document; - } catch (e) { - return false; - } -} - -export function isInsideIframe(curWindow = window) { - return curWindow !== curWindow.top; -} - -export function isInsideSafeframe(curWindow = window) { - return !topDocumentIsReachable(curWindow) && !!curWindow.$sf; -} - -export function isInsideFriendlyIframe(curWindow = window) { - return isInsideIframe(curWindow) && topDocumentIsReachable(curWindow); -} - -export function getIframeType(curWindow = window) { - if (!isInsideIframe(curWindow)) return; - if (isInsideSafeframe(curWindow)) return IframeType.safeframe; - if (isInsideFriendlyIframe(curWindow)) return IframeType.friendly; - return IframeType.nonfriendly; -} - -function getElementWindow(element) { - return element.ownerDocument - ? element.ownerDocument.defaultView - : element.defaultView; -} - -const NO_CUTS = { - top: 0, - right: 0, - bottom: 0, - left: 0 -}; - -export function getRectCuts(rect, vh, vw, vCuts = NO_CUTS) { - let { top, left } = rect; - const { bottom, right } = rect; - top = top + vCuts.top; - left = left + vCuts.left; - vh = vh + vCuts.bottom; - vw = vw + vCuts.right; - return { - bottom: Math.min(0, vh - bottom), - left: Math.min(0, left), - right: Math.min(0, vw - right), - top: Math.min(0, top) - }; -} - -export function getFrameElements(curWindow = window) { - const frameElements = []; - - while (curWindow && curWindow.frameElement) { - frameElements.unshift(curWindow.frameElement); - curWindow = - curWindow.frameElement.ownerDocument && - curWindow.frameElement.ownerDocument.defaultView; - } - - return frameElements; -} - -export function getElementCuts(element, vCuts) { - const window = getElementWindow(element); - return getRectCuts( - element.getBoundingClientRect(), - window ? window.innerHeight : 0, - window ? window.innerWidth : 0, - vCuts - ); -} - -export function area(width, height, areaCuts = NO_CUTS) { - const { top, right, bottom, left } = areaCuts; - return Math.max(0, (width + left + right) * (height + top + bottom)); -} - -export function getInViewRatio(element) { - const elements = [...getFrameElements(getElementWindow(element)), element]; - const vCuts = elements.reduce( - (vCuts, element) => getElementCuts(element, vCuts), - NO_CUTS - ); - return ( - area(element.offsetWidth || 1, element.offsetHeight || 1, vCuts) / - area(element.offsetWidth || 1, element.offsetHeight || 1) - ); -} - -export function getInViewRatioInsideTopFrame(element) { - const elements = [...getFrameElements().slice(1), element]; - const vCuts = elements.reduce( - (vCuts, element) => getElementCuts(element, vCuts), - NO_CUTS - ); - return ( - area(element.offsetWidth, element.offsetHeight, vCuts) / - area(element.offsetWidth, element.offsetHeight) - ); -} - -export function getMayBecomeVisible(element) { - return !isInsideIframe() || !!getInViewRatioInsideTopFrame(element); -} - -export function getInViewPercentage(element) { - return ratioToPercentageCeil(getInViewRatio(element)); -} - -export function getOffsetTopDocument(element) { - return [...getFrameElements(getElementWindow(element)), element].reduce( - (acc, elem) => merge(acc, getOffset(elem), (a, b) => a + b), - { - top: 0, - right: 0, - bottom: 0, - left: 0 - } - ); -} - -export function getOffsetTopDocumentPercentage(element) { - const elementWindow = getElementWindow(element); - if (!elementWindow) throw new Error('cannot get element window'); - if (!topDocumentIsReachable(elementWindow)) { - throw new Error("top window isn't reachable"); - } - const topWindow = getTopmostReachableWindow(elementWindow); - const documentHeight = getDocumentHeight(topWindow.document); - return ratioToPercentageCeil( - getOffsetTopDocument(element).top / documentHeight - ); -} - -export function getOffsetToView(element) { - const elemWindow = getElementWindow(element); - if (!elemWindow) throw new Error('cannot get element window'); - const topWindow = getTopmostReachableWindow(elemWindow); - const { top, bottom } = getOffsetTopDocument(element); - const topWindowHeight = topWindow.innerHeight; - - if (bottom < topWindow.scrollY) return bottom - topWindow.scrollY; - - if (top > topWindow.scrollY + topWindowHeight) { - return top - topWindow.scrollY - topWindowHeight; - } - - return 0; -} - -export function getOffsetToViewPercentage(element) { - return ratioToPercentageCeil( - getOffsetToView(element) / - getDocumentHeight( - getTopmostReachableWindow(getElementWindow(element)).document - ) - ); -} - -export function getViewabilityDescription(element) { - let iframeType; - try { - if (!element) { - return { - error: 'no element' - }; - } - iframeType = getIframeType(getElementWindow(element)); - if (!iframeType || iframeType === IframeType.friendly) { - const inViewPercentage = getInViewPercentage(element); - return { - inView: inViewPercentage, - hidden: !inViewPercentage && !getMayBecomeVisible(element), - offsetTop: getOffsetTopDocumentPercentage(element), - offsetView: getOffsetToViewPercentage(element), - iframeType - }; - } - return { - iframeType - }; - } catch (error) { - return { - iframeType, - error: error.message - }; - } -} - -export function mergeArrays(hashFn, ...args) { - const seen = {}; - const merged = []; - args.forEach(sizes => { - sizes.forEach(size => { - const key = hashFn(size); - if (!(key in seen)) { - seen[key] = true; - merged.push(size); - } - }); - }); - return merged; -} - -export function documentFocus(doc) { - return typeof doc.hasFocus === 'function' ? +doc.hasFocus() : undefined; -} - -const spec = { - code: 'vi', - supportedMediaTypes: [mediaTypes.VIDEO, mediaTypes.BANNER], - - isBidRequestValid({ adUnitCode, params: { pubId, lang, cat } = {} }) { - return [pubId, lang, cat].every(x => typeof x === 'string'); - }, - - /** - * - * @param bidRequests - * @param bidderRequest - * @return { - * {method: string, - * data: { - imps: { - bidId: string, - adUnitCode: string, - sizes: [[number, number]], - pubId: string, - lang: string, - cat: string, - iframeType: string | undefined, - error: string | null, - inView: number, - offsetTop: number, - offsetView: number, - hidden: boolean, - bidFloor: number - }[], - refererInfo: { - referer: string - reachedTop: boolean, - numIframes: number, - stack: string[] - canonicalUrl: string - } - }, - * options: {withCredentials: boolean, contentType: string}, url: string}} - */ - buildRequests(bidRequests, bidderRequest) { - return { - method: 'POST', - url: 'https://pb.vi-serve.com/prebid/bid', - data: { - refererInfo: bidderRequest.refererInfo, - imps: bidRequests.map( - ({ bidId, adUnitCode, sizes, params, mediaTypes }) => { - const slot = document.getElementById(adUnitCode); - const bannerSizes = get('banner.sizes', mediaTypes); - const playerSize = get('video.playerSize', mediaTypes); - - const sizesToMerge = []; - if (!params.useSizes) { - if (sizes) sizesToMerge.push(sizes); - if (bannerSizes) sizesToMerge.push(bannerSizes); - if (playerSize) sizesToMerge.push(playerSize); - } else if (params.useSizes === 'banner' && bannerSizes) { - sizesToMerge.push(bannerSizes); - } else if (params.useSizes === 'video' && playerSize) { - sizesToMerge.push(playerSize); - } - return { - bidId, - adUnitCode, - sizes: mergeArrays(x => x.join(','), ...sizesToMerge), - ...getViewabilityDescription(slot), - ...params - }; - } - ), - focus: documentFocus(document) - }, - options: { - contentType: 'application/json', - withCredentials: true - } - }; - }, - - interpretResponse({ body }) { - return body; - } -}; -registerBidder(spec); diff --git a/modules/viBidAdapter.md b/modules/viBidAdapter.md deleted file mode 100644 index 2608ccc4adb..00000000000 --- a/modules/viBidAdapter.md +++ /dev/null @@ -1,42 +0,0 @@ -# Overview - -``` -Module Name: vi bid adapter -Module Type: Bidder adapter -Maintainer: support@vi.ai -``` - -# Description - -The video intelligence (vi) adapter integration to the Prebid library. -Connects to vi’s demand sources. -There should be only one ad unit with vi bid adapter on each single page. - -# Test Parameters - -``` -var adUnits = [{ - code: 'div-0', - sizes: [[320, 480]], - bids: [{ - bidder: 'vi', - params: { - pubId: 'sb_test', - lang: 'en-US', - cat: 'IAB1', - bidFloor: 0.05 //optional - } - }] -}]; -``` - -# Parameters - -| Name | Scope | Description | Example | -| :------------ | :------- | :---------------------------------------------- | :--------------------------------- | -| `pubId` | required | Publisher ID, provided by vi | 'sb_test' | -| `lang` | required | Ad language, in ISO 639-1 language code format | 'en-US', 'es-ES', 'de' | -| `cat` | required | Ad IAB category (top-level or subcategory), single one supported | 'IAB1', 'IAB9-1' | -| `bidFloor` | optional | Lowest value of expected bid price | 0.001 | -| `useSizes` | optional | Specifies from which section of the config sizes are taken, possible values are 'banner', 'video'. If omitted, sizes from both sections are merged. | 'banner' | - diff --git a/modules/vidazooBidAdapter.js b/modules/vidazooBidAdapter.js deleted file mode 100644 index 7fc6e3a5395..00000000000 --- a/modules/vidazooBidAdapter.js +++ /dev/null @@ -1,278 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const GVLID = 744; -const DEFAULT_SUB_DOMAIN = 'prebid'; -const BIDDER_CODE = 'vidazoo'; -const BIDDER_VERSION = '1.0.0'; -const CURRENCY = 'USD'; -const TTL_SECONDS = 60 * 5; -const DEAL_ID_EXPIRY = 1000 * 60 * 15; -const UNIQUE_DEAL_ID_EXPIRY = 1000 * 60 * 15; -const SESSION_ID_KEY = 'vidSid'; -export const SUPPORTED_ID_SYSTEMS = { - 'britepoolid': 1, - 'criteoId': 1, - 'digitrustid': 1, - 'id5id': 1, - 'idl_env': 1, - 'lipb': 1, - 'netId': 1, - 'parrableId': 1, - 'pubcid': 1, - 'tdid': 1, -}; -const storage = getStorageManager(GVLID); - -export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { - return `https://${subDomain}.cootlogix.com`; -} - -export function extractCID(params) { - return params.cId || params.CID || params.cID || params.CId || params.cid || params.ciD || params.Cid || params.CiD; -} - -export function extractPID(params) { - return params.pId || params.PID || params.pID || params.PId || params.pid || params.piD || params.Pid || params.PiD; -} - -export function extractSubDomain(params) { - return params.subDomain || params.SubDomain || params.Subdomain || params.subdomain || params.SUBDOMAIN || params.subDOMAIN; -} - -function isBidRequestValid(bid) { - const params = bid.params || {}; - return !!(extractCID(params) && extractPID(params)); -} - -function buildRequest(bid, topWindowUrl, sizes, bidderRequest) { - const { params, bidId, userId, adUnitCode } = bid; - const { bidFloor, ext } = params; - const hashUrl = hashCode(topWindowUrl); - const dealId = getNextDealId(hashUrl); - const uniqueDealId = getUniqueDealId(hashUrl); - const sId = getVidazooSessionId(); - const cId = extractCID(params); - const pId = extractPID(params); - const subDomain = extractSubDomain(params); - - let data = { - url: encodeURIComponent(topWindowUrl), - cb: Date.now(), - bidFloor: bidFloor, - bidId: bidId, - adUnitCode: adUnitCode, - publisherId: pId, - sessionId: sId, - sizes: sizes, - dealId: dealId, - uniqueDealId: uniqueDealId, - bidderVersion: BIDDER_VERSION, - prebidVersion: '$prebid.version$', - res: `${screen.width}x${screen.height}` - }; - - appendUserIdsToRequestPayload(data, userId); - - if (bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.consentString) { - data.gdprConsent = bidderRequest.gdprConsent.consentString; - } - if (bidderRequest.gdprConsent.gdprApplies !== undefined) { - data.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; - } - } - if (bidderRequest.uspConsent) { - data.usPrivacy = bidderRequest.uspConsent - } - - const dto = { - method: 'POST', - url: `${createDomain(subDomain)}/prebid/multi/${cId}`, - data: data - }; - - utils._each(ext, (value, key) => { - dto.data['ext.' + key] = value; - }); - - return dto; -} - -function appendUserIdsToRequestPayload(payloadRef, userIds) { - let key; - utils._each(userIds, (userId, idSystemProviderName) => { - if (SUPPORTED_ID_SYSTEMS[idSystemProviderName]) { - key = `uid.${idSystemProviderName}`; - - switch (idSystemProviderName) { - case 'digitrustid': - payloadRef[key] = utils.deepAccess(userId, 'data.id'); - break; - case 'lipb': - payloadRef[key] = userId.lipbid; - break; - case 'parrableId': - payloadRef[key] = userId.eid; - break; - case 'id5id': - payloadRef[key] = userId.uid; - break; - default: - payloadRef[key] = userId; - } - } - }); -} - -function buildRequests(validBidRequests, bidderRequest) { - const topWindowUrl = bidderRequest.refererInfo.referer; - const requests = []; - validBidRequests.forEach(validBidRequest => { - const sizes = utils.parseSizesInput(validBidRequest.sizes); - const request = buildRequest(validBidRequest, topWindowUrl, sizes, bidderRequest); - requests.push(request); - }); - return requests; -} - -function interpretResponse(serverResponse, request) { - if (!serverResponse || !serverResponse.body) { - return []; - } - const { bidId } = request.data; - const { results } = serverResponse.body; - - let output = []; - - try { - results.forEach(result => { - const { creativeId, ad, price, exp, width, height, currency } = result; - if (!ad || !price) { - return; - } - output.push({ - requestId: bidId, - cpm: price, - width: width, - height: height, - creativeId: creativeId, - currency: currency || CURRENCY, - netRevenue: true, - ttl: exp || TTL_SECONDS, - ad: ad - }) - }); - return output; - } catch (e) { - return []; - } -} - -function getUserSyncs(syncOptions, responses, gdprConsent = {}, uspConsent = '') { - let syncs = []; - const { iframeEnabled, pixelEnabled } = syncOptions; - const { gdprApplies, consentString = '' } = gdprConsent; - const params = `?gdpr=${gdprApplies ? 1 : 0}&gdpr_consent=${encodeURIComponent(consentString || '')}&us_privacy=${encodeURIComponent(uspConsent || '')}` - if (iframeEnabled) { - syncs.push({ - type: 'iframe', - url: `https://prebid.cootlogix.com/api/sync/iframe/${params}` - }); - } - if (pixelEnabled) { - syncs.push({ - type: 'image', - url: `https://prebid.cootlogix.com/api/sync/image/${params}` - }); - } - return syncs; -} - -export function hashCode(s, prefix = '_') { - const l = s.length; - let h = 0 - let i = 0; - if (l > 0) { - while (i < l) { h = (h << 5) - h + s.charCodeAt(i++) | 0; } - } - return prefix + h; -} - -export function getNextDealId(key, expiry = DEAL_ID_EXPIRY) { - try { - const data = getStorageItem(key); - let currentValue = 0; - let timestamp; - - if (data && data.value && Date.now() - data.created < expiry) { - currentValue = data.value; - timestamp = data.created; - } - - const nextValue = currentValue + 1; - setStorageItem(key, nextValue, timestamp); - return nextValue; - } catch (e) { - return 0; - } -} - -export function getUniqueDealId(key, expiry = UNIQUE_DEAL_ID_EXPIRY) { - const storageKey = `u_${key}`; - const now = Date.now(); - const data = getStorageItem(storageKey); - let uniqueId; - - if (!data || !data.value || now - data.created > expiry) { - uniqueId = `${key}_${now.toString()}`; - setStorageItem(storageKey, uniqueId); - } else { - uniqueId = data.value; - } - - return uniqueId; -} - -export function getVidazooSessionId() { - return getStorageItem(SESSION_ID_KEY) || ''; -} - -export function getStorageItem(key) { - try { - return tryParseJSON(storage.getDataFromLocalStorage(key)); - } catch (e) { } - - return null; -} - -export function setStorageItem(key, value, timestamp) { - try { - const created = timestamp || Date.now(); - const data = JSON.stringify({ value, created }); - storage.setDataInLocalStorage(key, data); - } catch (e) { } -} - -export function tryParseJSON(value) { - try { - return JSON.parse(value); - } catch (e) { - return value; - } -} - -export const spec = { - code: BIDDER_CODE, - gvlid: GVLID, - version: BIDDER_VERSION, - supportedMediaTypes: [BANNER], - isBidRequestValid, - buildRequests, - interpretResponse, - getUserSyncs -}; - -registerBidder(spec); diff --git a/modules/vidazooBidAdapter.md b/modules/vidazooBidAdapter.md deleted file mode 100644 index df7700cb05a..00000000000 --- a/modules/vidazooBidAdapter.md +++ /dev/null @@ -1,35 +0,0 @@ -# Overview - -**Module Name:** Vidazoo Bidder Adapter - -**Module Type:** Bidder Adapter - -**Maintainer:** dev@vidazoo.com - -# Description - -Module that connects to Vidazoo's demand sources. - -# Test Parameters -```js -var adUnits = [ - { - code: 'test-ad', - sizes: [[300, 250]], - bids: [ - { - bidder: 'vidazoo', - params: { - cId: '5a1c419d95fce900044c334e', - pId: '59ac17c192832d0011283fe3', - bidFloor: 0.0001, - ext: { - param1: 'loremipsum', - param2: 'dolorsitamet' - } - } - } - ] - } -]; -``` diff --git a/modules/videoNowBidAdapter.js b/modules/videoNowBidAdapter.js deleted file mode 100644 index b391af08d49..00000000000 --- a/modules/videoNowBidAdapter.js +++ /dev/null @@ -1,187 +0,0 @@ -import * as utils from '../src/utils.js' -import { registerBidder } from '../src/adapters/bidderFactory.js' -import { BANNER } from '../src/mediaTypes.js' -import { loadExternalScript } from '../src/adloader.js' - -const RTB_URL = 'https://bidder.videonow.ru/prebid' - -const BIDDER_CODE = 'videonow' -const TTL_SECONDS = 60 * 5 - -function isBidRequestValid(bid) { - return !!(bid && bid.params && bid.params.pId) -} - -function buildRequest(bid, bidderRequest) { - const { refererInfo } = bidderRequest - const { ext, bidId, params, code, sizes } = bid - const { pId, bidFloor, cur, placementId, url: rtbUrl } = params || {} - - let url = rtbUrl || RTB_URL - url = `${url}${~url.indexOf('?') ? '&' : '?'}profile_id=${pId}` - - const dto = { - method: 'POST', - url, - data: { - id: bidId, - cpm: bidFloor, - code, - sizes, - cur: cur || 'RUB', - placementId, - ref: refererInfo && refererInfo.referer, - }, - } - - ext && Object.keys(ext).forEach(key => { - dto.data[`ext_${key}`] = ext[key] - }) - - return dto -} - -function buildRequests(validBidRequests, bidderRequest) { - utils.logInfo(`${BIDDER_CODE}. buildRequests`) - const requests = [] - validBidRequests.forEach(validBidRequest => { - const request = buildRequest(validBidRequest, bidderRequest) - request && requests.push(request) - }) - return requests -} - -function interpretResponse(serverResponse, bidRequest) { - if (!serverResponse || !serverResponse.body) { - return [] - } - const { id: bidId } = (bidRequest && bidRequest.data) || {} - if (!bidId) return [] - - const { seatbid, cur, ext } = serverResponse.body - if (!seatbid || !seatbid.length) return [] - - const { placementId } = ext || {} - if (!placementId) return [] - - const bids = [] - seatbid.forEach(sb => { - const { bid } = sb - bid && bid.length && bid.forEach(b => { - const res = createResponseBid(b, bidId, cur, placementId) - res && bids.push(res) - }) - }) - - return bids -} - -function createResponseBid(bidInfo, bidId, cur, placementId) { - const { id, nurl, code, price, crid, ext, ttl, netRevenue, w, h, adm } = bidInfo - - if (!id || !price || !adm) { - return null - } - - const { init: initPath, module, format } = ext || {} - if (!initPath) { - utils.logError(`vnInitModulePath is not defined`) - return null - } - - const { log, min } = module || {} - - if (!min && !log) { - utils.logError('module\'s paths are not defined') - return null - } - - return { - requestId: bidId, - cpm: price, - width: w, - height: h, - creativeId: crid, - currency: cur || 'RUB', - netRevenue: netRevenue !== undefined ? netRevenue : true, - ttl: ttl || TTL_SECONDS, - ad: code, - nurl, - renderer: { - url: min || log, - render: function() { - const d = window.document - const el = placementId && d.getElementById(placementId) - if (el) { - const pId = 1 - // prepare data for vn_init script - const profileData = { - module, - dataXml: adm, - } - - format && (profileData.format = format) - - // add init data for vn_init on the page - const videonow = window.videonow = window.videonow || {} - const init = videonow.init = window.videonow.init || {} - init[pId] = profileData - - // add vn_init js on the page - loadExternalScript(`${initPath}${~initPath.indexOf('?') ? '&' : '?'}profileId=${pId}`, 'outstream') - } else { - utils.logError(`bidAdapter ${BIDDER_CODE}: ${placementId} not found`) - } - } - } - } -} - -function getUserSyncs(syncOptions, serverResponses) { - const syncs = [] - - if (!serverResponses || !serverResponses.length) return syncs - - serverResponses.forEach(response => { - const { ext } = (response && response.body) || {} - const { pixels, iframes } = ext || {} - - if (syncOptions.iframeEnabled && iframes && iframes.length) { - iframes.forEach(i => syncs.push({ - type: 'iframe', - url: i, - }), - ) - } - - if (syncOptions.pixelEnabled && pixels && pixels.length) { - pixels.forEach(p => syncs.push({ - type: 'image', - url: p, - }), - ) - } - }) - - utils.logInfo(`${BIDDER_CODE} getUserSyncs() syncs=${syncs.length}`) - return syncs -} - -function onBidWon(bid) { - const { nurl } = bid || {} - if (nurl) { - utils.triggerPixel(utils.replaceAuctionPrice(nurl, bid.cpm)); - } -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - isBidRequestValid, - buildRequests, - interpretResponse, - getUserSyncs, - onBidWon -} - -registerBidder(spec) diff --git a/modules/videoNowBidAdapter.md b/modules/videoNowBidAdapter.md deleted file mode 100644 index 2ac2a431378..00000000000 --- a/modules/videoNowBidAdapter.md +++ /dev/null @@ -1,35 +0,0 @@ -# Overview - -``` -Module Name: Videonow Bidder Adapter -Module Type: Bidder Adapter -Maintainer: info@videonow.ru -``` - -# Description - -Connect to Videonow for bids. - -The Videonow bidder adapter requires setup and approval from the videoNow team. -Please reach out to your account team or info@videonow.ru for more information. - -# Test Parameters -```javascript -var adUnits = [ - // Banner adUnit - { - code: 'banner-div', - mediaTypes: { - banner: { - sizes: [[640, 480], [300, 250], [336, 280]] - } - }, - bids: [{ - bidder: 'videonow', - params: { - pId: 1, - placementId: '36891' - } - }] - }] -``` diff --git a/modules/videofyBidAdapter.js b/modules/videofyBidAdapter.js deleted file mode 100644 index 11bc21303fd..00000000000 --- a/modules/videofyBidAdapter.js +++ /dev/null @@ -1,300 +0,0 @@ -import { VIDEO } from '../src/mediaTypes.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { Renderer } from '../src/Renderer.js'; -import * as utils from '../src/utils.js'; - -const BIDDER_CODE = 'videofy'; -const TTL = 600; - -function avRenderer(bid) { - bid.renderer.push(function() { - let eventCallback = bid && bid.renderer && bid.renderer.handleVideoEvent ? bid.renderer.handleVideoEvent : null; - window.aniviewRenderer.renderAd({ - id: bid.adUnitCode + '_' + bid.adId, - debug: window.location.href.indexOf('pbjsDebug') >= 0, - placement: bid.adUnitCode, - width: bid.width, - height: bid.height, - vastUrl: bid.vastUrl, - vastXml: bid.vastXml, - config: bid.params[0].rendererConfig, - eventsCallback: eventCallback, - bid: bid - }); - }); -} - -function newRenderer(bidRequest) { - const renderer = Renderer.install({ - url: 'https://player.srv-mars.com/script/6.1/prebidRenderer.js', - config: {}, - loaded: false, - }); - - try { - renderer.setRender(avRenderer); - } catch (err) { - } - - return renderer; -} - -function isBidRequestValid(bid) { - if (!bid.params || !bid.params.AV_PUBLISHERID || !bid.params.AV_CHANNELID) { return false; } - - return true; -} -let irc = 0; -function buildRequests(validBidRequests, bidderRequest) { - let bidRequests = []; - - for (let i = 0; i < validBidRequests.length; i++) { - let bidRequest = validBidRequests[i]; - var sizes = [[640, 480]]; - - if (bidRequest.mediaTypes && bidRequest.mediaTypes.video && bidRequest.mediaTypes.video.playerSize) { - sizes = bidRequest.mediaTypes.video.playerSize; - } else { - if (bidRequest.sizes) { - sizes = bidRequest.sizes; - } - } - if (sizes.length === 2 && typeof sizes[0] === 'number') { - sizes = [[sizes[0], sizes[1]]]; - } - - for (let j = 0; j < sizes.length; j++) { - let size = sizes[j]; - let playerWidth; - let playerHeight; - - if (size && size.length == 2) { - playerWidth = size[0]; - playerHeight = size[1]; - } else { - playerWidth = 640; - playerHeight = 480; - } - - let s2sParams = {}; - - for (var attrname in bidRequest.params) { - if (bidRequest.params.hasOwnProperty(attrname) && attrname.indexOf('AV_') == 0) { - s2sParams[attrname] = bidRequest.params[attrname]; - } - }; - - if (s2sParams.AV_APPPKGNAME && !s2sParams.AV_URL) { s2sParams.AV_URL = s2sParams.AV_APPPKGNAME; } - if (!s2sParams.AV_IDFA && !s2sParams.AV_URL) { - if (bidderRequest && bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { - s2sParams.AV_URL = bidderRequest.refererInfo.referer; - } else { - s2sParams.AV_URL = window.location.href; - } - } - if (s2sParams.AV_IDFA && !s2sParams.AV_AID) { s2sParams.AV_AID = s2sParams.AV_IDFA; } - if (s2sParams.AV_AID && !s2sParams.AV_IDFA) { s2sParams.AV_IDFA = s2sParams.AV_AID; } - - s2sParams.cb = Math.floor(Math.random() * 999999999); - s2sParams.AV_WIDTH = playerWidth; - s2sParams.AV_HEIGHT = playerHeight; - s2sParams.bidWidth = playerWidth; - s2sParams.bidHeight = playerHeight; - s2sParams.bidId = bidRequest.bidId; - s2sParams.pbjs = 1; - s2sParams.tgt = 10; - s2sParams.s2s = '1'; - s2sParams.irc = irc; - irc++; - s2sParams.wpm = 1; - - if (bidderRequest && bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.gdprApplies) { - s2sParams.AV_GDPR = 1; - s2sParams.AV_CONSENT = bidderRequest.gdprConsent.consentString; - } - } - if (bidderRequest && bidderRequest.uspConsent) { - s2sParams.AV_CCPA = bidderRequest.uspConsent; - } - - let serverDomain = (bidRequest.params && bidRequest.params.serverDomain) ? bidRequest.params.serverDomain : 'servx.srv-mars.com'; - let servingUrl = 'https://' + serverDomain + '/api/adserver/vast3/'; - - bidRequests.push({ - method: 'GET', - url: servingUrl, - data: s2sParams, - bidRequest - }); - } - } - - return bidRequests; -} -function getCpmData(xml) { - let ret = {cpm: 0, currency: 'USD'}; - if (xml) { - let ext = xml.getElementsByTagName('Extensions'); - if (ext && ext.length > 0) { - ext = ext[0].getElementsByTagName('Extension'); - if (ext && ext.length > 0) { - for (var i = 0; i < ext.length; i++) { - if (ext[i].getAttribute('type') == 'ANIVIEW') { - let price = ext[i].getElementsByTagName('Cpm'); - if (price && price.length == 1) { - ret.cpm = price[0].textContent; - } - break; - } - } - } - } - } - return ret; -} -function interpretResponse(serverResponse, bidRequest) { - let bidResponses = []; - if (serverResponse && serverResponse.body) { - if (serverResponse.error) { - return bidResponses; - } else { - try { - let bidResponse = {}; - if (bidRequest && bidRequest.data && bidRequest.data.bidId && bidRequest.data.bidId !== '') { - let xmlStr = serverResponse.body; - let xml = new window.DOMParser().parseFromString(xmlStr, 'text/xml'); - if (xml && xml.getElementsByTagName('parsererror').length == 0) { - let cpmData = getCpmData(xml); - if (cpmData && cpmData.cpm > 0) { - bidResponse.requestId = bidRequest.data.bidId; - bidResponse.bidderCode = BIDDER_CODE; - bidResponse.ad = ''; - bidResponse.cpm = cpmData.cpm; - bidResponse.width = bidRequest.data.AV_WIDTH; - bidResponse.height = bidRequest.data.AV_HEIGHT; - bidResponse.ttl = TTL; - bidResponse.creativeId = xml.getElementsByTagName('Ad') && xml.getElementsByTagName('Ad')[0] && xml.getElementsByTagName('Ad')[0].getAttribute('id') ? xml.getElementsByTagName('Ad')[0].getAttribute('id') : 'creativeId'; - bidResponse.currency = cpmData.currency; - bidResponse.netRevenue = true; - var blob = new Blob([xmlStr], { - type: 'application/xml' - }); - bidResponse.vastUrl = window.URL.createObjectURL(blob); - bidResponse.vastXml = xmlStr; - bidResponse.mediaType = VIDEO; - if (bidRequest.bidRequest && bidRequest.bidRequest.mediaTypes && bidRequest.bidRequest.mediaTypes.video && bidRequest.bidRequest.mediaTypes.video.context === 'outstream') { bidResponse.renderer = newRenderer(bidRequest); } - - bidResponses.push(bidResponse); - } - } else {} - } else {} - } catch (e) {} - } - } else {} - - return bidResponses; -} - -function getSyncData(xml, options) { - let ret = []; - if (xml) { - let ext = xml.getElementsByTagName('Extensions'); - if (ext && ext.length > 0) { - ext = ext[0].getElementsByTagName('Extension'); - if (ext && ext.length > 0) { - for (var i = 0; i < ext.length; i++) { - if (ext[i].getAttribute('type') == 'ANIVIEW') { - let syncs = ext[i].getElementsByTagName('AdServingSync'); - if (syncs && syncs.length == 1) { - try { - let data = JSON.parse(syncs[0].textContent); - if (data && data.trackers && data.trackers.length) { - data = data.trackers; - for (var j = 0; j < data.length; j++) { - if (typeof data[j] === 'object' && typeof data[j].url === 'string' && data[j].e === 'inventory') { - if (data[j].t == 1 && options.pixelEnabled) { - ret.push({url: data[j].url, type: 'image'}); - } else { - if (data[j].t == 3 && options.iframeEnabled) { - ret.push({url: data[j].url, type: 'iframe'}); - } - } - } - } - } - } catch (e) {} - } - break; - } - } - } - } - } - return ret; -} - -function getUserSyncs(syncOptions, serverResponses) { - if (serverResponses && serverResponses[0] && serverResponses[0].body) { - if (serverResponses.error) { - return []; - } else { - try { - let xmlStr = serverResponses[0].body; - let xml = new window.DOMParser().parseFromString(xmlStr, 'text/xml'); - if (xml && xml.getElementsByTagName('parsererror').length == 0) { - let syncData = getSyncData(xml, syncOptions); - return syncData; - } - } catch (e) {} - } - } -} - -function onBidWon(bid) { - sendbeacon(bid, 17); -} - -function onTimeout(bid) { - sendbeacon(bid, 19); -} - -function onSetTargeting(bid) { - sendbeacon(bid, 20); -} - -function sendbeacon(bid, type) { - const bidCopy = { - bidder: bid.bidder, - cpm: bid.cpm, - originalCpm: bid.originalCpm, - currency: bid.currency, - originalCurrency: bid.originalCurrency, - timeToRespond: bid.timeToRespond, - statusMessage: bid.statusMessage, - width: bid.width, - height: bid.height, - size: bid.size, - params: bid.params, - status: bid.status, - adserverTargeting: bid.adserverTargeting, - ttl: bid.ttl - }; - const bidString = JSON.stringify(bidCopy); - const encodedBuf = window.btoa(bidString); - utils.triggerPixel('https://beacon.videofy.io/notification/rtb/beacon/?bt=' + type + '&bid=hcwqso&hb_j=' + encodedBuf, null); -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [VIDEO], - isBidRequestValid, - buildRequests, - interpretResponse, - getUserSyncs, - onBidWon, - onTimeout, - onSetTargeting -}; - -registerBidder(spec); diff --git a/modules/videofyBidAdapter.md b/modules/videofyBidAdapter.md deleted file mode 100644 index b50eaf5672e..00000000000 --- a/modules/videofyBidAdapter.md +++ /dev/null @@ -1,36 +0,0 @@ -# Overview - -``` -Module Name: Videofy Bidder Adapter -Module Type: Bidder Adapter -Maintainer: support1@videofy.ai -``` - -# Description - -Connects to Videofy for bids. - -Videofy bid adapter supports Video ads currently. - -# Sample Ad Unit: For Publishers -```javascript -var videoAdUnit = [ -{ - code: 'video1', - mediaTypes: { - video: { - playerSize: [[640, 480]], - context: 'outstream' - }, - }, - bids: [{ - bidder: 'videofy', - params: { - AV_PUBLISHERID: '55b78633181f4603178b4568', - AV_CHANNELID: '5d19dfca4b6236688c0a2fc4' - } - }] -}]; -``` - -``` diff --git a/modules/videoreachBidAdapter.js b/modules/videoreachBidAdapter.js deleted file mode 100644 index 710920c54fc..00000000000 --- a/modules/videoreachBidAdapter.js +++ /dev/null @@ -1,119 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -const utils = require('../src/utils.js'); -const BIDDER_CODE = 'videoreach'; -const ENDPOINT_URL = 'https://a.videoreach.com/hb/'; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: ['banner'], - - isBidRequestValid: function(bid) { - return !!(bid.params.TagId); - }, - - buildRequests: function(validBidRequests, bidderRequest) { - let data = { - data: validBidRequests.map(function(bid) { - return { - TagId: utils.getValue(bid.params, 'TagId'), - adUnitCode: utils.getBidIdParameter('adUnitCode', bid), - bidId: utils.getBidIdParameter('bidId', bid), - bidderRequestId: utils.getBidIdParameter('bidderRequestId', bid), - auctionId: utils.getBidIdParameter('auctionId', bid), - transactionId: utils.getBidIdParameter('transactionId', bid) - } - }) - }; - - if (bidderRequest && bidderRequest.refererInfo) { - data.referrer = bidderRequest.refererInfo.referer; - } - - if (bidderRequest && bidderRequest.gdprConsent) { - data.gdpr = { - consent_string: bidderRequest.gdprConsent.consentString, - consent_required: bidderRequest.gdprConsent.gdprApplies - }; - } - - return { - method: 'POST', - url: ENDPOINT_URL, - data: JSON.stringify(data) - }; - }, - - interpretResponse: function(serverResponse) { - const bidResponses = []; - serverResponse = serverResponse.body; - - if (serverResponse.responses) { - serverResponse.responses.forEach(function (bid) { - const bidResponse = { - cpm: bid.cpm, - width: bid.width, - height: bid.height, - currency: bid.currency, - netRevenue: true, - ttl: bid.ttl, - ad: bid.ad, - requestId: bid.bidId, - creativeId: bid.creativeId - }; - bidResponses.push(bidResponse); - }); - } - return bidResponses; - }, - - getUserSyncs: function(syncOptions, responses, gdprConsent) { - const syncs = []; - - if (responses.length && responses[0].body.responses.length) { - let params = ''; - var gdpr; - - if (gdprConsent && typeof gdprConsent.consentString === 'string') { - if (typeof gdprConsent.gdprApplies === 'boolean') { - params += 'gdpr=' + gdprConsent.gdprApplies + '&gdpr_consent=' + gdprConsent.consentString; - } else { - params += 'gdpr_consent=' + gdprConsent.consentString; - } - } - - if (syncOptions.pixelEnabled) { - const SyncPixels = responses[0].body.responses[0].sync; - - if (SyncPixels) { - SyncPixels.forEach(sync => { - gdpr = (params) ? ((sync.split('?')[1] ? '&' : '?') + params) : ''; - - syncs.push({ - type: 'image', - url: sync + gdpr - }); - }); - } - } - - if (syncOptions.iframeEnabled) { - const SyncFrame = responses[0].body.responses[0].syncframe; - - if (SyncFrame) { - SyncFrame.forEach(sync => { - gdpr = (params) ? ((sync.split('?')[1] ? '&' : '?') + params) : ''; - - syncs.push({ - type: 'iframe', - url: sync + gdpr - }); - }); - } - } - } - - return syncs; - } -}; - -registerBidder(spec); diff --git a/modules/videoreachBidAdapter.md b/modules/videoreachBidAdapter.md deleted file mode 100644 index a0bc1081b1d..00000000000 --- a/modules/videoreachBidAdapter.md +++ /dev/null @@ -1,32 +0,0 @@ -# Overview - -**Module Name**: Video Reach Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: hello@videoreach.com - -# Description - -Video Reach Bidder Adapter for Prebid.js. - -Use `videoreach` as bidder. - -`TagId` ist required. - -## AdUnits configuration example -``` - var adUnits = [{ - code: 'your-slot', //use exactly the same code as your slot div id. - mediaTypes: { - banner: { - sizes: [[1,1]] - } - }, - bids: [{ - bidder: 'videoreach', - params: { - TagId: 'XXXXX' - } - }] - }]; - -``` diff --git a/modules/viewdeosDXBidAdapter.js b/modules/viewdeosDXBidAdapter.js deleted file mode 100644 index 22c16ab5b34..00000000000 --- a/modules/viewdeosDXBidAdapter.js +++ /dev/null @@ -1,251 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {VIDEO, BANNER} from '../src/mediaTypes.js'; -import {Renderer} from '../src/Renderer.js'; -import findIndex from 'core-js-pure/features/array/find-index.js'; - -const URL = 'https://ghb.sync.viewdeos.com/auction/'; -const OUTSTREAM_SRC = 'https://player.sync.viewdeos.com/outstream-unit/2.01/outstream.min.js'; -const BIDDER_CODE = 'viewdeosDX'; -const OUTSTREAM = 'outstream'; -const DISPLAY = 'display'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['viewdeos'], - gvlid: 924, - supportedMediaTypes: [VIDEO, BANNER], - isBidRequestValid: function (bid) { - return !!utils.deepAccess(bid, 'params.aid'); - }, - getUserSyncs: function (syncOptions, serverResponses) { - const syncs = []; - - function addSyncs(bid) { - const uris = bid.cookieURLs; - const types = bid.cookieURLSTypes || []; - - if (Array.isArray(uris)) { - uris.forEach((uri, i) => { - const type = types[i] || 'image'; - - if ((!syncOptions.pixelEnabled && type === 'image') || - (!syncOptions.iframeEnabled && type === 'iframe')) { - return; - } - - syncs.push({ - type: type, - url: uri - }) - }) - } - } - - if (syncOptions.pixelEnabled || syncOptions.iframeEnabled) { - utils.isArray(serverResponses) && serverResponses.forEach((response) => { - if (response.body) { - if (utils.isArray(response.body)) { - response.body.forEach(b => { - addSyncs(b); - }) - } else { - addSyncs(response.body) - } - } - }) - } - return syncs; - }, - /** - * Make a server request from the list of BidRequests - * @param bidRequests - * @param bidderRequest - */ - buildRequests: function (bidRequests, bidderRequest) { - return { - data: bidToTag(bidRequests, bidderRequest), - bidderRequest, - method: 'GET', - url: URL - }; - }, - - /** - * Unpack the response from the server into a list of bids - * @param serverResponse - * @param bidderRequest - * @return {Bid[]} An array of bids which were nested inside the server - */ - interpretResponse: function (serverResponse, {bidderRequest}) { - serverResponse = serverResponse.body; - let bids = []; - - if (!utils.isArray(serverResponse)) { - return parseRTBResponse(serverResponse, bidderRequest); - } - - serverResponse.forEach(serverBidResponse => { - bids = utils.flatten(bids, parseRTBResponse(serverBidResponse, bidderRequest)); - }); - - return bids; - } -}; - -function parseRTBResponse(serverResponse, bidderRequest) { - const isInvalidValidResp = !serverResponse || !utils.isArray(serverResponse.bids); - - const bids = []; - - if (isInvalidValidResp) { - const extMessage = serverResponse && serverResponse.ext && serverResponse.ext.message ? `: ${serverResponse.ext.message}` : ''; - const errorMessage = `in response for ${bidderRequest.bidderCode} adapter ${extMessage}`; - - utils.logError(errorMessage); - - return bids; - } - - serverResponse.bids.forEach(serverBid => { - const requestId = findIndex(bidderRequest.bids, (bidRequest) => { - return bidRequest.bidId === serverBid.requestId; - }); - - if (serverBid.cpm !== 0 && requestId !== -1) { - const bidReq = bidderRequest.bids[requestId]; - const bid = createBid(serverBid, getMediaType(bidReq), bidReq.params); - - bids.push(bid); - } - }); - - return bids; -} - -function bidToTag(bidRequests, bidderRequest) { - const tag = { - domain: utils.deepAccess(bidderRequest, 'refererInfo.referer') - }; - - if (utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies')) { - tag.gdpr = 1; - tag.gdpr_consent = utils.deepAccess(bidderRequest, 'gdprConsent.consentString'); - } - - if (utils.deepAccess(bidderRequest, 'bidderRequest.uspConsent')) { - tag.us_privacy = bidderRequest.uspConsent; - } - - for (let i = 0, length = bidRequests.length; i < length; i++) { - Object.assign(tag, prepareRTBRequestParams(i, bidRequests[i])); - } - - return tag; -} - -/** - * Parse mediaType - * @param _index {number} - * @param bid {object} - * @returns {object} - */ -function prepareRTBRequestParams(_index, bid) { - const mediaType = utils.deepAccess(bid, 'mediaTypes.video') ? VIDEO : DISPLAY; - const index = !_index ? '' : `${_index + 1}`; - const sizes = bid.sizes ? bid.sizes : (mediaType === VIDEO ? utils.deepAccess(bid, 'mediaTypes.video.playerSize') : utils.deepAccess(bid, 'mediaTypes.banner.sizes')); - return { - ['callbackId' + index]: bid.bidId, - ['aid' + index]: bid.params.aid, - ['ad_type' + index]: mediaType, - ['sizes' + index]: utils.parseSizesInput(sizes).join() - }; -} - -/** - * Prepare all parameters for request - * @param bidderRequest {object} - * @returns {object} - */ -function getMediaType(bidderRequest) { - const videoMediaType = utils.deepAccess(bidderRequest, 'mediaTypes.video'); - const context = utils.deepAccess(bidderRequest, 'mediaTypes.video.context'); - - return !videoMediaType ? DISPLAY : context === OUTSTREAM ? OUTSTREAM : VIDEO; -} - -/** - * Configure new bid by response - * @param bidResponse {object} - * @param mediaType {Object} - * @returns {object} - */ -function createBid(bidResponse, mediaType, bidderParams) { - const bid = { - requestId: bidResponse.requestId, - creativeId: bidResponse.cmpId, - height: bidResponse.height, - currency: bidResponse.cur, - width: bidResponse.width, - cpm: bidResponse.cpm, - netRevenue: true, - mediaType, - ttl: 3600 - }; - - if (mediaType === DISPLAY) { - return Object.assign(bid, { - ad: bidResponse.ad - }); - } - - Object.assign(bid, { - vastUrl: bidResponse.vastUrl - }); - - if (mediaType === OUTSTREAM) { - Object.assign(bid, { - mediaType: 'video', - adResponse: bidResponse, - renderer: newRenderer(bidResponse.requestId, bidderParams) - }); - } - - return bid; -} - -/** - * Create renderer - * @param requestId - * @returns {*} - */ -function newRenderer(requestId, bidderParams) { - const renderer = Renderer.install({ - id: requestId, - url: OUTSTREAM_SRC, - config: bidderParams.outstream || {}, - loaded: false - }); - - renderer.setRender(outstreamRender); - - return renderer; -} - -/** - * Initialise outstream - * @param bid - */ -function outstreamRender(bid) { - bid.renderer.push(() => { - const opts = Object.assign({}, bid.renderer.getConfig(), { - width: bid.width, - height: bid.height, - vastUrl: bid.vastUrl, - elId: bid.adUnitCode - }); - window.VOutstreamAPI.initOutstreams([opts]); - }); -} - -registerBidder(spec); diff --git a/modules/viewdeosDXBidAdapter.md b/modules/viewdeosDXBidAdapter.md deleted file mode 100644 index a3fa34525b8..00000000000 --- a/modules/viewdeosDXBidAdapter.md +++ /dev/null @@ -1,64 +0,0 @@ -# Overview - -**Module Name**: Viewdeos DX Bidder Adapter -**Module Type**: Bidder Adapter - -# Description - -Get access to multiple demand partners across Viewdeos and maximize your yield with Viewdeos header bidding adapter. - -# Test Parameters -``` - var adUnits = [ - - // Video instream adUnit - { - code: 'div-test-div', - mediaTypes: { - video: { - context: 'instream', - playerSize: [[640, 480]] - } - }, - bids: [{ - bidder: 'viewdeosDX', - params: { - aid: 331133 - } - }] - }, - - // Video outstream adUnit - { - code: 'outstream-test-div', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [[640, 480]] - } - }, - bids: [{ - bidder: 'viewdeosDX', - params: { - aid: 331133, - outstream: { - default_volume:50, - video_controls:'show' - } - } - }] - }, - - // Banner adUnit - { - code: 'div-test-div', - sizes: [[300, 250]], - bids: [{ - bidder: 'viewdeosDX', - params: { - aid: 350975 - } - }] - } - ]; -``` diff --git a/modules/visxBidAdapter.js b/modules/visxBidAdapter.js deleted file mode 100644 index 63f4121724e..00000000000 --- a/modules/visxBidAdapter.js +++ /dev/null @@ -1,362 +0,0 @@ -import * as utils 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'; -const { parseSizesInput, getKeys, logError, deepAccess } = utils; -const BIDDER_CODE = 'visx'; -const BASE_URL = 'https://t.visx.net'; -const ENDPOINT_URL = BASE_URL + '/hb'; -const TIME_TO_LIVE = 360; -const DEFAULT_CUR = 'EUR'; -const ADAPTER_SYNC_URL = BASE_URL + '/push_sync'; -const TRACK_WIN_URL = BASE_URL + '/track/win'; -const TRACK_PENDING_URL = BASE_URL + '/track/pending'; -const TRACK_TIMEOUT_URL = BASE_URL + '/track/bid_timeout'; -const LOG_ERROR_MESS = { - noAuid: 'Bid from response has no auid parameter - ', - noAdm: 'Bid from response has no adm parameter - ', - noBid: 'Array of bid objects is empty', - noPlacementCode: 'Can\'t find in requested bids the bid with auid - ', - emptyUids: 'Uids should not be empty', - emptySeatbid: 'Seatbid array from response has an empty item', - emptyResponse: 'Response is empty', - hasEmptySeatbidArray: 'Response has empty seatbid array', - hasNoArrayOfBids: 'Seatbid from response has no array of bid objects - ', - notAllowedCurrency: 'Currency is not supported - ', - currencyMismatch: 'Currency from the request is not match currency from the response - ', - onlyVideoInstream: `Only video ${VIDEO_INSTREAM} supported`, - videoMissing: 'Bid request videoType property is missing - ' -}; -const currencyWhiteList = ['EUR', 'USD', 'GBP', 'PLN']; -const RE_EMPTY_OR_ONLY_COMMAS = /^,*$/; -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - isBidRequestValid: function(bid) { - if (_isVideoBid(bid)) { - if (!_isValidVideoBid(bid)) { - return false; - } - } - return !!bid.params.uid; - }, - buildRequests: function(validBidRequests, bidderRequest) { - const auids = []; - const bidsMap = {}; - const slotsMapByUid = {}; - const sizeMap = {}; - const bids = validBidRequests || []; - const currency = - config.getConfig(`currency.bidderCurrencyDefault.${BIDDER_CODE}`) || - config.getConfig('currency.adServerCurrency') || - DEFAULT_CUR; - let reqId; - let payloadSchain; - let payloadUserId; - const videoTypes = _initVideoTypes(bids); - - if (currencyWhiteList.indexOf(currency) === -1) { - logError(LOG_ERROR_MESS.notAllowedCurrency + currency); - return; - } - - bids.forEach(bid => { - reqId = bid.bidderRequestId; - const {params: {uid}, adUnitCode, schain, userId} = bid; - auids.push(uid); - if (!payloadSchain && schain) { - payloadSchain = schain; - } - if (!payloadUserId && userId) { - payloadUserId = userId; - } - const sizesId = parseSizesInput(bid.sizes); - - if (!slotsMapByUid[uid]) { - slotsMapByUid[uid] = {}; - } - const slotsMap = slotsMapByUid[uid]; - if (!slotsMap[adUnitCode]) { - slotsMap[adUnitCode] = {adUnitCode, bids: [bid], parents: []}; - } else { - slotsMap[adUnitCode].bids.push(bid); - } - const slot = slotsMap[adUnitCode]; - - sizesId.forEach((sizeId) => { - sizeMap[sizeId] = true; - if (!bidsMap[uid]) { - bidsMap[uid] = {}; - } - - if (!bidsMap[uid][sizeId]) { - bidsMap[uid][sizeId] = [slot]; - } else { - bidsMap[uid][sizeId].push(slot); - } - slot.parents.push({parent: bidsMap[uid], key: sizeId, uid}); - }); - }); - - const payload = { - pt: 'net', - auids: auids.join(','), - sizes: getKeys(sizeMap).join(','), - r: reqId, - cur: currency, - wrapperType: 'Prebid_js', - wrapperVersion: '$prebid.version$', - ...videoTypes - }; - - if (payloadSchain) { - payload.schain = JSON.stringify(payloadSchain); - } - - if (payloadUserId) { - if (payloadUserId.tdid) { - payload.tdid = payloadUserId.tdid; - } - if (payloadUserId.id5id && payloadUserId.id5id.uid) { - payload.id5 = payloadUserId.id5id.uid; - } - if (payloadUserId.digitrustid && payloadUserId.digitrustid.data && payloadUserId.digitrustid.data.id) { - payload.dtid = payloadUserId.digitrustid.data.id; - } - } - - if (bidderRequest) { - if (bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { - payload.u = bidderRequest.refererInfo.referer; - } - if (bidderRequest.gdprConsent) { - if (bidderRequest.gdprConsent.consentString) { - payload.gdpr_consent = bidderRequest.gdprConsent.consentString; - } - payload.gdpr_applies = - (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') - ? Number(bidderRequest.gdprConsent.gdprApplies) : 1; - } - } - - return { - method: 'GET', - url: ENDPOINT_URL, - data: payload, - bidsMap: bidsMap, - }; - }, - interpretResponse: function(serverResponse, bidRequest) { - serverResponse = serverResponse && serverResponse.body; - const bidResponses = []; - const bidsWithoutSizeMatching = []; - const bidsMap = bidRequest.bidsMap; - const currency = bidRequest.data.cur; - - let errorMessage; - - if (!serverResponse) errorMessage = LOG_ERROR_MESS.emptyResponse; - else if (serverResponse.seatbid && !serverResponse.seatbid.length) { - errorMessage = LOG_ERROR_MESS.hasEmptySeatbidArray; - } - - if (!errorMessage && serverResponse.seatbid) { - serverResponse.seatbid.forEach(respItem => { - _addBidResponse(_getBidFromResponse(respItem), bidsMap, currency, bidResponses, bidsWithoutSizeMatching); - }); - bidsWithoutSizeMatching.forEach(serverBid => { - _addBidResponse(serverBid, bidsMap, currency, bidResponses); - }); - } - if (errorMessage) logError(errorMessage); - return bidResponses; - }, - getUserSyncs: function(syncOptions, serverResponses, gdprConsent) { - if (syncOptions.pixelEnabled) { - var query = []; - if (gdprConsent) { - if (gdprConsent.consentString) { - query.push('gdpr_consent=' + encodeURIComponent(gdprConsent.consentString)); - } - query.push('gdpr_applies=' + encodeURIComponent( - (typeof gdprConsent.gdprApplies === 'boolean') - ? Number(gdprConsent.gdprApplies) : 1)); - } - return [{ - type: 'image', - url: ADAPTER_SYNC_URL + (query.length ? '?' + query.join('&') : '') - }]; - } - }, - onSetTargeting: function(bid) { - // Call '/track/pending' with the corresponding bid.requestId - utils.triggerPixel(TRACK_PENDING_URL + '?requestId=' + bid.requestId); - }, - onBidWon: function(bid) { - // Call '/track/win' with the corresponding bid.requestId - utils.triggerPixel(TRACK_WIN_URL + '?requestId=' + bid.requestId); - }, - onTimeout: function(timeoutData) { - // Call '/track/bid_timeout' with timeout data - utils.triggerPixel(TRACK_TIMEOUT_URL + '?data=' + JSON.stringify(timeoutData)); - } -}; - -function _getBidFromResponse(respItem) { - if (!respItem) { - logError(LOG_ERROR_MESS.emptySeatbid); - } else if (!respItem.bid) { - logError(LOG_ERROR_MESS.hasNoArrayOfBids + JSON.stringify(respItem)); - } else if (!respItem.bid[0]) { - logError(LOG_ERROR_MESS.noBid); - } - return respItem && respItem.bid && respItem.bid[0]; -} - -function _addBidResponse(serverBid, bidsMap, currency, bidResponses, bidsWithoutSizeMatching) { - if (!serverBid) return; - let errorMessage; - if (!serverBid.auid) errorMessage = LOG_ERROR_MESS.noAuid + JSON.stringify(serverBid); - if (!serverBid.adm) errorMessage = LOG_ERROR_MESS.noAdm + JSON.stringify(serverBid); - else { - const reqCurrency = currency || DEFAULT_CUR; - const awaitingBids = bidsMap[serverBid.auid]; - if (awaitingBids) { - if (serverBid.cur && serverBid.cur !== reqCurrency) { - errorMessage = LOG_ERROR_MESS.currencyMismatch + reqCurrency + ' - ' + serverBid.cur; - } else { - const sizeId = bidsWithoutSizeMatching ? `${serverBid.w}x${serverBid.h}` : Object.keys(awaitingBids)[0]; - if (awaitingBids[sizeId]) { - const slot = awaitingBids[sizeId][0]; - - const bid = slot.bids.shift(); - const bidResponse = { - requestId: bid.bidId, - cpm: serverBid.price, - width: serverBid.w, - height: serverBid.h, - creativeId: serverBid.auid, - currency: reqCurrency, - netRevenue: true, - ttl: TIME_TO_LIVE, - dealId: serverBid.dealid - }; - - if (!_isVideoBid(bid)) { - bidResponse.ad = serverBid.adm; - } else { - bidResponse.vastXml = serverBid.adm; - bidResponse.mediaType = 'video'; - } - - bidResponses.push(bidResponse); - - if (!slot.bids.length) { - slot.parents.forEach(({parent, key, uid}) => { - const index = parent[key].indexOf(slot); - if (index > -1) { - parent[key].splice(index, 1); - } - if (!parent[key].length) { - delete parent[key]; - if (!getKeys(parent).length) { - delete bidsMap[uid]; - } - } - }); - } - } else { - bidsWithoutSizeMatching && bidsWithoutSizeMatching.push(serverBid); - } - } - } else { - errorMessage = LOG_ERROR_MESS.noPlacementCode + serverBid.auid; - } - } - if (errorMessage) { - logError(errorMessage); - } -} - -function _isVideoBid(bid) { - return bid.mediaType === VIDEO || deepAccess(bid, 'mediaTypes.video'); -} - -function _isValidVideoBid(bid) { - let result = true; - const videoMediaType = deepAccess(bid, 'mediaTypes.video'); - if (videoMediaType.context !== VIDEO_INSTREAM) { - logError(LOG_ERROR_MESS.onlyVideoInstream) - result = false; - } - if (!(videoMediaType.playerSize && parseSizesInput(deepAccess(videoMediaType, 'playerSize', [])))) { - logError(LOG_ERROR_MESS.videoMissing + 'playerSize'); - result = false; - } - if (!videoMediaType.mimes) { - logError(LOG_ERROR_MESS.videoMissing + 'mimes'); - result = false; - } - if (!videoMediaType.protocols) { - logError(LOG_ERROR_MESS.videoMissing + 'protocols'); - result = false; - } - return result; -} - -function _initVideoTypes(bids) { - const result = {}; - let _playerSize = []; - let _protocols = []; - let _api = []; - let _mimes = []; - let _minduration = []; - let _maxduration = []; - let _skip = []; - if (bids && bids.length) { - bids.forEach(function (bid) { - const mediaTypes = deepAccess(bid, 'mediaTypes.video', {}); - _playerSize.push(parseSizesInput(deepAccess(mediaTypes, 'playerSize', [])).join('|')); - _protocols.push(deepAccess(mediaTypes, 'protocols', []).join('|')); - _api.push(deepAccess(mediaTypes, 'api', []).join('|')); - _mimes.push(deepAccess(mediaTypes, 'mimes', []).join('|')); - _minduration.push(deepAccess(mediaTypes, 'minduration', null)); - _maxduration.push(deepAccess(mediaTypes, 'maxduration', null)); - _skip.push(deepAccess(mediaTypes, 'skip', null)); - }); - } - _playerSize = _playerSize.join(','); - _protocols = _protocols.join(','); - _api = _api.join(','); - _mimes = _mimes.join(','); - _minduration = _minduration.join(','); - _maxduration = _maxduration.join(','); - _skip = _skip.join(','); - - if (!RE_EMPTY_OR_ONLY_COMMAS.test(_playerSize)) { - result.playerSize = _playerSize; - } - if (!RE_EMPTY_OR_ONLY_COMMAS.test(_protocols)) { - result.protocols = _protocols; - } - if (!RE_EMPTY_OR_ONLY_COMMAS.test(_api)) { - result.api = _api; - } - if (!RE_EMPTY_OR_ONLY_COMMAS.test(_mimes)) { - result.mimes = _mimes; - } - if (!RE_EMPTY_OR_ONLY_COMMAS.test(_minduration)) { - result.minduration = _minduration; - } - if (!RE_EMPTY_OR_ONLY_COMMAS.test(_maxduration)) { - result.maxduration = _maxduration; - } - if (!RE_EMPTY_OR_ONLY_COMMAS.test(_skip)) { - result.skip = _skip; - } - - return result; -} - -registerBidder(spec); diff --git a/modules/visxBidAdapter.md b/modules/visxBidAdapter.md deleted file mode 100644 index 9578f7cc4a7..00000000000 --- a/modules/visxBidAdapter.md +++ /dev/null @@ -1,71 +0,0 @@ -# Overview - -``` -Module Name: YOC VIS.X Bidder Adapter -Module Type: Bidder Adapter -Maintainer: service@yoc.com -``` - -# Description - -Module that connects to YOC VIS.X® demand source to fetch bids. - -# Test Parameters -```javascript -var adUnits = [ - // YOC Mystery Ad adUnit - { - code: 'yma-test-div', - mediaTypes: { - banner: { - sizes: [[1, 1]] - } - }, - bids: [ - { - bidder: 'visx', - params: { - uid: '903535' - } - } - ] - }, - // YOC Understitial Ad adUnit - { - code: 'yua-test-div', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [ - { - bidder: 'visx', - params: { - uid: '903536' - } - } - ] - }, - // YOC In-stream adUnit - { - code: 'instream-test-div', - mediaTypes: { - video: { - context: 'instream', - playerSize: [400, 300], - mimes: ['video/mp4'], - protocols: [3, 6] - }, - }, - bids: [ - { - bidder: 'visx', - params: { - uid: '921068' - } - } - ] - } -]; -``` diff --git a/modules/vmgBidAdapter.js b/modules/vmgBidAdapter.js deleted file mode 100644 index 57a812ec466..00000000000 --- a/modules/vmgBidAdapter.js +++ /dev/null @@ -1,86 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -const BIDDER_CODE = 'vmg'; -const ENDPOINT = 'https://predict.vmg.nyc'; - -export const spec = { - code: BIDDER_CODE, - /** - * Determines whether or not the given bid request is valid. - * - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bidRequest) { - if (typeof bidRequest !== 'undefined') { - return true; - } else { - return false; - } - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - let bidRequests = []; - let referer = window.location.href; - try { - referer = typeof bidderRequest.refererInfo === 'undefined' - ? window.top.location.href - : bidderRequest.refererInfo.referer; - } catch (e) {} - - validBidRequests.forEach(function(validBidRequest) { - bidRequests.push({ - adUnitCode: validBidRequest.adUnitCode, - referer: referer, - bidId: validBidRequest.bidId - }); - }); - - return { - method: 'POST', - url: ENDPOINT, - data: JSON.stringify(bidRequests) - }; - }, - /** - * Unpack the response from the server into a list of bids. - * - * Some required bid params are not needed for this so default - * values are used. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function (serverResponse, bidRequest) { - const validBids = JSON.parse(bidRequest.data); - let bidResponses = []; - if (typeof serverResponse.body !== 'undefined') { - const deals = serverResponse.body; - validBids.forEach(function(validBid) { - if (typeof deals[validBid.adUnitCode] !== 'undefined') { - const bidResponse = { - requestId: validBid.bidId, - ad: '
', - cpm: 0.01, - width: 0, - height: 0, - dealId: deals[validBid.adUnitCode], - ttl: 300, - creativeId: '1', - netRevenue: '0', - currency: 'USD' - }; - - bidResponses.push(bidResponse); - } - }); - } - - return bidResponses; - } -} - -registerBidder(spec); diff --git a/modules/vmgBidAdapter.md b/modules/vmgBidAdapter.md deleted file mode 100644 index 3ebfce91dee..00000000000 --- a/modules/vmgBidAdapter.md +++ /dev/null @@ -1,28 +0,0 @@ -# Overview - -``` -Module Name: VMG Bidder Adapter -Module Type: Bidder Adapter -Maintainer: paul@vmgood.com -``` - -# Description - -Connects DFP to the VMG Predict engine. - -# Test Parameters -``` - var adUnits = [{ - code: 'div-0', - mediaTypes: { - banner: { - sizes: sizes - } - }, - bids: [ - { - bidder: 'vmg' - } - ] - }]; -``` diff --git a/modules/voxBidAdapter.js b/modules/voxBidAdapter.js deleted file mode 100644 index 73df9bb8b9b..00000000000 --- a/modules/voxBidAdapter.js +++ /dev/null @@ -1,247 +0,0 @@ -import * as utils from '../src/utils.js' -import { registerBidder } from '../src/adapters/bidderFactory.js' -import {BANNER, VIDEO} from '../src/mediaTypes.js' -import find from 'core-js-pure/features/array/find.js'; -import {auctionManager} from '../src/auctionManager.js'; -import {Renderer} from '../src/Renderer.js'; - -const BIDDER_CODE = 'vox'; -const SSP_ENDPOINT = 'https://ssp.hybrid.ai/auction/prebid'; -const VIDEO_RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js'; -const TTL = 60; - -function buildBidRequests(validBidRequests) { - return utils._map(validBidRequests, function(validBidRequest) { - const params = validBidRequest.params; - const bidRequest = { - bidId: validBidRequest.bidId, - transactionId: validBidRequest.transactionId, - sizes: validBidRequest.sizes, - placement: params.placement, - placeId: params.placementId, - imageUrl: params.imageUrl - }; - - return bidRequest; - }) -} - -const outstreamRender = bid => { - bid.renderer.push(() => { - window.ANOutstreamVideo.renderAd({ - sizes: [bid.width, bid.height], - targetId: bid.adUnitCode, - rendererOptions: { - showBigPlayButton: false, - showProgressBar: 'bar', - showVolume: false, - allowFullscreen: true, - skippable: false, - content: bid.vastXml - } - }); - }); -} - -const createRenderer = (bid) => { - const renderer = Renderer.install({ - targetId: bid.adUnitCode, - url: VIDEO_RENDERER_URL, - loaded: false - }); - - try { - renderer.setRender(outstreamRender); - } catch (err) { - utils.logWarn('Prebid Error calling setRender on renderer', err); - } - - return renderer; -} - -function buildBid(bidData) { - const bid = { - requestId: bidData.bidId, - cpm: bidData.price, - width: bidData.content.width, - height: bidData.content.height, - creativeId: bidData.content.seanceId || bidData.bidId, - currency: bidData.currency, - netRevenue: true, - mediaType: BANNER, - ttl: TTL, - content: bidData.content - }; - - if (bidData.placement === 'video') { - bid.vastXml = bidData.content; - bid.mediaType = VIDEO; - - let adUnit = find(auctionManager.getAdUnits(), function (unit) { - return unit.transactionId === bidData.transactionId; - }); - - if (adUnit) { - bid.width = adUnit.mediaTypes.video.playerSize[0][0]; - bid.height = adUnit.mediaTypes.video.playerSize[0][1]; - - if (adUnit.mediaTypes.video.context === 'outstream') { - bid.renderer = createRenderer(bid); - } - } - } else if (bidData.placement === 'inImage') { - bid.mediaType = BANNER; - bid.ad = wrapInImageBanner(bid, bidData); - } else { - bid.mediaType = BANNER; - bid.ad = wrapBanner(bid, bidData); - } - - return bid; -} - -function getMediaTypeFromBid(bid) { - return bid.mediaTypes && Object.keys(bid.mediaTypes)[0]; -} - -function hasVideoMandatoryParams(mediaTypes) { - const isHasVideoContext = !!mediaTypes.video && (mediaTypes.video.context === 'instream' || mediaTypes.video.context === 'outstream'); - - const isPlayerSize = - !!utils.deepAccess(mediaTypes, 'video.playerSize') && - utils.isArray(utils.deepAccess(mediaTypes, 'video.playerSize')); - - return isHasVideoContext && isPlayerSize; -} - -function wrapInImageBanner(bid, bidData) { - return ` - - - - - - - - -
- - - `; -} - -function wrapBanner(bid, bidData) { - return ` - - - - - - - - -
- - - `; -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid(bid) { - return ( - !!bid.params.placementId && - !!bid.params.placement && - ( - (getMediaTypeFromBid(bid) === BANNER && bid.params.placement === 'banner') || - (getMediaTypeFromBid(bid) === BANNER && bid.params.placement === 'inImage' && !!bid.params.imageUrl) || - (getMediaTypeFromBid(bid) === VIDEO && bid.params.placement === 'video' && hasVideoMandatoryParams(bid.mediaTypes)) - ) - ); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests(validBidRequests, bidderRequest) { - const payload = { - url: bidderRequest.refererInfo.referer, - cmp: !!bidderRequest.gdprConsent, - bidRequests: buildBidRequests(validBidRequests) - }; - - if (payload.cmp) { - const gdprApplies = bidderRequest.gdprConsent.gdprApplies; - if (gdprApplies !== undefined) payload['ga'] = gdprApplies; - payload['cs'] = bidderRequest.gdprConsent.consentString; - } - - const payloadString = JSON.stringify(payload); - - return { - method: 'POST', - url: SSP_ENDPOINT, - data: payloadString, - options: { - contentType: 'application/json' - } - } - }, - - /** - * Unpack the 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. - */ - interpretResponse: function(serverResponse, bidRequest) { - let bidRequests = JSON.parse(bidRequest.data).bidRequests; - const serverBody = serverResponse.body; - - if (serverBody && serverBody.bids && utils.isArray(serverBody.bids)) { - return utils._map(serverBody.bids, function(bid) { - let rawBid = find(bidRequests, function (item) { - return item.bidId === bid.bidId; - }); - bid.placement = rawBid.placement; - bid.transactionId = rawBid.transactionId; - bid.placeId = rawBid.placeId; - return buildBid(bid); - }); - } else { - return []; - } - } - -} -registerBidder(spec); diff --git a/modules/voxBidAdapter.md b/modules/voxBidAdapter.md deleted file mode 100644 index 3fc0383e6f8..00000000000 --- a/modules/voxBidAdapter.md +++ /dev/null @@ -1,237 +0,0 @@ -# Overview - - -**Module Name**: VOX Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: prebid@hybrid.ai - -# Description - -You can use this adapter to get a bid from partners.hybrid.ai - - -## Sample Banner Ad Unit - -```js -var adUnits = [{ - code: 'banner_ad_unit', - mediaTypes: { - banner: { - sizes: [[160, 600]] - } - }, - bids: [{ - bidder: "vox", - params: { - placement: "banner", // required - placementId: "5fc77bc5a757531e24c89a4c" // required - } - }] -}]; -``` - -## Sample Video Ad Unit - -```js -var adUnits = [{ - code: 'video_ad_unit', - mediaTypes: { - video: { - context: 'outstream', // required - playerSize: [[640, 480]] // required - } - }, - bids: [{ - bidder: 'vox', - params: { - placement: "video", // required - placementId: "5fc77a94a757531e24c89a3d" // required - } - }] -}]; -``` - -# Sample In-Image Ad Unit - -```js -var adUnits = [{ - code: 'test-div', - mediaTypes: { - banner: { - sizes: [0, 0] - } - }, - bids: [{ - bidder: "vox", - params: { - placement: "inImage", - placementId: "5fc77b40a757531e24c89a42", - imageUrl: "https://gallery.voxexchange.io/vox-main.png" - } - }] -}]; -``` - -# Example page with In-Image - -```html - - - - - Prebid.js Banner Example - - - - - -

Prebid.js InImage Banner Test

-
- - -
- - -``` - -# Example page with In-Image and GPT - -```html - - - - - Prebid.js Banner Example - - - - - - -

Prebid.js Banner Ad Unit Test

-
- - -
- - -``` diff --git a/modules/vrtcalBidAdapter.js b/modules/vrtcalBidAdapter.js deleted file mode 100644 index ff24803f688..00000000000 --- a/modules/vrtcalBidAdapter.js +++ /dev/null @@ -1,88 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { BANNER } from '../src/mediaTypes.js'; -import {ajax} from '../src/ajax.js'; - -export const spec = { - code: 'vrtcal', - supportedMediaTypes: [BANNER], - isBidRequestValid: function (bid) { - if (bid.bidId == '' || bid.auctionId == '') { return false; } else { return true; }// No extras params required - }, - buildRequests: function (bidRequests) { - const requests = bidRequests.map(function (bid) { - const params = { - - prebidJS: 1, - prebidAdUnitCode: bid.adUnitCode, - id: bid.bidId, - imp: [{ - id: '1', - banner: { - }, - bidfloor: 0.75 - }], - site: { - id: 'VRTCAL_FILLED', - name: 'VRTCAL_FILLED', - cat: ['VRTCAL_FILLED'], - domain: decodeURIComponent(window.location.href).replace('https://', '').replace('http://', '').split('/')[0] - - }, - device: { - ua: 'VRTCAL_FILLED', - ip: 'VRTCAL_FILLED' - } - }; - - if (typeof (bid.mediaTypes) !== 'undefined' && typeof (bid.mediaTypes.banner) !== 'undefined' && typeof (bid.mediaTypes.banner.sizes) !== 'undefined') { - params.imp[0].banner.w = bid.mediaTypes.banner.sizes[0][0]; - params.imp[0].banner.h = bid.mediaTypes.banner.sizes[0][1]; - } else { - params.imp[0].banner.w = bid.sizes[0][0]; - params.imp[0].banner.h = bid.sizes[0][1]; - } - - return {method: 'POST', url: 'https://rtb.vrtcal.com/bidder_prebid.vap?ssp=1804', data: JSON.stringify(params), options: {withCredentials: false, crossOrigin: true}} - }); - - return requests; - }, - interpretResponse: function (serverResponse, bidRequest) { - if (!serverResponse || !serverResponse.body) { - return []; - } - - const bidResponses = []; - - var response = serverResponse.body; - - if (response) { - const bidResponse = { - requestId: response.id, - cpm: response.seatbid[0].bid[0].price, - width: response.seatbid[0].bid[0].w, - height: response.seatbid[0].bid[0].h, - creativeId: response.seatbid[0].bid[0].crid, - currency: 'USD', - netRevenue: true, - ttl: 900, - ad: response.seatbid[0].bid[0].adm, - nurl: response.seatbid[0].bid[0].nurl - }; - - bidResponses.push(bidResponse); - } - return bidResponses; - }, - onBidWon: function(bid) { - if (!bid.nurl) { return false; } - const winUrl = bid.nurl.replace( - /\$\{AUCTION_PRICE\}/, - bid.cpm - ); - ajax(winUrl, null); - return true; - } -}; - -registerBidder(spec); diff --git a/modules/vrtcalBidAdapter.md b/modules/vrtcalBidAdapter.md deleted file mode 100644 index 8d2809f7d5d..00000000000 --- a/modules/vrtcalBidAdapter.md +++ /dev/null @@ -1,30 +0,0 @@ -# Overview - -Module Name: Vrtcal Bidder Adapter -Module Type: Bidder Adapter -Maintainer: support@vrtcal.com - -# Description - -You can use this adapter to get a bid from vrtcal.com. - - -# Test Parameters -``` - var adUnits = [ - { - code: "vrtcal-test-adunit", - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [ - { - bidder: "vrtcal" - } - ] - } - ]; -``` -#Vrtcal requires no extra params passed, thus no params struct included diff --git a/modules/vubleAnalyticsAdapter.md b/modules/vubleAnalyticsAdapter.md deleted file mode 100644 index dfe0a8d8eb0..00000000000 --- a/modules/vubleAnalyticsAdapter.md +++ /dev/null @@ -1,23 +0,0 @@ -# Overview - -Module Name: Vuble Analytics Adapter - -Module Type: Vuble Analytics Adapter - -Maintainer: abruyere@mediabong.com - -# Description - -Analytics adapter for vuble.tv Contact contact@mediabong.com for information. - -# Test Parameters - -``` -{ - provider: 'vuble', - options: { - pubId: 18, // require - env: 'net', // require - } -} -``` diff --git a/modules/vubleBidAdapter.js b/modules/vubleBidAdapter.js deleted file mode 100644 index d14f24e9993..00000000000 --- a/modules/vubleBidAdapter.js +++ /dev/null @@ -1,198 +0,0 @@ -// Vuble Adapter - -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { Renderer } from '../src/Renderer.js'; - -const BIDDER_CODE = 'vuble'; - -const ENVS = ['com', 'net']; -const CURRENCIES = { - com: 'EUR', - net: 'USD' -}; -const TTL = 60; - -const outstreamRender = bid => { - bid.renderer.push(() => { - window.ANOutstreamVideo.renderAd({ - sizes: [bid.width, bid.height], - targetId: bid.adUnitCode, - adResponse: bid.adResponse, - rendererOptions: { - showBigPlayButton: false, - showProgressBar: 'bar', - showVolume: false, - allowFullscreen: true, - skippable: false, - } - }); - }); -} - -const createRenderer = (bid, serverResponse) => { - const renderer = Renderer.install({ - id: serverResponse.renderer_id, - url: serverResponse.renderer_url, - loaded: false, - }); - - try { - renderer.setRender(outstreamRender); - } catch (err) { - utils.logWarn('Prebid Error calling setRender on renderer', err); - } - - return renderer; -} - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: ['video'], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - let rawSizes = utils.deepAccess(bid, 'mediaTypes.video.playerSize') || bid.sizes; - if (utils.isEmpty(rawSizes) || utils.parseSizesInput(rawSizes).length == 0) { - return false; - } - - if (!utils.deepAccess(bid, 'mediaTypes.video.context')) { - return false; - } - - if (!utils.contains(ENVS, bid.params.env)) { - return false; - } - - return !!(bid.params.env && bid.params.pubId && bid.params.zoneId); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - return validBidRequests.map(bidRequest => { - // We take the first size - let rawSize = utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize') || bidRequest.sizes; - let size = utils.parseSizesInput(rawSize)[0].split('x'); - - // Get the page's url - let referer = (bidderRequest && bidderRequest.refererInfo) ? bidderRequest.refererInfo.referer : ''; - if (bidRequest.params.referrer) { - referer = bidRequest.params.referrer; - } - - // Get Video Context - let context = utils.deepAccess(bidRequest, 'mediaTypes.video.context'); - - let url = 'https://player.mediabong.' + bidRequest.params.env + '/prebid/request'; - let data = { - width: size[0], - height: size[1], - pub_id: bidRequest.params.pubId, - zone_id: bidRequest.params.zoneId, - context: context, - floor_price: bidRequest.params.floorPrice ? bidRequest.params.floorPrice : 0, - url: referer, - env: bidRequest.params.env, - bid_id: bidRequest.bidId, - adUnitCode: bidRequest.adUnitCode - }; - - if (bidderRequest && bidderRequest.gdprConsent) { - data.gdpr_consent = { - consent_string: bidderRequest.gdprConsent.consentString, - gdpr_applies: (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') ? bidderRequest.gdprConsent.gdprApplies : true - } - } - - return { - method: 'POST', - url: url, - data: data - }; - }); - }, - - /** - * Unpack the 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. - */ - interpretResponse: function (serverResponse, bidRequest) { - const responseBody = serverResponse.body; - - if (typeof responseBody !== 'object' || responseBody.status !== 'ok') { - return []; - } - - let bids = []; - let bid = { - requestId: bidRequest.data.bid_id, - cpm: responseBody.cpm, - width: bidRequest.data.width, - height: bidRequest.data.height, - ttl: TTL, - creativeId: responseBody.creativeId, - dealId: responseBody.dealId, - netRevenue: true, - currency: CURRENCIES[bidRequest.data.env], - vastUrl: responseBody.url, - mediaType: 'video' - }; - - if (responseBody.renderer_url) { - let adResponse = { - ad: { - video: { - content: responseBody.content - } - } - }; - - Object.assign(bid, { - adResponse: adResponse, - adUnitCode: bidRequest.data.adUnitCode, - renderer: createRenderer(bid, responseBody) - }); - } - - bids.push(bid); - - return bids; - }, - - /** - * Register the user sync pixels which should be dropped after the auction. - * - * @param {SyncOptions} syncOptions Which user syncs are allowed? - * @param {ServerResponse[]} serverResponses List of server's responses. - * @return {UserSync[]} The user syncs which should be dropped. - */ - getUserSyncs: function (syncOptions, serverResponses) { - if (syncOptions.iframeEnabled) { - if (serverResponses.length > 0) { - let responseBody = serverResponses[0].body; - if (typeof responseBody !== 'object' || responseBody.iframeSync) { - return [{ - type: 'iframe', - url: responseBody.iframeSync - }]; - } - } - } - return []; - } -}; - -registerBidder(spec); diff --git a/modules/vubleBidAdapter.md b/modules/vubleBidAdapter.md deleted file mode 100644 index 6bd8d3f779a..00000000000 --- a/modules/vubleBidAdapter.md +++ /dev/null @@ -1,58 +0,0 @@ -# Overview - -``` -Module Name: Vuble Bidder Adapter -Module Type: Vuble Adapter -Maintainer: gv@mediabong.com -``` - -# Description - -Module that connects to Vuble's demand sources - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-video-instream', - sizes: [[640, 360]], - mediaTypes: { - video: { - context: 'instream' - } - }, - bids: [ - { - bidder: "vuble", - params: { - env: 'net', - pubId: '18', - zoneId: '12345', - referrer: "http://www.vuble.tv/", // optional - floorPrice: 5.00 // optional - } - } - ] - }, - { - code: 'test-video-outstream', - sizes: [[640, 360]], - mediaTypes: { - video: { - context: 'outstream' - } - }, - bids: [ - { - bidder: "vuble", - params: { - env: 'net', - pubId: '18', - zoneId: '12345', - referrer: "http://www.vuble.tv/", // optional - floorPrice: 5.00 // optional - } - } - ] - } - ]; \ No newline at end of file diff --git a/modules/vuukleBidAdapter.js b/modules/vuukleBidAdapter.js deleted file mode 100644 index e9770b5e62e..00000000000 --- a/modules/vuukleBidAdapter.js +++ /dev/null @@ -1,63 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'vuukle'; -const URL = 'https://pb.vuukle.com/adapter'; -const TIME_TO_LIVE = 360; - -export const spec = { - code: BIDDER_CODE, - - isBidRequestValid: function(bid) { - return true - }, - - buildRequests: function(bidRequests) { - const requests = bidRequests.map(function (bid) { - const parseSized = utils.parseSizesInput(bid.sizes); - const arrSize = parseSized[0].split('x'); - const params = { - url: encodeURIComponent(window.location.href), - sizes: JSON.stringify(parseSized), - width: arrSize[0], - height: arrSize[1], - params: JSON.stringify(bid.params), - rnd: Math.random(), - bidId: bid.bidId, - source: 'pbjs', - version: '$prebid.version$', - v: 1, - }; - - return { - method: 'GET', - url: URL, - data: params, - options: {withCredentials: false} - } - }); - - return requests; - }, - - interpretResponse: function(serverResponse, bidRequest) { - if (!serverResponse || !serverResponse.body || !serverResponse.body.ad) { - return []; - } - - const res = serverResponse.body; - const bidResponse = { - requestId: bidRequest.data.bidId, - cpm: res.cpm, - width: res.width, - height: res.height, - creativeId: res.creative_id, - currency: res.currency || 'USD', - netRevenue: true, - ttl: TIME_TO_LIVE, - ad: res.ad - }; - return [bidResponse]; - }, -} -registerBidder(spec); diff --git a/modules/vuukleBidAdapter.md b/modules/vuukleBidAdapter.md deleted file mode 100644 index ee7b54c6262..00000000000 --- a/modules/vuukleBidAdapter.md +++ /dev/null @@ -1,26 +0,0 @@ -# Overview -``` -Module Name: Vuukle Bid Adapter -Module Type: Bidder Adapter -Maintainer: support@vuukle.com -``` - -# Description -Module that connects to Vuukle's server for bids. -Currently module supports only banner mediaType. - -# Test Parameters -``` - var adUnits = [{ - code: '/test/div', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [{ - bidder: 'vuukle', - params: {} - }] - }]; -``` diff --git a/modules/waardexBidAdapter.js b/modules/waardexBidAdapter.js deleted file mode 100644 index 1558ea39cd1..00000000000 --- a/modules/waardexBidAdapter.js +++ /dev/null @@ -1,295 +0,0 @@ -import {registerBidder} 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 find from 'core-js-pure/features/array/find.js'; - -const ENDPOINT = `https://hb.justbidit.xyz:8843/prebid`; -const BIDDER_CODE = 'waardex'; - -const isBidRequestValid = bid => { - if (!bid.bidId) { - utils.logError(BIDDER_CODE + ': bid.bidId should be non-empty'); - return false; - } - - if (!bid.params) { - utils.logError(BIDDER_CODE + ': bid.params should be non-empty'); - return false; - } - - if (!+bid.params.zoneId) { - utils.logError(BIDDER_CODE + ': bid.params.zoneId should be non-empty Number'); - return false; - } - - if (bid.mediaTypes && bid.mediaTypes.video) { - if (!bid.mediaTypes.video.playerSize) { - utils.logError(BIDDER_CODE + ': bid.mediaTypes.video.playerSize should be non-empty'); - return false; - } - - if (!utils.isArray(bid.mediaTypes.video.playerSize)) { - utils.logError(BIDDER_CODE + ': bid.mediaTypes.video.playerSize should be an Array'); - return false; - } - - if (!bid.mediaTypes.video.playerSize[0]) { - utils.logError(BIDDER_CODE + ': bid.mediaTypes.video.playerSize should be non-empty'); - return false; - } - - if (!utils.isArray(bid.mediaTypes.video.playerSize[0])) { - utils.logError(BIDDER_CODE + ': bid.mediaTypes.video.playerSize should be non-empty Array'); - return false; - } - } - - return true; -}; - -const buildRequests = (validBidRequests, bidderRequest) => { - const dataToSend = { - ...getCommonBidsData(bidderRequest), - bidRequests: getBidRequestsToSend(validBidRequests) - }; - - let zoneId = ''; - if (validBidRequests[0] && validBidRequests[0].params && +validBidRequests[0].params.zoneId) { - zoneId = +validBidRequests[0].params.zoneId; - } - - 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] : '', - }; - - if (bidderRequest && bidderRequest.refererInfo) { - payload.referer = encodeURIComponent(bidderRequest.refererInfo.referer); - } - - if (bidderRequest && bidderRequest.uspConsent) { - payload.us_privacy = bidderRequest.uspConsent; - } - - if (bidderRequest && bidderRequest.gdprConsent) { - payload.gdpr_consent = { - consent_string: bidderRequest.gdprConsent.consentString, - consent_required: bidderRequest.gdprConsent.gdprApplies, - } - } - - payload.coppa = !!config.getConfig('coppa'); - - return payload; -}; - -const getBidRequestsToSend = validBidRequests => { - return validBidRequests.map(getBidRequestToSend); -}; - -const getBidRequestToSend = validBidRequest => { - const result = { - bidId: validBidRequest.bidId, - bidfloor: parseFloat(validBidRequest.params.bidfloor) || 0, - position: parseInt(validBidRequest.params.position) || 1, - instl: parseInt(validBidRequest.params.instl) || 0, - }; - - if (validBidRequest.mediaTypes[BANNER]) { - result[BANNER] = createBannerObject(validBidRequest.mediaTypes[BANNER]); - } - - if (validBidRequest.mediaTypes[VIDEO]) { - result[VIDEO] = createVideoObject(validBidRequest.mediaTypes[VIDEO], validBidRequest.params); - } - - return result; -}; - -const createBannerObject = banner => { - return { - sizes: transformSizes(banner.sizes), - }; -}; - -const transformSizes = requestSizes => { - let result = []; - - if (Array.isArray(requestSizes) && !Array.isArray(requestSizes[0])) { - result[0] = { - width: parseInt(requestSizes[0], 10) || 0, - height: parseInt(requestSizes[1], 10) || 0, - }; - } else if (Array.isArray(requestSizes) && Array.isArray(requestSizes[0])) { - result = requestSizes.map(item => { - return { - width: parseInt(item[0], 10) || 0, - height: parseInt(item[1], 10) || 0, - } - }); - } - - return result; -}; - -const createVideoObject = (videoMediaTypes, videoParams) => { - return { - w: utils.deepAccess(videoMediaTypes, 'playerSize')[0][0], - h: utils.deepAccess(videoMediaTypes, 'playerSize')[0][1], - mimes: utils.getBidIdParameter('mimes', videoParams) || ['application/javascript', 'video/mp4', 'video/webm'], - minduration: utils.getBidIdParameter('minduration', videoParams) || 0, - maxduration: utils.getBidIdParameter('maxduration', videoParams) || 500, - protocols: utils.getBidIdParameter('protocols', videoParams) || [2, 3, 5, 6], - startdelay: utils.getBidIdParameter('startdelay', videoParams) || 0, - placement: utils.getBidIdParameter('placement', videoParams) || videoMediaTypes.context === 'outstream' ? 3 : 1, - skip: utils.getBidIdParameter('skip', videoParams) || 1, - skipafter: utils.getBidIdParameter('skipafter', videoParams) || 0, - minbitrate: utils.getBidIdParameter('minbitrate', videoParams) || 0, - maxbitrate: utils.getBidIdParameter('maxbitrate', videoParams) || 3500, - delivery: utils.getBidIdParameter('delivery', videoParams) || [2], - playbackmethod: utils.getBidIdParameter('playbackmethod', videoParams) || [1, 2, 3, 4], - api: utils.getBidIdParameter('api', videoParams) || [2], - linearity: utils.getBidIdParameter('linearity', videoParams) || 1 - }; -}; - -const interpretResponse = (serverResponse, bidRequest) => { - try { - const responseBody = serverResponse.body; - - if (!responseBody.seatbid || !responseBody.seatbid[0]) { - return []; - } - - return responseBody.seatbid[0].bid - .map(openRtbBid => { - const hbRequestBid = getHbRequestBid(openRtbBid, bidRequest.data); - if (!hbRequestBid) return; - - const hbRequestMediaType = getHbRequestMediaType(hbRequestBid); - if (!hbRequestMediaType) return; - - return mapOpenRtbToHbBid(openRtbBid, hbRequestMediaType, hbRequestBid); - }) - .filter(x => x); - } catch (e) { - return []; - } -}; - -const getHbRequestBid = (openRtbBid, bidRequest) => { - return find(bidRequest.bidRequests, x => x.bidId === openRtbBid.impid); -}; - -const getHbRequestMediaType = hbRequestBid => { - if (hbRequestBid.banner) return BANNER; - if (hbRequestBid.video) return VIDEO; - return null; -}; - -const mapOpenRtbToHbBid = (openRtbBid, mediaType, hbRequestBid) => { - let bid = null; - - if (mediaType === BANNER) { - bid = mapOpenRtbBannerToHbBid(openRtbBid, hbRequestBid); - } - - if (mediaType === VIDEO) { - bid = mapOpenRtbVideoToHbBid(openRtbBid, hbRequestBid); - } - - return isBidValid(bid) ? bid : null; -}; - -const mapOpenRtbBannerToHbBid = (openRtbBid, hbRequestBid) => { - return { - mediaType: BANNER, - requestId: hbRequestBid.bidId, - cpm: openRtbBid.price, - currency: 'USD', - width: openRtbBid.w, - height: openRtbBid.h, - creativeId: openRtbBid.crid, - netRevenue: true, - ttl: 3000, - ad: openRtbBid.adm, - dealId: openRtbBid.dealid, - meta: { - cid: openRtbBid.cid, - adomain: openRtbBid.adomain, - mediaType: openRtbBid.ext && openRtbBid.ext.mediaType - }, - }; -}; - -const mapOpenRtbVideoToHbBid = (openRtbBid, hbRequestBid) => { - return { - mediaType: VIDEO, - requestId: hbRequestBid.bidId, - cpm: openRtbBid.price, - currency: 'USD', - width: hbRequestBid.video.w, - height: hbRequestBid.video.h, - ad: openRtbBid.adm, - ttl: 3000, - creativeId: openRtbBid.crid, - netRevenue: true, - vastUrl: getVastUrl(openRtbBid), - // An impression tracking URL to serve with video Ad - // Optional; only usable with vastUrl and requires prebid cache to be enabled - // Example: "https://vid.exmpale.com/imp/134" - // For now we don't need this field - // vastImpUrl: null, - vastXml: openRtbBid.adm, - dealId: openRtbBid.dealid, - meta: { - cid: openRtbBid.cid, - adomain: openRtbBid.adomain, - networkId: null, - networkName: null, - agencyId: null, - agencyName: null, - advertiserId: null, - advertiserName: null, - advertiserDomains: null, - brandId: null, - brandName: null, - primaryCatId: null, - secondaryCatIds: null, - mediaType: 'video', - }, - } -}; - -const getVastUrl = openRtbBid => { - const adm = (openRtbBid.adm || '').trim(); - - if (adm.startsWith('http')) { - return adm; - } else { - return null - } -}; - -const isBidValid = bid => { - if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) { - return false; - } - - return Boolean(bid.width && bid.height && bid.ad); -}; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - isBidRequestValid, - buildRequests, - interpretResponse, -}; - -registerBidder(spec); diff --git a/modules/waardexBidAdapter.md b/modules/waardexBidAdapter.md deleted file mode 100644 index 8eade8409f4..00000000000 --- a/modules/waardexBidAdapter.md +++ /dev/null @@ -1,93 +0,0 @@ -# Overview - -``` -Module Name: Waardex Bid Adapter -Module Type: Bidder Adapter -Maintainer: info@prebid.org -``` - -# Description - -Connects to Waardex exchange for bids. - -Waardex bid adapter supports Banner and Video. - -# Test Parameters -## Banner -```javascript -var sizes = [ - [300, 250] -]; -var PREBID_TIMEOUT = 5000; -var FAILSAFE_TIMEOUT = 5000; - -var adUnits = [ - { - code: '/19968336/header-bid-tag-0', - mediaTypes: { - banner: { - sizes: sizes - } - }, - bids: [ - { - bidder: 'waardex', - params: { - bidfloor: 1.5, - position: 1, - instl: 1, - zoneId: 1 - } - } - ] - } -]; -``` - -## Video - -```javascript -const PREBID_TIMEOUT = 1000; -const FAILSAFE_TIMEOUT = 3000; - -const sizes = [ - [640, 480] -]; - -const adUnits = [ - { - code: 'video1', - mediaTypes: { - video: { - context: 'instream', - playerSize: sizes[0] - } - }, - bids: [ - { - bidder: 'waardex', - params: { - bidfloor: 1.5, - position: 1, - instl: 1, - zoneId: 1, - mimes: ['video/x-ms-wmv', 'video/mp4'], - minduration: 2, - maxduration: 10, - protocols: ['VAST 1.0', 'VAST 2.0'], - startdelay: -1, - placement: 1, - skip: 1, - skipafter: 2, - minbitrate: 0, - maxbitrate: 0, - delivery: [1, 2, 3], - playbackmethod: [1, 2], - api: [1, 2, 3, 4, 5, 6], - linearity: 1, - } - } - ] - } -] -``` diff --git a/modules/weboramaBidAdapter.md b/modules/weboramaBidAdapter.md deleted file mode 100644 index 5bdca0bfcd1..00000000000 --- a/modules/weboramaBidAdapter.md +++ /dev/null @@ -1,27 +0,0 @@ -# Overview - -``` -Module Name: Weborama SSP Bidder Adapter -Module Type: Bidder Adapter -Maintainer: devweborama@gmail.com -``` - -# Description - -Module that connects to Weborama SSP demand sources - -# Test Parameters -``` - var adUnits = [{ - code: 'placementCode', - sizes: [[300, 250]], - bids: [{ - bidder: 'weborama', - params: { - placementId: 0, - traffic: 'banner' - } - }] - } - ]; -``` diff --git a/modules/welectBidAdapter.js b/modules/welectBidAdapter.js deleted file mode 100644 index 467b628c944..00000000000 --- a/modules/welectBidAdapter.js +++ /dev/null @@ -1,92 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'welect'; -const DEFAULT_DOMAIN = 'www.welect.de'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['wlt'], - gvlid: 282, - supportedMediaTypes: ['video'], - - // short code - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return ( - utils.deepAccess(bid, 'mediaTypes.video.context') === 'instream' && - !!bid.params.placementId - ); - }, - /** - * Make a server request from the list of BidRequests. - * - * @param {validBidRequests[]} - an array of bids - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (validBidRequests) { - return validBidRequests.map((bidRequest) => { - let rawSizes = - utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize') || - bidRequest.sizes; - let size = rawSizes[0]; - - let domain = bidRequest.params.domain || DEFAULT_DOMAIN; - - let url = `https://${domain}/api/v2/preflight/${bidRequest.params.placementId}`; - - let gdprConsent = null; - - if (bidRequest && bidRequest.gdprConsent) { - gdprConsent = { - gdpr_consent: { - gdprApplies: bidRequest.gdprConsent.gdprApplies, - tcString: bidRequest.gdprConsent.gdprConsent, - }, - }; - } - - const data = { - width: size[0], - height: size[1], - bid_id: bidRequest.bidId, - ...gdprConsent, - }; - - return { - method: 'POST', - url: url, - data: data, - options: { - contentType: 'application/json', - withCredentials: false, - crossOrigin: true, - }, - }; - }); - }, - /** - * Unpack the 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. - */ - interpretResponse: function (serverResponse, bidRequest) { - const responseBody = serverResponse.body; - - if (typeof responseBody !== 'object' || responseBody.available !== true) { - return []; - } - - const bidResponses = []; - const bidResponse = responseBody.bidResponse; - bidResponses.push(bidResponse); - return bidResponses; - }, -}; -registerBidder(spec); diff --git a/modules/welectBidAdapter.md b/modules/welectBidAdapter.md deleted file mode 100644 index 7f72a0bd949..00000000000 --- a/modules/welectBidAdapter.md +++ /dev/null @@ -1,30 +0,0 @@ -# Overview - -``` -Module Name: Welect Bidder Adapter -Module Type: Welect Adapter -Maintainer: nick.duitz@9elements.com -``` - -# Description - -Module that connects to Welect's demand sources - -# Test Parameters -``` -var adUnits = [ - { - bidder: 'welect', - params: { - placementId: 'exampleId', - domain: 'www.welect.de' - }, - sizes: [[640, 360]], - mediaTypes: { - video: { - context: 'instream' - } - }, - }; -]; -``` \ No newline at end of file diff --git a/modules/widespaceBidAdapter.js b/modules/widespaceBidAdapter.js deleted file mode 100644 index 3cea5ca57a1..00000000000 --- a/modules/widespaceBidAdapter.js +++ /dev/null @@ -1,258 +0,0 @@ -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { - parseQueryStringParameters, - parseSizesInput -} from '../src/utils.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import find from 'core-js-pure/features/array/find.js'; -import { getStorageManager } from '../src/storageManager.js'; - -export const storage = getStorageManager(); - -const BIDDER_CODE = 'widespace'; -const WS_ADAPTER_VERSION = '2.0.1'; -const LS_KEYS = { - PERF_DATA: 'wsPerfData', - LC_UID: 'wsLcuid', - CUST_DATA: 'wsCustomData' -}; - -let preReqTime = 0; - -export const spec = { - code: BIDDER_CODE, - - supportedMediaTypes: ['banner'], - - isBidRequestValid: function (bid) { - if (bid.params && bid.params.sid) { - return true; - } - return false; - }, - - buildRequests: function (validBidRequests, bidderRequest) { - let serverRequests = []; - const REQUEST_SERVER_URL = getEngineUrl(); - const DEMO_DATA_PARAMS = ['gender', 'country', 'region', 'postal', 'city', 'yob']; - const PERF_DATA = getData(LS_KEYS.PERF_DATA).map(perfData => JSON.parse(perfData)); - const CUST_DATA = getData(LS_KEYS.CUST_DATA, false)[0]; - const LC_UID = getLcuid(); - - let isInHostileIframe = false; - try { - window.top.location.toString(); - isInHostileIframe = false; - } catch (e) { - isInHostileIframe = true; - } - - validBidRequests.forEach((bid, i) => { - let data = { - 'screenWidthPx': screen && screen.width, - 'screenHeightPx': screen && screen.height, - 'adSpaceHttpRefUrl': getTopWindowReferrer(), - 'referer': (isInHostileIframe ? window : window.top).location.href.split('#')[0], - 'inFrame': 1, - 'sid': bid.params.sid, - 'lcuid': LC_UID, - 'vol': isInHostileIframe ? '' : visibleOnLoad(document.getElementById(bid.adUnitCode)), - 'gdprCmp': bidderRequest && bidderRequest.gdprConsent ? 1 : 0, - 'hb': '1', - 'hb.cd': CUST_DATA ? encodedParamValue(CUST_DATA) : '', - 'hb.floor': bid.bidfloor || '', - 'hb.spb': i === 0 ? pixelSyncPossibility() : -1, - 'hb.ver': WS_ADAPTER_VERSION, - 'hb.name': 'prebidjs-$prebid.version$', - 'hb.bidId': bid.bidId, - 'hb.sizes': parseSizesInput(bid.sizes).join(','), - 'hb.currency': bid.params.cur || bid.params.currency || '' - }; - - // Include demo data - if (bid.params.demo) { - DEMO_DATA_PARAMS.forEach((key) => { - if (bid.params.demo[key]) { - data[key] = bid.params.demo[key]; - } - }); - } - - // Include performance data - if (PERF_DATA[i]) { - Object.keys(PERF_DATA[i]).forEach((perfDataKey) => { - data[perfDataKey] = PERF_DATA[i][perfDataKey]; - }); - } - - // Include connection info if available - const CONNECTION = navigator.connection || navigator.webkitConnection; - if (CONNECTION && CONNECTION.type && CONNECTION.downlinkMax) { - data['netinfo.type'] = CONNECTION.type; - data['netinfo.downlinkMax'] = CONNECTION.downlinkMax; - } - - // Include debug data when available - if (!isInHostileIframe) { - const DEBUG_AD = (find(window.top.location.hash.split('&'), - val => includes(val, 'WS_DEBUG_FORCEADID') - ) || '').split('=')[1]; - data.forceAdId = DEBUG_AD; - } - - // GDPR Consent info - if (data.gdprCmp) { - const {gdprApplies, consentString, vendorData} = bidderRequest.gdprConsent; - const hasGlobalScope = vendorData && vendorData.hasGlobalScope; - data.gdprApplies = gdprApplies ? 1 : gdprApplies === undefined ? '' : 0; - data.gdprConsentData = consentString; - data.gdprHasGlobalScope = hasGlobalScope ? 1 : hasGlobalScope === undefined ? '' : 0; - } - - // Remove empty params - Object.keys(data).forEach((key) => { - if (data[key] === '' || data[key] === undefined) { - delete data[key]; - } - }); - - serverRequests.push({ - method: 'POST', - options: { - contentType: 'application/x-www-form-urlencoded' - }, - url: REQUEST_SERVER_URL, - data: parseQueryStringParameters(data) - }); - }); - preReqTime = Date.now(); - return serverRequests; - }, - - interpretResponse: function (serverResponse, request) { - const responseTime = Date.now() - preReqTime; - const successBids = serverResponse.body || []; - let bidResponses = []; - successBids.forEach((bid) => { - storeData({ - 'perf_status': 'OK', - 'perf_reqid': bid.reqId, - 'perf_ms': responseTime - }, `${LS_KEYS.PERF_DATA}${bid.reqId}`); - if (bid.status === 'ad') { - bidResponses.push({ - requestId: bid.bidId, - cpm: bid.cpm, - width: bid.width, - height: bid.height, - creativeId: bid.adId, - currency: bid.currency, - netRevenue: Boolean(bid.netRev), - ttl: bid.ttl, - referrer: getTopWindowReferrer(), - ad: bid.code - }); - } - }); - - return bidResponses - }, - - getUserSyncs: function (syncOptions, serverResponses = []) { - let userSyncs = []; - userSyncs = serverResponses.reduce((allSyncPixels, response) => { - if (response && response.body && response.body[0]) { - (response.body[0].syncPixels || []).forEach((url) => { - allSyncPixels.push({type: 'image', url}); - }); - } - return allSyncPixels; - }, []); - return userSyncs; - } -}; - -function storeData(data, name, stringify = true) { - const value = stringify ? JSON.stringify(data) : data; - if (storage.hasLocalStorage()) { - storage.setDataInLocalStorage(name, value); - return true; - } else if (storage.cookiesAreEnabled()) { - const theDate = new Date(); - const expDate = new Date(theDate.setMonth(theDate.getMonth() + 12)).toGMTString(); - storage.setCookie(name, value, expDate); - return true; - } -} - -function getData(name, remove = true) { - let data = []; - if (storage.hasLocalStorage()) { - Object.keys(localStorage).filter((key) => { - if (key.indexOf(name) > -1) { - data.push(storage.getDataFromLocalStorage(key)); - if (remove) { - storage.removeDataFromLocalStorage(key); - } - } - }); - } - - if (storage.cookiesAreEnabled()) { - document.cookie.split(';').forEach((item) => { - let value = item.split('='); - if (value[0].indexOf(name) > -1) { - data.push(value[1]); - if (remove) { - storage.setCookie(value[0], '', 'Thu, 01 Jan 1970 00:00:01 GMT'); - } - } - }); - } - return data; -} - -function pixelSyncPossibility() { - const userSync = config.getConfig('userSync'); - return userSync && userSync.pixelEnabled && userSync.syncEnabled ? userSync.syncsPerBidder : -1; -} - -function visibleOnLoad(element) { - if (element && element.getBoundingClientRect) { - const topPos = element.getBoundingClientRect().top; - return topPos < screen.height && topPos >= window.top.pageYOffset ? 1 : 0; - } - ; - return ''; -} - -function getLcuid() { - let lcuid = getData(LS_KEYS.LC_UID, false)[0]; - if (!lcuid) { - const random = ('4' + new Date().getTime() + String(Math.floor(Math.random() * 1000000000))).substring(0, 18); - storeData(random, LS_KEYS.LC_UID, false); - lcuid = getData(LS_KEYS.LC_UID, false)[0]; - } - return lcuid; -} - -function encodedParamValue(value) { - const requiredStringify = typeof JSON.parse(JSON.stringify(value)) === 'object'; - return encodeURIComponent(requiredStringify ? JSON.stringify(value) : value); -} - -function getEngineUrl() { - const ENGINE_URL = 'https://engine.widespace.com/map/engine/dynadreq'; - return window.wisp && window.wisp.ENGINE_URL ? window.wisp.ENGINE_URL : ENGINE_URL; -} - -function getTopWindowReferrer() { - try { - return window.top.document.referrer; - } catch (e) { - return ''; - } -} - -registerBidder(spec); diff --git a/modules/widespaceBidAdapter.md b/modules/widespaceBidAdapter.md deleted file mode 100644 index 1ca2b61d406..00000000000 --- a/modules/widespaceBidAdapter.md +++ /dev/null @@ -1,40 +0,0 @@ -# Overview - - -**Module Name:** Widespace Bidder Adapter. -**Module Type:** Bidder Adapter. -**Maintainer:** support@widespace.com - - -# Description - -Widespace Bidder Adapter for Prebid.js. -Banner and video formats are supported. - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - sizes: [[300, 250], [300, 300]], - bids: [ - { - bidder: 'widespace', - params: { - sid: '7b6589bf-95c8-4656-90b9-af9737bb9ad3', // Required - currency: 'EUR', // Optional - bidfloor: '0.5', // Optional - demo: { // Optional - gender: 'M', - country: 'Sweden', - region: 'Stockholm', - postal: '15115', - city: 'Stockholm', - yob: '1984' - } - } - } - ] - } - ]; -``` diff --git a/modules/windtalkerBidAdapter.js b/modules/windtalkerBidAdapter.js deleted file mode 100644 index 512cc7f839b..00000000000 --- a/modules/windtalkerBidAdapter.js +++ /dev/null @@ -1,307 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -const NATIVE_DEFAULTS = { - TITLE_LEN: 100, - DESCR_LEN: 200, - SPONSORED_BY_LEN: 50, - IMG_MIN: 150, - ICON_MIN: 50, -}; -const DEFAULT_MIMES = ['video/mp4', 'video/webm', 'application/x-shockwave-flash', 'application/javascript']; -const VIDEO_TARGETING = ['mimes', 'skippable', 'playback_method', 'protocols', 'api']; -const DEFAULT_PROTOCOLS = [2, 3, 5, 6]; -const DEFAULT_APIS = [1, 2]; - -export const spec = { - - code: 'windtalker', - supportedMediaTypes: ['banner', 'native', 'video'], - - isBidRequestValid: bid => ( - !!(bid && bid.params && bid.params.pubId && bid.params.placementId) - ), - buildRequests: (bidRequests, bidderRequest) => { - const request = { - id: bidRequests[0].bidderRequestId, - at: 2, - imp: bidRequests.map(slot => impression(slot)), - site: site(bidRequests), - app: app(bidRequests), - device: device(bidRequests), - }; - applyGdpr(bidderRequest, request); - return { - method: 'POST', - url: 'https://windtalkerdisplay.hb.adp3.net/', - data: JSON.stringify(request), - }; - }, - interpretResponse: (response, request) => ( - bidResponseAvailable(request, response.body) - ), -}; - -function bidResponseAvailable(bidRequest, bidResponse) { - const idToImpMap = {}; - const idToBidMap = {}; - const ortbRequest = parse(bidRequest.data); - ortbRequest.imp.forEach(imp => { - idToImpMap[imp.id] = imp; - }); - if (bidResponse) { - bidResponse.seatbid.forEach(seatBid => seatBid.bid.forEach(bid => { - idToBidMap[bid.impid] = bid; - })); - } - const bids = []; - Object.keys(idToImpMap).forEach(id => { - if (idToBidMap[id]) { - const bid = {}; - bid.requestId = id; - bid.adId = id; - bid.creativeId = id; - bid.cpm = idToBidMap[id].price; - bid.currency = bidResponse.cur; - bid.ttl = 360; - bid.netRevenue = true; - if (idToImpMap[id]['native']) { - bid['native'] = nativeResponse(idToImpMap[id], idToBidMap[id]); - let nurl = idToBidMap[id].nurl; - nurl = nurl.replace(/\$(%7B|\{)AUCTION_IMP_ID(%7D|\})/gi, idToBidMap[id].impid); - nurl = nurl.replace(/\$(%7B|\{)AUCTION_PRICE(%7D|\})/gi, idToBidMap[id].price); - nurl = nurl.replace(/\$(%7B|\{)AUCTION_CURRENCY(%7D|\})/gi, bidResponse.cur); - nurl = nurl.replace(/\$(%7B|\{)AUCTION_BID_ID(%7D|\})/gi, bidResponse.bidid); - bid['native']['impressionTrackers'] = [nurl]; - bid.mediaType = 'native'; - } else if (idToImpMap[id]['video']) { - bid.vastUrl = idToBidMap[id].adm; - bid.vastUrl = bid.vastUrl.replace(/\$(%7B|\{)AUCTION_PRICE(%7D|\})/gi, idToBidMap[id].price); - bid.crid = idToBidMap[id].crid; - bid.width = idToImpMap[id].video.w; - bid.height = idToImpMap[id].video.h; - bid.mediaType = 'video'; - } else if (idToImpMap[id]['banner']) { - bid.ad = idToBidMap[id].adm; - bid.ad = bid.ad.replace(/\$(%7B|\{)AUCTION_IMP_ID(%7D|\})/gi, idToBidMap[id].impid); - bid.ad = bid.ad.replace(/\$(%7B|\{)AUCTION_AD_ID(%7D|\})/gi, idToBidMap[id].adid); - bid.ad = bid.ad.replace(/\$(%7B|\{)AUCTION_PRICE(%7D|\})/gi, idToBidMap[id].price); - bid.ad = bid.ad.replace(/\$(%7B|\{)AUCTION_CURRENCY(%7D|\})/gi, bidResponse.cur); - bid.ad = bid.ad.replace(/\$(%7B|\{)AUCTION_BID_ID(%7D|\})/gi, bidResponse.bidid); - bid.width = idToBidMap[id].w; - bid.height = idToBidMap[id].h; - bid.mediaType = 'banner'; - } - bids.push(bid); - } - }); - return bids; -} -function impression(slot) { - return { - id: slot.bidId, - secure: window.location.protocol === 'https:' ? 1 : 0, - 'banner': banner(slot), - 'native': nativeImpression(slot), - 'video': videoImpression(slot), - bidfloor: slot.params.bidFloor || '0.000001', - tagid: slot.params.placementId.toString(), - }; -} - -function banner(slot) { - if (slot.mediaType === 'banner' || utils.deepAccess(slot, 'mediaTypes.banner')) { - const sizes = utils.deepAccess(slot, 'mediaTypes.banner.sizes'); - if (sizes.length > 1) { - let format = []; - for (let f = 0; f < sizes.length; f++) { - format.push({'w': sizes[f][0], 'h': sizes[f][1]}); - } - return {'format': format}; - } else { - return { - w: sizes[0][0], - h: sizes[0][1] - } - } - } - return null; -} - -function videoImpression(slot) { - if (slot.mediaType === 'video' || utils.deepAccess(slot, 'mediaTypes.video')) { - const sizes = utils.deepAccess(slot, 'mediaTypes.video.playerSize'); - const video = { - w: sizes[0][0], - h: sizes[0][1], - mimes: DEFAULT_MIMES, - protocols: DEFAULT_PROTOCOLS, - api: DEFAULT_APIS, - }; - if (slot.params.video) { - Object.keys(slot.params.video).filter(param => includes(VIDEO_TARGETING, param)).forEach(param => video[param] = slot.params.video[param]); - } - return video; - } - return null; -} - -function nativeImpression(slot) { - if (slot.mediaType === 'native' || utils.deepAccess(slot, 'mediaTypes.native')) { - const assets = []; - addAsset(assets, titleAsset(1, slot.nativeParams.title, NATIVE_DEFAULTS.TITLE_LEN)); - addAsset(assets, dataAsset(2, slot.nativeParams.body, 2, NATIVE_DEFAULTS.DESCR_LEN)); - addAsset(assets, dataAsset(3, slot.nativeParams.sponsoredBy, 1, NATIVE_DEFAULTS.SPONSORED_BY_LEN)); - addAsset(assets, imageAsset(4, slot.nativeParams.icon, 1, NATIVE_DEFAULTS.ICON_MIN, NATIVE_DEFAULTS.ICON_MIN)); - addAsset(assets, imageAsset(5, slot.nativeParams.image, 3, NATIVE_DEFAULTS.IMG_MIN, NATIVE_DEFAULTS.IMG_MIN)); - return { - request: JSON.stringify({ assets }), - ver: '1.1', - }; - } - return null; -} - -function addAsset(assets, asset) { - if (asset) { - assets.push(asset); - } -} - -function titleAsset(id, params, defaultLen) { - if (params) { - return { - id, - required: params.required ? 1 : 0, - title: { - len: params.len || defaultLen, - }, - }; - } - return null; -} - -function imageAsset(id, params, type, defaultMinWidth, defaultMinHeight) { - return params ? { - id, - required: params.required ? 1 : 0, - img: { - type, - wmin: params.wmin || defaultMinWidth, - hmin: params.hmin || defaultMinHeight, - } - } : null; -} - -function dataAsset(id, params, type, defaultLen) { - return params ? { - id, - required: params.required ? 1 : 0, - data: { - type, - len: params.len || defaultLen, - } - } : null; -} - -function site(bidderRequest) { - const pubId = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.pubId : '0'; - const siteId = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.siteId : '0'; - const appParams = bidderRequest[0].params.app; - if (!appParams) { - return { - publisher: { - id: pubId.toString(), - domain: window.location.hostname, - }, - id: siteId.toString(), - ref: window.top.document.referrer, - page: window.location.href, - } - } - return null; -} - -function app(bidderRequest) { - const pubId = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.pubId : '0'; - const appParams = bidderRequest[0].params.app; - if (appParams) { - return { - publisher: { - id: pubId.toString(), - }, - id: appParams.id, - name: appParams.name, - bundle: appParams.bundle, - storeurl: appParams.storeUrl, - domain: appParams.domain, - } - } - return null; -} - -function device(bidderRequest) { - const lat = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.latitude : ''; - const lon = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.longitude : ''; - const ifa = bidderRequest && bidderRequest.length > 0 ? bidderRequest[0].params.ifa : ''; - return { - dnt: utils.getDNT() ? 1 : 0, - ua: navigator.userAgent, - language: (navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage), - w: (window.screen.width || window.innerWidth), - h: (window.screen.height || window.innerHeigh), - geo: { - lat: lat, - lon: lon, - }, - ifa: ifa, - }; -} - -function parse(rawResponse) { - try { - if (rawResponse) { - return JSON.parse(rawResponse); - } - } catch (ex) { - utils.logError('windtalker.parse', 'ERROR', ex); - } - return null; -} - -function applyGdpr(bidderRequest, ortbRequest) { - if (bidderRequest && bidderRequest.gdprConsent) { - ortbRequest.regs = { ext: { gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0 } }; - ortbRequest.user = { ext: { consent: bidderRequest.gdprConsent.consentString } }; - } -} - -function nativeResponse(imp, bid) { - if (imp['native']) { - const nativeAd = parse(bid.adm); - const keys = {}; - keys.image = {}; - keys.icon = {}; - if (nativeAd && nativeAd['native'] && nativeAd['native'].assets) { - nativeAd['native'].assets.forEach(asset => { - keys.title = asset.title ? asset.title.text : keys.title; - keys.body = asset.data && asset.id === 2 ? asset.data.value : keys.body; - keys.sponsoredBy = asset.data && asset.id === 3 ? asset.data.value : keys.sponsoredBy; - keys.icon.url = asset.img && asset.id === 4 ? asset.img.url : keys.icon.url; - keys.icon.width = asset.img && asset.id === 4 ? asset.img.w : keys.icon.width; - keys.icon.height = asset.img && asset.id === 4 ? asset.img.h : keys.icon.height; - keys.image.url = asset.img && asset.id === 5 ? asset.img.url : keys.image.url; - keys.image.width = asset.img && asset.id === 5 ? asset.img.w : keys.image.width; - keys.image.height = asset.img && asset.id === 5 ? asset.img.h : keys.image.height; - }); - if (nativeAd['native'].link) { - keys.clickUrl = encodeURIComponent(nativeAd['native'].link.url); - } - return keys; - } - } - return null; -} - -registerBidder(spec); diff --git a/modules/windtalkerBidAdapter.md b/modules/windtalkerBidAdapter.md deleted file mode 100644 index f7441effc47..00000000000 --- a/modules/windtalkerBidAdapter.md +++ /dev/null @@ -1,86 +0,0 @@ -# Overview - -**Module Name**: Windtalker Bidder Adapter -**Module Type**: Bidder Adapter -**Maintainer**: corbin@windtalker.io - -# Description - -Connects to Windtalker demand source to fetch bids. -Banner, Native, Video formats are supported. -Please use ```windtalker``` as the bidder code. - -# Test Parameters -``` - var adUnits = [{ - code: 'dfp-native-div', - mediaTypes: { - native: { - title: { - required: true, - len: 75 - }, - image: { - required: true - }, - body: { - len: 200 - }, - icon: { - required: false - } - } - }, - bids: [{ - bidder: 'windtalker', - params: { - pubId: '584971', - siteId: '584971', - placementId: '123', - bidFloor: '0.001', // optional - ifa: 'XXX-XXX', // optional - latitude: '40.712775', // optional - longitude: '-74.005973', // optional - } - }] - }, - { - code: 'dfp-banner-div', - mediaTypes: { - banner: { - sizes: [ - [300, 250],[300,600] - ], - } - }, - bids: [{ - bidder: 'windtalker', - params: { - pubId: '584971', - siteId: '584971', - placementId: '123', - } - }] - }, - { - code: 'dfp-video-div', - mediaTypes: { - video: { - playerSize: [[640, 480]], - context: "instream" - } - }, - bids: [{ - bidder: 'windtalker', - params: { - pubId: '584971', - siteId: '584971', - placementId: '123', - video: { - skipppable: true, - } - } - }] - } - ]; -``` diff --git a/modules/wipesBidAdapter.js b/modules/wipesBidAdapter.js deleted file mode 100644 index f381bcb68a0..00000000000 --- a/modules/wipesBidAdapter.js +++ /dev/null @@ -1,71 +0,0 @@ -import * as utils from '../src/utils.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'wipes'; -const ALIAS_BIDDER_CODE = ['wi']; -const SUPPORTED_MEDIA_TYPES = [BANNER] -const ENDPOINT_URL = 'https://adn-srv.reckoner-api.com/v1/prebid'; - -function isBidRequestValid(bid) { - switch (true) { - case !!(bid.params.asid): - break; - default: - utils.logWarn(`isBidRequestValid Error. ${bid.params}, please check your implementation.`); - return false; - } - return true; -} - -function buildRequests(validBidRequests, bidderRequest) { - return validBidRequests.map(bidRequest => { - const bidId = bidRequest.bidId - const params = bidRequest.params; - const asid = params.asid; - return { - method: 'GET', - url: ENDPOINT_URL, - data: { - asid: asid, - bid_id: bidId, - } - } - }); -} - -function interpretResponse(serverResponse, bidRequest) { - const bidResponses = []; - const response = serverResponse.body; - const cpm = response.cpm || 0; - if (cpm !== 0) { - const netRevenue = (response.netRevenue === undefined) ? true : response.netRevenue; - const bidResponse = { - requestId: response.bid_id, - cpm: cpm, - width: response.width, - height: response.height, - creativeId: response.video_creative_id || 0, - dealId: response.deal_id, - currency: 'JPY', - netRevenue: netRevenue, - ttl: config.getConfig('_bidderTimeout'), - referrer: bidRequest.data.r || '', - mediaType: BANNER, - ad: response.ad_tag, - }; - bidResponses.push(bidResponse); - } - return bidResponses; -} - -export const spec = { - code: BIDDER_CODE, - aliases: ALIAS_BIDDER_CODE, - isBidRequestValid, - buildRequests, - interpretResponse, - supportedMediaTypes: SUPPORTED_MEDIA_TYPES -} -registerBidder(spec); diff --git a/modules/wipesBidAdapter.md b/modules/wipesBidAdapter.md deleted file mode 100644 index 712bf0b15d8..00000000000 --- a/modules/wipesBidAdapter.md +++ /dev/null @@ -1,33 +0,0 @@ -# Overview - -``` -Module Name: WIPES Bidder Adapter -Module Type: Bidder Adapter -Maintainer: contact@3-shake.com -``` - -# Description - -Connect to WIPES for bids. -Publishers needs to be set up and approved by WIPES team to enable this adapter. -Please contact support@wipestream.com for further information. - -# Test Parameters -```javascript -var adUnits = [ - // adUnit - { - code: 'video-div', - mediaTypes: { - banner: { - sizes: [[160, 300]], - } - }, - bids: [{ - bidder: 'wipes', - params: { - asid: 'dWyPondh2EGB_bNlrVjzIXRZO9F0k1dpo0I8ZvQ' - } - }] - }] -``` diff --git a/modules/xendizBidAdapter.md b/modules/xendizBidAdapter.md deleted file mode 100644 index 4ecabe7070f..00000000000 --- a/modules/xendizBidAdapter.md +++ /dev/null @@ -1,41 +0,0 @@ -# Overview - -Module Name: Xendiz Bidder Adapter -Module Type: Bidder Adapter -Maintainer: hello@xendiz.com - -# Description - -Module that connects to Xendiz demand sources - -# Test Parameters -``` - var adUnits = [ - { - code: 'test-div', - sizes: [[300, 250]], - bids: [ - { - bidder: "xendiz", - params: { - pid: '00000000-0000-0000-0000-000000000000' - } - } - ] - },{ - code: 'test-div', - sizes: [[300, 50]], - bids: [ - { - bidder: "xendiz", - params: { - pid: '00000000-0000-0000-0000-000000000000', - ext: { - uid: '550e8400-e29b-41d4-a716-446655440000' - } - } - } - ] - } - ]; -``` \ No newline at end of file diff --git a/modules/xhbBidAdapter.js b/modules/xhbBidAdapter.js deleted file mode 100644 index 9363eb97ddc..00000000000 --- a/modules/xhbBidAdapter.js +++ /dev/null @@ -1,457 +0,0 @@ -import { Renderer } from '../src/Renderer.js'; -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import find from 'core-js-pure/features/array/find.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -const BIDDER_CODE = 'xhb'; -const URL = 'https://ib.adnxs.com/ut/v3/prebid'; -const VIDEO_TARGETING = ['id', 'mimes', 'minduration', 'maxduration', - 'startdelay', 'skippable', 'playback_method', 'frameworks']; -const USER_PARAMS = ['age', 'external_uid', 'segments', 'gender', 'dnt', 'language']; -const NATIVE_MAPPING = { - body: 'description', - cta: 'ctatext', - image: { - serverName: 'main_image', - requiredParams: { required: true }, - minimumParams: { sizes: [{}] }, - }, - icon: { - serverName: 'icon', - requiredParams: { required: true }, - minimumParams: { sizes: [{}] }, - }, - sponsoredBy: 'sponsored_by', -}; -const SOURCE = 'pbjs'; - -export const spec = { - code: BIDDER_CODE, - aliases: [], - supportedMediaTypes: [BANNER, VIDEO, NATIVE], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {object} bid The bid to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - return !!(bid.params.placementId || (bid.params.member && bid.params.invCode)); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server. - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(bidRequests, bidderRequest) { - const tags = bidRequests.map(bidToTag); - const userObjBid = find(bidRequests, hasUserInfo); - let userObj; - if (userObjBid) { - userObj = {}; - Object.keys(userObjBid.params.user) - .filter(param => includes(USER_PARAMS, param)) - .forEach(param => userObj[param] = userObjBid.params.user[param]); - } - - const memberIdBid = find(bidRequests, hasMemberId); - const member = memberIdBid ? parseInt(memberIdBid.params.member, 10) : 0; - - const payload = { - tags: [...tags], - user: userObj, - sdk: { - source: SOURCE, - version: '$prebid.version$' - } - }; - if (member > 0) { - payload.member_id = member; - } - - if (bidderRequest && bidderRequest.gdprConsent) { - // note - objects for impbus use underscore instead of camelCase - payload.gdpr_consent = { - consent_string: bidderRequest.gdprConsent.consentString, - consent_required: bidderRequest.gdprConsent.gdprApplies - }; - } - - const payloadString = JSON.stringify(payload); - return { - method: 'POST', - url: URL, - data: payloadString, - bidderRequest - }; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse, {bidderRequest}) { - serverResponse = serverResponse.body; - const bids = []; - if (!serverResponse || serverResponse.error) { - let errorMessage = `in response for ${bidderRequest.bidderCode} adapter`; - if (serverResponse && serverResponse.error) { errorMessage += `: ${serverResponse.error}`; } - utils.logError(errorMessage); - return bids; - } - - if (serverResponse.tags) { - serverResponse.tags.forEach(serverBid => { - const rtbBid = getRtbBid(serverBid); - if (rtbBid) { - if (rtbBid.cpm !== 0 && includes(this.supportedMediaTypes, rtbBid.ad_type)) { - const bid = newBid(serverBid, rtbBid, bidderRequest); - bid.mediaType = parseMediaType(rtbBid); - bids.push(bid); - } - } - }); - } - return bids; - }, - - getUserSyncs: function(syncOptions) { - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: 'https://acdn.adnxs.com/dmp/async_usersync.html' - }]; - } - } -}; - -function newRenderer(adUnitCode, rtbBid, rendererOptions = {}) { - const renderer = Renderer.install({ - id: rtbBid.renderer_id, - url: rtbBid.renderer_url, - config: rendererOptions, - loaded: false, - }); - - try { - renderer.setRender(outstreamRender); - } catch (err) { - utils.logWarn('Prebid Error calling setRender on renderer', err); - } - - renderer.setEventHandlers({ - impression: () => utils.logMessage('xhb outstream video impression event'), - loaded: () => utils.logMessage('xhb outstream video loaded event'), - ended: () => { - utils.logMessage('xhb outstream renderer video event'); - document.querySelector(`#${adUnitCode}`).style.display = 'none'; - } - }); - return renderer; -} - -/* Turn keywords parameter into ut-compatible format */ -function getKeywords(keywords) { - let arrs = []; - - utils._each(keywords, (v, k) => { - if (utils.isArray(v)) { - let values = []; - utils._each(v, (val) => { - val = utils.getValueString('keywords.' + k, val); - if (val) { values.push(val); } - }); - v = values; - } else { - v = utils.getValueString('keywords.' + k, v); - if (utils.isStr(v)) { - v = [v]; - } else { - return; - } // unsuported types - don't send a key - } - arrs.push({key: k, value: v}); - }); - - return arrs; -} - -/** - * Unpack the Server's Bid into a Prebid-compatible one. - * @param serverBid - * @param rtbBid - * @param bidderRequest - * @return Bid - */ -function newBid(serverBid, rtbBid, bidderRequest) { - const bid = { - requestId: serverBid.uuid, - cpm: 0.00, - creativeId: rtbBid.creative_id, - dealId: 99999999, - currency: 'USD', - netRevenue: true, - ttl: 300, - appnexus: { - buyerMemberId: rtbBid.buyer_member_id - } - }; - - if (rtbBid.rtb.video) { - Object.assign(bid, { - width: rtbBid.rtb.video.player_width, - height: rtbBid.rtb.video.player_height, - vastUrl: rtbBid.rtb.video.asset_url, - vastImpUrl: rtbBid.notify_url, - ttl: 3600 - }); - // This supports Outstream Video - if (rtbBid.renderer_url) { - const rendererOptions = utils.deepAccess( - bidderRequest.bids[0], - 'renderer.options' - ); - - Object.assign(bid, { - adResponse: serverBid, - renderer: newRenderer(bid.adUnitCode, rtbBid, rendererOptions) - }); - bid.adResponse.ad = bid.adResponse.ads[0]; - bid.adResponse.ad.video = bid.adResponse.ad.rtb.video; - } - } else if (rtbBid.rtb[NATIVE]) { - const nativeAd = rtbBid.rtb[NATIVE]; - bid[NATIVE] = { - title: nativeAd.title, - body: nativeAd.desc, - cta: nativeAd.ctatext, - sponsoredBy: nativeAd.sponsored, - clickUrl: nativeAd.link.url, - clickTrackers: nativeAd.link.click_trackers, - impressionTrackers: nativeAd.impression_trackers, - javascriptTrackers: nativeAd.javascript_trackers, - }; - if (nativeAd.main_img) { - bid['native'].image = { - url: nativeAd.main_img.url, - height: nativeAd.main_img.height, - width: nativeAd.main_img.width, - }; - } - if (nativeAd.icon) { - bid['native'].icon = { - url: nativeAd.icon.url, - height: nativeAd.icon.height, - width: nativeAd.icon.width, - }; - } - } else { - Object.assign(bid, { - width: rtbBid.rtb.banner.width, - height: rtbBid.rtb.banner.height, - ad: rtbBid.rtb.banner.content - }); - try { - const url = rtbBid.rtb.trackers[0].impression_urls[0]; - const tracker = utils.createTrackPixelHtml(url); - bid.ad += tracker; - } catch (error) { - utils.logError('Error appending tracking pixel', error); - } - } - - return bid; -} - -function bidToTag(bid) { - const tag = {}; - tag.sizes = transformSizes(bid.sizes); - tag.primary_size = tag.sizes[0]; - tag.ad_types = []; - tag.uuid = bid.bidId; - if (bid.params.placementId) { - tag.id = parseInt(bid.params.placementId, 10); - } else { - tag.code = bid.params.invCode; - } - tag.allow_smaller_sizes = bid.params.allowSmallerSizes || false; - tag.use_pmt_rule = bid.params.usePaymentRule || false; - tag.prebid = true; - tag.disable_psa = true; - if (bid.params.reserve) { - tag.reserve = bid.params.reserve; - } - if (bid.params.position) { - tag.position = {'above': 1, 'below': 2}[bid.params.position] || 0; - } - if (bid.params.trafficSourceCode) { - tag.traffic_source_code = bid.params.trafficSourceCode; - } - if (bid.params.privateSizes) { - tag.private_sizes = transformSizes(bid.params.privateSizes); - } - if (bid.params.supplyType) { - tag.supply_type = bid.params.supplyType; - } - if (bid.params.pubClick) { - tag.pubclick = bid.params.pubClick; - } - if (bid.params.extInvCode) { - tag.ext_inv_code = bid.params.extInvCode; - } - if (bid.params.externalImpId) { - tag.external_imp_id = bid.params.externalImpId; - } - if (!utils.isEmpty(bid.params.keywords)) { - tag.keywords = getKeywords(bid.params.keywords); - } - - if (bid.mediaType === NATIVE || utils.deepAccess(bid, `mediaTypes.${NATIVE}`)) { - tag.ad_types.push(NATIVE); - - if (bid.nativeParams) { - const nativeRequest = buildNativeRequest(bid.nativeParams); - tag[NATIVE] = {layouts: [nativeRequest]}; - } - } - - const videoMediaType = utils.deepAccess(bid, `mediaTypes.${VIDEO}`); - const context = utils.deepAccess(bid, 'mediaTypes.video.context'); - - if (bid.mediaType === VIDEO || videoMediaType) { - tag.ad_types.push(VIDEO); - } - - // instream gets vastUrl, outstream gets vastXml - if (bid.mediaType === VIDEO || (videoMediaType && context !== 'outstream')) { - tag.require_asset_url = true; - } - - if (bid.params.video) { - tag.video = {}; - // place any valid video params on the tag - Object.keys(bid.params.video) - .filter(param => includes(VIDEO_TARGETING, param)) - .forEach(param => tag.video[param] = bid.params.video[param]); - } - - if ( - (utils.isEmpty(bid.mediaType) && utils.isEmpty(bid.mediaTypes)) || - (bid.mediaType === BANNER || (bid.mediaTypes && bid.mediaTypes[BANNER])) - ) { - tag.ad_types.push(BANNER); - } - - return tag; -} - -/* Turn bid request sizes into ut-compatible format */ -function transformSizes(requestSizes) { - let sizes = []; - let sizeObj = {}; - - if (utils.isArray(requestSizes) && requestSizes.length === 2 && - !utils.isArray(requestSizes[0])) { - sizeObj.width = parseInt(requestSizes[0], 10); - sizeObj.height = parseInt(requestSizes[1], 10); - sizes.push(sizeObj); - } else if (typeof requestSizes === 'object') { - for (let i = 0; i < requestSizes.length; i++) { - let size = requestSizes[i]; - sizeObj = {}; - sizeObj.width = parseInt(size[0], 10); - sizeObj.height = parseInt(size[1], 10); - sizes.push(sizeObj); - } - } - - return sizes; -} - -function hasUserInfo(bid) { - return !!bid.params.user; -} - -function hasMemberId(bid) { - return !!parseInt(bid.params.member, 10); -} - -function getRtbBid(tag) { - return tag && tag.ads && tag.ads.length && find(tag.ads, ad => ad.rtb); -} - -function buildNativeRequest(params) { - const request = {}; - - // map standard prebid native asset identifier to /ut parameters - // e.g., tag specifies `body` but /ut only knows `description`. - // mapping may be in form {tag: ''} or - // {tag: {serverName: '', requiredParams: {...}}} - Object.keys(params).forEach(key => { - // check if one of the forms is used, otherwise - // a mapping wasn't specified so pass the key straight through - const requestKey = - (NATIVE_MAPPING[key] && NATIVE_MAPPING[key].serverName) || - NATIVE_MAPPING[key] || - key; - - // required params are always passed on request - const requiredParams = NATIVE_MAPPING[key] && NATIVE_MAPPING[key].requiredParams; - request[requestKey] = Object.assign({}, requiredParams, params[key]); - - // minimum params are passed if no non-required params given on adunit - const minimumParams = NATIVE_MAPPING[key] && NATIVE_MAPPING[key].minimumParams; - - if (requiredParams && minimumParams) { - // subtract required keys from adunit keys - const adunitKeys = Object.keys(params[key]); - const requiredKeys = Object.keys(requiredParams); - const remaining = adunitKeys.filter(key => !includes(requiredKeys, key)); - - // if none are left over, the minimum params needs to be sent - if (remaining.length === 0) { - request[requestKey] = Object.assign({}, request[requestKey], minimumParams); - } - } - }); - - return request; -} - -function outstreamRender(bid) { - // push to render queue because ANOutstreamVideo may not be loaded yet - bid.renderer.push(() => { - window.ANOutstreamVideo.renderAd({ - tagId: bid.adResponse.tag_id, - sizes: [bid.getSize().split('x')], - targetId: bid.adUnitCode, // target div id to render video - uuid: bid.adResponse.uuid, - adResponse: bid.adResponse, - rendererOptions: bid.renderer.getConfig() - }, handleOutstreamRendererEvents.bind(null, bid)); - }); -} - -function handleOutstreamRendererEvents(bid, id, eventName) { - bid.renderer.handleVideoEvent({ id, eventName }); -} - -function parseMediaType(rtbBid) { - const adType = rtbBid.ad_type; - if (adType === VIDEO) { - return VIDEO; - } else if (adType === NATIVE) { - return NATIVE; - } else { - return BANNER; - } -} - -registerBidder(spec); diff --git a/modules/xhbBidAdapter.md b/modules/xhbBidAdapter.md deleted file mode 100644 index bb95f4f499c..00000000000 --- a/modules/xhbBidAdapter.md +++ /dev/null @@ -1,100 +0,0 @@ -# Overview - -``` -Module Name: XHB Bid Adapter -Module Type: Bidder Adapter -Maintainer: daniel.hoffmann@xaxis.com -``` - -# Description - -Connects to Appnexus exchange for bids. - -XHB bid adapter supports Banner, Video (instream and outstream) and Native. - -# Test Parameters -``` -var adUnits = [ - // Banner adUnit - { - code: 'banner-div', - sizes: [[300, 250], [300,600]], - bids: [{ - bidder: 'xhb', - params: { - placementId: '10433394' - } - }] - }, - // Native adUnit - { - code: 'native-div', - sizes: [[300, 250], [300,600]], - mediaTypes: { - native: { - title: { - required: true, - len: 80 - }, - body: { - required: true - }, - image: { - required: true - }, - clickUrl: { - required: true - }, - } - }, - bids: [{ - bidder: 'xhb', - params: { - placementId: '9880618' - } - }] - }, - // Video instream adUnit - { - code: 'video-instream', - sizes: [640, 480], - mediaTypes: { - video: { - context: 'instream' - }, - }, - bids: [{ - bidder: 'xhb', - params: { - placementId: '9333431', - video: { - skippable: true, - playback_methods: ['auto_play_sound_off'] - } - } - }] - }, - // Video outstream adUnit - { - code: 'video-outstream', - sizes: [[640, 480]], - mediaTypes: { - video: { - context: 'outstream' - } - }, - bids: [ - { - bidder: 'xhb', - params: { - placementId: '5768085', - video: { - skippable: true, - playback_method: ['auto_play_sound_off'] - } - } - } - ] - } -]; -``` diff --git a/modules/yieldbotBidAdapter.md b/modules/yieldbotBidAdapter.md deleted file mode 100644 index db6f4dc100b..00000000000 --- a/modules/yieldbotBidAdapter.md +++ /dev/null @@ -1,192 +0,0 @@ -# Overview - -``` -Module Name: Yieldbot Bid Adapter -Module Type: Bidder Adapter -Maintainer: pubops@yieldbot.com -``` - -# Description -The Yieldbot Prebid.js bid adapter integrates Yieldbot demand to publisher inventory. - -# BaseAdapter Settings - -| Setting | Value | -| :-------------------- | :------------ | -| `supportedMediaTypes` | **banner** | -| `getUserSyncs` | **image** pixel | -| `ttl` | **180** [s] | -| `currency` | **USD** | - -# Parameters -The following table lists parameters required for Yieldbot bidder configuration. -See also [Test Parameters](#test-parameters) for an illustration of parameter usage. - -| Name | Scope | Description | Example | -| :------ | :------- | :------------------------------------------------------------------ | :-------------- | -| `psn` | required | The Yieldbot publisher account short name identifier | "7b25" | -| `slot` | required | The Yieldbot slot name associated to the publisher adUnit to bid on | "mobile_REC_2" | - -## Example Bidder Configuration -```javascript -var adUnit0 = { - code: '/00000000/leaderboard', - mediaTypes: { - banner: { - sizes: [728, 90] - } - }, - bids: [ - { - bidder: 'yieldbot', - params: { - psn: '7b25', - slot: 'desktop_LB' - } - } - ] -}; -``` - -# Test Parameters -For integration testing, the Yieldbot Platform can be set to always return a bid for requested slots. - -When Yieldbot testing mode is enabled, a cookie (`__ybot_test`) on the domain `.yldbt.com` tells the Yieldbot ad server to always return a bid. Each bid is associated to a static mock integration testing creative. - -- **Enable** integration testing mode: - - http://i.yldbt.com/integration/start -- **Disable** integration testing mode: - - http://i.yldbt.com/integration/stop - -***Note:*** - -- No ad serving metrics are impacted when integration testing mode is enabled. -- The `__ybot_test` cookie expires in 24 hours. -- It is good practice to click "Stop testing" when testing is complete, to return to normal ad delivery. - -For reference, the test bidder configuration below is included in the following manual test/example file [test/spec/e2e/gpt-examples/gpt_yieldbot.html](../test/spec/e2e/gpt-examples/gpt_yieldbot.html) -- Replace the adUnit `code` values with your respective DFP adUnitCode. -- ***Remember*** to **Enable** Yieldbot testing mode to force a bid to be returned. - -```javascript -var adUnit0 = { - code: '/00000000/leaderboard', - mediaTypes: { - banner: { - sizes: [728, 90] - } - }, - bids: [ - { - bidder: 'yieldbot', - params: { - psn: '1234', - slot: 'leaderboard' - } - } - ] -}; - -var adUnit1 = { - code: '/00000000/medium-rectangle', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [ - { - bidder: 'yieldbot', - params: { - psn: '1234', - slot: 'medrec' - } - } - ] -}; - -var adUnit2 = { - code: '/00000000/large-rectangle', - mediaTypes: { - banner: { - sizes: [[300, 600]] - } - }, - bids: [ - { - bidder: 'yieldbot', - params: { - psn: '1234', - slot: 'sidebar' - } - } - ] -}; - -var adUnit3 = { - code: '/00000000/skyscraper', - mediaTypes: { - banner: { - sizes: [[160, 600]] - } - }, - bids: [ - { - bidder: 'yieldbot', - params: { - psn: '1234', - slot: 'skyscraper' - } - } - ] -}; -``` - -# Yieldbot Query Parameters - -| Name | Description | -| :--- | :---------- | -| `apie` | Yieldbot error description parameter | -| `bt` | Yieldbot bid request type: `initial` or `refresh` | -| `cts_ad` | Yieldbot ad creative request sent timestamp, in milliseconds since the UNIX epoch | -| `cts_imp` | Yieldbot ad impression request sent timestamp, in milliseconds since the UNIX epoch | -| `cts_ini` | Yieldbot bid request sent timestamp, in milliseconds since the UNIX epoch | -| `cts_js` | Adapter code interpreting started timestamp, in milliseconds since the UNIX epoch | -| `cts_ns` | Performance timing navigationStart | -| `cts_rend` | Yieldbot ad creative render started timestamp, in milliseconds since the UNIX epoch | -| `cts_res` | Yieldbot bid response processing started timestamp, in milliseconds since the UNIX epoch | -| `e` | Yieldbot search parameters terminator | -| `ioa` | Indicator that the user-agent supports the Intersection Observer API | -| `it` | Indicator to specify Yieldbot creative rendering occured in an iframe: same/cross origin (`so`)/(`co`) or top (`none`) | -| `la` | Language and locale of the user-agent | -| `lo` | The page visit location Url | -| `lpv` | Time in milliseconds since the last page visit | -| `lpvi` | Pageview identifier for the last pageview within the session TTL | -| `np` | User-agent browsing platform | -| `pvd` | Counter for page visits within a session | -| `pvi` | Page visit identifier | -| `r` | The referring page Url | -| `ri` | Yieldbot ad request identifier | -| `sb` | Yieldbot ads blocked by user opt-out or suspicious activity detected during session | -| `sd` | User-agent screen dimensions | -| `si` | Publisher site visit session identifier | -| `slot` | Slot name for Yieldbot ad markup request e.g. `:x` | -| `sn` | Yieldbot bid slot names | -| `ssz` | Dimensions for the respective bid slot names | -| `to` | Number of hours offset from UTC | -| `ua` | User-Agent string | -| `v` | The version of the YieldbotAdapter | -| `vi` | First party user identifier | - - -# First-party Cookies - -| Name | Description | -| :--- | :---------- | -| `__ybotn` | The session is temporarily suspended from the ad server e.g. User-Agent, Geo location or suspicious activity | -| `__ybotu` | The Yieldbot first-party user identifier | -| `__ybotsi` | The user session identifier | -| `__ybotpvd` | The session pageview depth | -| `__ybotlpvi` | The last pageview identifier within the session | -| `__ybotlpv` | The time in **[ms]** since the last visit within the session | -| `__ybotc` | Geo/IP proximity location request Url | diff --git a/modules/yieldlabBidAdapter.js b/modules/yieldlabBidAdapter.js deleted file mode 100644 index 9c1c54cfb2b..00000000000 --- a/modules/yieldlabBidAdapter.js +++ /dev/null @@ -1,273 +0,0 @@ -import * as utils from '../src/utils.js' -import { registerBidder } from '../src/adapters/bidderFactory.js' -import find from 'core-js-pure/features/array/find.js' -import { VIDEO, BANNER } from '../src/mediaTypes.js' -import { Renderer } from '../src/Renderer.js' - -const ENDPOINT = 'https://ad.yieldlab.net' -const BIDDER_CODE = 'yieldlab' -const BID_RESPONSE_TTL_SEC = 300 -const CURRENCY_CODE = 'EUR' -const OUTSTREAMPLAYER_URL = 'https://ad.adition.com/dynamic.ad?a=o193092&ma_loadEvent=ma-start-event' - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [VIDEO, BANNER], - - isBidRequestValid: function (bid) { - if (bid && bid.params && bid.params.adslotId && bid.params.supplyId) { - return true - } - return false - }, - - /** - * This method should build correct URL - * @param validBidRequests - * @returns {{method: string, url: string}} - */ - buildRequests: function (validBidRequests, bidderRequest) { - const adslotIds = [] - const timestamp = Date.now() - const query = { - ts: timestamp, - json: true - } - - utils._each(validBidRequests, function (bid) { - adslotIds.push(bid.params.adslotId) - if (bid.params.targeting) { - query.t = createTargetingString(bid.params.targeting) - } - if (bid.userIdAsEids && Array.isArray(bid.userIdAsEids)) { - query.ids = createUserIdString(bid.userIdAsEids) - } - if (bid.params.customParams && utils.isPlainObject(bid.params.customParams)) { - for (let prop in bid.params.customParams) { - query[prop] = bid.params.customParams[prop] - } - } - if (bid.schain && utils.isPlainObject(bid.schain) && Array.isArray(bid.schain.nodes)) { - query.schain = createSchainString(bid.schain) - } - }) - - if (bidderRequest) { - if (bidderRequest.refererInfo && bidderRequest.refererInfo.referer) { - query.pubref = bidderRequest.refererInfo.referer - } - - if (bidderRequest.gdprConsent) { - query.gdpr = (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') ? bidderRequest.gdprConsent.gdprApplies : true - if (query.gdpr) { - query.consent = bidderRequest.gdprConsent.consentString - } - } - } - - const adslots = adslotIds.join(',') - const queryString = createQueryString(query) - - return { - method: 'GET', - url: `${ENDPOINT}/yp/${adslots}?${queryString}`, - validBidRequests: validBidRequests, - queryParams: query - } - }, - - /** - * Map ad values and pricing and stuff - * @param serverResponse - * @param originalBidRequest - */ - interpretResponse: function (serverResponse, originalBidRequest) { - const bidResponses = [] - const timestamp = Date.now() - const reqParams = originalBidRequest.queryParams - - originalBidRequest.validBidRequests.forEach(function (bidRequest) { - if (!serverResponse.body) { - return - } - - let matchedBid = find(serverResponse.body, function (bidResponse) { - return bidRequest.params.adslotId == bidResponse.id - }) - - if (matchedBid) { - const adUnitSize = bidRequest.sizes.length === 2 && !utils.isArray(bidRequest.sizes[0]) ? bidRequest.sizes : bidRequest.sizes[0] - const adSize = bidRequest.params.adSize !== undefined ? parseSize(bidRequest.params.adSize) : (matchedBid.adsize !== undefined) ? parseSize(matchedBid.adsize) : adUnitSize - const extId = bidRequest.params.extId !== undefined ? '&id=' + bidRequest.params.extId : '' - const adType = matchedBid.adtype !== undefined ? matchedBid.adtype : '' - const gdprApplies = reqParams.gdpr ? '&gdpr=' + reqParams.gdpr : '' - const gdprConsent = reqParams.consent ? '&consent=' + reqParams.consent : '' - - const bidResponse = { - requestId: bidRequest.bidId, - cpm: matchedBid.price / 100, - width: adSize[0], - height: adSize[1], - creativeId: '' + matchedBid.id, - dealId: (matchedBid['c.dealid']) ? matchedBid['c.dealid'] : matchedBid.pid, - currency: CURRENCY_CODE, - netRevenue: false, - ttl: BID_RESPONSE_TTL_SEC, - referrer: '', - ad: `` - } - - if (isVideo(bidRequest, adType)) { - const playersize = getPlayerSize(bidRequest) - if (playersize) { - bidResponse.width = playersize[0] - bidResponse.height = playersize[1] - } - bidResponse.mediaType = VIDEO - bidResponse.vastUrl = `${ENDPOINT}/d/${matchedBid.id}/${bidRequest.params.supplyId}/?ts=${timestamp}${extId}${gdprApplies}${gdprConsent}` - if (isOutstream(bidRequest)) { - const renderer = Renderer.install({ - id: bidRequest.bidId, - url: OUTSTREAMPLAYER_URL, - loaded: false - }) - renderer.setRender(outstreamRender) - bidResponse.renderer = renderer - } - } - - bidResponses.push(bidResponse) - } - }) - return bidResponses - } -}; - -/** - * Is this a video format? - * @param {Object} format - * @param {String} adtype - * @returns {Boolean} - */ -function isVideo (format, adtype) { - return utils.deepAccess(format, 'mediaTypes.video') && adtype.toLowerCase() === 'video' -} - -/** - * Is this an outstream context? - * @param {Object} format - * @returns {Boolean} - */ -function isOutstream (format) { - let context = utils.deepAccess(format, 'mediaTypes.video.context') - return (context === 'outstream') -} - -/** - * Gets optional player size - * @param {Object} format - * @returns {Array} - */ -function getPlayerSize (format) { - let playerSize = utils.deepAccess(format, 'mediaTypes.video.playerSize') - return (playerSize && utils.isArray(playerSize[0])) ? playerSize[0] : playerSize -} - -/** - * Expands a 'WxH' string as a 2-element [W, H] array - * @param {String} size - * @returns {Array} - */ -function parseSize (size) { - return size.split('x').map(Number) -} - -/** - * Creates a string out of an array of eids with source and uid - * @param {Array} eids - * @returns {String} - */ -function createUserIdString (eids) { - let str = [] - for (let i = 0; i < eids.length; i++) { - str.push(eids[i].source + ':' + eids[i].uids[0].id) - } - return str.join(',') -} - -/** - * Creates a querystring out of an object with key-values - * @param {Object} obj - * @returns {String} - */ -function createQueryString (obj) { - let str = [] - for (var p in obj) { - if (obj.hasOwnProperty(p)) { - let val = obj[p] - if (p !== 'schain') { - str.push(encodeURIComponent(p) + '=' + encodeURIComponent(val)) - } else { - str.push(p + '=' + val) - } - } - } - return str.join('&') -} - -/** - * Creates an unencoded targeting string out of an object with key-values - * @param {Object} obj - * @returns {String} - */ -function createTargetingString (obj) { - let str = [] - for (var p in obj) { - if (obj.hasOwnProperty(p)) { - let key = p - let val = obj[p] - str.push(key + '=' + val) - } - } - return str.join('&') -} - -/** - * Creates a string out of a schain object - * @param {Object} schain - * @returns {String} - */ -function createSchainString (schain) { - const ver = schain.ver || '' - const complete = (schain.complete === 1 || schain.complete === 0) ? schain.complete : '' - const keys = ['asi', 'sid', 'hp', 'rid', 'name', 'domain', 'ext'] - const nodesString = schain.nodes.reduce((acc, node) => { - return acc += `!${keys.map(key => node[key] ? encodeURIComponentWithBangIncluded(node[key]) : '').join(',')}` - }, '') - return `${ver},${complete}${nodesString}` -} - -/** - * Encodes URI Component with exlamation mark included. Needed for schain object. - * @param {String} str - * @returns {String} - */ -function encodeURIComponentWithBangIncluded(str) { - return encodeURIComponent(str).replace(/!/g, '%21') -} - -/** - * Handles an outstream response after the library is loaded - * @param {Object} bid - */ -function outstreamRender(bid) { - bid.renderer.push(() => { - window.ma_width = bid.width - window.ma_height = bid.height - window.ma_vastUrl = bid.vastUrl - window.ma_container = bid.adUnitCode - window.document.dispatchEvent(new Event('ma-start-event')) - }); -} - -registerBidder(spec) diff --git a/modules/yieldlabBidAdapter.md b/modules/yieldlabBidAdapter.md deleted file mode 100644 index a7a3f2715dc..00000000000 --- a/modules/yieldlabBidAdapter.md +++ /dev/null @@ -1,48 +0,0 @@ -# Overview - -``` -Module Name: Yieldlab Bidder Adapter -Module Type: Bidder Adapter -Maintainer: solutions@yieldlab.de -``` - -# Description - -Module that connects to Yieldlab's demand sources - -# Test Parameters -``` - var adUnits = [ - { - code: "banner", - sizes: [[728, 90]], - bids: [{ - bidder: "yieldlab", - params: { - adslotId: "5220336", - supplyId: "1381604", - targeting: { - key1: "value1", - key2: "value2" - }, - extId: "abc" - } - }] - }, { - code: "video", - sizes: [[640, 480]], - mediaTypes: { - video: { - context: "instream" // or "outstream" - } - }, - bids: [{ - bidder: "yieldlab", - params: { - adslotId: "5220339", - supplyId: "1381604" - } - }] - } - ]; -``` diff --git a/modules/yieldliftBidAdapter.js b/modules/yieldliftBidAdapter.js deleted file mode 100644 index 87a598bd335..00000000000 --- a/modules/yieldliftBidAdapter.js +++ /dev/null @@ -1,144 +0,0 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import * as utils from '../src/utils.js'; -import {BANNER} from '../src/mediaTypes.js'; - -const ENDPOINT_URL = 'https://x.yieldlift.com/auction'; - -const DEFAULT_BID_TTL = 30; -const DEFAULT_CURRENCY = 'USD'; -const DEFAULT_NET_REVENUE = true; - -export const spec = { - code: 'yieldlift', - aliases: ['yl'], - supportedMediaTypes: [BANNER], - - isBidRequestValid: function (bid) { - return (!!bid.params.unitId && typeof bid.params.unitId === 'string') || - (!!bid.params.networkId && typeof bid.params.networkId === 'string') || - (!!bid.params.publisherId && typeof bid.params.publisherId === 'string'); - }, - - buildRequests: function (validBidRequests, bidderRequest) { - if (!validBidRequests || !bidderRequest) { - return; - } - const publisherId = validBidRequests[0].params.publisherId; - const networkId = validBidRequests[0].params.networkId; - const impressions = validBidRequests.map(bidRequest => ({ - id: bidRequest.bidId, - banner: { - format: bidRequest.mediaTypes.banner.sizes.map(sizeArr => ({ - w: sizeArr[0], - h: sizeArr[1] - })) - }, - ext: { - exchange: { - unitId: bidRequest.params.unitId - } - } - })); - - const openrtbRequest = { - id: bidderRequest.auctionId, - imp: impressions, - site: { - domain: window.location.hostname, - page: window.location.href, - ref: bidderRequest.refererInfo ? bidderRequest.refererInfo.referer || null : null - }, - ext: { - exchange: { - publisherId: publisherId, - networkId: networkId, - } - } - }; - - // adding schain object - if (validBidRequests[0].schain) { - utils.deepSetValue(openrtbRequest, 'source.ext.schain', validBidRequests[0].schain); - } - - // Attaching GDPR Consent Params - if (bidderRequest.gdprConsent) { - utils.deepSetValue(openrtbRequest, 'user.ext.consent', bidderRequest.gdprConsent.consentString); - utils.deepSetValue(openrtbRequest, 'regs.ext.gdpr', (bidderRequest.gdprConsent.gdprApplies ? 1 : 0)); - } - - // CCPA - if (bidderRequest.uspConsent) { - utils.deepSetValue(openrtbRequest, 'regs.ext.us_privacy', bidderRequest.uspConsent); - } - - const payloadString = JSON.stringify(openrtbRequest); - return { - method: 'POST', - url: ENDPOINT_URL, - data: payloadString, - }; - }, - - interpretResponse: function (serverResponse) { - const bidResponses = []; - const response = (serverResponse || {}).body; - // response is always one seat (exchange) with (optional) bids for each impression - if (response && response.seatbid && response.seatbid.length === 1 && response.seatbid[0].bid && response.seatbid[0].bid.length) { - response.seatbid[0].bid.forEach(bid => { - bidResponses.push({ - requestId: bid.impid, - cpm: bid.price, - width: bid.w, - height: bid.h, - ad: bid.adm, - ttl: DEFAULT_BID_TTL, - creativeId: bid.crid, - netRevenue: DEFAULT_NET_REVENUE, - currency: DEFAULT_CURRENCY, - }) - }) - } else { - utils.logInfo('yieldlift.interpretResponse :: no valid responses to interpret'); - } - return bidResponses; - }, - getUserSyncs: function (syncOptions, serverResponses) { - utils.logInfo('yieldlift.getUserSyncs', 'syncOptions', syncOptions, 'serverResponses', serverResponses); - let syncs = []; - - if (!syncOptions.iframeEnabled && !syncOptions.pixelEnabled) { - return syncs; - } - - serverResponses.forEach(resp => { - const userSync = utils.deepAccess(resp, 'body.ext.usersync'); - if (userSync) { - let syncDetails = []; - Object.keys(userSync).forEach(key => { - const value = userSync[key]; - if (value.syncs && value.syncs.length) { - syncDetails = syncDetails.concat(value.syncs); - } - }); - syncDetails.forEach(syncDetails => { - syncs.push({ - type: syncDetails.type === 'iframe' ? 'iframe' : 'image', - url: syncDetails.url - }); - }); - - if (!syncOptions.iframeEnabled) { - syncs = syncs.filter(s => s.type !== 'iframe') - } - if (!syncOptions.pixelEnabled) { - syncs = syncs.filter(s => s.type !== 'image') - } - } - }); - utils.logInfo('yieldlift.getUserSyncs result=%o', syncs); - return syncs; - }, - -}; -registerBidder(spec); diff --git a/modules/yieldliftBidAdapter.md b/modules/yieldliftBidAdapter.md deleted file mode 100644 index 96b5de1b618..00000000000 --- a/modules/yieldliftBidAdapter.md +++ /dev/null @@ -1,31 +0,0 @@ -# Overview - -``` -Module Name: YieldLift Bid Adapter -Module Type: Bidder Adapter -Maintainer: info@yieldlift.com -``` - -# Description - -Module that connects to YieldLift's demand sources - -# Test Parameters -``` -var adUnits = [ - { - code: 'banner-ad-div', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]] - } - }, - bids: [{ - bidder: 'yieldlift', - params: { - unitId: 'test' - } - }] - } -]; -``` diff --git a/modules/yieldmoBidAdapter.js b/modules/yieldmoBidAdapter.js deleted file mode 100644 index 36f93f60c9e..00000000000 --- a/modules/yieldmoBidAdapter.js +++ /dev/null @@ -1,555 +0,0 @@ -import * as utils from '../src/utils.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { Renderer } from '../src/Renderer.js'; -import includes from 'core-js-pure/features/array/includes'; -import find from 'core-js-pure/features/array/find.js'; - -const BIDDER_CODE = 'yieldmo'; -const CURRENCY = 'USD'; -const TIME_TO_LIVE = 300; -const NET_REVENUE = true; -const BANNER_SERVER_ENDPOINT = 'https://ads.yieldmo.com/exchange/prebid'; -const VIDEO_SERVER_ENDPOINT = 'https://ads.yieldmo.com/exchange/prebidvideo'; -const OUTSTREAM_VIDEO_PLAYER_URL = 'https://prebid-outstream.yieldmo.com/bundle.js'; -const OPENRTB_VIDEO_BIDPARAMS = ['placement', 'startdelay', 'skipafter', - 'protocols', 'api', 'playbackmethod', 'maxduration', 'minduration', 'pos']; -const OPENRTB_VIDEO_SITEPARAMS = ['name', 'domain', 'cat', 'keywords']; -const LOCAL_WINDOW = utils.getWindowTop(); -const DEFAULT_PLAYBACK_METHOD = 2; -const DEFAULT_START_DELAY = 0; -const VAST_TIMEOUT = 15000; -const MAX_BANNER_REQUEST_URL_LENGTH = 8000; -const BANNER_REQUEST_PROPERTIES_TO_REDUCE = ['description', 'title', 'pr', 'page_url']; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER, VIDEO], - - /** - * Determines whether or not the given bid request is valid. - * @param {object} bid, bid to validate - * @return boolean, true if valid, otherwise false - */ - isBidRequestValid: function (bid) { - return !!(bid && bid.adUnitCode && bid.bidId && (hasBannerMediaType(bid) || hasVideoMediaType(bid)) && - validateVideoParams(bid)); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server. - * @param {BidderRequest} bidderRequest bidder request object. - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (bidRequests, bidderRequest) { - const bannerBidRequests = bidRequests.filter(request => hasBannerMediaType(request)); - const videoBidRequests = bidRequests.filter(request => hasVideoMediaType(request)); - - let serverRequests = []; - if (bannerBidRequests.length > 0) { - let serverRequest = { - pbav: '$prebid.version$', - p: [], - page_url: bidderRequest.refererInfo.referer, - bust: new Date().getTime().toString(), - pr: (LOCAL_WINDOW.document && LOCAL_WINDOW.document.referrer) || '', - scrd: LOCAL_WINDOW.devicePixelRatio || 0, - dnt: getDNT(), - description: getPageDescription(), - title: LOCAL_WINDOW.document.title || '', - w: LOCAL_WINDOW.innerWidth, - h: LOCAL_WINDOW.innerHeight, - userConsent: JSON.stringify({ - // case of undefined, stringify will remove param - gdprApplies: utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies') || '', - cmp: utils.deepAccess(bidderRequest, 'gdprConsent.consentString') || '' - }), - us_privacy: utils.deepAccess(bidderRequest, 'uspConsent') || '' - }; - - const mtp = window.navigator.maxTouchPoints; - if (mtp) { - serverRequest.mtp = mtp; - } - - bannerBidRequests.forEach(request => { - serverRequest.p.push(addPlacement(request)); - const pubcid = getId(request, 'pubcid'); - if (pubcid) { - serverRequest.pubcid = pubcid; - } else if (request.crumbs && request.crumbs.pubcid) { - serverRequest.pubcid = request.crumbs.pubcid; - } - const tdid = getId(request, 'tdid'); - if (tdid) { - serverRequest.tdid = tdid; - } - const criteoId = getId(request, 'criteoId'); - if (criteoId) { - serverRequest.cri_prebid = criteoId; - } - if (request.schain) { - serverRequest.schain = JSON.stringify(request.schain); - } - }); - serverRequest.p = '[' + serverRequest.p.toString() + ']'; - - // check if url exceeded max length - const url = `${BANNER_SERVER_ENDPOINT}?${utils.parseQueryStringParameters(serverRequest)}`; - let extraCharacters = url.length - MAX_BANNER_REQUEST_URL_LENGTH; - if (extraCharacters > 0) { - for (let i = 0; i < BANNER_REQUEST_PROPERTIES_TO_REDUCE.length; i++) { - extraCharacters = shortcutProperty(extraCharacters, serverRequest, BANNER_REQUEST_PROPERTIES_TO_REDUCE[i]); - - if (extraCharacters <= 0) { - break; - } - } - } - - serverRequests.push({ - method: 'GET', - url: BANNER_SERVER_ENDPOINT, - data: serverRequest - }); - } - - if (videoBidRequests.length > 0) { - const serverRequest = openRtbRequest(videoBidRequests, bidderRequest); - serverRequests.push({ - method: 'POST', - url: VIDEO_SERVER_ENDPOINT, - data: serverRequest - }); - } - return serverRequests; - }, - - /** - * Makes Yieldmo Ad Server response compatible to Prebid specs - * @param {ServerResponse} serverResponse successful response from Ad Server - * @param {ServerRequest} bidRequest - * @return {Bid[]} an array of bids - */ - interpretResponse: function (serverResponse, bidRequest) { - let bids = []; - const data = serverResponse.body; - if (data.length > 0) { - data.forEach(response => { - if (response.cpm > 0) { - bids.push(createNewBannerBid(response)); - } - }); - } - if (data.seatbid) { - const seatbids = data.seatbid.reduce((acc, seatBid) => acc.concat(seatBid.bid), []); - seatbids.forEach(bid => bids.push(createNewVideoBid(bid, bidRequest))); - } - return bids; - }, - - getUserSyncs: function () { - return []; - } -}; -registerBidder(spec); - -/*************************************** - * Helper Functions - ***************************************/ - -/** - * @param {BidRequest} bidRequest bid request - */ -function hasBannerMediaType(bidRequest) { - return !!utils.deepAccess(bidRequest, 'mediaTypes.banner'); -} - -/** - * @param {BidRequest} bidRequest bid request - */ -function hasVideoMediaType(bidRequest) { - return !!utils.deepAccess(bidRequest, 'mediaTypes.video'); -} - -/** - * Adds placement information to array - * @param request bid request - */ -function addPlacement(request) { - const placementInfo = { - placement_id: request.adUnitCode, - callback_id: request.bidId, - sizes: request.mediaTypes.banner.sizes - }; - if (request.params) { - if (request.params.placementId) { - placementInfo.ym_placement_id = request.params.placementId; - } - const bidfloor = getBidFloor(request, BANNER); - if (bidfloor) { - placementInfo.bidFloor = bidfloor; - } - } - return JSON.stringify(placementInfo); -} - -/** - * creates a new banner bid with response information - * @param response server response - */ -function createNewBannerBid(response) { - return { - requestId: response['callback_id'], - cpm: response.cpm, - width: response.width, - height: response.height, - creativeId: response.creative_id, - currency: CURRENCY, - netRevenue: NET_REVENUE, - ttl: TIME_TO_LIVE, - ad: response.ad, - meta: { - advertiserDomains: response.adomain || [], - mediaType: BANNER, - }, - }; -} - -/** - * creates a new video bid with response information - * @param response openRTB server response - * @param bidRequest server request - */ -function createNewVideoBid(response, bidRequest) { - const imp = find((utils.deepAccess(bidRequest, 'data.imp') || []), imp => imp.id === response.impid); - - let result = { - requestId: imp.id, - cpm: response.price, - width: imp.video.w, - height: imp.video.h, - creativeId: response.crid || response.adid, - currency: CURRENCY, - netRevenue: NET_REVENUE, - mediaType: VIDEO, - ttl: TIME_TO_LIVE, - vastXml: response.adm, - meta: { - advertiserDomains: response.adomain || [], - mediaType: VIDEO, - }, - }; - - if (imp.video.placement && imp.video.placement !== 1) { - const renderer = Renderer.install({ - url: OUTSTREAM_VIDEO_PLAYER_URL, - config: { - width: result.width, - height: result.height, - vastTimeout: VAST_TIMEOUT, - maxAllowedVastTagRedirects: 5, - allowVpaid: true, - autoPlay: true, - preload: true, - mute: true - }, - id: imp.tagid, - loaded: false, - }); - - renderer.setRender(function (bid) { - bid.renderer.push(() => { - const { id, config } = bid.renderer; - window.YMoutstreamPlayer(bid, id, config); - }); - }); - - result.renderer = renderer; - } - - return result; -} - -/** - * Detects whether dnt is true - * @returns true if user enabled dnt - */ -function getDNT() { - return ( - window.doNotTrack === '1' || window.navigator.doNotTrack === '1' || false - ); -} - -/** - * get page description - */ -function getPageDescription() { - if (document.querySelector('meta[name="description"]')) { - return document - .querySelector('meta[name="description"]') - .getAttribute('content') || ''; // Value of the description metadata from the publisher's page. - } else { - return ''; - } -} - -/** - * Gets an id from the userId object if it exists - * @param {*} request - * @param {*} idType - * @returns an id if there is one, or undefined - */ -function getId(request, idType) { - return (typeof utils.deepAccess(request, 'userId') === 'object') ? request.userId[idType] : undefined; -} - -/** - * @param {BidRequest[]} bidRequests bid request object - * @param {BidderRequest} bidderRequest bidder request object - * @return Object OpenRTB request object - */ -function openRtbRequest(bidRequests, bidderRequest) { - let openRtbRequest = { - id: bidRequests[0].bidderRequestId, - at: 1, - imp: bidRequests.map(bidRequest => openRtbImpression(bidRequest)), - site: openRtbSite(bidRequests[0], bidderRequest), - device: openRtbDevice(), - badv: bidRequests[0].params.badv || [], - bcat: bidRequests[0].params.bcat || [], - ext: { - prebid: '$prebid.version$', - } - }; - - populateOpenRtbGdpr(openRtbRequest, bidderRequest); - - return openRtbRequest; -} - -/** - * @param {BidRequest} bidRequest bidder request object. - * @return Object OpenRTB's 'imp' (impression) object - */ -function openRtbImpression(bidRequest) { - const videoReq = utils.deepAccess(bidRequest, 'mediaTypes.video'); - const size = extractPlayerSize(bidRequest); - const imp = { - id: bidRequest.bidId, - tagid: bidRequest.adUnitCode, - bidfloor: getBidFloor(bidRequest, VIDEO), - ext: { - placement_id: bidRequest.params.placementId - }, - video: { - w: size[0], - h: size[1], - mimes: videoReq.mimes, - linearity: 1 - } - }; - - const videoParams = utils.deepAccess(bidRequest, 'params.video'); - Object.keys(videoParams) - .filter(param => includes(OPENRTB_VIDEO_BIDPARAMS, param)) - .forEach(param => imp.video[param] = videoParams[param]); - - if (videoParams.skippable) imp.video.skip = 1; - if (videoParams.placement !== 1) { - imp.video = { - ...imp.video, - startdelay: DEFAULT_START_DELAY, - playbackmethod: [ DEFAULT_PLAYBACK_METHOD ] - } - } - return imp; -} - -function getBidFloor(bidRequest, mediaType) { - let floorInfo = {}; - - if (typeof bidRequest.getFloor === 'function') { - floorInfo = bidRequest.getFloor({ currency: CURRENCY, mediaType, size: '*' }); - } - - return floorInfo.floor || bidRequest.params.bidfloor || bidRequest.params.bidFloor || 0; -} - -/** - * @param {BidRequest} bidRequest bidder request object. - * @return [number, number] || null Player's width and height, or undefined otherwise. - */ -function extractPlayerSize(bidRequest) { - const sizeArr = utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize'); - if (utils.isArrayOfNums(sizeArr, 2)) { - return sizeArr; - } else if (utils.isArray(sizeArr) && utils.isArrayOfNums(sizeArr[0], 2)) { - return sizeArr[0]; - } - return null; -} - -/** - * @param {BidRequest} bidRequest bid request object - * @param {BidderRequest} bidderRequest bidder request object - * @return Object OpenRTB's 'site' object - */ -function openRtbSite(bidRequest, bidderRequest) { - let result = {}; - - const loc = utils.parseUrl(utils.deepAccess(bidderRequest, 'refererInfo.referer')); - if (!utils.isEmpty(loc)) { - result.page = `${loc.protocol}://${loc.hostname}${loc.pathname}`; - } - - if (self === top && document.referrer) { - result.ref = document.referrer; - } - - const keywords = document.getElementsByTagName('meta')['keywords']; - if (keywords && keywords.content) { - result.keywords = keywords.content; - } - - const siteParams = utils.deepAccess(bidRequest, 'params.site'); - if (siteParams) { - Object.keys(siteParams) - .filter(param => includes(OPENRTB_VIDEO_SITEPARAMS, param)) - .forEach(param => result[param] = siteParams[param]); - } - return result; -} - -/** - * @return Object OpenRTB's 'device' object - */ -function openRtbDevice() { - return { - ua: navigator.userAgent, - language: (navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage), - }; -} - -/** - * Updates openRtbRequest with GDPR info from bidderRequest, if present. - * @param {Object} openRtbRequest OpenRTB's request to update. - * @param {BidderRequest} bidderRequest bidder request object. - */ -function populateOpenRtbGdpr(openRtbRequest, bidderRequest) { - const gdpr = bidderRequest.gdprConsent; - if (gdpr && 'gdprApplies' in gdpr) { - utils.deepSetValue(openRtbRequest, 'regs.ext.gdpr', gdpr.gdprApplies ? 1 : 0); - utils.deepSetValue(openRtbRequest, 'user.ext.consent', gdpr.consentString); - } - const uspConsent = utils.deepAccess(bidderRequest, 'uspConsent'); - if (uspConsent) { - utils.deepSetValue(openRtbRequest, 'regs.ext.us_privacy', uspConsent); - } -} - -/** - * Determines whether or not the given video bid request is valid. If it's not a video bid, returns true. - * @param {object} bid, bid to validate - * @return boolean, true if valid, otherwise false - */ -function validateVideoParams(bid) { - if (!hasVideoMediaType(bid)) { - return true; - } - - const paramRequired = (paramStr, value, conditionStr) => { - let error = `"${paramStr}" is required`; - if (conditionStr) { - error += ' when ' + conditionStr; - } - throw new Error(error); - } - - const paramInvalid = (paramStr, value, expectedStr) => { - expectedStr = expectedStr ? ', expected: ' + expectedStr : ''; - value = JSON.stringify(value); - throw new Error(`"${paramStr}"=${value} is invalid${expectedStr}`); - } - - const isDefined = val => typeof val !== 'undefined'; - const validate = (fieldPath, validateCb, errorCb, errorCbParam) => { - const value = utils.deepAccess(bid, fieldPath); - if (!validateCb(value)) { - errorCb(fieldPath, value, errorCbParam); - } - return value; - } - - try { - validate('params.placementId', val => !utils.isEmpty(val), paramRequired); - - validate('mediaTypes.video.playerSize', val => utils.isArrayOfNums(val, 2) || - (utils.isArray(val) && val.every(v => utils.isArrayOfNums(v, 2))), - paramInvalid, 'array of 2 integers, ex: [640,480] or [[640,480]]'); - - validate('mediaTypes.video.mimes', val => isDefined(val), paramRequired); - validate('mediaTypes.video.mimes', val => utils.isArray(val) && val.every(v => utils.isStr(v)), paramInvalid, - 'array of strings, ex: ["video/mp4"]'); - - validate('params.video', val => !utils.isEmpty(val), paramRequired); - - const placement = validate('params.video.placement', val => isDefined(val), paramRequired); - validate('params.video.placement', val => val >= 1 && val <= 5, paramInvalid); - if (placement === 1) { - validate('params.video.startdelay', val => isDefined(val), - (field, v) => paramRequired(field, v, 'placement == 1')); - validate('params.video.startdelay', val => utils.isNumber(val), paramInvalid, 'number, ex: 5'); - } - - validate('params.video.protocols', val => isDefined(val), paramRequired); - validate('params.video.protocols', val => utils.isArrayOfNums(val) && val.every(v => (v >= 1 && v <= 6)), - paramInvalid, 'array of numbers, ex: [2,3]'); - - validate('params.video.api', val => isDefined(val), paramRequired); - validate('params.video.api', val => utils.isArrayOfNums(val) && val.every(v => (v >= 1 && v <= 6)), - paramInvalid, 'array of numbers, ex: [2,3]'); - - validate('params.video.playbackmethod', val => !isDefined(val) || utils.isArrayOfNums(val), paramInvalid, - 'array of integers, ex: [2,6]'); - - validate('params.video.maxduration', val => isDefined(val), paramRequired); - validate('params.video.maxduration', val => utils.isInteger(val), paramInvalid); - validate('params.video.minduration', val => !isDefined(val) || utils.isNumber(val), paramInvalid); - validate('params.video.skippable', val => !isDefined(val) || utils.isBoolean(val), paramInvalid); - validate('params.video.skipafter', val => !isDefined(val) || utils.isNumber(val), paramInvalid); - validate('params.video.pos', val => !isDefined(val) || utils.isNumber(val), paramInvalid); - validate('params.badv', val => !isDefined(val) || utils.isArray(val), paramInvalid, - 'array of strings, ex: ["ford.com","pepsi.com"]'); - validate('params.bcat', val => !isDefined(val) || utils.isArray(val), paramInvalid, - 'array of strings, ex: ["IAB1-5","IAB1-6"]'); - return true; - } catch (e) { - utils.logError(e.message); - return false; - } -} - -/** - * Shortcut object property and check if required characters count was deleted - * - * @param {number} extraCharacters, count of characters to remove - * @param {object} target, object on which string property length should be reduced - * @param {string} propertyName, name of property to reduce - * @return {number} 0 if required characters count was removed otherwise count of how many left - */ -function shortcutProperty(extraCharacters, target, propertyName) { - if (target[propertyName].length > extraCharacters) { - target[propertyName] = target[propertyName].substring(0, target[propertyName].length - extraCharacters); - - return 0 - } - - const charactersLeft = extraCharacters - target[propertyName].length; - - target[propertyName] = ''; - - return charactersLeft; -} diff --git a/modules/yieldmoBidAdapter.md b/modules/yieldmoBidAdapter.md deleted file mode 100644 index 54be295a1a1..00000000000 --- a/modules/yieldmoBidAdapter.md +++ /dev/null @@ -1,98 +0,0 @@ -# Overview - -``` -Module Name: Yieldmo Bid Adapter -Module Type: Bidder Adapter -Maintainer: opensource@yieldmo.com -Note: Our ads will only render in mobile -``` - -# Description - -Connects to Yieldmo Ad Server for bids. - -Yieldmo bid adapter supports Banner and Video. - -# Test Parameters - -## Banner - -Sample banner ad unit config: -```javascript -var adUnits = [{ // Banner adUnit - code: 'div-gpt-ad-1460505748561-0', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - } - }, - bids: [{ - bidder: 'yieldmo', - params: { - placementId: '1779781193098233305', // string with at most 19 characters (may include numbers only) - bidFloor: .28 // optional param - } - }] -}]; -``` - -## Video - -Sample instream video ad unit config: -```javascript -var adUnits = [{ // Video adUnit - code: 'div-video-ad-1234567890', - mediaTypes: { - video: { - playerSize: [640, 480], // required - context: 'instream', - mimes: ['video/mp4'] // required, array of strings - } - }, - bids: [{ - bidder: 'yieldmo', - params: { - placementId: '1524592390382976659', // required - video: { - placement: 1, // required, integer - maxduration: 30, // required, integer - minduration: 15, // optional, integer - pos: 1, // optional, integer - startdelay: 10, // required if placement == 1 - protocols: [2, 3], // required, array of integers - api: [2, 3], // required, array of integers - playbackmethod: [2,6], // required, array of integers - skippable: true, // optional, boolean - skipafter: 10 // optional, integer - } - } - }] -}]; -``` - -Sample out-stream video ad unit config: -```javascript -var videoAdUnit = [{ - code: 'div-video-ad-1234567890', - mediaTypes: { - video: { - playerSize: [640, 480], // required - context: 'outstream', - mimes: ['video/mp4'] // required, array of strings - } - }, - bids: [{ - bidder: 'yieldmo', - params: { - placementId: '1524592390382976659', // required - video: { - placement: 3, // required, integer ( 3,4,5 ) - maxduration: 30, // required, integer - protocols: [2, 3], // required, array of integers - api: [2, 3], // required, array of integers - playbackmethod: [1,2] // required, array of integers - } - } - }] -}]; -``` diff --git a/modules/yieldnexusBidAdapter.md b/modules/yieldnexusBidAdapter.md deleted file mode 100644 index 675e8948a3e..00000000000 --- a/modules/yieldnexusBidAdapter.md +++ /dev/null @@ -1,53 +0,0 @@ -# Overview - -``` -Module Name: YieldNexus Bid Adapter -Module Type: Bidder Adapter -Maintainer: rtbops@yieldnexus.com -``` - -# Description - -Adds support to query the YieldNexus platform for bids. The YieldNexus platform supports banners & video. - -Only one parameter is required: `spid`, which provides your YieldNexus account number. - -# Test Parameters -``` -var adUnits = [ - // Banner: - { - code: 'banner-ad-unit', - sizes: [[300, 250]], - bids: [{ - bidder: 'yieldnexus', - params: { - spid: '1253', // your supply ID in your YieldNexus dashboard - bidfloor: 0.03, // an optional custom bid floor - adpos: 1, // ad position on the page (optional) - instl: 0 // interstitial placement? (0 or 1, optional) - } - }] - }, - // Outstream video: - { - code: 'video-ad-unit', - sizes: [[640, 480]], - mediaTypes: { - video: { - context: 'outstream', - playerSize: [640, 480] - } - }, - bids: [ { - bidder: 'yieldnexus', - params: { - spid: '1254', // your supply ID in your YieldNexus dashboard - bidfloor: 0.03, // an optional custom bid floor - adpos: 1, // ad position on the page (optional) - instl: 0 // interstitial placement? (0 or 1, optional) - } - }] - } -]; -``` diff --git a/modules/yieldoneAnalyticsAdapter.js b/modules/yieldoneAnalyticsAdapter.js deleted file mode 100644 index 542c0917708..00000000000 --- a/modules/yieldoneAnalyticsAdapter.js +++ /dev/null @@ -1,183 +0,0 @@ -import {ajax} from '../src/ajax.js'; -import adapter from '../src/AnalyticsAdapter.js'; -import CONSTANTS from '../src/constants.json'; -import adapterManager from '../src/adapterManager.js'; -import { targeting } from '../src/targeting.js'; -import { auctionManager } from '../src/auctionManager.js'; -import * as utils from '../src/utils.js'; - -const ANALYTICS_CODE = 'yieldone'; -const analyticsType = 'endpoint'; -// const VERSION = '1.0.0'; -const defaultUrl = 'https://pool.tsukiji.iponweb.net/hba'; -const requestedBidders = {}; -const requestedBids = {}; -const referrers = {}; -const ignoredEvents = {}; -ignoredEvents[CONSTANTS.EVENTS.BID_ADJUSTMENT] = true; -ignoredEvents[CONSTANTS.EVENTS.BIDDER_DONE] = true; -ignoredEvents[CONSTANTS.EVENTS.AUCTION_END] = true; - -let currentAuctionId = ''; -let url = defaultUrl; -let pubId = ''; - -function makeAdUnitNameMap() { - if (window.googletag && window.googletag.pubads) { - // eslint-disable-next-line no-undef - const p = googletag.pubads(); - if (p && p.getSlots) { - const slots = p.getSlots(); - if (slots && slots.length) { - const map = {}; - slots.forEach((slot) => { - const id = slot.getSlotElementId(); - const name = (slot.getAdUnitPath() || '').split('/').pop(); - map[id] = name; - }); - return map; - } - } - } -} - -function addAdUnitNameForArray(ar, map) { - if (utils.isArray(ar)) { - ar.forEach((it) => { addAdUnitName(it, map) }); - } -} - -function addAdUnitName(params, map) { - if (params.adUnitCode && map[params.adUnitCode]) { - params.adUnitName = map[params.adUnitCode]; - } - if (utils.isArray(params.adUnits)) { - params.adUnits.forEach((adUnit) => { - if (adUnit.code && map[adUnit.code]) { - adUnit.name = map[adUnit.code]; - } - }); - } - if (utils.isArray(params.adUnitCodes)) { - params.adUnitNames = params.adUnitCodes.map((code) => map[code]); - } - ['bids', 'bidderRequests', 'bidsReceived', 'noBids'].forEach((it) => { - addAdUnitNameForArray(params[it], map); - }); -} - -const yieldoneAnalytics = Object.assign(adapter({analyticsType}), { - getUrl() { return url; }, - track({eventType, args = {}}) { - if (eventType === CONSTANTS.EVENTS.BID_REQUESTED) { - const reqBidderId = `${args.bidderCode}_${args.auctionId}`; - requestedBidders[reqBidderId] = utils.deepClone(args); - requestedBidders[reqBidderId].bids = []; - args.bids.forEach((bid) => { - requestedBids[`${bid.bidId}_${bid.auctionId}`] = bid; - }); - } - if (eventType === CONSTANTS.EVENTS.BID_TIMEOUT && utils.isArray(args)) { - const eventsStorage = yieldoneAnalytics.eventsStorage; - const reqBidders = {}; - args.forEach((bid) => { - const reqBidId = `${bid.bidId}_${bid.auctionId}`; - const reqBidderId = `${bid.bidder}_${bid.auctionId}`; - 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]}); - delete requestedBidders[reqBidderId]; - } - reqBidders[bid.bidder].bids.push(requestedBids[reqBidId]); - delete requestedBids[reqBidId]; - } - }); - } else { - currentAuctionId = args.auctionId || currentAuctionId; - if (currentAuctionId) { - const eventsStorage = yieldoneAnalytics.eventsStorage; - if (!eventsStorage[currentAuctionId]) eventsStorage[currentAuctionId] = {events: []}; - const referrer = args.refererInfo && args.refererInfo.referer; - if (referrer && referrers[currentAuctionId] !== referrer) { - referrers[currentAuctionId] = referrer; - } - const params = Object.assign({}, args); - delete params.ad; - if (params.bidsReceived) { - params.bidsReceived = params.bidsReceived.map((bid) => { - const res = Object.assign({}, bid); - delete res.ad; - return res; - }); - } - if (!ignoredEvents[eventType]) { - eventsStorage[currentAuctionId].events.push({eventType, params}); - } - - if ( - eventType === CONSTANTS.EVENTS.AUCTION_END || eventType === CONSTANTS.EVENTS.BID_WON - ) { - params.adServerTargeting = targeting.getAllTargeting( - auctionManager.getAdUnitCodes(), - auctionManager.getBidsReceived() - ); - if (yieldoneAnalytics.eventsStorage[currentAuctionId] && yieldoneAnalytics.eventsStorage[currentAuctionId].events.length) { - yieldoneAnalytics.eventsStorage[currentAuctionId].page = {url: referrers[currentAuctionId]}; - yieldoneAnalytics.eventsStorage[currentAuctionId].pubId = pubId; - yieldoneAnalytics.eventsStorage[currentAuctionId].wrapper_version = '$prebid.version$'; - const adUnitNameMap = makeAdUnitNameMap(); - if (adUnitNameMap) { - yieldoneAnalytics.eventsStorage[currentAuctionId].events.forEach((it) => { - addAdUnitName(it.params, adUnitNameMap); - }); - } - } - yieldoneAnalytics.sendStat(yieldoneAnalytics.eventsStorage[currentAuctionId], currentAuctionId); - } - } - } - }, - sendStat(data, auctionId) { - if (!data || !data.events || !data.events.length) return; - delete yieldoneAnalytics.eventsStorage[auctionId]; - ajax( - url, - { - success: function() {}, - error: function() {} - }, - JSON.stringify(data), - { - method: 'POST' - } - ); - } -}); - -yieldoneAnalytics.eventsStorage = {}; - -// save the base class function -yieldoneAnalytics.originEnableAnalytics = yieldoneAnalytics.enableAnalytics; - -// override enableAnalytics so we can get access to the config passed in from the page -yieldoneAnalytics.enableAnalytics = function (config) { - const options = config && config.options; - if (options) { - if (typeof options.url === 'string') { - url = options.url; - } - if (options.pubId) { - pubId = options.pubId.toString(); - } - } - yieldoneAnalytics.originEnableAnalytics(config); // call the base class function -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: yieldoneAnalytics, - code: ANALYTICS_CODE -}); - -export default yieldoneAnalytics; diff --git a/modules/yieldoneAnalyticsAdapter.md b/modules/yieldoneAnalyticsAdapter.md deleted file mode 100644 index 43be87b114b..00000000000 --- a/modules/yieldoneAnalyticsAdapter.md +++ /dev/null @@ -1,21 +0,0 @@ -# Overview -Module Name: Platform One Analytics - -Module Type: Analytics Adapter - -Maintainer: y1s@platform-one.co.jp - -# Description - -Analytics adapter for Platform One. Please contact y1s@platform-one.co.jp for any additional information. Official website link to the vendor: www.platform-one.co.jp/. - -# Test Parameters - -``` -{ - provider: 'yieldone', - options : { - pubId : 'TestAnalyticsPublisher', //id provided by Platform One publisher team - } -} -``` \ No newline at end of file diff --git a/modules/yieldoneBidAdapter.js b/modules/yieldoneBidAdapter.js deleted file mode 100644 index 574967db291..00000000000 --- a/modules/yieldoneBidAdapter.js +++ /dev/null @@ -1,205 +0,0 @@ -import * as utils from '../src/utils.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import { Renderer } from '../src/Renderer.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; - -const BIDDER_CODE = 'yieldone'; -const ENDPOINT_URL = 'https://y.one.impact-ad.jp/h_bid'; -const USER_SYNC_URL = 'https://y.one.impact-ad.jp/push_sync'; -const VIDEO_PLAYER_URL = 'https://img.ak.impact-ad.jp/ic/pone/ivt/firstview/js/dac-video-prebid.min.js'; -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'; - -export const spec = { - code: BIDDER_CODE, - aliases: ['y1'], - supportedMediaTypes: [BANNER, VIDEO], - isBidRequestValid: function(bid) { - return !!(bid.params.placementId); - }, - buildRequests: function(validBidRequests, bidderRequest) { - return validBidRequests.map(bidRequest => { - const params = bidRequest.params; - const placementId = params.placementId; - const cb = Math.floor(Math.random() * 99999999999); - const referrer = bidderRequest.refererInfo.referer; - const bidId = bidRequest.bidId; - const transactionId = bidRequest.transactionId; - const unitCode = bidRequest.adUnitCode; - const timeout = config.getConfig('bidderTimeout'); - const payload = { - v: 'hb1', - p: placementId, - cb: cb, - r: referrer, - uid: bidId, - tid: transactionId, - uc: unitCode, - tmax: timeout, - t: 'i' - }; - - const videoMediaType = utils.deepAccess(bidRequest, 'mediaTypes.video'); - if ((utils.isEmpty(bidRequest.mediaType) && utils.isEmpty(bidRequest.mediaTypes)) || - (bidRequest.mediaType === BANNER || (bidRequest.mediaTypes && bidRequest.mediaTypes[BANNER]))) { - const sizes = utils.deepAccess(bidRequest, 'mediaTypes.banner.sizes') || bidRequest.sizes; - payload.sz = utils.parseSizesInput(sizes).join(','); - } else if (bidRequest.mediaType === VIDEO || videoMediaType) { - const sizes = utils.deepAccess(bidRequest, 'mediaTypes.video.playerSize') || bidRequest.sizes; - const size = utils.parseSizesInput(sizes)[0]; - payload.w = size.split('x')[0]; - payload.h = size.split('x')[1]; - } - - return { - method: 'GET', - url: ENDPOINT_URL, - data: payload, - } - }); - }, - interpretResponse: function(serverResponse, bidRequest) { - const bidResponses = []; - const response = serverResponse.body; - const crid = response.crid || 0; - const width = response.width || 0; - const height = response.height || 0; - const cpm = response.cpm * 1000 || 0; - if (width !== 0 && height !== 0 && cpm !== 0 && crid !== 0) { - const dealId = response.dealId || ''; - const renderId = response.renderid || ''; - const currency = response.currency || 'JPY'; - const netRevenue = (response.netRevenue === undefined) ? true : response.netRevenue; - const referrer = bidRequest.data.r || ''; - const bidResponse = { - requestId: response.uid, - cpm: cpm, - width: response.width, - height: response.height, - creativeId: crid, - dealId: dealId, - currency: currency, - netRevenue: netRevenue, - ttl: config.getConfig('_bidderTimeout'), - referrer: referrer - }; - - if (response.adTag && renderId === 'ViewableRendering') { - bidResponse.mediaType = BANNER; - let viewableScript = ` - - - `; - bidResponse.ad = viewableScript; - } else if (response.adTag) { - bidResponse.mediaType = BANNER; - bidResponse.ad = response.adTag; - } else if (response.adm) { - bidResponse.mediaType = VIDEO; - bidResponse.vastXml = response.adm; - if (renderId === 'cmer') { - bidResponse.renderer = newCmerRenderer(response); - } else { - bidResponse.renderer = newRenderer(response); - } - } - - bidResponses.push(bidResponse); - } - return bidResponses; - }, - getUserSyncs: function(syncOptions) { - if (syncOptions.iframeEnabled) { - return [{ - type: 'iframe', - url: USER_SYNC_URL - }]; - } - }, -} - -function newRenderer(response) { - const renderer = Renderer.install({ - id: response.uid, - url: VIDEO_PLAYER_URL, - loaded: false, - }); - - try { - renderer.setRender(outstreamRender); - } catch (err) { - utils.logWarn('Prebid Error calling setRender on newRenderer', err); - } - - return renderer; -} - -function outstreamRender(bid) { - bid.renderer.push(() => { - window.DACIVTPREBID.renderPrebid(bid); - }); -} - -function newCmerRenderer(response) { - const renderer = Renderer.install({ - id: response.uid, - url: CMER_PLAYER_URL, - loaded: false, - }); - - try { - renderer.setRender(cmerRender); - } catch (err) { - utils.logWarn('Prebid Error calling setRender on newRenderer', err); - } - - return renderer; -} - -function cmerRender(bid) { - bid.renderer.push(() => { - window.CMERYONEPREBID.renderPrebid(bid); - }); -} - -registerBidder(spec); diff --git a/modules/yieldoneBidAdapter.md b/modules/yieldoneBidAdapter.md deleted file mode 100644 index 1414d4e464f..00000000000 --- a/modules/yieldoneBidAdapter.md +++ /dev/null @@ -1,65 +0,0 @@ -# Overview - -``` -Module Name: YIELDONE Bidder Adapter -Module Type: Bidder Adapter -Maintainer: y1dev@platform-one.co.jp -``` - -# Description - -Connect to YIELDONE for bids. - -THE YIELDONE adapter requires setup and approval from the YIELDONE team. -Please reach out to your account team or y1s@platform-one.co.jp for more information. - -Note: THE YIELDONE adapter do not support "multi-format" scenario... if both -banner and video are specified as mediatypes, YIELDONE will treat it as a video unit. - -# Test Parameters -```javascript -var adUnits = [ - // Banner adUnit - { - code: 'banner-div', - mediaTypes: { - banner: { - sizes: [[300, 250], [336, 280]] - } - }, - bids: [{ - bidder: 'yieldone', - params: { - placementId: '36891' - } - }] - }, - // Video adUnit - { - code: 'video-div', - mediaTypes: { - video: { - playerSize: [[640, 480]], - context: 'outstream' - }, - }, - bids: [{ - bidder: 'yieldone', - params: { - placementId: '41993' - } - }] - } -``` - -### Configuration - -YIELDONE recommends the UserSync configuration below. Without it, the YIELDONE adapter will not able to perform user syncs, which lowers match rate and reduces monetization. - -```javascript -pbjs.setConfig({ - userSync: { - iframeEnabled: true, - enabledBidders: ['yieldone'] - }}); -``` diff --git a/modules/yuktamediaAnalyticsAdapter.js b/modules/yuktamediaAnalyticsAdapter.js deleted file mode 100644 index 2ef2d251ace..00000000000 --- a/modules/yuktamediaAnalyticsAdapter.js +++ /dev/null @@ -1,265 +0,0 @@ -import { ajax } from '../src/ajax.js'; -import adapter from '../src/AnalyticsAdapter.js'; -import adapterManager from '../src/adapterManager.js'; -import CONSTANTS from '../src/constants.json'; -import * as utils from '../src/utils.js'; -import { getStorageManager } from '../src/storageManager.js'; -import { getRefererInfo } from '../src/refererDetection.js'; -import strIncludes from 'core-js-pure/features/string/includes.js'; - -const storage = getStorageManager(); -const yuktamediaAnalyticsVersion = 'v3.1.0'; - -let initOptions; - -const events = { - auctions: {} -}; -const localStoragePrefix = 'yuktamediaAnalytics_'; -const utmTags = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content']; -const location = utils.getWindowLocation(); -const referer = getRefererInfo().referer; -const _pageInfo = { - userAgent: window.navigator.userAgent, - timezoneOffset: new Date().getTimezoneOffset(), - language: window.navigator.language, - screenWidth: window.screen.width, - screenHeight: window.screen.height, - pageViewId: utils.generateUUID(), - host: location.host, - path: location.pathname, - search: location.search, - hash: location.hash, - referer: referer, - refererDomain: utils.parseUrl(referer).host, - yuktamediaAnalyticsVersion: yuktamediaAnalyticsVersion, - prebidVersion: $$PREBID_GLOBAL$$.version -}; - -function getParameterByName(param) { - let vars = {}; - window.location.href.replace(location.hash, '').replace( - /[?&]+([^=&]+)=?([^&]*)?/gi, - function (m, key, value) { - vars[key] = value !== undefined ? value : ''; - } - ); - return vars[param] ? vars[param] : ''; -} - -function isNavigatorSendBeaconSupported() { - return ('navigator' in window) && ('sendBeacon' in window.navigator); -} - -function updateSessionId() { - if (isSessionIdTimeoutExpired()) { - let newSessionId = utils.generateUUID(); - storage.setDataInLocalStorage(localStoragePrefix.concat('session_id'), newSessionId); - } - initOptions.sessionId = getSessionId(); - updateSessionIdTimeout(); -} - -function updateSessionIdTimeout() { - storage.setDataInLocalStorage(localStoragePrefix.concat('session_timeout'), Date.now()); -} - -function isSessionIdTimeoutExpired() { - let cpmSessionTimestamp = storage.getDataFromLocalStorage(localStoragePrefix.concat('session_timeout')); - return Date.now() - cpmSessionTimestamp > 3600000; -} - -function getSessionId() { - return storage.getDataFromLocalStorage(localStoragePrefix.concat('session_id')) ? storage.getDataFromLocalStorage(localStoragePrefix.concat('session_id')) : ''; -} - -function isUtmTimeoutExpired() { - let utmTimestamp = storage.getDataFromLocalStorage(localStoragePrefix.concat('utm_timeout')); - return (Date.now() - utmTimestamp) > 3600000; -} - -function send(data, status) { - data.initOptions = Object.assign(_pageInfo, initOptions); - const yuktamediaAnalyticsRequestUrl = utils.buildUrl({ - protocol: 'https', - hostname: 'analytics-prebid.yuktamedia.com', - pathname: '/api/bids' - }); - if (isNavigatorSendBeaconSupported()) { - window.navigator.sendBeacon(yuktamediaAnalyticsRequestUrl, JSON.stringify(data)); - } else { - ajax(yuktamediaAnalyticsRequestUrl, undefined, JSON.stringify(data), { method: 'POST', contentType: 'text/plain' }); - } -} - -var yuktamediaAnalyticsAdapter = Object.assign(adapter({ analyticsType: 'endpoint' }), { - track({ eventType, args }) { - if (typeof args !== 'undefined') { - switch (eventType) { - case CONSTANTS.EVENTS.AUCTION_INIT: - utils.logInfo(localStoragePrefix + 'AUCTION_INIT:', JSON.stringify(args)); - if (typeof args.auctionId !== 'undefined' && args.auctionId.length) { - events.auctions[args.auctionId] = { bids: {} }; - } - break; - case CONSTANTS.EVENTS.BID_REQUESTED: - utils.logInfo(localStoragePrefix + 'BID_REQUESTED:', JSON.stringify(args)); - if (typeof args.auctionId !== 'undefined' && args.auctionId.length) { - if (typeof events.auctions[args.auctionId] === 'undefined') { - events.auctions[args.auctionId] = { bids: {} }; - } - events.auctions[args.auctionId]['timeStamp'] = args.start; - args.bids.forEach(function (bidRequest) { - events.auctions[args.auctionId]['bids'][bidRequest.bidId] = { - bidder: bidRequest.bidder, - adUnit: bidRequest.adUnitCode, - sizes: utils.parseSizesInput(bidRequest.sizes).toString(), - isBid: false, - won: false, - timeout: false, - renderStatus: 'bid-requested', - bidId: bidRequest.bidId, - auctionId: args.auctionId - } - if (typeof initOptions.enableUserIdCollection !== 'undefined' && initOptions.enableUserIdCollection && typeof bidRequest['userId'] !== 'undefined') { - for (let [userIdProvider, userId] in Object.entries(bidRequest['userId'])) { - userIdProvider = typeof userIdProvider !== 'string' ? JSON.stringify(userIdProvider) : userIdProvider; - userId = typeof userId !== 'string' ? JSON.stringify(userId) : userId; - events.auctions[args.auctionId]['bids'][bidRequest.bidId]['userID-'.concat(userIdProvider)] = userId; - } - } - }); - } - break; - case CONSTANTS.EVENTS.BID_RESPONSE: - utils.logInfo(localStoragePrefix + 'BID_RESPONSE:', JSON.stringify(args)); - if (typeof args.auctionId !== 'undefined' && args.auctionId.length) { - if (typeof events.auctions[args.auctionId] === 'undefined') { - events.auctions[args.auctionId] = { bids: {} }; - } else if (Object.keys(events.auctions[args.auctionId]['bids']).length) { - let bidResponse = events.auctions[args.auctionId]['bids'][args.requestId]; - bidResponse.isBid = args.getStatusCode() === CONSTANTS.STATUS.GOOD; - bidResponse.cpm = args.cpm; - bidResponse.currency = args.currency; - bidResponse.netRevenue = args.netRevenue; - bidResponse.dealId = typeof args.dealId !== 'undefined' ? args.dealId : ''; - bidResponse.mediaType = args.mediaType; - if (bidResponse.mediaType === 'native') { - bidResponse.nativeTitle = typeof args['native']['title'] !== 'undefined' ? args['native']['title'] : ''; - bidResponse.nativeSponsoredBy = typeof args['native']['sponsoredBy'] !== 'undefined' ? args['native']['sponsoredBy'] : ''; - } - bidResponse.timeToRespond = args.timeToRespond; - bidResponse.requestTimestamp = args.requestTimestamp; - bidResponse.responseTimestamp = args.responseTimestamp; - bidResponse.bidForSize = args.size; - for (const [adserverTargetingKey, adserverTargetingValue] of Object.entries(args.adserverTargeting)) { - if (['body', 'icon', 'image', 'linkurl', 'host', 'path'].every((ele) => !strIncludes(adserverTargetingKey, ele))) { - bidResponse['adserverTargeting-' + adserverTargetingKey] = adserverTargetingValue; - } - } - bidResponse.renderStatus = 'bid-response-received'; - } - } - break; - case CONSTANTS.EVENTS.NO_BID: - utils.logInfo(localStoragePrefix + 'NO_BID:', JSON.stringify(args)); - if (typeof args.auctionId !== 'undefined' && args.auctionId.length) { - if (typeof events.auctions[args.auctionId] === 'undefined') { - events.auctions[args.auctionId] = { bids: {} }; - } else if (Object.keys(events.auctions[args.auctionId]['bids']).length) { - const noBid = events.auctions[args.auctionId]['bids'][args.bidId]; - noBid.renderStatus = 'no-bid'; - } - } - break; - case CONSTANTS.EVENTS.BID_WON: - utils.logInfo(localStoragePrefix + 'BID_WON:', JSON.stringify(args)); - if (typeof initOptions.enableSession !== 'undefined' && initOptions.enableSession) { - updateSessionId(); - } - if (typeof args.auctionId !== 'undefined' && args.auctionId.length) { - if (typeof events.auctions[args.auctionId] === 'undefined') { - events.auctions[args.auctionId] = { bids: {} }; - } else if (Object.keys(events.auctions[args.auctionId]['bids']).length) { - const wonBid = events.auctions[args.auctionId]['bids'][args.requestId]; - wonBid.won = true; - wonBid.renderStatus = 'bid-won'; - send({ 'bids': [wonBid] }, 'won'); - } - } - break; - case CONSTANTS.EVENTS.BID_TIMEOUT: - utils.logInfo(localStoragePrefix + 'BID_TIMEOUT:', JSON.stringify(args)); - if (args.length) { - args.forEach(timeout => { - if (typeof timeout !== 'undefined' && typeof timeout.auctionId !== 'undefined' && timeout.auctionId.length) { - if (typeof events.auctions[args.auctionId] === 'undefined') { - events.auctions[args.auctionId] = { bids: {} }; - } else if (Object.keys(events.auctions[args.auctionId]['bids']).length) { - const timeoutBid = events.auctions[timeout.auctionId].bids[timeout.bidId]; - timeoutBid.timeout = true; - timeoutBid.renderStatus = 'bid-timedout'; - } - } - }); - } - break; - case CONSTANTS.EVENTS.AUCTION_END: - utils.logInfo(localStoragePrefix + 'AUCTION_END:', JSON.stringify(args)); - if (typeof initOptions.enableSession !== 'undefined' && initOptions.enableSession) { - updateSessionId(); - } - if (typeof args.auctionId !== 'undefined' && args.auctionId.length) { - const bids = Object.values(events.auctions[args.auctionId]['bids']); - send({ 'bids': bids }, 'auctionEnd'); - } - break; - } - } - } -}); - -yuktamediaAnalyticsAdapter.buildUtmTagData = function (options) { - let utmTagData = {}; - let utmTagsDetected = false; - if (typeof options.enableUTMCollection !== 'undefined' && options.enableUTMCollection) { - utmTags.forEach(function (utmTagKey) { - let utmTagValue = getParameterByName(utmTagKey); - if (utmTagValue !== '') { - utmTagsDetected = true; - } - utmTagData[utmTagKey] = utmTagValue; - }); - utmTags.forEach(function (utmTagKey) { - if (utmTagsDetected) { - storage.setDataInLocalStorage(localStoragePrefix.concat(utmTagKey), utmTagData[utmTagKey]); - storage.setDataInLocalStorage(localStoragePrefix.concat('utm_timeout'), Date.now()); - } else { - if (!isUtmTimeoutExpired()) { - utmTagData[utmTagKey] = storage.getDataFromLocalStorage(localStoragePrefix.concat(utmTagKey)) ? storage.getDataFromLocalStorage(localStoragePrefix.concat(utmTagKey)) : ''; - storage.setDataInLocalStorage(localStoragePrefix.concat('utm_timeout'), Date.now()); - } - } - }); - } - return utmTagData; -}; - -yuktamediaAnalyticsAdapter.originEnableAnalytics = yuktamediaAnalyticsAdapter.enableAnalytics; -yuktamediaAnalyticsAdapter.enableAnalytics = function (config) { - if (config && config.options) { - if (typeof config.options.pubId === 'undefined' || typeof config.options.pubKey === 'undefined') { - utils.logError('Need pubId and pubKey to log auction results. Please contact a YuktaMedia representative if you do not know your pubId and pubKey.'); - return; - } - } - initOptions = Object.assign({}, config.options, this.buildUtmTagData(config.options)); - yuktamediaAnalyticsAdapter.originEnableAnalytics(config); -}; - -adapterManager.registerAnalyticsAdapter({ - adapter: yuktamediaAnalyticsAdapter, - code: 'yuktamedia' -}); - -export default yuktamediaAnalyticsAdapter; diff --git a/modules/yuktamediaAnalyticsAdapter.md b/modules/yuktamediaAnalyticsAdapter.md deleted file mode 100644 index af47985c834..00000000000 --- a/modules/yuktamediaAnalyticsAdapter.md +++ /dev/null @@ -1,25 +0,0 @@ -# Overview -Module Name: YuktaOne Analytics by YuktaMedia - -Module Type: Analytics Adapter - -Maintainer: info@yuktamedia.com - -# Description - -Analytics adapter for prebid provided by YuktaMedia. Contact info@yuktamedia.com for information. - -# Test Parameters - -``` -{ - provider: 'yuktamedia', - options : { - pubId : 50357, // id provided by YuktaMedia LLP - pubKey: 'xxx', // key provided by YuktaMedia LLP - enableUTMCollection: true, // set true if want to collect utm info - enableSession: true, // set true if want to collect information by sessions - enableUserIdCollection: true // set true if want to collect user ID module info - } -} -``` diff --git a/modules/zedoBidAdapter.js b/modules/zedoBidAdapter.js deleted file mode 100644 index e75b9c82065..00000000000 --- a/modules/zedoBidAdapter.js +++ /dev/null @@ -1,342 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import find from 'core-js-pure/features/array/find'; -import { Renderer } from '../src/Renderer.js'; -import { getRefererInfo } from '../src/refererDetection.js'; - -const BIDDER_CODE = 'zedo'; -const SECURE_URL = 'https://saxp.zedo.com/asw/fmh.json'; -const DIM_TYPE = { - '7': 'display', - '9': 'display', - '14': 'display', - '70': 'SBR', - '83': 'CurtainRaiser', - '85': 'Inarticle', - '86': 'pswipeup', - '88': 'Inview', - '100': 'display', - '101': 'display', - '102': 'display', - '103': 'display' - // '85': 'pre-mid-post-roll', -}; -const SECURE_EVENT_PIXEL_URL = 'tt1.zedo.com/log/p.gif'; - -export const spec = { - code: BIDDER_CODE, - aliases: [], - supportedMediaTypes: [BANNER, VIDEO], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {object} bid The bid to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - return !!(bid.params && bid.params.channelCode && bid.params.dimId); - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {BidRequest[]} bidRequests A non-empty list of bid requests which should be sent to the Server. - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (bidRequests, bidderRequest) { - let data = { - placements: [] - }; - bidRequests.map(bidRequest => { - let channelCode = parseInt(bidRequest.params.channelCode); - let network = parseInt(channelCode / 1000000); - let channel = channelCode % 1000000; - let dim = getSizes(bidRequest.sizes); - let placement = { - id: bidRequest.bidId, - network: network, - channel: channel, - publisher: bidRequest.params.pubId ? bidRequest.params.pubId : 0, - width: dim[0], - height: dim[1], - dimension: bidRequest.params.dimId, - version: '$prebid.version$', - keyword: '', - transactionId: bidRequest.transactionId - } - if (bidderRequest && bidderRequest.gdprConsent) { - if (typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') { - data.gdpr = Number(bidderRequest.gdprConsent.gdprApplies); - } - data.gdpr_consent = bidderRequest.gdprConsent.consentString; - } - // Add CCPA consent string - if (bidderRequest && bidderRequest.uspConsent) { - data.usp = bidderRequest.uspConsent; - } - - let dimType = DIM_TYPE[String(bidRequest.params.dimId)] - if (dimType) { - placement['renderers'] = [{ - 'name': dimType - }] - } else { // default to display - placement['renderers'] = [{ - 'name': 'display' - }] - } - data['placements'].push(placement); - }); - // adding schain object - if (bidRequests[0].schain) { - data['supplyChain'] = getSupplyChain(bidRequests[0].schain); - } - return { - method: 'GET', - url: SECURE_URL, - data: 'g=' + JSON.stringify(data) - } - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {*} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function (serverResponse, request) { - serverResponse = serverResponse.body; - const bids = []; - if (!serverResponse || serverResponse.error) { - let errorMessage = `in response for ${request.bidderCode} adapter`; - if (serverResponse && serverResponse.error) { errorMessage += `: ${serverResponse.error}`; } - utils.logError(errorMessage); - return bids; - } - - if (serverResponse.ad) { - serverResponse.ad.forEach(ad => { - const creativeBid = getCreative(ad); - if (creativeBid) { - if (parseInt(creativeBid.cpm) !== 0) { - const bid = newBid(ad, creativeBid, request); - bid.mediaType = parseMediaType(creativeBid); - bids.push(bid); - } - } - }); - } - return bids; - }, - - getUserSyncs: function (syncOptions, responses, gdprConsent) { - if (syncOptions.iframeEnabled) { - let url = 'https://tt3.zedo.com/rs/us/fcs.html'; - if (gdprConsent && typeof gdprConsent.consentString === 'string') { - // add 'gdpr' only if 'gdprApplies' is defined - if (typeof gdprConsent.gdprApplies === 'boolean') { - url += `?gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`; - } else { - url += `?gdpr_consent=${gdprConsent.consentString}`; - } - } - return [{ - type: 'iframe', - url: url - }]; - } - }, - - onTimeout: function (timeoutData) { - try { - logEvent('117', timeoutData); - } catch (e) { - utils.logError(e); - } - }, - - onBidWon: function (bid) { - try { - logEvent('116', [bid]); - } catch (e) { - utils.logError(e); - } - } - -}; - -function getSupplyChain (supplyChain) { - return { - complete: supplyChain.complete, - nodes: supplyChain.nodes - } -}; - -function getCreative(ad) { - return ad && ad.creatives && ad.creatives.length && find(ad.creatives, creative => creative.adId); -}; -/** - * Unpack the Server's Bid into a Prebid-compatible one. - * @param serverBid - * @param rtbBid - * @param bidderRequest - * @return Bid - */ -function newBid(serverBid, creativeBid, bidderRequest) { - const bid = { - requestId: serverBid.slotId, - creativeId: creativeBid.adId, - network: serverBid.network, - adType: creativeBid.creativeDetails.type, - dealId: 99999999, - currency: 'USD', - netRevenue: true, - ttl: 300 - }; - - if (creativeBid.creativeDetails.type === 'VAST') { - Object.assign(bid, { - width: creativeBid.width, - height: creativeBid.height, - vastXml: creativeBid.creativeDetails.adContent, - cpm: parseInt(creativeBid.bidCpm) / 1000000, - ttl: 3600 - }); - const rendererOptions = utils.deepAccess( - bidderRequest, - 'renderer.options' - ); - let rendererUrl = 'https://ss3.zedo.com/gecko/beta/fmpbgt.min.js'; - Object.assign(bid, { - adResponse: serverBid, - renderer: getRenderer(bid.adUnitCode, serverBid.slotId, rendererUrl, rendererOptions) - }); - } else { - Object.assign(bid, { - width: creativeBid.width, - height: creativeBid.height, - cpm: parseInt(creativeBid.bidCpm) / 1000000, - ad: creativeBid.creativeDetails.adContent, - }); - } - - return bid; -} -/* Turn bid request sizes into compatible format */ -function getSizes(requestSizes) { - let width = 0; - let height = 0; - if (utils.isArray(requestSizes) && requestSizes.length === 2 && - !utils.isArray(requestSizes[0])) { - width = parseInt(requestSizes[0], 10); - height = parseInt(requestSizes[1], 10); - } else if (typeof requestSizes === 'object') { - for (let i = 0; i < requestSizes.length; i++) { - let size = requestSizes[i]; - width = parseInt(size[0], 10); - height = parseInt(size[1], 10); - break; - } - } - return [width, height]; -} - -function getRenderer(adUnitCode, rendererId, rendererUrl, rendererOptions = {}) { - const renderer = Renderer.install({ - id: rendererId, - url: rendererUrl, - config: rendererOptions, - loaded: false, - }); - - try { - renderer.setRender(videoRenderer); - } catch (err) { - utils.logWarn('Prebid Error calling setRender on renderer', err); - } - - renderer.setEventHandlers({ - impression: () => utils.logMessage('ZEDO video impression'), - loaded: () => utils.logMessage('ZEDO video loaded'), - ended: () => { - utils.logMessage('ZEDO renderer video ended'); - document.querySelector(`#${adUnitCode}`).style.display = 'none'; - } - }); - return renderer; -} - -function videoRenderer(bid) { - // push to render queue - const refererInfo = getRefererInfo(); - let referrer = ''; - if (refererInfo) { - referrer = refererInfo.referer; - } - bid.renderer.push(() => { - let channelCode = utils.deepAccess(bid, 'params.0.channelCode') || 0; - let dimId = utils.deepAccess(bid, 'params.0.dimId') || 0; - let publisher = utils.deepAccess(bid, 'params.0.pubId') || 0; - let options = utils.deepAccess(bid, 'params.0.options') || {}; - let channel = (channelCode > 0) ? (channelCode - (bid.network * 1000000)) : 0; - - var rndr = new window.ZdPBTag(bid.adUnitCode, bid.network, bid.width, bid.height, bid.adType, bid.vastXml, channel, dimId, - (encodeURI(referrer) || ''), options); - rndr.renderAd(publisher); - }); -} - -function parseMediaType(creativeBid) { - const adType = creativeBid.creativeDetails.type; - if (adType === 'VAST') { - return VIDEO; - } else { - return BANNER; - } -} - -function logEvent(eid, data) { - let getParams = { - protocol: 'https', - hostname: SECURE_EVENT_PIXEL_URL, - search: getLoggingData(eid, data) - }; - let eventUrl = utils.buildUrl(getParams).replace(/&/g, ';'); - utils.triggerPixel(eventUrl); -} - -function getLoggingData(eid, data) { - data = (utils.isArray(data) && data) || []; - - let params = {}; - let channel, network, dim, publisher, adunitCode, timeToRespond, cpm; - data.map((adunit) => { - adunitCode = adunit.adUnitCode; - channel = utils.deepAccess(adunit, 'params.0.channelCode') || 0; - network = channel > 0 ? parseInt(channel / 1000000) : 0; - dim = utils.deepAccess(adunit, 'params.0.dimId') * 256 || 0; - publisher = utils.deepAccess(adunit, 'params.0.pubId') || 0; - timeToRespond = adunit.timeout ? adunit.timeout : adunit.timeToRespond; - cpm = adunit.cpm; - }); - let referrer = ''; - const refererInfo = getRefererInfo(); - if (refererInfo) { - referrer = refererInfo.referer; - } - params.n = network; - params.c = channel; - params.s = publisher; - params.x = dim; - params.ai = encodeURI('Prebid^zedo^' + adunitCode + '^' + cpm + '^' + timeToRespond); - params.pu = encodeURI(referrer) || ''; - params.eid = eid; - params.e = 'e'; - params.z = Math.random(); - - return params; -} - -registerBidder(spec); diff --git a/modules/zedoBidAdapter.md b/modules/zedoBidAdapter.md deleted file mode 100644 index 2f31e8aed9b..00000000000 --- a/modules/zedoBidAdapter.md +++ /dev/null @@ -1,65 +0,0 @@ -# Overview - -Module Name: ZEDO Bidder Adapter -Module Type: Bidder Adapter -Maintainer: prebidsupport@zedo.com - -# Description - -Module that connects to ZEDO's demand sources. - -ZEDO supports both display and video. -For video integration, ZEDO returns content as vastXML and requires the publisher to define the cache url in config passed to Prebid for it to be valid in the auction - -ZEDO has its own renderer and will render the video unit if not defined in the config. - - -# Test Parameters -# display -``` - - var adUnits = [{ - code: 'div-gpt-ad-1460505748561-0', - mediaTypes: { - banner: { - sizes: [[300, 250], [300,600]], - } - }, - // Replace this object to test a new Adapter! - bids: [{ - bidder: 'zedo', - params: { - channelCode: 2264004735, //REQUIRED - dimId:9 //REQUIRED - } - }] - - }]; -``` -# video -``` - - var adUnit1 = [ - { - code: 'videoAdUnit', - mediaTypes: - { - video: - { - context: 'outstream', - playerSize: [640, 480] - } - }, - bids: [ - { - bidder: 'zedo', - params: - { - channelCode: 2264004735, // required - dimId: 85, // required - pubId: 1 // optional - } - } - ] - }]; -``` \ No newline at end of file diff --git a/modules/zemantaBidAdapter.js b/modules/zemantaBidAdapter.js deleted file mode 100644 index b2c00b69c24..00000000000 --- a/modules/zemantaBidAdapter.js +++ /dev/null @@ -1,281 +0,0 @@ -// jshint esversion: 6, es3: false, node: true -'use strict'; - -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 { config } from '../src/config.js'; - -const BIDDER_CODE = 'zemanta'; -const GVLID = 164; -const CURRENCY = 'USD'; -const NATIVE_ASSET_IDS = { 0: 'title', 2: 'icon', 3: 'image', 5: 'sponsoredBy', 4: 'body', 1: 'cta' }; -const NATIVE_PARAMS = { - title: { id: 0, name: 'title' }, - icon: { id: 2, type: 1, name: 'img' }, - image: { id: 3, type: 3, name: 'img' }, - sponsoredBy: { id: 5, name: 'data', type: 1 }, - body: { id: 4, name: 'data', type: 2 }, - cta: { id: 1, type: 12, name: 'data' } -}; - -export const spec = { - code: BIDDER_CODE, - gvlid: GVLID, - aliases: [ - { code: 'outbrain', gvlid: GVLID } - ], - supportedMediaTypes: [ NATIVE, BANNER ], - isBidRequestValid: (bid) => { - return ( - (!!config.getConfig('zemanta.bidderUrl') || !!config.getConfig('outbrain.bidderUrl')) && - !!utils.deepAccess(bid, 'params.publisher.id') && - !!(bid.nativeParams || bid.sizes) - ); - }, - buildRequests: (validBidRequests, bidderRequest) => { - const page = bidderRequest.refererInfo.referer; - const ua = navigator.userAgent; - const test = setOnAny(validBidRequests, 'params.test'); - const publisher = setOnAny(validBidRequests, 'params.publisher'); - const bcat = setOnAny(validBidRequests, 'params.bcat'); - const badv = setOnAny(validBidRequests, 'params.badv'); - const cur = CURRENCY; - const endpointUrl = config.getConfig('zemanta.bidderUrl') || config.getConfig('outbrain.bidderUrl'); - const timeout = bidderRequest.timeout; - - const imps = validBidRequests.map((bid, id) => { - bid.netRevenue = 'net'; - const imp = { - id: id + 1 + '' - } - - if (bid.params.tagid) { - imp.tagid = bid.params.tagid - } - - if (bid.nativeParams) { - imp.native = { - request: JSON.stringify({ - assets: getNativeAssets(bid) - }) - } - } else { - imp.banner = { - format: transformSizes(bid.sizes) - } - } - - return imp; - }); - - const request = { - id: bidderRequest.auctionId, - site: { page, publisher }, - device: { ua }, - source: { fd: 1 }, - cur: [cur], - tmax: timeout, - imp: imps, - bcat: bcat, - badv: badv, - }; - - if (test) { - request.is_debug = !!test; - request.test = 1; - } - - if (utils.deepAccess(bidderRequest, 'gdprConsent.gdprApplies')) { - utils.deepSetValue(request, 'user.ext.consent', bidderRequest.gdprConsent.consentString) - utils.deepSetValue(request, 'regs.ext.gdpr', bidderRequest.gdprConsent.gdprApplies & 1) - } - if (bidderRequest.uspConsent) { - utils.deepSetValue(request, 'regs.ext.us_privacy', bidderRequest.uspConsent) - } - if (config.getConfig('coppa') === true) { - utils.deepSetValue(request, 'regs.coppa', config.getConfig('coppa') & 1) - } - - return { - method: 'POST', - url: endpointUrl, - data: JSON.stringify(request), - bids: validBidRequests - }; - }, - interpretResponse: (serverResponse, { bids }) => { - if (!serverResponse.body) { - return []; - } - const { seatbid, cur } = serverResponse.body; - - const bidResponses = flatten(seatbid.map(seat => seat.bid)).reduce((result, bid) => { - result[bid.impid - 1] = bid; - return result; - }, []); - - return bids.map((bid, id) => { - const bidResponse = bidResponses[id]; - if (bidResponse) { - const type = bid.nativeParams ? NATIVE : BANNER; - const bidObject = { - requestId: bid.bidId, - cpm: bidResponse.price, - creativeId: bidResponse.crid, - ttl: 360, - netRevenue: bid.netRevenue === 'net', - currency: cur, - mediaType: type, - nurl: bidResponse.nurl, - }; - if (type === NATIVE) { - bidObject.native = parseNative(bidResponse); - } else { - bidObject.ad = bidResponse.adm; - bidObject.width = bidResponse.w; - bidObject.height = bidResponse.h; - } - bidObject.meta = {}; - if (bidResponse.adomain && bidResponse.adomain.length > 0) { - bidObject.meta.advertiserDomains = bidResponse.adomain; - } - return bidObject; - } - }).filter(Boolean); - }, - getUserSyncs: (syncOptions, responses, gdprConsent, uspConsent) => { - const syncs = []; - let syncUrl = config.getConfig('zemanta.usersyncUrl') || config.getConfig('outbrain.usersyncUrl'); - if (syncOptions.pixelEnabled && syncUrl) { - if (gdprConsent) { - syncUrl += '&gdpr=' + (gdprConsent.gdprApplies & 1); - syncUrl += '&gdpr_consent=' + encodeURIComponent(gdprConsent.consentString || ''); - } - if (uspConsent) { - syncUrl += '&us_privacy=' + encodeURIComponent(uspConsent); - } - - syncs.push({ - type: 'image', - url: syncUrl - }); - } - return syncs; - }, - onBidWon: (bid) => { - // for native requests we put the nurl as an imp tracker, otherwise if the auction takes place on prebid server - // the server JS adapter puts the nurl in the adm as a tracking pixel and removes the attribute - if (bid.nurl) { - ajax(utils.replaceAuctionPrice(bid.nurl, bid.originalCpm)) - } - } -}; - -registerBidder(spec); - -function parseNative(bid) { - const { assets, link, eventtrackers } = JSON.parse(bid.adm); - const result = { - clickUrl: link.url, - clickTrackers: link.clicktrackers || undefined - }; - assets.forEach(asset => { - const kind = NATIVE_ASSET_IDS[asset.id]; - const content = kind && asset[NATIVE_PARAMS[kind].name]; - if (content) { - result[kind] = content.text || content.value || { url: content.url, width: content.w, height: content.h }; - } - }); - if (eventtrackers) { - result.impressionTrackers = []; - eventtrackers.forEach(tracker => { - if (tracker.event !== 1) return; - switch (tracker.method) { - case 1: // img - result.impressionTrackers.push(tracker.url); - break; - case 2: // js - result.javascriptTrackers = ``; - break; - } - }); - } - return result; -} - -function setOnAny(collection, key) { - for (let i = 0, result; i < collection.length; i++) { - result = utils.deepAccess(collection[i], key); - if (result) { - return result; - } - } -} - -function flatten(arr) { - return [].concat(...arr); -} - -function getNativeAssets(bid) { - return utils._map(bid.nativeParams, (bidParams, key) => { - const props = NATIVE_PARAMS[key]; - const asset = { - required: bidParams.required & 1, - }; - if (props) { - asset.id = props.id; - let wmin, hmin, w, h; - let aRatios = bidParams.aspect_ratios; - - if (aRatios && aRatios[0]) { - aRatios = aRatios[0]; - wmin = aRatios.min_width || 0; - hmin = aRatios.ratio_height * wmin / aRatios.ratio_width | 0; - } - - if (bidParams.sizes) { - const sizes = flatten(bidParams.sizes); - w = sizes[0]; - h = sizes[1]; - } - - asset[props.name] = { - len: bidParams.len, - type: props.type, - wmin, - hmin, - w, - h - }; - - return asset; - } - }).filter(Boolean); -} - -/* Turn bid request sizes into ut-compatible format */ -function transformSizes(requestSizes) { - if (!utils.isArray(requestSizes)) { - return []; - } - - if (requestSizes.length === 2 && !utils.isArray(requestSizes[0])) { - return [{ - w: parseInt(requestSizes[0], 10), - h: parseInt(requestSizes[1], 10) - }]; - } else if (utils.isArray(requestSizes[0])) { - return requestSizes.map(item => - ({ - w: parseInt(item[0], 10), - h: parseInt(item[1], 10) - }) - ); - } - - return []; -} diff --git a/modules/zemantaBidAdapter.md b/modules/zemantaBidAdapter.md deleted file mode 100644 index fa933ecd922..00000000000 --- a/modules/zemantaBidAdapter.md +++ /dev/null @@ -1,111 +0,0 @@ -# Overview - -``` -Module Name: Zemanta Adapter -Module Type: Bidder Adapter -Maintainer: prog-ops-team@outbrain.com -``` - -# Description - -Module that connects to zemanta bidder to fetch bids. -Both native and display formats are supported but not at the same time. Using OpenRTB standard. - -# Configuration - -## Bidder and usersync URLs - -The Zemanta adapter does not work without setting the correct bidder and usersync URLs. -You will receive the URLs when contacting us. - -``` -pbjs.setConfig({ - zemanta: { - bidderUrl: 'https://bidder-url.com', - usersyncUrl: 'https://usersync-url.com' - } -}); -``` - - -# Test Native Parameters -``` - var adUnits = [ - code: '/19968336/prebid_native_example_1', - mediaTypes: { - native: { - image: { - required: false, - sizes: [100, 50] - }, - title: { - required: false, - len: 140 - }, - sponsoredBy: { - required: false - }, - clickUrl: { - required: false - }, - body: { - required: false - }, - icon: { - required: false, - sizes: [50, 50] - } - } - }, - bids: [{ - bidder: 'zemanta', - params: { - publisher: { - id: '2706', // required - name: 'Publishers Name', - domain: 'publisher.com' - }, - tagid: 'tag-id', - bcat: ['IAB1-1'], - badv: ['example.com'] - } - }] - ]; - - pbjs.setConfig({ - zemanta: { - bidderUrl: 'https://prebidtest.zemanta.com/api/bidder/prebidtest/bid/' - } - }); -``` - -# Test Display Parameters -``` - var adUnits = [ - code: '/19968336/prebid_display_example_1', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [{ - bidder: 'zemanta', - params: { - publisher: { - id: '2706', // required - name: 'Publishers Name', - domain: 'publisher.com' - }, - tagid: 'tag-id', - bcat: ['IAB1-1'], - badv: ['example.com'] - }, - }] - ]; - - pbjs.setConfig({ - zemanta: { - bidderUrl: 'https://prebidtest.zemanta.com/api/bidder/prebidtest/bid/' - } - }); -``` diff --git a/modules/zeotapIdPlusIdSystem.js b/modules/zeotapIdPlusIdSystem.js deleted file mode 100644 index 8f26cc827d6..00000000000 --- a/modules/zeotapIdPlusIdSystem.js +++ /dev/null @@ -1,64 +0,0 @@ -/** - * This module adds Zeotap to the User ID module - * The {@link module:modules/userId} module is required - * @module modules/zeotapIdPlusIdSystem - * @requires module:modules/userId - */ -import * as utils from '../src/utils.js' -import {submodule} from '../src/hook.js'; -import { getStorageManager } from '../src/storageManager.js'; - -const ZEOTAP_COOKIE_NAME = 'IDP'; -const ZEOTAP_VENDOR_ID = 301; -const ZEOTAP_MODULE_NAME = 'zeotapIdPlus'; - -function readCookie() { - return storage.cookiesAreEnabled() ? storage.getCookie(ZEOTAP_COOKIE_NAME) : null; -} - -function readFromLocalStorage() { - return storage.localStorageIsEnabled() ? storage.getDataFromLocalStorage(ZEOTAP_COOKIE_NAME) : null; -} - -export function getStorage() { - return getStorageManager(ZEOTAP_VENDOR_ID, ZEOTAP_MODULE_NAME); -} - -export const storage = getStorage(); - -/** @type {Submodule} */ -export const zeotapIdPlusSubmodule = { - /** - * used to link submodule with config - * @type {string} - */ - name: ZEOTAP_MODULE_NAME, - /** - * Vendor ID of Zeotap - * @type {Number} - */ - gvlid: ZEOTAP_VENDOR_ID, - /** - * decode the stored id value for passing to bid requests - * @function - * @param { Object | string | undefined } value - * @return { Object | string | undefined } - */ - decode(value) { - const id = value ? utils.isStr(value) ? value : utils.isPlainObject(value) ? value.id : undefined : undefined; - return id ? { - 'IDP': JSON.parse(atob(id)) - } : undefined; - }, - /** - * performs action to obtain id and return a value in the callback's response argument - * @function - * @param {SubmoduleConfig} config - * @return {{id: string | undefined} | undefined} - */ - getId() { - const id = readCookie() || readFromLocalStorage(); - return id ? { id } : undefined; - } -}; -submodule('userId', zeotapIdPlusSubmodule); diff --git a/modules/zetaBidAdapter.js b/modules/zetaBidAdapter.js deleted file mode 100644 index ee5c854df97..00000000000 --- a/modules/zetaBidAdapter.js +++ /dev/null @@ -1,185 +0,0 @@ -import * as utils from '../src/utils.js'; -import { registerBidder } from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -const BIDDER_CODE = 'zeta_global'; -const ENDPOINT_URL = 'https://prebid.rfihub.com/prebid'; -const USER_SYNC_URL = 'https://p.rfihub.com/cm?pub=42770&in=1'; -const DEFAULT_CUR = 'USD'; -const TTL = 200; -const NET_REV = true; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function(bid) { - // check for all required bid fields - if (!(bid && - bid.bidId && - bid.params)) { - utils.logWarn('Invalid bid request - missing required bid data'); - return false; - } - - if (!(bid.params.user && - bid.params.user.buyeruid)) { - utils.logWarn('Invalid bid request - missing required user data'); - return false; - } - - if (!(bid.params.device && - bid.params.device.ip)) { - utils.logWarn('Invalid bid request - missing required device data'); - return false; - } - - if (!(bid.params.device.geo && - bid.params.device.geo.country)) { - utils.logWarn('Invalid bid request - missing required geo data'); - return false; - } - - if (!bid.params.definerId) { - utils.logWarn('Invalid bid request - missing required definer data'); - return false; - } - - return true; - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {Bids[]} validBidRequests - an array of bidRequest objects - * @param {BidderRequest} bidderRequest - master bidRequest object - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function(validBidRequests, bidderRequest) { - const secure = 1; // treat all requests as secure - const request = validBidRequests[0]; - const params = request.params; - let impData = { - id: request.bidId, - secure: secure, - banner: buildBanner(request) - }; - let payload = { - id: bidderRequest.auctionId, - imp: [impData], - site: params.site ? params.site : {}, - app: params.app ? params.app : {}, - device: params.device ? params.device : {}, - user: params.user ? params.user : {}, - at: params.at, - tmax: params.tmax, - wseat: params.wseat, - bseat: params.bseat, - allimps: params.allimps, - cur: [DEFAULT_CUR], - wlang: params.wlang, - bcat: params.bcat, - badv: params.badv, - bapp: params.bapp, - source: params.source ? params.source : {}, - ext: params.ext ? params.ext : {} - }; - - payload.device.ua = navigator.userAgent; - payload.site.page = bidderRequest.refererInfo.referer; - payload.site.mobile = /(ios|ipod|ipad|iphone|android)/i.test(navigator.userAgent) ? 1 : 0; - payload.ext.definerId = params.definerId; - - if (params.test) { - payload.test = params.test; - } - if (request.gdprConsent) { - payload.regs = { - ext: { - gdpr: request.gdprConsent.gdprApplies === true ? 1 : 0 - } - }; - } - if (request.gdprConsent && request.gdprConsent.gdprApplies) { - payload.user = { - ext: { - consent: request.gdprConsent.consentString - } - }; - } - const postUrl = params.definerId !== '0' ? ENDPOINT_URL.concat('/', params.definerId) : ENDPOINT_URL; - return { - method: 'POST', - url: postUrl, - data: JSON.stringify(payload), - }; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {ServerResponse} serverResponse A successful response from the server. - * @param bidRequest The payload from the server's response. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function(serverResponse, bidRequest) { - let bidResponse = []; - if (Object.keys(serverResponse.body).length !== 0) { - let zetaResponse = serverResponse.body; - let zetaBid = zetaResponse.seatbid[0].bid[0]; - let bid = { - requestId: zetaBid.impid, - cpm: zetaBid.price, - currency: zetaResponse.cur, - width: zetaBid.w, - height: zetaBid.h, - ad: zetaBid.adm, - ttl: TTL, - creativeId: zetaBid.crid, - netRevenue: NET_REV - }; - bidResponse.push(bid); - } - return bidResponse; - }, - - /** - * Register the user sync pixels which should be dropped after the auction. - * - * @param {SyncOptions} syncOptions Which user syncs are allowed? - * @param {ServerResponse[]} serverResponses List of server's responses. - * @param gdprConsent The GDPR consent parameters - * @param uspConsent The USP consent parameters - * @return {UserSync[]} The user syncs which should be dropped. - */ - getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) { - const syncs = []; - if (syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: USER_SYNC_URL - }); - } - return syncs; - } -} - -function buildBanner(request) { - let sizes = request.sizes; - if (request.mediaTypes && - request.mediaTypes.banner && - request.mediaTypes.banner.sizes) { - sizes = request.mediaTypes.banner.sizes; - } - return { - w: sizes[0][0], - h: sizes[0][1] - }; -} - -registerBidder(spec); diff --git a/modules/zetaBidAdapter.md b/modules/zetaBidAdapter.md deleted file mode 100644 index 89a9767d29a..00000000000 --- a/modules/zetaBidAdapter.md +++ /dev/null @@ -1,45 +0,0 @@ -# Overview - -``` -Module Name: Zeta Bidder Adapter -Module Type: Bidder Adapter -Maintainer: DL-ZetaDSP-Supply-Engineering@zetaglobal.com -``` - -# Description - -Module that connects to Zeta's demand sources - -# Test Parameters -``` - var adUnits = [ - { - mediaTypes: { - banner: { - sizes: [[300, 250]], // a display size - } - }, - bids: [ - { - bidder: 'zeta_global', - bidId: 12345, - params: { - placement: 12345, - user: { - uid: 12345, - buyeruid: 12345 - }, - device: { - ip: '111.222.33.44', - geo: { - country: 'USA' - } - }, - definerId: '0', - test: 1 - } - } - ] - } - ]; -``` diff --git a/modules/zetaSspBidAdapter.js b/modules/zetaSspBidAdapter.js deleted file mode 100644 index e267942862b..00000000000 --- a/modules/zetaSspBidAdapter.js +++ /dev/null @@ -1,159 +0,0 @@ -import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; - -const BIDDER_CODE = 'zeta_global_ssp'; -const ENDPOINT_URL = 'https://ssp.disqus.com/bid'; -const USER_SYNC_URL = 'https://ssp.disqus.com/match'; -const DEFAULT_CUR = 'USD'; -const TTL = 200; -const NET_REV = true; - -export const spec = { - code: BIDDER_CODE, - supportedMediaTypes: [BANNER], - - /** - * Determines whether or not the given bid request is valid. - * - * @param {BidRequest} bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. - */ - isBidRequestValid: function (bid) { - // check for all required bid fields - if (!(bid && - bid.bidId && - bid.params)) { - utils.logWarn('Invalid bid request - missing required bid data'); - return false; - } - return true; - }, - - /** - * Make a server request from the list of BidRequests. - * - * @param {Bids[]} validBidRequests - an array of bidRequest objects - * @param {BidderRequest} bidderRequest - master bidRequest object - * @return ServerRequest Info describing the request to the server. - */ - buildRequests: function (validBidRequests, bidderRequest) { - const secure = 1; // treat all requests as secure - const request = validBidRequests[0]; - const params = request.params; - let impData = { - id: request.bidId, - secure: secure, - banner: buildBanner(request) - }; - const fpd = config.getLegacyFpd(config.getConfig('ortb2')) || {}; - let payload = { - id: bidderRequest.auctionId, - cur: [DEFAULT_CUR], - imp: [impData], - site: params.site ? params.site : {}, - device: fpd.device ? fpd.device : {}, - user: params.user ? params.user : {}, - app: params.app ? params.app : {}, - ext: { - tags: params.tags ? params.tags : {}, - sid: params.sid ? params.sid : {} - } - }; - - payload.device.ua = navigator.userAgent; - payload.site.page = bidderRequest.refererInfo.referer; - payload.site.mobile = /(ios|ipod|ipad|iphone|android)/i.test(navigator.userAgent) ? 1 : 0; - - if (params.test) { - payload.test = params.test; - } - if (request.gdprConsent) { - payload.regs = { - ext: { - gdpr: request.gdprConsent.gdprApplies === true ? 1 : 0 - } - }; - } - if (request.gdprConsent && request.gdprConsent.gdprApplies) { - payload.user = { - ext: { - consent: request.gdprConsent.consentString - } - }; - } - return { - method: 'POST', - url: ENDPOINT_URL, - data: JSON.stringify(payload), - }; - }, - - /** - * Unpack the response from the server into a list of bids. - * - * @param {ServerResponse} serverResponse A successful response from the server. - * @param bidRequest The payload from the server's response. - * @return {Bid[]} An array of bids which were nested inside the server. - */ - interpretResponse: function (serverResponse, bidRequest) { - let bidResponse = []; - if (Object.keys(serverResponse.body).length !== 0) { - let zetaResponse = serverResponse.body; - let zetaBid = zetaResponse.seatbid[0].bid[0]; - let bid = { - requestId: zetaBid.impid, - cpm: zetaBid.price, - currency: zetaResponse.cur, - width: zetaBid.w, - height: zetaBid.h, - ad: zetaBid.adm, - ttl: TTL, - creativeId: zetaBid.crid, - netRevenue: NET_REV, - }; - if (zetaBid.adomain && zetaBid.adomain.length) { - bid.meta = {}; - bid.meta.advertiserDomains = zetaBid.adomain; - } - bidResponse.push(bid); - } - return bidResponse; - }, - - /** - * Register the user sync pixels which should be dropped after the auction. - * - * @param {SyncOptions} syncOptions Which user syncs are allowed? - * @param {ServerResponse[]} serverResponses List of server's responses. - * @param gdprConsent The GDPR consent parameters - * @param uspConsent The USP consent parameters - * @return {UserSync[]} The user syncs which should be dropped. - */ - getUserSyncs: function (syncOptions, serverResponses, gdprConsent, uspConsent) { - const syncs = []; - if (syncOptions.iframeEnabled) { - syncs.push({ - type: 'iframe', - url: USER_SYNC_URL - }); - } - return syncs; - } -} - -function buildBanner(request) { - let sizes = request.sizes; - if (request.mediaTypes && - request.mediaTypes.banner && - request.mediaTypes.banner.sizes) { - sizes = request.mediaTypes.banner.sizes; - } - return { - w: sizes[0][0], - h: sizes[0][1] - }; -} - -registerBidder(spec); diff --git a/modules/zetaSspBidAdapter.md b/modules/zetaSspBidAdapter.md deleted file mode 100644 index d2950bce6b9..00000000000 --- a/modules/zetaSspBidAdapter.md +++ /dev/null @@ -1,42 +0,0 @@ -# Overview - -``` -Module Name: Zeta Ssp Bidder Adapter -Module Type: Bidder Adapter -Maintainer: miakovlev@zetaglobal.com -``` - -# Description - -Module that connects to Zeta's SSP - -# Test Parameters -``` - var adUnits = [ - { - mediaTypes: { - banner: { - sizes: [[300, 250]], // a display size - } - }, - bids: [ - { - bidder: 'zeta_global_ssp', - bidId: 12345, - params: { - placement: 12345, - user: { - uid: 12345, - buyeruid: 12345 - }, - tags: { - someTag: 123, - sid: 'publisherId' - }, - test: 1 - } - } - ] - } - ]; -``` diff --git a/package-lock.json b/package-lock.json index 3c4e59cdba7..a8e31dbf1e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "4.39.0-pre", + "version": "4.40.0-pre", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -6120,13 +6120,21 @@ "dev": true }, "copy-props": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz", - "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.5.tgz", + "integrity": "sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==", "dev": true, "requires": { - "each-props": "^1.3.0", - "is-plain-object": "^2.0.1" + "each-props": "^1.3.2", + "is-plain-object": "^5.0.0" + }, + "dependencies": { + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true + } } }, "core-js": { @@ -10348,15 +10356,15 @@ } }, "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", "dev": true }, "yargs": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.1.tgz", - "integrity": "sha512-huO4Fr1f9PmiJJdll5kwoS2e4GqzGSsMT3PPMpOwoVkOK8ckqAewMTZyA6LXVQWflleb/Z8oPBEvNsMft0XE+g==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.2.tgz", + "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==", "dev": true, "requires": { "camelcase": "^3.0.0", @@ -10371,13 +10379,13 @@ "string-width": "^1.0.2", "which-module": "^1.0.0", "y18n": "^3.2.1", - "yargs-parser": "5.0.0-security.0" + "yargs-parser": "^5.0.1" } }, "yargs-parser": { - "version": "5.0.0-security.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0-security.0.tgz", - "integrity": "sha512-T69y4Ps64LNesYxeYGYPvfoMTt/7y1XtfpIslUeK4um+9Hu7hlGoRtaDLvdXb7+/tfq4opVa2HRY5xGip022rQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.1.tgz", + "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==", "dev": true, "requires": { "camelcase": "^3.0.0", @@ -15180,9 +15188,9 @@ "integrity": "sha1-v7P672WqEqMWBYcSlFwyb9jwFDQ=" }, "just-debounce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz", - "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.1.0.tgz", + "integrity": "sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==", "dev": true }, "just-extend": { @@ -21710,9 +21718,9 @@ "dev": true }, "undertaker": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz", - "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", + "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", "dev": true, "requires": { "arr-flatten": "^1.0.1", @@ -21720,10 +21728,19 @@ "bach": "^1.0.0", "collection-map": "^1.0.0", "es6-weak-map": "^2.0.1", + "fast-levenshtein": "^1.0.0", "last-run": "^1.1.0", "object.defaults": "^1.0.0", "object.reduce": "^1.0.0", "undertaker-registry": "^1.0.0" + }, + "dependencies": { + "fast-levenshtein": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz", + "integrity": "sha1-5qdUzI8V5YmHqpy9J69m/W9OWvk=", + "dev": true + } } }, "undertaker-registry": { diff --git a/package.json b/package.json index 05f68f4a009..97c5d97f1b9 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "execa": "^1.0.0", "faker": "^3.1.0", "fs.extra": "^1.3.2", - "gulp": "^4.0.0", + "gulp": "^4.0.2", "gulp-clean": "^0.3.2", "gulp-concat": "^2.6.0", "gulp-connect": "^5.7.0", diff --git a/plugins/RequireEnsureWithoutJsonp.js b/plugins/RequireEnsureWithoutJsonp.js deleted file mode 100644 index c15af360e56..00000000000 --- a/plugins/RequireEnsureWithoutJsonp.js +++ /dev/null @@ -1,23 +0,0 @@ -/** - * RequireEnsureWithoutJsonp - * - * This plugin redefines the behavior of require.ensure that is used by webpack to load chunks. Usually require.ensure - * includes code that allows the asynchronous loading of webpack chunks through jsonp requests AND includes a manifest - * of all the build chunks so that they can be requested by name (e.g. require.ensure('./module.js'). Since that - * functionality is not required and we plan on loading all of our chunks manually (either by concatenating all the - * files together or including as individual scripts) we don't want the overhead of including that loading code or the - * file manifest. In this plugin, that code is replaced with an error message if a module is requested that hasn't been - * loaded manually. - * - * @constructor - */ -function RequireEnsureWithoutJsonp() {} -RequireEnsureWithoutJsonp.prototype.apply = function(compiler) { - compiler.plugin('compilation', function(compilation) { - compilation.mainTemplate.plugin('require-ensure', function(_, chunk, hash) { - return ''; - }); - }); -}; - -module.exports = RequireEnsureWithoutJsonp; diff --git a/plugins/eslint/package.json b/plugins/eslint/package.json deleted file mode 100644 index fa18ad83718..00000000000 --- a/plugins/eslint/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "eslint-plugin-prebid", - "version": "1.0.0", - "description": "validates module imports can be found without custom webpack resolvers, are in module whitelist, and not module entry points", - "main": "validateImports.js", - "author": "the prebid.js contributors", - "license": "Apache-2.0" -} diff --git a/plugins/eslint/validateImports.js b/plugins/eslint/validateImports.js deleted file mode 100644 index a39bf9b26d5..00000000000 --- a/plugins/eslint/validateImports.js +++ /dev/null @@ -1,73 +0,0 @@ - -let path = require('path'); -let _ = require('lodash'); -let resolveFrom = require('resolve-from'); - -function flagErrors(context, node, importPath) { - let absFileDir = path.dirname(context.getFilename()); - let absImportPath = path.resolve(absFileDir, importPath); - - try { - resolveFrom(absFileDir, importPath); - } catch (e) { - return context.report(node, `import "${importPath}" cannot be resolved`); - } - - if ( - Array.isArray(_.get(context, ['options', 0])) && - importPath.match(/^\w+/) && - !context.options[0].some(name => importPath.startsWith(name)) - ) { - context.report(node, `import "${importPath}" not in import whitelist`); - } else { - let absModulePath = path.resolve(__dirname, '../../modules'); - - // don't allow import of any files directly within modules folder or index.js files within modules' sub-folders - if ( - path.dirname(absImportPath) === absModulePath || ( - absImportPath.startsWith(absModulePath) && - path.basename(absImportPath) === 'index.js' - ) - ) { - context.report(node, `import "${importPath}" cannot require module entry point`); - } - - // don't allow extension-less local imports - if ( - !importPath.match(/^\w+/) && - !['.js', '.json'].includes(path.extname(absImportPath)) - ) { - context.report(node, `import "${importPath}" should include extension as .js or .json`); - } - } -} - -module.exports = { - rules: { - 'validate-imports': { - meta: { - docs: { - description: 'validates module imports can be found without custom webpack resolvers, are in module whitelist, and not module entry points' - } - }, - create: function(context) { - return { - "CallExpression[callee.name='require']"(node) { - let importPath = _.get(node, ['arguments', 0, 'value']); - if (importPath) { - flagErrors(context, node, importPath); - } - }, - ImportDeclaration(node) { - let importPath = node.source.value.trim(); - flagErrors(context, node, importPath); - }, - "ExportNamedDeclaration[source]"(node) { - let importPath = node.source.value.trim(); - flagErrors(context, node, importPath); - } - } - } - } - } -}; diff --git a/plugins/pbjsGlobals.js b/plugins/pbjsGlobals.js deleted file mode 100644 index bf3c9033ee6..00000000000 --- a/plugins/pbjsGlobals.js +++ /dev/null @@ -1,65 +0,0 @@ - -let t = require('@babel/core').types; -let prebid = require('../package.json'); - -module.exports = function(api, options) { - let replace = { - '$prebid.version$': prebid.version, - '$$PREBID_GLOBAL$$': options.globalVarName || prebid.globalVarName, - '$$REPO_AND_VERSION$$': `${prebid.repository.url.split('/')[3]}_prebid_${prebid.version}` - }; - - let identifierToStringLiteral = [ - '$$REPO_AND_VERSION$$' - ]; - - return { - visitor: { - StringLiteral(path) { - Object.keys(replace).forEach(name => { - if (path.node.value.includes(name)) { - path.node.value = path.node.value.replace( - new RegExp(escapeRegExp(name), 'g'), - replace[name] - ); - } - }); - }, - TemplateLiteral(path) { - path.traverse({ - TemplateElement(path) { - Object.keys(replace).forEach(name => { - ['raw', 'cooked'].forEach(type => { - if (path.node.value[type].includes(name)) { - path.node.value[type] = path.node.value[type].replace( - new RegExp(escapeRegExp(name), 'g'), - replace[name] - ); - } - }); - }); - } - }); - }, - Identifier(path) { - Object.keys(replace).forEach(name => { - if (path.node.name === name) { - if (identifierToStringLiteral.includes(name)) { - path.replaceWith( - t.StringLiteral(replace[name]) - ); - } else { - path.replaceWith( - t.Identifier(replace[name]) - ); - } - } - }); - } - } - }; -}; - -function escapeRegExp(str) { - return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); -} diff --git a/src/AnalyticsAdapter.js b/src/AnalyticsAdapter.js deleted file mode 100644 index 80c12a3eb8e..00000000000 --- a/src/AnalyticsAdapter.js +++ /dev/null @@ -1,161 +0,0 @@ -import CONSTANTS from './constants.json'; -import { ajax } from './ajax.js'; - -const events = require('./events.js'); -const utils = require('./utils.js'); - -const { - EVENTS: { - AUCTION_INIT, - AUCTION_END, - REQUEST_BIDS, - BID_REQUESTED, - BID_TIMEOUT, - BID_RESPONSE, - NO_BID, - BID_WON, - BID_ADJUSTMENT, - BIDDER_DONE, - SET_TARGETING, - AD_RENDER_FAILED, - AUCTION_DEBUG, - ADD_AD_UNITS - } -} = CONSTANTS; - -const ENDPOINT = 'endpoint'; -const BUNDLE = 'bundle'; - -var _sampled = true; - -export default function AnalyticsAdapter({ url, analyticsType, global, handler }) { - var _queue = []; - var _eventCount = 0; - var _enableCheck = true; - var _handlers; - - if (analyticsType === ENDPOINT || BUNDLE) { - _emptyQueue(); - } - - return { - track: _track, - enqueue: _enqueue, - enableAnalytics: _enable, - disableAnalytics: _disable, - getAdapterType: () => analyticsType, - getGlobal: () => global, - getHandler: () => handler, - getUrl: () => url - }; - - function _track({ eventType, args }) { - if (this.getAdapterType() === BUNDLE) { - window[global](handler, eventType, args); - } - - if (this.getAdapterType() === ENDPOINT) { - _callEndpoint(...arguments); - } - } - - function _callEndpoint({ eventType, args, callback }) { - ajax(url, callback, JSON.stringify({ eventType, args })); - } - - function _enqueue({ eventType, args }) { - const _this = this; - - if (global && window[global] && eventType && args) { - this.track({ eventType, args }); - } else { - _queue.push(function () { - _eventCount++; - _this.track({ eventType, args }); - }); - } - } - - function _enable(config) { - var _this = this; - - if (typeof config === 'object' && typeof config.options === 'object') { - _sampled = typeof config.options.sampling === 'undefined' || Math.random() < parseFloat(config.options.sampling); - } else { - _sampled = true; - } - - if (_sampled) { - // first send all events fired before enableAnalytics called - events.getEvents().forEach(event => { - if (!event) { - return; - } - - const { eventType, args } = event; - - if (eventType !== BID_TIMEOUT) { - _enqueue.call(_this, { eventType, args }); - } - }); - - // Next register event listeners to send data immediately - - _handlers = { - [REQUEST_BIDS]: args => this.enqueue({ eventType: REQUEST_BIDS, args }), - [BID_REQUESTED]: args => this.enqueue({ eventType: BID_REQUESTED, args }), - [BID_RESPONSE]: args => this.enqueue({ eventType: BID_RESPONSE, args }), - [NO_BID]: args => this.enqueue({ eventType: NO_BID, args }), - [BID_TIMEOUT]: args => this.enqueue({ eventType: BID_TIMEOUT, args }), - [BID_WON]: args => this.enqueue({ eventType: BID_WON, args }), - [BID_ADJUSTMENT]: args => this.enqueue({ eventType: BID_ADJUSTMENT, args }), - [BIDDER_DONE]: args => this.enqueue({ eventType: BIDDER_DONE, args }), - [SET_TARGETING]: args => this.enqueue({ eventType: SET_TARGETING, args }), - [AUCTION_END]: args => this.enqueue({ eventType: AUCTION_END, args }), - [AD_RENDER_FAILED]: args => this.enqueue({ eventType: AD_RENDER_FAILED, args }), - [AUCTION_DEBUG]: args => this.enqueue({ eventType: AUCTION_DEBUG, args }), - [ADD_AD_UNITS]: args => this.enqueue({ eventType: ADD_AD_UNITS, args }), - [AUCTION_INIT]: args => { - args.config = typeof config === 'object' ? config.options || {} : {}; // enableAnaltyics configuration object - this.enqueue({ eventType: AUCTION_INIT, args }); - } - }; - - utils._each(_handlers, (handler, event) => { - events.on(event, handler); - }); - } else { - utils.logMessage(`Analytics adapter for "${global}" disabled by sampling`); - } - - // finally set this function to return log message, prevents multiple adapter listeners - this._oldEnable = this.enableAnalytics; - this.enableAnalytics = function _enable() { - return utils.logMessage(`Analytics adapter for "${global}" already enabled, unnecessary call to \`enableAnalytics\`.`); - }; - } - - function _disable() { - utils._each(_handlers, (handler, event) => { - events.off(event, handler); - }); - this.enableAnalytics = this._oldEnable ? this._oldEnable : _enable; - } - - function _emptyQueue() { - if (_enableCheck) { - for (var i = 0; i < _queue.length; i++) { - _queue[i](); - } - - // override push to execute the command immediately from now on - _queue.push = function (fn) { - fn(); - }; - - _enableCheck = false; - } - - utils.logMessage(`event count sent to ${global}: ${_eventCount}`); - } -} diff --git a/src/Renderer.js b/src/Renderer.js deleted file mode 100644 index c997658b30b..00000000000 --- a/src/Renderer.js +++ /dev/null @@ -1,140 +0,0 @@ -import { loadExternalScript } from './adloader.js'; -import * as utils from './utils.js'; -import find from 'core-js-pure/features/array/find.js'; -const moduleCode = 'outstream'; - -/** - * @typedef {object} Renderer - * - * A Renderer stores some functions which are used to render a particular Bid. - * These are used in Outstream Video Bids, returned on the Bid by the adapter, and will - * be used to render that bid unless the Publisher overrides them. - */ - -export function Renderer(options) { - const { url, config, id, callback, loaded, adUnitCode } = options; - this.url = url; - this.config = config; - this.handlers = {}; - this.id = id; - - // a renderer may push to the command queue to delay rendering until the - // render function is loaded by loadExternalScript, at which point the the command - // queue will be processed - this.loaded = loaded; - this.cmd = []; - this.push = func => { - if (typeof func !== 'function') { - utils.logError('Commands given to Renderer.push must be wrapped in a function'); - return; - } - this.loaded ? func.call() : this.cmd.push(func); - }; - - // bidders may override this with the `callback` property given to `install` - this.callback = callback || (() => { - this.loaded = true; - this.process(); - }); - - // use a function, not an arrow, in order to be able to pass "arguments" through - this.render = function () { - const renderArgs = arguments - const runRender = () => { - if (this._render) { - this._render.apply(this, renderArgs) - } else { - utils.logWarn(`No render function was provided, please use .setRender on the renderer`); - } - } - - if (!isRendererPreferredFromAdUnit(adUnitCode)) { - // we expect to load a renderer url once only so cache the request to load script - this.cmd.unshift(runRender) // should render run first ? - loadExternalScript(url, moduleCode, this.callback); - } else { - utils.logWarn(`External Js not loaded by Renderer since renderer url and callback is already defined on adUnit ${adUnitCode}`); - runRender() - } - }.bind(this) // bind the function to this object to avoid 'this' errors -} - -Renderer.install = function({ url, config, id, callback, loaded, adUnitCode }) { - return new Renderer({ url, config, id, callback, loaded, adUnitCode }); -}; - -Renderer.prototype.getConfig = function() { - return this.config; -}; - -Renderer.prototype.setRender = function(fn) { - this._render = fn; -}; - -Renderer.prototype.setEventHandlers = function(handlers) { - this.handlers = handlers; -}; - -Renderer.prototype.handleVideoEvent = function({ id, eventName }) { - if (typeof this.handlers[eventName] === 'function') { - this.handlers[eventName](); - } - - utils.logMessage(`Prebid Renderer event for id ${id} type ${eventName}`); -}; - -/* - * Calls functions that were pushed to the command queue before the - * renderer was loaded by `loadExternalScript` - */ -Renderer.prototype.process = function() { - while (this.cmd.length > 0) { - try { - this.cmd.shift().call(); - } catch (error) { - utils.logError('Error processing Renderer command: ', error); - } - } -}; - -/** - * Checks whether creative rendering should be done by Renderer or not. - * @param {Object} renderer Renderer object installed by adapter - * @returns {Boolean} - */ -export function isRendererRequired(renderer) { - return !!(renderer && renderer.url); -} - -/** - * Render the bid returned by the adapter - * @param {Object} renderer Renderer object installed by adapter - * @param {Object} bid Bid response - */ -export function executeRenderer(renderer, bid) { - renderer.render(bid); -} - -function isRendererPreferredFromAdUnit(adUnitCode) { - const adUnits = $$PREBID_GLOBAL$$.adUnits; - const adUnit = find(adUnits, adUnit => { - return adUnit.code === adUnitCode; - }); - - if (!adUnit) { - return false - } - - // renderer defined at adUnit level - const adUnitRenderer = utils.deepAccess(adUnit, 'renderer'); - const hasValidAdUnitRenderer = !!(adUnitRenderer && adUnitRenderer.url && adUnitRenderer.render); - - // renderer defined at adUnit.mediaTypes level - const mediaTypeRenderer = utils.deepAccess(adUnit, 'mediaTypes.video.renderer'); - const hasValidMediaTypeRenderer = !!(mediaTypeRenderer && mediaTypeRenderer.url && mediaTypeRenderer.render) - - return !!( - (hasValidAdUnitRenderer && !(adUnitRenderer.backupOnly === true)) || - (hasValidMediaTypeRenderer && !(mediaTypeRenderer.backupOnly === true)) - ); -} diff --git a/src/adServerManager.js b/src/adServerManager.js deleted file mode 100644 index af8fe34920e..00000000000 --- a/src/adServerManager.js +++ /dev/null @@ -1,56 +0,0 @@ -import { getGlobal } from './prebidGlobal.js'; -import { logWarn } from './utils.js'; - -const prebid = getGlobal(); - -/** - * This file defines the plugin points in prebid-core for AdServer-specific functionality. - * - * Its main job is to expose functions for AdServer modules to append functionality to the Prebid public API. - * For a given Ad Server with name "adServerName", these functions will only change the API in the - * $$PREBID_GLOBAL$$.adServers[adServerName] namespace. - */ - -/** - * @typedef {Object} CachedVideoBid - * - * @property {string} videoCacheId The ID which can be used to retrieve this video from prebid-server. - * This is the same ID given to the callback in the videoCache's store function. - */ - -/** - * @function VideoAdUrlBuilder - * - * @param {CachedVideoBid} bid The winning Bid which the ad server should show, assuming it beats out - * the competition. - * - * @param {Object} options Options required by the Ad Server to make a valid AdServer URL. - * This object will have different properties depending on the specific ad server supported. - * For more information, see the docs inside the ad server module you're supporting. - * - * @return {string} A URL which can be passed into the Video player to play an ad. - */ - -/** - * @typedef {Object} VideoSupport - * - * @function {VideoAdUrlBuilder} buildVideoAdUrl - */ - -/** - * Enable video support for the Ad Server. - * - * @property {string} name The identifying name for this adserver. - * @property {VideoSupport} videoSupport An object with the functions needed to support video in Prebid. - */ -export function registerVideoSupport(name, videoSupport) { - prebid.adServers = prebid.adServers || { }; - prebid.adServers[name] = prebid.adServers[name] || { }; - Object.keys(videoSupport).forEach((key) => { - if (prebid.adServers[name][key]) { - logWarn(`Attempting to add an already registered function property ${key} for AdServer ${name}.`); - return; - } - prebid.adServers[name][key] = videoSupport[key]; - }); -} diff --git a/src/adUnits.js b/src/adUnits.js deleted file mode 100644 index cdac649c5b8..00000000000 --- a/src/adUnits.js +++ /dev/null @@ -1,90 +0,0 @@ -import { deepAccess } from './utils.js'; - -let adUnits = {}; - -function ensureAdUnit(adunit, bidderCode) { - let adUnit = adUnits[adunit] = adUnits[adunit] || { bidders: {} }; - if (bidderCode) { - return adUnit.bidders[bidderCode] = adUnit.bidders[bidderCode] || {} - } - return adUnit; -} - -function incrementAdUnitCount(adunit, counter, bidderCode) { - let adUnit = ensureAdUnit(adunit, bidderCode); - adUnit[counter] = (adUnit[counter] || 0) + 1; - return adUnit[counter]; -} - -/** - * Increments and returns current Adunit counter - * @param {string} adunit id - * @returns {number} current adunit count - */ -function incrementRequestsCounter(adunit) { - return incrementAdUnitCount(adunit, 'requestsCounter'); -} - -/** - * Increments and returns current Adunit requests counter for a bidder - * @param {string} adunit id - * @param {string} bidderCode code - * @returns {number} current adunit bidder requests count - */ -function incrementBidderRequestsCounter(adunit, bidderCode) { - return incrementAdUnitCount(adunit, 'requestsCounter', bidderCode); -} - -/** - * Increments and returns current Adunit wins counter for a bidder - * @param {string} adunit id - * @param {string} bidderCode code - * @returns {number} current adunit bidder requests count - */ -function incrementBidderWinsCounter(adunit, bidderCode) { - return incrementAdUnitCount(adunit, 'winsCounter', bidderCode); -} - -/** - * Returns current Adunit counter - * @param {string} adunit id - * @returns {number} current adunit count - */ -function getRequestsCounter(adunit) { - return deepAccess(adUnits, `${adunit}.requestsCounter`) || 0; -} - -/** - * Returns current Adunit requests counter for a specific bidder code - * @param {string} adunit id - * @param {string} bidder code - * @returns {number} current adunit bidder requests count - */ -function getBidderRequestsCounter(adunit, bidder) { - return deepAccess(adUnits, `${adunit}.bidders.${bidder}.requestsCounter`) || 0; -} - -/** - * Returns current Adunit requests counter for a specific bidder code - * @param {string} adunit id - * @param {string} bidder code - * @returns {number} current adunit bidder requests count - */ -function getBidderWinsCounter(adunit, bidder) { - return deepAccess(adUnits, `${adunit}.bidders.${bidder}.winsCounter`) || 0; -} - -/** - * A module which counts how many times an adunit was called - * @module adunitCounter - */ -let adunitCounter = { - incrementRequestsCounter, - incrementBidderRequestsCounter, - incrementBidderWinsCounter, - getRequestsCounter, - getBidderRequestsCounter, - getBidderWinsCounter -} - -export { adunitCounter }; diff --git a/src/adapter.js b/src/adapter.js deleted file mode 100644 index df81790aa1c..00000000000 --- a/src/adapter.js +++ /dev/null @@ -1,20 +0,0 @@ -export default function Adapter(code) { - var bidderCode = code; - - function setBidderCode(code) { - bidderCode = code; - } - - function getBidderCode() { - return bidderCode; - } - - function callBids() { - } - - return { - callBids: callBids, - setBidderCode: setBidderCode, - getBidderCode: getBidderCode - }; -} diff --git a/src/adapterManager.js b/src/adapterManager.js deleted file mode 100644 index 5f8f2e5721c..00000000000 --- a/src/adapterManager.js +++ /dev/null @@ -1,621 +0,0 @@ -/** @module adaptermanger */ - -import { flatten, getBidderCodes, getDefinedParams, shuffle, timestamp, getBidderRequest, bind } from './utils.js'; -import { getLabels, resolveStatus } from './sizeMapping.js'; -import { processNativeAdUnitParams, 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 includes from 'core-js-pure/features/array/includes.js'; -import find from 'core-js-pure/features/array/find.js'; -import { adunitCounter } from './adUnits.js'; -import { getRefererInfo } from './refererDetection.js'; - -var utils = require('./utils.js'); -var CONSTANTS = require('./constants.json'); -var events = require('./events.js'); -let s2sTestingModule; // store s2sTesting module if it's loaded - -let adapterManager = {}; - -let _bidderRegistry = adapterManager.bidderRegistry = {}; -let _aliasRegistry = adapterManager.aliasRegistry = {}; - -let _s2sConfigs = []; -config.getConfig('s2sConfig', config => { - if (config && config.s2sConfig) { - _s2sConfigs = Array.isArray(config.s2sConfig) ? config.s2sConfig : [config.s2sConfig]; - } -}); - -var _analyticsRegistry = {}; - -/** - * @typedef {object} LabelDescriptor - * @property {boolean} labelAll describes whether or not this object expects all labels to match, or any label to match - * @property {Array} labels the labels listed on the bidder or adUnit - * @property {Array} activeLabels the labels specified as being active by requestBids - */ - -function getBids({bidderCode, auctionId, bidderRequestId, adUnits, labels, src}) { - return adUnits.reduce((result, adUnit) => { - let { - active, - mediaTypes: filteredMediaTypes, - filterResults - } = resolveStatus( - getLabels(adUnit, labels), - adUnit.mediaTypes, - adUnit.sizes - ); - - if (!active) { - utils.logInfo(`Size mapping disabled adUnit "${adUnit.code}"`); - } else if (filterResults) { - utils.logInfo(`Size mapping filtered adUnit "${adUnit.code}" banner sizes from `, filterResults.before, 'to ', filterResults.after); - } - - if (active) { - result.push(adUnit.bids.filter(bid => bid.bidder === bidderCode) - .reduce((bids, bid) => { - const nativeParams = - adUnit.nativeParams || utils.deepAccess(adUnit, 'mediaTypes.native'); - if (nativeParams) { - bid = Object.assign({}, bid, { - nativeParams: processNativeAdUnitParams(nativeParams), - }); - } - - bid = Object.assign({}, bid, getDefinedParams(adUnit, [ - 'ortb2Imp', - 'mediaType', - 'renderer', - 'storedAuctionResponse' - ])); - - let { - active, - mediaTypes, - filterResults - } = resolveStatus(getLabels(bid, labels), filteredMediaTypes); - - if (!active) { - utils.logInfo(`Size mapping deactivated adUnit "${adUnit.code}" bidder "${bid.bidder}"`); - } else if (filterResults) { - utils.logInfo(`Size mapping filtered adUnit "${adUnit.code}" bidder "${bid.bidder}" banner sizes from `, filterResults.before, 'to ', filterResults.after); - } - - if (utils.isValidMediaTypes(mediaTypes)) { - bid = Object.assign({}, bid, { - mediaTypes - }); - } else { - utils.logError( - `mediaTypes is not correctly configured for adunit ${adUnit.code}` - ); - } - - if (active) { - bids.push(Object.assign({}, bid, { - adUnitCode: adUnit.code, - transactionId: adUnit.transactionId, - sizes: utils.deepAccess(mediaTypes, 'banner.sizes') || utils.deepAccess(mediaTypes, 'video.playerSize') || [], - bidId: bid.bid_id || utils.getUniqueIdentifierStr(), - bidderRequestId, - auctionId, - src, - bidRequestsCount: adunitCounter.getRequestsCounter(adUnit.code), - bidderRequestsCount: adunitCounter.getBidderRequestsCounter(adUnit.code, bid.bidder), - bidderWinsCount: adunitCounter.getBidderWinsCounter(adUnit.code, bid.bidder), - })); - } - return bids; - }, []) - ); - } - return result; - }, []).reduce(flatten, []).filter(val => val !== ''); -} - -const hookedGetBids = hook('sync', getBids, 'getBids'); - -function getAdUnitCopyForPrebidServer(adUnits, s2sConfig) { - let adaptersServerSide = s2sConfig.bidders; - let adUnitsCopy = utils.deepClone(adUnits); - - adUnitsCopy.forEach((adUnit) => { - // filter out client side bids - adUnit.bids = adUnit.bids.filter((bid) => { - return includes(adaptersServerSide, bid.bidder) && - (!doingS2STesting(s2sConfig) || bid.finalSource !== s2sTestingModule.CLIENT); - }).map((bid) => { - bid.bid_id = utils.getUniqueIdentifierStr(); - return bid; - }); - }); - - // don't send empty requests - adUnitsCopy = adUnitsCopy.filter(adUnit => { - return adUnit.bids.length !== 0; - }); - return adUnitsCopy; -} - -function getAdUnitCopyForClientAdapters(adUnits) { - let adUnitsClientCopy = utils.deepClone(adUnits); - // filter out s2s bids - adUnitsClientCopy.forEach((adUnit) => { - adUnit.bids = adUnit.bids.filter((bid) => { - return !clientTestAdapters.length || bid.finalSource !== s2sTestingModule.SERVER; - }) - }); - - // don't send empty requests - adUnitsClientCopy = adUnitsClientCopy.filter(adUnit => { - return adUnit.bids.length !== 0; - }); - - return adUnitsClientCopy; -} - -export let gdprDataHandler = { - consentData: null, - setConsentData: function(consentInfo) { - gdprDataHandler.consentData = consentInfo; - }, - getConsentData: function() { - return gdprDataHandler.consentData; - } -}; - -export let uspDataHandler = { - consentData: null, - setConsentData: function(consentInfo) { - uspDataHandler.consentData = consentInfo; - }, - getConsentData: function() { - return uspDataHandler.consentData; - } -}; - -export let coppaDataHandler = { - getCoppa: function() { - return !!(config.getConfig('coppa')) - } -}; - -// export for testing -export let clientTestAdapters = []; -export const allS2SBidders = []; - -export function getAllS2SBidders() { - adapterManager.s2STestingEnabled = false; - _s2sConfigs.forEach(s2sConfig => { - if (s2sConfig && s2sConfig.enabled) { - if (s2sConfig.bidders && s2sConfig.bidders.length) { - allS2SBidders.push(...s2sConfig.bidders); - } - } - }) -} - -adapterManager.makeBidRequests = hook('sync', function (adUnits, auctionStart, auctionId, cbTimeout, labels) { - /** - * emit and pass adunits for external modification - * @see {@link https://github.com/prebid/Prebid.js/issues/4149|Issue} - */ - events.emit(CONSTANTS.EVENTS.BEFORE_REQUEST_BIDS, adUnits); - - let bidderCodes = getBidderCodes(adUnits); - if (config.getConfig('bidderSequence') === RANDOM) { - bidderCodes = shuffle(bidderCodes); - } - const refererInfo = getRefererInfo(); - - let clientBidderCodes = bidderCodes; - - let bidRequests = []; - - if (allS2SBidders.length === 0) { - getAllS2SBidders(); - } - - _s2sConfigs.forEach(s2sConfig => { - if (s2sConfig && s2sConfig.enabled) { - if (doingS2STesting(s2sConfig)) { - s2sTestingModule.calculateBidSources(s2sConfig); - const bidderMap = s2sTestingModule.getSourceBidderMap(adUnits, allS2SBidders); - // get all adapters doing client testing - bidderMap[s2sTestingModule.CLIENT].forEach(bidder => { - if (!includes(clientTestAdapters, bidder)) { - clientTestAdapters.push(bidder); - } - }) - } - } - }) - - // don't call these client side (unless client request is needed for testing) - clientBidderCodes = bidderCodes.filter(bidderCode => { - return !includes(allS2SBidders, bidderCode) || includes(clientTestAdapters, bidderCode) - }); - - // these are called on the s2s adapter - let adaptersServerSide = allS2SBidders; - - const adUnitsContainServerRequests = (adUnits, s2sConfig) => Boolean( - find(adUnits, adUnit => find(adUnit.bids, bid => ( - bid.bidSource || - (s2sConfig.bidderControl && s2sConfig.bidderControl[bid.bidder]) - ) && bid.finalSource === s2sTestingModule.SERVER)) - ); - - _s2sConfigs.forEach(s2sConfig => { - if (s2sConfig && s2sConfig.enabled) { - if ((isTestingServerOnly(s2sConfig) && adUnitsContainServerRequests(adUnits, s2sConfig))) { - utils.logWarn('testServerOnly: True. All client requests will be suppressed.'); - clientBidderCodes.length = 0; - } - - let adUnitsS2SCopy = getAdUnitCopyForPrebidServer(adUnits, s2sConfig); - let tid = utils.generateUUID(); - adaptersServerSide.forEach(bidderCode => { - const bidderRequestId = utils.getUniqueIdentifierStr(); - const bidderRequest = { - bidderCode, - auctionId, - bidderRequestId, - tid, - bids: hookedGetBids({bidderCode, auctionId, bidderRequestId, 'adUnits': utils.deepClone(adUnitsS2SCopy), labels, src: CONSTANTS.S2S.SRC}), - auctionStart: auctionStart, - timeout: s2sConfig.timeout, - src: CONSTANTS.S2S.SRC, - refererInfo - }; - if (bidderRequest.bids.length !== 0) { - bidRequests.push(bidderRequest); - } - }); - - // update the s2sAdUnits object and remove all bids that didn't pass sizeConfig/label checks from getBids() - // this is to keep consistency and only allow bids/adunits that passed the checks to go to pbs - adUnitsS2SCopy.forEach((adUnitCopy) => { - let validBids = adUnitCopy.bids.filter((adUnitBid) => - find(bidRequests, request => - find(request.bids, (reqBid) => reqBid.bidId === adUnitBid.bid_id))); - adUnitCopy.bids = validBids; - }); - - bidRequests.forEach(request => { - if (request.adUnitsS2SCopy === undefined) { - request.adUnitsS2SCopy = adUnitsS2SCopy.filter(adUnitCopy => adUnitCopy.bids.length > 0); - } - }); - } - }) - - // client adapters - let adUnitsClientCopy = getAdUnitCopyForClientAdapters(adUnits); - clientBidderCodes.forEach(bidderCode => { - const bidderRequestId = utils.getUniqueIdentifierStr(); - const bidderRequest = { - bidderCode, - auctionId, - bidderRequestId, - bids: hookedGetBids({bidderCode, auctionId, bidderRequestId, 'adUnits': utils.deepClone(adUnitsClientCopy), labels, src: 'client'}), - auctionStart: auctionStart, - timeout: cbTimeout, - refererInfo - }; - const adapter = _bidderRegistry[bidderCode]; - if (!adapter) { - utils.logError(`Trying to make a request for bidder that does not exist: ${bidderCode}`); - } - - if (adapter && bidderRequest.bids && bidderRequest.bids.length !== 0) { - bidRequests.push(bidderRequest); - } - }); - - if (gdprDataHandler.getConsentData()) { - bidRequests.forEach(bidRequest => { - bidRequest['gdprConsent'] = gdprDataHandler.getConsentData(); - }); - } - - if (uspDataHandler.getConsentData()) { - bidRequests.forEach(bidRequest => { - bidRequest['uspConsent'] = uspDataHandler.getConsentData(); - }); - } - return bidRequests; -}, 'makeBidRequests'); - -adapterManager.callBids = (adUnits, bidRequests, addBidResponse, doneCb, requestCallbacks, requestBidsTimeout, onTimelyResponse) => { - if (!bidRequests.length) { - utils.logWarn('callBids executed with no bidRequests. Were they filtered by labels or sizing?'); - return; - } - - let [clientBidRequests, serverBidRequests] = bidRequests.reduce((partitions, bidRequest) => { - partitions[Number(typeof bidRequest.src !== 'undefined' && bidRequest.src === CONSTANTS.S2S.SRC)].push(bidRequest); - return partitions; - }, [[], []]); - - var uniqueServerBidRequests = []; - serverBidRequests.forEach(serverBidRequest => { - var index = -1; - for (var i = 0; i < uniqueServerBidRequests.length; ++i) { - if (serverBidRequest.tid === uniqueServerBidRequests[i].tid) { - index = i; - break; - } - } - if (index <= -1) { - uniqueServerBidRequests.push(serverBidRequest); - } - }); - - let counter = 0 - _s2sConfigs.forEach((s2sConfig) => { - if (s2sConfig && uniqueServerBidRequests[counter] && includes(s2sConfig.bidders, uniqueServerBidRequests[counter].bidderCode)) { - // s2s should get the same client side timeout as other client side requests. - const s2sAjax = ajaxBuilder(requestBidsTimeout, requestCallbacks ? { - request: requestCallbacks.request.bind(null, 's2s'), - done: requestCallbacks.done - } : undefined); - let adaptersServerSide = s2sConfig.bidders; - const s2sAdapter = _bidderRegistry[s2sConfig.adapter]; - let tid = uniqueServerBidRequests[counter].tid; - let adUnitsS2SCopy = uniqueServerBidRequests[counter].adUnitsS2SCopy; - - let uniqueServerRequests = serverBidRequests.filter(serverBidRequest => serverBidRequest.tid === tid) - - if (s2sAdapter) { - let s2sBidRequest = {tid, 'ad_units': adUnitsS2SCopy, s2sConfig}; - if (s2sBidRequest.ad_units.length) { - let doneCbs = uniqueServerRequests.map(bidRequest => { - bidRequest.start = timestamp(); - return doneCb.bind(bidRequest); - }); - - // only log adapters that actually have adUnit bids - let allBidders = s2sBidRequest.ad_units.reduce((adapters, adUnit) => { - return adapters.concat((adUnit.bids || []).reduce((adapters, bid) => adapters.concat(bid.bidder), [])); - }, []); - utils.logMessage(`CALLING S2S HEADER BIDDERS ==== ${adaptersServerSide.filter(adapter => includes(allBidders, adapter)).join(',')}`); - - // fire BID_REQUESTED event for each s2s bidRequest - uniqueServerRequests.forEach(bidRequest => { - events.emit(CONSTANTS.EVENTS.BID_REQUESTED, bidRequest); - }); - - // make bid requests - s2sAdapter.callBids( - s2sBidRequest, - serverBidRequests, - (adUnitCode, bid) => { - let bidderRequest = getBidderRequest(serverBidRequests, bid.bidderCode, adUnitCode); - if (bidderRequest) { - addBidResponse.call(bidderRequest, adUnitCode, bid) - } - }, - () => doneCbs.forEach(done => done()), - s2sAjax - ); - } - } else { - utils.logError('missing ' + s2sConfig.adapter); - } - counter++ - } - }); - - // handle client adapter requests - clientBidRequests.forEach(bidRequest => { - bidRequest.start = timestamp(); - // TODO : Do we check for bid in pool from here and skip calling adapter again ? - const adapter = _bidderRegistry[bidRequest.bidderCode]; - config.runWithBidder(bidRequest.bidderCode, () => { - utils.logMessage(`CALLING BIDDER`); - events.emit(CONSTANTS.EVENTS.BID_REQUESTED, bidRequest); - }); - let ajax = ajaxBuilder(requestBidsTimeout, requestCallbacks ? { - request: requestCallbacks.request.bind(null, bidRequest.bidderCode), - done: requestCallbacks.done - } : undefined); - const adapterDone = doneCb.bind(bidRequest); - try { - config.runWithBidder( - bidRequest.bidderCode, - bind.call( - adapter.callBids, - adapter, - bidRequest, - addBidResponse.bind(bidRequest), - adapterDone, - ajax, - onTimelyResponse, - config.callbackWithBidder(bidRequest.bidderCode) - ) - ); - } catch (e) { - utils.logError(`${bidRequest.bidderCode} Bid Adapter emitted an uncaught error when parsing their bidRequest`, {e, bidRequest}); - adapterDone(); - } - }); -}; - -function doingS2STesting(s2sConfig) { - return s2sConfig && s2sConfig.enabled && s2sConfig.testing && s2sTestingModule; -} - -function isTestingServerOnly(s2sConfig) { - return Boolean(doingS2STesting(s2sConfig) && s2sConfig.testServerOnly); -}; - -function getSupportedMediaTypes(bidderCode) { - let supportedMediaTypes = []; - if (includes(adapterManager.videoAdapters, bidderCode)) supportedMediaTypes.push('video'); - if (includes(nativeAdapters, bidderCode)) supportedMediaTypes.push('native'); - return supportedMediaTypes; -} - -adapterManager.videoAdapters = []; // added by adapterLoader for now - -adapterManager.registerBidAdapter = function (bidAdapter, bidderCode, {supportedMediaTypes = []} = {}) { - if (bidAdapter && bidderCode) { - if (typeof bidAdapter.callBids === 'function') { - _bidderRegistry[bidderCode] = bidAdapter; - - if (includes(supportedMediaTypes, 'video')) { - adapterManager.videoAdapters.push(bidderCode); - } - if (includes(supportedMediaTypes, 'native')) { - nativeAdapters.push(bidderCode); - } - } else { - utils.logError('Bidder adaptor error for bidder code: ' + bidderCode + 'bidder must implement a callBids() function'); - } - } else { - utils.logError('bidAdapter or bidderCode not specified'); - } -}; - -adapterManager.aliasBidAdapter = function (bidderCode, alias, options) { - let existingAlias = _bidderRegistry[alias]; - - if (typeof existingAlias === 'undefined') { - let bidAdapter = _bidderRegistry[bidderCode]; - if (typeof bidAdapter === 'undefined') { - // check if alias is part of s2sConfig and allow them to register if so (as base bidder may be s2s-only) - const nonS2SAlias = []; - _s2sConfigs.forEach(s2sConfig => { - if (s2sConfig.bidders && s2sConfig.bidders.length) { - const s2sBidders = s2sConfig && s2sConfig.bidders; - if (!(s2sConfig && includes(s2sBidders, alias))) { - nonS2SAlias.push(bidderCode); - } else { - _aliasRegistry[alias] = bidderCode; - } - } - }); - nonS2SAlias.forEach(bidderCode => { - utils.logError('bidderCode "' + bidderCode + '" is not an existing bidder.', 'adapterManager.aliasBidAdapter'); - }) - } else { - try { - let newAdapter; - let supportedMediaTypes = getSupportedMediaTypes(bidderCode); - // Have kept old code to support backward compatibilitiy. - // Remove this if loop when all adapters are supporting bidderFactory. i.e When Prebid.js is 1.0 - if (bidAdapter.constructor.prototype != Object.prototype) { - newAdapter = new bidAdapter.constructor(); - newAdapter.setBidderCode(alias); - } else { - let spec = bidAdapter.getSpec(); - let gvlid = options && options.gvlid; - let skipPbsAliasing = options && options.skipPbsAliasing; - newAdapter = newBidder(Object.assign({}, spec, { code: alias, gvlid, skipPbsAliasing })); - _aliasRegistry[alias] = bidderCode; - } - adapterManager.registerBidAdapter(newAdapter, alias, { - supportedMediaTypes - }); - } catch (e) { - utils.logError(bidderCode + ' bidder does not currently support aliasing.', 'adapterManager.aliasBidAdapter'); - } - } - } else { - utils.logMessage('alias name "' + alias + '" has been already specified.'); - } -}; - -adapterManager.registerAnalyticsAdapter = function ({adapter, code, gvlid}) { - if (adapter && code) { - if (typeof adapter.enableAnalytics === 'function') { - adapter.code = code; - _analyticsRegistry[code] = { adapter, gvlid }; - } else { - utils.logError(`Prebid Error: Analytics adaptor error for analytics "${code}" - analytics adapter must implement an enableAnalytics() function`); - } - } else { - utils.logError('Prebid Error: analyticsAdapter or analyticsCode not specified'); - } -}; - -adapterManager.enableAnalytics = function (config) { - if (!utils.isArray(config)) { - config = [config]; - } - - utils._each(config, adapterConfig => { - var adapter = _analyticsRegistry[adapterConfig.provider].adapter; - if (adapter) { - adapter.enableAnalytics(adapterConfig); - } else { - utils.logError(`Prebid Error: no analytics adapter found in registry for - ${adapterConfig.provider}.`); - } - }); -} - -adapterManager.getBidAdapter = function(bidder) { - return _bidderRegistry[bidder]; -}; - -adapterManager.getAnalyticsAdapter = function(code) { - return _analyticsRegistry[code]; -} - -// the s2sTesting module is injected when it's loaded rather than being imported -// importing it causes the packager to include it even when it's not explicitly included in the build -export function setS2STestingModule(module) { - s2sTestingModule = module; -} - -function tryCallBidderMethod(bidder, method, param) { - try { - const adapter = _bidderRegistry[bidder]; - const spec = adapter.getSpec(); - if (spec && spec[method] && typeof spec[method] === 'function') { - utils.logInfo(`Invoking ${bidder}.${method}`); - config.runWithBidder(bidder, bind.call(spec[method], spec, param)); - } - } catch (e) { - utils.logWarn(`Error calling ${method} of ${bidder}`); - } -} - -adapterManager.callTimedOutBidders = function(adUnits, timedOutBidders, cbTimeout) { - timedOutBidders = timedOutBidders.map((timedOutBidder) => { - // Adding user configured params & timeout to timeout event data - timedOutBidder.params = utils.getUserConfiguredParams(adUnits, timedOutBidder.adUnitCode, timedOutBidder.bidder); - timedOutBidder.timeout = cbTimeout; - return timedOutBidder; - }); - timedOutBidders = utils.groupBy(timedOutBidders, 'bidder'); - - Object.keys(timedOutBidders).forEach((bidder) => { - tryCallBidderMethod(bidder, 'onTimeout', timedOutBidders[bidder]); - }); -} - -adapterManager.callBidWonBidder = function(bidder, bid, adUnits) { - // Adding user configured params to bidWon event data - bid.params = utils.getUserConfiguredParams(adUnits, bid.adUnitCode, bid.bidder); - adunitCounter.incrementBidderWinsCounter(bid.adUnitCode, bid.bidder); - tryCallBidderMethod(bidder, 'onBidWon', bid); -}; - -adapterManager.callSetTargetingBidder = function(bidder, bid) { - tryCallBidderMethod(bidder, 'onSetTargeting', bid); -}; - -adapterManager.callBidViewableBidder = function(bidder, bid) { - tryCallBidderMethod(bidder, 'onBidViewable', bid); -}; - -export default adapterManager; diff --git a/src/adapters/analytics/example.js b/src/adapters/analytics/example.js deleted file mode 100644 index 1321612b688..00000000000 --- a/src/adapters/analytics/example.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * example.js - analytics adapter for Example Analytics Library example - */ - -import adapter from '../../AnalyticsAdapter.js'; - -export default adapter( - { - url: 'http://localhost:9999/src/adapters/analytics/libraries/example.js', - global: 'ExampleAnalyticsGlobalObject', - handler: 'on', - analyticsType: 'library' - } -); diff --git a/src/adapters/analytics/example2.js b/src/adapters/analytics/example2.js deleted file mode 100644 index eadf994ce36..00000000000 --- a/src/adapters/analytics/example2.js +++ /dev/null @@ -1,25 +0,0 @@ -/* eslint-disable no-console */ -import { ajax } from '../../../src/ajax.js'; - -/** - * example2.js - analytics adapter for Example2 Analytics Endpoint example - */ - -import adapter from '../../AnalyticsAdapter.js'; - -const url = 'https://httpbin.org/post'; -const analyticsType = 'endpoint'; - -export default Object.assign(adapter( - { - url, - analyticsType - } -), -{ - // Override AnalyticsAdapter functions by supplying custom methods - track({ eventType, args }) { - console.log('track function override for Example2 Analytics'); - ajax(url, (result) => console.log('Analytics Endpoint Example2: result = ' + result), JSON.stringify({ eventType, args })); - } -}); diff --git a/src/adapters/analytics/libraries/example.js b/src/adapters/analytics/libraries/example.js deleted file mode 100644 index 0d758fd5513..00000000000 --- a/src/adapters/analytics/libraries/example.js +++ /dev/null @@ -1,59 +0,0 @@ -/* eslint-disable no-console */ -/** @module example */ - -window.ExampleAnalyticsGlobalObject = function(hander, type, data) { - console.log(`call to Example Analytics library: example('${hander}', '${type}', ${JSON.stringify(data)})`); -}; - -window[window.ExampleAnalyticsGlobalObject] = function() {}; - -// var utils = require('utils'); -// var events = require('events'); -// var pbjsHandlers = require('prebid-event-handlers'); -var utils = { errorless: function(fn) { return fn; } }; - -var events = { init: function() { return arguments; } }; - -var pbjsHandlers = { - onBidAdjustment: args => console.log('pbjsHandlers onBidAdjustment args:', args), - onBidTimeout: args => console.log('pbjsHandlers bidTimeout args:', args), - onBidRequested: args => console.log('pbjsHandlers bidRequested args:', args), - onBidResponse: args => console.log('pbjsHandlers bidResponse args:', args), - onBidWon: args => console.log('pbjsHandlers bidWon args:', args) -}; - -// init -var example = window[window.ExampleAnalyticsGlobalObject]; -var bufferedQueries = example.q || []; - -events.init(); - -// overwrite example object and handle 'on' callbacks -window[window.ExampleAnalyticsGlobalObject] = example = utils.errorless(function() { - if (arguments[0] && arguments[0] === 'on') { - var eventName = arguments[1] && arguments[1]; - var args = arguments[2] && arguments[2]; - if (eventName && args) { - if (eventName === 'bidAdjustment') { - pbjsHandlers.onBidAdjustment.apply(this, [args]); - } - if (eventName === 'bidTimeout') { - pbjsHandlers.onBidTimeout.apply(this, [args]); - } - if (eventName === 'bidRequested') { - pbjsHandlers.onBidRequested.apply(this, [args]); - } - if (eventName === 'bidResponse') { - pbjsHandlers.onBidResponse.apply(this, [args]); - } - if (eventName === 'bidWon') { - pbjsHandlers.onBidWon.apply(this, [args]); - } - } - } -}); - -// apply bufferedQueries -bufferedQueries.forEach(function(args) { - example.apply(this, args); -}); diff --git a/src/adapters/analytics/libraries/example2.js b/src/adapters/analytics/libraries/example2.js deleted file mode 100644 index 68e814b1417..00000000000 --- a/src/adapters/analytics/libraries/example2.js +++ /dev/null @@ -1,59 +0,0 @@ -/* eslint-disable no-console */ -/** @module example */ - -window.ExampleAnalyticsGlobalObject2 = function(hander, type, data) { - console.log(`call to Example2 Analytics library: example2('${hander}', '${type}', ${JSON.stringify(data)})`); -}; - -window[window.ExampleAnalyticsGlobalObject2] = function() {}; - -// var utils = require('utils'); -// var events = require('events'); -// var pbjsHandlers = require('prebid-event-handlers'); -var utils = { errorless: function(fn) { return fn; } }; - -var events = { init: function() { return arguments; } }; - -var pbjsHandlers = { - onBidAdjustment: args => console.log('pbjsHandlers onBidAdjustment args:', args), - onBidTimeout: args => console.log('pbjsHandlers bidTimeout args:', args), - onBidRequested: args => console.log('pbjsHandlers bidRequested args:', args), - onBidResponse: args => console.log('pbjsHandlers bidResponse args:', args), - onBidWon: args => console.log('pbjsHandlers bidWon args:', args) -}; - -// init -var example = window[window.ExampleAnalyticsGlobalObject2]; -var bufferedQueries = example.q || []; - -events.init(); - -// overwrite example object and handle 'on' callbacks -window[window.ExampleAnalyticsGlobalObject2] = example = utils.errorless(function() { - if (arguments[0] && arguments[0] === 'on') { - var eventName = arguments[1] && arguments[1]; - var args = arguments[2] && arguments[2]; - if (eventName && args) { - if (eventName === 'bidAdjustment') { - pbjsHandlers.onBidAdjustment.apply(this, [args]); - } - if (eventName === 'bidTimeout') { - pbjsHandlers.onBidTimeout.apply(this, [args]); - } - if (eventName === 'bidRequested') { - pbjsHandlers.onBidRequested.apply(this, [args]); - } - if (eventName === 'bidResponse') { - pbjsHandlers.onBidResponse.apply(this, [args]); - } - if (eventName === 'bidWon') { - pbjsHandlers.onBidWon.apply(this, [args]); - } - } - } -}); - -// apply bufferedQueries -bufferedQueries.forEach(function(args) { - example.apply(this, args); -}); diff --git a/src/adapters/bidderFactory.js b/src/adapters/bidderFactory.js deleted file mode 100644 index c71c4ee355b..00000000000 --- a/src/adapters/bidderFactory.js +++ /dev/null @@ -1,516 +0,0 @@ -import Adapter from '../adapter.js'; -import adapterManager from '../adapterManager.js'; -import { config } from '../config.js'; -import { createBid } from '../bidfactory.js'; -import { userSync } from '../userSync.js'; -import { nativeBidIsValid } from '../native.js'; -import { isValidVideoBid } from '../video.js'; -import CONSTANTS from '../constants.json'; -import events from '../events.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import { ajax } from '../ajax.js'; -import { logWarn, logError, parseQueryStringParameters, delayExecution, parseSizesInput, getBidderRequest, flatten, uniques, timestamp, deepAccess, isArray, isPlainObject } from '../utils.js'; -import { ADPOD } from '../mediaTypes.js'; -import { getHook, hook } from '../hook.js'; -import { getCoreStorageManager } from '../storageManager.js'; - -export const storage = getCoreStorageManager('bidderFactory'); - -/** - * This file aims to support Adapters during the Prebid 0.x -> 1.x transition. - * - * Prebid 1.x and Prebid 0.x will be in separate branches--perhaps for a long time. - * This function defines an API for adapter construction which is compatible with both versions. - * Adapters which use it can maintain their code in master, and only this file will need to change - * in the 1.x branch. - * - * Typical usage looks something like: - * - * const adapter = registerBidder({ - * code: 'myBidderCode', - * aliases: ['alias1', 'alias2'], - * supportedMediaTypes: ['video', 'native'], - * isBidRequestValid: function(paramsObject) { return true/false }, - * buildRequests: function(bidRequests, bidderRequest) { return some ServerRequest(s) }, - * interpretResponse: function(oneServerResponse) { return some Bids, or throw an error. } - * }); - * - * @see BidderSpec for the full API and more thorough descriptions. - */ - -/** - * @typedef {object} BidderSpec An object containing the adapter-specific functions needed to - * make a Bidder. - * - * @property {string} code A code which will be used to uniquely identify this bidder. This should be the same - * one as is used in the call to registerBidAdapter - * @property {string[]} [aliases] A list of aliases which should also resolve to this bidder. - * @property {MediaType[]} [supportedMediaTypes]: A list of Media Types which the adapter supports. - * @property {function(object): boolean} isBidRequestValid Determines whether or not the given bid has all the params - * needed to make a valid request. - * @property {function(BidRequest[], bidderRequest): ServerRequest|ServerRequest[]} buildRequests Build the request to the Server - * which requests Bids for the given array of Requests. Each BidRequest in the argument array is guaranteed to have - * passed the isBidRequestValid() test. - * @property {function(ServerResponse, BidRequest): Bid[]} interpretResponse Given a successful response from the Server, - * interpret it and return the Bid objects. This function will be run inside a try/catch. - * If it throws any errors, your bids will be discarded. - * @property {function(SyncOptions, ServerResponse[]): UserSync[]} [getUserSyncs] Given an array of all the responses - * from the server, determine which user syncs should occur. The argument array will contain every element - * which has been sent through to interpretResponse. The order of syncs in this array matters. The most - * important ones should come first, since publishers may limit how many are dropped on their page. - * @property {function(object): object} transformBidParams Updates bid params before creating bid request - }} - */ - -/** - * @typedef {object} BidRequest - * - * @property {string} bidId A string which uniquely identifies this BidRequest in the current Auction. - * @property {object} params Any bidder-specific params which the publisher used in their bid request. - */ - -/** - * @typedef {object} ServerRequest - * - * @property {('GET'|'POST')} method The type of request which this is. - * @property {string} url The endpoint for the request. For example, "//bids.example.com". - * @property {string|object} data Data to be sent in the request. - * @property {object} options Content-Type set in the header of the bid request, overrides default 'text/plain'. - * If this is a GET request, they'll become query params. If it's a POST request, they'll be added to the body. - * Strings will be added as-is. Objects will be unpacked into query params based on key/value mappings, or - * JSON-serialized into the Request body. - */ - -/** - * @typedef {object} ServerResponse - * - * @property {*} body The response body. If this is legal JSON, then it will be parsed. Otherwise it'll be a - * string with the body's content. - * @property {{get: function(string): string} headers The response headers. - * Call this like `ServerResponse.headers.get("Content-Type")` - */ - -/** - * @typedef {object} Bid - * - * @property {string} requestId The specific BidRequest which this bid is aimed at. - * This should match the BidRequest.bidId which this Bid targets. - * @property {string} ad A URL which can be used to load this ad, if it's chosen by the publisher. - * @property {string} currency The currency code for the cpm value - * @property {number} cpm The bid price, in US cents per thousand impressions. - * @property {number} ttl Time-to-live - how long (in seconds) Prebid can use this bid. - * @property {boolean} netRevenue Boolean defining whether the bid is Net or Gross. The default is true (Net). - * @property {number} height The height of the ad, in pixels. - * @property {number} width The width of the ad, in pixels. - * - * @property {object} [native] Object for storing native creative assets - * @property {object} [video] Object for storing video response data - * @property {object} [meta] Object for storing bid meta data - * @property {string} [meta.primaryCatId] The IAB primary category ID - * @property [Renderer] renderer A Renderer which can be used as a default for this bid, - * if the publisher doesn't override it. This is only relevant for Outstream Video bids. - */ - -/** - * @typedef {Object} SyncOptions - * - * An object containing information about usersyncs which the adapter should obey. - * - * @property {boolean} iframeEnabled True if iframe usersyncs are allowed, and false otherwise - * @property {boolean} pixelEnabled True if image usersyncs are allowed, and false otherwise - */ - -/** - * TODO: Move this to the UserSync module after that PR is merged. - * - * @typedef {object} UserSync - * - * @property {('image'|'iframe')} type The type of user sync to be done. - * @property {string} url The URL which makes the sync happen. - */ - -// common params for all mediaTypes -const COMMON_BID_RESPONSE_KEYS = ['requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency']; - -const DEFAULT_REFRESHIN_DAYS = 1; - -/** - * Register a bidder with prebid, using the given spec. - * - * If possible, Adapter modules should use this function instead of adapterManager.registerBidAdapter(). - * - * @param {BidderSpec} spec An object containing the bare-bones functions we need to make a Bidder. - */ -export function registerBidder(spec) { - const mediaTypes = Array.isArray(spec.supportedMediaTypes) - ? { supportedMediaTypes: spec.supportedMediaTypes } - : undefined; - function putBidder(spec) { - const bidder = newBidder(spec); - adapterManager.registerBidAdapter(bidder, spec.code, mediaTypes); - } - - putBidder(spec); - if (Array.isArray(spec.aliases)) { - spec.aliases.forEach(alias => { - let aliasCode = alias; - let gvlid; - let skipPbsAliasing; - if (isPlainObject(alias)) { - aliasCode = alias.code; - gvlid = alias.gvlid; - skipPbsAliasing = alias.skipPbsAliasing - } - adapterManager.aliasRegistry[aliasCode] = spec.code; - putBidder(Object.assign({}, spec, { code: aliasCode, gvlid, skipPbsAliasing })); - }); - } -} - -/** - * Make a new bidder from the given spec. This is exported mainly for testing. - * Adapters will probably find it more convenient to use registerBidder instead. - * - * @param {BidderSpec} spec - */ -export function newBidder(spec) { - return Object.assign(new Adapter(spec.code), { - getSpec: function() { - return Object.freeze(spec); - }, - registerSyncs, - callBids: function(bidderRequest, addBidResponse, done, ajax, onTimelyResponse, configEnabledCallback) { - if (!Array.isArray(bidderRequest.bids)) { - return; - } - - const adUnitCodesHandled = {}; - function addBidWithCode(adUnitCode, bid) { - adUnitCodesHandled[adUnitCode] = true; - if (isValid(adUnitCode, bid, [bidderRequest])) { - addBidResponse(adUnitCode, bid); - } - } - - // After all the responses have come back, call done() and - // register any required usersync pixels. - const responses = []; - function afterAllResponses() { - done(); - config.runWithBidder(spec.code, () => { - events.emit(CONSTANTS.EVENTS.BIDDER_DONE, bidderRequest); - registerSyncs(responses, bidderRequest.gdprConsent, bidderRequest.uspConsent); - }); - } - - const validBidRequests = bidderRequest.bids.filter(filterAndWarn); - if (validBidRequests.length === 0) { - afterAllResponses(); - return; - } - const bidRequestMap = {}; - validBidRequests.forEach(bid => { - bidRequestMap[bid.bidId] = bid; - // Delete this once we are 1.0 - if (!bid.adUnitCode) { - bid.adUnitCode = bid.placementCode - } - }); - - let requests = spec.buildRequests(validBidRequests, bidderRequest); - if (!requests || requests.length === 0) { - afterAllResponses(); - return; - } - if (!Array.isArray(requests)) { - requests = [requests]; - } - - // Callbacks don't compose as nicely as Promises. We should call done() once _all_ the - // Server requests have returned and been processed. Since `ajax` accepts a single callback, - // we need to rig up a function which only executes after all the requests have been responded. - const onResponse = delayExecution(configEnabledCallback(afterAllResponses), requests.length) - requests.forEach(processRequest); - - function formatGetParameters(data) { - if (data) { - return `?${typeof data === 'object' ? parseQueryStringParameters(data) : data}`; - } - - return ''; - } - - function processRequest(request) { - switch (request.method) { - case 'GET': - ajax( - `${request.url}${formatGetParameters(request.data)}`, - { - success: configEnabledCallback(onSuccess), - error: onFailure - }, - undefined, - Object.assign({ - method: 'GET', - withCredentials: true - }, request.options) - ); - break; - case 'POST': - ajax( - request.url, - { - success: configEnabledCallback(onSuccess), - error: onFailure - }, - typeof request.data === 'string' ? request.data : JSON.stringify(request.data), - Object.assign({ - method: 'POST', - contentType: 'text/plain', - withCredentials: true - }, request.options) - ); - break; - default: - logWarn(`Skipping invalid request from ${spec.code}. Request type ${request.type} must be GET or POST`); - onResponse(); - } - - // If the server responds successfully, use the adapter code to unpack the Bids from it. - // If the adapter code fails, no bids should be added. After all the bids have been added, make - // sure to call the `onResponse` function so that we're one step closer to calling done(). - function onSuccess(response, responseObj) { - onTimelyResponse(spec.code); - - try { - response = JSON.parse(response); - } catch (e) { /* response might not be JSON... that's ok. */ } - - // Make response headers available for #1742. These are lazy-loaded because most adapters won't need them. - response = { - body: response, - headers: headerParser(responseObj) - }; - responses.push(response); - - let bids; - try { - bids = spec.interpretResponse(response, request); - } catch (err) { - logError(`Bidder ${spec.code} failed to interpret the server's response. Continuing without bids`, null, err); - onResponse(); - return; - } - - if (bids) { - if (isArray(bids)) { - bids.forEach(addBidUsingRequestMap); - } else { - addBidUsingRequestMap(bids); - } - } - onResponse(bids); - - function addBidUsingRequestMap(bid) { - const bidRequest = bidRequestMap[bid.requestId]; - if (bidRequest) { - // creating a copy of original values as cpm and currency are modified later - bid.originalCpm = bid.cpm; - bid.originalCurrency = bid.currency; - bid.meta = bid.meta || Object.assign({}, bid[bidRequest.bidder]); - const prebidBid = Object.assign(createBid(CONSTANTS.STATUS.GOOD, bidRequest), bid); - addBidWithCode(bidRequest.adUnitCode, prebidBid); - } else { - logWarn(`Bidder ${spec.code} made bid for unknown request ID: ${bid.requestId}. Ignoring.`); - } - } - - function headerParser(xmlHttpResponse) { - return { - get: responseObj.getResponseHeader.bind(responseObj) - }; - } - } - - // If the server responds with an error, there's not much we can do. Log it, and make sure to - // call onResponse() so that we're one step closer to calling done(). - function onFailure(err) { - onTimelyResponse(spec.code); - - logError(`Server call for ${spec.code} failed: ${err}. Continuing without bids.`); - onResponse(); - } - } - } - }); - - function registerSyncs(responses, gdprConsent, uspConsent) { - registerSyncInner(spec, responses, gdprConsent, uspConsent); - } - - function filterAndWarn(bid) { - if (!spec.isBidRequestValid(bid)) { - logWarn(`Invalid bid sent to bidder ${spec.code}: ${JSON.stringify(bid)}`); - return false; - } - return true; - } -} - -export const registerSyncInner = hook('async', function(spec, responses, gdprConsent, uspConsent) { - const aliasSyncEnabled = config.getConfig('userSync.aliasSyncEnabled'); - if (spec.getUserSyncs && (aliasSyncEnabled || !adapterManager.aliasRegistry[spec.code])) { - let filterConfig = config.getConfig('userSync.filterSettings'); - let syncs = spec.getUserSyncs({ - iframeEnabled: !!(filterConfig && (filterConfig.iframe || filterConfig.all)), - pixelEnabled: !!(filterConfig && (filterConfig.image || filterConfig.all)), - }, responses, gdprConsent, uspConsent); - if (syncs) { - if (!Array.isArray(syncs)) { - syncs = [syncs]; - } - syncs.forEach((sync) => { - userSync.registerSync(sync.type, spec.code, sync.url) - }); - } - } -}, 'registerSyncs') - -export function preloadBidderMappingFile(fn, adUnits) { - if (!config.getConfig('adpod.brandCategoryExclusion')) { - return fn.call(this, adUnits); - } - let adPodBidders = adUnits - .filter((adUnit) => deepAccess(adUnit, 'mediaTypes.video.context') === ADPOD) - .map((adUnit) => adUnit.bids.map((bid) => bid.bidder)) - .reduce(flatten, []) - .filter(uniques); - - adPodBidders.forEach(bidder => { - let bidderSpec = adapterManager.getBidAdapter(bidder); - if (bidderSpec.getSpec().getMappingFileInfo) { - let info = bidderSpec.getSpec().getMappingFileInfo(); - let refreshInDays = (info.refreshInDays) ? info.refreshInDays : DEFAULT_REFRESHIN_DAYS; - let key = (info.localStorageKey) ? info.localStorageKey : bidderSpec.getSpec().code; - let mappingData = storage.getDataFromLocalStorage(key); - try { - mappingData = mappingData ? JSON.parse(mappingData) : undefined; - if (!mappingData || timestamp() > mappingData.lastUpdated + refreshInDays * 24 * 60 * 60 * 1000) { - ajax(info.url, - { - success: (response) => { - try { - response = JSON.parse(response); - let mapping = { - lastUpdated: timestamp(), - mapping: response.mapping - } - storage.setDataInLocalStorage(key, JSON.stringify(mapping)); - } catch (error) { - logError(`Failed to parse ${bidder} bidder translation mapping file`); - } - }, - error: () => { - logError(`Failed to load ${bidder} bidder translation file`) - } - }, - ); - } - } catch (error) { - logError(`Failed to parse ${bidder} bidder translation mapping file`); - } - } - }); - fn.call(this, adUnits); -} - -getHook('checkAdUnitSetup').before(preloadBidderMappingFile); - -/** - * Reads the data stored in localstorage and returns iab subcategory - * @param {string} bidderCode bidderCode - * @param {string} category bidders category - */ -export function getIabSubCategory(bidderCode, category) { - let bidderSpec = adapterManager.getBidAdapter(bidderCode); - if (bidderSpec.getSpec().getMappingFileInfo) { - let info = bidderSpec.getSpec().getMappingFileInfo(); - let key = (info.localStorageKey) ? info.localStorageKey : bidderSpec.getBidderCode(); - let data = storage.getDataFromLocalStorage(key); - if (data) { - try { - data = JSON.parse(data); - } catch (error) { - logError(`Failed to parse ${bidderCode} mapping data stored in local storage`); - } - return (data.mapping[category]) ? data.mapping[category] : null; - } - } -} - -// check that the bid has a width and height set -function validBidSize(adUnitCode, bid, bidRequests) { - 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); - return true; - } - - const adUnit = getBidderRequest(bidRequests, bid.bidderCode, adUnitCode); - - const sizes = adUnit && adUnit.bids && adUnit.bids[0] && adUnit.bids[0].sizes; - const parsedSizes = parseSizesInput(sizes); - - // 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'); - bid.width = parseInt(width, 10); - bid.height = parseInt(height, 10); - return true; - } - - return false; -} - -// Validate the arguments sent to us by the adapter. If this returns false, the bid should be totally ignored. -export function isValid(adUnitCode, bid, bidRequests) { - function hasValidKeys() { - let bidKeys = Object.keys(bid); - return COMMON_BID_RESPONSE_KEYS.every(key => includes(bidKeys, key) && !includes([undefined, null], bid[key])); - } - - function errorMessage(msg) { - return `Invalid bid from ${bid.bidderCode}. Ignoring bid: ${msg}`; - } - - if (!adUnitCode) { - logWarn('No adUnitCode was supplied to addBidResponse.'); - return false; - } - - if (!bid) { - logWarn(`Some adapter tried to add an undefined bid for ${adUnitCode}.`); - return false; - } - - if (!hasValidKeys()) { - logError(errorMessage(`Bidder ${bid.bidderCode} is missing required params. Check http://prebid.org/dev-docs/bidder-adapter-1.html for list of params.`)); - return false; - } - - if (bid.mediaType === 'native' && !nativeBidIsValid(bid, bidRequests)) { - logError(errorMessage('Native bid missing some required properties.')); - return false; - } - if (bid.mediaType === 'video' && !isValidVideoBid(bid, bidRequests)) { - logError(errorMessage(`Video bid does not have required vastUrl or renderer property`)); - return false; - } - if (bid.mediaType === 'banner' && !validBidSize(adUnitCode, bid, bidRequests)) { - logError(errorMessage(`Banner bids require a width and height`)); - return false; - } - - return true; -} diff --git a/src/adloader.js b/src/adloader.js deleted file mode 100644 index 5460cc79410..00000000000 --- a/src/adloader.js +++ /dev/null @@ -1,91 +0,0 @@ -import includes from 'core-js-pure/features/array/includes.js'; -import * as utils from './utils.js'; - -const _requestCache = {}; -// The below list contains modules or vendors whom Prebid allows to load external JS. -const _approvedLoadExternalJSList = [ - 'adloox', - 'criteo', - 'outstream', - 'adagio', - 'browsi' -] - -/** - * 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 - * Each unique URL will be loaded at most 1 time. - * @param {string} url the url to load - * @param {string} moduleCode bidderCode or module code of the module requesting this resource - * @param {function} [callback] callback function to be called after the script is loaded. - */ -export function loadExternalScript(url, moduleCode, callback) { - if (!moduleCode || !url) { - utils.logError('cannot load external script without url and moduleCode'); - return; - } - if (!includes(_approvedLoadExternalJSList, moduleCode)) { - utils.logError(`${moduleCode} not whitelisted for loading external JavaScript`); - return; - } - // only load each asset once - if (_requestCache[url]) { - if (callback && typeof callback === 'function') { - if (_requestCache[url].loaded) { - // invokeCallbacks immediately - callback(); - } else { - // queue the callback - _requestCache[url].callbacks.push(callback); - } - } - return _requestCache[url].tag; - } - _requestCache[url] = { - loaded: false, - tag: null, - callbacks: [] - }; - if (callback && typeof callback === 'function') { - _requestCache[url].callbacks.push(callback); - } - - utils.logWarn(`module ${moduleCode} is loading external JavaScript`); - return requestResource(url, function () { - _requestCache[url].loaded = true; - try { - for (let i = 0; i < _requestCache[url].callbacks.length; i++) { - _requestCache[url].callbacks[i](); - } - } catch (e) { - utils.logError('Error executing callback', 'adloader.js:loadExternalScript', e); - } - }); - - function requestResource(tagSrc, callback) { - var jptScript = document.createElement('script'); - jptScript.type = 'text/javascript'; - jptScript.async = true; - - _requestCache[url].tag = jptScript; - - if (jptScript.readyState) { - jptScript.onreadystatechange = function () { - if (jptScript.readyState === 'loaded' || jptScript.readyState === 'complete') { - jptScript.onreadystatechange = null; - callback(); - } - }; - } else { - jptScript.onload = function () { - callback(); - }; - } - - jptScript.src = tagSrc; - - // add the new script tag to the page - utils.insertElement(jptScript); - - return jptScript; - } -}; diff --git a/src/adserver.js b/src/adserver.js deleted file mode 100644 index 61af8862972..00000000000 --- a/src/adserver.js +++ /dev/null @@ -1,55 +0,0 @@ -import { formatQS } from './utils.js'; -import { targeting } from './targeting.js'; - -// Adserver parent class -const AdServer = function(attr) { - this.name = attr.adserver; - this.code = attr.code; - this.getWinningBidByCode = function() { - return targeting.getWinningBids(this.code)[0]; - }; -}; - -// DFP ad server -export function dfpAdserver(options, urlComponents) { - var adserver = new AdServer(options); - adserver.urlComponents = urlComponents; - - var dfpReqParams = { - 'env': 'vp', - 'gdfp_req': '1', - 'impl': 's', - 'unviewed_position_start': '1' - }; - - var dfpParamsWithVariableValue = ['output', 'iu', 'sz', 'url', 'correlator', 'description_url', 'hl']; - - var getCustomParams = function(targeting) { - return encodeURIComponent(formatQS(targeting)); - }; - - adserver.appendQueryParams = function() { - var bid = adserver.getWinningBidByCode(); - if (bid) { - this.urlComponents.search.description_url = encodeURIComponent(bid.vastUrl); - this.urlComponents.search.cust_params = getCustomParams(bid.adserverTargeting); - this.urlComponents.search.correlator = Date.now(); - } - }; - - adserver.verifyAdserverTag = function() { - for (var key in dfpReqParams) { - if (!this.urlComponents.search.hasOwnProperty(key) || this.urlComponents.search[key] !== dfpReqParams[key]) { - return false; - } - } - for (var i in dfpParamsWithVariableValue) { - if (!this.urlComponents.search.hasOwnProperty(dfpParamsWithVariableValue[i])) { - return false; - } - } - return true; - }; - - return adserver; -}; diff --git a/src/ajax.js b/src/ajax.js deleted file mode 100644 index b1e4cbdbdff..00000000000 --- a/src/ajax.js +++ /dev/null @@ -1,99 +0,0 @@ -import { config } from './config.js'; - -var utils = require('./utils.js'); - -const XHR_DONE = 4; - -/** - * Simple IE9+ and cross-browser ajax request function - * Note: x-domain requests in IE9 do not support the use of cookies - * - * @param url string url - * @param callback {object | function} callback - * @param data mixed data - * @param options object - */ -export const ajax = ajaxBuilder(); - -export function ajaxBuilder(timeout = 3000, {request, done} = {}) { - return function(url, callback, data, options = {}) { - try { - let x; - let method = options.method || (data ? 'POST' : 'GET'); - let parser = document.createElement('a'); - parser.href = url; - - let callbacks = typeof callback === 'object' && callback !== null ? callback : { - success: function() { - utils.logMessage('xhr success'); - }, - error: function(e) { - utils.logError('xhr error', null, e); - } - }; - - if (typeof callback === 'function') { - callbacks.success = callback; - } - - x = new window.XMLHttpRequest(); - - x.onreadystatechange = function () { - if (x.readyState === XHR_DONE) { - if (typeof done === 'function') { - done(parser.origin); - } - let status = x.status; - if ((status >= 200 && status < 300) || status === 304) { - callbacks.success(x.responseText, x); - } else { - callbacks.error(x.statusText, x); - } - } - }; - - // Disabled timeout temporarily to avoid xhr failed requests. https://github.com/prebid/Prebid.js/issues/2648 - if (!config.getConfig('disableAjaxTimeout')) { - x.ontimeout = function () { - utils.logError(' xhr timeout after ', x.timeout, 'ms'); - }; - } - - if (method === 'GET' && data) { - let urlInfo = utils.parseUrl(url, options); - Object.assign(urlInfo.search, data); - url = utils.buildUrl(urlInfo); - } - - x.open(method, url, true); - // IE needs timoeut to be set after open - see #1410 - // Disabled timeout temporarily to avoid xhr failed requests. https://github.com/prebid/Prebid.js/issues/2648 - if (!config.getConfig('disableAjaxTimeout')) { - x.timeout = timeout; - } - - if (options.withCredentials) { - x.withCredentials = true; - } - utils._each(options.customHeaders, (value, header) => { - x.setRequestHeader(header, value); - }); - if (options.preflight) { - x.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); - } - x.setRequestHeader('Content-Type', options.contentType || 'text/plain'); - - if (typeof request === 'function') { - request(parser.origin); - } - - if (method === 'POST' && data) { - x.send(data); - } else { - x.send(); - } - } catch (error) { - utils.logError('xhr construction', error); - } - } -} diff --git a/src/auction.js b/src/auction.js deleted file mode 100644 index a6f0342e582..00000000000 --- a/src/auction.js +++ /dev/null @@ -1,833 +0,0 @@ -/** - * Module for auction instances. - * - * In Prebid 0.x, $$PREBID_GLOBAL$$ had _bidsRequested and _bidsReceived as public properties. - * Starting 1.0, Prebid will support concurrent auctions. Each auction instance will store private properties, bidsRequested and bidsReceived. - * - * AuctionManager will create instance of auction and will store all the auctions. - * - */ - -/** - * @typedef {Object} AdUnit An object containing the adUnit configuration. - * - * @property {string} code A code which will be used to uniquely identify this bidder. This should be the same - * one as is used in the call to registerBidAdapter - * @property {Array.} sizes A list of size for adUnit. - * @property {object} params Any bidder-specific params which the publisher used in their bid request. - * This is guaranteed to have passed the spec.areParamsValid() test. - */ - -/** - * @typedef {Array.} size - */ - -/** - * @typedef {Array.} AdUnitCode - */ - -/** - * @typedef {Object} BidderRequest - * - * @property {string} bidderCode - adUnit bidder - * @property {number} auctionId - random UUID - * @property {string} bidderRequestId - random string, unique key set on all bidRequest.bids[] - * @property {Array.} bids - * @property {number} auctionStart - Date.now() at auction start - * @property {number} timeout - callback timeout - * @property {refererInfo} refererInfo - referer info object - * @property {string} [tid] - random UUID (used for s2s) - * @property {string} [src] - s2s or client (used for s2s) - */ - -/** - * @typedef {Object} BidReceived - * //TODO add all properties - */ - -/** - * @typedef {Object} Auction - * - * @property {function(): string} getAuctionStatus - returns the auction status which can be any one of 'started', 'in progress' or 'completed' - * @property {function(): AdUnit[]} getAdUnits - return the adUnits for this auction instance - * @property {function(): AdUnitCode[]} getAdUnitCodes - return the adUnitCodes for this auction instance - * @property {function(): BidRequest[]} getBidRequests - get all bid requests for this auction instance - * @property {function(): BidReceived[]} getBidsReceived - get all bid received for this auction instance - * @property {function(): void} startAuctionTimer - sets the bidsBackHandler callback and starts the timer for auction - * @property {function(): void} callBids - sends requests to all adapters for bids - */ - -import {flatten, timestamp, adUnitsFilter, deepAccess, getBidRequest, getValue, parseUrl} from './utils.js'; -import { getPriceBucketString } from './cpmBucketManager.js'; -import { getNativeTargeting } from './native.js'; -import { getCacheUrl, store } from './videoCache.js'; -import { Renderer } from './Renderer.js'; -import { config } from './config.js'; -import { userSync } from './userSync.js'; -import { hook } from './hook.js'; -import find from 'core-js-pure/features/array/find.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import { OUTSTREAM } from './video.js'; -import { VIDEO } from './mediaTypes.js'; - -const { syncUsers } = userSync; -const utils = require('./utils.js'); -const adapterManager = require('./adapterManager.js').default; -const events = require('./events.js'); -const CONSTANTS = require('./constants.json'); - -export const AUCTION_STARTED = 'started'; -export const AUCTION_IN_PROGRESS = 'inProgress'; -export const AUCTION_COMPLETED = 'completed'; - -// register event for bid adjustment -events.on(CONSTANTS.EVENTS.BID_ADJUSTMENT, function (bid) { - adjustBids(bid); -}); - -const MAX_REQUESTS_PER_ORIGIN = 4; -const outstandingRequests = {}; -const sourceInfo = {}; -const queuedCalls = []; - -/** - * Creates new auction instance - * - * @param {Object} requestConfig - * @param {AdUnit} requestConfig.adUnits - * @param {AdUnitCode} requestConfig.adUnitCodes - * @param {function():void} requestConfig.callback - * @param {number} requestConfig.cbTimeout - * @param {Array.} requestConfig.labels - * @param {string} requestConfig.auctionId - * - * @returns {Auction} auction instance - */ -export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels, auctionId}) { - let _adUnits = adUnits; - let _labels = labels; - let _adUnitCodes = adUnitCodes; - let _bidderRequests = []; - let _bidsReceived = []; - let _noBids = []; - let _auctionStart; - let _auctionEnd; - let _auctionId = auctionId || utils.generateUUID(); - let _auctionStatus; - let _callback = callback; - let _timer; - let _timeout = cbTimeout; - let _winningBids = []; - let _timelyBidders = new Set(); - - function addBidRequests(bidderRequests) { _bidderRequests = _bidderRequests.concat(bidderRequests); } - function addBidReceived(bidsReceived) { _bidsReceived = _bidsReceived.concat(bidsReceived); } - function addNoBid(noBid) { _noBids = _noBids.concat(noBid); } - - function getProperties() { - return { - auctionId: _auctionId, - timestamp: _auctionStart, - auctionEnd: _auctionEnd, - auctionStatus: _auctionStatus, - adUnits: _adUnits, - adUnitCodes: _adUnitCodes, - labels: _labels, - bidderRequests: _bidderRequests, - noBids: _noBids, - bidsReceived: _bidsReceived, - winningBids: _winningBids, - timeout: _timeout - }; - } - - function startAuctionTimer() { - const timedOut = true; - const timeoutCallback = executeCallback.bind(null, timedOut); - let timer = setTimeout(timeoutCallback, _timeout); - _timer = timer; - } - - function executeCallback(timedOut, cleartimer) { - // clear timer when done calls executeCallback - if (cleartimer) { - clearTimeout(_timer); - } - - if (_auctionEnd === undefined) { - let timedOutBidders = []; - if (timedOut) { - utils.logMessage(`Auction ${_auctionId} timedOut`); - timedOutBidders = getTimedOutBids(_bidderRequests, _timelyBidders); - if (timedOutBidders.length) { - events.emit(CONSTANTS.EVENTS.BID_TIMEOUT, timedOutBidders); - } - } - - _auctionStatus = AUCTION_COMPLETED; - _auctionEnd = Date.now(); - - events.emit(CONSTANTS.EVENTS.AUCTION_END, getProperties()); - bidsBackCallback(_adUnits, function () { - try { - if (_callback != null) { - const adUnitCodes = _adUnitCodes; - const bids = _bidsReceived - .filter(utils.bind.call(adUnitsFilter, this, adUnitCodes)) - .reduce(groupByPlacement, {}); - _callback.apply($$PREBID_GLOBAL$$, [bids, timedOut, _auctionId]); - _callback = null; - } - } catch (e) { - utils.logError('Error executing bidsBackHandler', null, e); - } finally { - // Calling timed out bidders - if (timedOutBidders.length) { - adapterManager.callTimedOutBidders(adUnits, timedOutBidders, _timeout); - } - // Only automatically sync if the publisher has not chosen to "enableOverride" - let userSyncConfig = config.getConfig('userSync') || {}; - if (!userSyncConfig.enableOverride) { - // Delay the auto sync by the config delay - syncUsers(userSyncConfig.syncDelay); - } - } - }) - } - } - - function auctionDone() { - config.resetBidder(); - // when all bidders have called done callback atleast once it means auction is complete - utils.logInfo(`Bids Received for Auction with id: ${_auctionId}`, _bidsReceived); - _auctionStatus = AUCTION_COMPLETED; - executeCallback(false, true); - } - - function onTimelyResponse(bidderCode) { - _timelyBidders.add(bidderCode); - } - - function callBids() { - _auctionStatus = AUCTION_STARTED; - _auctionStart = Date.now(); - - let bidRequests = adapterManager.makeBidRequests(_adUnits, _auctionStart, _auctionId, _timeout, _labels); - utils.logInfo(`Bids Requested for Auction with id: ${_auctionId}`, bidRequests); - - if (bidRequests.length < 1) { - utils.logWarn('No valid bid requests returned for auction'); - auctionDone(); - } else { - addBidderRequests.call({ - dispatch: addBidderRequestsCallback, - context: this - }, bidRequests); - } - } - - /** - * callback executed after addBidderRequests completes - * @param {BidRequest[]} bidRequests - */ - function addBidderRequestsCallback(bidRequests) { - bidRequests.forEach(bidRequest => { - addBidRequests(bidRequest); - }); - - let requests = {}; - let call = { - bidRequests, - run: () => { - startAuctionTimer(); - - _auctionStatus = AUCTION_IN_PROGRESS; - - events.emit(CONSTANTS.EVENTS.AUCTION_INIT, getProperties()); - - let callbacks = auctionCallbacks(auctionDone, this); - adapterManager.callBids(_adUnits, bidRequests, function(...args) { - addBidResponse.apply({ - dispatch: callbacks.addBidResponse, - bidderRequest: this - }, args) - }, callbacks.adapterDone, { - request(source, origin) { - increment(outstandingRequests, origin); - increment(requests, source); - - if (!sourceInfo[source]) { - sourceInfo[source] = { - SRA: true, - origin - }; - } - if (requests[source] > 1) { - sourceInfo[source].SRA = false; - } - }, - done(origin) { - outstandingRequests[origin]--; - if (queuedCalls[0]) { - if (runIfOriginHasCapacity(queuedCalls[0])) { - queuedCalls.shift(); - } - } - } - }, _timeout, onTimelyResponse); - } - }; - - if (!runIfOriginHasCapacity(call)) { - utils.logWarn('queueing auction due to limited endpoint capacity'); - queuedCalls.push(call); - } - - function runIfOriginHasCapacity(call) { - let hasCapacity = true; - - let maxRequests = config.getConfig('maxRequestsPerOrigin') || MAX_REQUESTS_PER_ORIGIN; - - call.bidRequests.some(bidRequest => { - let requests = 1; - let source = (typeof bidRequest.src !== 'undefined' && bidRequest.src === CONSTANTS.S2S.SRC) ? 's2s' - : bidRequest.bidderCode; - // if we have no previous info on this source just let them through - if (sourceInfo[source]) { - if (sourceInfo[source].SRA === false) { - // some bidders might use more than the MAX_REQUESTS_PER_ORIGIN in a single auction. In those cases - // set their request count to MAX_REQUESTS_PER_ORIGIN so the auction isn't permanently queued waiting - // for capacity for that bidder - requests = Math.min(bidRequest.bids.length, maxRequests); - } - if (outstandingRequests[sourceInfo[source].origin] + requests > maxRequests) { - hasCapacity = false; - } - } - // return only used for terminating this .some() iteration early if it is determined we don't have capacity - return !hasCapacity; - }); - - if (hasCapacity) { - call.run(); - } - - return hasCapacity; - } - - function increment(obj, prop) { - if (typeof obj[prop] === 'undefined') { - obj[prop] = 1 - } else { - obj[prop]++; - } - } - } - - function addWinningBid(winningBid) { - _winningBids = _winningBids.concat(winningBid); - adapterManager.callBidWonBidder(winningBid.bidder, winningBid, adUnits); - } - - function setBidTargeting(bid) { - adapterManager.callSetTargetingBidder(bid.bidder, bid); - } - - return { - addBidReceived, - addNoBid, - executeCallback, - callBids, - addWinningBid, - setBidTargeting, - getWinningBids: () => _winningBids, - getTimeout: () => _timeout, - getAuctionId: () => _auctionId, - getAuctionStatus: () => _auctionStatus, - getAdUnits: () => _adUnits, - getAdUnitCodes: () => _adUnitCodes, - getBidRequests: () => _bidderRequests, - getBidsReceived: () => _bidsReceived, - getNoBids: () => _noBids - } -} - -export const addBidResponse = hook('async', function(adUnitCode, bid) { - this.dispatch.call(this.bidderRequest, adUnitCode, bid); -}, 'addBidResponse'); - -export const addBidderRequests = hook('sync', function(bidderRequests) { - this.dispatch.call(this.context, bidderRequests); -}, 'addBidderRequests'); - -export const bidsBackCallback = hook('async', function (adUnits, callback) { - if (callback) { - callback(); - } -}, 'bidsBackCallback'); - -export function auctionCallbacks(auctionDone, auctionInstance) { - let outstandingBidsAdded = 0; - let allAdapterCalledDone = false; - let bidderRequestsDone = new Set(); - let bidResponseMap = {}; - - function afterBidAdded() { - outstandingBidsAdded--; - if (allAdapterCalledDone && outstandingBidsAdded === 0) { - auctionDone() - } - } - - function addBidResponse(adUnitCode, bid) { - let bidderRequest = this; - - bidResponseMap[bid.requestId] = true; - - outstandingBidsAdded++; - let auctionId = auctionInstance.getAuctionId(); - - let bidResponse = getPreparedBidForAuction({adUnitCode, bid, bidderRequest, auctionId}); - - if (bidResponse.mediaType === 'video') { - tryAddVideoBid(auctionInstance, bidResponse, bidderRequest, afterBidAdded); - } else { - addBidToAuction(auctionInstance, bidResponse); - afterBidAdded(); - } - } - - function adapterDone() { - let bidderRequest = this; - let bidderRequests = auctionInstance.getBidRequests(); - const auctionOptionsConfig = config.getConfig('auctionOptions'); - - bidderRequestsDone.add(bidderRequest); - - if (auctionOptionsConfig && !utils.isEmpty(auctionOptionsConfig)) { - const secondaryBidders = auctionOptionsConfig.secondaryBidders; - if (secondaryBidders && !bidderRequests.every(bidder => includes(secondaryBidders, bidder.bidderCode))) { - bidderRequests = bidderRequests.filter(request => !includes(secondaryBidders, request.bidderCode)); - } - } - - allAdapterCalledDone = bidderRequests.every(bidderRequest => bidderRequestsDone.has(bidderRequest)); - - bidderRequest.bids.forEach(bid => { - if (!bidResponseMap[bid.bidId]) { - auctionInstance.addNoBid(bid); - events.emit(CONSTANTS.EVENTS.NO_BID, bid); - } - }); - - if (allAdapterCalledDone && outstandingBidsAdded === 0) { - auctionDone(); - } - } - - return { - addBidResponse, - adapterDone - } -} - -export function doCallbacksIfTimedout(auctionInstance, bidResponse) { - if (bidResponse.timeToRespond > auctionInstance.getTimeout() + config.getConfig('timeoutBuffer')) { - auctionInstance.executeCallback(true); - } -} - -// Add a bid to the auction. -export function addBidToAuction(auctionInstance, bidResponse) { - let bidderRequests = auctionInstance.getBidRequests(); - let bidderRequest = find(bidderRequests, bidderRequest => bidderRequest.bidderCode === bidResponse.bidderCode); - setupBidTargeting(bidResponse, bidderRequest); - - events.emit(CONSTANTS.EVENTS.BID_RESPONSE, bidResponse); - auctionInstance.addBidReceived(bidResponse); - - doCallbacksIfTimedout(auctionInstance, bidResponse); -} - -// Video bids may fail if the cache is down, or there's trouble on the network. -function tryAddVideoBid(auctionInstance, bidResponse, bidRequests, afterBidAdded) { - let addBid = true; - - const bidderRequest = getBidRequest(bidResponse.originalRequestId || bidResponse.requestId, [bidRequests]); - const videoMediaType = - bidderRequest && deepAccess(bidderRequest, 'mediaTypes.video'); - const context = videoMediaType && deepAccess(videoMediaType, 'context'); - - if (config.getConfig('cache.url') && context !== OUTSTREAM) { - if (!bidResponse.videoCacheKey || config.getConfig('cache.ignoreBidderCacheKey')) { - addBid = false; - callPrebidCache(auctionInstance, bidResponse, afterBidAdded, bidderRequest); - } else if (!bidResponse.vastUrl) { - utils.logError('videoCacheKey specified but not required vastUrl for video bid'); - addBid = false; - } - } - if (addBid) { - addBidToAuction(auctionInstance, bidResponse); - afterBidAdded(); - } -} - -export const callPrebidCache = hook('async', function(auctionInstance, bidResponse, afterBidAdded, bidderRequest) { - store([bidResponse], function (error, cacheIds) { - if (error) { - utils.logWarn(`Failed to save to the video cache: ${error}. Video bid must be discarded.`); - - doCallbacksIfTimedout(auctionInstance, bidResponse); - } else { - if (cacheIds[0].uuid === '') { - utils.logWarn(`Supplied video cache key was already in use by Prebid Cache; caching attempt was rejected. Video bid must be discarded.`); - - doCallbacksIfTimedout(auctionInstance, bidResponse); - } else { - bidResponse.videoCacheKey = cacheIds[0].uuid; - - if (!bidResponse.vastUrl) { - bidResponse.vastUrl = getCacheUrl(bidResponse.videoCacheKey); - } - addBidToAuction(auctionInstance, bidResponse); - afterBidAdded(); - } - } - }, bidderRequest); -}, 'callPrebidCache'); - -// Postprocess the bids so that all the universal properties exist, no matter which bidder they came from. -// This should be called before addBidToAuction(). -function getPreparedBidForAuction({adUnitCode, bid, bidderRequest, auctionId}) { - const start = bidderRequest.start; - - let bidObject = Object.assign({}, bid, { - auctionId, - responseTimestamp: timestamp(), - requestTimestamp: start, - cpm: parseFloat(bid.cpm) || 0, - bidder: bid.bidderCode, - adUnitCode - }); - - bidObject.timeToRespond = bidObject.responseTimestamp - bidObject.requestTimestamp; - - // 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), - // but others to not be set yet (like priceStrings). See #1372 and #1389. - events.emit(CONSTANTS.EVENTS.BID_ADJUSTMENT, bidObject); - - // a publisher-defined renderer can be used to render bids - const bidReq = bidderRequest.bids && find(bidderRequest.bids, bid => bid.adUnitCode == adUnitCode && bid.bidId == bidObject.requestId); - const adUnitRenderer = bidReq && bidReq.renderer; - - // a publisher can also define a renderer for a mediaType - const bidObjectMediaType = bidObject.mediaType; - const bidMediaType = bidReq && - bidReq.mediaTypes && - bidReq.mediaTypes[bidObjectMediaType]; - - var mediaTypeRenderer = bidMediaType && bidMediaType.renderer; - - var renderer = null; - - // the renderer for the mediaType takes precendence - if (mediaTypeRenderer && mediaTypeRenderer.url && mediaTypeRenderer.render && !(mediaTypeRenderer.backupOnly === true && bid.renderer)) { - renderer = mediaTypeRenderer; - } else if (adUnitRenderer && adUnitRenderer.url && adUnitRenderer.render && !(adUnitRenderer.backupOnly === true && bid.renderer)) { - renderer = adUnitRenderer; - } - - if (renderer) { - bidObject.renderer = Renderer.install({ url: renderer.url }); - bidObject.renderer.setRender(renderer.render); - } - - // Use the config value 'mediaTypeGranularity' if it has been defined for mediaType, else use 'customPriceBucket' - const mediaTypeGranularity = getMediaTypeGranularity(bid.mediaType, bidReq, config.getConfig('mediaTypePriceGranularity')); - const priceStringsObj = getPriceBucketString( - bidObject.cpm, - (typeof mediaTypeGranularity === 'object') ? mediaTypeGranularity : config.getConfig('customPriceBucket'), - config.getConfig('currency.granularityMultiplier') - ); - bidObject.pbLg = priceStringsObj.low; - bidObject.pbMg = priceStringsObj.med; - bidObject.pbHg = priceStringsObj.high; - bidObject.pbAg = priceStringsObj.auto; - bidObject.pbDg = priceStringsObj.dense; - bidObject.pbCg = priceStringsObj.custom; - - return bidObject; -} - -function setupBidTargeting(bidObject, bidderRequest) { - let keyValues; - if (bidObject.bidderCode && (bidObject.cpm > 0 || bidObject.dealId)) { - let bidReq = find(bidderRequest.bids, bid => bid.adUnitCode === bidObject.adUnitCode); - keyValues = getKeyValueTargetingPairs(bidObject.bidderCode, bidObject, bidReq); - } - - // use any targeting provided as defaults, otherwise just set from getKeyValueTargetingPairs - bidObject.adserverTargeting = Object.assign(bidObject.adserverTargeting || {}, keyValues); -} - -/** - * @param {MediaType} mediaType - * @param {Bid} [bidReq] - * @param {MediaTypePriceGranularity} [mediaTypePriceGranularity] - * @returns {(Object|string|undefined)} - */ -export function getMediaTypeGranularity(mediaType, bidReq, mediaTypePriceGranularity) { - if (mediaType && mediaTypePriceGranularity) { - if (mediaType === VIDEO) { - const context = deepAccess(bidReq, `mediaTypes.${VIDEO}.context`, 'instream'); - if (mediaTypePriceGranularity[`${VIDEO}-${context}`]) { - return mediaTypePriceGranularity[`${VIDEO}-${context}`]; - } - } - return mediaTypePriceGranularity[mediaType]; - } -} - -/** - * This function returns the price granularity defined. It can be either publisher defined or default value - * @param {string} mediaType - * @param {BidRequest} bidReq - * @returns {string} granularity - */ -export const getPriceGranularity = (mediaType, bidReq) => { - // Use the config value 'mediaTypeGranularity' if it has been set for mediaType, else use 'priceGranularity' - const mediaTypeGranularity = getMediaTypeGranularity(mediaType, bidReq, config.getConfig('mediaTypePriceGranularity')); - const granularity = (typeof mediaType === 'string' && mediaTypeGranularity) ? ((typeof mediaTypeGranularity === 'string') ? mediaTypeGranularity : 'custom') : config.getConfig('priceGranularity'); - return granularity; -} - -/** - * This function returns a function to get bid price by price granularity - * @param {string} granularity - * @returns {function} - */ -export const getPriceByGranularity = (granularity) => { - return (bid) => { - if (granularity === CONSTANTS.GRANULARITY_OPTIONS.AUTO) { - return bid.pbAg; - } else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.DENSE) { - return bid.pbDg; - } else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.LOW) { - return bid.pbLg; - } else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.MEDIUM) { - return bid.pbMg; - } else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.HIGH) { - return bid.pbHg; - } else if (granularity === CONSTANTS.GRANULARITY_OPTIONS.CUSTOM) { - return bid.pbCg; - } - } -} - -/** - * This function returns a function to get first advertiser domain from bid response meta - * @returns {function} - */ -export const getAdvertiserDomain = () => { - return (bid) => { - return (bid.meta && bid.meta.advertiserDomains && bid.meta.advertiserDomains.length > 0) ? bid.meta.advertiserDomains[0] : ''; - } -} - -/** - * @param {string} mediaType - * @param {string} bidderCode - * @param {BidRequest} bidReq - * @returns {*} - */ -export function getStandardBidderSettings(mediaType, bidderCode, bidReq) { - // factory for key value objs - function createKeyVal(key, value) { - return { - key, - val: (typeof value === 'function') - ? function (bidResponse) { - return value(bidResponse); - } - : function (bidResponse) { - return getValue(bidResponse, value); - } - }; - } - const TARGETING_KEYS = CONSTANTS.TARGETING_KEYS; - const granularity = getPriceGranularity(mediaType, bidReq); - - let bidderSettings = $$PREBID_GLOBAL$$.bidderSettings; - if (!bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD]) { - bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD] = {}; - } - if (!bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD][CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING]) { - bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD][CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING] = [ - createKeyVal(TARGETING_KEYS.BIDDER, 'bidderCode'), - createKeyVal(TARGETING_KEYS.AD_ID, 'adId'), - createKeyVal(TARGETING_KEYS.PRICE_BUCKET, getPriceByGranularity(granularity)), - createKeyVal(TARGETING_KEYS.SIZE, 'size'), - createKeyVal(TARGETING_KEYS.DEAL, 'dealId'), - createKeyVal(TARGETING_KEYS.SOURCE, 'source'), - createKeyVal(TARGETING_KEYS.FORMAT, 'mediaType'), - createKeyVal(TARGETING_KEYS.ADOMAIN, getAdvertiserDomain()), - ] - } - - if (mediaType === 'video') { - const adserverTargeting = bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD][CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING]; - - // Adding hb_uuid + hb_cache_id - [TARGETING_KEYS.UUID, TARGETING_KEYS.CACHE_ID].forEach(targetingKeyVal => { - if (typeof find(adserverTargeting, kvPair => kvPair.key === targetingKeyVal) === 'undefined') { - adserverTargeting.push(createKeyVal(targetingKeyVal, 'videoCacheKey')); - } - }); - - // Adding hb_cache_host - if (config.getConfig('cache.url') && (!bidderCode || utils.deepAccess(bidderSettings, `${bidderCode}.sendStandardTargeting`) !== false)) { - const urlInfo = parseUrl(config.getConfig('cache.url')); - - if (typeof find(adserverTargeting, targetingKeyVal => targetingKeyVal.key === TARGETING_KEYS.CACHE_HOST) === 'undefined') { - adserverTargeting.push(createKeyVal(TARGETING_KEYS.CACHE_HOST, function(bidResponse) { - return utils.deepAccess(bidResponse, `adserverTargeting.${TARGETING_KEYS.CACHE_HOST}`) - ? bidResponse.adserverTargeting[TARGETING_KEYS.CACHE_HOST] : urlInfo.hostname; - })); - } - } - } - return bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD]; -} - -export function getKeyValueTargetingPairs(bidderCode, custBidObj, bidReq) { - if (!custBidObj) { - return {}; - } - - var keyValues = {}; - var bidderSettings = $$PREBID_GLOBAL$$.bidderSettings; - - // 1) set the keys from "standard" setting or from prebid defaults - if (bidderSettings) { - // initialize default if not set - const standardSettings = getStandardBidderSettings(custBidObj.mediaType, bidderCode, bidReq); - setKeys(keyValues, standardSettings, custBidObj); - - // 2) set keys from specific bidder setting override if they exist - if (bidderCode && bidderSettings[bidderCode] && bidderSettings[bidderCode][CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING]) { - setKeys(keyValues, bidderSettings[bidderCode], custBidObj); - custBidObj.sendStandardTargeting = bidderSettings[bidderCode].sendStandardTargeting; - } - } - - // set native key value targeting - if (custBidObj['native']) { - keyValues = Object.assign({}, keyValues, getNativeTargeting(custBidObj, bidReq)); - } - - return keyValues; -} - -function setKeys(keyValues, bidderSettings, custBidObj) { - var targeting = bidderSettings[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING]; - custBidObj.size = custBidObj.getSize(); - - utils._each(targeting, function (kvPair) { - var key = kvPair.key; - var value = kvPair.val; - - if (keyValues[key]) { - utils.logWarn('The key: ' + key + ' is getting ovewritten'); - } - - if (utils.isFn(value)) { - try { - value = value(custBidObj); - } catch (e) { - utils.logError('bidmanager', 'ERROR', e); - } - } - - if ( - ((typeof bidderSettings.suppressEmptyKeys !== 'undefined' && bidderSettings.suppressEmptyKeys === true) || - key === CONSTANTS.TARGETING_KEYS.DEAL) && // hb_deal is suppressed automatically if not set - ( - utils.isEmptyStr(value) || - value === null || - value === undefined - ) - ) { - utils.logInfo("suppressing empty key '" + key + "' from adserver targeting"); - } else { - keyValues[key] = value; - } - }); - - return keyValues; -} - -export function adjustBids(bid) { - let code = bid.bidderCode; - let bidPriceAdjusted = bid.cpm; - let bidCpmAdjustment; - if ($$PREBID_GLOBAL$$.bidderSettings) { - if (code && $$PREBID_GLOBAL$$.bidderSettings[code] && typeof $$PREBID_GLOBAL$$.bidderSettings[code].bidCpmAdjustment === 'function') { - bidCpmAdjustment = $$PREBID_GLOBAL$$.bidderSettings[code].bidCpmAdjustment; - } else if ($$PREBID_GLOBAL$$.bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD] && typeof $$PREBID_GLOBAL$$.bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD].bidCpmAdjustment === 'function') { - bidCpmAdjustment = $$PREBID_GLOBAL$$.bidderSettings[CONSTANTS.JSON_MAPPING.BD_SETTING_STANDARD].bidCpmAdjustment; - } - if (bidCpmAdjustment) { - try { - bidPriceAdjusted = bidCpmAdjustment(bid.cpm, Object.assign({}, bid)); - } catch (e) { - utils.logError('Error during bid adjustment', 'bidmanager.js', e); - } - } - } - - if (bidPriceAdjusted >= 0) { - bid.cpm = bidPriceAdjusted; - } -} - -/** - * groupByPlacement is a reduce function that converts an array of Bid objects - * to an object with placement codes as keys, with each key representing an object - * with an array of `Bid` objects for that placement - * @returns {*} as { [adUnitCode]: { bids: [Bid, Bid, Bid] } } - */ -function groupByPlacement(bidsByPlacement, bid) { - if (!bidsByPlacement[bid.adUnitCode]) { bidsByPlacement[bid.adUnitCode] = { bids: [] }; } - bidsByPlacement[bid.adUnitCode].bids.push(bid); - return bidsByPlacement; -} - -/** - * Returns a list of bids that we haven't received a response yet where the bidder did not call done - * @param {BidRequest[]} bidderRequests List of bids requested for auction instance - * @param {Set} timelyBidders Set of bidders which responded in time - * - * @typedef {Object} TimedOutBid - * @property {string} bidId The id representing the bid - * @property {string} bidder The string name of the bidder - * @property {string} adUnitCode The code used to uniquely identify the ad unit on the publisher's page - * @property {string} auctionId The id representing the auction - * - * @return {Array} List of bids that Prebid hasn't received a response for - */ -function getTimedOutBids(bidderRequests, timelyBidders) { - const timedOutBids = bidderRequests - .map(bid => (bid.bids || []).filter(bid => !timelyBidders.has(bid.bidder))) - .reduce(flatten, []) - .map(bid => ({ - bidId: bid.bidId, - bidder: bid.bidder, - adUnitCode: bid.adUnitCode, - auctionId: bid.auctionId, - })); - - return timedOutBids; -} diff --git a/src/auctionManager.js b/src/auctionManager.js deleted file mode 100644 index 1aca1277aa8..00000000000 --- a/src/auctionManager.js +++ /dev/null @@ -1,123 +0,0 @@ -/** - * AuctionManager modules is responsible for creating auction instances. - * This module is the gateway for Prebid core to access auctions. - * It stores all created instances of auction and can be used to get consolidated values from auction. - */ - -/** - * @typedef {Object} AuctionManager - * - * @property {function(): Array} getBidsRequested - returns consolidated bid requests - * @property {function(): Array} getBidsReceived - returns consolidated bid received - * @property {function(): Array} getAllBidsForAdUnitCode - returns consolidated bid received for a given adUnit - * @property {function(): Array} getAdUnits - returns consolidated adUnits - * @property {function(): Array} getAdUnitCodes - returns consolidated adUnitCodes - * @property {function(): Object} createAuction - creates auction instance and stores it for future reference - * @property {function(): Object} findBidByAdId - find bid received by adId. This function will be called by $$PREBID_GLOBAL$$.renderAd - * @property {function(): Object} getStandardBidderAdServerTargeting - returns standard bidder targeting for all the adapters. Refer http://prebid.org/dev-docs/publisher-api-reference.html#module_pbjs.bidderSettings for more details - */ - -import { uniques, flatten, logWarn } from './utils.js'; -import { newAuction, getStandardBidderSettings, AUCTION_COMPLETED } from './auction.js'; -import find from 'core-js-pure/features/array/find.js'; - -const CONSTANTS = require('./constants.json'); - -/** - * Creates new instance of auctionManager. There will only be one instance of auctionManager but - * a factory is created to assist in testing. - * - * @returns {AuctionManager} auctionManagerInstance - */ -export function newAuctionManager() { - const _auctions = []; - const auctionManager = {}; - - auctionManager.addWinningBid = function(bid) { - const auction = find(_auctions, auction => auction.getAuctionId() === bid.auctionId); - if (auction) { - bid.status = CONSTANTS.BID_STATUS.RENDERED; - auction.addWinningBid(bid); - } else { - logWarn(`Auction not found when adding winning bid`); - } - }; - - auctionManager.getAllWinningBids = function() { - return _auctions.map(auction => auction.getWinningBids()) - .reduce(flatten, []); - }; - - auctionManager.getBidsRequested = function() { - return _auctions.map(auction => auction.getBidRequests()) - .reduce(flatten, []); - }; - - auctionManager.getNoBids = function() { - return _auctions.map(auction => auction.getNoBids()) - .reduce(flatten, []); - }; - - auctionManager.getBidsReceived = function() { - return _auctions.map((auction) => { - if (auction.getAuctionStatus() === AUCTION_COMPLETED) { - return auction.getBidsReceived(); - } - }).reduce(flatten, []) - .filter(bid => bid); - }; - - auctionManager.getAllBidsForAdUnitCode = function(adUnitCode) { - return _auctions.map((auction) => { - return auction.getBidsReceived(); - }).reduce(flatten, []) - .filter(bid => bid && bid.adUnitCode === adUnitCode) - }; - - auctionManager.getAdUnits = function() { - return _auctions.map(auction => auction.getAdUnits()) - .reduce(flatten, []); - }; - - auctionManager.getAdUnitCodes = function() { - return _auctions.map(auction => auction.getAdUnitCodes()) - .reduce(flatten, []) - .filter(uniques); - }; - - auctionManager.createAuction = function({ adUnits, adUnitCodes, callback, cbTimeout, labels, auctionId }) { - const auction = newAuction({ adUnits, adUnitCodes, callback, cbTimeout, labels, auctionId }); - _addAuction(auction); - return auction; - }; - - auctionManager.findBidByAdId = function(adId) { - return find(_auctions.map(auction => auction.getBidsReceived()).reduce(flatten, []), bid => bid.adId === adId); - }; - - auctionManager.getStandardBidderAdServerTargeting = function() { - return getStandardBidderSettings()[CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING]; - }; - - auctionManager.setStatusForBids = function(adId, status) { - let bid = auctionManager.findBidByAdId(adId); - if (bid) bid.status = status; - - if (bid && status === CONSTANTS.BID_STATUS.BID_TARGETING_SET) { - const auction = find(_auctions, auction => auction.getAuctionId() === bid.auctionId); - if (auction) auction.setBidTargeting(bid); - } - } - - auctionManager.getLastAuctionId = function() { - return _auctions.length && _auctions[_auctions.length - 1].getAuctionId() - }; - - function _addAuction(auction) { - _auctions.push(auction); - } - - return auctionManager; -} - -export const auctionManager = newAuctionManager(); diff --git a/src/bidfactory.js b/src/bidfactory.js deleted file mode 100644 index 8701184c799..00000000000 --- a/src/bidfactory.js +++ /dev/null @@ -1,56 +0,0 @@ -var utils = require('./utils.js'); - -/** - Required paramaters - bidderCode, - height, - width, - statusCode - Optional paramaters - adId, - cpm, - ad, - adUrl, - dealId, - priceKeyString; - */ -function Bid(statusCode, bidRequest) { - var _bidSrc = (bidRequest && bidRequest.src) || 'client'; - var _statusCode = statusCode || 0; - - this.bidderCode = (bidRequest && bidRequest.bidder) || ''; - this.width = 0; - this.height = 0; - this.statusMessage = _getStatus(); - this.adId = utils.getUniqueIdentifierStr(); - this.requestId = bidRequest && bidRequest.bidId; - this.mediaType = 'banner'; - this.source = _bidSrc; - - function _getStatus() { - switch (_statusCode) { - case 0: - return 'Pending'; - case 1: - return 'Bid available'; - case 2: - return 'Bid returned empty or error response'; - case 3: - return 'Bid timed out'; - } - } - - this.getStatusCode = function () { - return _statusCode; - }; - - // returns the size of the bid creative. Concatenation of width and height by ‘x’. - this.getSize = function () { - return this.width + 'x' + this.height; - }; -} - -// Bid factory function. -export function createBid(statusCode, bidRequest) { - return new Bid(statusCode, bidRequest); -} diff --git a/src/config.js b/src/config.js deleted file mode 100644 index 7cb1a81955d..00000000000 --- a/src/config.js +++ /dev/null @@ -1,640 +0,0 @@ -/* - * Module for getting and setting Prebid configuration. - */ - -/** - * @typedef {Object} MediaTypePriceGranularity - * - * @property {(string|Object)} [banner] - * @property {(string|Object)} [native] - * @property {(string|Object)} [video] - * @property {(string|Object)} [video-instream] - * @property {(string|Object)} [video-outstream] - */ - -import { isValidPriceConfig } from './cpmBucketManager.js'; -import find from 'core-js-pure/features/array/find.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import Set from 'core-js-pure/features/set'; -import { mergeDeep } from './utils.js'; - -const from = require('core-js-pure/features/array/from.js'); -const utils = require('./utils.js'); -const CONSTANTS = require('./constants.json'); - -const DEFAULT_DEBUG = utils.getParameterByName(CONSTANTS.DEBUG_MODE).toUpperCase() === 'TRUE'; -const DEFAULT_BIDDER_TIMEOUT = 3000; -const DEFAULT_PUBLISHER_DOMAIN = window.location.origin; -const DEFAULT_ENABLE_SEND_ALL_BIDS = true; -const DEFAULT_DISABLE_AJAX_TIMEOUT = false; -const DEFAULT_BID_CACHE = false; -const DEFAULT_DEVICE_ACCESS = true; -const DEFAULT_MAX_NESTED_IFRAMES = 10; - -const DEFAULT_TIMEOUTBUFFER = 400; - -export const RANDOM = 'random'; -const FIXED = 'fixed'; - -const VALID_ORDERS = {}; -VALID_ORDERS[RANDOM] = true; -VALID_ORDERS[FIXED] = true; - -const DEFAULT_BIDDER_SEQUENCE = RANDOM; - -const GRANULARITY_OPTIONS = { - LOW: 'low', - MEDIUM: 'medium', - HIGH: 'high', - AUTO: 'auto', - DENSE: 'dense', - CUSTOM: 'custom' -}; - -const ALL_TOPICS = '*'; - -/** - * @typedef {object} PrebidConfig - * - * @property {string} cache.url Set a url if we should use prebid-cache to store video bids before adding - * bids to the auction. **NOTE** This must be set if you want to use the dfpAdServerVideo module. - */ - -export function newConfig() { - let listeners = []; - let defaults; - let config; - let bidderConfig; - let currBidder = null; - - function resetConfig() { - defaults = {}; - let newConfig = { - // `debug` is equivalent to legacy `pbjs.logging` property - _debug: DEFAULT_DEBUG, - get debug() { - return this._debug; - }, - set debug(val) { - this._debug = val; - }, - - // default timeout for all bids - _bidderTimeout: DEFAULT_BIDDER_TIMEOUT, - get bidderTimeout() { - return this._bidderTimeout; - }, - set bidderTimeout(val) { - this._bidderTimeout = val; - }, - - // domain where prebid is running for cross domain iframe communication - _publisherDomain: DEFAULT_PUBLISHER_DOMAIN, - get publisherDomain() { - return this._publisherDomain; - }, - set publisherDomain(val) { - this._publisherDomain = val; - }, - - // calls existing function which may be moved after deprecation - _priceGranularity: GRANULARITY_OPTIONS.MEDIUM, - set priceGranularity(val) { - if (validatePriceGranularity(val)) { - if (typeof val === 'string') { - this._priceGranularity = (hasGranularity(val)) ? val : GRANULARITY_OPTIONS.MEDIUM; - } else if (utils.isPlainObject(val)) { - this._customPriceBucket = val; - this._priceGranularity = GRANULARITY_OPTIONS.CUSTOM; - utils.logMessage('Using custom price granularity'); - } - } - }, - get priceGranularity() { - return this._priceGranularity; - }, - - _customPriceBucket: {}, - get customPriceBucket() { - return this._customPriceBucket; - }, - - /** - * mediaTypePriceGranularity - * @type {MediaTypePriceGranularity} - */ - _mediaTypePriceGranularity: {}, - - get mediaTypePriceGranularity() { - return this._mediaTypePriceGranularity; - }, - set mediaTypePriceGranularity(val) { - this._mediaTypePriceGranularity = Object.keys(val).reduce((aggregate, item) => { - if (validatePriceGranularity(val[item])) { - if (typeof val === 'string') { - aggregate[item] = (hasGranularity(val[item])) ? val[item] : this._priceGranularity; - } else if (utils.isPlainObject(val)) { - aggregate[item] = val[item]; - utils.logMessage(`Using custom price granularity for ${item}`); - } - } else { - utils.logWarn(`Invalid price granularity for media type: ${item}`); - } - return aggregate; - }, {}); - }, - - _sendAllBids: DEFAULT_ENABLE_SEND_ALL_BIDS, - get enableSendAllBids() { - return this._sendAllBids; - }, - set enableSendAllBids(val) { - this._sendAllBids = val; - }, - - _useBidCache: DEFAULT_BID_CACHE, - get useBidCache() { - return this._useBidCache; - }, - set useBidCache(val) { - this._useBidCache = val; - }, - - /** - * deviceAccess set to false will disable setCookie, getCookie, hasLocalStorage - * @type {boolean} - */ - _deviceAccess: DEFAULT_DEVICE_ACCESS, - get deviceAccess() { - return this._deviceAccess; - }, - set deviceAccess(val) { - this._deviceAccess = val; - }, - - _bidderSequence: DEFAULT_BIDDER_SEQUENCE, - get bidderSequence() { - return this._bidderSequence; - }, - set bidderSequence(val) { - if (VALID_ORDERS[val]) { - this._bidderSequence = val; - } else { - utils.logWarn(`Invalid order: ${val}. Bidder Sequence was not set.`); - } - }, - - // timeout buffer to adjust for bidder CDN latency - _timeoutBuffer: DEFAULT_TIMEOUTBUFFER, - get timeoutBuffer() { - return this._timeoutBuffer; - }, - set timeoutBuffer(val) { - this._timeoutBuffer = val; - }, - - _disableAjaxTimeout: DEFAULT_DISABLE_AJAX_TIMEOUT, - get disableAjaxTimeout() { - return this._disableAjaxTimeout; - }, - set disableAjaxTimeout(val) { - this._disableAjaxTimeout = val; - }, - - // default max nested iframes for referer detection - _maxNestedIframes: DEFAULT_MAX_NESTED_IFRAMES, - get maxNestedIframes() { - return this._maxNestedIframes; - }, - set maxNestedIframes(val) { - this._maxNestedIframes = val; - }, - - _auctionOptions: {}, - get auctionOptions() { - return this._auctionOptions; - }, - set auctionOptions(val) { - if (validateauctionOptions(val)) { - this._auctionOptions = val; - } - }, - }; - - if (config) { - callSubscribers( - Object.keys(config).reduce((memo, topic) => { - if (config[topic] !== newConfig[topic]) { - memo[topic] = newConfig[topic] || {}; - } - return memo; - }, - {}) - ); - } - - config = newConfig; - bidderConfig = {}; - - function hasGranularity(val) { - return find(Object.keys(GRANULARITY_OPTIONS), option => val === GRANULARITY_OPTIONS[option]); - } - - function validatePriceGranularity(val) { - if (!val) { - utils.logError('Prebid Error: no value passed to `setPriceGranularity()`'); - return false; - } - if (typeof val === 'string') { - if (!hasGranularity(val)) { - utils.logWarn('Prebid Warning: setPriceGranularity was called with invalid setting, using `medium` as default.'); - } - } else if (utils.isPlainObject(val)) { - if (!isValidPriceConfig(val)) { - utils.logError('Invalid custom price value passed to `setPriceGranularity()`'); - return false; - } - } - return true; - } - - function validateauctionOptions(val) { - if (!utils.isPlainObject(val)) { - utils.logWarn('Auction Options must be an object') - return false - } - - for (let k of Object.keys(val)) { - if (k !== 'secondaryBidders') { - utils.logWarn(`Auction Options given an incorrect param: ${k}`) - return false - } - if (k === 'secondaryBidders') { - if (!utils.isArray(val[k])) { - utils.logWarn(`Auction Options ${k} must be of type Array`); - return false - } else if (!val[k].every(utils.isStr)) { - utils.logWarn(`Auction Options ${k} must be only string`); - return false - } - } - } - return true; - } - } - - /** - * Returns base config with bidder overrides (if there is currently a bidder) - * @private - */ - function _getConfig() { - if (currBidder && bidderConfig && utils.isPlainObject(bidderConfig[currBidder])) { - let currBidderConfig = bidderConfig[currBidder]; - const configTopicSet = new Set(Object.keys(config).concat(Object.keys(currBidderConfig))); - - return from(configTopicSet).reduce((memo, topic) => { - if (typeof currBidderConfig[topic] === 'undefined') { - memo[topic] = config[topic]; - } else if (typeof config[topic] === 'undefined') { - memo[topic] = currBidderConfig[topic]; - } else { - if (utils.isPlainObject(currBidderConfig[topic])) { - memo[topic] = mergeDeep({}, config[topic], currBidderConfig[topic]); - } else { - memo[topic] = currBidderConfig[topic]; - } - } - return memo; - }, {}); - } - return Object.assign({}, config); - } - - /* - * Returns configuration object if called without parameters, - * or single configuration property if given a string matching a configuration - * property name. Allows deep access e.g. getConfig('currency.adServerCurrency') - * - * If called with callback parameter, or a string and a callback parameter, - * subscribes to configuration updates. See `subscribe` function for usage. - */ - function getConfig(...args) { - if (args.length <= 1 && typeof args[0] !== 'function') { - const option = args[0]; - return option ? utils.deepAccess(_getConfig(), option) : _getConfig(); - } - - return subscribe(...args); - } - - /** - * Internal API for modules (such as prebid-server) that might need access to all bidder config - */ - function getBidderConfig() { - return bidderConfig; - } - - /** - * Returns backwards compatible FPD data for modules - */ - function getLegacyFpd(obj) { - if (typeof obj !== 'object') return; - - let duplicate = {}; - - Object.keys(obj).forEach((type) => { - let prop = (type === 'site') ? 'context' : type; - duplicate[prop] = (prop === 'context' || prop === 'user') ? Object.keys(obj[type]).filter(key => key !== 'data').reduce((result, key) => { - if (key === 'ext') { - utils.mergeDeep(result, obj[type][key]); - } else { - utils.mergeDeep(result, {[key]: obj[type][key]}); - } - - return result; - }, {}) : obj[type]; - }); - - return duplicate; - } - - /** - * Returns backwards compatible FPD data for modules - */ - function getLegacyImpFpd(obj) { - if (typeof obj !== 'object') return; - - let duplicate = {}; - - if (utils.deepAccess(obj, 'ext.data')) { - Object.keys(obj.ext.data).forEach((key) => { - if (key === 'pbadslot') { - utils.mergeDeep(duplicate, {context: {pbAdSlot: obj.ext.data[key]}}); - } else if (key === 'adserver') { - utils.mergeDeep(duplicate, {context: {adServer: obj.ext.data[key]}}); - } else { - utils.mergeDeep(duplicate, {context: {data: {[key]: obj.ext.data[key]}}}); - } - }); - } - - return duplicate; - } - - /** - * Copy FPD over to OpenRTB standard format in config - */ - function convertFpd(opt) { - let duplicate = {}; - - Object.keys(opt).forEach((type) => { - let prop = (type === 'context') ? 'site' : type; - duplicate[prop] = (prop === 'site' || prop === 'user') ? Object.keys(opt[type]).reduce((result, key) => { - if (key === 'data') { - utils.mergeDeep(result, {ext: {data: opt[type][key]}}); - } else { - utils.mergeDeep(result, {[key]: opt[type][key]}); - } - - return result; - }, {}) : opt[type]; - }); - - return duplicate; - } - - /** - * Copy Impression FPD over to OpenRTB standard format in config - * Only accepts bid level context.data values with pbAdSlot and adServer exceptions - */ - function convertImpFpd(opt) { - let duplicate = {}; - - Object.keys(opt).filter(prop => prop === 'context').forEach((type) => { - Object.keys(opt[type]).forEach((key) => { - if (key === 'data') { - utils.mergeDeep(duplicate, {ext: {data: opt[type][key]}}); - } else { - if (typeof opt[type][key] === 'object' && !Array.isArray(opt[type][key])) { - Object.keys(opt[type][key]).forEach(data => { - utils.mergeDeep(duplicate, {ext: {data: {[key.toLowerCase()]: {[data.toLowerCase()]: opt[type][key][data]}}}}); - }); - } else { - utils.mergeDeep(duplicate, {ext: {data: {[key.toLowerCase()]: opt[type][key]}}}); - } - } - }); - }); - - return duplicate; - } - - /** - * Copy FPD over to OpenRTB standard format in each adunit - */ - function convertAdUnitFpd(arr) { - let convert = []; - - arr.forEach((adunit) => { - if (adunit.fpd) { - (adunit['ortb2Imp']) ? utils.mergeDeep(adunit['ortb2Imp'], convertImpFpd(adunit.fpd)) : adunit['ortb2Imp'] = convertImpFpd(adunit.fpd); - convert.push((({ fpd, ...duplicate }) => duplicate)(adunit)); - } else { - convert.push(adunit); - } - }); - - return convert; - } - - /* - * Sets configuration given an object containing key-value pairs and calls - * listeners that were added by the `subscribe` function - */ - function setConfig(options) { - if (!utils.isPlainObject(options)) { - utils.logError('setConfig options must be an object'); - return; - } - - let topics = Object.keys(options); - let topicalConfig = {}; - - topics.forEach(topic => { - let prop = (topic === 'fpd') ? 'ortb2' : topic; - let option = (topic === 'fpd') ? convertFpd(options[topic]) : options[topic]; - - if (utils.isPlainObject(defaults[prop]) && utils.isPlainObject(option)) { - option = Object.assign({}, defaults[prop], option); - } - - topicalConfig[prop] = config[prop] = option; - }); - - callSubscribers(topicalConfig); - } - - /** - * Sets configuration defaults which setConfig values can be applied on top of - * @param {object} options - */ - function setDefaults(options) { - if (!utils.isPlainObject(defaults)) { - utils.logError('defaults must be an object'); - return; - } - - Object.assign(defaults, options); - // Add default values to config as well - Object.assign(config, options); - } - - /* - * Adds a function to a set of listeners that are invoked whenever `setConfig` - * is called. The subscribed function will be passed the options object that - * was used in the `setConfig` call. Topics can be subscribed to to only get - * updates when specific properties are updated by passing a topic string as - * the first parameter. - * - * Returns an `unsubscribe` function for removing the subscriber from the - * set of listeners - * - * Example use: - * // subscribe to all configuration changes - * subscribe((config) => console.log('config set:', config)); - * - * // subscribe to only 'logging' changes - * subscribe('logging', (config) => console.log('logging set:', config)); - * - * // unsubscribe - * const unsubscribe = subscribe(...); - * unsubscribe(); // no longer listening - */ - function subscribe(topic, listener) { - let callback = listener; - - if (typeof topic !== 'string') { - // first param should be callback function in this case, - // meaning it gets called for any config change - callback = topic; - topic = ALL_TOPICS; - } - - if (typeof callback !== 'function') { - utils.logError('listener must be a function'); - return; - } - - const nl = { topic, callback }; - listeners.push(nl); - - // save and call this function to remove the listener - return function unsubscribe() { - listeners.splice(listeners.indexOf(nl), 1); - }; - } - - /* - * Calls listeners that were added by the `subscribe` function - */ - function callSubscribers(options) { - const TOPICS = Object.keys(options); - - // call subscribers of a specific topic, passing only that configuration - listeners - .filter(listener => includes(TOPICS, listener.topic)) - .forEach(listener => { - listener.callback({ [listener.topic]: options[listener.topic] }); - }); - - // call subscribers that didn't give a topic, passing everything that was set - listeners - .filter(listener => listener.topic === ALL_TOPICS) - .forEach(listener => listener.callback(options)); - } - - function setBidderConfig(config) { - try { - check(config); - config.bidders.forEach(bidder => { - if (!bidderConfig[bidder]) { - bidderConfig[bidder] = {}; - } - Object.keys(config.config).forEach(topic => { - let prop = (topic === 'fpd') ? 'ortb2' : topic; - let option = (topic === 'fpd') ? convertFpd(config.config[topic]) : config.config[topic]; - - if (utils.isPlainObject(option)) { - bidderConfig[bidder][prop] = Object.assign({}, bidderConfig[bidder][prop] || {}, option); - } else { - bidderConfig[bidder][prop] = option; - } - }); - }); - } catch (e) { - utils.logError(e); - } - function check(obj) { - if (!utils.isPlainObject(obj)) { - throw 'setBidderConfig bidder options must be an object'; - } - if (!(Array.isArray(obj.bidders) && obj.bidders.length)) { - throw 'setBidderConfig bidder options must contain a bidders list with at least 1 bidder'; - } - if (!utils.isPlainObject(obj.config)) { - throw 'setBidderConfig bidder options must contain a config object'; - } - } - } - - /** - * Internal functions for core to execute some synchronous code while having an active bidder set. - */ - function runWithBidder(bidder, fn) { - currBidder = bidder; - try { - return fn(); - } finally { - resetBidder(); - } - } - function callbackWithBidder(bidder) { - return function(cb) { - return function(...args) { - if (typeof cb === 'function') { - return runWithBidder(bidder, utils.bind.call(cb, this, ...args)) - } else { - utils.logWarn('config.callbackWithBidder callback is not a function'); - } - } - } - } - - function getCurrentBidder() { - return currBidder; - } - - function resetBidder() { - currBidder = null; - } - - resetConfig(); - - return { - getCurrentBidder, - resetBidder, - getConfig, - setConfig, - setDefaults, - resetConfig, - runWithBidder, - callbackWithBidder, - setBidderConfig, - getBidderConfig, - convertAdUnitFpd, - getLegacyFpd, - getLegacyImpFpd - }; -} - -export const config = newConfig(); diff --git a/src/constants.json b/src/constants.json deleted file mode 100644 index e6b9687f911..00000000000 --- a/src/constants.json +++ /dev/null @@ -1,119 +0,0 @@ -{ - "JSON_MAPPING": { - "PL_CODE": "code", - "PL_SIZE": "sizes", - "PL_BIDS": "bids", - "BD_BIDDER": "bidder", - "BD_ID": "paramsd", - "BD_PL_ID": "placementId", - "ADSERVER_TARGETING": "adserverTargeting", - "BD_SETTING_STANDARD": "standard" - }, - "DEBUG_MODE": "pbjs_debug", - "STATUS": { - "GOOD": 1, - "NO_BID": 2 - }, - "CB": { - "TYPE": { - "ALL_BIDS_BACK": "allRequestedBidsBack", - "AD_UNIT_BIDS_BACK": "adUnitBidsBack", - "BID_WON": "bidWon", - "REQUEST_BIDS": "requestBids" - } - }, - "EVENTS": { - "AUCTION_INIT": "auctionInit", - "AUCTION_END": "auctionEnd", - "BID_ADJUSTMENT": "bidAdjustment", - "BID_TIMEOUT": "bidTimeout", - "BID_REQUESTED": "bidRequested", - "BID_RESPONSE": "bidResponse", - "NO_BID": "noBid", - "BID_WON": "bidWon", - "BIDDER_DONE": "bidderDone", - "SET_TARGETING": "setTargeting", - "BEFORE_REQUEST_BIDS": "beforeRequestBids", - "REQUEST_BIDS": "requestBids", - "ADD_AD_UNITS": "addAdUnits", - "AD_RENDER_FAILED": "adRenderFailed", - "TCF2_ENFORCEMENT": "tcf2Enforcement", - "AUCTION_DEBUG": "auctionDebug", - "BID_VIEWABLE": "bidViewable" - }, - "AD_RENDER_FAILED_REASON" : { - "PREVENT_WRITING_ON_MAIN_DOCUMENT": "preventWritingOnMainDocument", - "NO_AD": "noAd", - "EXCEPTION": "exception", - "CANNOT_FIND_AD": "cannotFindAd", - "MISSING_DOC_OR_ADID": "missingDocOrAdid" - }, - "EVENT_ID_PATHS": { - "bidWon": "adUnitCode" - }, - "GRANULARITY_OPTIONS": { - "LOW": "low", - "MEDIUM": "medium", - "HIGH": "high", - "AUTO": "auto", - "DENSE": "dense", - "CUSTOM": "custom" - }, - "TARGETING_KEYS": { - "BIDDER": "hb_bidder", - "AD_ID": "hb_adid", - "PRICE_BUCKET": "hb_pb", - "SIZE": "hb_size", - "DEAL": "hb_deal", - "SOURCE": "hb_source", - "FORMAT": "hb_format", - "UUID": "hb_uuid", - "CACHE_ID": "hb_cache_id", - "CACHE_HOST": "hb_cache_host", - "ADOMAIN" : "hb_adomain" - }, - "DEFAULT_TARGETING_KEYS": { - "BIDDER": "hb_bidder", - "AD_ID": "hb_adid", - "PRICE_BUCKET": "hb_pb", - "SIZE": "hb_size", - "DEAL": "hb_deal", - "SOURCE": "hb_source", - "FORMAT": "hb_format", - "UUID": "hb_uuid", - "CACHE_ID": "hb_cache_id", - "CACHE_HOST": "hb_cache_host" - }, - "NATIVE_KEYS": { - "title": "hb_native_title", - "body": "hb_native_body", - "body2": "hb_native_body2", - "privacyLink": "hb_native_privacy", - "privacyIcon": "hb_native_privicon", - "sponsoredBy": "hb_native_brand", - "image": "hb_native_image", - "icon": "hb_native_icon", - "clickUrl": "hb_native_linkurl", - "displayUrl": "hb_native_displayurl", - "cta": "hb_native_cta", - "rating": "hb_native_rating", - "address": "hb_native_address", - "downloads": "hb_native_downloads", - "likes": "hb_native_likes", - "phone": "hb_native_phone", - "price": "hb_native_price", - "salePrice": "hb_native_saleprice", - "rendererUrl": "hb_renderer_url", - "adTemplate": "hb_adTemplate" - }, - "S2S" : { - "SRC" : "s2s", - "DEFAULT_ENDPOINT" : "https://prebid.adnxs.com/pbs/v1/openrtb2/auction", - "SYNCED_BIDDERS_KEY": "pbjsSyncs" - }, - "BID_STATUS" : { - "BID_TARGETING_SET": "targetingSet", - "RENDERED": "rendered", - "BID_REJECTED": "bidRejected" - } -} diff --git a/src/cpmBucketManager.js b/src/cpmBucketManager.js deleted file mode 100644 index a6b76cc38e2..00000000000 --- a/src/cpmBucketManager.js +++ /dev/null @@ -1,136 +0,0 @@ -import find from 'core-js-pure/features/array/find.js'; -const utils = require('./utils.js'); - -const _defaultPrecision = 2; -const _lgPriceConfig = { - 'buckets': [{ - 'max': 5, - 'increment': 0.5 - }] -}; -const _mgPriceConfig = { - 'buckets': [{ - 'max': 20, - 'increment': 0.1 - }] -}; -const _hgPriceConfig = { - 'buckets': [{ - 'max': 20, - 'increment': 0.01 - }] -}; -const _densePriceConfig = { - 'buckets': [{ - 'max': 3, - 'increment': 0.01 - }, - { - 'max': 8, - 'increment': 0.05 - }, - { - 'max': 20, - 'increment': 0.5 - }] -}; -const _autoPriceConfig = { - 'buckets': [{ - 'max': 5, - 'increment': 0.05 - }, - { - 'max': 10, - 'increment': 0.1 - }, - { - 'max': 20, - 'increment': 0.5 - }] -}; - -function getPriceBucketString(cpm, customConfig, granularityMultiplier = 1) { - let cpmFloat = parseFloat(cpm); - if (isNaN(cpmFloat)) { - cpmFloat = ''; - } - - return { - low: (cpmFloat === '') ? '' : getCpmStringValue(cpm, _lgPriceConfig, granularityMultiplier), - med: (cpmFloat === '') ? '' : getCpmStringValue(cpm, _mgPriceConfig, granularityMultiplier), - high: (cpmFloat === '') ? '' : getCpmStringValue(cpm, _hgPriceConfig, granularityMultiplier), - auto: (cpmFloat === '') ? '' : getCpmStringValue(cpm, _autoPriceConfig, granularityMultiplier), - dense: (cpmFloat === '') ? '' : getCpmStringValue(cpm, _densePriceConfig, granularityMultiplier), - custom: (cpmFloat === '') ? '' : getCpmStringValue(cpm, customConfig, granularityMultiplier) - }; -} - -function getCpmStringValue(cpm, config, granularityMultiplier) { - let cpmStr = ''; - if (!isValidPriceConfig(config)) { - return cpmStr; - } - const cap = config.buckets.reduce((prev, curr) => { - if (prev.max > curr.max) { - return prev; - } - return curr; - }, { - 'max': 0, - }); - - let bucketFloor = 0; - let bucket = find(config.buckets, bucket => { - if (cpm > cap.max * granularityMultiplier) { - // cpm exceeds cap, just return the cap. - let precision = bucket.precision; - if (typeof precision === 'undefined') { - precision = _defaultPrecision; - } - cpmStr = (bucket.max * granularityMultiplier).toFixed(precision); - } else if (cpm <= bucket.max * granularityMultiplier && cpm >= bucketFloor * granularityMultiplier) { - bucket.min = bucketFloor; - return bucket; - } else { - bucketFloor = bucket.max; - } - }); - if (bucket) { - cpmStr = getCpmTarget(cpm, bucket, granularityMultiplier); - } - return cpmStr; -} - -function isValidPriceConfig(config) { - if (utils.isEmpty(config) || !config.buckets || !Array.isArray(config.buckets)) { - return false; - } - let isValid = true; - config.buckets.forEach(bucket => { - if (!bucket.max || !bucket.increment) { - isValid = false; - } - }); - return isValid; -} - -function getCpmTarget(cpm, bucket, granularityMultiplier) { - const precision = typeof bucket.precision !== 'undefined' ? bucket.precision : _defaultPrecision; - const increment = bucket.increment * granularityMultiplier; - const bucketMin = bucket.min * granularityMultiplier; - - // start increments at the bucket min and then add bucket min back to arrive at the correct rounding - // note - we're padding the values to avoid using decimals in the math prior to flooring - // this is done as JS can return values slightly below the expected mark which would skew the price bucket target - // (eg 4.01 / 0.01 = 400.99999999999994) - // min precison should be 2 to move decimal place over. - let pow = Math.pow(10, precision + 2); - let cpmToFloor = ((cpm * pow) - (bucketMin * pow)) / (increment * pow); - let cpmTarget = ((Math.floor(cpmToFloor)) * increment) + bucketMin; - // force to 10 decimal places to deal with imprecise decimal/binary conversions - // (for example 0.1 * 3 = 0.30000000000000004) - cpmTarget = Number(cpmTarget.toFixed(10)); - return cpmTarget.toFixed(precision); -} - -export { getPriceBucketString, isValidPriceConfig }; diff --git a/src/debugging.js b/src/debugging.js deleted file mode 100644 index dc479f74674..00000000000 --- a/src/debugging.js +++ /dev/null @@ -1,153 +0,0 @@ - -import { config } from './config.js'; -import { logMessage as utilsLogMessage, logWarn as utilsLogWarn } from './utils.js'; -import { addBidderRequests, addBidResponse } from './auction.js'; - -const OVERRIDE_KEY = '$$PREBID_GLOBAL$$:debugging'; - -export let addBidResponseBound; -export let addBidderRequestsBound; - -function logMessage(msg) { - utilsLogMessage('DEBUG: ' + msg); -} - -function logWarn(msg) { - utilsLogWarn('DEBUG: ' + msg); -} - -function addHooks(overrides) { - addBidResponseBound = addBidResponseHook.bind(overrides); - addBidResponse.before(addBidResponseBound, 5); - - addBidderRequestsBound = addBidderRequestsHook.bind(overrides); - addBidderRequests.before(addBidderRequestsBound, 5); -} - -function removeHooks() { - addBidResponse.getHooks({hook: addBidResponseBound}).remove(); - addBidderRequests.getHooks({hook: addBidderRequestsBound}).remove(); -} - -export function enableOverrides(overrides, fromSession = false) { - config.setConfig({'debug': true}); - removeHooks(); - addHooks(overrides); - logMessage(`bidder overrides enabled${fromSession ? ' from session' : ''}`); -} - -export function disableOverrides() { - removeHooks(); - logMessage('bidder overrides disabled'); -} - -/** - * @param {{bidder:string, adUnitCode:string}} overrideObj - * @param {string} bidderCode - * @param {string} adUnitCode - * @returns {boolean} - */ -export function bidExcluded(overrideObj, bidderCode, adUnitCode) { - if (overrideObj.bidder && overrideObj.bidder !== bidderCode) { - return true; - } - if (overrideObj.adUnitCode && overrideObj.adUnitCode !== adUnitCode) { - return true; - } - return false; -} - -/** - * @param {string[]} bidders - * @param {string} bidderCode - * @returns {boolean} - */ -export function bidderExcluded(bidders, bidderCode) { - return (Array.isArray(bidders) && bidders.indexOf(bidderCode) === -1); -} - -/** - * @param {Object} overrideObj - * @param {Object} bidObj - * @param {Object} bidType - * @returns {Object} bidObj with overridden properties - */ -export function applyBidOverrides(overrideObj, bidObj, bidType) { - return Object.keys(overrideObj).filter(key => (['adUnitCode', 'bidder'].indexOf(key) === -1)).reduce(function(result, key) { - logMessage(`bidder overrides changed '${result.adUnitCode}/${result.bidderCode}' ${bidType}.${key} from '${result[key]}.js' to '${overrideObj[key]}'`); - result[key] = overrideObj[key]; - return result; - }, bidObj); -} - -export function addBidResponseHook(next, adUnitCode, bid) { - const overrides = this; - - if (bidderExcluded(overrides.bidders, bid.bidderCode)) { - logWarn(`bidder '${bid.bidderCode}' excluded from auction by bidder overrides`); - return; - } - - if (Array.isArray(overrides.bids)) { - overrides.bids.forEach(function(overrideBid) { - if (!bidExcluded(overrideBid, bid.bidderCode, adUnitCode)) { - applyBidOverrides(overrideBid, bid, 'bidder'); - } - }); - } - - next(adUnitCode, bid); -} - -export function addBidderRequestsHook(next, bidderRequests) { - const overrides = this; - - const includedBidderRequests = bidderRequests.filter(function(bidderRequest) { - if (bidderExcluded(overrides.bidders, bidderRequest.bidderCode)) { - logWarn(`bidRequest '${bidderRequest.bidderCode}' excluded from auction by bidder overrides`); - return false; - } - return true; - }); - - if (Array.isArray(overrides.bidRequests)) { - includedBidderRequests.forEach(function(bidderRequest) { - overrides.bidRequests.forEach(function(overrideBid) { - bidderRequest.bids.forEach(function(bid) { - if (!bidExcluded(overrideBid, bidderRequest.bidderCode, bid.adUnitCode)) { - applyBidOverrides(overrideBid, bid, 'bidRequest'); - } - }); - }); - }); - } - - next(includedBidderRequests); -} - -export function getConfig(debugging) { - if (!debugging.enabled) { - disableOverrides(); - try { - window.sessionStorage.removeItem(OVERRIDE_KEY); - } catch (e) {} - } else { - try { - window.sessionStorage.setItem(OVERRIDE_KEY, JSON.stringify(debugging)); - } catch (e) {} - enableOverrides(debugging); - } -} -config.getConfig('debugging', ({debugging}) => getConfig(debugging)); - -export function sessionLoader(storage) { - let overrides; - try { - storage = storage || window.sessionStorage; - overrides = JSON.parse(storage.getItem(OVERRIDE_KEY)); - } catch (e) { - } - if (overrides) { - enableOverrides(overrides, true); - } -} diff --git a/src/events.js b/src/events.js deleted file mode 100644 index 8749ddf206b..00000000000 --- a/src/events.js +++ /dev/null @@ -1,151 +0,0 @@ -/** - * events.js - */ -var utils = require('./utils.js'); -var CONSTANTS = require('./constants.json'); -var slice = Array.prototype.slice; -var push = Array.prototype.push; - -// define entire events -// var allEvents = ['bidRequested','bidResponse','bidWon','bidTimeout']; -var allEvents = utils._map(CONSTANTS.EVENTS, function (v) { - return v; -}); - -var idPaths = CONSTANTS.EVENT_ID_PATHS; - -// keep a record of all events fired -var eventsFired = []; - -module.exports = (function () { - var _handlers = {}; - var _public = {}; - - /** - * - * @param {String} eventString The name of the event. - * @param {Array} args The payload emitted with the event. - * @private - */ - function _dispatch(eventString, args) { - utils.logMessage('Emitting event for: ' + eventString); - - var eventPayload = args[0] || {}; - var idPath = idPaths[eventString]; - var key = eventPayload[idPath]; - var event = _handlers[eventString] || { que: [] }; - var eventKeys = utils._map(event, function (v, k) { - return k; - }); - - var callbacks = []; - - // record the event: - eventsFired.push({ - eventType: eventString, - args: eventPayload, - id: key, - elapsedTime: utils.getPerformanceNow(), - }); - - /** Push each specific callback to the `callbacks` array. - * If the `event` map has a key that matches the value of the - * event payload id path, e.g. `eventPayload[idPath]`, then apply - * each function in the `que` array as an argument to push to the - * `callbacks` array - * */ - if (key && utils.contains(eventKeys, key)) { - push.apply(callbacks, event[key].que); - } - - /** Push each general callback to the `callbacks` array. */ - push.apply(callbacks, event.que); - - /** call each of the callbacks */ - utils._each(callbacks, function (fn) { - if (!fn) return; - try { - fn.apply(null, args); - } catch (e) { - utils.logError('Error executing handler:', 'events.js', e); - } - }); - } - - function _checkAvailableEvent(event) { - return utils.contains(allEvents, event); - } - - _public.on = function (eventString, handler, id) { - // check whether available event or not - if (_checkAvailableEvent(eventString)) { - var event = _handlers[eventString] || { que: [] }; - - if (id) { - event[id] = event[id] || { que: [] }; - event[id].que.push(handler); - } else { - event.que.push(handler); - } - - _handlers[eventString] = event; - } else { - utils.logError('Wrong event name : ' + eventString + ' Valid event names :' + allEvents); - } - }; - - _public.emit = function (event) { - var args = slice.call(arguments, 1); - _dispatch(event, args); - }; - - _public.off = function (eventString, handler, id) { - var event = _handlers[eventString]; - - if (utils.isEmpty(event) || (utils.isEmpty(event.que) && utils.isEmpty(event[id]))) { - return; - } - - if (id && (utils.isEmpty(event[id]) || utils.isEmpty(event[id].que))) { - return; - } - - if (id) { - utils._each(event[id].que, function (_handler) { - var que = event[id].que; - if (_handler === handler) { - que.splice(que.indexOf(_handler), 1); - } - }); - } else { - utils._each(event.que, function (_handler) { - var que = event.que; - if (_handler === handler) { - que.splice(que.indexOf(_handler), 1); - } - }); - } - - _handlers[eventString] = event; - }; - - _public.get = function () { - return _handlers; - }; - - /** - * This method can return a copy of all the events fired - * @return {Array} array of events fired - */ - _public.getEvents = function () { - var arrayCopy = []; - utils._each(eventsFired, function (value) { - var newProp = Object.assign({}, value); - arrayCopy.push(newProp); - }); - - return arrayCopy; - }; - - return _public; -}()); diff --git a/src/hook.js b/src/hook.js deleted file mode 100644 index 9050bf2f7dc..00000000000 --- a/src/hook.js +++ /dev/null @@ -1,28 +0,0 @@ - -import funHooks from 'fun-hooks/no-eval/index.js'; - -export let hook = funHooks({ - ready: funHooks.SYNC | funHooks.ASYNC | funHooks.QUEUE -}); - -export const getHook = hook.get; - -export function setupBeforeHookFnOnce(baseFn, hookFn, priority = 15) { - let result = baseFn.getHooks({hook: hookFn}); - if (result.length === 0) { - baseFn.before(hookFn, priority); - } -} - -export function module(name, install) { - hook('async', function (submodules) { - submodules.forEach(args => install(...args)); - }, name)([]); // will be queued until hook.ready() called in pbjs.processQueue(); -} - -export function submodule(name, ...args) { - getHook(name).before((next, modules) => { - modules.push(args); - next(modules); - }); -} diff --git a/src/mediaTypes.js b/src/mediaTypes.js deleted file mode 100644 index eea286f7af5..00000000000 --- a/src/mediaTypes.js +++ /dev/null @@ -1,20 +0,0 @@ -/** - * This file contains the valid Media Types in Prebid. - * - * All adapters are assumed to support banner ads. Other media types are specified by Adapters when they - * register themselves with prebid-core. - */ - -/** - * @typedef {('native'|'video'|'banner')} MediaType - * @typedef {('adpod')} VideoContext - */ - -/** @type MediaType */ -export const NATIVE = 'native'; -/** @type MediaType */ -export const VIDEO = 'video'; -/** @type MediaType */ -export const BANNER = 'banner'; -/** @type VideoContext */ -export const ADPOD = 'adpod'; diff --git a/src/native.js b/src/native.js deleted file mode 100644 index 7596b38534d..00000000000 --- a/src/native.js +++ /dev/null @@ -1,275 +0,0 @@ -import { deepAccess, getBidRequest, getKeyByValue, insertHtmlIntoIframe, logError, triggerPixel } from './utils.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -const CONSTANTS = require('./constants.json'); - -export const nativeAdapters = []; - -export const NATIVE_TARGETING_KEYS = Object.keys(CONSTANTS.NATIVE_KEYS).map( - key => CONSTANTS.NATIVE_KEYS[key] -); - -const IMAGE = { - image: { required: true }, - title: { required: true }, - sponsoredBy: { required: true }, - clickUrl: { required: true }, - body: { required: false }, - icon: { required: false }, -}; - -const SUPPORTED_TYPES = { - image: IMAGE -}; - -/** - * Recieves nativeParams from an adUnit. If the params were not of type 'type', - * passes them on directly. If they were of type 'type', translate - * them into the predefined specific asset requests for that type of native ad. - */ -export function processNativeAdUnitParams(params) { - if (params && params.type && typeIsSupported(params.type)) { - return SUPPORTED_TYPES[params.type]; - } - - return params; -} - -/** - * Check if the native type specified in the adUnit is supported by Prebid. - */ -function typeIsSupported(type) { - if (!(type && includes(Object.keys(SUPPORTED_TYPES), type))) { - logError(`${type} nativeParam is not supported`); - return false; - } - - return true; -} - -/** - * Helper functions for working with native-enabled adUnits - * TODO: abstract this and the video helper functions into general - * adunit validation helper functions - */ -export const nativeAdUnit = adUnit => { - const mediaType = adUnit.mediaType === 'native'; - const mediaTypes = deepAccess(adUnit, 'mediaTypes.native'); - return mediaType || mediaTypes; -} -export const nativeBidder = bid => includes(nativeAdapters, bid.bidder); -export const hasNonNativeBidder = adUnit => - adUnit.bids.filter(bid => !nativeBidder(bid)).length; - -/** - * Validate that the native assets on this bid contain all assets that were - * marked as required in the adUnit configuration. - * @param {Bid} bid Native bid to validate - * @param {BidRequest[]} bidRequests All bid requests for an auction - * @return {Boolean} If object is valid - */ -export function nativeBidIsValid(bid, bidRequests) { - const bidRequest = getBidRequest(bid.requestId, bidRequests); - if (!bidRequest) { return false; } - - // all native bid responses must define a landing page url - if (!deepAccess(bid, 'native.clickUrl')) { - return false; - } - - const requestedAssets = bidRequest.nativeParams; - if (!requestedAssets) { - return true; - } - - const requiredAssets = Object.keys(requestedAssets).filter( - key => requestedAssets[key].required - ); - const returnedAssets = Object.keys(bid['native']).filter( - key => bid['native'][key] - ); - - return requiredAssets.every(asset => includes(returnedAssets, asset)); -} - -/* - * Native responses may have associated impression or click trackers. - * This retrieves the appropriate tracker urls for the given ad object and - * fires them. As a native creatives may be in a cross-origin frame, it may be - * necessary to invoke this function via postMessage. secureCreatives is - * configured to fire this function when it receives a `message` of 'Prebid Native' - * and an `adId` with the value of the `bid.adId`. When a message is posted with - * these parameters, impression trackers are fired. To fire click trackers, the - * message should contain an `action` set to 'click'. - * - * // Native creative template example usage - * - * %%PATTERN:hb_native_title%% - * - * - * - */ -export function fireNativeTrackers(message, adObject) { - let trackers; - if (message.action === 'click') { - trackers = adObject['native'] && adObject['native'].clickTrackers; - } else { - trackers = adObject['native'] && adObject['native'].impressionTrackers; - - if (adObject['native'] && adObject['native'].javascriptTrackers) { - insertHtmlIntoIframe(adObject['native'].javascriptTrackers); - } - } - - (trackers || []).forEach(triggerPixel); - return message.action; -} - -/** - * Gets native targeting key-value pairs - * @param {Object} bid - * @return {Object} targeting - */ -export function getNativeTargeting(bid, bidReq) { - let keyValues = {}; - - if (deepAccess(bidReq, 'nativeParams.rendererUrl')) { - bid['native']['rendererUrl'] = getAssetValue(bidReq.nativeParams['rendererUrl']); - } else if (deepAccess(bidReq, 'nativeParams.adTemplate')) { - bid['native']['adTemplate'] = getAssetValue(bidReq.nativeParams['adTemplate']); - } - - const globalSendTargetingKeys = deepAccess( - bidReq, - `nativeParams.sendTargetingKeys` - ) !== false; - - const nativeKeys = getNativeKeys(bidReq); - - const flatBidNativeKeys = { ...bid.native, ...bid.native.ext }; - delete flatBidNativeKeys.ext; - - Object.keys(flatBidNativeKeys).forEach(asset => { - const key = nativeKeys[asset]; - let value = getAssetValue(bid.native[asset]) || getAssetValue(deepAccess(bid, `native.ext.${asset}`)); - - if (asset === 'adTemplate' || !key || !value) { - return; - } - - let sendPlaceholder = deepAccess(bidReq, `nativeParams.${asset}.sendId`); - if (typeof sendPlaceholder !== 'boolean') { - sendPlaceholder = deepAccess(bidReq, `nativeParams.ext.${asset}.sendId`); - } - - if (sendPlaceholder) { - const placeholder = `${key}:${bid.adId}`; - value = placeholder; - } - - let assetSendTargetingKeys = deepAccess(bidReq, `nativeParams.${asset}.sendTargetingKeys`) - if (typeof assetSendTargetingKeys !== 'boolean') { - assetSendTargetingKeys = deepAccess(bidReq, `nativeParams.ext.${asset}.sendTargetingKeys`); - } - - const sendTargeting = typeof assetSendTargetingKeys === 'boolean' ? assetSendTargetingKeys : globalSendTargetingKeys; - - if (sendTargeting) { - keyValues[key] = value; - } - }); - - return keyValues; -} - -/** - * Constructs a message object containing asset values for each of the - * requested data keys. - */ -export function getAssetMessage(data, adObject) { - const message = { - message: 'assetResponse', - adId: data.adId, - assets: [], - }; - - if (adObject.native.hasOwnProperty('adTemplate')) { - message.adTemplate = getAssetValue(adObject.native['adTemplate']); - } if (adObject.native.hasOwnProperty('rendererUrl')) { - message.rendererUrl = getAssetValue(adObject.native['rendererUrl']); - } - - data.assets.forEach(asset => { - const key = getKeyByValue(CONSTANTS.NATIVE_KEYS, asset); - const value = getAssetValue(adObject.native[key]); - - message.assets.push({ key, value }); - }); - - return message; -} - -export function getAllAssetsMessage(data, adObject) { - const message = { - message: 'assetResponse', - adId: data.adId, - assets: [] - }; - - Object.keys(adObject.native).forEach(function(key, index) { - if (key === 'adTemplate' && adObject.native[key]) { - message.adTemplate = getAssetValue(adObject.native[key]); - } else if (key === 'rendererUrl' && adObject.native[key]) { - message.rendererUrl = getAssetValue(adObject.native[key]); - } else if (key === 'ext') { - Object.keys(adObject.native[key]).forEach(extKey => { - if (adObject.native[key][extKey]) { - const value = getAssetValue(adObject.native[key][extKey]); - message.assets.push({ key: extKey, value }); - } - }) - } else if (adObject.native[key] && CONSTANTS.NATIVE_KEYS.hasOwnProperty(key)) { - const value = getAssetValue(adObject.native[key]); - - message.assets.push({ key, value }); - } - }); - - return message; -} - -/** - * Native assets can be a string or an object with a url prop. Returns the value - * appropriate for sending in adserver targeting or placeholder replacement. - */ -function getAssetValue(value) { - if (typeof value === 'object' && value.url) { - return value.url; - } - - return value; -} - -function getNativeKeys(bidReq) { - const extraNativeKeys = {} - - if (deepAccess(bidReq, 'nativeParams.ext')) { - Object.keys(bidReq.nativeParams.ext).forEach(extKey => { - extraNativeKeys[extKey] = `hb_native_${extKey}`; - }) - } - - return { - ...CONSTANTS.NATIVE_KEYS, - ...extraNativeKeys - } -} diff --git a/src/prebid.js b/src/prebid.js deleted file mode 100644 index 2211e8ec2b5..00000000000 --- a/src/prebid.js +++ /dev/null @@ -1,967 +0,0 @@ -/** @module pbjs */ - -import { getGlobal } from './prebidGlobal.js'; -import { adUnitsFilter, flatten, getHighestCpm, isArrayOfNums, isGptPubadsDefined, uniques } from './utils.js'; -import { listenMessagesFromCreative } from './secureCreatives.js'; -import { userSync } from './userSync.js'; -import { config } from './config.js'; -import { auctionManager } from './auctionManager.js'; -import { filters, targeting } from './targeting.js'; -import { hook } from './hook.js'; -import { sessionLoader } from './debugging.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import { adunitCounter } from './adUnits.js'; -import { executeRenderer, isRendererRequired } from './Renderer.js'; -import { createBid } from './bidfactory.js'; -import { storageCallbacks } from './storageManager.js'; - -const $$PREBID_GLOBAL$$ = getGlobal(); -const CONSTANTS = require('./constants.json'); -const utils = require('./utils.js'); -const adapterManager = require('./adapterManager.js').default; -const events = require('./events.js'); -const { triggerUserSyncs } = userSync; - -/* private variables */ -const { ADD_AD_UNITS, BID_WON, REQUEST_BIDS, SET_TARGETING, AD_RENDER_FAILED } = CONSTANTS.EVENTS; -const { PREVENT_WRITING_ON_MAIN_DOCUMENT, NO_AD, EXCEPTION, CANNOT_FIND_AD, MISSING_DOC_OR_ADID } = CONSTANTS.AD_RENDER_FAILED_REASON; - -const eventValidators = { - bidWon: checkDefinedPlacement -}; - -// initialize existing debugging sessions if present -sessionLoader(); - -/* Public vars */ -$$PREBID_GLOBAL$$.bidderSettings = $$PREBID_GLOBAL$$.bidderSettings || {}; - -// let the world know we are loaded -$$PREBID_GLOBAL$$.libLoaded = true; - -// version auto generated from build -$$PREBID_GLOBAL$$.version = 'v$prebid.version$'; -utils.logInfo('Prebid.js v$prebid.version$ loaded'); - -// modules list generated from build -$$PREBID_GLOBAL$$.installedModules = ['v$prebid.modulesList$']; - -// create adUnit array -$$PREBID_GLOBAL$$.adUnits = $$PREBID_GLOBAL$$.adUnits || []; - -// Allow publishers who enable user sync override to trigger their sync -$$PREBID_GLOBAL$$.triggerUserSyncs = triggerUserSyncs; - -function checkDefinedPlacement(id) { - var adUnitCodes = auctionManager.getBidsRequested().map(bidSet => bidSet.bids.map(bid => bid.adUnitCode)) - .reduce(flatten) - .filter(uniques); - - if (!utils.contains(adUnitCodes, id)) { - utils.logError('The "' + id + '" placement is not defined.'); - return; - } - - return true; -} - -function setRenderSize(doc, width, height) { - if (doc.defaultView && doc.defaultView.frameElement) { - doc.defaultView.frameElement.width = width; - doc.defaultView.frameElement.height = height; - } -} - -function validateSizes(sizes, targLength) { - let cleanSizes = []; - if (utils.isArray(sizes) && ((targLength) ? sizes.length === targLength : sizes.length > 0)) { - // check if an array of arrays or array of numbers - if (sizes.every(sz => isArrayOfNums(sz, 2))) { - cleanSizes = sizes; - } else if (isArrayOfNums(sizes, 2)) { - cleanSizes.push(sizes); - } - } - return cleanSizes; -} - -function validateBannerMediaType(adUnit) { - const validatedAdUnit = utils.deepClone(adUnit); - const banner = validatedAdUnit.mediaTypes.banner; - const bannerSizes = validateSizes(banner.sizes); - if (bannerSizes.length > 0) { - banner.sizes = bannerSizes; - // Deprecation Warning: This property will be deprecated in next release in favor of adUnit.mediaTypes.banner.sizes - validatedAdUnit.sizes = bannerSizes; - } else { - utils.logError('Detected a mediaTypes.banner object without a proper sizes field. Please ensure the sizes are listed like: [[300, 250], ...]. Removing invalid mediaTypes.banner object from request.'); - delete validatedAdUnit.mediaTypes.banner - } - return validatedAdUnit; -} - -function validateVideoMediaType(adUnit) { - const validatedAdUnit = utils.deepClone(adUnit); - const video = validatedAdUnit.mediaTypes.video; - if (video.playerSize) { - let tarPlayerSizeLen = (typeof video.playerSize[0] === 'number') ? 2 : 1; - - const videoSizes = validateSizes(video.playerSize, tarPlayerSizeLen); - if (videoSizes.length > 0) { - if (tarPlayerSizeLen === 2) { - utils.logInfo('Transforming video.playerSize from [640,480] to [[640,480]] so it\'s in the proper format.'); - } - video.playerSize = videoSizes; - // Deprecation Warning: This property will be deprecated in next release in favor of adUnit.mediaTypes.video.playerSize - validatedAdUnit.sizes = videoSizes; - } else { - utils.logError('Detected incorrect configuration of mediaTypes.video.playerSize. Please specify only one set of dimensions in a format like: [[640, 480]]. Removing invalid mediaTypes.video.playerSize property from request.'); - delete validatedAdUnit.mediaTypes.video.playerSize; - } - } - return validatedAdUnit; -} - -function validateNativeMediaType(adUnit) { - const validatedAdUnit = utils.deepClone(adUnit); - const native = validatedAdUnit.mediaTypes.native; - if (native.image && native.image.sizes && !Array.isArray(native.image.sizes)) { - utils.logError('Please use an array of sizes for native.image.sizes field. Removing invalid mediaTypes.native.image.sizes property from request.'); - delete validatedAdUnit.mediaTypes.native.image.sizes; - } - if (native.image && native.image.aspect_ratios && !Array.isArray(native.image.aspect_ratios)) { - utils.logError('Please use an array of sizes for native.image.aspect_ratios field. Removing invalid mediaTypes.native.image.aspect_ratios property from request.'); - delete validatedAdUnit.mediaTypes.native.image.aspect_ratios; - } - if (native.icon && native.icon.sizes && !Array.isArray(native.icon.sizes)) { - utils.logError('Please use an array of sizes for native.icon.sizes field. Removing invalid mediaTypes.native.icon.sizes property from request.'); - delete validatedAdUnit.mediaTypes.native.icon.sizes; - } - return validatedAdUnit; -} - -export const adUnitSetupChecks = { - validateBannerMediaType, - validateVideoMediaType, - validateNativeMediaType, - validateSizes -}; - -export const checkAdUnitSetup = hook('sync', function (adUnits) { - const validatedAdUnits = []; - - adUnits.forEach(adUnit => { - const mediaTypes = adUnit.mediaTypes; - const bids = adUnit.bids; - let validatedBanner, validatedVideo, validatedNative; - - if (!bids || !utils.isArray(bids)) { - utils.logError(`Detected adUnit.code '${adUnit.code}' did not have 'adUnit.bids' defined or 'adUnit.bids' is not an array. Removing adUnit from auction.`); - return; - } - - if (!mediaTypes || Object.keys(mediaTypes).length === 0) { - utils.logError(`Detected adUnit.code '${adUnit.code}' did not have a 'mediaTypes' object defined. This is a required field for the auction, so this adUnit has been removed.`); - return; - } - - if (mediaTypes.banner) { - validatedBanner = validateBannerMediaType(adUnit); - } - - if (mediaTypes.video) { - validatedVideo = validatedBanner ? validateVideoMediaType(validatedBanner) : validateVideoMediaType(adUnit); - } - - if (mediaTypes.native) { - validatedNative = validatedVideo ? validateNativeMediaType(validatedVideo) : validatedBanner ? validateNativeMediaType(validatedBanner) : validateNativeMediaType(adUnit); - } - - const validatedAdUnit = Object.assign({}, validatedBanner, validatedVideo, validatedNative); - - validatedAdUnits.push(validatedAdUnit); - }); - - return validatedAdUnits; -}, 'checkAdUnitSetup'); - -/// /////////////////////////////// -// // -// Start Public APIs // -// // -/// /////////////////////////////// - -/** - * This function returns the query string targeting parameters available at this moment for a given ad unit. Note that some bidder's response may not have been received if you call this function too quickly after the requests are sent. - * @param {string} [adunitCode] adUnitCode to get the bid responses for - * @alias module:pbjs.getAdserverTargetingForAdUnitCodeStr - * @return {Array} returnObj return bids array - */ -$$PREBID_GLOBAL$$.getAdserverTargetingForAdUnitCodeStr = function (adunitCode) { - utils.logInfo('Invoking $$PREBID_GLOBAL$$.getAdserverTargetingForAdUnitCodeStr', arguments); - - // call to retrieve bids array - if (adunitCode) { - var res = $$PREBID_GLOBAL$$.getAdserverTargetingForAdUnitCode(adunitCode); - return utils.transformAdServerTargetingObj(res); - } else { - utils.logMessage('Need to call getAdserverTargetingForAdUnitCodeStr with adunitCode'); - } -}; - -/** - * This function returns the query string targeting parameters available at this moment for a given ad unit. Note that some bidder's response may not have been received if you call this function too quickly after the requests are sent. - * @param adUnitCode {string} adUnitCode to get the bid responses for - * @alias module:pbjs.getHighestUnusedBidResponseForAdUnitCode - * @returns {Object} returnObj return bid - */ -$$PREBID_GLOBAL$$.getHighestUnusedBidResponseForAdUnitCode = function (adunitCode) { - if (adunitCode) { - const bid = auctionManager.getAllBidsForAdUnitCode(adunitCode) - .filter(filters.isUnusedBid) - .filter(filters.isBidNotExpired) - - return bid.length ? bid.reduce(getHighestCpm) : {} - } else { - utils.logMessage('Need to call getHighestUnusedBidResponseForAdUnitCode with adunitCode'); - } -}; - -/** - * This function returns the query string targeting parameters available at this moment for a given ad unit. Note that some bidder's response may not have been received if you call this function too quickly after the requests are sent. - * @param adUnitCode {string} adUnitCode to get the bid responses for - * @alias module:pbjs.getAdserverTargetingForAdUnitCode - * @returns {Object} returnObj return bids - */ -$$PREBID_GLOBAL$$.getAdserverTargetingForAdUnitCode = function (adUnitCode) { - return $$PREBID_GLOBAL$$.getAdserverTargeting(adUnitCode)[adUnitCode]; -}; - -/** - * returns all ad server targeting for all ad units - * @return {Object} Map of adUnitCodes and targeting values [] - * @alias module:pbjs.getAdserverTargeting - */ - -$$PREBID_GLOBAL$$.getAdserverTargeting = function (adUnitCode) { - utils.logInfo('Invoking $$PREBID_GLOBAL$$.getAdserverTargeting', arguments); - return targeting.getAllTargeting(adUnitCode); -}; - -function getBids(type) { - const responses = auctionManager[type]() - .filter(utils.bind.call(adUnitsFilter, this, auctionManager.getAdUnitCodes())); - - // find the last auction id to get responses for most recent auction only - const currentAuctionId = auctionManager.getLastAuctionId(); - - return responses - .map(bid => bid.adUnitCode) - .filter(uniques).map(adUnitCode => responses - .filter(bid => bid.auctionId === currentAuctionId && bid.adUnitCode === adUnitCode)) - .filter(bids => bids && bids[0] && bids[0].adUnitCode) - .map(bids => { - return { - [bids[0].adUnitCode]: { bids } - }; - }) - .reduce((a, b) => Object.assign(a, b), {}); -} - -/** - * This function returns the bids requests involved in an auction but not bid on - * @alias module:pbjs.getNoBids - * @return {Object} map | object that contains the bidRequests - */ - -$$PREBID_GLOBAL$$.getNoBids = function () { - utils.logInfo('Invoking $$PREBID_GLOBAL$$.getNoBids', arguments); - return getBids('getNoBids'); -}; - -/** - * This function returns the bids requests involved in an auction but not bid on or the specified adUnitCode - * @param {string} adUnitCode adUnitCode - * @alias module:pbjs.getNoBidsForAdUnitCode - * @return {Object} bidResponse object - */ - -$$PREBID_GLOBAL$$.getNoBidsForAdUnitCode = function (adUnitCode) { - const bids = auctionManager.getNoBids().filter(bid => bid.adUnitCode === adUnitCode); - return { bids }; -}; - -/** - * This function returns the bid responses at the given moment. - * @alias module:pbjs.getBidResponses - * @return {Object} map | object that contains the bidResponses - */ - -$$PREBID_GLOBAL$$.getBidResponses = function () { - utils.logInfo('Invoking $$PREBID_GLOBAL$$.getBidResponses', arguments); - return getBids('getBidsReceived'); -}; - -/** - * Returns bidResponses for the specified adUnitCode - * @param {string} adUnitCode adUnitCode - * @alias module:pbjs.getBidResponsesForAdUnitCode - * @return {Object} bidResponse object - */ - -$$PREBID_GLOBAL$$.getBidResponsesForAdUnitCode = function (adUnitCode) { - const bids = auctionManager.getBidsReceived().filter(bid => bid.adUnitCode === adUnitCode); - return { bids }; -}; - -/** - * Set query string targeting on one or more GPT ad units. - * @param {(string|string[])} adUnit a single `adUnit.code` or multiple. - * @param {function(object)} customSlotMatching gets a GoogleTag slot and returns a filter function for adUnitCode, so you can decide to match on either eg. return slot => { return adUnitCode => { return slot.getSlotElementId() === 'myFavoriteDivId'; } }; - * @alias module:pbjs.setTargetingForGPTAsync - */ -$$PREBID_GLOBAL$$.setTargetingForGPTAsync = function (adUnit, customSlotMatching) { - utils.logInfo('Invoking $$PREBID_GLOBAL$$.setTargetingForGPTAsync', arguments); - if (!isGptPubadsDefined()) { - utils.logError('window.googletag is not defined on the page'); - return; - } - - // get our ad unit codes - let targetingSet = targeting.getAllTargeting(adUnit); - - // first reset any old targeting - targeting.resetPresetTargeting(adUnit, customSlotMatching); - - // now set new targeting keys - targeting.setTargetingForGPT(targetingSet, customSlotMatching); - - Object.keys(targetingSet).forEach((adUnitCode) => { - Object.keys(targetingSet[adUnitCode]).forEach((targetingKey) => { - if (targetingKey === 'hb_adid') { - auctionManager.setStatusForBids(targetingSet[adUnitCode][targetingKey], CONSTANTS.BID_STATUS.BID_TARGETING_SET); - } - }); - }); - - // emit event - events.emit(SET_TARGETING, targetingSet); -}; - -/** - * Set query string targeting on all AST (AppNexus Seller Tag) ad units. Note that this function has to be called after all ad units on page are defined. For working example code, see [Using Prebid.js with AppNexus Publisher Ad Server](http://prebid.org/dev-docs/examples/use-prebid-with-appnexus-ad-server.html). - * @param {(string|string[])} adUnitCode adUnitCode or array of adUnitCodes - * @alias module:pbjs.setTargetingForAst - */ -$$PREBID_GLOBAL$$.setTargetingForAst = function (adUnitCodes) { - utils.logInfo('Invoking $$PREBID_GLOBAL$$.setTargetingForAn', arguments); - if (!targeting.isApntagDefined()) { - utils.logError('window.apntag is not defined on the page'); - return; - } - - targeting.setTargetingForAst(adUnitCodes); - - // emit event - events.emit(SET_TARGETING, targeting.getAllTargeting()); -}; - -function emitAdRenderFail({ reason, message, bid, id }) { - const data = { reason, message }; - if (bid) data.bid = bid; - if (id) data.adId = id; - - utils.logError(message); - events.emit(AD_RENDER_FAILED, data); -} - -/** - * This function will render the ad (based on params) in the given iframe document passed through. - * Note that doc SHOULD NOT be the parent document page as we can't doc.write() asynchronously - * @param {HTMLDocument} doc document - * @param {string} id bid id to locate the ad - * @alias module:pbjs.renderAd - */ -$$PREBID_GLOBAL$$.renderAd = function (doc, id, options) { - utils.logInfo('Invoking $$PREBID_GLOBAL$$.renderAd', arguments); - utils.logMessage('Calling renderAd with adId :' + id); - - if (doc && id) { - try { - // lookup ad by ad Id - const bid = auctionManager.findBidByAdId(id); - if (bid) { - // replace macros according to openRTB with price paid = bid.cpm - bid.ad = utils.replaceAuctionPrice(bid.ad, bid.cpm); - bid.adUrl = utils.replaceAuctionPrice(bid.adUrl, bid.cpm); - - // replacing clickthrough if submitted - if (options && options.clickThrough) { - const { clickThrough } = options; - bid.ad = utils.replaceClickThrough(bid.ad, clickThrough); - bid.adUrl = utils.replaceClickThrough(bid.adUrl, clickThrough); - } - - // save winning bids - auctionManager.addWinningBid(bid); - - // emit 'bid won' event here - events.emit(BID_WON, bid); - - const { height, width, ad, mediaType, adUrl, renderer } = bid; - - const creativeComment = document.createComment(`Creative ${bid.creativeId} served by ${bid.bidder} Prebid.js Header Bidding`); - utils.insertElement(creativeComment, doc, 'body'); - - if (isRendererRequired(renderer)) { - executeRenderer(renderer, bid); - } else if ((doc === document && !utils.inIframe()) || mediaType === 'video') { - const message = `Error trying to write ad. Ad render call ad id ${id} was prevented from writing to the main document.`; - emitAdRenderFail({ reason: PREVENT_WRITING_ON_MAIN_DOCUMENT, message, bid, id }); - } else if (ad) { - // will check if browser is firefox and below version 67, if so execute special doc.open() - // for details see: https://github.com/prebid/Prebid.js/pull/3524 - // TODO remove this browser specific code at later date (when Firefox < 67 usage is mostly gone) - if (navigator.userAgent && navigator.userAgent.toLowerCase().indexOf('firefox/') > -1) { - const firefoxVerRegx = /firefox\/([\d\.]+)/; - let firefoxVer = navigator.userAgent.toLowerCase().match(firefoxVerRegx)[1]; // grabs the text in the 1st matching group - if (firefoxVer && parseInt(firefoxVer, 10) < 67) { - doc.open('text/html', 'replace'); - } - } - doc.write(ad); - doc.close(); - setRenderSize(doc, width, height); - utils.callBurl(bid); - } else if (adUrl) { - const iframe = utils.createInvisibleIframe(); - iframe.height = height; - iframe.width = width; - iframe.style.display = 'inline'; - iframe.style.overflow = 'hidden'; - iframe.src = adUrl; - - utils.insertElement(iframe, doc, 'body'); - setRenderSize(doc, width, height); - utils.callBurl(bid); - } else { - const message = `Error trying to write ad. No ad for bid response id: ${id}`; - emitAdRenderFail({ reason: NO_AD, message, bid, id }); - } - } else { - const message = `Error trying to write ad. Cannot find ad by given id : ${id}`; - emitAdRenderFail({ reason: CANNOT_FIND_AD, message, id }); - } - } catch (e) { - const message = `Error trying to write ad Id :${id} to the page:${e.message}`; - emitAdRenderFail({ reason: EXCEPTION, message, id }); - } - } else { - const message = `Error trying to write ad Id :${id} to the page. Missing document or adId`; - emitAdRenderFail({ reason: MISSING_DOC_OR_ADID, message, id }); - } -}; - -/** - * Remove adUnit from the $$PREBID_GLOBAL$$ configuration, if there are no addUnitCode(s) it will remove all - * @param {string| Array} adUnitCode the adUnitCode(s) to remove - * @alias module:pbjs.removeAdUnit - */ -$$PREBID_GLOBAL$$.removeAdUnit = function (adUnitCode) { - utils.logInfo('Invoking $$PREBID_GLOBAL$$.removeAdUnit', arguments); - - if (!adUnitCode) { - $$PREBID_GLOBAL$$.adUnits = []; - return; - } - - let adUnitCodes; - - if (utils.isArray(adUnitCode)) { - adUnitCodes = adUnitCode; - } else { - adUnitCodes = [adUnitCode]; - } - - adUnitCodes.forEach((adUnitCode) => { - for (let i = $$PREBID_GLOBAL$$.adUnits.length - 1; i >= 0; i--) { - if ($$PREBID_GLOBAL$$.adUnits[i].code === adUnitCode) { - $$PREBID_GLOBAL$$.adUnits.splice(i, 1); - } - } - }); -}; - -/** - * @param {Object} requestOptions - * @param {function} requestOptions.bidsBackHandler - * @param {number} requestOptions.timeout - * @param {Array} requestOptions.adUnits - * @param {Array} requestOptions.adUnitCodes - * @param {Array} requestOptions.labels - * @param {String} requestOptions.auctionId - * @alias module:pbjs.requestBids - */ -$$PREBID_GLOBAL$$.requestBids = hook('async', function ({ bidsBackHandler, timeout, adUnits, adUnitCodes, labels, auctionId } = {}) { - events.emit(REQUEST_BIDS); - const cbTimeout = timeout || config.getConfig('bidderTimeout'); - adUnits = (adUnits && config.convertAdUnitFpd(utils.isArray(adUnits) ? adUnits : [adUnits])) || $$PREBID_GLOBAL$$.adUnits; - - utils.logInfo('Invoking $$PREBID_GLOBAL$$.requestBids', arguments); - - let _s2sConfigs = []; - const s2sBidders = []; - config.getConfig('s2sConfig', config => { - if (config && config.s2sConfig) { - _s2sConfigs = Array.isArray(config.s2sConfig) ? config.s2sConfig : [config.s2sConfig]; - } - }); - - _s2sConfigs.forEach(s2sConfig => { - s2sBidders.push(...s2sConfig.bidders); - }); - - adUnits = checkAdUnitSetup(adUnits); - - if (adUnitCodes && adUnitCodes.length) { - // if specific adUnitCodes supplied filter adUnits for those codes - adUnits = adUnits.filter(unit => includes(adUnitCodes, unit.code)); - } else { - // otherwise derive adUnitCodes from adUnits - adUnitCodes = adUnits && adUnits.map(unit => unit.code); - } - - /* - * for a given adunit which supports a set of mediaTypes - * and a given bidder which supports a set of mediaTypes - * a bidder is eligible to participate on the adunit - * if it supports at least one of the mediaTypes on the adunit - */ - adUnits.forEach(adUnit => { - // get the adunit's mediaTypes, defaulting to banner if mediaTypes isn't present - const adUnitMediaTypes = Object.keys(adUnit.mediaTypes || { 'banner': 'banner' }); - - // get the bidder's mediaTypes - const allBidders = adUnit.bids.map(bid => bid.bidder); - const bidderRegistry = adapterManager.bidderRegistry; - - const bidders = (s2sBidders) ? allBidders.filter(bidder => !includes(s2sBidders, bidder)) : allBidders; - - adUnit.transactionId = utils.generateUUID(); - - bidders.forEach(bidder => { - const adapter = bidderRegistry[bidder]; - const spec = adapter && adapter.getSpec && adapter.getSpec(); - // banner is default if not specified in spec - const bidderMediaTypes = (spec && spec.supportedMediaTypes) || ['banner']; - - // check if the bidder's mediaTypes are not in the adUnit's mediaTypes - const bidderEligible = adUnitMediaTypes.some(type => includes(bidderMediaTypes, type)); - if (!bidderEligible) { - // drop the bidder from the ad unit if it's not compatible - utils.logWarn(utils.unsupportedBidderMessage(adUnit, bidder)); - adUnit.bids = adUnit.bids.filter(bid => bid.bidder !== bidder); - } else { - adunitCounter.incrementBidderRequestsCounter(adUnit.code, bidder); - } - }); - adunitCounter.incrementRequestsCounter(adUnit.code); - }); - - if (!adUnits || adUnits.length === 0) { - utils.logMessage('No adUnits configured. No bids requested.'); - if (typeof bidsBackHandler === 'function') { - // executeCallback, this will only be called in case of first request - try { - bidsBackHandler(); - } catch (e) { - utils.logError('Error executing bidsBackHandler', null, e); - } - } - return; - } - - const auction = auctionManager.createAuction({ adUnits, adUnitCodes, callback: bidsBackHandler, cbTimeout, labels, auctionId }); - - let adUnitsLen = adUnits.length; - if (adUnitsLen > 15) { - utils.logInfo(`Current auction ${auction.getAuctionId()} contains ${adUnitsLen} adUnits.`, adUnits); - } - - adUnitCodes.forEach(code => targeting.setLatestAuctionForAdUnit(code, auction.getAuctionId())); - auction.callBids(); -}); - -export function executeCallbacks(fn, reqBidsConfigObj) { - runAll(storageCallbacks); - runAll(enableAnalyticsCallbacks); - fn.call(this, reqBidsConfigObj); - - function runAll(queue) { - var queued; - while ((queued = queue.shift())) { - queued(); - } - } -} - -// This hook will execute all storage callbacks which were registered before gdpr enforcement hook was added. Some bidders, user id modules use storage functions when module is parsed but gdpr enforcement hook is not added at that stage as setConfig callbacks are yet to be called. Hence for such calls we execute all the stored callbacks just before requestBids. At this hook point we will know for sure that gdprEnforcement module is added or not -$$PREBID_GLOBAL$$.requestBids.before(executeCallbacks, 49); - -/** - * - * Add adunit(s) - * @param {Array|Object} adUnitArr Array of adUnits or single adUnit Object. - * @alias module:pbjs.addAdUnits - */ -$$PREBID_GLOBAL$$.addAdUnits = function (adUnitArr) { - utils.logInfo('Invoking $$PREBID_GLOBAL$$.addAdUnits', arguments); - $$PREBID_GLOBAL$$.adUnits.push.apply($$PREBID_GLOBAL$$.adUnits, config.convertAdUnitFpd(utils.isArray(adUnitArr) ? adUnitArr : [adUnitArr])); - // emit event - events.emit(ADD_AD_UNITS); -}; - -/** - * @param {string} event the name of the event - * @param {Function} handler a callback to set on event - * @param {string} id an identifier in the context of the event - * @alias module:pbjs.onEvent - * - * This API call allows you to register a callback to handle a Prebid.js event. - * An optional `id` parameter provides more finely-grained event callback registration. - * This makes it possible to register callback events for a specific item in the - * event context. For example, `bidWon` events will accept an `id` for ad unit code. - * `bidWon` callbacks registered with an ad unit code id will be called when a bid - * for that ad unit code wins the auction. Without an `id` this method registers the - * callback for every `bidWon` event. - * - * Currently `bidWon` is the only event that accepts an `id` parameter. - */ -$$PREBID_GLOBAL$$.onEvent = function (event, handler, id) { - utils.logInfo('Invoking $$PREBID_GLOBAL$$.onEvent', arguments); - if (!utils.isFn(handler)) { - utils.logError('The event handler provided is not a function and was not set on event "' + event + '".'); - return; - } - - if (id && !eventValidators[event].call(null, id)) { - utils.logError('The id provided is not valid for event "' + event + '" and no handler was set.'); - return; - } - - events.on(event, handler, id); -}; - -/** - * @param {string} event the name of the event - * @param {Function} handler a callback to remove from the event - * @param {string} id an identifier in the context of the event (see `$$PREBID_GLOBAL$$.onEvent`) - * @alias module:pbjs.offEvent - */ -$$PREBID_GLOBAL$$.offEvent = function (event, handler, id) { - utils.logInfo('Invoking $$PREBID_GLOBAL$$.offEvent', arguments); - if (id && !eventValidators[event].call(null, id)) { - return; - } - - events.off(event, handler, id); -}; - -/** - * Return a copy of all events emitted - * - * @alias module:pbjs.getEvents - */ -$$PREBID_GLOBAL$$.getEvents = function () { - utils.logInfo('Invoking $$PREBID_GLOBAL$$.getEvents'); - return events.getEvents(); -}; - -/* - * Wrapper to register bidderAdapter externally (adapterManager.registerBidAdapter()) - * @param {Function} bidderAdaptor [description] - * @param {string} bidderCode [description] - * @alias module:pbjs.registerBidAdapter - */ -$$PREBID_GLOBAL$$.registerBidAdapter = function (bidderAdaptor, bidderCode) { - utils.logInfo('Invoking $$PREBID_GLOBAL$$.registerBidAdapter', arguments); - try { - adapterManager.registerBidAdapter(bidderAdaptor(), bidderCode); - } catch (e) { - utils.logError('Error registering bidder adapter : ' + e.message); - } -}; - -/** - * Wrapper to register analyticsAdapter externally (adapterManager.registerAnalyticsAdapter()) - * @param {Object} options [description] - * @alias module:pbjs.registerAnalyticsAdapter - */ -$$PREBID_GLOBAL$$.registerAnalyticsAdapter = function (options) { - utils.logInfo('Invoking $$PREBID_GLOBAL$$.registerAnalyticsAdapter', arguments); - try { - adapterManager.registerAnalyticsAdapter(options); - } catch (e) { - utils.logError('Error registering analytics adapter : ' + e.message); - } -}; - -/** - * Wrapper to bidfactory.createBid() - * @param {string} statusCode [description] - * @alias module:pbjs.createBid - * @return {Object} bidResponse [description] - */ -$$PREBID_GLOBAL$$.createBid = function (statusCode) { - utils.logInfo('Invoking $$PREBID_GLOBAL$$.createBid', arguments); - return createBid(statusCode); -}; - -/** - * Enable sending analytics data to the analytics provider of your - * choice. - * - * For usage, see [Integrate with the Prebid Analytics - * API](http://prebid.org/dev-docs/integrate-with-the-prebid-analytics-api.html). - * - * For a list of analytics adapters, see [Analytics for - * Prebid](http://prebid.org/overview/analytics.html). - * @param {Object} config - * @param {string} config.provider The name of the provider, e.g., `"ga"` for Google Analytics. - * @param {Object} config.options The options for this particular analytics adapter. This will likely vary between adapters. - * @alias module:pbjs.enableAnalytics - */ - -// Stores 'enableAnalytics' callbacks for later execution. -const enableAnalyticsCallbacks = []; - -const enableAnalyticsCb = hook('async', function (config) { - if (config && !utils.isEmpty(config)) { - utils.logInfo('Invoking $$PREBID_GLOBAL$$.enableAnalytics for: ', config); - adapterManager.enableAnalytics(config); - } else { - utils.logError('$$PREBID_GLOBAL$$.enableAnalytics should be called with option {}'); - } -}, 'enableAnalyticsCb'); - -$$PREBID_GLOBAL$$.enableAnalytics = function (config) { - enableAnalyticsCallbacks.push(enableAnalyticsCb.bind(this, config)); -}; - -/** - * @alias module:pbjs.aliasBidder - */ -$$PREBID_GLOBAL$$.aliasBidder = function (bidderCode, alias, options) { - utils.logInfo('Invoking $$PREBID_GLOBAL$$.aliasBidder', arguments); - if (bidderCode && alias) { - adapterManager.aliasBidAdapter(bidderCode, alias, options); - } else { - utils.logError('bidderCode and alias must be passed as arguments', '$$PREBID_GLOBAL$$.aliasBidder'); - } -}; - -/** - * The bid response object returned by an external bidder adapter during the auction. - * @typedef {Object} AdapterBidResponse - * @property {string} pbAg Auto granularity price bucket; CPM <= 5 ? increment = 0.05 : CPM > 5 && CPM <= 10 ? increment = 0.10 : CPM > 10 && CPM <= 20 ? increment = 0.50 : CPM > 20 ? priceCap = 20.00. Example: `"0.80"`. - * @property {string} pbCg Custom price bucket. For example setup, see {@link setPriceGranularity}. Example: `"0.84"`. - * @property {string} pbDg Dense granularity price bucket; CPM <= 3 ? increment = 0.01 : CPM > 3 && CPM <= 8 ? increment = 0.05 : CPM > 8 && CPM <= 20 ? increment = 0.50 : CPM > 20? priceCap = 20.00. Example: `"0.84"`. - * @property {string} pbLg Low granularity price bucket; $0.50 increment, capped at $5, floored to two decimal places. Example: `"0.50"`. - * @property {string} pbMg Medium granularity price bucket; $0.10 increment, capped at $20, floored to two decimal places. Example: `"0.80"`. - * @property {string} pbHg High granularity price bucket; $0.01 increment, capped at $20, floored to two decimal places. Example: `"0.84"`. - * - * @property {string} bidder The string name of the bidder. This *may* be the same as the `bidderCode`. For For a list of all bidders and their codes, see [Bidders' Params](http://prebid.org/dev-docs/bidders.html). - * @property {string} bidderCode The unique string that identifies this bidder. For a list of all bidders and their codes, see [Bidders' Params](http://prebid.org/dev-docs/bidders.html). - * - * @property {string} requestId The [UUID](https://en.wikipedia.org/wiki/Universally_unique_identifier) representing the bid request. - * @property {number} requestTimestamp The time at which the bid request was sent out, expressed in milliseconds. - * @property {number} responseTimestamp The time at which the bid response was received, expressed in milliseconds. - * @property {number} timeToRespond How long it took for the bidder to respond with this bid, expressed in milliseconds. - * - * @property {string} size The size of the ad creative, expressed in `"AxB"` format, where A and B are numbers of pixels. Example: `"320x50"`. - * @property {string} width The width of the ad creative in pixels. Example: `"320"`. - * @property {string} height The height of the ad creative in pixels. Example: `"50"`. - * - * @property {string} ad The actual ad creative content, often HTML with CSS, JavaScript, and/or links to additional content. Example: `"",`. - * @property {number} ad_id The ad ID of the creative, as understood by the bidder's system. Used by the line item's [creative in the ad server](http://prebid.org/adops/send-all-bids-adops.html#step-3-add-a-creative). - * @property {string} adUnitCode The code used to uniquely identify the ad unit on the publisher's page. - * - * @property {string} statusMessage The status of the bid. Allowed values: `"Bid available"` or `"Bid returned empty or error response"`. - * @property {number} cpm The exact bid price from the bidder, expressed to the thousandths place. Example: `"0.849"`. - * - * @property {Object} adserverTargeting An object whose values represent the ad server's targeting on the bid. - * @property {string} adserverTargeting.hb_adid The ad ID of the creative, as understood by the ad server. - * @property {string} adserverTargeting.hb_pb The price paid to show the creative, as logged in the ad server. - * @property {string} adserverTargeting.hb_bidder The winning bidder whose ad creative will be served by the ad server. - */ - -/** - * Get all of the bids that have been rendered. Useful for [troubleshooting your integration](http://prebid.org/dev-docs/prebid-troubleshooting-guide.html). - * @return {Array} A list of bids that have been rendered. - */ -$$PREBID_GLOBAL$$.getAllWinningBids = function () { - return auctionManager.getAllWinningBids(); -}; - -/** - * Get all of the bids that have won their respective auctions. - * @return {Array} A list of bids that have won their respective auctions. - */ -$$PREBID_GLOBAL$$.getAllPrebidWinningBids = function () { - return auctionManager.getBidsReceived() - .filter(bid => bid.status === CONSTANTS.BID_STATUS.BID_TARGETING_SET); -}; - -/** - * Get array of highest cpm bids for all adUnits, or highest cpm bid - * object for the given adUnit - * @param {string} adUnitCode - optional ad unit code - * @alias module:pbjs.getHighestCpmBids - * @return {Array} array containing highest cpm bid object(s) - */ -$$PREBID_GLOBAL$$.getHighestCpmBids = function (adUnitCode) { - return targeting.getWinningBids(adUnitCode); -}; - -/** - * Mark the winning bid as used, should only be used in conjunction with video - * @typedef {Object} MarkBidRequest - * @property {string} adUnitCode The ad unit code - * @property {string} adId The id representing the ad we want to mark - * - * @alias module:pbjs.markWinningBidAsUsed - */ -$$PREBID_GLOBAL$$.markWinningBidAsUsed = function (markBidRequest) { - let bids = []; - - if (markBidRequest.adUnitCode && markBidRequest.adId) { - bids = auctionManager.getBidsReceived() - .filter(bid => bid.adId === markBidRequest.adId && bid.adUnitCode === markBidRequest.adUnitCode); - } else if (markBidRequest.adUnitCode) { - bids = targeting.getWinningBids(markBidRequest.adUnitCode); - } else if (markBidRequest.adId) { - bids = auctionManager.getBidsReceived().filter(bid => bid.adId === markBidRequest.adId); - } else { - utils.logWarn('Improper use of markWinningBidAsUsed. It needs an adUnitCode or an adId to function.'); - } - - if (bids.length > 0) { - bids[0].status = CONSTANTS.BID_STATUS.RENDERED; - } -}; - -/** - * Get Prebid config options - * @param {Object} options - * @alias module:pbjs.getConfig - */ -$$PREBID_GLOBAL$$.getConfig = config.getConfig; - -/** - * Set Prebid config options. - * (Added in version 0.27.0). - * - * `setConfig` is designed to allow for advanced configuration while - * reducing the surface area of the public API. For more information - * about the move to `setConfig` (and the resulting deprecations of - * some other public methods), see [the Prebid 1.0 public API - * proposal](https://gist.github.com/mkendall07/51ee5f6b9f2df01a89162cf6de7fe5b6). - * - * #### Troubleshooting your configuration - * - * If you call `pbjs.setConfig` without an object, e.g., - * - * `pbjs.setConfig('debug', 'true'))` - * - * then Prebid.js will print an error to the console that says: - * - * ``` - * ERROR: setConfig options must be an object - * ``` - * - * If you don't see that message, you can assume the config object is valid. - * - * @param {Object} options Global Prebid configuration object. Must be JSON - no JavaScript functions are allowed. - * @param {string} options.bidderSequence The order in which bidders are called. Example: `pbjs.setConfig({ bidderSequence: "fixed" })`. Allowed values: `"fixed"` (order defined in `adUnit.bids` array on page), `"random"`. - * @param {boolean} options.debug Turn debug logging on/off. Example: `pbjs.setConfig({ debug: true })`. - * @param {string} options.priceGranularity The bid price granularity to use. Example: `pbjs.setConfig({ priceGranularity: "medium" })`. Allowed values: `"low"` ($0.50), `"medium"` ($0.10), `"high"` ($0.01), `"auto"` (sliding scale), `"dense"` (like `"auto"`, with smaller increments at lower CPMs), or a custom price bucket object, e.g., `{ "buckets" : [{"min" : 0,"max" : 20,"increment" : 0.1,"cap" : true}]}`. - * @param {boolean} options.enableSendAllBids Turn "send all bids" mode on/off. Example: `pbjs.setConfig({ enableSendAllBids: true })`. - * @param {number} options.bidderTimeout Set a global bidder timeout, in milliseconds. Example: `pbjs.setConfig({ bidderTimeout: 3000 })`. Note that it's still possible for a bid to get into the auction that responds after this timeout. This is due to how [`setTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout) works in JS: it queues the callback in the event loop in an approximate location that should execute after this time but it is not guaranteed. For more information about the asynchronous event loop and `setTimeout`, see [How JavaScript Timers Work](https://johnresig.com/blog/how-javascript-timers-work/). - * @param {string} options.publisherDomain The publisher's domain where Prebid is running, for cross-domain iFrame communication. Example: `pbjs.setConfig({ publisherDomain: "https://www.theverge.com" })`. - * @param {Object} options.s2sConfig The configuration object for [server-to-server header bidding](http://prebid.org/dev-docs/get-started-with-prebid-server.html). Example: - * @alias module:pbjs.setConfig - * ``` - * pbjs.setConfig({ - * s2sConfig: { - * accountId: '1', - * enabled: true, - * bidders: ['appnexus', 'pubmatic'], - * timeout: 1000, - * adapter: 'prebidServer', - * endpoint: 'https://prebid.adnxs.com/pbs/v1/auction' - * } - * }) - * ``` - */ -$$PREBID_GLOBAL$$.setConfig = config.setConfig; -$$PREBID_GLOBAL$$.setBidderConfig = config.setBidderConfig; - -$$PREBID_GLOBAL$$.que.push(() => listenMessagesFromCreative()); - -/** - * This queue lets users load Prebid asynchronously, but run functions the same way regardless of whether it gets loaded - * before or after their script executes. For example, given the code: - * - * - * - * - * If the page's script runs before prebid loads, then their function gets added to the queue, and executed - * by prebid once it's done loading. If it runs after prebid loads, then this monkey-patch causes their - * function to execute immediately. - * - * @memberof pbjs - * @param {function} command A function which takes no arguments. This is guaranteed to run exactly once, and only after - * the Prebid script has been fully loaded. - * @alias module:pbjs.cmd.push - */ -$$PREBID_GLOBAL$$.cmd.push = function (command) { - if (typeof command === 'function') { - try { - command.call(); - } catch (e) { - utils.logError('Error processing command :', e.message, e.stack); - } - } else { - utils.logError('Commands written into $$PREBID_GLOBAL$$.cmd.push must be wrapped in a function'); - } -}; - -$$PREBID_GLOBAL$$.que.push = $$PREBID_GLOBAL$$.cmd.push; - -function processQueue(queue) { - queue.forEach(function (cmd) { - if (typeof cmd.called === 'undefined') { - try { - cmd.call(); - cmd.called = true; - } catch (e) { - utils.logError('Error processing command :', 'prebid.js', e); - } - } - }); -} - -/** - * @alias module:pbjs.processQueue - */ -$$PREBID_GLOBAL$$.processQueue = function () { - hook.ready(); - processQueue($$PREBID_GLOBAL$$.que); - processQueue($$PREBID_GLOBAL$$.cmd); -}; - -export default $$PREBID_GLOBAL$$; diff --git a/src/prebidGlobal.js b/src/prebidGlobal.js deleted file mode 100644 index 5eed4b3670f..00000000000 --- a/src/prebidGlobal.js +++ /dev/null @@ -1,13 +0,0 @@ -// if $$PREBID_GLOBAL$$ already exists in global document scope, use it, if not, create the object -// global defination should happen BEFORE imports to avoid global undefined errors. -window.$$PREBID_GLOBAL$$ = (window.$$PREBID_GLOBAL$$ || {}); -window.$$PREBID_GLOBAL$$.cmd = window.$$PREBID_GLOBAL$$.cmd || []; -window.$$PREBID_GLOBAL$$.que = window.$$PREBID_GLOBAL$$.que || []; - -// create a pbjs global pointer -window._pbjsGlobals = window._pbjsGlobals || []; -window._pbjsGlobals.push('$$PREBID_GLOBAL$$'); - -export function getGlobal() { - return window.$$PREBID_GLOBAL$$; -} diff --git a/src/refererDetection.js b/src/refererDetection.js deleted file mode 100644 index 56d1fa43f7b..00000000000 --- a/src/refererDetection.js +++ /dev/null @@ -1,183 +0,0 @@ -/** - * The referer detection module attempts to gather referer information from the current page that prebid.js resides in. - * The information that it tries to collect includes: - * The detected top url in the nav bar, - * Whether it was able to reach the top most window (if for example it was embedded in several iframes), - * The number of iframes it was embedded in if applicable (by default max ten iframes), - * A list of the domains of each embedded window if applicable. - * Canonical URL which refers to an HTML link element, with the attribute of rel="canonical", found in the element of your webpage - */ - -import { config } from './config.js'; -import { logWarn } from './utils.js'; - -/** - * @param {Window} win Window - * @returns {Function} - */ -export function detectReferer(win) { - /** - * This function would return a read-only array of hostnames for all the parent frames. - * win.location.ancestorOrigins is only supported in webkit browsers. For non-webkit browsers it will return undefined. - * - * @param {Window} win Window object - * @returns {(undefined|Array)} Ancestor origins or undefined - */ - function getAncestorOrigins(win) { - try { - if (!win.location.ancestorOrigins) { - return; - } - - return win.location.ancestorOrigins; - } catch (e) { - // Ignore error - } - } - - /** - * This function returns canonical URL which refers to an HTML link element, with the attribute of rel="canonical", found in the element of your webpage - * - * @param {Object} doc document - * @returns {string|null} - */ - function getCanonicalUrl(doc) { - try { - const element = doc.querySelector("link[rel='canonical']"); - - if (element !== null) { - return element.href; - } - } catch (e) { - // Ignore error - } - - return null; - } - - /** - * Referer info - * @typedef {Object} refererInfo - * @property {string} referer detected top url - * @property {boolean} reachedTop whether prebid was able to walk upto top window or not - * @property {number} numIframes number of iframes - * @property {string} stack comma separated urls of all origins - * @property {string} canonicalUrl canonical URL refers to an HTML link element, with the attribute of rel="canonical", found in the element of your webpage - */ - - /** - * Walk up the windows to get the origin stack and best available referrer, canonical URL, etc. - * - * @returns {refererInfo} - */ - function refererInfo() { - const stack = []; - const ancestors = getAncestorOrigins(win); - const maxNestedIframes = config.getConfig('maxNestedIframes'); - let currentWindow; - let bestReferrer; - let bestCanonicalUrl; - let reachedTop = false; - let level = 0; - let valuesFromAmp = false; - let inAmpFrame = false; - - do { - const previousWindow = currentWindow; - const wasInAmpFrame = inAmpFrame; - let currentLocation; - let crossOrigin = false; - let foundReferrer = null; - - inAmpFrame = false; - currentWindow = currentWindow ? currentWindow.parent : win; - - try { - currentLocation = currentWindow.location.href || null; - } catch (e) { - crossOrigin = true; - } - - if (crossOrigin) { - if (wasInAmpFrame) { - const context = previousWindow.context; - - try { - foundReferrer = context.sourceUrl; - bestReferrer = foundReferrer; - - valuesFromAmp = true; - - if (currentWindow === win.top) { - reachedTop = true; - } - - if (context.canonicalUrl) { - bestCanonicalUrl = context.canonicalUrl; - } - } catch (e) { /* Do nothing */ } - } else { - logWarn('Trying to access cross domain iframe. Continuing without referrer and location'); - - try { - const referrer = previousWindow.document.referrer; - - if (referrer) { - foundReferrer = referrer; - - if (currentWindow === win.top) { - reachedTop = true; - } - } - } catch (e) { /* Do nothing */ } - - if (!foundReferrer && ancestors && ancestors[level - 1]) { - foundReferrer = ancestors[level - 1]; - } - - if (foundReferrer && !valuesFromAmp) { - bestReferrer = foundReferrer; - } - } - } else { - if (currentLocation) { - foundReferrer = currentLocation; - bestReferrer = foundReferrer; - valuesFromAmp = false; - - if (currentWindow === win.top) { - reachedTop = true; - - const canonicalUrl = getCanonicalUrl(currentWindow.document); - - if (canonicalUrl) { - bestCanonicalUrl = canonicalUrl; - } - } - } - - if (currentWindow.context && currentWindow.context.sourceUrl) { - inAmpFrame = true; - } - } - - stack.push(foundReferrer); - level++; - } while (currentWindow !== win.top && level < maxNestedIframes); - - stack.reverse(); - - return { - referer: bestReferrer || null, - reachedTop, - isAmp: valuesFromAmp, - numIframes: level - 1, - stack, - canonicalUrl: bestCanonicalUrl || null - }; - } - - return refererInfo; -} - -export const getRefererInfo = detectReferer(window); diff --git a/src/secureCreatives.js b/src/secureCreatives.js deleted file mode 100644 index def1a9abdbb..00000000000 --- a/src/secureCreatives.js +++ /dev/null @@ -1,132 +0,0 @@ -/* Secure Creatives - Provides support for rendering creatives into cross domain iframes such as SafeFrame to prevent - access to a publisher page from creative payloads. - */ - -import events from './events.js'; -import { fireNativeTrackers, getAssetMessage, getAllAssetsMessage } from './native.js'; -import constants from './constants.json'; -import { logWarn, replaceAuctionPrice } from './utils.js'; -import { auctionManager } from './auctionManager.js'; -import find from 'core-js-pure/features/array/find.js'; -import { isRendererRequired, executeRenderer } from './Renderer.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -const BID_WON = constants.EVENTS.BID_WON; - -export function listenMessagesFromCreative() { - window.addEventListener('message', receiveMessage, false); -} - -function receiveMessage(ev) { - var key = ev.message ? 'message' : 'data'; - var data = {}; - try { - data = JSON.parse(ev[key]); - } catch (e) { - return; - } - - if (data && data.adId) { - const adObject = find(auctionManager.getBidsReceived(), function (bid) { - return bid.adId === data.adId; - }); - - if (adObject && data.message === 'Prebid Request') { - _sendAdToCreative(adObject, ev); - - // save winning bids - auctionManager.addWinningBid(adObject); - - events.emit(BID_WON, adObject); - } - - // handle this script from native template in an ad server - // window.parent.postMessage(JSON.stringify({ - // message: 'Prebid Native', - // adId: '%%PATTERN:hb_adid%%' - // }), '*'); - if (adObject && data.message === 'Prebid Native') { - if (data.action === 'assetRequest') { - const message = getAssetMessage(data, adObject); - ev.source.postMessage(JSON.stringify(message), ev.origin); - return; - } else if (data.action === 'allAssetRequest') { - const message = getAllAssetsMessage(data, adObject); - ev.source.postMessage(JSON.stringify(message), ev.origin); - } else if (data.action === 'resizeNativeHeight') { - adObject.height = data.height; - adObject.width = data.width; - resizeRemoteCreative(adObject); - } - - const trackerType = fireNativeTrackers(data, adObject); - if (trackerType === 'click') { return; } - - auctionManager.addWinningBid(adObject); - events.emit(BID_WON, adObject); - } - } -} - -export function _sendAdToCreative(adObject, ev) { - const { adId, ad, adUrl, width, height, renderer, cpm } = adObject; - // rendering for outstream safeframe - if (isRendererRequired(renderer)) { - executeRenderer(renderer, adObject); - } else if (adId) { - resizeRemoteCreative(adObject); - ev.source.postMessage(JSON.stringify({ - message: 'Prebid Response', - ad: replaceAuctionPrice(ad, cpm), - adUrl: replaceAuctionPrice(adUrl, cpm), - adId, - width, - height - }), ev.origin); - } -} - -function resizeRemoteCreative({ adId, adUnitCode, width, height }) { - // resize both container div + iframe - ['div', 'iframe'].forEach(elmType => { - // not select element that gets removed after dfp render - let element = getElementByAdUnit(elmType + ':not([style*="display: none"])'); - if (element) { - let elementStyle = element.style; - elementStyle.width = width + 'px'; - elementStyle.height = height + 'px'; - } else { - logWarn(`Unable to locate matching page element for adUnitCode ${adUnitCode}. Can't resize it to ad's dimensions. Please review setup.`); - } - }); - - function getElementByAdUnit(elmType) { - let id = getElementIdBasedOnAdServer(adId, adUnitCode); - let parentDivEle = document.getElementById(id); - return parentDivEle && parentDivEle.querySelector(elmType); - } - - function getElementIdBasedOnAdServer(adId, adUnitCode) { - if (window.googletag) { - return getDfpElementId(adId) - } else if (window.apntag) { - return getAstElementId(adUnitCode) - } else { - return adUnitCode; - } - } - - function getDfpElementId(adId) { - return find(window.googletag.pubads().getSlots(), slot => { - return find(slot.getTargetingKeys(), key => { - return includes(slot.getTargeting(key), adId); - }); - }).getSlotElementId(); - } - - function getAstElementId(adUnitCode) { - let astTag = window.apntag.getTag(adUnitCode); - return astTag && astTag.targetId; - } -} diff --git a/src/sizeMapping.js b/src/sizeMapping.js deleted file mode 100644 index 313da3f422a..00000000000 --- a/src/sizeMapping.js +++ /dev/null @@ -1,161 +0,0 @@ -import { config } from './config.js'; -import {logWarn, isPlainObject, deepAccess, deepClone, getWindowTop} from './utils.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -let sizeConfig = []; - -/** - * @typedef {object} SizeConfig - * - * @property {string} [mediaQuery] A CSS media query string that will to be interpreted by window.matchMedia. If the - * media query matches then the this config will be active and sizesSupported will filter bid and adUnit sizes. If - * this property is not present then this SizeConfig will only be active if triggered manually by a call to - * pbjs.setConfig({labels:['label']) specifying one of the labels present on this SizeConfig. - * @property {Array} sizesSupported The sizes to be accepted if this SizeConfig is enabled. - * @property {Array} labels The active labels to match this SizeConfig to an adUnits and/or bidders. - */ - -/** - * - * @param {Array} config - */ -export function setSizeConfig(config) { - sizeConfig = config; -} -config.getConfig('sizeConfig', config => setSizeConfig(config.sizeConfig)); - -/** - * Returns object describing the status of labels on the adUnit or bidder along with labels passed into requestBids - * @param bidOrAdUnit the bidder or adUnit to get label info on - * @param activeLabels the labels passed to requestBids - * @returns {LabelDescriptor} - */ -export function getLabels(bidOrAdUnit, activeLabels) { - if (bidOrAdUnit.labelAll) { - return {labelAll: true, labels: bidOrAdUnit.labelAll, activeLabels}; - } - return {labelAll: false, labels: bidOrAdUnit.labelAny, activeLabels}; -} - -/** - * Determines whether a single size is valid given configured sizes - * @param {Array} size [width, height] - * @param {Array} configs - * @returns {boolean} - */ -export function sizeSupported(size, configs = sizeConfig) { - let maps = evaluateSizeConfig(configs); - if (!maps.shouldFilter) { - return true; - } - return !!maps.sizesSupported[size]; -} - -/** - * Resolves the unique set of the union of all sizes and labels that are active from a SizeConfig.mediaQuery match - * @param {Array} labels Labels specified on adUnit or bidder - * @param {boolean} labelAll if true, all labels must match to be enabled - * @param {Array} activeLabels Labels passed in through requestBids - * @param {object} mediaTypes A mediaTypes object describing the various media types (banner, video, native) - * @param {Array>} sizes Sizes specified on adUnit (deprecated) - * @param {Array} configs - * @returns {{labels: Array, sizes: Array>}} - */ -export function resolveStatus({labels = [], labelAll = false, activeLabels = []} = {}, mediaTypes, sizes, configs = sizeConfig) { - let maps = evaluateSizeConfig(configs); - - if (!isPlainObject(mediaTypes)) { - // add support for deprecated adUnit.sizes by creating correct banner mediaTypes if they don't already exist - if (sizes) { - mediaTypes = { - banner: { - sizes - } - }; - } else { - mediaTypes = {}; - } - } else { - mediaTypes = deepClone(mediaTypes); - } - - let oldSizes = deepAccess(mediaTypes, 'banner.sizes'); - if (maps.shouldFilter && oldSizes) { - mediaTypes.banner.sizes = oldSizes.filter(size => maps.sizesSupported[size]); - } - - let allMediaTypes = Object.keys(mediaTypes); - - let results = { - active: ( - allMediaTypes.every(type => type !== 'banner') - ) || ( - allMediaTypes.some(type => type === 'banner') && deepAccess(mediaTypes, 'banner.sizes.length') > 0 && ( - labels.length === 0 || ( - (!labelAll && ( - labels.some(label => maps.labels[label]) || - labels.some(label => includes(activeLabels, label)) - )) || - (labelAll && ( - labels.reduce((result, label) => !result ? result : ( - maps.labels[label] || includes(activeLabels, label) - ), true) - )) - ) - ) - ), - mediaTypes - }; - - if (oldSizes && oldSizes.length !== mediaTypes.banner.sizes.length) { - results.filterResults = { - before: oldSizes, - after: mediaTypes.banner.sizes - } - } - - return results; -} - -function evaluateSizeConfig(configs) { - return configs.reduce((results, config) => { - if ( - typeof config === 'object' && - typeof config.mediaQuery === 'string' - ) { - let ruleMatch = false; - - // TODO: (Prebid - 4.0) Remove empty mediaQuery string check. Disallow empty mediaQuery in sizeConfig. - // Refer: https://github.com/prebid/Prebid.js/pull/4691, https://github.com/prebid/Prebid.js/issues/4810 for more details. - if (config.mediaQuery === '') { - ruleMatch = true; - } else { - try { - ruleMatch = getWindowTop().matchMedia(config.mediaQuery).matches; - } catch (e) { - logWarn('Unfriendly iFrame blocks sizeConfig from being correctly evaluated'); - - ruleMatch = matchMedia(config.mediaQuery).matches; - } - } - - if (ruleMatch) { - if (Array.isArray(config.sizesSupported)) { - results.shouldFilter = true; - } - ['labels', 'sizesSupported'].forEach( - type => (config[type] || []).forEach( - thing => results[type][thing] = true - ) - ); - } - } else { - logWarn('sizeConfig rule missing required property "mediaQuery"'); - } - return results; - }, { - labels: {}, - sizesSupported: {}, - shouldFilter: false - }); -} diff --git a/src/storageManager.js b/src/storageManager.js deleted file mode 100644 index 66a0cf68cbf..00000000000 --- a/src/storageManager.js +++ /dev/null @@ -1,316 +0,0 @@ -import {hook} from './hook.js'; -import * as utils from './utils.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -const moduleTypeWhiteList = ['core', 'prebid-module']; - -export let storageCallbacks = []; - -/** - * Storage options - * @typedef {Object} storageOptions - * @property {Number=} gvlid - Vendor id - * @property {string} moduleName - Module name - * @property {string=} moduleType - Module type, value can be anyone of core or prebid-module - */ - -/** - * Returns list of storage related functions with gvlid, module name and module type in its scope. - * All three argument are optional here. Below shows the usage of of these - * - GVL Id: Pass GVL id if you are a vendor - * - Module name: All modules need to pass module name - * - Module type: Some modules may need these functions but are not vendor. e.g prebid core files in src and modules like currency. - * @param {storageOptions} options - */ -export function newStorageManager({gvlid, moduleName, moduleType} = {}) { - function isValid(cb) { - if (includes(moduleTypeWhiteList, moduleType)) { - let result = { - valid: true - } - return cb(result); - } else { - let value; - let hookDetails = { - hasEnforcementHook: false - } - validateStorageEnforcement(gvlid, moduleName, hookDetails, function(result) { - if (result && result.hasEnforcementHook) { - value = cb(result); - } else { - let result = { - hasEnforcementHook: false, - valid: utils.hasDeviceAccess() - } - value = cb(result); - } - }); - return value; - } - } - - /** - * @param {string} key - * @param {string} value - * @param {string} [expires=''] - * @param {string} [sameSite='/'] - * @param {string} [domain] domain (e.g., 'example.com' or 'subdomain.example.com'). - * If not specified, defaults to the host portion of the current document location. - * If a domain is specified, subdomains are always included. - * Domain must match the domain of the JavaScript origin. Setting cookies to foreign domains will be silently ignored. - */ - const setCookie = function (key, value, expires, sameSite, domain, done) { - let cb = function (result) { - if (result && result.valid) { - const domainPortion = (domain && domain !== '') ? ` ;domain=${encodeURIComponent(domain)}` : ''; - const expiresPortion = (expires && expires !== '') ? ` ;expires=${expires}` : ''; - const isNone = (sameSite != null && sameSite.toLowerCase() == 'none') - const secure = (isNone) ? '; Secure' : ''; - document.cookie = `${key}=${encodeURIComponent(value)}${expiresPortion}; path=/${domainPortion}${sameSite ? `; SameSite=${sameSite}` : ''}${secure}`; - } - } - if (done && typeof done === 'function') { - storageCallbacks.push(function() { - let result = isValid(cb); - done(result); - }); - } else { - return isValid(cb); - } - }; - - /** - * @param {string} name - * @returns {(string|null)} - */ - const getCookie = function(name, done) { - let cb = function (result) { - if (result && result.valid) { - let m = window.document.cookie.match('(^|;)\\s*' + name + '\\s*=\\s*([^;]*)\\s*(;|$)'); - return m ? decodeURIComponent(m[2]) : null; - } - return null; - } - if (done && typeof done === 'function') { - storageCallbacks.push(function() { - let result = isValid(cb); - done(result); - }); - } else { - return isValid(cb); - } - }; - - /** - * @returns {boolean} - */ - const localStorageIsEnabled = function (done) { - let cb = function (result) { - if (result && result.valid) { - try { - localStorage.setItem('prebid.cookieTest', '1'); - return localStorage.getItem('prebid.cookieTest') === '1'; - } catch (error) { - } finally { - try { - localStorage.removeItem('prebid.cookieTest'); - } catch (error) {} - } - } - return false; - } - if (done && typeof done === 'function') { - storageCallbacks.push(function() { - let result = isValid(cb); - done(result); - }); - } else { - return isValid(cb); - } - } - - /** - * @returns {boolean} - */ - const cookiesAreEnabled = function (done) { - let cb = function (result) { - if (result && result.valid) { - if (utils.checkCookieSupport()) { - return true; - } - window.document.cookie = 'prebid.cookieTest'; - return window.document.cookie.indexOf('prebid.cookieTest') !== -1; - } - return false; - } - if (done && typeof done === 'function') { - storageCallbacks.push(function() { - let result = isValid(cb); - done(result); - }); - } else { - return isValid(cb); - } - } - - /** - * @param {string} key - * @param {string} value - */ - const setDataInLocalStorage = function (key, value, done) { - let cb = function (result) { - if (result && result.valid && hasLocalStorage()) { - window.localStorage.setItem(key, value); - } - } - if (done && typeof done === 'function') { - storageCallbacks.push(function() { - let result = isValid(cb); - done(result); - }); - } else { - return isValid(cb); - } - } - - /** - * @param {string} key - * @returns {(string|null)} - */ - const getDataFromLocalStorage = function (key, done) { - let cb = function (result) { - if (result && result.valid && hasLocalStorage()) { - return window.localStorage.getItem(key); - } - return null; - } - if (done && typeof done === 'function') { - storageCallbacks.push(function() { - let result = isValid(cb); - done(result); - }); - } else { - return isValid(cb); - } - } - - /** - * @param {string} key - */ - const removeDataFromLocalStorage = function (key, done) { - let cb = function (result) { - if (result && result.valid && hasLocalStorage()) { - window.localStorage.removeItem(key); - } - } - if (done && typeof done === 'function') { - storageCallbacks.push(function() { - let result = isValid(cb); - done(result); - }); - } else { - return isValid(cb); - } - } - - /** - * @returns {boolean} - */ - const hasLocalStorage = function (done) { - let cb = function (result) { - if (result && result.valid) { - try { - return !!window.localStorage; - } catch (e) { - utils.logError('Local storage api disabled'); - } - } - return false; - } - if (done && typeof done === 'function') { - storageCallbacks.push(function() { - let result = isValid(cb); - done(result); - }); - } else { - return isValid(cb); - } - } - - /** - * Returns all cookie values from the jar whose names contain the `keyLike` - * Needs to exist in `utils.js` as it follows the StorageHandler interface defined in live-connect-js. If that module were to be removed, this function can go as well. - * @param {string} keyLike - * @return {[]} - */ - const findSimilarCookies = function(keyLike, done) { - let cb = function (result) { - if (result && result.valid) { - const all = []; - if (utils.hasDeviceAccess()) { - const cookies = document.cookie.split(';'); - while (cookies.length) { - const cookie = cookies.pop(); - let separatorIndex = cookie.indexOf('='); - separatorIndex = separatorIndex < 0 ? cookie.length : separatorIndex; - const cookieName = decodeURIComponent(cookie.slice(0, separatorIndex).replace(/^\s+/, '')); - if (cookieName.indexOf(keyLike) >= 0) { - all.push(decodeURIComponent(cookie.slice(separatorIndex + 1))); - } - } - } - return all; - } - } - - if (done && typeof done === 'function') { - storageCallbacks.push(function() { - let result = isValid(cb); - done(result); - }); - } else { - return isValid(cb); - } - } - - return { - setCookie, - getCookie, - localStorageIsEnabled, - cookiesAreEnabled, - setDataInLocalStorage, - getDataFromLocalStorage, - removeDataFromLocalStorage, - hasLocalStorage, - findSimilarCookies - } -} - -/** - * This hook validates the storage enforcement if gdprEnforcement module is included - */ -export const validateStorageEnforcement = hook('async', function(gvlid, moduleName, hookDetails, callback) { - callback(hookDetails); -}, 'validateStorageEnforcement'); - -/** - * This function returns storage functions to access cookies and localstorage. This function will bypass the gdpr enforcement requirement. Prebid as a software needs to use storage in some scenarios and is not a vendor so GDPR enforcement rules does not apply on Prebid. - * @param {string} moduleName Module name - */ -export function getCoreStorageManager(moduleName) { - return newStorageManager({moduleName: moduleName, moduleType: 'core'}); -} - -/** - * Note: Core modules or Prebid modules like Currency, SizeMapping should use getCoreStorageManager - * This function returns storage functions to access cookies and localstorage. Bidders and User id modules should import this and use it in their module if needed. GVL ID and Module name are optional param but gvl id is needed for when gdpr enforcement module is used. - * @param {Number=} gvlid Vendor id - * @param {string=} moduleName BidderCode or module name - */ -export function getStorageManager(gvlid, moduleName) { - return newStorageManager({gvlid: gvlid, moduleName: moduleName}); -} - -export function resetData() { - storageCallbacks = []; -} diff --git a/src/targeting.js b/src/targeting.js deleted file mode 100644 index 365453e1e8f..00000000000 --- a/src/targeting.js +++ /dev/null @@ -1,651 +0,0 @@ -import { uniques, isGptPubadsDefined, getHighestCpm, getOldestHighestCpmBid, groupBy, isAdUnitCodeMatchingSlot, timestamp, deepAccess, deepClone, logError, logWarn, logInfo } from './utils.js'; -import { config } from './config.js'; -import { NATIVE_TARGETING_KEYS } from './native.js'; -import { auctionManager } from './auctionManager.js'; -import { sizeSupported } from './sizeMapping.js'; -import { ADPOD } from './mediaTypes.js'; -import { hook } from './hook.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import find from 'core-js-pure/features/array/find.js'; - -const utils = require('./utils.js'); -var CONSTANTS = require('./constants.json'); - -var pbTargetingKeys = []; - -const MAX_DFP_KEYLENGTH = 20; -const TTL_BUFFER = 1000; - -export const TARGETING_KEYS = Object.keys(CONSTANTS.TARGETING_KEYS).map( - key => CONSTANTS.TARGETING_KEYS[key] -); - -// return unexpired bids -const isBidNotExpired = (bid) => (bid.responseTimestamp + bid.ttl * 1000 - TTL_BUFFER) > timestamp(); - -// return bids whose status is not set. Winning bids can only have a status of `rendered`. -const isUnusedBid = (bid) => bid && ((bid.status && !includes([CONSTANTS.BID_STATUS.RENDERED], bid.status)) || !bid.status); - -export let filters = { - isBidNotExpired, - isUnusedBid -}; - -// If two bids are found for same adUnitCode, we will use the highest one to take part in auction -// This can happen in case of concurrent auctions -// If adUnitBidLimit is set above 0 return top N number of bids -export const getHighestCpmBidsFromBidPool = hook('sync', function(bidsReceived, highestCpmCallback, adUnitBidLimit = 0, hasModified = false) { - if (!hasModified) { - const bids = []; - const dealPrioritization = config.getConfig('sendBidsControl.dealPrioritization'); - // bucket by adUnitcode - let buckets = groupBy(bidsReceived, 'adUnitCode'); - // filter top bid for each bucket by bidder - Object.keys(buckets).forEach(bucketKey => { - let bucketBids = []; - let bidsByBidder = groupBy(buckets[bucketKey], 'bidderCode'); - Object.keys(bidsByBidder).forEach(key => bucketBids.push(bidsByBidder[key].reduce(highestCpmCallback))); - // if adUnitBidLimit is set, pass top N number bids - if (adUnitBidLimit > 0) { - bucketBids = dealPrioritization ? bucketBids.sort(sortByDealAndPriceBucketOrCpm(true)) : bucketBids.sort((a, b) => b.cpm - a.cpm); - bids.push(...bucketBids.slice(0, adUnitBidLimit)); - } else { - bids.push(...bucketBids); - } - }); - - return bids; - } - - return bidsReceived; -}) - -/** -* A descending sort function that will sort the list of objects based on the following two dimensions: -* - bids with a deal are sorted before bids w/o a deal -* - then sort bids in each grouping based on the hb_pb value -* eg: the following list of bids would be sorted like: -* [{ -* "hb_adid": "vwx", -* "hb_pb": "28", -* "hb_deal": "7747" -* }, { -* "hb_adid": "jkl", -* "hb_pb": "10", -* "hb_deal": "9234" -* }, { -* "hb_adid": "stu", -* "hb_pb": "50" -* }, { -* "hb_adid": "def", -* "hb_pb": "2" -* }] -*/ -export function sortByDealAndPriceBucketOrCpm(useCpm = false) { - return function(a, b) { - if (a.adserverTargeting.hb_deal !== undefined && b.adserverTargeting.hb_deal === undefined) { - return -1; - } - - if ((a.adserverTargeting.hb_deal === undefined && b.adserverTargeting.hb_deal !== undefined)) { - return 1; - } - - // assuming both values either have a deal or don't have a deal - sort by the hb_pb param - if (useCpm) { - return b.cpm - a.cpm; - } - - return b.adserverTargeting.hb_pb - a.adserverTargeting.hb_pb; - } -} - -/** - * @typedef {Object.} targeting - * @property {string} targeting_key - */ - -/** - * @typedef {Object.[]>[]} targetingArray - */ - -export function newTargeting(auctionManager) { - let targeting = {}; - let latestAuctionForAdUnit = {}; - - targeting.setLatestAuctionForAdUnit = function(adUnitCode, auctionId) { - latestAuctionForAdUnit[adUnitCode] = auctionId; - }; - - targeting.resetPresetTargeting = function(adUnitCode, customSlotMatching) { - if (isGptPubadsDefined()) { - const adUnitCodes = getAdUnitCodes(adUnitCode); - const adUnits = auctionManager.getAdUnits().filter(adUnit => includes(adUnitCodes, adUnit.code)); - window.googletag.pubads().getSlots().forEach(slot => { - let customSlotMatchingFunc = utils.isFn(customSlotMatching) && customSlotMatching(slot); - pbTargetingKeys.forEach(function(key) { - // reset only registered adunits - adUnits.forEach(function(unit) { - if (unit.code === slot.getAdUnitPath() || - unit.code === slot.getSlotElementId() || - (utils.isFn(customSlotMatchingFunc) && customSlotMatchingFunc(unit.code))) { - slot.setTargeting(key, null); - } - }); - }); - }); - } - }; - - targeting.resetPresetTargetingAST = function(adUnitCode) { - const adUnitCodes = getAdUnitCodes(adUnitCode); - adUnitCodes.forEach(function(unit) { - const astTag = window.apntag.getTag(unit); - if (astTag && astTag.keywords) { - const currentKeywords = Object.keys(astTag.keywords); - const newKeywords = {}; - currentKeywords.forEach((key) => { - if (!includes(pbTargetingKeys, key.toLowerCase())) { - newKeywords[key] = astTag.keywords[key]; - } - }) - window.apntag.modifyTag(unit, { keywords: newKeywords }) - } - }); - }; - - /** - * checks if bid has targeting set and belongs based on matching ad unit codes - * @return {boolean} true or false - */ - function bidShouldBeAddedToTargeting(bid, adUnitCodes) { - return bid.adserverTargeting && adUnitCodes && - ((utils.isArray(adUnitCodes) && includes(adUnitCodes, bid.adUnitCode)) || - (typeof adUnitCodes === 'string' && bid.adUnitCode === adUnitCodes)); - }; - - /** - * Returns targeting for any bids which have deals if alwaysIncludeDeals === true - */ - function getDealBids(adUnitCodes, bidsReceived) { - if (config.getConfig('targetingControls.alwaysIncludeDeals') === true) { - const standardKeys = TARGETING_KEYS.concat(NATIVE_TARGETING_KEYS); - - // we only want the top bid from bidders who have multiple entries per ad unit code - const bids = getHighestCpmBidsFromBidPool(bidsReceived, getHighestCpm); - - // populate targeting keys for the remaining bids if they have a dealId - return bids.map(bid => { - if (bid.dealId && bidShouldBeAddedToTargeting(bid, adUnitCodes)) { - return { - [bid.adUnitCode]: getTargetingMap(bid, standardKeys.filter( - key => typeof bid.adserverTargeting[key] !== 'undefined') - ) - }; - } - }).filter(bid => bid); // removes empty elements in array - } - return []; - }; - - /** - * Returns filtered ad server targeting for custom and allowed keys. - * @param {targetingArray} targeting - * @param {string[]} allowedKeys - * @return {targetingArray} filtered targeting - */ - function getAllowedTargetingKeyValues(targeting, allowedKeys) { - const defaultKeyring = Object.assign({}, CONSTANTS.TARGETING_KEYS, CONSTANTS.NATIVE_KEYS); - const defaultKeys = Object.keys(defaultKeyring); - const keyDispositions = {}; - logInfo(`allowTargetingKeys - allowed keys [ ${allowedKeys.map(k => defaultKeyring[k]).join(', ')} ]`); - targeting.map(adUnit => { - const adUnitCode = Object.keys(adUnit)[0]; - const keyring = adUnit[adUnitCode]; - const keys = keyring.filter(kvPair => { - const key = Object.keys(kvPair)[0]; - // check if key is in default keys, if not, it's custom, we won't remove it. - const isCustom = defaultKeys.filter(defaultKey => key.indexOf(defaultKeyring[defaultKey]) === 0).length === 0; - // check if key explicitly allowed, if not, we'll remove it. - const found = isCustom || find(allowedKeys, allowedKey => { - const allowedKeyName = defaultKeyring[allowedKey]; - // we're looking to see if the key exactly starts with one of our default keys. - // (which hopefully means it's not custom) - const found = key.indexOf(allowedKeyName) === 0; - return found; - }); - keyDispositions[key] = !found; - return found; - }); - adUnit[adUnitCode] = keys; - }); - const removedKeys = Object.keys(keyDispositions).filter(d => keyDispositions[d]); - logInfo(`allowTargetingKeys - removed keys [ ${removedKeys.join(', ')} ]`); - // remove any empty targeting objects, as they're unnecessary. - const filteredTargeting = targeting.filter(adUnit => { - const adUnitCode = Object.keys(adUnit)[0]; - const keyring = adUnit[adUnitCode]; - return keyring.length > 0; - }); - return filteredTargeting - } - - /** - * Returns all ad server targeting for all ad units. - * @param {string=} adUnitCode - * @return {Object.} targeting - */ - targeting.getAllTargeting = function(adUnitCode, bidsReceived = getBidsReceived()) { - const adUnitCodes = getAdUnitCodes(adUnitCode); - - // Get targeting for the winning bid. Add targeting for any bids that have - // `alwaysUseBid=true`. If sending all bids is enabled, add targeting for losing bids. - var targeting = getWinningBidTargeting(adUnitCodes, bidsReceived) - .concat(getCustomBidTargeting(adUnitCodes, bidsReceived)) - .concat(config.getConfig('enableSendAllBids') ? getBidLandscapeTargeting(adUnitCodes, bidsReceived) : getDealBids(adUnitCodes, bidsReceived)) - .concat(getAdUnitTargeting(adUnitCodes)); - - // store a reference of the targeting keys - targeting.map(adUnitCode => { - Object.keys(adUnitCode).map(key => { - adUnitCode[key].map(targetKey => { - if (pbTargetingKeys.indexOf(Object.keys(targetKey)[0]) === -1) { - pbTargetingKeys = Object.keys(targetKey).concat(pbTargetingKeys); - } - }); - }); - }); - - const defaultKeys = Object.keys(Object.assign({}, CONSTANTS.DEFAULT_TARGETING_KEYS, CONSTANTS.NATIVE_KEYS)); - const allowedKeys = config.getConfig('targetingControls.allowTargetingKeys') || defaultKeys; - if (Array.isArray(allowedKeys) && allowedKeys.length > 0) { - targeting = getAllowedTargetingKeyValues(targeting, allowedKeys); - } - - targeting = flattenTargeting(targeting); - - const auctionKeysThreshold = config.getConfig('targetingControls.auctionKeyMaxChars'); - if (auctionKeysThreshold) { - logInfo(`Detected 'targetingControls.auctionKeyMaxChars' was active for this auction; set with a limit of ${auctionKeysThreshold} characters. Running checks on auction keys...`); - targeting = filterTargetingKeys(targeting, auctionKeysThreshold); - } - - // make sure at least there is a entry per adUnit code in the targetingSet so receivers of SET_TARGETING call's can know what ad units are being invoked - adUnitCodes.forEach(code => { - if (!targeting[code]) { - targeting[code] = {}; - } - }); - - return targeting; - }; - - // create an encoded string variant based on the keypairs of the provided object - // - note this will encode the characters between the keys (ie = and &) - function convertKeysToQueryForm(keyMap) { - return Object.keys(keyMap).reduce(function (queryString, key) { - let encodedKeyPair = `${key}%3d${encodeURIComponent(keyMap[key])}%26`; - return queryString += encodedKeyPair; - }, ''); - } - - function filterTargetingKeys(targeting, auctionKeysThreshold) { - // read each targeting.adUnit object and sort the adUnits into a list of adUnitCodes based on priorization setting (eg CPM) - let targetingCopy = deepClone(targeting); - - let targetingMap = Object.keys(targetingCopy).map(adUnitCode => { - return { - adUnitCode, - adserverTargeting: targetingCopy[adUnitCode] - }; - }).sort(sortByDealAndPriceBucketOrCpm()); - - // iterate through the targeting based on above list and transform the keys into the query-equivalent and count characters - return targetingMap.reduce(function (accMap, currMap, index, arr) { - let adUnitQueryString = convertKeysToQueryForm(currMap.adserverTargeting); - - // for the last adUnit - trim last encoded ampersand from the converted query string - if ((index + 1) === arr.length) { - adUnitQueryString = adUnitQueryString.slice(0, -3); - } - - // if under running threshold add to result - let code = currMap.adUnitCode; - let querySize = adUnitQueryString.length; - if (querySize <= auctionKeysThreshold) { - auctionKeysThreshold -= querySize; - logInfo(`AdUnit '${code}' auction keys comprised of ${querySize} characters. Deducted from running threshold; new limit is ${auctionKeysThreshold}`, targetingCopy[code]); - - accMap[code] = targetingCopy[code]; - } else { - logWarn(`The following keys for adUnitCode '${code}' exceeded the current limit of the 'auctionKeyMaxChars' setting.\nThe key-set size was ${querySize}, the current allotted amount was ${auctionKeysThreshold}.\n`, targetingCopy[code]); - } - - if ((index + 1) === arr.length && Object.keys(accMap).length === 0) { - logError('No auction targeting keys were permitted due to the setting in setConfig(targetingControls.auctionKeyMaxChars). Please review setup and consider adjusting.'); - } - return accMap; - }, {}); - } - - /** - * Converts targeting array and flattens to make it easily iteratable - * e.g: Sample input to this function - * ``` - * [ - * { - * "div-gpt-ad-1460505748561-0": [{"hb_bidder": ["appnexusAst"]}] - * }, - * { - * "div-gpt-ad-1460505748561-0": [{"hb_bidder_appnexusAs": ["appnexusAst"]}] - * } - * ] - * ``` - * Resulting array - * ``` - * { - * "div-gpt-ad-1460505748561-0": { - * "hb_bidder": "appnexusAst", - * "hb_bidder_appnexusAs": "appnexusAst" - * } - * } - * ``` - * - * @param {targetingArray} targeting - * @return {Object.} targeting - */ - function flattenTargeting(targeting) { - let targetingObj = targeting.map(targeting => { - return { - [Object.keys(targeting)[0]]: targeting[Object.keys(targeting)[0]] - .map(target => { - return { - [Object.keys(target)[0]]: target[Object.keys(target)[0]].join(', ') - }; - }).reduce((p, c) => Object.assign(c, p), {}) - }; - }).reduce(function (accumulator, targeting) { - var key = Object.keys(targeting)[0]; - accumulator[key] = Object.assign({}, accumulator[key], targeting[key]); - return accumulator; - }, {}); - return targetingObj; - } - - /** - * Sets targeting for DFP - * @param {Object.>} targetingConfig - */ - targeting.setTargetingForGPT = function(targetingConfig, customSlotMatching) { - window.googletag.pubads().getSlots().forEach(slot => { - Object.keys(targetingConfig).filter(customSlotMatching ? customSlotMatching(slot) : isAdUnitCodeMatchingSlot(slot)) - .forEach(targetId => - Object.keys(targetingConfig[targetId]).forEach(key => { - let valueArr = targetingConfig[targetId][key]; - if (typeof valueArr === 'string') { - valueArr = valueArr.split(','); - } - valueArr = (valueArr.length > 1) ? [valueArr] : valueArr; - valueArr.map((value) => { - utils.logMessage(`Attempting to set key value for slot: ${slot.getSlotElementId()} key: ${key} value: ${value}`); - return value; - }).forEach(value => { - slot.setTargeting(key, value); - }); - }) - ) - }) - }; - - /** - * normlizes input to a `adUnit.code` array - * @param {(string|string[])} adUnitCode [description] - * @return {string[]} AdUnit code array - */ - function getAdUnitCodes(adUnitCode) { - if (typeof adUnitCode === 'string') { - return [adUnitCode]; - } else if (utils.isArray(adUnitCode)) { - return adUnitCode; - } - return auctionManager.getAdUnitCodes() || []; - } - - function getBidsReceived() { - let bidsReceived = auctionManager.getBidsReceived(); - - if (!config.getConfig('useBidCache')) { - bidsReceived = bidsReceived.filter(bid => latestAuctionForAdUnit[bid.adUnitCode] === bid.auctionId) - } - - bidsReceived = bidsReceived - .filter(bid => deepAccess(bid, 'video.context') !== ADPOD) - .filter(bid => bid.mediaType !== 'banner' || sizeSupported([bid.width, bid.height])) - .filter(filters.isUnusedBid) - .filter(filters.isBidNotExpired) - ; - - return getHighestCpmBidsFromBidPool(bidsReceived, getOldestHighestCpmBid); - } - - /** - * Returns top bids for a given adUnit or set of adUnits. - * @param {(string|string[])} adUnitCode adUnitCode or array of adUnitCodes - * @return {[type]} [description] - */ - targeting.getWinningBids = function(adUnitCode, bidsReceived = getBidsReceived()) { - const adUnitCodes = getAdUnitCodes(adUnitCode); - return bidsReceived - .filter(bid => includes(adUnitCodes, bid.adUnitCode)) - .filter(bid => bid.cpm > 0) - .map(bid => bid.adUnitCode) - .filter(uniques) - .map(adUnitCode => bidsReceived - .filter(bid => bid.adUnitCode === adUnitCode ? bid : null) - .reduce(getHighestCpm)); - }; - - /** - * @param {(string|string[])} adUnitCode adUnitCode or array of adUnitCodes - * Sets targeting for AST - */ - targeting.setTargetingForAst = function(adUnitCodes) { - let astTargeting = targeting.getAllTargeting(adUnitCodes); - - try { - targeting.resetPresetTargetingAST(adUnitCodes); - } catch (e) { - utils.logError('unable to reset targeting for AST' + e) - } - - Object.keys(astTargeting).forEach(targetId => - Object.keys(astTargeting[targetId]).forEach(key => { - utils.logMessage(`Attempting to set targeting for targetId: ${targetId} key: ${key} value: ${astTargeting[targetId][key]}`); - // setKeywords supports string and array as value - if (utils.isStr(astTargeting[targetId][key]) || utils.isArray(astTargeting[targetId][key])) { - let keywordsObj = {}; - let regex = /pt[0-9]/; - if (key.search(regex) < 0) { - keywordsObj[key.toUpperCase()] = astTargeting[targetId][key]; - } else { - // pt${n} keys should not be uppercased - keywordsObj[key] = astTargeting[targetId][key]; - } - window.apntag.setKeywords(targetId, keywordsObj, { overrideKeyValue: true }); - } - }) - ); - }; - - /** - * Get targeting key value pairs for winning bid. - * @param {string[]} AdUnit code array - * @return {targetingArray} winning bids targeting - */ - function getWinningBidTargeting(adUnitCodes, bidsReceived) { - let winners = targeting.getWinningBids(adUnitCodes, bidsReceived); - let standardKeys = getStandardKeys(); - - winners = winners.map(winner => { - return { - [winner.adUnitCode]: Object.keys(winner.adserverTargeting) - .filter(key => - typeof winner.sendStandardTargeting === 'undefined' || - winner.sendStandardTargeting || - standardKeys.indexOf(key) === -1) - .reduce((acc, key) => { - const targetingValue = [winner.adserverTargeting[key]]; - const targeting = { [key.substring(0, MAX_DFP_KEYLENGTH)]: targetingValue }; - if (key === CONSTANTS.TARGETING_KEYS.DEAL) { - const bidderCodeTargetingKey = `${key}_${winner.bidderCode}`.substring(0, MAX_DFP_KEYLENGTH); - const bidderCodeTargeting = { [bidderCodeTargetingKey]: targetingValue }; - return [...acc, targeting, bidderCodeTargeting]; - } - return [...acc, targeting]; - }, []) - }; - }); - - return winners; - } - - function getStandardKeys() { - return auctionManager.getStandardBidderAdServerTargeting() // in case using a custom standard key set - .map(targeting => targeting.key) - .concat(TARGETING_KEYS).filter(uniques); // standard keys defined in the library. - } - - /** - * Merge custom adserverTargeting with same key name for same adUnitCode. - * e.g: Appnexus defining custom keyvalue pair foo:bar and Rubicon defining custom keyvalue pair foo:baz will be merged to foo: ['bar','baz'] - * - * @param {Object[]} acc Accumulator for reducer. It will store updated bidResponse objects - * @param {Object} bid BidResponse - * @param {number} index current index - * @param {Array} arr original array - */ - function mergeAdServerTargeting(acc, bid, index, arr) { - function concatTargetingValue(key) { - return function(currentBidElement) { - if (!utils.isArray(currentBidElement.adserverTargeting[key])) { - currentBidElement.adserverTargeting[key] = [currentBidElement.adserverTargeting[key]]; - } - currentBidElement.adserverTargeting[key] = currentBidElement.adserverTargeting[key].concat(bid.adserverTargeting[key]).filter(uniques); - delete bid.adserverTargeting[key]; - } - } - - function hasSameAdunitCodeAndKey(key) { - return function(currentBidElement) { - return currentBidElement.adUnitCode === bid.adUnitCode && currentBidElement.adserverTargeting[key] - } - } - - Object.keys(bid.adserverTargeting) - .filter(getCustomKeys()) - .forEach(key => { - if (acc.length) { - acc.filter(hasSameAdunitCodeAndKey(key)) - .forEach(concatTargetingValue(key)); - } - }); - acc.push(bid); - return acc; - } - - function getCustomKeys() { - let standardKeys = getStandardKeys().concat(NATIVE_TARGETING_KEYS); - return function(key) { - return standardKeys.indexOf(key) === -1; - } - } - - function truncateCustomKeys(bid) { - return { - [bid.adUnitCode]: Object.keys(bid.adserverTargeting) - // Get only the non-standard keys of the losing bids, since we - // don't want to override the standard keys of the winning bid. - .filter(getCustomKeys()) - .map(key => { - return { - [key.substring(0, MAX_DFP_KEYLENGTH)]: [bid.adserverTargeting[key]] - }; - }) - } - } - - /** - * Get custom targeting key value pairs for bids. - * @param {string[]} AdUnit code array - * @return {targetingArray} bids with custom targeting defined in bidderSettings - */ - function getCustomBidTargeting(adUnitCodes, bidsReceived) { - return bidsReceived - .filter(bid => includes(adUnitCodes, bid.adUnitCode)) - .map(bid => Object.assign({}, bid)) - .reduce(mergeAdServerTargeting, []) - .map(truncateCustomKeys) - .filter(bid => bid); // removes empty elements in array; - } - - /** - * Get targeting key value pairs for non-winning bids. - * @param {string[]} AdUnit code array - * @return {targetingArray} all non-winning bids targeting - */ - function getBidLandscapeTargeting(adUnitCodes, bidsReceived) { - const standardKeys = TARGETING_KEYS.concat(NATIVE_TARGETING_KEYS); - const adUnitBidLimit = config.getConfig('sendBidsControl.bidLimit'); - const bids = getHighestCpmBidsFromBidPool(bidsReceived, getHighestCpm, adUnitBidLimit); - - // populate targeting keys for the remaining bids - return bids.map(bid => { - if (bidShouldBeAddedToTargeting(bid, adUnitCodes)) { - return { - [bid.adUnitCode]: getTargetingMap(bid, standardKeys.filter( - key => typeof bid.adserverTargeting[key] !== 'undefined') - ) - }; - } - }).filter(bid => bid); // removes empty elements in array - } - - function getTargetingMap(bid, keys) { - return keys.map(key => { - return { - [`${key}_${bid.bidderCode}`.substring(0, MAX_DFP_KEYLENGTH)]: [bid.adserverTargeting[key]] - }; - }); - } - - function getAdUnitTargeting(adUnitCodes) { - function getTargetingObj(adUnit) { - return deepAccess(adUnit, CONSTANTS.JSON_MAPPING.ADSERVER_TARGETING); - } - - function getTargetingValues(adUnit) { - const aut = getTargetingObj(adUnit); - - return Object.keys(aut) - .map(function(key) { - return {[key]: utils.isArray(aut[key]) ? aut[key] : aut[key].split(',')}; - }); - } - - return auctionManager.getAdUnits() - .filter(adUnit => includes(adUnitCodes, adUnit.code) && getTargetingObj(adUnit)) - .map(adUnit => { - return {[adUnit.code]: getTargetingValues(adUnit)} - }); - } - - targeting.isApntagDefined = function() { - if (window.apntag && utils.isFn(window.apntag.setKeywords)) { - return true; - } - }; - - return targeting; -} - -export const targeting = newTargeting(auctionManager); diff --git a/src/userSync.js b/src/userSync.js deleted file mode 100644 index f653880fa29..00000000000 --- a/src/userSync.js +++ /dev/null @@ -1,327 +0,0 @@ -import * as utils from './utils.js'; -import { config } from './config.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import { getCoreStorageManager } from './storageManager.js'; - -export const USERSYNC_DEFAULT_CONFIG = { - syncEnabled: true, - filterSettings: { - image: { - bidders: '*', - filter: 'include' - } - }, - syncsPerBidder: 5, - syncDelay: 3000, - auctionDelay: 0 -}; - -// Set userSync default values -config.setDefaults({ - 'userSync': utils.deepClone(USERSYNC_DEFAULT_CONFIG) -}); - -const storage = getCoreStorageManager('usersync'); - -/** - * Factory function which creates a new UserSyncPool. - * - * @param {UserSyncDependencies} userSyncDependencies Configuration options and dependencies which the - * UserSync object needs in order to behave properly. - */ -export function newUserSync(userSyncDependencies) { - let publicApi = {}; - // A queue of user syncs for each adapter - // Let getDefaultQueue() set the defaults - let queue = getDefaultQueue(); - - // Whether or not user syncs have been trigger on this page load for a specific bidder - let hasFiredBidder = new Set(); - // How many bids for each adapter - let numAdapterBids = {}; - - // for now - default both to false in case filterSettings config is absent/misconfigured - let permittedPixels = { - image: true, - iframe: false - }; - - // Use what is in config by default - let usConfig = userSyncDependencies.config; - // Update if it's (re)set - config.getConfig('userSync', (conf) => { - // Added this logic for https://github.com/prebid/Prebid.js/issues/4864 - // if userSync.filterSettings does not contain image/all configs, merge in default image config to ensure image pixels are fired - if (conf.userSync) { - let fs = conf.userSync.filterSettings; - if (utils.isPlainObject(fs)) { - if (!fs.image && !fs.all) { - conf.userSync.filterSettings.image = { - bidders: '*', - filter: 'include' - }; - } - } - } - - usConfig = Object.assign(usConfig, conf.userSync); - }); - - /** - * @function getDefaultQueue - * @summary Returns the default empty queue - * @private - * @return {object} A queue with no syncs - */ - function getDefaultQueue() { - return { - image: [], - iframe: [] - }; - } - - /** - * @function fireSyncs - * @summary Trigger all user syncs in the queue - * @private - */ - function fireSyncs() { - if (!usConfig.syncEnabled || !userSyncDependencies.browserSupportsCookies) { - return; - } - - try { - // Image pixels - fireImagePixels(); - // Iframe syncs - loadIframes(); - } catch (e) { - return utils.logError('Error firing user syncs', e); - } - // Reset the user sync queue - queue = getDefaultQueue(); - } - - function forEachFire(queue, fn) { - // Randomize the order of the pixels before firing - // This is to avoid giving any bidder who has registered multiple syncs - // any preferential treatment and balancing them out - utils.shuffle(queue).forEach((sync) => { - fn(sync); - hasFiredBidder.add(sync[0]); - }); - } - - /** - * @function fireImagePixels - * @summary Loops through user sync pixels and fires each one - * @private - */ - function fireImagePixels() { - if (!permittedPixels.image) { - return; - } - forEachFire(queue.image, (sync) => { - let [bidderName, trackingPixelUrl] = sync; - utils.logMessage(`Invoking image pixel user sync for bidder: ${bidderName}`); - // Create image object and add the src url - utils.triggerPixel(trackingPixelUrl); - }); - } - - /** - * @function loadIframes - * @summary Loops through iframe syncs and loads an iframe element into the page - * @private - */ - function loadIframes() { - if (!(permittedPixels.iframe)) { - return; - } - forEachFire(queue.iframe, (sync) => { - let [bidderName, iframeUrl] = sync; - utils.logMessage(`Invoking iframe user sync for bidder: ${bidderName}`); - // Insert iframe into DOM - utils.insertUserSyncIframe(iframeUrl); - }); - } - - /** - * @function incrementAdapterBids - * @summary Increment the count of user syncs queue for the adapter - * @private - * @params {object} numAdapterBids The object contain counts for all adapters - * @params {string} bidder The name of the bidder adding a sync - * @returns {object} The updated version of numAdapterBids - */ - function incrementAdapterBids(numAdapterBids, bidder) { - if (!numAdapterBids[bidder]) { - numAdapterBids[bidder] = 1; - } else { - numAdapterBids[bidder] += 1; - } - return numAdapterBids; - } - - /** - * @function registerSync - * @summary Add sync for this bidder to a queue to be fired later - * @public - * @params {string} type The type of the sync including image, iframe - * @params {string} bidder The name of the adapter. e.g. "rubicon" - * @params {string} url Either the pixel url or iframe url depending on the type - - * @example Using Image Sync - * // registerSync(type, adapter, pixelUrl) - * userSync.registerSync('image', 'rubicon', 'http://example.com/pixel') - */ - publicApi.registerSync = (type, bidder, url) => { - if (hasFiredBidder.has(bidder)) { - return utils.logMessage(`already fired syncs for "${bidder}", ignoring registerSync call`); - } - if (!usConfig.syncEnabled || !utils.isArray(queue[type])) { - return utils.logWarn(`User sync type "${type}" not supported`); - } - if (!bidder) { - return utils.logWarn(`Bidder is required for registering sync`); - } - if (usConfig.syncsPerBidder !== 0 && Number(numAdapterBids[bidder]) >= usConfig.syncsPerBidder) { - return utils.logWarn(`Number of user syncs exceeded for "${bidder}"`); - } - - const canBidderRegisterSync = publicApi.canBidderRegisterSync(type, bidder); - if (!canBidderRegisterSync) { - return utils.logWarn(`Bidder "${bidder}" not permitted to register their "${type}" userSync pixels.`); - } - - // the bidder's pixel has passed all checks and is allowed to register - queue[type].push([bidder, url]); - numAdapterBids = incrementAdapterBids(numAdapterBids, bidder); - }; - - /** - * @function shouldBidderBeBlocked - * @summary Check filterSettings logic to determine if the bidder should be prevented from registering their userSync tracker - * @private - * @param {string} type The type of the sync; either image or iframe - * @param {string} bidder The name of the adapter. e.g. "rubicon" - * @returns {boolean} true => bidder is not allowed to register; false => bidder can register - */ - function shouldBidderBeBlocked(type, bidder) { - let filterConfig = usConfig.filterSettings; - - // apply the filter check if the config object is there (eg filterSettings.iframe exists) and if the config object is properly setup - if (isFilterConfigValid(filterConfig, type)) { - permittedPixels[type] = true; - - let activeConfig = (filterConfig.all) ? filterConfig.all : filterConfig[type]; - let biddersToFilter = (activeConfig.bidders === '*') ? [bidder] : activeConfig.bidders; - let filterType = activeConfig.filter || 'include'; // set default if undefined - - // return true if the bidder is either: not part of the include (ie outside the whitelist) or part of the exclude (ie inside the blacklist) - const checkForFiltering = { - 'include': (bidders, bidder) => !includes(bidders, bidder), - 'exclude': (bidders, bidder) => includes(bidders, bidder) - } - return checkForFiltering[filterType](biddersToFilter, bidder); - } - return !permittedPixels[type]; - } - - /** - * @function isFilterConfigValid - * @summary Check if the filterSettings object in the userSync config is setup properly - * @private - * @param {object} filterConfig sub-config object taken from filterSettings - * @param {string} type The type of the sync; either image or iframe - * @returns {boolean} true => config is setup correctly, false => setup incorrectly or filterConfig[type] is not present - */ - function isFilterConfigValid(filterConfig, type) { - if (filterConfig.all && filterConfig[type]) { - utils.logWarn(`Detected presence of the "filterSettings.all" and "filterSettings.${type}" in userSync config. You cannot mix "all" with "iframe/image" configs; they are mutually exclusive.`); - return false; - } - - let activeConfig = (filterConfig.all) ? filterConfig.all : filterConfig[type]; - let activeConfigName = (filterConfig.all) ? 'all' : type; - - // if current pixel type isn't part of the config's logic, skip rest of the config checks... - // we return false to skip subsequent filter checks in shouldBidderBeBlocked() function - if (!activeConfig) { - return false; - } - - let filterField = activeConfig.filter; - let biddersField = activeConfig.bidders; - - if (filterField && filterField !== 'include' && filterField !== 'exclude') { - utils.logWarn(`UserSync "filterSettings.${activeConfigName}.filter" setting '${filterField}' is not a valid option; use either 'include' or 'exclude'.`); - return false; - } - - if (biddersField !== '*' && !(Array.isArray(biddersField) && biddersField.length > 0 && biddersField.every(bidderInList => utils.isStr(bidderInList) && bidderInList !== '*'))) { - utils.logWarn(`Detected an invalid setup in userSync "filterSettings.${activeConfigName}.bidders"; use either '*' (to represent all bidders) or an array of bidders.`); - return false; - } - - return true; - } - - /** - * @function syncUsers - * @summary Trigger all the user syncs based on publisher-defined timeout - * @public - * @params {int} timeout The delay in ms before syncing data - default 0 - */ - publicApi.syncUsers = (timeout = 0) => { - if (timeout) { - return setTimeout(fireSyncs, Number(timeout)); - } - fireSyncs(); - }; - - /** - * @function triggerUserSyncs - * @summary A `syncUsers` wrapper for determining if enableOverride has been turned on - * @public - */ - publicApi.triggerUserSyncs = () => { - if (usConfig.enableOverride) { - publicApi.syncUsers(); - } - }; - - publicApi.canBidderRegisterSync = (type, bidder) => { - if (usConfig.filterSettings) { - if (shouldBidderBeBlocked(type, bidder)) { - return false; - } - } - return true; - } - return publicApi; -} - -const browserSupportsCookies = !utils.isSafariBrowser() && storage.cookiesAreEnabled(); - -export const userSync = newUserSync({ - config: config.getConfig('userSync'), - browserSupportsCookies: browserSupportsCookies -}); - -/** - * @typedef {Object} UserSyncDependencies - * - * @property {UserSyncConfig} config - * @property {boolean} browserSupportsCookies True if the current browser supports cookies, and false otherwise. - */ - -/** - * @typedef {Object} UserSyncConfig - * - * @property {boolean} enableOverride - * @property {boolean} syncEnabled - * @property {int} syncsPerBidder - * @property {string[]} enabledBidders - * @property {Object} filterSettings - */ diff --git a/src/utils.js b/src/utils.js deleted file mode 100644 index 35ce3e7d0dd..00000000000 --- a/src/utils.js +++ /dev/null @@ -1,1290 +0,0 @@ -/* eslint-disable no-console */ -import { config } from './config.js'; -import clone from 'just-clone'; -import find from 'core-js-pure/features/array/find.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -const CONSTANTS = require('./constants.json'); - -export { default as deepAccess } from 'dlv/index.js'; -export { default as deepSetValue } from 'dset'; - -var tArr = 'Array'; -var tStr = 'String'; -var tFn = 'Function'; -var tNumb = 'Number'; -var tObject = 'Object'; -var tBoolean = 'Boolean'; -var toString = Object.prototype.toString; -let consoleExists = Boolean(window.console); -let consoleLogExists = Boolean(consoleExists && window.console.log); -let consoleInfoExists = Boolean(consoleExists && window.console.info); -let consoleWarnExists = Boolean(consoleExists && window.console.warn); -let consoleErrorExists = Boolean(consoleExists && window.console.error); -var events = require('./events.js'); - -// this allows stubbing of utility functions that are used internally by other utility functions -export const internal = { - checkCookieSupport, - createTrackPixelIframeHtml, - getWindowSelf, - getWindowTop, - getWindowLocation, - insertUserSyncIframe, - insertElement, - isFn, - triggerPixel, - logError, - logWarn, - logMessage, - logInfo, - parseQS, - formatQS, - deepEqual -}; - -let prebidInternal = {} -/** - * Returns object that is used as internal prebid namespace - */ -export function getPrebidInternal() { - return prebidInternal; -} - -var uniqueRef = {}; -export let bind = function(a, b) { return b; }.bind(null, 1, uniqueRef)() === uniqueRef - ? Function.prototype.bind - : function(bind) { - var self = this; - var args = Array.prototype.slice.call(arguments, 1); - return function() { - return self.apply(bind, args.concat(Array.prototype.slice.call(arguments))); - }; - }; - -/* utility method to get incremental integer starting from 1 */ -var getIncrementalInteger = (function () { - var count = 0; - return function () { - count++; - return count; - }; -})(); - -// generate a random string (to be used as a dynamic JSONP callback) -export function getUniqueIdentifierStr() { - return getIncrementalInteger() + Math.random().toString(16).substr(2); -} - -/** - * Returns a random v4 UUID of the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx, - * where each x is replaced with a random hexadecimal digit from 0 to f, - * and y is replaced with a random hexadecimal digit from 8 to b. - * https://gist.github.com/jed/982883 via node-uuid - */ -export function generateUUID(placeholder) { - return placeholder - ? (placeholder ^ _getRandomData() >> placeholder / 4).toString(16) - : ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, generateUUID); -} - -/** - * Returns random data using the Crypto API if available and Math.random if not - * Method is from https://gist.github.com/jed/982883 like generateUUID, direct link https://gist.github.com/jed/982883#gistcomment-45104 - */ -function _getRandomData() { - if (window && window.crypto && window.crypto.getRandomValues) { - return crypto.getRandomValues(new Uint8Array(1))[0] % 16; - } else { - return Math.random() * 16; - } -} - -export function getBidIdParameter(key, paramsObj) { - if (paramsObj && paramsObj[key]) { - return paramsObj[key]; - } - - return ''; -} - -export function tryAppendQueryString(existingUrl, key, value) { - if (value) { - return existingUrl + key + '=' + encodeURIComponent(value) + '&'; - } - - return existingUrl; -} - -// parse a query string object passed in bid params -// bid params should be an object such as {key: "value", key1 : "value1"} -// aliases to formatQS -export function parseQueryStringParameters(queryObj) { - let result = ''; - for (var k in queryObj) { - if (queryObj.hasOwnProperty(k)) { result += k + '=' + encodeURIComponent(queryObj[k]) + '&'; } - } - result = result.replace(/&$/, ''); - return result; -} - -// transform an AdServer targeting bids into a query string to send to the adserver -export function transformAdServerTargetingObj(targeting) { - // we expect to receive targeting for a single slot at a time - if (targeting && Object.getOwnPropertyNames(targeting).length > 0) { - return getKeys(targeting) - .map(key => `${key}=${encodeURIComponent(getValue(targeting, key))}`).join('&'); - } else { - return ''; - } -} - -/** - * Read an adUnit object and return the sizes used in an [[728, 90]] format (even if they had [728, 90] defined) - * Preference is given to the `adUnit.mediaTypes.banner.sizes` object over the `adUnit.sizes` - * @param {object} adUnit one adUnit object from the normal list of adUnits - * @returns {Array.} array of arrays containing numeric sizes - */ -export function getAdUnitSizes(adUnit) { - if (!adUnit) { - return; - } - - let sizes = []; - if (adUnit.mediaTypes && adUnit.mediaTypes.banner && Array.isArray(adUnit.mediaTypes.banner.sizes)) { - let bannerSizes = adUnit.mediaTypes.banner.sizes; - if (Array.isArray(bannerSizes[0])) { - sizes = bannerSizes; - } else { - sizes.push(bannerSizes); - } - // TODO - remove this else block when we're ready to deprecate adUnit.sizes for bidders - } else if (Array.isArray(adUnit.sizes)) { - if (Array.isArray(adUnit.sizes[0])) { - sizes = adUnit.sizes; - } else { - sizes.push(adUnit.sizes); - } - } - return sizes; -} - -/** - * Parse a GPT-Style general size Array like `[[300, 250]]` or `"300x250,970x90"` into an array of sizes `["300x250"]` or '['300x250', '970x90']' - * @param {(Array.|Array.)} sizeObj Input array or double array [300,250] or [[300,250], [728,90]] - * @return {Array.} Array of strings like `["300x250"]` or `["300x250", "728x90"]` - */ -export function parseSizesInput(sizeObj) { - var parsedSizes = []; - - // if a string for now we can assume it is a single size, like "300x250" - if (typeof sizeObj === 'string') { - // multiple sizes will be comma-separated - var sizes = sizeObj.split(','); - - // regular expression to match strigns like 300x250 - // start of line, at least 1 number, an "x" , then at least 1 number, and the then end of the line - var sizeRegex = /^(\d)+x(\d)+$/i; - if (sizes) { - for (var curSizePos in sizes) { - if (hasOwn(sizes, curSizePos) && sizes[curSizePos].match(sizeRegex)) { - parsedSizes.push(sizes[curSizePos]); - } - } - } - } else if (typeof sizeObj === 'object') { - var sizeArrayLength = sizeObj.length; - - // don't process empty array - if (sizeArrayLength > 0) { - // if we are a 2 item array of 2 numbers, we must be a SingleSize array - if (sizeArrayLength === 2 && typeof sizeObj[0] === 'number' && typeof sizeObj[1] === 'number') { - parsedSizes.push(parseGPTSingleSizeArray(sizeObj)); - } else { - // otherwise, we must be a MultiSize array - for (var i = 0; i < sizeArrayLength; i++) { - parsedSizes.push(parseGPTSingleSizeArray(sizeObj[i])); - } - } - } - } - - return parsedSizes; -} - -// Parse a GPT style single size array, (i.e [300, 250]) -// into an AppNexus style string, (i.e. 300x250) -export function parseGPTSingleSizeArray(singleSize) { - if (isValidGPTSingleSize(singleSize)) { - return singleSize[0] + 'x' + singleSize[1]; - } -} - -// Parse a GPT style single size array, (i.e [300, 250]) -// into OpenRTB-compatible (imp.banner.w/h, imp.banner.format.w/h, imp.video.w/h) object(i.e. {w:300, h:250}) -export function parseGPTSingleSizeArrayToRtbSize(singleSize) { - if (isValidGPTSingleSize(singleSize)) { - return {w: singleSize[0], h: singleSize[1]}; - } -} - -function isValidGPTSingleSize(singleSize) { - // if we aren't exactly 2 items in this array, it is invalid - return isArray(singleSize) && singleSize.length === 2 && (!isNaN(singleSize[0]) && !isNaN(singleSize[1])); -} - -export function getWindowTop() { - return window.top; -} - -export function getWindowSelf() { - return window.self; -} - -export function getWindowLocation() { - return window.location; -} - -/** - * Wrappers to console.(log | info | warn | error). Takes N arguments, the same as the native methods - */ -export function logMessage() { - if (debugTurnedOn() && consoleLogExists) { - console.log.apply(console, decorateLog(arguments, 'MESSAGE:')); - } -} - -export function logInfo() { - if (debugTurnedOn() && consoleInfoExists) { - console.info.apply(console, decorateLog(arguments, 'INFO:')); - } -} - -export function logWarn() { - if (debugTurnedOn() && consoleWarnExists) { - console.warn.apply(console, decorateLog(arguments, 'WARNING:')); - } - events.emit(CONSTANTS.EVENTS.AUCTION_DEBUG, {type: 'WARNING', arguments: arguments}); -} - -export function logError() { - if (debugTurnedOn() && consoleErrorExists) { - console.error.apply(console, decorateLog(arguments, 'ERROR:')); - } - events.emit(CONSTANTS.EVENTS.AUCTION_DEBUG, {type: 'ERROR', arguments: arguments}); -} - -function decorateLog(args, prefix) { - args = [].slice.call(args); - let bidder = config.getCurrentBidder(); - - prefix && args.unshift(prefix); - if (bidder) { - args.unshift(label('#aaa')); - } - args.unshift(label('#3b88c3')); - args.unshift('%cPrebid' + (bidder ? `%c${bidder}` : '')); - return args; - - function label(color) { - return `display: inline-block; color: #fff; background: ${color}; padding: 1px 4px; border-radius: 3px;` - } -} - -export function hasConsoleLogger() { - return consoleLogExists; -} - -export function debugTurnedOn() { - return !!config.getConfig('debug'); -} - -export function createInvisibleIframe() { - var f = document.createElement('iframe'); - f.id = getUniqueIdentifierStr(); - f.height = 0; - f.width = 0; - f.border = '0px'; - f.hspace = '0'; - f.vspace = '0'; - f.marginWidth = '0'; - f.marginHeight = '0'; - f.style.border = '0'; - f.scrolling = 'no'; - f.frameBorder = '0'; - f.src = 'about:blank'; - f.style.display = 'none'; - return f; -} - -/* - * Check if a given parameter name exists in query string - * and if it does return the value - */ -export function getParameterByName(name) { - return parseQS(getWindowLocation().search)[name] || ''; -} - -/** - * Return if the object is of the - * given type. - * @param {*} object to test - * @param {String} _t type string (e.g., Array) - * @return {Boolean} if object is of type _t - */ -export function isA(object, _t) { - return toString.call(object) === '[object ' + _t + ']'; -} - -export function isFn(object) { - return isA(object, tFn); -} - -export function isStr(object) { - return isA(object, tStr); -} - -export function isArray(object) { - return isA(object, tArr); -} - -export function isNumber(object) { - return isA(object, tNumb); -} - -export function isPlainObject(object) { - return isA(object, tObject); -} - -export function isBoolean(object) { - return isA(object, tBoolean); -} - -/** - * Return if the object is "empty"; - * this includes falsey, no keys, or no items at indices - * @param {*} object object to test - * @return {Boolean} if object is empty - */ -export function isEmpty(object) { - if (!object) return true; - if (isArray(object) || isStr(object)) { - return !(object.length > 0); - } - - for (var k in object) { - if (hasOwnProperty.call(object, k)) return false; - } - - return true; -} - -/** - * Return if string is empty, null, or undefined - * @param str string to test - * @returns {boolean} if string is empty - */ -export function isEmptyStr(str) { - return isStr(str) && (!str || str.length === 0); -} - -/** - * Iterate object with the function - * falls back to es5 `forEach` - * @param {Array|Object} object - * @param {Function(value, key, object)} fn - */ -export function _each(object, fn) { - if (isEmpty(object)) return; - if (isFn(object.forEach)) return object.forEach(fn, this); - - var k = 0; - var l = object.length; - - if (l > 0) { - for (; k < l; k++) fn(object[k], k, object); - } else { - for (k in object) { - if (hasOwnProperty.call(object, k)) fn.call(this, object[k], k); - } - } -} - -export function contains(a, obj) { - if (isEmpty(a)) { - return false; - } - - if (isFn(a.indexOf)) { - return a.indexOf(obj) !== -1; - } - - var i = a.length; - while (i--) { - if (a[i] === obj) { - return true; - } - } - - return false; -} - -/** - * Map an array or object into another array - * given a function - * @param {Array|Object} object - * @param {Function(value, key, object)} callback - * @return {Array} - */ -export function _map(object, callback) { - if (isEmpty(object)) return []; - if (isFn(object.map)) return object.map(callback); - var output = []; - _each(object, function (value, key) { - output.push(callback(value, key, object)); - }); - - return output; -} - -export function hasOwn(objectToCheck, propertyToCheckFor) { - if (objectToCheck.hasOwnProperty) { - return objectToCheck.hasOwnProperty(propertyToCheckFor); - } else { - return (typeof objectToCheck[propertyToCheckFor] !== 'undefined') && (objectToCheck.constructor.prototype[propertyToCheckFor] !== objectToCheck[propertyToCheckFor]); - } -}; - -/* -* Inserts an element(elm) as targets child, by default as first child -* @param {HTMLElement} elm -* @param {HTMLElement} [doc] -* @param {HTMLElement} [target] -* @param {Boolean} [asLastChildChild] -* @return {HTMLElement} -*/ -export function insertElement(elm, doc, target, asLastChildChild) { - doc = doc || document; - let parentEl; - if (target) { - parentEl = doc.getElementsByTagName(target); - } else { - parentEl = doc.getElementsByTagName('head'); - } - try { - parentEl = parentEl.length ? parentEl : doc.getElementsByTagName('body'); - if (parentEl.length) { - parentEl = parentEl[0]; - let insertBeforeEl = asLastChildChild ? null : parentEl.firstChild; - return parentEl.insertBefore(elm, insertBeforeEl); - } - } catch (e) {} -} - -/** - * Inserts an image pixel with the specified `url` for cookie sync - * @param {string} url URL string of the image pixel to load - * @param {function} [done] an optional exit callback, used when this usersync pixel is added during an async process - */ -export function triggerPixel(url, done) { - const img = new Image(); - if (done && internal.isFn(done)) { - img.addEventListener('load', done); - img.addEventListener('error', done); - } - img.src = url; -} - -export function callBurl({ source, burl }) { - if (source === CONSTANTS.S2S.SRC && burl) { - internal.triggerPixel(burl); - } -} - -/** - * Inserts an empty iframe with the specified `html`, primarily used for tracking purposes - * (though could be for other purposes) - * @param {string} htmlCode snippet of HTML code used for tracking purposes - */ -export function insertHtmlIntoIframe(htmlCode) { - if (!htmlCode) { - return; - } - - let iframe = document.createElement('iframe'); - iframe.id = getUniqueIdentifierStr(); - iframe.width = 0; - iframe.height = 0; - iframe.hspace = '0'; - iframe.vspace = '0'; - iframe.marginWidth = '0'; - iframe.marginHeight = '0'; - iframe.style.display = 'none'; - iframe.style.height = '0px'; - iframe.style.width = '0px'; - iframe.scrolling = 'no'; - iframe.frameBorder = '0'; - iframe.allowtransparency = 'true'; - - internal.insertElement(iframe, document, 'body'); - - iframe.contentWindow.document.open(); - iframe.contentWindow.document.write(htmlCode); - iframe.contentWindow.document.close(); -} - -/** - * Inserts empty iframe with the specified `url` for cookie sync - * @param {string} url URL to be requested - * @param {string} encodeUri boolean if URL should be encoded before inserted. Defaults to true - * @param {function} [done] an optional exit callback, used when this usersync pixel is added during an async process - */ -export function insertUserSyncIframe(url, done) { - let iframeHtml = internal.createTrackPixelIframeHtml(url, false, 'allow-scripts allow-same-origin'); - let div = document.createElement('div'); - div.innerHTML = iframeHtml; - let iframe = div.firstChild; - if (done && internal.isFn(done)) { - iframe.addEventListener('load', done); - iframe.addEventListener('error', done); - } - internal.insertElement(iframe, document, 'html', true); -}; - -/** - * Creates a snippet of HTML that retrieves the specified `url` - * @param {string} url URL to be requested - * @return {string} HTML snippet that contains the img src = set to `url` - */ -export function createTrackPixelHtml(url) { - if (!url) { - return ''; - } - - let escapedUrl = encodeURI(url); - let img = '
'; - img += '
'; - return img; -}; - -/** - * Creates a snippet of Iframe HTML that retrieves the specified `url` - * @param {string} url plain URL to be requested - * @param {string} encodeUri boolean if URL should be encoded before inserted. Defaults to true - * @param {string} sandbox string if provided the sandbox attribute will be included with the given value - * @return {string} HTML snippet that contains the iframe src = set to `url` - */ -export function createTrackPixelIframeHtml(url, encodeUri = true, sandbox = '') { - if (!url) { - return ''; - } - if (encodeUri) { - url = encodeURI(url); - } - if (sandbox) { - sandbox = `sandbox="${sandbox}"`; - } - - return ``; -} - -export function getValueString(param, val, defaultValue) { - if (val === undefined || val === null) { - return defaultValue; - } - if (isStr(val)) { - return val; - } - if (isNumber(val)) { - return val.toString(); - } - internal.logWarn('Unsuported type for param: ' + param + ' required type: String'); -} - -export function uniques(value, index, arry) { - return arry.indexOf(value) === index; -} - -export function flatten(a, b) { - return a.concat(b); -} - -export function getBidRequest(id, bidderRequests) { - if (!id) { - return; - } - let bidRequest; - bidderRequests.some(bidderRequest => { - let result = find(bidderRequest.bids, bid => ['bidId', 'adId', 'bid_id'].some(type => bid[type] === id)); - if (result) { - bidRequest = result; - } - return result; - }); - return bidRequest; -} - -export function getKeys(obj) { - return Object.keys(obj); -} - -export function getValue(obj, key) { - return obj[key]; -} - -/** - * Get the key of an object for a given value - */ -export function getKeyByValue(obj, value) { - for (let prop in obj) { - if (obj.hasOwnProperty(prop)) { - if (obj[prop] === value) { - return prop; - } - } - } -} - -export function getBidderCodes(adUnits = $$PREBID_GLOBAL$$.adUnits) { - // this could memoize adUnits - return adUnits.map(unit => unit.bids.map(bid => bid.bidder) - .reduce(flatten, [])).reduce(flatten).filter(uniques); -} - -export function isGptPubadsDefined() { - if (window.googletag && isFn(window.googletag.pubads) && isFn(window.googletag.pubads().getSlots)) { - return true; - } -} - -// This function will get highest cpm value bid, in case of tie it will return the bid with lowest timeToRespond -export const getHighestCpm = getHighestCpmCallback('timeToRespond', (previous, current) => previous > current); - -// This function will get the oldest hightest cpm value bid, in case of tie it will return the bid which came in first -// Use case for tie: https://github.com/prebid/Prebid.js/issues/2448 -export const getOldestHighestCpmBid = getHighestCpmCallback('responseTimestamp', (previous, current) => previous > current); - -// This function will get the latest hightest cpm value bid, in case of tie it will return the bid which came in last -// Use case for tie: https://github.com/prebid/Prebid.js/issues/2539 -export const getLatestHighestCpmBid = getHighestCpmCallback('responseTimestamp', (previous, current) => previous < current); - -function getHighestCpmCallback(useTieBreakerProperty, tieBreakerCallback) { - return (previous, current) => { - if (previous.cpm === current.cpm) { - return tieBreakerCallback(previous[useTieBreakerProperty], current[useTieBreakerProperty]) ? current : previous; - } - return previous.cpm < current.cpm ? current : previous; - } -} - -/** - * Fisher–Yates shuffle - * http://stackoverflow.com/a/6274398 - * https://bost.ocks.org/mike/shuffle/ - * istanbul ignore next - */ -export function shuffle(array) { - let counter = array.length; - - // while there are elements in the array - while (counter > 0) { - // pick a random index - let index = Math.floor(Math.random() * counter); - - // decrease counter by 1 - counter--; - - // and swap the last element with it - let temp = array[counter]; - array[counter] = array[index]; - array[index] = temp; - } - - return array; -} - -export function adUnitsFilter(filter, bid) { - return includes(filter, bid && bid.adUnitCode); -} - -export function deepClone(obj) { - return clone(obj); -} - -export function inIframe() { - try { - return internal.getWindowSelf() !== internal.getWindowTop(); - } catch (e) { - return true; - } -} - -export function isSafariBrowser() { - return /^((?!chrome|android|crios|fxios).)*safari/i.test(navigator.userAgent); -} - -export function replaceAuctionPrice(str, cpm) { - if (!str) return; - return str.replace(/\$\{AUCTION_PRICE\}/g, cpm); -} - -export function replaceClickThrough(str, clicktag) { - if (!str || !clicktag || typeof clicktag !== 'string') return; - return str.replace(/\${CLICKTHROUGH}/g, clicktag); -} - -export function timestamp() { - return new Date().getTime(); -} - -/** - * The returned value represents the time elapsed since the time origin. @see https://developer.mozilla.org/en-US/docs/Web/API/Performance/now - * @returns {number} - */ -export function getPerformanceNow() { - return (window.performance && window.performance.now && window.performance.now()) || 0; -} - -/** - * When the deviceAccess flag config option is false, no cookies should be read or set - * @returns {boolean} - */ -export function hasDeviceAccess() { - return config.getConfig('deviceAccess') !== false; -} - -/** - * @returns {(boolean|undefined)} - */ -export function checkCookieSupport() { - if (window.navigator.cookieEnabled || !!document.cookie.length) { - return true; - } -} - -/** - * Given a function, return a function which only executes the original after - * it's been called numRequiredCalls times. - * - * Note that the arguments from the previous calls will *not* be forwarded to the original function. - * Only the final call's arguments matter. - * - * @param {function} func The function which should be executed, once the returned function has been executed - * numRequiredCalls times. - * @param {int} numRequiredCalls The number of times which the returned function needs to be called before - * func is. - */ -export function delayExecution(func, numRequiredCalls) { - if (numRequiredCalls < 1) { - throw new Error(`numRequiredCalls must be a positive number. Got ${numRequiredCalls}`); - } - let numCalls = 0; - return function () { - numCalls++; - if (numCalls === numRequiredCalls) { - func.apply(this, arguments); - } - } -} - -/** - * https://stackoverflow.com/a/34890276/428704 - * @export - * @param {array} xs - * @param {string} key - * @returns {Object} {${key_value}: ${groupByArray}, key_value: {groupByArray}} - */ -export function groupBy(xs, key) { - return xs.reduce(function(rv, x) { - (rv[x[key]] = rv[x[key]] || []).push(x); - return rv; - }, {}); -} - -/** - * Build an object consisting of only defined parameters to avoid creating an - * object with defined keys and undefined values. - * @param {Object} object The object to pick defined params out of - * @param {string[]} params An array of strings representing properties to look for in the object - * @returns {Object} An object containing all the specified values that are defined - */ -export function getDefinedParams(object, params) { - return params - .filter(param => object[param]) - .reduce((bid, param) => Object.assign(bid, { [param]: object[param] }), {}); -} - -/** - * @typedef {Object} MediaTypes - * @property {Object} banner banner configuration - * @property {Object} native native configuration - * @property {Object} video video configuration - */ - -/** - * Validates an adunit's `mediaTypes` parameter - * @param {MediaTypes} mediaTypes mediaTypes parameter to validate - * @return {boolean} If object is valid - */ -export function isValidMediaTypes(mediaTypes) { - const SUPPORTED_MEDIA_TYPES = ['banner', 'native', 'video']; - const SUPPORTED_STREAM_TYPES = ['instream', 'outstream', 'adpod']; - - const types = Object.keys(mediaTypes); - - if (!types.every(type => includes(SUPPORTED_MEDIA_TYPES, type))) { - return false; - } - - if (mediaTypes.video && mediaTypes.video.context) { - return includes(SUPPORTED_STREAM_TYPES, mediaTypes.video.context); - } - - return true; -} - -export function getBidderRequest(bidRequests, bidder, adUnitCode) { - return find(bidRequests, request => { - return request.bids - .filter(bid => bid.bidder === bidder && bid.adUnitCode === adUnitCode).length > 0; - }) || { start: null, auctionId: null }; -} -/** - * Returns user configured bidder params from adunit - * @param {Object} adUnits - * @param {string} adUnitCode code - * @param {string} bidder code - * @return {Array} user configured param for the given bidder adunit configuration - */ -export function getUserConfiguredParams(adUnits, adUnitCode, bidder) { - return adUnits - .filter(adUnit => adUnit.code === adUnitCode) - .map((adUnit) => adUnit.bids) - .reduce(flatten, []) - .filter((bidderData) => bidderData.bidder === bidder) - .map((bidderData) => bidderData.params || {}); -} -/** - * Returns the origin - */ -export function getOrigin() { - // IE10 does not have this property. https://gist.github.com/hbogs/7908703 - if (!window.location.origin) { - return window.location.protocol + '//' + window.location.hostname + (window.location.port ? ':' + window.location.port : ''); - } else { - return window.location.origin; - } -} - -/** - * Returns Do Not Track state - */ -export function getDNT() { - return navigator.doNotTrack === '1' || window.doNotTrack === '1' || navigator.msDoNotTrack === '1' || navigator.doNotTrack === 'yes'; -} - -const compareCodeAndSlot = (slot, adUnitCode) => slot.getAdUnitPath() === adUnitCode || slot.getSlotElementId() === adUnitCode; - -/** - * Returns filter function to match adUnitCode in slot - * @param {Object} slot GoogleTag slot - * @return {function} filter function - */ -export function isAdUnitCodeMatchingSlot(slot) { - return (adUnitCode) => compareCodeAndSlot(slot, adUnitCode); -} - -/** - * Returns filter function to match adUnitCode in slot - * @param {string} adUnitCode AdUnit code - * @return {function} filter function - */ -export function isSlotMatchingAdUnitCode(adUnitCode) { - return (slot) => compareCodeAndSlot(slot, adUnitCode); -} - -/** - * @summary Uses the adUnit's code in order to find a matching gptSlot on the page - */ -export function getGptSlotInfoForAdUnitCode(adUnitCode) { - let matchingSlot; - if (isGptPubadsDefined()) { - // find the first matching gpt slot on the page - matchingSlot = find(window.googletag.pubads().getSlots(), isSlotMatchingAdUnitCode(adUnitCode)); - } - if (matchingSlot) { - return { - gptSlot: matchingSlot.getAdUnitPath(), - divId: matchingSlot.getSlotElementId() - } - } - return {}; -}; - -/** - * Constructs warning message for when unsupported bidders are dropped from an adunit - * @param {Object} adUnit ad unit from which the bidder is being dropped - * @param {string} bidder bidder code that is not compatible with the adUnit - * @return {string} warning message to display when condition is met - */ -export function unsupportedBidderMessage(adUnit, bidder) { - const mediaType = Object.keys(adUnit.mediaTypes || {'banner': 'banner'}).join(', '); - - return ` - ${adUnit.code} is a ${mediaType} ad unit - containing bidders that don't support ${mediaType}: ${bidder}. - This bidder won't fetch demand. - `; -} - -/** - * Checks input is integer or not - * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger - * @param {*} value - */ -export function isInteger(value) { - if (Number.isInteger) { - return Number.isInteger(value); - } else { - return typeof value === 'number' && isFinite(value) && Math.floor(value) === value; - } -} - -/** - * Converts a string value in camel-case to underscore eg 'placementId' becomes 'placement_id' - * @param {string} value string value to convert - */ -export function convertCamelToUnderscore(value) { - return value.replace(/(?:^|\.?)([A-Z])/g, function (x, y) { return '_' + y.toLowerCase() }).replace(/^_/, ''); -} - -/** - * Returns a new object with undefined properties removed from given object - * @param obj the object to clean - */ -export function cleanObj(obj) { - return Object.keys(obj).reduce((newObj, key) => { - if (typeof obj[key] !== 'undefined') { - newObj[key] = obj[key]; - } - return newObj; - }, {}) -} - -/** - * Create a new object with selected properties. Also allows property renaming and transform functions. - * @param obj the original object - * @param properties An array of desired properties - */ -export function pick(obj, properties) { - if (typeof obj !== 'object') { - return {}; - } - return properties.reduce((newObj, prop, i) => { - if (typeof prop === 'function') { - return newObj; - } - - let newProp = prop; - let match = prop.match(/^(.+?)\sas\s(.+?)$/i); - - if (match) { - prop = match[1]; - newProp = match[2]; - } - - let value = obj[prop]; - if (typeof properties[i + 1] === 'function') { - value = properties[i + 1](value, newObj); - } - if (typeof value !== 'undefined') { - newObj[newProp] = value; - } - - return newObj; - }, {}); -} - -/** - * Converts an object of arrays (either strings or numbers) into an array of objects containing key and value properties - * normally read from bidder params - * eg { foo: ['bar', 'baz'], fizz: ['buzz'] } - * becomes [{ key: 'foo', value: ['bar', 'baz']}, {key: 'fizz', value: ['buzz']}] - * @param {Object} keywords object of arrays representing keyvalue pairs - * @param {string} paramName name of parent object (eg 'keywords') containing keyword data, used in error handling - */ -export function transformBidderParamKeywords(keywords, paramName = 'keywords') { - let arrs = []; - - _each(keywords, (v, k) => { - if (isArray(v)) { - let values = []; - _each(v, (val) => { - val = getValueString(paramName + '.' + k, val); - if (val || val === '') { values.push(val); } - }); - v = values; - } else { - v = getValueString(paramName + '.' + k, v); - if (isStr(v)) { - v = [v]; - } else { - return; - } // unsuported types - don't send a key - } - arrs.push({key: k, value: v}); - }); - - return arrs; -} - -/** - * Try to convert a value to a type. - * If it can't be done, the value will be returned. - * - * @param {string} typeToConvert The target type. e.g. "string", "number", etc. - * @param {*} value The value to be converted into typeToConvert. - */ -function tryConvertType(typeToConvert, value) { - if (typeToConvert === 'string') { - return value && value.toString(); - } else if (typeToConvert === 'number') { - return Number(value); - } else { - return value; - } -} - -export function convertTypes(types, params) { - Object.keys(types).forEach(key => { - if (params[key]) { - if (isFn(types[key])) { - params[key] = types[key](params[key]); - } else { - params[key] = tryConvertType(types[key], params[key]); - } - - // don't send invalid values - if (isNaN(params[key])) { - delete params.key; - } - } - }); - return params; -} - -export function isArrayOfNums(val, size) { - return (isArray(val)) && ((size) ? val.length === size : true) && (val.every(v => isInteger(v))); -} - -/** - * Creates an array of n length and fills each item with the given value - */ -export function fill(value, length) { - let newArray = []; - - for (let i = 0; i < length; i++) { - let valueToPush = isPlainObject(value) ? deepClone(value) : value; - newArray.push(valueToPush); - } - - return newArray; -} - -/** - * http://npm.im/chunk - * Returns an array with *size* chunks from given array - * - * Example: - * ['a', 'b', 'c', 'd', 'e'] chunked by 2 => - * [['a', 'b'], ['c', 'd'], ['e']] - */ -export function chunk(array, size) { - let newArray = []; - - for (let i = 0; i < Math.ceil(array.length / size); i++) { - let start = i * size; - let end = start + size; - newArray.push(array.slice(start, end)); - } - - return newArray; -} - -export function getMinValueFromArray(array) { - return Math.min(...array); -} - -export function getMaxValueFromArray(array) { - return Math.max(...array); -} - -/** - * This function will create compare function to sort on object property - * @param {string} property - * @returns {function} compare function to be used in sorting - */ -export function compareOn(property) { - return function compare(a, b) { - if (a[property] < b[property]) { - return 1; - } - if (a[property] > b[property]) { - return -1; - } - return 0; - } -} - -export function parseQS(query) { - return !query ? {} : query - .replace(/^\?/, '') - .split('&') - .reduce((acc, criteria) => { - let [k, v] = criteria.split('='); - if (/\[\]$/.test(k)) { - k = k.replace('[]', ''); - acc[k] = acc[k] || []; - acc[k].push(v); - } else { - acc[k] = v || ''; - } - return acc; - }, {}); -} - -export function formatQS(query) { - return Object - .keys(query) - .map(k => Array.isArray(query[k]) - ? query[k].map(v => `${k}[]=${v}`).join('&') - : `${k}=${query[k]}`) - .join('&'); -} - -export function parseUrl(url, options) { - let parsed = document.createElement('a'); - if (options && 'noDecodeWholeURL' in options && options.noDecodeWholeURL) { - parsed.href = url; - } else { - parsed.href = decodeURIComponent(url); - } - // in window.location 'search' is string, not object - let qsAsString = (options && 'decodeSearchAsString' in options && options.decodeSearchAsString); - return { - href: parsed.href, - protocol: (parsed.protocol || '').replace(/:$/, ''), - hostname: parsed.hostname, - port: +parsed.port, - pathname: parsed.pathname.replace(/^(?!\/)/, '/'), - search: (qsAsString) ? parsed.search : internal.parseQS(parsed.search || ''), - hash: (parsed.hash || '').replace(/^#/, ''), - host: parsed.host || window.location.host - }; -} - -export function buildUrl(obj) { - return (obj.protocol || 'http') + '://' + - (obj.host || - obj.hostname + (obj.port ? `:${obj.port}` : '')) + - (obj.pathname || '') + - (obj.search ? `?${internal.formatQS(obj.search || '')}` : '') + - (obj.hash ? `#${obj.hash}` : ''); -} - -/** - * This function deeply compares two objects checking for their equivalence. - * @param {Object} obj1 - * @param {Object} obj2 - * @returns {boolean} - */ -export function deepEqual(obj1, obj2) { - if (obj1 === obj2) return true; - else if ((typeof obj1 === 'object' && obj1 !== null) && (typeof obj2 === 'object' && obj2 !== null)) { - if (Object.keys(obj1).length !== Object.keys(obj2).length) return false; - for (let prop in obj1) { - if (obj2.hasOwnProperty(prop)) { - if (!deepEqual(obj1[prop], obj2[prop])) { - return false; - } - } else { - return false; - } - } - return true; - } else { - return false; - } -} - -export function mergeDeep(target, ...sources) { - if (!sources.length) return target; - const source = sources.shift(); - - if (isPlainObject(target) && isPlainObject(source)) { - for (const key in source) { - if (isPlainObject(source[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] }); - } else if (isArray(target[key])) { - target[key] = target[key].concat(source[key]); - } - } else { - Object.assign(target, { [key]: source[key] }); - } - } - } - - return mergeDeep(target, ...sources); -} - -/** - * returns a hash of a string using a fast algorithm - * source: https://stackoverflow.com/a/52171480/845390 - * @param str - * @param seed (optional) - * @returns {string} - */ -export function cyrb53Hash(str, seed = 0) { - // IE doesn't support imul - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul#Polyfill - let imul = function(opA, opB) { - if (isFn(Math.imul)) { - return Math.imul(opA, opB); - } else { - opB |= 0; // ensure that opB is an integer. opA will automatically be coerced. - // floating points give us 53 bits of precision to work with plus 1 sign bit - // automatically handled for our convienence: - // 1. 0x003fffff /*opA & 0x000fffff*/ * 0x7fffffff /*opB*/ = 0x1fffff7fc00001 - // 0x1fffff7fc00001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/ - var result = (opA & 0x003fffff) * opB; - // 2. We can remove an integer coersion from the statement above because: - // 0x1fffff7fc00001 + 0xffc00000 = 0x1fffffff800001 - // 0x1fffffff800001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/ - if (opA & 0xffc00000) result += (opA & 0xffc00000) * opB | 0; - return result | 0; - } - }; - - let h1 = 0xdeadbeef ^ seed; - let h2 = 0x41c6ce57 ^ seed; - for (let i = 0, ch; i < str.length; i++) { - ch = str.charCodeAt(i); - h1 = imul(h1 ^ ch, 2654435761); - h2 = imul(h2 ^ ch, 1597334677); - } - h1 = imul(h1 ^ (h1 >>> 16), 2246822507) ^ imul(h2 ^ (h2 >>> 13), 3266489909); - h2 = imul(h2 ^ (h2 >>> 16), 2246822507) ^ imul(h1 ^ (h1 >>> 13), 3266489909); - return (4294967296 * (2097151 & h2) + (h1 >>> 0)).toString(); -} diff --git a/src/video.js b/src/video.js deleted file mode 100644 index 20df7a92442..00000000000 --- a/src/video.js +++ /dev/null @@ -1,66 +0,0 @@ -import adapterManager from './adapterManager.js'; -import { getBidRequest, deepAccess, logError } from './utils.js'; -import { config } from '../src/config.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import { hook } from './hook.js'; - -const VIDEO_MEDIA_TYPE = 'video'; -export const OUTSTREAM = 'outstream'; -export const INSTREAM = 'instream'; - -/** - * Helper functions for working with video-enabled adUnits - */ -export const videoAdUnit = adUnit => { - const mediaType = adUnit.mediaType === VIDEO_MEDIA_TYPE; - const mediaTypes = deepAccess(adUnit, 'mediaTypes.video'); - return mediaType || mediaTypes; -}; -export const videoBidder = bid => includes(adapterManager.videoAdapters, bid.bidder); -export const hasNonVideoBidder = adUnit => - adUnit.bids.filter(bid => !videoBidder(bid)).length; - -/** - * @typedef {object} VideoBid - * @property {string} adId id of the bid - */ - -/** - * Validate that the assets required for video context are present on the bid - * @param {VideoBid} bid Video bid to validate - * @param {BidRequest[]} bidRequests All bid requests for an auction - * @return {Boolean} If object is valid - */ -export function isValidVideoBid(bid, bidRequests) { - const bidRequest = getBidRequest(bid.requestId, bidRequests); - - const videoMediaType = - bidRequest && deepAccess(bidRequest, 'mediaTypes.video'); - const context = videoMediaType && deepAccess(videoMediaType, 'context'); - - // if context not defined assume default 'instream' for video bids - // instream bids require a vast url or vast xml content - return checkVideoBidSetup(bid, bidRequest, videoMediaType, context); -} - -export const checkVideoBidSetup = hook('sync', function(bid, bidRequest, videoMediaType, context) { - if (!bidRequest || (videoMediaType && context !== OUTSTREAM)) { - // xml-only video bids require a prebid cache url - if (!config.getConfig('cache.url') && bid.vastXml && !bid.vastUrl) { - logError(` - This bid contains only vastXml and will not work when a prebid cache url is not specified. - Try enabling prebid cache with $$PREBID_GLOBAL$$.setConfig({ cache: {url: "..."} }); - `); - return false; - } - - return !!(bid.vastUrl || bid.vastXml); - } - - // outstream bids require a renderer on the bid or pub-defined on adunit - if (context === OUTSTREAM) { - return !!(bid.renderer || bidRequest.renderer || videoMediaType.renderer); - } - - return true; -}, 'checkVideoBidSetup'); diff --git a/src/videoCache.js b/src/videoCache.js deleted file mode 100644 index 9e378d90574..00000000000 --- a/src/videoCache.js +++ /dev/null @@ -1,151 +0,0 @@ -/** - * This module interacts with the server used to cache video ad content to be restored later. - * At a high level, the expected workflow goes like this: - * - * - Request video ads from Bidders - * - Generate IDs for each valid bid, and cache the key/value pair on the server. - * - Return these IDs so that publishers can use them to fetch the bids later. - * - * This trickery helps integrate with ad servers, which set character limits on request params. - */ - -import { ajax } from './ajax.js'; -import { config } from './config.js'; -import * as utils from './utils.js'; - -/** - * @typedef {object} CacheableUrlBid - * @property {string} vastUrl A URL which loads some valid VAST XML. - */ - -/** - * @typedef {object} CacheablePayloadBid - * @property {string} vastXml Some VAST XML which loads an ad in a video player. - */ - -/** - * A CacheableBid describes the types which the videoCache can store. - * - * @typedef {CacheableUrlBid|CacheablePayloadBid} CacheableBid - */ - -/** - * Function which wraps a URI that serves VAST XML, so that it can be loaded. - * - * @param {string} uri The URI where the VAST content can be found. - * @param {string} impUrl An impression tracker URL for the delivery of the video ad - * @return A VAST URL which loads XML from the given URI. - */ -function wrapURI(uri, impUrl) { - // Technically, this is vulnerable to cross-script injection by sketchy vastUrl bids. - // We could make sure it's a valid URI... but since we're loading VAST XML from the - // URL they provide anyway, that's probably not a big deal. - let vastImp = (impUrl) ? `` : ``; - return ` - - - prebid.org wrapper - - ${vastImp} - - - - `; -} - -/** - * Wraps a bid in the format expected by the prebid-server endpoints, or returns null if - * the bid can't be converted cleanly. - * - * @param {CacheableBid} bid - */ -function toStorageRequest(bid) { - const vastValue = bid.vastXml ? bid.vastXml : wrapURI(bid.vastUrl, bid.vastImpUrl); - - let payload = { - type: 'xml', - value: vastValue, - ttlseconds: Number(bid.ttl) - }; - - if (config.getConfig('cache.vasttrack')) { - payload.bidder = bid.bidder; - payload.bidid = bid.requestId; - payload.aid = bid.auctionId; - // function has a thisArg set to bidderRequest for accessing the auctionStart - if (utils.isPlainObject(this) && this.hasOwnProperty('auctionStart')) { - payload.timestamp = this.auctionStart; - } - } - - if (typeof bid.customCacheKey === 'string' && bid.customCacheKey !== '') { - payload.key = bid.customCacheKey; - } - - return payload; -} - -/** - * A function which should be called with the results of the storage operation. - * - * @callback videoCacheStoreCallback - * - * @param {Error} [error] The error, if one occurred. - * @param {?string[]} uuids An array of unique IDs. The array will have one element for each bid we were asked - * to store. It may include null elements if some of the bids were malformed, or an error occurred. - * Each non-null element in this array is a valid input into the retrieve function, which will fetch - * some VAST XML which can be used to render this bid's ad. - */ - -/** - * A function which bridges the APIs between the videoCacheStoreCallback and our ajax function's API. - * - * @param {videoCacheStoreCallback} done A callback to the "store" function. - * @return {Function} A callback which interprets the cache server's responses, and makes up the right - * arguments for our callback. - */ -function shimStorageCallback(done) { - return { - success: function (responseBody) { - let ids; - try { - ids = JSON.parse(responseBody).responses - } catch (e) { - done(e, []); - return; - } - - if (ids) { - done(null, ids); - } else { - done(new Error("The cache server didn't respond with a responses property."), []); - } - }, - error: function (statusText, responseBody) { - done(new Error(`Error storing video ad in the cache: ${statusText}: ${JSON.stringify(responseBody)}`), []); - } - } -} - -/** - * If the given bid is for a Video ad, generate a unique ID and cache it somewhere server-side. - * - * @param {CacheableBid[]} bids A list of bid objects which should be cached. - * @param {videoCacheStoreCallback} [done] An optional callback which should be executed after - * @param {BidderRequest} [bidderRequest] - * the data has been stored in the cache. - */ -export function store(bids, done, bidderRequest) { - const requestData = { - puts: bids.map(toStorageRequest, bidderRequest) - }; - - ajax(config.getConfig('cache.url'), shimStorageCallback(done), JSON.stringify(requestData), { - contentType: 'text/plain', - withCredentials: true - }); -} - -export function getCacheUrl(id) { - return `${config.getConfig('cache.url')}?uuid=${id}`; -} diff --git a/test/.eslintrc.js b/test/.eslintrc.js deleted file mode 100644 index 842bccd99b1..00000000000 --- a/test/.eslintrc.js +++ /dev/null @@ -1,40 +0,0 @@ -module.exports = { - "env": { - "browser": true, - "mocha": true - }, - "extends": "standard", - "globals": { - "$$PREBID_GLOBAL$$": false - }, - "parserOptions": { - "sourceType": "module" - }, - "rules": { - "comma-dangle": "off", - "semi": "off", - "space-before-function-paren": "off", - - // Exceptions below this line are temporary, so that eslint can be added into the CI process. - // Violations of these styles should be fixed, and the exceptions removed over time. - // - // See Issue #1111. - "camelcase": "off", - "eqeqeq": "off", - "no-mixed-spaces-and-tabs": "off", - "no-tabs": "off", - "no-unused-expressions": "off", - "import/no-duplicates": "off", - "no-template-curly-in-string": "off", - "no-global-assign": "off", - "no-path-concat": "off", - "no-redeclare": "off", - "node/no-deprecated-api": "off", - "no-return-assign": "off", - "no-undef": "off", - "no-unused-vars": "off", - "no-use-before-define": "off", - "no-useless-escape": "off", - "one-var": "off" - } -}; diff --git a/test/fake-server/README.md b/test/fake-server/README.md deleted file mode 100644 index 2e93fa44947..00000000000 --- a/test/fake-server/README.md +++ /dev/null @@ -1,28 +0,0 @@ -## fake-server - -A simple http server that matches incoming requests to a stored list of `request-response` pair, and returns a fake response. The server is meant to replace actual calls to `appnexus` adapter (extendable to any other adapter) endpoint when the e2e tests runs. - - -## How to add a Request - Response pair ? - -All the `request-response` pairs are stored in the `fixtures/` directory. They are organized by their test group and test name. - -Follow the steps below to add another `request-response` pair. - -1. Inside the `/fixtures` directory, create a directory and give it a suitable name. - - If you are creating a one-off type of test, you can name this directory with a name that describes the test; for example `basic-banner`. - - If you plan to create a series of tests focusing on one feature/topic, then you can create a generic container directory to hold all your tests together; for example `longform`. - - If you did the latter case, please proceed to create the necessary test directories describing them with a meaningful and **unique** test name. -2. If you are planning to handle multiple bidder requests as part of your tests, you will need to create a specific directory for each request. For example, you could create a pair named like so `longform_biddersettings_1` and `longform_biddersettings_2`. -3. Once all your directories are created, inside the bottom test folder(s), create **three files**: - - `description.md` (Contains path of test page and spec file. Also, contains the ad unit that generates the **request-response** pair) - - `request.json` (This object will be matched against the acutal incoming request) - - `response.json` (This object will be returned as response of the fake-server, if the response object's request pair matchest the incoming request) - -For reference, please have a look at `fixtures/basic-banner` or `fixtures/longform` directories (as matching your scenario). - -## How is the server initiated ? - -When the command `gulp e2e-test --host=test.localhost` is executed, gulp task `test` automatically spawns the `fake-server` which runs on port `4444`. - -On execution of the tests, the server automatically stops. \ No newline at end of file diff --git a/test/fake-server/fake-responder.js b/test/fake-server/fake-responder.js deleted file mode 100644 index c884b00ca9c..00000000000 --- a/test/fake-server/fake-responder.js +++ /dev/null @@ -1,75 +0,0 @@ -/* eslint no-console: 0 */ -const deepEqual = require('deep-equal'); -const generateFixtures = require('./fixtures'); -const path = require('path'); - -// path to the fixture directory -const fixturesPath = path.join(__dirname, 'fixtures'); - -// An object storing 'Request-Response' pairs. -let REQ_RES_MAP = generateFixtures(fixturesPath); - -/** - * Matches 'req.body' with the responseBody pair - * @param {object} requestBody - `req.body` of incoming request hitting middleware 'fakeResponder'. - * @returns {objct} responseBody - */ -const matchResponse = function (requestBody) { - let actualUuids = []; - - const requestResponsePairs = Object.keys(REQ_RES_MAP).map(testName => REQ_RES_MAP[testName]); - - // delete 'uuid' property - requestBody.tags.forEach(body => { - // store the 'uuid' before deleting it. - actualUuids.push(body.uuid); - - // delete the 'uuid' - delete body.uuid; - }); - - ['sdk', 'referrer_detection', 'gdpr_consent'].forEach(prop => { - if (requestBody && requestBody[prop]) { - delete requestBody[prop]; - } - }); - - // delete 'uuid' from `expected request body` - requestResponsePairs - .forEach(reqRes => { reqRes.request.httpRequest && reqRes.request.httpRequest.body.tags.forEach(body => body.uuid && delete body.uuid) }); - - // match the 'actual' requestBody with the 'expected' requestBody and find the 'responseBody' - const responseBody = requestResponsePairs.filter(reqRes => reqRes.request.httpRequest && deepEqual(reqRes.request.httpRequest.body.tags, requestBody.tags))[0].response.httpResponse.body; - - // ENABLE THE FOLLOWING CODE FOR TROUBLE-SHOOTING FAKED REQUESTS; COMMENT AGAIN WHEN DONE - // console.log('value found for responseBody:', responseBody); - // responseBody.tags.forEach((tag, index) => { - // console.log('value found for responseBody.tag[', index, ']:ads', tag.ads); - // }); - - // copy the actual uuids to the responseBody - // TODO:: what if responseBody is 'undefined' - responseBody.tags.forEach(body => { - body.uuid = actualUuids.shift(); - }); - - return responseBody; -} - -/** - * An ExpressJs middleware function that checks the incoming Request Body - * and returns the corresponding Fake Response Body pertaining to that Request. - */ - -const fakeResponder = function (req, res, next) { - const request = JSON.parse(req.body); - - const response = matchResponse(request); - - res.type('json'); - res.write(JSON.stringify(response)); - - next(); -} - -module.exports = fakeResponder; diff --git a/test/fake-server/fixtures/basic-banner/description.md b/test/fake-server/fixtures/basic-banner/description.md deleted file mode 100644 index 45ef571aaac..00000000000 --- a/test/fake-server/fixtures/basic-banner/description.md +++ /dev/null @@ -1,34 +0,0 @@ -Test Page - 'test/pages/banner.html' -Test Spec File - 'test/spec/e2e/banner/basic_banner_ad.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'div-gpt-ad-1460505748561-0', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13144370 - } - }] -}, { - code: 'div-gpt-ad-1460505748561-1', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - } - }, - bids: [{ - bidder: "appnexus", - params: { - placementId: 13144370 - } - }] -}]; -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-banner/request.json b/test/fake-server/fixtures/basic-banner/request.json deleted file mode 100644 index ea85b5a6842..00000000000 --- a/test/fake-server/fixtures/basic-banner/request.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 300, - "height": 250 - }, - { - "width": 300, - "height": 600 - } - ], - "primary_size": { - "width": 300, - "height": 250 - }, - "ad_types": [ - "banner" - ], - "id": 13144370, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 1 - }, - { - "sizes": [ - { - "width": 300, - "height": 250 - }, - { - "width": 300, - "height": 600 - } - ], - "primary_size": { - "width": 300, - "height": 250 - }, - "ad_types": [ - "banner" - ], - "id": 13144370, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 1 - } - ], - "user": {} - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-banner/response.json b/test/fake-server/fixtures/basic-banner/response.json deleted file mode 100644 index dc73d3fa3d2..00000000000 --- a/test/fake-server/fixtures/basic-banner/response.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "tag_id": 13144370, - "auction_id": "8147841645883553832", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Fgpt%2Fhello_world.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKzCKAzBAAAAwDWAAUBCJKPpe4FEKjwl-js2byJcRiq5MnUovf28WEqNgkAAAkCABEJBywAABkAAACA61HgPyEREgApEQkAMREb8GkwsqKiBjjtSEDtSEgAUABYnPFbYABotc95eACAAQGKAQCSAQNVU0SYAawCoAH6AagBAbABALgBAcABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3MzQ3MjE0Nik7AR0scicsIDk2ODQ2MDM1Nh4A8PWSAqUCIXp6ZmhVQWl1c0s0S0VOT0JseTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFzcUtpQmxnQVlJSUNhQUJ3Q0hncWdBRWtpQUVxa0FFQW1BRUFvQUVCcUFFRHNBRUF1UUVwaTRpREFBRGdQOEVCS1l1SWd3QUE0RF9KQVozRkl5WjA1Tm9fMlFFQUFBQUFBQUR3UC1BQkFQVUJBQUFBQUpnQ0FLQUNBTFVDQUFBQUFMMENBQUFBQU9BQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEcnJDdUNyb0RDVk5KVGpNNk5EY3pOZUFEcUJXSUJBQ1FCQUNZQkFIQkIFRQkBCHlRUQkJAQEUTmdFQVBFEY0BkEg0QkFDSUJmOGuaAokBIUl3OTBCOikBJG5QRmJJQVFvQUQROFhEZ1B6b0pVMGxPTXpvME56TTFRS2dWUxFoDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwQGVBQS7CAi9odHRwOi8vcHJlYmlkLm9yZy9kZXYtZG9jcy9nZXR0aW5nLXN0YXJ0ZWQuaHRtbNgCAOACrZhI6gJTDTrYdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2dwdC9oZWxsb193b3JsZAVO8EA_cGJqc19kZWJ1Zz10cnVlgAMAiAMBkAMAmAMXoAMBqgMAwAOsAsgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw248F6YBACiBAsxMC43NS43NC42OagEkECyBBIIBBAEGKwCIPoBKAEoAjAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggA4AQB8ATTgZcuiAUBmAUAoAX______wEDFAHABQDJBWmAFPA_0gUJCQkMcAAA2AUB4AUB8AUB-gUECAAQAJAGAJgGALgGAMEGCSM08L_IBgDQBvUv2gYWChAJFBkBUBAAGADgBgHyBgIIAIAHAYgHAKAHAQ..&s=68cfb6ed042ea47f5d3fc2c32cc068500e542066", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "banner", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 96846035, - "media_type_id": 1, - "media_subtype_id": 1, - "cpm": 0.5, - "cpm_publisher_currency": 0.5, - "is_bin_price_applied": false, - "publisher_currency_code": "$", - "brand_category_id": 0, - "test": 99999, - "client_initiated_ad_counting": true, - "rtb": { - "banner": { - "content": "
", - "width": 300, - "height": 250 - }, - "trackers": [ - { - "impression_urls": [ - "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Fgpt%2Fhello_world.html%3Fpbjs_debug%3Dtrue&e=wqT_3QK7CKA7BAAAAwDWAAUBCJKPpe4FEKjwl-js2byJcRiq5MnUovf28WEqNgkAAAECCOA_EQEHNAAA4D8ZAAAAgOtR4D8hERIAKREJADERG6gwsqKiBjjtSEDtSEgCUNOBly5YnPFbYABotc95eJK4BYABAYoBA1VTRJIBAQbwUpgBrAKgAfoBqAEBsAEAuAEBwAEEyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTczNDcyMTQ2KTt1ZigncicsIDk2ODQ2MDM1Nh4A8PWSAqUCIXp6ZmhVQWl1c0s0S0VOT0JseTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFzcUtpQmxnQVlJSUNhQUJ3Q0hncWdBRWtpQUVxa0FFQW1BRUFvQUVCcUFFRHNBRUF1UUVwaTRpREFBRGdQOEVCS1l1SWd3QUE0RF9KQVozRkl5WjA1Tm9fMlFFQUFBQUFBQUR3UC1BQkFQVUJBQUFBQUpnQ0FLQUNBTFVDQUFBQUFMMENBQUFBQU9BQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEcnJDdUNyb0RDVk5KVGpNNk5EY3pOZUFEcUJXSUJBQ1FCQUNZQkFIQkIFRQkBCHlRUQkJAQEUTmdFQVBFEY0BkEg0QkFDSUJmOGuaAokBIUl3OTBCOikBJG5QRmJJQVFvQUQROFhEZ1B6b0pVMGxPTXpvME56TTFRS2dWUxFoDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwQGVBQS7CAi9odHRwOi8vcHJlYmlkLm9yZy9kZXYtZG9jcy9nZXR0aW5nLXN0YXJ0ZWQuaHRtbNgCAOACrZhI6gJTDTrYdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2dwdC9oZWxsb193b3JsZAVO8EA_cGJqc19kZWJ1Zz10cnVlgAMAiAMBkAMAmAMXoAMBqgMAwAOsAsgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw248F6YBACiBAsxMC43NS43NC42OagEkECyBBIIBBAEGKwCIPoBKAEoAjAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggB4AQB8ATTgZcuiAUBmAUAoAX______wEDFAHABQDJBWmIFPA_0gUJCQkMcAAA2AUB4AUB8AUB-gUECAAQAJAGAJgGALgGAMEGCSM08D_IBgDQBvUv2gYWChAJFBkBUBAAGADgBgHyBgIIAIAHAYgHAKAHAQ..&s=951a029669a69e3f0c527c937c2d852be92802e1" - ], - "video_events": {} - } - ] - } - } - ] - }, - { - "tag_id": 13144370, - "auction_id": "8147841645883553832", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Fgpt%2Fhello_world.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKzCKAzBAAAAwDWAAUBCJKPpe4FEKjwl-js2byJcRiq5MnUovf28WEqNgkAAAkCABEJBywAABkAAACA61HgPyEREgApEQkAMREb8GkwsqKiBjjtSEDtSEgAUABYnPFbYABotc95eACAAQGKAQCSAQNVU0SYAawCoAH6AagBAbABALgBAcABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3MzQ3MjE0Nik7AR0scicsIDk2ODQ2MDM1Nh4A8PWSAqUCIXp6ZmhVQWl1c0s0S0VOT0JseTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFzcUtpQmxnQVlJSUNhQUJ3Q0hncWdBRWtpQUVxa0FFQW1BRUFvQUVCcUFFRHNBRUF1UUVwaTRpREFBRGdQOEVCS1l1SWd3QUE0RF9KQVozRkl5WjA1Tm9fMlFFQUFBQUFBQUR3UC1BQkFQVUJBQUFBQUpnQ0FLQUNBTFVDQUFBQUFMMENBQUFBQU9BQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEcnJDdUNyb0RDVk5KVGpNNk5EY3pOZUFEcUJXSUJBQ1FCQUNZQkFIQkIFRQkBCHlRUQkJAQEUTmdFQVBFEY0BkEg0QkFDSUJmOGuaAokBIUl3OTBCOikBJG5QRmJJQVFvQUQROFhEZ1B6b0pVMGxPTXpvME56TTFRS2dWUxFoDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwQGVBQS7CAi9odHRwOi8vcHJlYmlkLm9yZy9kZXYtZG9jcy9nZXR0aW5nLXN0YXJ0ZWQuaHRtbNgCAOACrZhI6gJTDTrYdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2dwdC9oZWxsb193b3JsZAVO8EA_cGJqc19kZWJ1Zz10cnVlgAMAiAMBkAMAmAMXoAMBqgMAwAOsAsgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw248F6YBACiBAsxMC43NS43NC42OagEkECyBBIIBBAEGKwCIPoBKAEoAjAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggA4AQB8ATTgZcuiAUBmAUAoAX______wEDFAHABQDJBWmAFPA_0gUJCQkMcAAA2AUB4AUB8AUB-gUECAAQAJAGAJgGALgGAMEGCSM08L_IBgDQBvUv2gYWChAJFBkBUBAAGADgBgHyBgIIAIAHAYgHAKAHAQ..&s=68cfb6ed042ea47f5d3fc2c32cc068500e542066", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "banner", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 968460356666, - "media_type_id": 1, - "media_subtype_id": 1, - "cpm": 0.5, - "cpm_publisher_currency": 0.5, - "is_bin_price_applied": false, - "publisher_currency_code": "$", - "brand_category_id": 0, - "client_initiated_ad_counting": true, - "rtb": { - "banner": { - "content": "
", - "width": 300, - "height": 250 - }, - "trackers": [ - { - "impression_urls": [ - "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Fgpt%2Fhello_world.html%3Fpbjs_debug%3Dtrue&e=wqT_3QK7CKA7BAAAAwDWAAUBCJKPpe4FEKjwl-js2byJcRiq5MnUovf28WEqNgkAAAECCOA_EQEHNAAA4D8ZAAAAgOtR4D8hERIAKREJADERG6gwsqKiBjjtSEDtSEgCUNOBly5YnPFbYABotc95eJK4BYABAYoBA1VTRJIBAQbwUpgBrAKgAfoBqAEBsAEAuAEBwAEEyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTczNDcyMTQ2KTt1ZigncicsIDk2ODQ2MDM1Nh4A8PWSAqUCIXp6ZmhVQWl1c0s0S0VOT0JseTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFzcUtpQmxnQVlJSUNhQUJ3Q0hncWdBRWtpQUVxa0FFQW1BRUFvQUVCcUFFRHNBRUF1UUVwaTRpREFBRGdQOEVCS1l1SWd3QUE0RF9KQVozRkl5WjA1Tm9fMlFFQUFBQUFBQUR3UC1BQkFQVUJBQUFBQUpnQ0FLQUNBTFVDQUFBQUFMMENBQUFBQU9BQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEcnJDdUNyb0RDVk5KVGpNNk5EY3pOZUFEcUJXSUJBQ1FCQUNZQkFIQkIFRQkBCHlRUQkJAQEUTmdFQVBFEY0BkEg0QkFDSUJmOGuaAokBIUl3OTBCOikBJG5QRmJJQVFvQUQROFhEZ1B6b0pVMGxPTXpvME56TTFRS2dWUxFoDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwQGVBQS7CAi9odHRwOi8vcHJlYmlkLm9yZy9kZXYtZG9jcy9nZXR0aW5nLXN0YXJ0ZWQuaHRtbNgCAOACrZhI6gJTDTrYdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2dwdC9oZWxsb193b3JsZAVO8EA_cGJqc19kZWJ1Zz10cnVlgAMAiAMBkAMAmAMXoAMBqgMAwAOsAsgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw248F6YBACiBAsxMC43NS43NC42OagEkECyBBIIBBAEGKwCIPoBKAEoAjAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggB4AQB8ATTgZcuiAUBmAUAoAX______wEDFAHABQDJBWmIFPA_0gUJCQkMcAAA2AUB4AUB8AUB-gUECAAQAJAGAJgGALgGAMEGCSM08D_IBgDQBvUv2gYWChAJFBkBUBAAGADgBgHyBgIIAIAHAYgHAKAHAQ..&s=951a029669a69e3f0c527c937c2d852be92802e1" - ], - "video_events": {} - } - ] - } - } - ] - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-instream/description.md b/test/fake-server/fixtures/basic-instream/description.md deleted file mode 100644 index 5d185f23ad3..00000000000 --- a/test/fake-server/fixtures/basic-instream/description.md +++ /dev/null @@ -1,28 +0,0 @@ -Test Page - 'test/pages/instream.html' -Test Spec File - 'test/spec/e2e/instream/basic_instream_ad.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'video1', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480] - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: '13232361', - video: { - skipppable: false, - playback_methods: ['auto_play_sound_off'] - } - } - } - ] -}]; -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-instream/request.json b/test/fake-server/fixtures/basic-instream/request.json deleted file mode 100644 index db07ad3e98a..00000000000 --- a/test/fake-server/fixtures/basic-instream/request.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 13232361, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "require_asset_url": true, - "video": {}, - "hb_source": 1 - } - ], - "user": {} - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-instream/response.json b/test/fake-server/fixtures/basic-instream/response.json deleted file mode 100644 index 5f51034f0be..00000000000 --- a/test/fake-server/fixtures/basic-instream/response.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [{ - "tag_id": 13232361, - "auction_id": "1398509384102899505", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Finstream.html&e=wqT_3QKxCKAxBAAAAwDWAAUBCKXQzPAFELHeg_SAnKC0ExjCs_b6q5D9_0oqNgkAAAkCABEJBywAABkAAADgehQUQCEREgApEQkAMREb8Hkw6dGnBjjtSEDtSEgAUABYnPFbYABozbp1eACAAQGKAQCSAQNVU0SYAQGgAQGoAQGwAQC4AQPAAQDIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzgzMTM3NjUpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPD1kgK1AiF5andtb2dpMi1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNmRHbkJsZ0FZTUlHYUFCd0tIZ0dnQUU4aUFFR2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFVUU1FQjg2MXFwQUFBRkVESkFmZjUwcVFyNGVvXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHR2aThDcm9EQ1ZOSlRqTTZORGN6T09BRC1SaUlCQUNRQkFDWUJBSEJCBUUJAQh5UVEJCQEBFE5nRUFQRRGNAZAsNEJBQ0lCWUlscVFVAREBFDx3UHcuLpoCiQEhTGc5WkRRNjkBJG5QRmJJQVFvQUQVSFRVUURvSlUwbE9Nem8wTnpNNFFQa1lTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBSZUFBLsICP2h0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctdmlkZW8td2l0aC1hLWRmcC12aWRlby10YWcuaHRtbNgCAOACrZhI6gIzaHQFSkh0ZXN0LmxvY2FsaG9zdDo5OTk5BRQ4L3BhZ2VzL2luc3RyZWFtBT7IgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvCanwXpgEAKIECzEwLjc1Ljc0LjY5qAS0LLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM42gQCCADgBADwBMuBwC6IBQGYBQCgBf______AQMUAcAFAMkFaX8U8D_SBQkJCQx4AADYBQHgBQHwBcOVC_oFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=6805157848bdfdf973d0dbafff4bb9b4c4ce7e60", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [{ - "content_source": "rtb", - "ad_type": "video", - "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQklKBNeAAAAABEx74AO4IBoExklKBNeAAAAACDLgcAuKAAw7Ug47UhA0-hISLuv1AFQ6dGnBljDlQtiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcuBwC6wAQE.&s=07e6e5f2f03cc92e899c3ddbf4e2988e966caaa2&event_type=1", - "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 97517771, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 10.000000, - "cpm_publisher_currency": 10.000000, - "publisher_currency_code": "$", - "brand_category_id": 36, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": ["auto_play_sound_on"], - "frameworks": ["vpaid_1_0", "vpaid_2_0"], - "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Finstream.html&e=wqT_3QKNCaCNBAAAAwDWAAUBCKXQzPAFELHeg_SAnKC0ExjCs_b6q5D9_0oqNgkAAAECCBRAEQEHNAAAFEAZAAAA4HoUFEAhERIAKREJADERG6gw6dGnBjjtSEDtSEgCUMuBwC5YnPFbYABozbp1eJG4BYABAYoBA1VTRJIBAQbwUpgBAaABAagBAbABALgBA8ABBMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3ODMxMzc2NSk7dWYoJ3InLCA5NzUxNzc3MSwgLh4A8PWSArUCIXlqd21vZ2kyLUx3S0VNdUJ3QzRZQUNDYzhWc3dBRGdBUUFSSTdVaFE2ZEduQmxnQVlNSUdhQUJ3S0hnR2dBRThpQUVHa0FFQW1BRUFvQUVCcUFFRHNBRUF1UUh6cldxa0FBQVVRTUVCODYxcXBBQUFGRURKQWZmNTBxUXI0ZW9fMlFFQUFBQUFBQUR3UC1BQkFQVUJBQUFBQUpnQ0FLQUNBTFVDQUFBQUFMMENBQUFBQU9BQ0FPZ0NBUGdDQUlBREFaZ0RBYWdEdHZpOENyb0RDVk5KVGpNNk5EY3pPT0FELVJpSUJBQ1FCQUNZQkFIQkIFRQkBCHlRUQkJAQEUTmdFQVBFEY0BkCw0QkFDSUJZSWxxUVUBEQEUPHdQdy4umgKJASFMZzlaRFE2OQEkblBGYklBUW9BRBVIVFVRRG9KVTBsT016bzBOek00UVBrWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8FJlQUEuwgI_aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy12aWRlby13aXRoLWEtZGZwLXZpZGVvLXRhZy5odG1s2AIA4AKtmEjqAjNodAVKSHRlc3QubG9jYWxob3N0Ojk5OTkFFDgvcGFnZXMvaW5zdHJlYW0FPmjyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-4ElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw398F6YBACiBAsxMC43NS43NC42OagEtCyyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczONoEAggB4AQA8ATLgcAuiAUBmAUAoAX______wEDFAHABQDJBWnbFPA_0gUJCQkMeAAA2AUB4AUB8AXDlQv6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=68b9d39d60a72307a201e479000a8c7be5508188" - } - } - }] - }] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-native/description.md b/test/fake-server/fixtures/basic-native/description.md deleted file mode 100644 index 950cc5da7d7..00000000000 --- a/test/fake-server/fixtures/basic-native/description.md +++ /dev/null @@ -1,62 +0,0 @@ -Test Page - 'test/pages/native.html' -Test Spec File - 'test/spec/e2e/native/basic_native_ad.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: '/19968336/prebid_native_example_1', - sizes: [360, 360], - mediaTypes: { - native: { - title: { - required: true - }, - image: { - required: true - }, - sponsoredBy: { - required: true - } - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13232354, - allowSmallerSizes: true - } - }] -}, { - code: '/19968336/prebid_native_example_2', - sizes: [ - [1, 1] - ], - mediaTypes: { - native: { - title: { - required: true - }, - body: { - required: true - }, - image: { - required: true - }, - sponsoredBy: { - required: true - }, - icon: { - required: false - }, - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13232354, - allowSmallerSizes: true - } - }] -}]; -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-native/request.json b/test/fake-server/fixtures/basic-native/request.json deleted file mode 100644 index 08e75d5bd69..00000000000 --- a/test/fake-server/fixtures/basic-native/request.json +++ /dev/null @@ -1,81 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 1, - "height": 1 - } - ], - "ad_types": [ - "native" - ], - "id": 13232354, - "allow_smaller_sizes": true, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "native": { - "layouts": [ - { - "title": { - "required": true - }, - "main_image": { - "required": true - }, - "sponsored_by": { - "required": true - } - } - ] - }, - "hb_source": 1 - }, - { - "sizes": [ - { - "width": 1, - "height": 1 - } - ], - "ad_types": [ - "native" - ], - "id": 13232354, - "allow_smaller_sizes": true, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "native": { - "layouts": [ - { - "title": { - "required": true - }, - "description": { - "required": true - }, - "main_image": { - "required": true - }, - "sponsored_by": { - "required": true - }, - "icon": { - "required": false - } - } - ] - }, - "hb_source": 1 - } - ], - "user": {} - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-native/response.json b/test/fake-server/fixtures/basic-native/response.json deleted file mode 100644 index fb85110663d..00000000000 --- a/test/fake-server/fixtures/basic-native/response.json +++ /dev/null @@ -1,116 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "tag_id": 13232354, - "auction_id": "2566965852006062421", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fnative.html&e=wqT_3QLhB6DhAwAAAwDWAAUBCNDZme8FENWyhPv4uuzPIxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMOLRpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc1MzgyMjI0KTsBHThyJywgOTc0OTQ0MDMsIDEdHvDQkgKpAiFCenhPTlFqOC1Md0tFSVBMdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZSUlDYUFCd0FIZ0FnQUdtQVlnQl9GLVFBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0JRTDdBTHVfbzFqX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBUDgBxIh1Z01KVTBsT016bzBOelF5NEFQbUZvZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BAVBQZ0VBSWdGaGlVLpoCiQEhYWdfb0o6LQEkblBGYklBUW9BRBVYDGtRRG8yhQAQUU9ZV1MRWAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0MoGVBQS7YAgDgAq2YSOoCMWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5BRTwvC9wYWdlcy9uYXRpdmUuaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qATruAKyBA4IABABGAAgACgAMAA4ArgEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQy2gQCCADgBAHwBIPLvi6IBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQkMeAAA2AUB4AUB8AWZ9CH6BQQIABAAkAYBmAYAuAYAwQYJJTTwv8gGANAG9S_aBhYKEAkUGQFQEAAYAOAGDPIGAggAgAcBiAcAoAdB&s=54514bb848c51d509dfe3e21af09b77edfe9738e", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "native", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 97494403, - "media_type_id": 12, - "media_subtype_id": 65, - "cpm": 10, - "cpm_publisher_currency": 10, - "publisher_currency_code": "$", - "brand_category_id": 53, - "client_initiated_ad_counting": true, - "viewability": { - "config": "" - }, - "rtb": { - "native": { - "title": "This is a Prebid Native Creative", - "sponsored": "Prebid.org", - "main_img": { - "url": "http://vcdn.adnxs.com/p/creative-image/94/22/cd/0f/9422cd0f-f400-45d3-80f5-2b92629d9257.jpg", - "width": 3000, - "height": 2250, - "prevent_crop": false - }, - "link": { - "url": "http://prebid.org/dev-docs/show-native-ads.html", - "click_trackers": [ - "http://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQFUZYY_XsZ8jKnKSKrrb42HQbOZdAAAAAOLoyQBtJAAAbSQAAAIAAACDpc8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoA8BZszgAAAAA./bcr=AAAAAAAA8D8=/cnd=%21ag_oJQj8-LwKEIPLvi4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0NzQyQOYWSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ3NDI=/bn=89169/" - ] - }, - "impression_trackers": [ - "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fnative.html&e=wqT_3QLpB6DpAwAAAwDWAAUBCNDZme8FENWyhPv4uuzPIxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlCDy74uWJzxW2AAaM26dXjRuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzUzODIyMjQpO3VmKCdyJywgOTc0OTQ0MDMsIC4eAPDQkgKpAiFCenhPTlFqOC1Md0tFSVBMdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZSUlDYUFCd0FIZ0FnQUdtQVlnQl9GLVFBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0JRTDdBTHVfbzFqX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBUDgBxIh1Z01KVTBsT016bzBOelF5NEFQbUZvZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BAVBQZ0VBSWdGaGlVLpoCiQEhYWdfb0o6LQEkblBGYklBUW9BRBVYDGtRRG8yhQAQUU9ZV1MRWAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0MoGVBQS7YAgDgAq2YSOoCMWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5BRTwlS9wYWdlcy9uYXRpdmUuaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qATruAKyBA4IABABGAAgACgAMAA4ArgEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQy2gQCCAHgBAHwBEH6IIgFAZgFAKAF_xEBGAHABQDJBQAFARTwP9IFCQkFC3wAAADYBQHgBQHwBZn0IfoFBAgAEACQBgGYBgC4BgDBBgEhQAAA8D_IBgDQBvUv2gYWChAAOgEAUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=6b203c7aee654cffa9c0b3771f6945f6d1e8d06c" - ], - "id": 97494403 - } - } - } - ] - }, - { - "tag_id": 13232354, - "auction_id": "6083251961435599864", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fnative.html&e=wqT_3QLhB6DhAwAAAwDWAAUBCNDZme8FEPjnxITbrYO2VBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMOLRpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc1MzgyMjI0KTsBHSxyJywgOTc0OTQyMDQ2HgDw0JICqQIhYlR3OWZBajgtTHdLRUx6SnZpNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTR0R25CbGdBWUlJQ2FBQndBSGdBZ0FHbUFZZ0JfRi1RQVFDWUFRQ2dBUUdvQVFPd0FRQzVBZk90YXFRQUFDUkF3UUh6cldxa0FBQWtRTWtCeVdmYjBYeWIxVF9aQVFBQUFBQUFBUEFfNEFFQTlRRUFBQUFBbUFJQW9BSUF0UUlBQUFBQXZRSUFBQUFBNEFJQTZBSUEtQUlBZ0FNQm1BTUJxQVA4AcSIdWdNSlUwbE9Nem8wTnpReTRBUG1Gb2dFQUpBRUFKZ0VBY0UJXQUBCERKQgUICQEYMkFRQThRUQkNAQFUUGdFQUlnRmhpVS6aAokBIW9ROTNPUTYtASRuUEZiSUFRb0FEFVgMa1FEbzKFABBRT1lXUxFYDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQygZUFBLtgCAOACrZhI6gIxaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkFFPC8L3BhZ2VzL25hdGl2ZS5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBOu4ArIEDggAEAEYACAAKAAwADgCuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDLaBAIIAOAEAfAEvMm-LogFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJCQx4AADYBQHgBQHwBZn0IfoFBAgAEACQBgGYBgC4BgDBBgklNPC_yAYA0Ab1L9oGFgoQCRQZAVAQABgA4AYM8gYCCACABwGIBwCgB0E.&s=99a73b39ab82dd9384eee306ff03276ab688cfe5", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "native", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 97494204, - "media_type_id": 12, - "media_subtype_id": 65, - "cpm": 10, - "cpm_publisher_currency": 10, - "publisher_currency_code": "$", - "brand_category_id": 53, - "client_initiated_ad_counting": true, - "viewability": { - "config": "" - }, - "rtb": { - "native": { - "title": "This is a Prebid Native Creative", - "desc": "This is a Prebid Native Creative. There are many like it, but this one is mine.", - "sponsored": "Prebid.org", - "icon": { - "url": "http://vcdn.adnxs.com/p/creative-image/1a/3e/e9/5b/1a3ee95b-06cd-4260-98c7-0258627c9197.png", - "width": 127, - "height": 83, - "prevent_crop": false - }, - "main_img": { - "url": "http://vcdn.adnxs.com/p/creative-image/f8/7f/0f/13/f87f0f13-230c-4f05-8087-db9216e393de.jpg", - "width": 989, - "height": 742, - "prevent_crop": false - }, - "link": { - "url": "http://prebid.org/dev-docs/show-native-ads.html", - "click_trackers": [ - "http://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQPgzkbBtDWxUKnKSKrrb42HQbOZdAAAAAOLoyQBtJAAAbSQAAAIAAAC8pM8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoAJhcX3AAAAAA./bcr=AAAAAAAA8D8=/cnd=%21oQ93OQj8-LwKELzJvi4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0NzQyQOYWSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ3NDI=/bn=89169/" - ] - }, - "impression_trackers": [ - "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fnative.html&e=wqT_3QLpB6DpAwAAAwDWAAUBCNDZme8FEPjnxITbrYO2VBiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlC8yb4uWJzxW2AAaM26dXjRuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzUzODIyMjQpO3VmKCdyJywgOTc0OTQyMDQsIC4eAPDQkgKpAiFiVHc5ZkFqOC1Md0tFTHpKdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZSUlDYUFCd0FIZ0FnQUdtQVlnQl9GLVFBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0J5V2ZiMFh5YjFUX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBUDgBxIh1Z01KVTBsT016bzBOelF5NEFQbUZvZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BAVRQZ0VBSWdGaGlVLpoCiQEhb1E5M09RNi0BJG5QRmJJQVFvQUQVWAxrUURvMoUAEFFPWVdTEVgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDKBlQUEu2AIA4AKtmEjqAjFodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OQUU8LwvcGFnZXMvbmF0aXZlLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagE67gCsgQOCAAQARgAIAAoADAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDc0MtoEAggB4AQB8AS8yb4uiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkJDHgAANgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGCSU48D_IBgDQBvUv2gYWChAAOgEAUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=5c316c116b6e2bdb19f3950c4c769821e735688e" - ], - "id": 97494204 - } - } - } - ] - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-outstream/description.md b/test/fake-server/fixtures/basic-outstream/description.md deleted file mode 100644 index c5855d6af15..00000000000 --- a/test/fake-server/fixtures/basic-outstream/description.md +++ /dev/null @@ -1,44 +0,0 @@ -Test Page - 'test/pages/outstream.html' -Test Spec File - 'test/spec/e2e/outstream/basic_outstream_ad.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'video_ad_unit_1', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [640, 480] - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13232385, - video: { - skippable: true, - playback_method: ['auto_play_sound_off'] - } - } - }] -}, { - code: 'video_ad_unit_2', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [640, 480] - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13232385, - video: { - skippable: true, - playback_method: ['auto_play_sound_off'] - } - } - }] -}]; -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-outstream/request.json b/test/fake-server/fixtures/basic-outstream/request.json deleted file mode 100644 index 611a518fc2d..00000000000 --- a/test/fake-server/fixtures/basic-outstream/request.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [{ - "sizes": [{ - "width": 640, - "height": 480 - }], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": ["video"], - "id": 13232385, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "video": { - "skippable": true, - "playback_method": ["auto_play_sound_off"] - }, - "hb_source": 1 - }, { - "sizes": [{ - "width": 640, - "height": 480 - }], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": ["video"], - "id": 13232385, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "video": { - "skippable": true, - "playback_method": ["auto_play_sound_off"] - }, - "hb_source": 1 - }], - "user": {} - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/basic-outstream/response.json b/test/fake-server/fixtures/basic-outstream/response.json deleted file mode 100644 index 13b4e527b1f..00000000000 --- a/test/fake-server/fixtures/basic-outstream/response.json +++ /dev/null @@ -1,105 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "tag_id": 13232385, - "auction_id": "527250675737245396", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Foutstream.html&e=wqT_3QKwCKAwBAAAAwDWAAUBCOiWpO8FENTtnJej9sqoBxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMIHSpwY47UhA7UhIAFAAWJzxW2AAaOWljwF4AIABAYoBAJIBA1VTRJgBAaABAagBAbABALgBA8ABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3NTU1Mzg5NikFHTRyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFUenpuS1FqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSG5NQW5aODYzalA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TOEE4RDgumgKJASFXdzkxSDo5ASRuUEZiSUFRb0FEFVhYa1FEb0pVMGxPTXpvME9ETTBRUGtXU1ENTwxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EllQUEuwgI4aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy1vdXRzdHJlYW0tdmlkZW8tYWRzLmh0bWzYAgDgAq2YSOoCNA1DSHRlc3QubG9jYWxob3N0Ojk5OTkFFBgvcGFnZXMvFUkALgE_yIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzLwmj8F6YBACiBAsxMC43NS43NC42OagEmM8CsgQSCAQQBBiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ4MzTaBAIIAOAEAPAEy4HALogFAZgFAKAF_____wUDFAHABQDJBWlyFPA_0gUJCQkMeAAA2AUB4AUB8AXDlQv6BQQIABAAkAYBmAYAuAYAwQYJJTTwv8gGANAG9S_aBhYKEAkUGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=9953ce4d94992db04897ab580bf81b3e274b2601", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQloC-ldAAAAABHUNucysitRBxloC-ldAAAAACDLgcAuKAAw7Ug47UhA0-hISLuv1AFQgdKnBljDlQtiAi0taAFwAXgAgAECiAEEkAGABZgB4AOgAQCoAcuBwC6wAQE.&s=979aee1106a0bea5609a3c23fdc46153ad6d9eec&event_type=1", - "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 97517771, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 10, - "cpm_publisher_currency": 10, - "publisher_currency_code": "$", - "brand_category_id": 36, - "renderer_url": "http://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js", - "renderer_id": 2, - "renderer_config": "{\"skippable\":{\"videoThreshold\":null,\"skipLocation\":\"top-right\"}}", - "client_initiated_ad_counting": true, - "viewability": { - "config": "tv=vh2-121&d=1x1&s=3479483&st=0&vctx=4&ts=1575553896&vc=iab;vid_ccr=1&vjs=http%3A%2F%2Fcdn.adnxs.com%2Fv%2Fvideo%2F182%2Ftrk.js&cb=http%3A%2F%2Fsin3-ib.adnxs.com%2Fvevent%3Fan_audit%3D0%26referrer%3Dhttp%253A%252F%252Ftest.localhost%253A9999%252Ftest%252Fpages%252Foutstream.html%26e%3DwqT_3QK4CKA4BAAAAwDWAAUBCOiWpO8FENTtnJej9sqoBxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIHSpwY47UhA7UhIAlDLgcAuWJzxW2AAaOWljwF4urgFgAEBigEDVVNEkgUG8FKYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzU1NTM4OTYpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFUenpuS1FqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSG5NQW5aODYzalA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TOEE4RDgumgKJASFXdzkxSDo5ASRuUEZiSUFRb0FEFVhYa1FEb0pVMGxPTXpvME9ETTBRUGtXU1ENTwxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EllQUEuwgI4aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy1vdXRzdHJlYW0tdmlkZW8tYWRzLmh0bWzYAgDgAq2YSOoCNA1DSHRlc3QubG9jYWxob3N0Ojk5OTkFFBgvcGFnZXMvFUkALgE_yIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzLwmj8F6YBACiBAsxMC43NS43NC42OagEmM8CsgQSCAQQBBiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ4MzTaBAIIAeAEAPAEy4HALogFAZgFAKAF_____wUDFAHABQDJBWl6FPA_0gUJCQkMeAAA2AUB4AUB8AXDlQv6BQQIABAAkAYBmAYAuAYAwQYJJTTwP8gGANAG9S_aBhYKEAkUGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA%26s%3D5adef946cd5f0d8db86d67860914e02ef6f91d6b&cet=0&cecb=&rdcb=http%3A%2F%2Fsin3-ib.adnxs.com%2Frd_log%3Fan_audit%3D0%26referrer%3Dhttp%253A%252F%252Ftest.localhost%253A9999%252Ftest%252Fpages%252Foutstream.html%26e%3DwqT_3QKMCaCMBAAAAwDWAAUBCOiWpO8FENTtnJej9sqoBxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIHSpwY47UhA7UhIAlDLgcAuWJzxW2AAaOWljwF4urgFgAEBigEDVVNEkgUG8FKYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzU1NTM4OTYpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFUenpuS1FqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSG5NQW5aODYzalA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TOEE4RDgumgKJASFXdzkxSDo5ASRuUEZiSUFRb0FEFVhYa1FEb0pVMGxPTXpvME9ETTBRUGtXU1ENTwxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EllQUEuwgI4aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy1vdXRzdHJlYW0tdmlkZW8tYWRzLmh0bWzYAgDgAq2YSOoCNA1DSHRlc3QubG9jYWxob3N0Ojk5OTkFFBgvcGFnZXMvFUkALgE_aPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7gSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDffwXpgEAKIECzEwLjc1Ljc0LjY5qASYzwKyBBIIBBAEGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDgzNNoEAggB4AQA8ATLgcAuiAUBmAUAoAX_____BQMUAcAFAMkFac4U8D_SBQkJCQx4AADYBQHgBQHwBcOVC_oFBAgAEACQBgGYBgC4BgDBBgklNPA_yAYA0Ab1L9oGFgoQCRQZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.%26s%3Df2a73057b50fb0c9e98a6093141472a4ed2e401e&bridge=1.11.0&rblog=auc=527250675737245396;bm=9325;sm=9325;cr=97517771;pl=13232385&vid_context=anoutstream;anbannerstream;anoverlayplayer" - }, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_off" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "content": "adnxs00:00:30.000" - } - } - } - ] - }, - { - "tag_id": 13232385, - "auction_id": "3449642271543746980", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Foutstream.html&e=wqT_3QKwCKAwBAAAAwDWAAUBCOiWpO8FEKTDpazn6-XvLxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMIHSpwY47UhA7UhIAFAAWJzxW2AAaOWljwF4AIABAYoBAJIBA1VTRJgBAaABAagBAbABALgBA8ABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3NTU1Mzg5NikFHTRyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFvendNV2dqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSHIwdDF2TTdMaVA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TPEE4RDgumgKJASFXdzkxSFE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBPRE0wUVBrV1NRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBJZUFBLsICOGh0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctb3V0c3RyZWFtLXZpZGVvLWFkcy5odG1s2AIA4AKtmEjqAjQNQ0h0ZXN0LmxvY2FsaG9zdDo5OTk5BRQYL3BhZ2VzLxVJAC4BP8iAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My8Jo_BemAQAogQLMTAuNzUuNzQuNjmoBJjPArIEEggEEAQYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0ODM02gQCCADgBADwBMuBwC6IBQGYBQCgBf____8FAxQBwAUAyQVpchTwP9IFCQkJDHgAANgFAeAFAfAFw5UL-gUECAAQAJAGAZgGALgGAMEGCSU08L_IBgDQBvUv2gYWChAJFBkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=e43b45a2391036da6d93eda546d8808de0169bb1", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQloC-ldAAAAABGkYYl1XpffLxloC-ldAAAAACDLgcAuKAAw7Ug47UhA0-hISLuv1AFQgdKnBljDlQtiAi0taAFwAXgAgAECiAEEkAGABZgB4AOgAQCoAcuBwC6wAQE.&s=414834fdc6e268f284292aedf8b01ee525c3e999&event_type=1", - "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 97517771, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 10, - "cpm_publisher_currency": 10, - "publisher_currency_code": "$", - "brand_category_id": 36, - "renderer_url": "http://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js", - "renderer_id": 2, - "renderer_config": "{\"skippable\":{\"videoThreshold\":null,\"skipLocation\":\"top-right\"}}", - "client_initiated_ad_counting": true, - "viewability": { - "config": "tv=vh2-121&d=1x1&s=3479483&st=0&vctx=4&ts=1575553896&vc=iab;vid_ccr=1&vjs=http%3A%2F%2Fcdn.adnxs.com%2Fv%2Fvideo%2F182%2Ftrk.js&cb=http%3A%2F%2Fsin3-ib.adnxs.com%2Fvevent%3Fan_audit%3D0%26referrer%3Dhttp%253A%252F%252Ftest.localhost%253A9999%252Ftest%252Fpages%252Foutstream.html%26e%3DwqT_3QK4CKA4BAAAAwDWAAUBCOiWpO8FEKTDpazn6-XvLxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIHSpwY47UhA7UhIAlDLgcAuWJzxW2AAaOWljwF4urgFgAEBigEDVVNEkgUG8FKYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzU1NTM4OTYpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFvendNV2dqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSHIwdDF2TTdMaVA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TPEE4RDgumgKJASFXdzkxSFE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBPRE0wUVBrV1NRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBJZUFBLsICOGh0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctb3V0c3RyZWFtLXZpZGVvLWFkcy5odG1s2AIA4AKtmEjqAjQNQ0h0ZXN0LmxvY2FsaG9zdDo5OTk5BRQYL3BhZ2VzLxVJAC4BP8iAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My8Jo_BemAQAogQLMTAuNzUuNzQuNjmoBJjPArIEEggEEAQYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0ODM02gQCCAHgBADwBMuBwC6IBQGYBQCgBf____8FAxQBwAUAyQVpehTwP9IFCQkJDHgAANgFAeAFAfAFw5UL-gUECAAQAJAGAZgGALgGAMEGCSU08D_IBgDQBvUv2gYWChAJFBkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..%26s%3Dc2a8dac8959d9366981afc868ec5b54853090944&cet=0&cecb=&rdcb=http%3A%2F%2Fsin3-ib.adnxs.com%2Frd_log%3Fan_audit%3D0%26referrer%3Dhttp%253A%252F%252Ftest.localhost%253A9999%252Ftest%252Fpages%252Foutstream.html%26e%3DwqT_3QKMCaCMBAAAAwDWAAUBCOiWpO8FEKTDpazn6-XvLxiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIHSpwY47UhA7UhIAlDLgcAuWJzxW2AAaOWljwF4urgFgAEBigEDVVNEkgUG8FKYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzU1NTM4OTYpO3VmKCdyJywgOTc1MTc3NzEsIC4eAPCakgK1AiFvendNV2dqWS1Md0tFTXVCd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRZ2RLbkJsZ0FZSUlDYUFCd0FIZ0FnQUhBQVlnQkFKQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRSHIwdDF2TTdMaVA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BOWo0dkFxNkF3bFRTVTR6T2pRNE16VGdBX2tXaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhpSmFrRg0TPEE4RDgumgKJASFXdzkxSFE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBPRE0wUVBrV1NRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBJZUFBLsICOGh0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctb3V0c3RyZWFtLXZpZGVvLWFkcy5odG1s2AIA4AKtmEjqAjQNQ0h0ZXN0LmxvY2FsaG9zdDo5OTk5BRQYL3BhZ2VzLxVJAC4BP2jyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-4ElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92Mw338F6YBACiBAsxMC43NS43NC42OagEmM8CsgQSCAQQBBiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ4MzTaBAIIAeAEAPAEy4HALogFAZgFAKAF_____wUDFAHABQDJBWnOFPA_0gUJCQkMeAAA2AUB4AUB8AXDlQv6BQQIABAAkAYBmAYAuAYAwQYJJTTwP8gGANAG9S_aBhYKEAkUGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA%26s%3D4e9e218d8f075cb19c4a4e8da2a7e716fa15d3c5&bridge=1.11.0&rblog=auc=3449642271543746980;bm=9325;sm=9325;cr=97517771;pl=13232385&vid_context=anoutstream;anbannerstream;anoverlayplayer" - }, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_off" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "content": "adnxs00:00:30.000" - } - } - } - ] - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/index.js b/test/fake-server/fixtures/index.js deleted file mode 100644 index bd58bda5ad5..00000000000 --- a/test/fake-server/fixtures/index.js +++ /dev/null @@ -1,41 +0,0 @@ -/* eslint-disable no-console */ - -const path = require('path'); -const fs = require('fs'); - -const REQ_RES_PAIRS = {}; - -/** - * @param {String} dirname - Path of the fixture directory - * @returns {object} reqResPair - An object containing 'request' - 'response' segregated by ad unit media type. - */ -function getReqResPairs (dirname) { - try { - const filenames = fs.readdirSync(dirname, { withFileTypes: true }); - filenames.forEach(filename => { - if (filename.isDirectory()) { - getReqResPairs(`${dirname}/${filename.name}`); - } else { - if (filename.name === 'request.json' || filename.name === 'response.json') { - const parentDir = path.basename(dirname); - if (!REQ_RES_PAIRS[parentDir]) { - REQ_RES_PAIRS[parentDir] = { - request: {}, - response: {} - } - } - if (filename.name === 'request.json') { - REQ_RES_PAIRS[parentDir]['request'] = JSON.parse(fs.readFileSync(`${dirname}/${filename.name}`, { encoding: 'utf-8' })); - } else { - REQ_RES_PAIRS[parentDir]['response'] = JSON.parse(fs.readFileSync(`${dirname}/${filename.name}`, { encoding: 'utf-8' })); - } - } - } - }); - return REQ_RES_PAIRS; - } catch (e) { - console.error(`Error:: ${e.message}`); - } -} - -module.exports = getReqResPairs; diff --git a/test/fake-server/fixtures/longform/longform_biddersettings_1/description.md b/test/fake-server/fixtures/longform/longform_biddersettings_1/description.md deleted file mode 100644 index 207e851af74..00000000000 --- a/test/fake-server/fixtures/longform/longform_biddersettings_1/description.md +++ /dev/null @@ -1,41 +0,0 @@ -Test Page - 'integrationExamples/longform/basic_w_bidderSettings.html' -Test Spec File - 'test/spec/e2e/longform/basic_w_bidderSettings.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'sample-code', - sizes: [640, 480], - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 300, - durationRangeSec: [15, 30], - requireExactDuration: false - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 15394006 - } - } - ] -}]; -``` - -SetConfig to use with AdUnit: -``` -pbjs.setConfig({ - debug: true, - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - }, - adpod: { - brandCategoryExclusion: true - } -}); -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_biddersettings_1/request.json b/test/fake-server/fixtures/longform/longform_biddersettings_1/request.json deleted file mode 100644 index aba76398093..00000000000 --- a/test/fake-server/fixtures/longform/longform_biddersettings_1/request.json +++ /dev/null @@ -1,387 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - } - ], - "user": {}, - "brand_category_uniqueness": true - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_biddersettings_1/response.json b/test/fake-server/fixtures/longform/longform_biddersettings_1/response.json deleted file mode 100644 index e3ea15d7c6e..00000000000 --- a/test/fake-server/fixtures/longform/longform_biddersettings_1/response.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "uuid": "2d4806af582cf6", - "tag_id": 15394006, - "auction_id": "2678252910506723691", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2d4806af582cf6", - "tag_id": 15394006, - "auction_id": "3548675574061430850", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2d4806af582cf6", - "tag_id": 15394006, - "auction_id": "8693167356543642173", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2d4806af582cf6", - "tag_id": 15394006, - "auction_id": "7686428711280367086", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2d4806af582cf6", - "tag_id": 15394006, - "auction_id": "3784359541475413084", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2d4806af582cf6", - "tag_id": 15394006, - "auction_id": "7233136875958651734", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2d4806af582cf6", - "tag_id": 15394006, - "auction_id": "159775901183771330", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2d4806af582cf6", - "tag_id": 15394006, - "auction_id": "6558726890185052779", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2d4806af582cf6", - "tag_id": 15394006, - "auction_id": "6624810255570939818", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2d4806af582cf6", - "tag_id": 15394006, - "auction_id": "528384387675374412", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2d4806af582cf6", - "tag_id": 15394006, - "auction_id": "2535665225687089273", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2d4806af582cf6", - "tag_id": 15394006, - "auction_id": "2166694611986638079", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2d4806af582cf6", - "tag_id": 15394006, - "auction_id": "9137369006412413609", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2d4806af582cf6", - "tag_id": 15394006, - "auction_id": "3524702228053475248", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2d4806af582cf6", - "tag_id": 15394006, - "auction_id": "57990683038266307", - "nobid": true, - "ad_profile_id": 1182765 - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_biddersettings_2/description.md b/test/fake-server/fixtures/longform/longform_biddersettings_2/description.md deleted file mode 100644 index cafbb17f61b..00000000000 --- a/test/fake-server/fixtures/longform/longform_biddersettings_2/description.md +++ /dev/null @@ -1,28 +0,0 @@ -Test Page - 'integrationExamples/longform/basic_w_bidderSettings.html' -Test Spec File - 'test/spec/e2e/longform/basic_w_bidderSettings.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'sample-code', - sizes: [640, 480], - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 300, - durationRangeSec: [15, 30], - requireExactDuration: false - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 15394006 - } - } - ] -}]; -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_biddersettings_2/request.json b/test/fake-server/fixtures/longform/longform_biddersettings_2/request.json deleted file mode 100644 index f2f20700ffe..00000000000 --- a/test/fake-server/fixtures/longform/longform_biddersettings_2/request.json +++ /dev/null @@ -1,137 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - } - ], - "user": {}, - "brand_category_uniqueness": true - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_biddersettings_2/response.json b/test/fake-server/fixtures/longform/longform_biddersettings_2/response.json deleted file mode 100644 index e2332806dbb..00000000000 --- a/test/fake-server/fixtures/longform/longform_biddersettings_2/response.json +++ /dev/null @@ -1,188 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "uuid": "245a09bd675168", - "tag_id": 15394006, - "auction_id": "3810681093956255668", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QKVCKAVBAAAAwDWAAUBCKD4kfAFELT_vOy9yJDxNBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIUxEMWZkUWlua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOE13Q2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFZVS10N09mcU9BXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTS1BRG9SaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJaRWxxUVUJE0RBRHdQdy4umgKJASFLdy1SRkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV6UUtFWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9AUBZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagErLkEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTPaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAGVbFPA_0gUJCQULfAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=66ba37441db5e28c87ee52e729333fd9324333f9", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQkgfAReAAAAABG0P4_dQ0LiNBkgfAReAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=6931bf3569012d0e1f02cb5a2e88dfcafe00dba9&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149419602, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 24, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QLxCOhxBAAAAwDWAAUBCKD4kfAFELT_vOy9yJDxNBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4vLgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFMRDFmZFFpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjhNd0NrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWVUtdDdPZnFPQV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU0tQURvUmlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWkVscVFVCRNEQUR3UHcuLpoCiQEhS3ctUkZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVelFLRVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkMyHQDwlUFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKy5BLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUz2gQCCAHgBADwBGGFIIgFAZgFAKAF_xEBFAHABQDJBWm2FPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=ea46ec90cf31744c7be2af5d5f239ab4eed29098" - } - } - } - ] - }, - { - "uuid": "245a09bd675168", - "tag_id": 15394006, - "auction_id": "7325897349627488405", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QKUCKAUBAAAAwDWAAUBCKD4kfAFEJXRloy0mrTVZRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIXJUeTNJd2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOE13Q2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFVSzAtQ2hwcWRrXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTS1BRG9SaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJaRWxxUVUJE0RBRHdQdy4umgKJASFBQTlLQlE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV6UUtFWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9AUBZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagErLkEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTPaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAGVbFPA_0gUJCQULeAAAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=271fd8a0ccdfc36e320f707164588ed1b33e9861", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQkgfAReAAAAABGVqIVB09CqZRkgfAReAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=115ac2b842cf3efeb5acaeda94ddf05632c345ca&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418671, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 30, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QLwCOhwBAAAAwDWAAUBCKD4kfAFEJXRloy0mrTVZRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4vLgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFyVHkzSXdpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjhNd0NrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVUswLUNocHFka18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU0tQURvUmlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWkVscVFVCRNEQUR3UHcuLpoCiQEhQUE5S0JRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVelFLRVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkMyHQDwlUFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKy5BLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUz2gQCCAHgBADwBGGFIIgFAZgFAKAF_xEBFAHABQDJBWm2FPA_0gUJCQkMdAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgkkKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=f73e060b15a6bbcca65f918a296f155b78c74eca" - } - } - } - ] - }, - { - "uuid": "245a09bd675168", - "tag_id": 15394006, - "auction_id": "968802322305726102", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QKVCKAVBAAAAwDWAAUBCKD4kfAFEJbt7LTEkvi4DRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTsBHTByJywgMTQ5NDE0MTg4Nh8A8P2SArkCIUtUejN5d2lHa184UEVLekNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOE13Q2tBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFTT3dTTWVaYnVJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGMxTS1BRG9SaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJaRWxxUVUJE0RBRHdQdy4umgKJASF0ZzY4Nmc2PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOelV6UUtFWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9AUBZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagErLkEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTPaBAIIAOAEAPAErMKfR4gFAZgFAKAF____________AcAFAMkFAGVbFPA_0gUJCQULfAAAANgFAeAFAfAF8owB-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=e35825a106304da78477df1575f981395be21d5f", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQkgfAReAAAAABGWNptGlOBxDRkgfAReAAAAACCswp9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jyjAFiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAazCn0ewAQE.&s=677bedd5b2d21fdc3f940cbae279261c8f84c2e7&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149414188, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 13.00001, - "cpm_publisher_currency": 13.00001, - "publisher_currency_code": "$", - "brand_category_id": 32, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 29000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QLxCOhxBAAAAwDWAAUBCKD4kfAFEJbt7LTEkvi4DRiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQrMKfR1ic8VtgAGjNunV4vLgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTt1ZigncicsIDE0OTQxNDE4OCwgMTUZH_D9kgK5AiFLVHozeXdpR2tfOFBFS3pDbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjhNd0NrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBU093U01lWmJ1SV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjMU0tQURvUmlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWkVscVFVCRNEQUR3UHcuLpoCiQEhdGc2ODZnNj0BJG5QRmJJQVFvQUQVSFRxUURvSlUwbE9Nem8wTnpVelFLRVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkMyHQDwlUFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKy5BLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUz2gQCCAHgBADwBGGFIIgFAZgFAKAF_xEBFAHABQDJBWm2FPA_0gUJCQkMeAAA2AUB4AUB8AXyjAH6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=0707b1385afa81517cd338f1516aeccc46fe33e1" - } - } - } - ] - }, - { - "uuid": "245a09bd675168", - "tag_id": 15394006, - "auction_id": "1273216786519070425", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "245a09bd675168", - "tag_id": 15394006, - "auction_id": "1769115862397582681", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QKUCKAUBAAAAwDWAAUBCKD4kfAFENn63YWPsMrGGBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIXp6djFzd2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOE13Q2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFZbW5MamdJaXVRXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTS1BRG9SaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJaRWxxUVUJE0RBRHdQdy4umgKJASFGdzkxRFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV6UUtFWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9AUBZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagErLkEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTPaBAIIAOAEAPAExOefR4gFAZgFAKAF____________AcAFAMkFAGVbFPA_0gUJCQULeAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=fb3a15e7ff747fccd750671b763e312d97083c72", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQkgfAReAAAAABFZfbfwgCmNGBkgfAReAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=7f4b8dd7c7dd9faecebac2e9ec6d7ef8da08da16&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418948, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 1, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_bidderSettings.html&e=wqT_3QLwCOhwBAAAAwDWAAUBCKD4kfAFENn63YWPsMrGGBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4vLgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3MzUyMjI0KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiF6enYxc3dpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjhNd0NrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWW1uTGpnSWl1UV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU0tQURvUmlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWkVscVFVCRNEQUR3UHcuLpoCiQEhRnc5MURRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVelFLRVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJTaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2JpZGRlclNldHRpbmdzLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkMyHQDwsEFTVF9NT0RJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKy5BLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUz2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBWm2FPA_0gUJCQkMdAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgkkKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=3a27c12c33ebaaae43dbce1cafb0bae43b753fa0" - } - } - } - ] - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/description.md b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/description.md deleted file mode 100644 index 45ae30a7a41..00000000000 --- a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/description.md +++ /dev/null @@ -1,43 +0,0 @@ -Test Page - 'integrationExamples/longform/basic_w_custom_adserver_translation.html' -Test Spec File - 'test/spec/e2e/longform/basic_w_custom_adserver_translation.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'sample-code', - sizes: [640, 480], - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 300, - durationRangeSec: [15, 30], - requireExactDuration: true - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 15394006 - } - } - ] -}]; -``` - -SetConfig to use with AdUnit: -``` -pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - }, - adpod: { - brandCategoryExclusion: true - }, - brandCategoryTranslation: { - translationFile: 'custom_adserver_translation.json' - } -}); -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/request.json b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/request.json deleted file mode 100644 index e7497ac78f3..00000000000 --- a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/request.json +++ /dev/null @@ -1,402 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - } - ], - "user": {}, - "brand_category_uniqueness": true - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/response.json b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/response.json deleted file mode 100644 index b4d8483a539..00000000000 --- a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_1/response.json +++ /dev/null @@ -1,294 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "uuid": "201bba5bb8827", - "tag_id": 15394006, - "auction_id": "7360998998672342781", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCN73l_AFEP39-97ssuGTZhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIVNqMmZTQWlua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaQmtTcHl1c2Q4XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFOZzhKRnc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfC2Lmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAZXZw2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYFIiwA8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=c92cbcde5c8bf8e053f86493dd4c4698da0392de", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQne-wVeAAAAABH9_t7LloUnZhne-wVeAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=8e35c1264cd1b4f1d89f929c3a4a334cf6a68eca&event_type=1", - "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149419602, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 24, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-COh-BAAAAwDWAAUBCN73l_AFEP39-97ssuGTZhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV40rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFTajJmU0FpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnV1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWkJrU3B5dXNkOF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhTmc4SkZ3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBJLGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBNLsn0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=ca640dffaea7bfcf2b0f2e11d8877821189b74bb" - } - } - } - ] - }, - { - "uuid": "201bba5bb8827", - "tag_id": 15394006, - "auction_id": "1919339751435064934", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCN73l_AFEOasy7zbqrfRGhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIU1EMUZJQWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFRclZ0ZGpIUGVBXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASE1QTdmLVE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfC2Lmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAZXZw2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYFIiwA8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=c3130de64bc0b8df258e603dfb96f78550ab0c3c", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQne-wVeAAAAABFm1pK3Vd2iGhne-wVeAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=2c3cee10303d9b93531bed443c0781d905270598&event_type=1", - "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418123, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 12, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-COh-BAAAAwDWAAUBCN73l_AFEOasy7zbqrfRGhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV40rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFNRDFGSUFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnV1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUXJWdGRqSFBlQV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhNUE3Zi1RNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBJLGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBIvhn0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx4AADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=996a3937245f03e5eefb0cb69917d2d8d7f60424" - } - } - } - ] - }, - { - "uuid": "201bba5bb8827", - "tag_id": 15394006, - "auction_id": "3257875652791896280", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "201bba5bb8827", - "tag_id": 15394006, - "auction_id": "5756905673624319729", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "201bba5bb8827", - "tag_id": 15394006, - "auction_id": "4205438746002589111", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "201bba5bb8827", - "tag_id": 15394006, - "auction_id": "204849530930208960", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "201bba5bb8827", - "tag_id": 15394006, - "auction_id": "3482944224379652843", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "201bba5bb8827", - "tag_id": 15394006, - "auction_id": "2123689132466331410", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "201bba5bb8827", - "tag_id": 15394006, - "auction_id": "6150444453316813936", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "201bba5bb8827", - "tag_id": 15394006, - "auction_id": "2810956382376737966", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "201bba5bb8827", - "tag_id": 15394006, - "auction_id": "7164199537578897638", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKhCKAhBAAAAwDWAAUBCN73l_AFEObhocvZsJa2Yxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIXNENXVfQWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYSEZfdmZOei1NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFDd19DQnc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfC2Lmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAZXZs2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgUhLADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=2b9ed1e2e7f27fea52cbdc64cb700195bbd14d75", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQne-wVeAAAAABHmcGiZhVlsYxne-wVeAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=8ba7f141449cb45f8b6e12361a62d8d68aa9c812&event_type=1", - "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418671, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 30, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL9COh9BAAAAwDWAAUBCN73l_AFEObhocvZsJa2Yxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV40rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFzRDV1X0FpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnV1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWEhGX3ZmTnotTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhQ3dfQ0J3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBJLGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBK_ln0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx0AADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSQo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=527640949733fba32740156d743d421eb1fe2863" - } - } - } - ] - }, - { - "uuid": "201bba5bb8827", - "tag_id": 15394006, - "auction_id": "8404712946290777461", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCN73l_AFEPW6p5bQvOLRdBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIWp6MkdiZ2lta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaQ0RhTlBDYk9NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFOUS0yRjo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56TXpRSzRZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwZWVBQS7YAgDgAq2YSOoCYGh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19jdXN0b21fYWRzZXJ2ZXJfdHJhbnNsYQE18LYuaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qASSxgSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggA4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABldnDYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgUiLADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=ed84428f432d6e743bcad6f7862aed957bece82b", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQne-wVeAAAAABF13ckC5YmjdBne-wVeAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=7024b063fcacac27e184ed097ad5878c4dd4dc1d&event_type=1", - "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149417951, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 33, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-COh-BAAAAwDWAAUBCN73l_AFEPW6p5bQvOLRdBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV40rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiFqejJHYmdpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnV1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWkNEYU5QQ2JPTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNAQUR3UHcuLpoCiQEhTlEtMkY6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNXwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wn0lGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAeAEAPAE39-fR4gFAZgFAKAF______8BBRQBwAUAyQVpwxTwP9IFCQkJDHgAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=aefe9625d8e866e048a156abdf26d7c626e6a398" - } - } - } - ] - }, - { - "uuid": "201bba5bb8827", - "tag_id": 15394006, - "auction_id": "4063389973481762703", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCN73l_AFEI_fjorv9IOyOBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUwNDYyKTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIV96eHRIQWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFSVExWM2x4c2VJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFEZy1VQ1E2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfC2Lmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAExd2fR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAZXZw2AUB4AUB8AXC8hf6BQQIABAAkAYBmAYAuAYAwQYFIiwA8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=2fb33b5204f9b75c58d89487725a9d55139f9ff4", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQne-wVeAAAAABGPr0Pxpg9kOBne-wVeAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=f9ec8d0b81c1cf4eefc58a7990f4a0a78440725f&event_type=1", - "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149417669, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 10, - "cpm_publisher_currency": 10, - "publisher_currency_code": "$", - "brand_category_id": 4, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-CKB-BAAAAwDWAAUBCN73l_AFEI_fjorv9IOyOBiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjSuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc0NTA0NjIpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIV96eHRIQWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCdXVZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFSVExWM2x4c2VJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFEZy1VQ1E2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOek16UUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNXwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wn0lGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEksYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAeAEAPAExd2fR4gFAZgFAKAF______8BBRQBwAUAyQVpwxTwP9IFCQkJDHgAANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=6b79542e3cee0319d8cb83d1daf127c3aeea9b28" - } - } - } - ] - }, - { - "uuid": "201bba5bb8827", - "tag_id": 15394006, - "auction_id": "5097385192927446024", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "201bba5bb8827", - "tag_id": 15394006, - "auction_id": "2612757136292876686", - "nobid": true, - "ad_profile_id": 1182765 - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/description.md b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/description.md deleted file mode 100644 index 45ae30a7a41..00000000000 --- a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/description.md +++ /dev/null @@ -1,43 +0,0 @@ -Test Page - 'integrationExamples/longform/basic_w_custom_adserver_translation.html' -Test Spec File - 'test/spec/e2e/longform/basic_w_custom_adserver_translation.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'sample-code', - sizes: [640, 480], - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 300, - durationRangeSec: [15, 30], - requireExactDuration: true - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 15394006 - } - } - ] -}]; -``` - -SetConfig to use with AdUnit: -``` -pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - }, - adpod: { - brandCategoryExclusion: true - }, - brandCategoryTranslation: { - translationFile: 'custom_adserver_translation.json' - } -}); -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/request.json b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/request.json deleted file mode 100644 index f4cea46918f..00000000000 --- a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/request.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - } - ], - "user": {}, - "brand_category_uniqueness": true - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/response.json b/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/response.json deleted file mode 100644 index 6a81de25ebe..00000000000 --- a/test/fake-server/fixtures/longform/longform_custom_adserver_translation_2/response.json +++ /dev/null @@ -1,188 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "uuid": "285a2f41615348", - "tag_id": 15394006, - "auction_id": "2837696487158070058", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCNSDmPAFEKr2uMu5veGwJxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIV9EemhKUWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFTbnRDdFVIdU9BXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0RBRHdQdy4umgKJASFOdzh1Rnc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek0xUUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfDtLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEq8YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzXaBAIIAOAEAPAE39-fR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPC_0Ab1L9oGFgoQAAAAAAU3DQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=3414eb9e83df14945d2dbfb00e17fb3f2bad2e33", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnUAQZeAAAAABEqO26Z64VhJxnUAQZeAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=e5a720a9884e1df845be9c33658ab69f4c56981e&event_type=1", - "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149417951, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 33, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-COh-BAAAAwDWAAUBCNSDmPAFEKr2uMu5veGwJxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiFfRHpoSlFpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjd1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBU250Q3RVSHVPQV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek5lQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjhrcVFVCRNEQUR3UHcuLpoCiQEhTnc4dUZ3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNMVFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKvGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM12gQCCAHgBADwBN_fn0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx4AADYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=99418325b8f5ec79e22c1a9aedd73f03de616c2d" - } - } - } - ] - }, - { - "uuid": "285a2f41615348", - "tag_id": 15394006, - "auction_id": "8688113570839045503", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKhCKAhBAAAAwDWAAUBCNSDmPAFEP_K8rCtqJjJeBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIUN6d3Rud2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFWUzRZeVVvR09JXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0RBRHdQdy4umgKJASFKQTlsRUE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek0xUUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfDXLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEq8YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzXaBAIIAOAEAPAExOefR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGBSEsAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=2e7c9d18300402e2e183667711728f7743b70a2b", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnUAQZeAAAAABF_pRzWQmGSeBnUAQZeAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=febf12010c66ac7247f571f03c33175ca9036b32&event_type=1", - "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418948, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 1, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL9COh9BAAAAwDWAAUBCNSDmPAFEP_K8rCtqJjJeBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFDend0bndpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjd1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVlM0WXlVb0dPSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek5lQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjhrcVFVCRNEQUR3UHcuLpoCiQEhSkE5bEVBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNMVFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKvGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM12gQCCAHgBADwBMTnn0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx0AADYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGCSQo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=92aa9e9c89384c435ab9c7fa62b963d8fc087ef7" - } - } - } - ] - }, - { - "uuid": "285a2f41615348", - "tag_id": 15394006, - "auction_id": "4162295099171231907", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKhCKAhBAAAAwDWAAUBCNSDmPAFEKOxzaPwqtzhORiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIWREMGtXZ2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhSFRjUzNjWS1VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0RBRHdQdy4umgKJASFEUTg2Q0E2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek0xUUs0WVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8GVlQUEu2AIA4AKtmEjqAmBodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfY3VzdG9tX2Fkc2VydmVyX3RyYW5zbGEBNfDXLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagEq8YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzXaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGBSEsAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=95047e919846faea401c778106fb33dae0c95b02", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnUAQZeAAAAABGjWHMEV3HDORnUAQZeAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICLS1oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=50350aadc603f4bb6c59888515d60e9182da0eb8&event_type=1", - "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418671, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 30, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL9COh9BAAAAwDWAAUBCNSDmPAFEKOxzaPwqtzhORiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFkRDBrV2dpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjd1WUNrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYUhUY1MzY1ktVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek5lQURyaGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjhrcVFVCRNEQUR3UHcuLpoCiQEhRFE4NkNBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNMVFLNFlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBlZUFBLtgCAOACrZhI6gJgaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X2N1c3RvbV9hZHNlcnZlcl90cmFuc2xhATV8Lmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChYyFgAgTEVBRl9OQU1FAR0IHgoaNh0ACEFTVAE-8J9JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQLMTAuNzUuNzQuNjmoBKvGBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM12gQCCAHgBADwBK_ln0eIBQGYBQCgBf______AQUUAcAFAMkFacMU8D_SBQkJCQx0AADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSQo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=82c42e6aa09e7c842254552ae524791fa3693bbb" - } - } - } - ] - }, - { - "uuid": "285a2f41615348", - "tag_id": 15394006, - "auction_id": "1076114531988487576", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QKiCKAiBAAAAwDWAAUBCNSDmPAFEJj7vIbyjsj3Dhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NDUxOTg4KTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIVRqMWVUZ2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFZOUNHX2M3MHRvXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0BBRHdQdy4umgKJASFFQThNQzo9ASRuUEZiSUFRb0FEFUhUa1FEb0pVMGxPTXpvME56TTFRSzRZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwZWVBQS7YAgDgAq2YSOoCYGh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19jdXN0b21fYWRzZXJ2ZXJfdHJhbnNsYQE18O0uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qASrxgSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggA4AQA8ATF3Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAAAABTcNAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=c49afba7ca4b5193f7da37b17e1fbfbee2328f61", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "http://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnUAQZeAAAAABGYPc8gdyDvDhnUAQZeAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAi0taAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=47618eb9096567900e84fd1c6aff09d753b2fe91&event_type=1", - "usersync_url": "http%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149417669, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 10, - "cpm_publisher_currency": 10, - "publisher_currency_code": "$", - "brand_category_id": 4, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "http://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_custom_adserver_translation.html&e=wqT_3QL-CKB-BAAAAwDWAAUBCNSDmPAFEJj7vIbyjsj3Dhiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjWuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc0NTE5ODgpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIVRqMWVUZ2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCN3VZQ2tBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFZOUNHX2M3MHRvXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TmVBRHJoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmOGtxUVUJE0BBRHdQdy4umgKJASFFQThNQzo9ASRuUEZiSUFRb0FEFUhUa1FEb0pVMGxPTXpvME56TTFRSzRZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwZWVBQS7YAgDgAq2YSOoCYGh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19jdXN0b21fYWRzZXJ2ZXJfdHJhbnNsYQE1fC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvCfSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qASrxgSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggB4AQA8ATF3Z9HiAUBmAUAoAX______wEFFAHABQDJBWnDFPA_0gUJCQkMeAAA2AUB4AUB8AXC8hf6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=72d1ec3db5baaa29c1b0e5f07c012db606675fe5" - } - } - } - ] - }, - { - "uuid": "285a2f41615348", - "tag_id": 15394006, - "auction_id": "7495588537924508785", - "nobid": true, - "ad_profile_id": 1182765 - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_priceGran_1/description.md b/test/fake-server/fixtures/longform/longform_priceGran_1/description.md deleted file mode 100644 index 8bc4d242f46..00000000000 --- a/test/fake-server/fixtures/longform/longform_priceGran_1/description.md +++ /dev/null @@ -1,62 +0,0 @@ -Test Page - 'integrationExamples/longform/basic_w_priceGran.html' -Test Spec File - 'test/spec/e2e/longform/basic_w_priceGran.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'sample-code', - sizes: [640, 480], - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 300, - durationRangeSec: [15, 30], - requireExactDuration: false - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 15394006 - } - } - ] -}]; -``` - -SetConfig to use with AdUnit: -``` -const customConfigObject = { - 'buckets': [{ - 'precision': 2, // default is 2 if omitted - means 2.1234 rounded to 2 decimal places = 2.12 - 'min': 0, - 'max': 5, - 'increment': 0.01 // from $0 to $5, 1-cent increments - }, - { - 'precision': 2, - 'min': 5, - 'max': 8, - 'increment': 0.05 // from $5 to $8, round down to the previous 5-cent increment - }, - { - 'precision': 2, - 'min': 8, - 'max': 40, - 'increment': 0.5 // from $8 to $40, round down to the previous 50-cent increment - }] -}; - -pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - }, - adpod: { - brandCategoryExclusion: true - }, - priceGranularity: customConfigObject -}); -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_priceGran_1/request.json b/test/fake-server/fixtures/longform/longform_priceGran_1/request.json deleted file mode 100644 index aba76398093..00000000000 --- a/test/fake-server/fixtures/longform/longform_priceGran_1/request.json +++ /dev/null @@ -1,387 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - } - ], - "user": {}, - "brand_category_uniqueness": true - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_priceGran_1/response.json b/test/fake-server/fixtures/longform/longform_priceGran_1/response.json deleted file mode 100644 index 4665aa4ef9c..00000000000 --- a/test/fake-server/fixtures/longform/longform_priceGran_1/response.json +++ /dev/null @@ -1,366 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "1249897353793397796", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEKTIuZTW4KGsERiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCITFqdjBlZ2lta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFXU1JOVU1OTk9jXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFTUTgtR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAE39-fR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=e9887c670ae9fcb7eb2a0253037c64c3587f4bcb", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABEkZI5iBYdYERnJwgleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=68a5c49da3a6ecf3dfc0835cb3da72b3b2c7b080&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149417951, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 33, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEKTIuZTW4KGsERiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiExanYwZWdpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBV1NSTlVNTk5PY18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhU1E4LUd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=9514ae5f8aae1ee9dddd24dce3e812ae76e0e783" - } - } - } - ] - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "4278372095219023172", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEMT65MOLmPWvOxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIUxEeUhqUWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaQWJScDluWS1FXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASEtQTVuX2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=987d4bb0c7611d41b5974ec412469da2241084cd", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABFEPXm4wNRfOxnJwgleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=75aaa9ec84807690ceff60e39fbba6625240f9f3&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418123, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 12, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEMT65MOLmPWvOxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFMRHlIalFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWkFiUnA5blktRV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhLUE1bl9nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=9872a378866ce61fc366ca8c34bdd9302fa41a9b" - } - } - } - ] - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "8860024420878272196", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKRCKARBAAAAwDWAAUBCMmFp_AFEMSN8Z3LqMj6ehiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIU9EMjhLZ2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFkZExBS3hfN09nXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFIdzlLREE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkcADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSMo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=1289862cbe265fd9af13d2aab9635e3232421ec1", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnKwgleAAAAABHERryzRCH1ehnJwgleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=0b094204d5c18803149e081bd2bc0077d25ebb14&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418671, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 30, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLtCOhtBAAAAwDWAAUBCMmFp_AFEMSN8Z3LqMj6ehiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFPRDI4S2dpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZGRMQUt4XzdPZ18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhSHc5S0RBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMdAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgkkKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=f35771975371bb250fd6701914534b4f595fcf68" - } - } - } - ] - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "5236733650551797458", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKRCKARBAAAAwDWAAUBCMmFp_AFENLt5YOosKfWSBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIThUMjJsZ2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFkczByb2Ytbk9VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFOZzkxRkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAExOefR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkcADYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGCSMo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=e997907677e4e2f9b641d51b522a901b85944899", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnKwgleAAAAABHSdnmAgp2sSBnJwgleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=d70eef0df40cece50465a13d05a2dc11b65eadeb&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418948, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 1, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLtCOhtBAAAAwDWAAUBCMmFp_AFENLt5YOosKfWSBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiE4VDIybGdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZHMwcm9mLW5PVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhTmc5MUZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_DtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAGn1FQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=e8b6716ad3d2fcbdb79976f72d60f8e90ce8f5a6" - } - } - } - ] - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "4987762881548953446", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "201567478388503336", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEKjm-NzbkYfmAhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIXV6NlFDd2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFkejE5MUdLNk8wXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFTZy1SRzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56TXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qASv5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAaWR0ANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=4a887316a3197dfae07c1443a4debc62a2f17fef", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABEoM567jRzMAhnJwgleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=eef6278d136f8df4879846840f97933e9d67388a&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149419602, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 24, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEKjm-NzbkYfmAhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiF1ejZRQ3dpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZHoxOTFHSzZPMF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNAQUR3UHcuLpoCiQEhU2ctUkc6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8JplQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkNVU1RPTREdCEFTVAEL8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAeAEAPAEYYIgiAUBmAUAoAX_EQEUAcAFAMkFabMU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=e68b089e4fc94aa7566784ccbff299e50c8bc090" - } - } - } - ] - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "3876520534914199302", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "4833995299234629234", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "8352235304492782614", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEJaok6aeuMb0cxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE0MTg4Nh8A8P2SArkCIUpUMS1FZ2lHa184UEVLekNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFmQ1lIN1I1bmVzXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASExUTY4OFE2PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAErMKfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBfKMAfoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=7081f4ad4ae9837aaff4b4f59abc4ce7f8b02cb6", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABEW1MTkwRnpcxnJwgleAAAAACCswp9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jyjAFiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAazCn0ewAQE.&s=71f281c81d1ae269bde275b84aa955c833ab1dea&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149414188, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 13.00001, - "cpm_publisher_currency": 13.00001, - "publisher_currency_code": "$", - "brand_category_id": 32, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 29000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEJaok6aeuMb0cxiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQrMKfR1ic8VtgAGjNunV4w7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxNDE4OCwgMTUZH_D9kgK5AiFKVDEtRWdpR2tfOFBFS3pDbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBZkNZSDdSNW5lc18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhMVE2ODhRNj0BJG5QRmJJQVFvQUQVSFRxUURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AXyjAH6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=05fc37623521011853ff69d194aa6d692b6c0504" - } - } - } - ] - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "2318891724556922037", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "5654583906891472332", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEMy7oJeqw8e8Thiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIXZ6Ml9mZ2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFhYzY5MFRlZi1rXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFJZzhjRDo9ASRuUEZiSUFRb0FEFUhUa1FEb0pVMGxPTXpvME56TXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qASv5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggA4AQA8ATF3Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAaWR0ANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=f929565158c7caa5b85e88fa456cdd04d0e4b6d8", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnKwgleAAAAABHMHeiiGh55ThnJwgleAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=a93773067b8588465b9c007e19970bd9e08c1b6c&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149417669, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 10, - "cpm_publisher_currency": 10, - "publisher_currency_code": "$", - "brand_category_id": 4, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCKBuBAAAAwDWAAUBCMmFp_AFEMy7oJeqw8e8Thiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjDuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc2OTc5OTMpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIXZ6Ml9mZ2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFhYzY5MFRlZi1rXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFJZzhjRDo9ASRuUEZiSUFRb0FEFUhUa1FEb0pVMGxPTXpvME56TXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwmmVBQS7YAgDgAq2YSOoCTmh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19wcmljZUdyYW4uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTV9NT0RFTF9MRUFGX05BTUUSAPICHgoaQ1VTVE9NER0IQVNUAQvwkElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qASv5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8ARhgiCIBQGYBQCgBf8RARQBwAUAyQVpsxTwP9IFCQkJDHgAANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=a3a24cbf148bb959f539e883af3d118f64e81bc9" - } - } - } - ] - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "2268711976967571175", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "8379392370800588084", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "6225030428438795793", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "1592368529919250324", - "nobid": true, - "ad_profile_id": 1182765 - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_priceGran_2/description.md b/test/fake-server/fixtures/longform/longform_priceGran_2/description.md deleted file mode 100644 index 8bc4d242f46..00000000000 --- a/test/fake-server/fixtures/longform/longform_priceGran_2/description.md +++ /dev/null @@ -1,62 +0,0 @@ -Test Page - 'integrationExamples/longform/basic_w_priceGran.html' -Test Spec File - 'test/spec/e2e/longform/basic_w_priceGran.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'sample-code', - sizes: [640, 480], - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 300, - durationRangeSec: [15, 30], - requireExactDuration: false - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 15394006 - } - } - ] -}]; -``` - -SetConfig to use with AdUnit: -``` -const customConfigObject = { - 'buckets': [{ - 'precision': 2, // default is 2 if omitted - means 2.1234 rounded to 2 decimal places = 2.12 - 'min': 0, - 'max': 5, - 'increment': 0.01 // from $0 to $5, 1-cent increments - }, - { - 'precision': 2, - 'min': 5, - 'max': 8, - 'increment': 0.05 // from $5 to $8, round down to the previous 5-cent increment - }, - { - 'precision': 2, - 'min': 8, - 'max': 40, - 'increment': 0.5 // from $8 to $40, round down to the previous 50-cent increment - }] -}; - -pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - }, - adpod: { - brandCategoryExclusion: true - }, - priceGranularity: customConfigObject -}); -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_priceGran_2/request.json b/test/fake-server/fixtures/longform/longform_priceGran_2/request.json deleted file mode 100644 index f2f20700ffe..00000000000 --- a/test/fake-server/fixtures/longform/longform_priceGran_2/request.json +++ /dev/null @@ -1,137 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - } - ], - "user": {}, - "brand_category_uniqueness": true - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_priceGran_2/response.json b/test/fake-server/fixtures/longform/longform_priceGran_2/response.json deleted file mode 100644 index ee7494ea665..00000000000 --- a/test/fake-server/fixtures/longform/longform_priceGran_2/response.json +++ /dev/null @@ -1,188 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "6123799897847039642", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKRCKARBAAAAwDWAAUBCMmFp_AFEJqN_JX98Yb-VBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIUN6dzV3Z2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYQm5aNWdRbi1NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASFJQS1IREE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkcADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSMo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=a7e4ff14c60153db90971365f90e514f45875324", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQnJwgleAAAAABGaBr_Sjxv8VBnJwgleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=842283d9de78fba7e92fac09f95bb63902a0b54a&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418671, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 30, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLtCOhtBAAAAwDWAAUBCMmFp_AFEJqN_JX98Yb-VBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4zrgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFDenc1d2dpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWEJuWjVnUW4tTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhSUEtSERBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMdAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgkkKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=0fb74d544be103e1440c3ee8f7abc14d2c322d15" - } - } - } - ] - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "889501690217653627", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEPvKoYSxoomsDBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIWt6eTlHUWlua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFRSzgzNzR1VnVVXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASFTd19PR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=78ac70aeeae1da43c90efd248fb30a4ee630ffd5", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnJwgleAAAAABF7ZYgQEyVYDBnJwgleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=f21e2a522ddcaf0a67bc7d52f70288fdf7e6f3dd&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149419602, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 24, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEPvKoYSxoomsDBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4zrgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFrenk5R1FpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUUs4Mzc0dVZ1VV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhU3dfT0d3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=69611db1024ddb77e0754087ddbeae68a00633a1" - } - } - } - ] - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "2793012314322059080", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFEMj-1IPuvLHhJhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE0MTg4Nh8A8P2SArkCIXhqb2ZBZ2lHa184UEVLekNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFRQWhlSGt0VHVRXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASExZzc1OFE2PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAOAEAPAErMKfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAGlkdADYBQHgBQHwBfKMAfoFBAgAEACQBgGYBgC4BgDBBgkkKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=243f58d85b09468de2fe485662c950a86b5d90fb", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnJwgleAAAAABFIP3Xg5sXCJhnJwgleAAAAACCswp9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jyjAFiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAazCn0ewAQE.&s=99dd40ab6ae736c6aa7c96b5319e1723ea581e0d&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149414188, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 13.00001, - "cpm_publisher_currency": 13.00001, - "publisher_currency_code": "$", - "brand_category_id": 32, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 29000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFEMj-1IPuvLHhJhiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQrMKfR1ic8VtgAGjNunV4zrgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxNDE4OCwgMTUZH_D9kgK5AiF4am9mQWdpR2tfOFBFS3pDbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBUUFoZUhrdFR1UV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhMWc3NThRNj0BJG5QRmJJQVFvQUQVSFRxUURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCaZUFBLtgCAOACrZhI6gJOaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3ByaWNlR3Jhbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX01PREVMX0xFQUZfTkFNRRIA8gIeChpDVVNUT00RHQhBU1QBC_CQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBK_mBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGCIIgFAZgFAKAF_xEBFAHABQDJBWmzFPA_0gUJCQkMeAAA2AUB4AUB8AXyjAH6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=d9a3c817696f263b6e6d81f7251827fa54a47c37" - } - } - } - ] - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "45194178065897765", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2def02900a6cda", - "tag_id": 15394006, - "auction_id": "3805126675549039795", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QKSCKASBAAAAwDWAAUBCMmFp_AFELPZ2uvQ0aHnNBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIWNUM1hkZ2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCOXFZRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFjbUQzMExTME9VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0BBRHdQdy4umgKJASEtUTZrXzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qASv5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0M9oEAggA4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAaWR0ANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=bbeaa584bea9afedf6dcab51b1616988441dfa22", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQnJwgleAAAAABGzrHYNjYbONBnJwgleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=b7e937b5acc3d8b910f6b08c3a40e04aa10818cd&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418123, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 12, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_priceGran.html&e=wqT_3QLuCOhuBAAAAwDWAAUBCMmFp_AFELPZ2uvQ0aHnNBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4zrgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk3OTkzKTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFjVDNYZGdpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQjlxWURrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBY21EMzBMUzBPVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNAQUR3UHcuLpoCiQEhLVE2a186PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8JplQUEu2AIA4AKtmEjqAk5odHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcHJpY2VHcmFuLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTU9ERUxfTEVBRl9OQU1FEgDyAh4KGkNVU1RPTREdCEFTVAEL8N5JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEr-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAeAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgAAYeYo8D_QBvUv2gYWChABDy4BAFAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=279827127eba3204bc3a152b8abaf701260eb494" - } - } - } - ] - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_requireExactDuration_1/description.md b/test/fake-server/fixtures/longform/longform_requireExactDuration_1/description.md deleted file mode 100644 index 8fe815912e8..00000000000 --- a/test/fake-server/fixtures/longform/longform_requireExactDuration_1/description.md +++ /dev/null @@ -1,40 +0,0 @@ -Test Page - 'integrationExamples/longform/basic_w_requireExactDuration.html' -Test Spec File - 'test/spec/e2e/longform/basic_w_requireExactDuration.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'sample-code', - sizes: [640, 480], - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 300, - durationRangeSec: [15, 30], - requireExactDuration: true - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 15394006 - } - } - ] -}]; -``` - -SetConfig to use with AdUnit: -``` -pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - }, - adpod: { - brandCategoryExclusion: true - } -}); -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_requireExactDuration_1/request.json b/test/fake-server/fixtures/longform/longform_requireExactDuration_1/request.json deleted file mode 100644 index 1e036c367c6..00000000000 --- a/test/fake-server/fixtures/longform/longform_requireExactDuration_1/request.json +++ /dev/null @@ -1,401 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 15, - "maxduration": 15 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - } - ], - "user": {} - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_requireExactDuration_1/response.json b/test/fake-server/fixtures/longform/longform_requireExactDuration_1/response.json deleted file mode 100644 index b91a5a3d523..00000000000 --- a/test/fake-server/fixtures/longform/longform_requireExactDuration_1/response.json +++ /dev/null @@ -1,330 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "4424969993715088689", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFELH6mcm82Km0PRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIWhUNEwzZ2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFjek5XT196NC1VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFTZy1SR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBNLsn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=3d8c006f4f85ecffd49c500554c3852b9079ff2b", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABExfSbJw6ZoPRlNxwleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=e2c6cedf67a96613ea8851673ebcfdd25a19435c&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149419602, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 24, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCM2Op_AFELH6mcm82Km0PRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFoVDRMM2dpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBY3pOV09fejQtVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhU2ctUkd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wkElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8ARhjSCIBQGYBQCgBf8RARQBwAUAyQVpvhTwP9IFCQkJDHgAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=de23f822f483b6e85615d4297d872262310c240d" - } - } - } - ] - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "2013100091803497646", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "2659371493620557151", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFEN_KtpiJif_zJBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIWR6eUJxQWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFWSHZpWGF0Q09zXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASEtQTVuX2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBIvhn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx4AADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=eafba287adec58427d1679f43a84ebb19223c4e7", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABFfpQ2TSPznJBlNxwleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=b335b2c79378c1699d54cf9ffe097958bd989a0b&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418123, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 12, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCM2Op_AFEN_KtpiJif_zJBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFkenlCcUFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVkh2aVhhdENPc18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhLUE1bl9nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wkElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8ARhjSCIBQGYBQCgBf8RARQBwAUAyQVpvhTwP9IFCQkJDHgAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=66b9e769da1e1d68b202605fc178fc172046e9c5" - } - } - } - ] - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "5424637592449788792", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "3470330348822422583", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "4415549097692431196", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "1628359298176905427", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "1949183409076770477", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "4707958683377993236", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "2499032734231846767", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "1295788165766409083", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKcCKAcBAAAAwDWAAUBCM2Op_AFEPvWpeWKj-T9ERiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCITR6eVM5d2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFlS0tONGIwQS00XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFOZzkxRkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBMTnn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx0AADYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=3cb170cdf53cd6a6bfec0676659daeb6170895e3", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQlNxwleAAAAABF7a6mseJD7ERlNxwleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=45f5cce314725120ec769afaacbb7aa92d32e674&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418948, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 1, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL4COh4BAAAAwDWAAUBCM2Op_AFEPvWpeWKj-T9ERiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiE0enlTOXdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZUtLTjRiMEEtNF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhTmc5MUZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7w7UlGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwP9AG9S_aBhYKEACJABUBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=5c9f03b9c5c6cc2bf070d8cdc6c9af4b06595879" - } - } - } - ] - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "702761892273189154", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKcCKAcBAAAAwDWAAUBCM2Op_AFEKLi_7T7xq3gCRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4NDg2Nh8A8P2SArkCITdUeVNDd2lva184UEVQYmpuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFHSTh5N21BQUFzUU1FQmlQTXU1Z0FBTEVESkFYQTM4QzJIcnVFXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHFKUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFaQThESlE2PQEkblBGYklBUW9BRBVIVHNRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBPbjn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx0AADYBQHgBQHwBf0F-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=f459a78a1b20c9643b90d7491f22593d79cff253", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQlNxwleAAAAABEi8Z-2N7bACRlNxwleAAAAACD2459HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1j9BWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgB9uOfR7ABAQ..&s=83289d261bced5258930a1ce2464260a96565241&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418486, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 14.00001, - "cpm_publisher_currency": 14.00001, - "publisher_currency_code": "$", - "brand_category_id": 30, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL4COh4BAAAAwDWAAUBCM2Op_AFEKLi_7T7xq3gCRiq5MnUovf28WEqNgmOWItPAQAsQBGOWItPAQAsQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ9uOfR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODQ4NiwgMTUZH_D9kgK5AiE3VHlTQ3dpb2tfOFBFUGJqbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRR0k4eTdtQUFBc1FNRUJpUE11NWdBQUxFREpBWEEzOEMySHJ1RV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RxSlBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNEQUR3UHcuLpoCiQEhWkE4REpRNj0BJG5QRmJJQVFvQUQVSFRzUURvSlUwbE9Nem8wTnpNelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7w7UlGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDczM9oEAggB4AQA8AT2459HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF_QX6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwP9AG9S_aBhYKEACJABUBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=16a432c0a05db78fa40fefc7967796ff2a2e8444" - } - } - } - ] - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "8192047453391406704", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFEPCMp9SW-P_XcRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIXhUdGdYZ2lHa184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFSR0FWSjZORXVNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0BBRHdQdy4umgKJASFKUThlRDo9ASRuUEZiSUFRb0FEFUhUcVFEb0pVMGxPTXpvME56TXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwXmVBQS7YAgDgAq2YSOoCWWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19yZXF1aXJlRXhhY3REdXJhAS7wny5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEwuYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MzPaBAIIAOAEAPAE39-fR4gFAZgFAKAF______8BBRQBwAUAyQVpYhTwP9IFCQkJDHgAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGCSUo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=8bf90e0756a9265ab6ac029e883e14803447a7fb", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABFwxolqwf-vcRlNxwleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=cf9ea0df7655a5c6150a527399cb2852c61ec14a&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149417951, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 13.00001, - "cpm_publisher_currency": 13.00001, - "publisher_currency_code": "$", - "brand_category_id": 33, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCM2Op_AFEPCMp9SW-P_XcRiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4lbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiF4VHRnWGdpR2tfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBUkdBVko2TkV1TV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjek0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCZjBrcVFVCRNAQUR3UHcuLpoCiQEhSlE4ZUQ6PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBGGNIIgFAZgFAKAF_xEBFAHABQDJBWm-FPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=cefb5f476892ed335cd8b0fc20fabf7650b1d2e3" - } - } - } - ] - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "9041697983972949142", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFEJb5yqiVjaS9fRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIURUMkpEd2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFYeHdUOEhkUmVzXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFJZzhjRGc2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCADgBADwBMXdn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx4AADYBQHgBQHwBcLyF_oFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=308ea3c3363b379ef62dbb6c7a91d1d91d9ee47a", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABGWvBJVaZB6fRlNxwleAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=70a33aa1a57d812d9da5c321e898197836ed16f8&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149417669, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 10, - "cpm_publisher_currency": 10, - "publisher_currency_code": "$", - "brand_category_id": 4, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5CKB5BAAAAwDWAAUBCM2Op_AFEJb5yqiVjaS9fRiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXiVuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc2OTkxNDkpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIURUMkpEd2lsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFYeHdUOEhkUmVzXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGN6TS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJmMGtxUVUJE0RBRHdQdy4umgKJASFJZzhjRGc2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOek16UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvDeSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzMz2gQCCAHgBADwBMXdn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXC8hf6BQQIABAAkAYBmAYAuAYAwQYAAGHxKPA_0Ab1L9oGFgoQAQ8uAQBQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=ee15793b41a9d22ffad9bd46878a47821d6044fa" - } - } - } - ] - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "356000177781223639", - "nobid": true, - "ad_profile_id": 1182765 - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_requireExactDuration_2/description.md b/test/fake-server/fixtures/longform/longform_requireExactDuration_2/description.md deleted file mode 100644 index 8fe815912e8..00000000000 --- a/test/fake-server/fixtures/longform/longform_requireExactDuration_2/description.md +++ /dev/null @@ -1,40 +0,0 @@ -Test Page - 'integrationExamples/longform/basic_w_requireExactDuration.html' -Test Spec File - 'test/spec/e2e/longform/basic_w_requireExactDuration.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'sample-code', - sizes: [640, 480], - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 300, - durationRangeSec: [15, 30], - requireExactDuration: true - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 15394006 - } - } - ] -}]; -``` - -SetConfig to use with AdUnit: -``` -pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - }, - adpod: { - brandCategoryExclusion: true - } -}); -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_requireExactDuration_2/request.json b/test/fake-server/fixtures/longform/longform_requireExactDuration_2/request.json deleted file mode 100644 index 83877ff9ac0..00000000000 --- a/test/fake-server/fixtures/longform/longform_requireExactDuration_2/request.json +++ /dev/null @@ -1,141 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "minduration": 30, - "maxduration": 30 - } - } - ], - "user": {} - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_requireExactDuration_2/response.json b/test/fake-server/fixtures/longform/longform_requireExactDuration_2/response.json deleted file mode 100644 index e776170328e..00000000000 --- a/test/fake-server/fixtures/longform/longform_requireExactDuration_2/response.json +++ /dev/null @@ -1,188 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "198494455120718841", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKcCKAcBAAAAwDWAAUBCM2Op_AFEPnX6_r7tMzgAhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIXpUMDRwQWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhejg2NVNoMGVJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0RBRHdQdy4umgKJASFKQTkzRFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCADgBADwBK_ln0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx0AADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=645b6e0a37eb3a315bc3208365bd4fc03e1ecd18", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQlNxwleAAAAABH561q_pzHBAhlNxwleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=35a21bf0bef1ca2c138e37a2e025ad523b5a1db2&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418671, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 30, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL4COh4BAAAAwDWAAUBCM2Op_AFEPnX6_r7tMzgAhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4xbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiF6VDA0cEFpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYXo4NjVTaDBlSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME4tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWXNscVFVCRNEQUR3UHcuLpoCiQEhSkE5M0RRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBeZUFBLtgCAOACrZhI6gJZaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193X3JlcXVpcmVFeGFjdER1cmEBLnwuaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFjIWACBMRUFGX05BTUUBHQgeCho2HQAIQVNUAT7wkElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATC5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0N9oEAggB4AQA8ARhjSCIBQGYBQCgBf8RARQBwAUAyQVpvhTwP9IFCQkJDHQAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYJJCjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=cf3130989b2b4fe5271240d65055b85d1192b78a" - } - } - } - ] - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "998265386177420565", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFEJW6sbXGoqPtDRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIVdqM1Jid2lHa184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFmcXpCNjduMU9rXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0BBRHdQdy4umgKJASFLZzlMRDo9ASRuUEZiSUFRb0FEFUhUcVFEb0pVMGxPTXpvME56UTNRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwXmVBQS7YAgDgAq2YSOoCWWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19yZXF1aXJlRXhhY3REdXJhAS7wny5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEwuYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDfaBAIIAOAEAPAE39-fR4gFAZgFAKAF______8BBRQBwAUAyQVpYhTwP9IFCQkJDHgAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGCSUo8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=33f01ddfb15bc84d7bf134a168aeb9d9de76fa57", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABEVXaxmFI3aDRlNxwleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=023640de7c18a0d0e80b2456144b89a351455cda&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149417951, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 13.00001, - "cpm_publisher_currency": 13.00001, - "publisher_currency_code": "$", - "brand_category_id": 33, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCM2Op_AFEJW6sbXGoqPtDRiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4xbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiFXajNSYndpR2tfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBZnF6QjY3bjFPa18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjME4tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWXNscVFVCRNAQUR3UHcuLpoCiQEhS2c5TEQ6PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCAHgBADwBGGNIIgFAZgFAKAF_xEBFAHABQDJBWm-FPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=515ab42a7fdcad8fcf34e4fb98b1e076a75006a9" - } - } - } - ] - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "8884527464400177295", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKcCKAcBAAAAwDWAAUBCM2Op_AFEI-RmcaB1Yumexiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCITVqcmtHUWlta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYb0paejlaR09NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0BBRHdQdy4umgKJASFPdy1pRjo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UTNRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQzwXmVBQS7YAgDgAq2YSOoCWWh0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5L2ludGVncmF0aW9uRXhhbXBsZXMvbG9uZ2Zvcm0vYmFzaWNfd19yZXF1aXJlRXhhY3REdXJhAS7wny5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEwuYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDfaBAIIAOAEAPAExOefR4gFAZgFAKAF______8BBRQBwAUAyQVpYhTwP9IFCQkJDHQAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYJJCjwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=dc7d874e52ac39980ec1070a7769632be56a2f00", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQlNxwleAAAAABGPSMYYqC5MexlNxwleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=9fd739e9f0a6054296f9bb5168c49a89a425795c&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418948, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 1, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL4COh4BAAAAwDWAAUBCM2Op_AFEI-RmcaB1Yumexiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4xbgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiE1anJrR1FpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQm5LY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWG9KWno5WkdPTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME4tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWXNscVFVCRNAQUR3UHcuLpoCiQEhT3ctaUY6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkAFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=1f8ea8f07f781fe149beb0d65dd25ad725a12f3b" - } - } - } - ] - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "1279521442385130931", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCM2Op_AFELPr8f6Pv_HgERiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5MTQ5KTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIW9EeDJEQWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFkb01fcFZkVGVVXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0RBRHdQdy4umgKJASFKdzlKRHc2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEu8J8uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCADgBADwBMXdn0eIBQGYBQCgBf______AQUUAcAFAMkFaWIU8D_SBQkJCQx4AADYBQHgBQHwBcLyF_oFBAgAEACQBgGYBgC4BgDBBgklKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=4b14660ae659b3d301ec6c40f0f096bb88db145b", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQlNxwleAAAAABGzddz_-MXBERlNxwleAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=5f277bcab624f05c9d3a3a9c111961f3f33ccca2&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149417669, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 10, - "cpm_publisher_currency": 10, - "publisher_currency_code": "$", - "brand_category_id": 4, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_w_requireExactDuration.html&e=wqT_3QL5CKB5BAAAAwDWAAUBCM2Op_AFELPr8f6Pv_HgERiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjFuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc2OTkxNDkpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIW9EeDJEQWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCbktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFkb01fcFZkVGVVXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMwTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZc2xxUVUJE0RBRHdQdy4umgKJASFKdzlKRHc2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOelEzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8F5lQUEu2AIA4AKtmEjqAllodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dfcmVxdWlyZUV4YWN0RHVyYQEufC5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWMhYAIExFQUZfTkFNRQEdCB4KGjYdAAhBU1QBPvDeSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMLmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ32gQCCAHgBADwBMXdn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXC8hf6BQQIABAAkAYBmAYAuAYAwQYAAGHxKPA_0Ab1L9oGFgoQAQ8uAQBQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=7bb7b75e4769a1260eaed2c79752ee542b4d28ce" - } - } - } - ] - }, - { - "uuid": "25593f19ac7ed2", - "tag_id": 15394006, - "auction_id": "7664937561033023835", - "nobid": true, - "ad_profile_id": 1182765 - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/description.md b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/description.md deleted file mode 100644 index 159ebbcc30b..00000000000 --- a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/description.md +++ /dev/null @@ -1,40 +0,0 @@ -Test Page - 'integrationExamples/longform/basic_wo_brandCategoryExclusion.html' -Test Spec File - 'test/spec/e2e/longform/basic_wo_brandCategoryExclusion.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'sample-code', - sizes: [640, 480], - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 300, - durationRangeSec: [15, 30], - requireExactDuration: false - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 15394006 - } - } - ] -}]; -``` - -SetConfig to use with AdUnit: -``` -pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - }, - adpod: { - brandCategoryExclusion: false - } -}); -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/request.json b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/request.json deleted file mode 100644 index 2d1fa3f16bf..00000000000 --- a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/request.json +++ /dev/null @@ -1,386 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - } - ], - "user": {} - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/response.json b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/response.json deleted file mode 100644 index bfef650e07a..00000000000 --- a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_1/response.json +++ /dev/null @@ -1,654 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "6316075342634007031", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEPfztqL2oc3TVxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIV96eWNLZ2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFZYkYwSW1fZGU0XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASE5dzR0Xzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBIvhn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=bb81a081c756fd493253bf765c06ff46888f009a", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABH3uU1kDzWnVxk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=a3da30186f69a5ce2edcfc14fa3a31b92ee70060&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418123, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 12, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEPfztqL2oc3TVxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFfenljS2dpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWWJGMEltX2RlNF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhOXc0dF86PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx4AADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=62b9db151b3739399e0970c74fafc4bb61486510" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "8259815099516488747", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFEKuY2qihwrDQchiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIW1UeUFCd2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYNml4eGFGdE8wXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFOUTg3RkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAAGmpDQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=8a55db8e788616ef057647b49c0560296fdacb65", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABErjBYVEsKgchk3yQleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=75d46be63f76fd4062f354a56c692855da366148&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418948, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 1, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFEKuY2qihwrDQchiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFtVHlBQndpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWDZpeHhhRnRPMF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhTlE4N0ZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkDFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=59e0ab1f626c2e4dc5c4f6e6837b77559cf502b4" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "7960926407704980889", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEJnboLK5jLm9bhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIUZEeFl4QWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhSUpVQVhXMC1JXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFTQThFR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=8d00bc7576c3cc19fe8b3fb4aa42966583741dfa", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABGZLUiWY-R6bhk3yQleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=c813392cbb81d43466d5d949b9bebc2305e6fe7d&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149417951, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 33, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEJnboLK5jLm9bhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiFGRHhZeEFpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYUlKVUFYVzAtSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhU0E4RUd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=284760a6e2d4f226b639d29237e9c1aa25ca49a9" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "7561862402601574638", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEO7By9umucj4aBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCITREcWpId2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFTSVA1dzg5RGVRXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASFTUTlYRzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBNLsn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=917e8af2ed1c82091f487b6abd78de47b99e9e46", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABHu4HJryiHxaBk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=ff73768bfb14e9ae603064fc91e95b60c8d872e2&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149419602, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 24, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEO7By9umucj4aBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiE0RHFqSHdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBU0lQNXc4OURlUV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhU1E5WEc6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=84c66b632a2930d28092e00985ee154ba2e97288" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "6577796711489765634", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEIKC0sii6MGkWxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIVBUem53UWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFlaE5hMWl1Y3V3XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASE5dzR0X2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=ea4a54786a8f3cf5177b3372ce97682da060c358", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABECgRQpQgdJWxk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=778fbf3014328ec0b01d6ebd7b306be32cf79950&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418123, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 12, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEIKC0sii6MGkWxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFQVHpud1FpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZWhOYTFpdWN1d18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhOXc0dF9nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=28a3b583912b95528519f63a75c0fe2d06064e7b" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "2418275491761094586", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFELr_z7v0l9zHIRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIUF6MUJSZ2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFVNUE2dXpUVy1ZXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFTUTlYR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=c563626304ebb31fd6f1644cc2d4098133dec096", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABG6_3NHv3CPIRk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=88c9fbb2b9dc273865a5f9238543a29224908b26&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149419602, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 24, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFELr_z7v0l9zHIRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFBejFCUmdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVTVBNnV6VFctWV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhU1E5WEd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=e76aeb8daad477f4428631fc89d277d4a4646ded" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "5990197965284733361", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFELHjwfj9qd2QUxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIURUeDF3d2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFmWXBYSEoxUGVNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASFTUTlYRzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBNLsn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=e443347514ff5f6a52a2811f591f9a346061a756", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABGxcRDfT3UhUxk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=50348eb78116f7d35ca5ac6f6fa4c5548a6ceffc&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149419602, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 24, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFELHjwfj9qd2QUxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFEVHgxd3dpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZllwWEhKMVBlTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhU1E5WEc6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=a24f331ff55f96c5afe5134762f8d8e230b6287c" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "4399290132982250349", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEO32psKU4tqGPRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCITN6dDlwd2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFRWlZqbkpncmV3XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASFTUTlYRzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBNLsn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=0d9b0a06992ff427d281fae8d8b18d4e6838b944", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABFtu0lIEWsNPRk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=52a446d84f5e9a2baa068760c4406f4a567a911a&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149419602, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 24, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEO32psKU4tqGPRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiEzenQ5cHdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUVpWam5KZ3Jld18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhU1E5WEc6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx4AADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgklKPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=e6ae592b5fc3de0053b5acd46294b83549aa00c8" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "8677372908685012092", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEPzYku74lY62eBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIVVEeGp5d2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFVN29abmh2c09RXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASE5dzR0X2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=522b764f2276ce75053a55a0198b79fb8d1d39d5", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABF8rMSNrzhseBk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=02b75d0ecc71c7897b9590be5e50b094158c8097&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418123, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 12, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEPzYku74lY62eBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFVRHhqeXdpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVTdvWm5odnNPUV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhOXc0dF9nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=0ae5558a7b0cc87eaa0c6811522629963b41bac5" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "617065604518434488", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFELitu4PevJDICBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIUFqMVNSZ2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaUzdZYTg5Ny13XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFTUTlYR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9HYBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAAAAAAAAAAAAAAAAAAAAEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f59bdb7b0f7020f75c6019f23686915b72d61779", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABG41m7g5UGQCBk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=912a721db8e85d4d64a8869d7cf9b56cd0c24907&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149419602, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 24, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFELitu4PevJDICBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFBajFTUmdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWlM3WWE4OTctd18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhU1E5WEd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBGAHABQDJBQAFARTwP9IFCQkFC3wAAADYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgEhMAAA8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=9b4372ae0674305d9cd7152959910d1fa7d4daec" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "8957511111704921777", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFELGNpebanN6nfBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIXVqdHppQWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFUM1dNOVpkQU9JXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0BBRHdQdy4umgKJASFIZzhRRDo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56VXdRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCADgBADwBK_ln0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPC_0Ab1L9oGFgoQAAAAaakNAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=a8817d9dc3326ba1b59fe308f126ddaca5710a9c", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABGxRsms5XhPfBk3yQleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=a0ac94e902cbc609881fa9f39537bbc67ba046e7&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418671, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 30, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFELGNpebanN6nfBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiF1anR6aUFpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVDNXTTlaZEFPSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNAQUR3UHcuLpoCiQEhSGc4UUQ6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NTDaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEUAcAFAMkFacEU8D_SBQkJCQx0AADYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGCSQo8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=75b3ad3e867323196da165cd655b3ae51c8b44d0" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "2680240375770812721", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFELGi6rO9jYiZJRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIWd6eTMtZ2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYcFdVTk9rai1jXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFOUTg3RkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAAGmpDQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f8458c6a48fed591c269169a9744aba11cb90285", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABExkXrWayAyJRk3yQleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=e2dbd082b353a37db9f632efc2532913a0c48166&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418948, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 1, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFELGi6rO9jYiZJRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFnenkzLWdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWHBXVU5Pa2otY18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhTlE4N0ZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkDFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=5475ac640321ae51a06b5c05ac62519e97e90114" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "8439286287321689724", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFEPzciY2kxZePdRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIU1UeWZ6d2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFWalR1QThjek9FXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFOUTg3RkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAAGmpDQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=73e760427d2aec3d47824994cf35c35f1eeddcf8", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABF8bqJBKl4edRk3yQleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=dac1e836a6f2c4dc036c50d0b3128dfefb34915d&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418948, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 1, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFEPzciY2kxZePdRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFNVHlmendpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVmpUdUE4Y3pPRV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhTlE4N0ZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkDFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=6c1fb35564d2ffd08fb4c5b290aadd6e1e3d83ec" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "5519278898732145414", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEIa29Pmn3ZrMTBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCITFEc0hwUWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFkQUZ3YVliRWVNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFTQThFR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=d01f411e7cc9126e912daca85136b2ca6f99a347", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABEGGz1_6mqYTBk3yQleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=81115280cee86ae0bc259627410fa5dbbc178646&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149417951, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 33, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEIa29Pmn3ZrMTBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiExRHNIcFFpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBZEFGd2FZYkVlTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhU0E4RUd3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=90f21feeb2c798cd77b3cadbc961240238825f0d" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "6754624236211478320", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFELC-hPXI3s_eXRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIVJqc0hVUWlta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaRjJPd05MVnVvXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMxTU9BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZNGxxUVUJE0RBRHdQdy4umgKJASFOUTg3RkE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelV3UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc1MNoEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAAGmpDQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=34811f7e5c917550619274f5b75a0cd214119812", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABEwH6GO9D69XRk3yQleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=d811faa48963b18d33c0a1f9d1e64ff97640a415&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418948, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 1, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFELC-hPXI3s_eXRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4ybgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFSanNIVVFpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWkYyT3dOTFZ1b18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjMU1PQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTRscVFVCRNEQUR3UHcuLpoCiQEhTlE4N0ZBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpVd1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDtSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzUw2gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPA_0Ab1L9oGFgoQAIkDFQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=c0a0a2d65dd091bd2ed81f95da1a9f7ff16ad70e" - } - } - } - ] - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/description.md b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/description.md deleted file mode 100644 index 159ebbcc30b..00000000000 --- a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/description.md +++ /dev/null @@ -1,40 +0,0 @@ -Test Page - 'integrationExamples/longform/basic_wo_brandCategoryExclusion.html' -Test Spec File - 'test/spec/e2e/longform/basic_wo_brandCategoryExclusion.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'sample-code', - sizes: [640, 480], - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 300, - durationRangeSec: [15, 30], - requireExactDuration: false - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 15394006 - } - } - ] -}]; -``` - -SetConfig to use with AdUnit: -``` -pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - }, - adpod: { - brandCategoryExclusion: false - } -}); -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/request.json b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/request.json deleted file mode 100644 index 5a5ddce7d54..00000000000 --- a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/request.json +++ /dev/null @@ -1,136 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - } - ], - "user": {} - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/response.json b/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/response.json deleted file mode 100644 index 9273f8e0c7b..00000000000 --- a/test/fake-server/fixtures/longform/longform_wo_brandCategoryExclusion_2/response.json +++ /dev/null @@ -1,224 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "4631210661889362034", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEPKQq-_0sdeiQBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIXF6eU1HUWlua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFVQk5fYTFxbHU0XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASFTd19PR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0M9oEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=0dae5294ed5bb48b7d3a156e5e587a26da27c7e1", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABFyyOpNj11FQBk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=9085e4dbb4849b0e6d3714d84a2754bbab578e16&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149419602, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 24, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEPKQq-_0sdeiQBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFxenlNR1FpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVUJOX2ExcWx1NF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhU3dfT0d3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=aa5533d04e16ee398f8028ab3af03a48d7d8cc17" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "714778825826946473", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEKmbi7Ph8dn1CRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIU56dmJOZ2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFRbjlXUzRmY09jXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0BBRHdQdy4umgKJASEtUTZrXzo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0UwFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCADgBADwBIvhn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYAAAAAAADwv9AG9S_aBhYKEAAAaakRAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=8917b1722eed5b6d85c6d5a01eea7862089bee32", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABGpzWIWjmfrCRk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=9ec7e7de16b948b60d74b47f1917faf5d3b6dbf0&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418123, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 12, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEKmbi7Ph8dn1CRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFOenZiTmdpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUW45V1M0ZmNPY18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNAQUR3UHcuLpoCiQEhLVE2a186PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8N5JRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAeAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAAAAADYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgAAYfQo8D_QBvUv2gYWChABDy4BAFAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=8198652a5ee16abf4595ab1bfc6b051f81f0579d" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "231404788116786844", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFEJydmpjcrYebAxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIUVqMFlVZ2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhLXFPTExmZ2VrXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASFTd19PR3c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0M9oEAggA4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=775dfc49086467337dee9a5e8d78b361931c6aaa", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABGcjgbDbR02Axk3yQleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=914256a92514df787ccb1eae7dea7578d23c8fba&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149419602, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 24, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFEJydmpjcrYebAxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFFajBZVWdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYS1xT0xMZmdla18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhU3dfT0d3Nj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPCQSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBGGQIIgFAZgFAKAF_xEBFAHABQDJBWnBFPA_0gUJCQkMeAAA2AUB4AUB8AXZugb6BQQIABAAkAYBmAYAuAYAwQYJJSjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f624619431372f9a248d0fa0dd8d09c4977bb544" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "7557072342526904599", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKfCKAfBAAAAwDWAAUBCLeSp_AFEJeS-7GaqIfwaBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIUFqdmVKQWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFSY2lLblVqeU9VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0BBRHdQdy4umgKJASFJQS1IRDo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UXpRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0dQFlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCADgBADwBK_ln0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXgWPoFBAgAEACQBgGYBgC4BgDBBgAAAAAAAPC_0Ab1L9oGFgoQAAAAAAAAAAAAAAAAAAAAABAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=552663ed1246fd2a3cc5824164f57d32f18078ee", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQk3yQleAAAAABEXyT6mQR3gaBk3yQleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=e1c80e622aa60bf7683413f4371b0055d0d16f47&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418671, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 30, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL7COh7BAAAAwDWAAUBCLeSp_AFEJeS-7GaqIfwaBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFBanZlSkFpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBUmNpS25VanlPVV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNAQUR3UHcuLpoCiQEhSUEtSEQ6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlxodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX2JyYW5kQ2F0ZWdvcnlFeGNsdXNpb24uaHRtbPICEwoPQ1VTVE9NX01PREVMX0lEEgDyAhoKFkNVU1RPTQ0WQExFQUZfTkFNRRIA8gIeChpDMh0ACEFTVAEo8JBJRklFRBIAgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gEy-YEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDPaBAIIAeAEAPAEYZAgiAUBmAUAoAX_EQEYAcAFAMkFAAUBFPA_0gUJCQULeAAAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYBIDAAAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=ccf266d1b02551a2ad0af0871d4af43e4aee4bba" - } - } - } - ] - }, - { - "uuid": "2c52d7d1f2f703", - "tag_id": 15394006, - "auction_id": "5093465143102876632", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QKgCKAgBAAAAwDWAAUBCLeSp_AFENjX7JP78efXRhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIUJUeXRwUWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCcktjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYamVBMVdNcXUwXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwTS1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZY2xxUVUJE0RBRHdQdy4umgKJASEtUTZrX2c2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelF6UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9FMBZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATL5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0M9oEAggA4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAAAAAAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGAAAAAAAA8L_QBvUv2gYWChAAAGmpEQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=6651c1436b699842aabb3ae53d96d07caf5b4938", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQk3yQleAAAAABHYK3uyj5-vRhk3yQleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=f62098bf5037b22ca4e5583289a1527fdfa87e43&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418123, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 12, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_brandCategoryExclusion.html&e=wqT_3QL8COh8BAAAAwDWAAUBCLeSp_AFENjX7JP78efXRhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4z7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3Njk5NjM5KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFCVHl0cFFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQnJLY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWGplQTFXTXF1MF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME0tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWWNscVFVCRNEQUR3UHcuLpoCiQEhLVE2a19nNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRelFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJcaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19icmFuZENhdGVnb3J5RXhjbHVzaW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT00NFkBMRUFGX05BTUUSAPICHgoaQzIdAAhBU1QBKPDeSUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBMvmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQz2gQCCAHgBADwBIvhn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAAAAAAA2AUB4AUB8AXa1gL6BQQIABAAkAYBmAYAuAYAwQYAAGH0KPA_0Ab1L9oGFgoQAQ8uAQBQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=4b43aaab766ee7d2e4c900ec32cb3c8b7ccef1d0" - } - } - } - ] - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/description.md b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/description.md deleted file mode 100644 index c1781561af5..00000000000 --- a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/description.md +++ /dev/null @@ -1,40 +0,0 @@ -Test Page - 'integrationExamples/longform/basic_wo_requireExactDuration.html' -Test Spec File - 'test/spec/e2e/longform/basic_wo_requireExactDuration.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'sample-code', - sizes: [640, 480], - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 300, - durationRangeSec: [15, 30], - requireExactDuration: false - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 15394006 - } - } - ] -}]; -``` - -SetConfig to use with AdUnit: -``` -pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - }, - adpod: { - brandCategoryExclusion: true - } -}); -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/request.json b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/request.json deleted file mode 100644 index aba76398093..00000000000 --- a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/request.json +++ /dev/null @@ -1,387 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - } - ], - "user": {}, - "brand_category_uniqueness": true - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/response.json b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/response.json deleted file mode 100644 index c35a47781f7..00000000000 --- a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_1/response.json +++ /dev/null @@ -1,366 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "8905202273088829598", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCLWXp_AFEJ7x1-ORyejKexiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIWlEeE84Z2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhV09TRWpDY09NXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0BBRHdQdy4umgKJASFQZzlaRjo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56YzNRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggA4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAZWQU8D_SBQkJBQt4AAAA2AUB4AUB8AWZPfoFBAgAEACQBgGYBgC4BgDBBgEgMAAA8L_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=21195aa3e27f8eb88ba43d5da32e6b78c2aa03f8", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQm1ywleAAAAABGe-HUcSaKVexm1ywleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=3c05b8509dd5c7c4459886f4c69fdd9cd07caa66&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418948, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 1, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCLWXp_AFEJ7x1-ORyejKexiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiFpRHhPOGdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYVdPU0VqQ2NPTV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNAQUR3UHcuLpoCiQEhUGc5WkY6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTQUWPExFQUZfTkFNRRIA8gIeChoyMwDwwkxBU1RfTU9ESUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBNXmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0Nzc32gQCCAHgBADwBMTnn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAGXObNgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYFISwA8D_QBvUv2gYWChAJERkBUBAAGADgBgTyBgIIAIAHAYgHAKAHQA..&s=203ae79160a460b18f20165e5de53bb1f45e4933" - } - } - } - ] - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "2428831247136753876", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFENSR0sfppLzaIRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIXRUeV9FQWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFTek5nNXJvQi0wXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFVUThpSFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAE39-fR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=af2d5096aa4f934e84b59ad16cd18dfe5b9bbc77", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABHUiPSYJvG0IRm1ywleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=440a389c7f556dac70c650bb1e593a10cbcdf2af&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149417951, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 33, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFENSR0sfppLzaIRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiF0VHlfRUFpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBU3pOZzVyb0ItMF8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNEQUR3UHcuLpoCiQEhVVE4aUhRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpjM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggB4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBay8FPoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=9b00ed17c420f328d63b72519d2d578c5921d0d7" - } - } - } - ] - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "1625697369389546128", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEJD1gLbO5OjHFhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIXVqeHMtUWlua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFhcDVwSkxuSXVVXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFBQTlhQUE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=0e70f535a95c82238d685147f41e0bd2f86631c0", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABGQOsDmJKOPFhm1ywleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=144214d77cc4ced0893c9fe64132ad01c429c43c&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418123, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 12, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEJD1gLbO5OjHFhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiF1anhzLVFpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYXA1cEpMbkl1VV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNEQUR3UHcuLpoCiQEhQUE5YUFBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpjM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggB4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f6bc475b66c167036dcb9f10c7c5f176124829a6" - } - } - } - ] - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "5434800203981031918", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCLWXp_AFEO6TivzZv5K2Sxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCIW5Ud3I5QWlta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFXVVcwV1Y1LU9JXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFKdzh1RGc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULeAAAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=c3ba85f0eb0293896e02066385f82b4450af2cfb", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQm1ywleAAAAABHuiYKf_UlsSxm1ywleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=9eb2d880fa9b524a6a0807eef0c65b7b1393f48a&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418671, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 30, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCLWXp_AFEO6TivzZv5K2Sxiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiFuVHdyOUFpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBV1VXMFdWNS1PSV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNEQUR3UHcuLpoCiQEhSnc4dURnNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpjM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggB4AQA8ASv5Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlzmzYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGBSEsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=17038c2671b58d2fd6ea98dd3f3e1166ee664dd0" - } - } - } - ] - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "8071104954749355970", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEMKP7OWZ5pSBcBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIXBUeEJEQWlsa184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFRbWtta1pXNGVZXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFSZ19sR1E2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=005579c0ff91586a887354409f637a63a1d69031", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABHCB7ucMVMCcBm1ywleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=edbfae73be0f41d672298d5c3ec9dd28a5307233&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149419602, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 10, - "cpm_publisher_currency": 10, - "publisher_currency_code": "$", - "brand_category_id": 24, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6CKB6BAAAAwDWAAUBCLWXp_AFEMKP7OWZ5pSBcBiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDS7J9HWJzxW2AAaM26dXjWuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc3MDAyNzcpO3VmKCdyJywgMTQ5NDE5NjAyLCAxNRkf8P2SArkCIXBUeEJEQWlsa184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFRbWtta1pXNGVZXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFSZ19sR1E2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTQUWPExFQUZfTkFNRRIA8gIeChoyMwDwwkxBU1RfTU9ESUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBNXmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0Nzc32gQCCAHgBADwBNLsn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAGXOcNgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGBSIsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=0ac18b64a6c0d58a114085d8b565b4c98de56448" - } - } - } - ] - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "6893555531330982923", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEIuopuO2h7XVXxiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE0MTg4Nh8A8P2SArkCIVFqd1R0Z2lHa184UEVLekNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFFajRyM1ZBQUFxUU1FQkktSzkxUUFBS2tESkFZS1J6NEZQV2V3XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRGhwUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASEzUTZnOHc2PQEkblBGYklBUW9BRBVIVHFRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAErMKfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF8owB-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=f9ddb1066825dfc556d108168ffc0d16cf567ae8", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABELlGlsO9SqXxm1ywleAAAAACCswp9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jyjAFiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAazCn0ewAQE.&s=db3a0d52f97edd94aa7e4213c437d8e4a5bd16ce&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149414188, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 13.00001, - "cpm_publisher_currency": 13.00001, - "publisher_currency_code": "$", - "brand_category_id": 32, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 29000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEIuopuO2h7XVXxiq5MnUovf28WEqNgmOWItPAQAqQBGOWItPAQAqQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQrMKfR1ic8VtgAGjNunV41rgFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxNDE4OCwgMTUZH_D9kgK5AiFRandUdGdpR2tfOFBFS3pDbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRRWo0cjNWQUFBcVFNRUJJLUs5MVFBQUtrREpBWUtSejRGUFdld18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RocFBfRDdvRENWTkpUak02TkRjM04tQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCYWtscVFVCRNEQUR3UHcuLpoCiQEhM1E2Zzh3Nj0BJG5QRmJJQVFvQUQVSFRxUURvSlUwbE9Nem8wTnpjM1FNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc3N9oEAggB4AQA8ASswp9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBfKMAfoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=917c8192c7dc7e382c0bb7296ab0df261e69f572" - } - } - } - ] - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "5615186251901272031", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "6647218197537074925", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "4707051182303115567", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "4831890668873532085", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "7151522995196673389", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "4077353832159380438", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFENaHwKvS9urKOBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE3NjY5Nh8A8P2SArkCIWJqeHo1UWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFZd1VQNVZMNi1VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFLZzhBRUE2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NzfaBAIIAOAEAPAExd2fR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=e96d121a0a7d49e05c1d2b4fab2da60d0b544287", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABHWA3AltauVOBm1ywleAAAAACDF3Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jC8hdiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAcXdn0ewAQE.&s=8d90e3ce42fe47da19cb85f8fb2d78822c590464&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149417669, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 10, - "cpm_publisher_currency": 10, - "publisher_currency_code": "$", - "brand_category_id": 4, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6CKB6BAAAAwDWAAUBCLWXp_AFENaHwKvS9urKOBiq5MnUovf28WEqNgkAAAECCCRAEQEHEAAAJEAZCQkI4D8hCQkIJEApEQkAMQkJsOA_MNbJqwc47UhA7UhIAlDF3Z9HWJzxW2AAaM26dXjWuAWAAQGKAQNVU0SSAQEG8FWYAQGgAQGoAQGwAQC4AQPAAQTIAQLQAQDYAQDgAQDwAQCKAjx1ZignYScsIDI1Mjk4ODUsIDE1Nzc3MDAyNzcpO3VmKCdyJywgMTQ5NDE3NjY5LCAxNRkf8P2SArkCIWJqeHo1UWlsa184UEVNWGRuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFZd1VQNVZMNi1VXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBaUF9EN29EQ1ZOSlRqTTZORGMzTi1BRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJha2xxUVUJE0RBRHdQdy4umgKJASFLZzhBRUE2PQEkblBGYklBUW9BRBVIVGtRRG9KVTBsT016bzBOemMzUU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTQUWPExFQUZfTkFNRRIA8gIeChoyMwDwwkxBU1RfTU9ESUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBNXmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0Nzc32gQCCAHgBADwBMXdn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAGXOcNgFAeAFAfAFwvIX-gUECAAQAJAGAZgGALgGAMEGBSIsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=db30796cc71c3bee3aa8fc2890c75ad7186f9d73" - } - } - } - ] - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "2099457773367093540", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "7214207858308840891", - "nobid": true, - "ad_profile_id": 1182765 - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "4564285281969145467", - "nobid": true, - "ad_profile_id": 1182765 - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/description.md b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/description.md deleted file mode 100644 index c1781561af5..00000000000 --- a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/description.md +++ /dev/null @@ -1,40 +0,0 @@ -Test Page - 'integrationExamples/longform/basic_wo_requireExactDuration.html' -Test Spec File - 'test/spec/e2e/longform/basic_wo_requireExactDuration.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'sample-code', - sizes: [640, 480], - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 300, - durationRangeSec: [15, 30], - requireExactDuration: false - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 15394006 - } - } - ] -}]; -``` - -SetConfig to use with AdUnit: -``` -pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - }, - adpod: { - brandCategoryExclusion: true - } -}); -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/request.json b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/request.json deleted file mode 100644 index f2f20700ffe..00000000000 --- a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/request.json +++ /dev/null @@ -1,137 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - }, - { - "sizes": [ - { - "width": 640, - "height": 480 - } - ], - "primary_size": { - "width": 640, - "height": 480 - }, - "ad_types": [ - "video" - ], - "id": 15394006, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 7, - "require_asset_url": true, - "video": { - "maxduration": 30 - } - } - ], - "user": {}, - "brand_category_uniqueness": true - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/response.json b/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/response.json deleted file mode 100644 index 5f2118095d4..00000000000 --- a/test/fake-server/fixtures/longform/longform_wo_requireExactDuration_2/response.json +++ /dev/null @@ -1,224 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "2704229116537156015", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEK_j3NPcwdbDJRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE3OTUxNh8A8P2SArkCIXpUczJvQWlta184UEVOX2ZuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFURVBwVy1oVE9ZXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0BBRHdQdy4umgKJASFVQV9qSDo9ASRuUEZiSUFRb0FEFUhUdVFEb0pVMGxPTXpvME56UTVRTUlZUxF4DFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0DgFlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWyAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggA4AQA8ATf359HiAUBmAUAoAX___________8BwAUAyQUAZWQU8D_SBQkJBQt8AAAA2AUB4AUB8AWsvBT6BQQIABAAkAYBmAYAuAYAwQYBITAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=64565aadf65d370e9730e9ce82c93c9bd2fcfc14", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABGvMXfKDVqHJRm1ywleAAAAACDf359HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1isvBRiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAd_fn0ewAQE.&s=3b1f10f67b3253e38770fff694edbe6052795602&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149417951, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 33, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEK_j3NPcwdbDJRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ39-fR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxNzk1MSwgMTUZH_D9kgK5AiF6VHMyb0FpbWtfOFBFTl9mbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBVEVQcFctaFRPWV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNAQUR3UHcuLpoCiQEhVUFfakg6PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8ItlQUEu2AIA4AKtmEjqAlpodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2xvbmdmb3JtL2Jhc2ljX3dvX3JlcXVpcmVFeGFjdER1cmF0aW9uLmh0bWzyAhMKD0NVU1RPTV9NT0RFTF9JRBIA8gIaChZDVVNUT01fTQUWPExFQUZfTkFNRRIA8gIeChoyMwDwwkxBU1RfTU9ESUZJRUQSAIADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIEDTIwMi41OS4yMzEuNDeoBNXmBLIEEggBEAIYgAUg4AMoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzQ52gQCCAHgBADwBN_fn0eIBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAGXOcNgFAeAFAfAFrLwU-gUECAAQAJAGAZgGALgGAMEGBSIsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=5316c3262f36e4d89735b1ba252c64651a84f479" - } - } - } - ] - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "7987581685263122854", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEKaDmaSQ5-Xsbhiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE5NjAyNh8A8P2SArkCIU16MXpZd2lua184UEVOTHNuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFYLVkxZU5tY3VRXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0RBRHdQdy4umgKJASFVUTgySFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDnaBAIIAOAEAPAE0uyfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF2boG-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=17f2a3f5e78c188cc6ca23e677ced305198a8a05", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABGmQYYEOZfZbhm1ywleAAAAACDS7J9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jZugZiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAdLsn0ewAQE.&s=28e8f96efdfb9bc1e33e4d087ff5ed992e4692b1&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149419602, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 24, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEKaDmaSQ5-Xsbhiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQ0uyfR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxOTYwMiwgMTUZH_D9kgK5AiFNejF6WXdpbmtfOFBFTkxzbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWC1ZMWVObWN1UV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNEQUR3UHcuLpoCiQEhVVE4MkhRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRNVFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggB4AQA8ATS7J9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBdm6BvoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=89d4586d9597cd2f9a4a918d1e6985aee45ade01" - } - } - } - ] - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "653115326806257319", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCLWXp_AFEKfdmd3enZWICRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4NjcxNh8A8P2SArkCITlEd0hNZ2lta184UEVLX2xuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFjTnlESmJxeS13XzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0RBRHdQdy4umgKJASFKZ192RFE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDnaBAIIAOAEAPAEr-WfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULeAAAANgFAeAFAfAF4Fj6BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=1928a9daadbd431792adace7620880dda961eefb", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQm1ywleAAAAABGnbqbr7VQQCRm1ywleAAAAACCv5Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1jgWGICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBr-WfR7ABAQ..&s=7617d08e0c16fe1dea8ec80cd6bf73ec0a736b41&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418671, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 30, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCLWXp_AFEKfdmd3enZWICRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQr-WfR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODY3MSwgMTUZH_D9kgK5AiE5RHdITWdpbWtfOFBFS19sbjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBY055REpicXktd18yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNEQUR3UHcuLpoCiQEhSmdfdkRRNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRNVFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggB4AQA8ASv5Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlzmzYBQHgBQHwBeBY-gUECAAQAJAGAZgGALgGAMEGBSEsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=0d1d3f42fa225995a2f57ab84877dce3d24e9901" - } - } - } - ] - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "866435845408148233", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKeCKAeBAAAAwDWAAUBCLWXp_AFEImW35H52YyDDBiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4MTIzNh8A8P2SArkCIXJEenNfZ2lua184UEVJdmhuMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFjMmZTZ1BpMi1BXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHA1UF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0RBRHdQdy4umgKJASFfdzRiQUE2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDnaBAIIAOAEAPAEi-GfR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULfAAAANgFAeAFAfAF2tYC-gUECAAQAJAGAZgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=83f65f38b4fd56344b3aceb70df7bac1b9b5f229", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=aAAAAAMArgAFAQm1ywleAAAAABEJyzeSzzIGDBm1ywleAAAAACCL4Z9HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1ja1gJiAklOaAFwAXgAgAEBiAEBkAGABZgB4AOgAQCoAYvhn0ewAQE.&s=9130c13cca7a1d3eb05c2b96585ccfdc2faa6844&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418123, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 12, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 15000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL6COh6BAAAAwDWAAUBCLWXp_AFEImW35H52YyDDBiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQi-GfR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODEyMywgMTUZH_D9kgK5AiFyRHpzX2dpbmtfOFBFSXZobjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBYzJmU2dQaTItQV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwNVBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNEQUR3UHcuLpoCiQEhX3c0YkFBNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRNVFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggB4AQA8ASL4Z9HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlznDYBQHgBQHwBdrWAvoFBAgAEACQBgGYBgC4BgDBBgUiLADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGBPIGAggAgAcBiAcAoAdA&s=1f88d8b0a467d528291f90a54fd810b8fdac4488" - } - } - } - ] - }, - { - "uuid": "2022b6b1fcf477", - "tag_id": 15394006, - "auction_id": "1540903203561034860", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QKdCKAdBAAAAwDWAAUBCLWXp_AFEOyokYzL6ZixFRiq5MnUovf28WEqNgkAAAkCABEJBwgAABkJCQjgPyEJCQgAACkRCQAxCQnwaeA_MNbJqwc47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEDwAEAyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTsBHTByJywgMTQ5NDE4OTQ4Nh8A8P2SArkCIXdUekVId2lta184UEVNVG5uMGNZQUNDYzhWc3dBRGdBUUFSSTdVaFExc21yQjFnQVlJSUNhQUJ3QUhnQWdBSElBb2dCd3FjRGtBRUFtQUVBb0FFQnFBRURzQUVBdVFIdEJLRDJBQUF1UU1FQjdRU2c5Z0FBTGtESkFaeE00NUxjRXVNXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFPQUNBT2dDQVBnQ0FJQURBWmdEQWFnRHBwUF9EN29EQ1ZOSlRqTTZORGMwT2VBRHdoaUlCQUNRQkFDWUJBSEJCQUFBQQ1yCHlRUQ0KJEFBQU5nRUFQRUUBCwkBMEQ0QkFDSUJZMGxxUVUJE0RBRHdQdy4umgKJASFQUThhRmc2PQEkblBGYklBUW9BRBVIVHVRRG9KVTBsT016bzBOelE1UU1JWVMReAxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M9A4BZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1sgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQNMjAyLjU5LjIzMS40N6gE1eYEsgQSCAEQAhiABSDgAygBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3NDnaBAIIAOAEAPAExOefR4gFAZgFAKAF____________AcAFAMkFAGVkFPA_0gUJCQULeAAAANgFAeAFAfAFmT36BQQIABAAkAYBmAYAuAYAwQYBIDAAAPC_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=a4de0e4084ce04a5cb2d347c07fde867aa9ff5c1", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "video", - "notify_url": "https://sin3-ib.adnxs.com/vast_track/v2?info=ZwAAAAMArgAFAQm1ywleAAAAABFsVISxTGNiFRm1ywleAAAAACDE559HKAAw7Ug47UhA0-hISLuv1AFQ1smrB1iZPWICSU5oAXABeACAAQGIAQGQAYAFmAHgA6ABAKgBxOefR7ABAQ..&s=cf600d825cec85f83c06119e5e383f8548b469a2&event_type=1", - "usersync_url": "https%3A%2F%2Facdn.adnxs.com%2Fdmp%2Fasync_usersync.html", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 149418948, - "media_type_id": 4, - "media_subtype_id": 64, - "cpm": 15.00001, - "cpm_publisher_currency": 15.00001, - "publisher_currency_code": "$", - "brand_category_id": 1, - "client_initiated_ad_counting": true, - "rtb": { - "video": { - "player_width": 640, - "player_height": 480, - "duration_ms": 30000, - "playback_methods": [ - "auto_play_sound_on" - ], - "frameworks": [ - "vpaid_1_0", - "vpaid_2_0" - ], - "asset_url": "https://sin3-ib.adnxs.com/ab?ro=1&an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2FintegrationExamples%2Flongform%2Fbasic_wo_requireExactDuration.html&e=wqT_3QL5COh5BAAAAwDWAAUBCLWXp_AFEOyokYzL6ZixFRiq5MnUovf28WEqNgmOWItPAQAuQBGOWItPAQAuQBkAAAECCOA_IREbACkRCQAxARm4AADgPzDWyasHOO1IQO1ISAJQxOefR1ic8VtgAGjNunV4t7gFgAEBigEDVVNEkgEBBvBVmAEBoAEBqAEBsAEAuAEDwAEEyAEC0AEA2AEA4AEA8AEAigI8dWYoJ2EnLCAyNTI5ODg1LCAxNTc3NzAwMjc3KTt1ZigncicsIDE0OTQxODk0OCwgMTUZH_D9kgK5AiF3VHpFSHdpbWtfOFBFTVRubjBjWUFDQ2M4VnN3QURnQVFBUkk3VWhRMXNtckIxZ0FZSUlDYUFCd0FIZ0FnQUhJQW9nQndxY0RrQUVBbUFFQW9BRUJxQUVEc0FFQXVRSHRCS0QyQUFBdVFNRUI3UVNnOWdBQUxrREpBWnhNNDVMY0V1TV8yUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBSmdDQUtBQ0FMVUNBQUFBQUwwQ0FBQUFBT0FDQU9nQ0FQZ0NBSUFEQVpnREFhZ0RwcFBfRDdvRENWTkpUak02TkRjME9lQUR3aGlJQkFDUUJBQ1lCQUhCQkFBQUENcgh5UVENCiRBQUFOZ0VBUEVFAQsJATBENEJBQ0lCWTBscVFVCRNEQUR3UHcuLpoCiQEhUFE4YUZnNj0BJG5QRmJJQVFvQUQVSFR1UURvSlUwbE9Nem8wTnpRNVFNSVlTEXgMUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPCLZUFBLtgCAOACrZhI6gJaaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkvaW50ZWdyYXRpb25FeGFtcGxlcy9sb25nZm9ybS9iYXNpY193b19yZXF1aXJlRXhhY3REdXJhdGlvbi5odG1s8gITCg9DVVNUT01fTU9ERUxfSUQSAPICGgoWQ1VTVE9NX00FFjxMRUFGX05BTUUSAPICHgoaMjMA8MJMQVNUX01PRElGSUVEEgCAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA0yMDIuNTkuMjMxLjQ3qATV5gSyBBIIARACGIAFIOADKAEoAjAAOAO4BADABADIBADSBA45MzI1I1NJTjM6NDc0OdoEAggB4AQA8ATE559HiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAAABlzmzYBQHgBQHwBZk9-gUECAAQAJAGAZgGALgGAMEGBSEsAPA_0Ab1L9oGFgoQCREZAVAQABgA4AYE8gYCCACABwGIBwCgB0A.&s=17c466ea45d5d4beff02aa2b0eb87bc6c4d5aff3" - } - } - } - ] - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/modules/description.md b/test/fake-server/fixtures/modules/description.md deleted file mode 100644 index db13453b8aa..00000000000 --- a/test/fake-server/fixtures/modules/description.md +++ /dev/null @@ -1,68 +0,0 @@ -Test Pages: - - 'test/pages/bidderSettings.html' - - 'test/pages/consent_mgt_gdpr.html' - - 'test/pages/currency.html' - - 'test/pages/priceGranularity.html' - - 'test/pages/sizeConfig.html' - - 'test/pages/userSync.html' -Test Spec Files: - - 'test/spec/e2e/modules/e2e_bidderSettings.spec.js' - - 'test/spec/e2e/modules/e2e_consent_mgt_gdpr.spec.js' - - 'test/spec/e2e/modules/e2e_currency.spec.js' - - 'test/spec/e2e/modules/e2e_priceGranularity.spec.js' - - 'test/spec/e2e/modules/e2e_sizeConfig.spec.js' - - 'test/spec/e2e/modules/e2e_userSync.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'div-gpt-ad-1460505748561-0', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - } - }, - // Replace this object to test a new Adapter! - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13144370 - } - }] - -}, { - code: '/19968336/prebid_native_example_2', - sizes: [ - [1, 1] - ], - mediaTypes: { - native: { - title: { - required: true - }, - body: { - required: true - }, - image: { - required: true - }, - sponsoredBy: { - required: true - }, - icon: { - required: false - }, - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13232354, - allowSmallerSizes: true - } - }] -}]; -``` - -Refer to individual test pages to see the proper setConfigs for each test. diff --git a/test/fake-server/fixtures/modules/request.json b/test/fake-server/fixtures/modules/request.json deleted file mode 100644 index 35dd6e2d499..00000000000 --- a/test/fake-server/fixtures/modules/request.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 300, - "height": 250 - }, - { - "width": 300, - "height": 600 - } - ], - "primary_size": { - "width": 300, - "height": 250 - }, - "ad_types": [ - "banner" - ], - "id": 13144370, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 1 - }, - { - "sizes": [ - { - "width": 1, - "height": 1 - } - ], - "ad_types": [ - "native" - ], - "id": 13232354, - "allow_smaller_sizes": true, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "native": { - "layouts": [ - { - "title": { - "required": true - }, - "description": { - "required": true - }, - "main_image": { - "required": true - }, - "sponsored_by": { - "required": true - }, - "icon": { - "required": false - } - } - ] - }, - "hb_source": 1 - } - ], - "user": {} - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/modules/response.json b/test/fake-server/fixtures/modules/response.json deleted file mode 100644 index 9b708fa1534..00000000000 --- a/test/fake-server/fixtures/modules/response.json +++ /dev/null @@ -1,106 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "tag_id": 13144370, - "auction_id": "4842409943576641356", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmodules%2Fcurrency.html%3Fpbjs_debug%3Dtrue&e=wqT_3QK7CKA7BAAAAwDWAAUBCNvV-_AFEMz-0f3_xeyZQxjCs_b6q5D9_0oqNgkAAAkCABEJBywAABkAAACA61HgPyEREgApEQkAMREb8GkwsqKiBjjtSEDtSEgAUABYnPFbYABotc95eACAAQGKAQCSAQNVU0SYAawCoAHYBKgBAbABALgBAcABAMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3OTA4NDUwNyk7AR0scicsIDk4NDkzNTgxNh4A8NCSArUCIVpqeldtZ2l1c0s0S0VJM0oteTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFzcUtpQmxnQVlNSUdhQUJ3RG5qd0U0QUJUSWdCOEJPUUFRQ1lBUUNnQVFHb0FRT3dBUUM1QVNtTGlJTUFBT0Ffd1FFcGk0aURBQURnUDhrQmxiMDhGYV9INERfWkFRQUFBQUFBQVBBXzRBRUE5UUVBQUFBQW1BSUFvQUlBdFFJQUFBQUF2UUlBQUFBQTRBSUE2QUlBLUFJQWdBTUJtQU1CcUFPdQHEiHVnTUpVMGxPTXpvME56TTE0QU80R1lnRUFKQUVBSmdFQWNFCV0FAQhESkIFCAkBGDJBUUE4UVEJDQEBLFBnRUFJZ0ZfeVNwQhEXNFBBX5oCiQEhblE4cUxBNjkBJG5QRmJJQVFvQUQRZBBEZ1B6bzKRABBRTGdaUx1NAFURDAxBQUFXHQwAWR0MAGEdDABjHQzwQGVBQS7CAi9odHRwOi8vcHJlYmlkLm9yZy9kZXYtZG9jcy9nZXR0aW5nLXN0YXJ0ZWQuaHRtbNgCAOACrZhI6gJLDTpIdGVzdC5sb2NhbGhvc3Q6OTk5OQUUWC9wYWdlcy9tb2R1bGVzL2N1cnJlbmN5BUbwQD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA6wCyAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDbDwXpgEAKIECzEwLjc1Ljc0LjY5qATikAGyBBIIBBAEGKwCIPoBKAEoAjAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggA4AQB8ASNyfsuiAUBmAUAoAX_____BQMYAcAFAMkFAAUBFPA_0gUJCQULfAAAANgFAeAFAfAFmfQh-gUECAAQAJAGAJgGALgGAMEGASEwAADwv9AG9S_aBhYKEAkRGQFQEAAYAOAGAfIGAggAgAcBiAcAoAcB&s=16a5ea7c8d5eb050a368495961803753dd6086c2", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "banner", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 98493581, - "media_type_id": 1, - "media_subtype_id": 1, - "cpm": 0.5, - "cpm_publisher_currency": 0.5, - "publisher_currency_code": "$", - "brand_category_id": 53, - "client_initiated_ad_counting": true, - "rtb": { - "banner": { - "content": "
", - "width": 300, - "height": 600 - }, - "trackers": [ - { - "impression_urls": [ - "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmodules%2Fcurrency.html%3Fpbjs_debug%3Dtrue&e=wqT_3QLDCKBDBAAAAwDWAAUBCNvV-_AFEMz-0f3_xeyZQxjCs_b6q5D9_0oqNgkAAAECCOA_EQEHNAAA4D8ZAAAAgOtR4D8hERIAKREJADERG6gwsqKiBjjtSEDtSEgCUI3J-y5YnPFbYABotc95eJ64BYABAYoBA1VTRJIBAQbwUpgBrAKgAdgEqAEBsAEAuAEBwAEEyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5MDg0NTA3KTt1ZigncicsIDk4NDkzNTgxNh4A8NCSArUCIVpqeldtZ2l1c0s0S0VJM0oteTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFzcUtpQmxnQVlNSUdhQUJ3RG5qd0U0QUJUSWdCOEJPUUFRQ1lBUUNnQVFHb0FRT3dBUUM1QVNtTGlJTUFBT0Ffd1FFcGk0aURBQURnUDhrQmxiMDhGYV9INERfWkFRQUFBQUFBQVBBXzRBRUE5UUVBQUFBQW1BSUFvQUlBdFFJQUFBQUF2UUlBQUFBQTRBSUE2QUlBLUFJQWdBTUJtQU1CcUFPdQHEiHVnTUpVMGxPTXpvME56TTE0QU80R1lnRUFKQUVBSmdFQWNFCV0FAQhESkIFCAkBGDJBUUE4UVEJDQEBLFBnRUFJZ0ZfeVNwQhEXNFBBX5oCiQEhblE4cUxBNjkBJG5QRmJJQVFvQUQRZBBEZ1B6bzKRABBRTGdaUx1NAFURDAxBQUFXHQwAWR0MAGEdDABjHQzwQGVBQS7CAi9odHRwOi8vcHJlYmlkLm9yZy9kZXYtZG9jcy9nZXR0aW5nLXN0YXJ0ZWQuaHRtbNgCAOACrZhI6gJLDTpIdGVzdC5sb2NhbGhvc3Q6OTk5OQUUWC9wYWdlcy9tb2R1bGVzL2N1cnJlbmN5BUbwQD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA6wCyAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDbDwXpgEAKIECzEwLjc1Ljc0LjY5qATikAGyBBIIBBAEGKwCIPoBKAEoAjAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggB4AQB8ASNyfsuiAUBmAUAoAX_____BQMYAcAFAMkFAAUBFPA_0gUJCQULfAAAANgFAeAFAfAFmfQh-gUECAAQAJAGAJgGALgGAMEGASEwAADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGAfIGAggAgAcBiAcAoAcB&s=9c378bb4ca21a7509f69955fb4e6fe72035190c6" - ], - "video_events": {} - } - ] - } - } - ] - }, - { - "tag_id": 13232354, - "auction_id": "8100967561168057198", - "nobid": false, - "no_ad_url": "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmodules%2Fcurrency.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKECKAEBAAAAwDWAAUBCNvV-_AFEO7mieO34pq2cBjCs_b6q5D9_0oqNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMOLRpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5MDg0NTA3KTsBHSxyJywgOTc0OTQyMDQ2HgDwmpICtQIhMVR6c3lRajgtTHdLRUx6SnZpNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTR0R25CbGdBWU1JR2FBQndBSGdBZ0FGTWlBSHdFNUFCQUpnQkFLQUJBYWdCQTdBQkFMa0I4NjFxcEFBQUpFREJBZk90YXFRQUFDUkF5UUc5QzZTMEtFampQOWtCQUFBQUFBQUE4RF9nQVFEMUFRAQ8sQ1lBZ0NnQWdDMUFnBRAAOQkI8EBEZ0FnRG9BZ0Q0QWdDQUF3R1lBd0dvQV96NHZBcTZBd2xUU1U0ek9qUTNNelhnQTdnWmlBUUFrQVFBbUFRQndRUQFNCQEITWtFCQkBARhEWUJBRHhCAQsNASwtQVFBaUFYX0pLa0YNEzxBOEQ4LpoCiQEhZUE4dE1BNjkBJG5QRmJJQVFvQUQVWFhrUURvSlUwbE9Nem8wTnpNMVFMZ1pTUQ1PDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQygZUFBLtgCAOACrZhI6gJLaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkFFPDXL3BhZ2VzL21vZHVsZXMvY3VycmVuY3kuaHRtbD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBAsxMC43NS43NC42OagE4pABsgQOCAAQARgAIAAoADAAOAK4BADABADIBADSBA45MzI1I1NJTjM6NDczNdoEAggA4AQB8AS8yb4uiAUBmAUAoAX___________8BwAUAyQUAAAAAAADwP9IFCQkAaVZ0ANgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGCSQo8L_QBvUv2gYWChAJERkBUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=428486554947609aac96ed5569d9bb2dd2be5502", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "native", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 97494204, - "media_type_id": 12, - "media_subtype_id": 65, - "cpm": 10, - "cpm_publisher_currency": 10, - "publisher_currency_code": "$", - "brand_category_id": 53, - "client_initiated_ad_counting": true, - "viewability": { - "config": "" - }, - "rtb": { - "native": { - "title": "This is a Prebid Native Creative", - "desc": "This is a Prebid Native Creative. There are many like it, but this one is mine.", - "sponsored": "Prebid.org", - "icon": { - "url": "http://vcdn.adnxs.com/p/creative-image/1a/3e/e9/5b/1a3ee95b-06cd-4260-98c7-0258627c9197.png", - "width": 127, - "height": 83, - "prevent_crop": false - }, - "main_img": { - "url": "http://vcdn.adnxs.com/p/creative-image/f8/7f/0f/13/f87f0f13-230c-4f05-8087-db9216e393de.jpg", - "width": 989, - "height": 742, - "prevent_crop": false - }, - "link": { - "url": "http://prebid.org/dev-docs/show-native-ads.html", - "click_trackers": [ - "http://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQG5zYnwTa2xwwpldv4L0_0rb6h5eAAAAAOLoyQBtJAAAbSQAAAIAAAC8pM8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoAYBc26wAAAAA./bcr=AAAAAAAA8D8=/cnd=%21eA8tMAj8-LwKELzJvi4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0NzM1QLgZSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ3MzU=/bn=89118/" - ] - }, - "impression_trackers": [ - "http://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmodules%2Fcurrency.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKMCKAMBAAAAwDWAAUBCNvV-_AFEO7mieO34pq2cBjCs_b6q5D9_0oqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlC8yb4uWJzxW2AAaM26dXieuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NzkwODQ1MDcpO3VmKCdyJywgOTc0OTQyMDQsIC4eAPCakgK1AiExVHpzeVFqOC1Md0tFTHpKdmk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRNHRHbkJsZ0FZTUlHYUFCd0FIZ0FnQUZNaUFId0U1QUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRRzlDNlMwS0VqalA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BX3o0dkFxNkF3bFRTVTR6T2pRM016WGdBN2daaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVhfSktrRg0TPEE4RDgumgKJASFlQTh0TUE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBOek0xUUxnWlNRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDKBlQUEu2AIA4AKtmEjqAktodHRwOi8vdGVzdC5sb2NhbGhvc3Q6OTk5OQUU8NcvcGFnZXMvbW9kdWxlcy9jdXJyZW5jeS5odG1sP3BianNfZGVidWc9dHJ1ZYADAIgDAZADAJgDF6ADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzL3ByZWJpZJgEAKIECzEwLjc1Ljc0LjY5qATikAGyBA4IABABGAAgACgAMAA4ArgEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM12gQCCAHgBAHwBLzJvi6IBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQBpXnQA2AUB4AUB8AWZ9CH6BQQIABAAkAYBmAYAuAYAwQYJJCjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGDPIGAggAgAcBiAcAoAdB&s=d6c58ebc137658c5dd258579c2575ad499e7a7b4" - ], - "id": 97494204 - } - } - } - ] - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/description.md b/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/description.md deleted file mode 100644 index c5b114e8bb3..00000000000 --- a/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/description.md +++ /dev/null @@ -1,43 +0,0 @@ -Test Page - 'test/pages/multiple_bidders.html' -Test Spec File - 'test/spec/e2e/multi-bidder/e2e_multiple_bidders.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'div-banner-native-1', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13232392, - } - }] -}, -{ - code: 'div-banner-native-2', - mediaTypes: { - native: { - title: { - required: true - }, - image: { - required: true - }, - sponsoredBy: { - required: true - } - } - }, - bids: [{ - bidder: 'adasta', - params: { - placementId: 13232392, - } - }] -}]; -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/request.json b/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/request.json deleted file mode 100644 index c4c862adc20..00000000000 --- a/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/request.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 1, - "height": 1 - } - ], - "ad_types": [ - "native" - ], - "id": 13232392, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "native": { - "layouts": [ - { - "title": { - "required": true - }, - "main_image": { - "required": true - }, - "sponsored_by": { - "required": true - } - } - ] - }, - "hb_source": 1 - } - ], - "user": {} - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/response.json b/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/response.json deleted file mode 100644 index 56894e97e05..00000000000 --- a/test/fake-server/fixtures/multi-bidder/multi-bidder-adasta/response.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "tag_id": 13232392, - "auction_id": "6287559286677633407", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKICKAIBAAAAwDWAAUBCM3FpfEFEP_yg9W7u_mgVxi7_-bKzp3kuD8qNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQnwaSRAMIjSpwY47UhA7UhIAFAAWJzxW2AAaM26dXgAgAEBigEAkgEDVVNEmAEBoAEBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5NzcwNTczKTsBHSxyJywgOTc1MjA0MzQ2HgDw0JICtQIhQWp4NUh3aUgtYndLRUxLV3dDNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUWlOS25CbGdBWUtzR2FBQndBbmlLQVlBQkhvZ0JpZ0dRQVFDWUFRQ2dBUUdvQVFPd0FRQzVBZk90YXFRQUFDUkF3UUh6cldxa0FBQWtRTWtCb2FZc1BwVDM0VF9aQVFBQUFBQUFBUEFfNEFFQTlRRUFBQUFBbUFJQW9BSUF0UUlBQUFBQXZRSUFBQUFBNEFJQTZBSUEtQUlBZ0FNQm1BTUJxQU9IAcSIdWdNSlUwbE9Nem8wT0RRMDRBUDRHWWdFQUpBRUFKZ0VBY0UJXQUBCERKQgUICQEYMkFRQThRUQkNAQEsUGdFQUlnRjdDV3BCERc0UEFfmgKJASFDZy1TX2c2OQEkblBGYklBUW9BRBVkDGtRRG8ykQAQUVBnWlMdTQBVEQwMQUFBVx0MAFkdDABhHQwAYx0MoGVBQS7YAgDgAq2YSOoCS2h0dHA6Ly90ZXN0LmxvY2FsaG9zdDo5OTk5BRTw3i9wYWdlcy9tdWx0aXBsZV9iaWRkZXJzLmh0bWw_cGJqc19kZWJ1Zz10cnVlgAMAiAMBkAMAmAMXoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMvcHJlYmlkmAQAogQOMTAzLjc5LjEwMC4xODCoBOZCsgQQCAQQARgAIAAoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0ODQ02gQCCADgBAHwBLKWwC6IBQGYBQCgBf___________wHABQDJBQAAAAAAAPA_0gUJCQAAAAABDnDYBQHgBQHwBZn0IfoFBAgAEACQBgGYBgC4BgDBBgEhMAAA8L_QBvUv2gYWChAJERkBUBAAGADgBgzyBgIIAIAHAYgHAKAHQQ..&s=8b14b952b73092945ef66436be991786b53f7a68", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "native", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 97520434, - "media_type_id": 12, - "media_subtype_id": 65, - "cpm": 10, - "cpm_publisher_currency": 10, - "publisher_currency_code": "$", - "brand_category_id": 53, - "client_initiated_ad_counting": true, - "viewability": { - "config": "" - }, - "rtb": { - "native": { - "title": "This is a Prebid Native Creative", - "sponsored": "Prebid.org", - "main_img": { - "url": "https://vcdn.adnxs.com/p/creative-image/f8/7f/0f/13/f87f0f13-230c-4f05-8087-db9216e393de.jpg", - "width": 989, - "height": 742, - "prevent_crop": false - }, - "link": { - "url": "http://prebid.org/dev-docs/show-multi-format-ads.html", - "click_trackers": [ - "https://sin3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQH_5oLrb5UFXu79Z6eyQcT_NYileAAAAAAjpyQBtJAAAbSQAAAIAAAAyC9AFnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAQQCAAAAALoAnRbC8wAAAAA./bcr=AAAAAAAA8D8=/cnd=%21Cg-S_giH-bwKELKWwC4YnPFbIAQoADEAAAAAAAAkQDoJU0lOMzo0ODQ0QPgZSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeAA./cca=OTMyNSNTSU4zOjQ4NDQ=/bn=89112/" - ] - }, - "impression_trackers": [ - "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QKQCKAQBAAAAwDWAAUBCM3FpfEFEP_yg9W7u_mgVxi7_-bKzp3kuD8qNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIjSpwY47UhA7UhIAlCylsAuWJzxW2AAaM26dXiYuAWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQHAAQTIAQLQAQDYAQDgAQDwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1Nzk3NzA1NzMpO3VmKCdyJywgOTc1MjA0MzQsIC4eAPDQkgK1AiFBang1SHdpSC1id0tFTEtXd0M0WUFDQ2M4VnN3QURnQVFBUkk3VWhRaU5LbkJsZ0FZS3NHYUFCd0FuaUtBWUFCSG9nQmlnR1FBUUNZQVFDZ0FRR29BUU93QVFDNUFmT3RhcVFBQUNSQXdRSHpyV3FrQUFBa1FNa0JvYVlzUHBUMzRUX1pBUUFBQUFBQUFQQV80QUVBOVFFQUFBQUFtQUlBb0FJQXRRSUFBQUFBdlFJQUFBQUE0QUlBNkFJQS1BSUFnQU1CbUFNQnFBT0gBxIh1Z01KVTBsT016bzBPRFEwNEFQNEdZZ0VBSkFFQUpnRUFjRQldBQEIREpCBQgJARgyQVFBOFFRCQ0BASxQZ0VBSWdGN0NXcEIRFzRQQV-aAokBIUNnLVNfZzY5ASRuUEZiSUFRb0FEFWQMa1FEbzKRABBRUGdaUx1NAFURDAxBQUFXHQwAWR0MAGEdDABjHQygZUFBLtgCAOACrZhI6gJLaHR0cDovL3Rlc3QubG9jYWxob3N0Ojk5OTkFFPDeL3BhZ2VzL211bHRpcGxlX2JpZGRlcnMuaHRtbD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA-CoAcgDANgDAOADAOgDAPgDAYAEAJIEDS91dC92My9wcmViaWSYBACiBA4xMDMuNzkuMTAwLjE4MKgE5kKyBBAIBBABGAAgACgBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ4NDTaBAIIAeAEAfAEspbALogFAZgFAKAF____________AcAFAMkFAAAAAAAA8D_SBQkJAAAAAAEOcNgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGASEwAADwP9AG9S_aBhYKEAkRGQFQEAAYAOAGDPIGAggAgAcBiAcAoAdB&s=2061bd85ce022a41bc16ebb20c193aabbbc07809" - ], - "id": 97520434 - } - } - } - ] - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/description.md b/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/description.md deleted file mode 100644 index c5b114e8bb3..00000000000 --- a/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/description.md +++ /dev/null @@ -1,43 +0,0 @@ -Test Page - 'test/pages/multiple_bidders.html' -Test Spec File - 'test/spec/e2e/multi-bidder/e2e_multiple_bidders.spec.js' - -Ad Unit that generates given 'Request' - 'Response' pairs. - -```(javascript) -[{ - code: 'div-banner-native-1', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13232392, - } - }] -}, -{ - code: 'div-banner-native-2', - mediaTypes: { - native: { - title: { - required: true - }, - image: { - required: true - }, - sponsoredBy: { - required: true - } - } - }, - bids: [{ - bidder: 'adasta', - params: { - placementId: 13232392, - } - }] -}]; -``` \ No newline at end of file diff --git a/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/request.json b/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/request.json deleted file mode 100644 index 8399bed631c..00000000000 --- a/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/request.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "httpRequest": { - "method": "POST", - "path": "/", - "body": { - "tags": [ - { - "sizes": [ - { - "width": 300, - "height": 250 - }, - { - "width": 300, - "height": 600 - } - ], - "primary_size": { - "width": 300, - "height": 250 - }, - "ad_types": [ - "banner" - ], - "id": 13232392, - "allow_smaller_sizes": false, - "use_pmt_rule": false, - "prebid": true, - "disable_psa": true, - "hb_source": 1 - } - ], - "user": {} - } - } -} \ No newline at end of file diff --git a/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/response.json b/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/response.json deleted file mode 100644 index 54ad643b82d..00000000000 --- a/test/fake-server/fixtures/multi-bidder/multi-bidder-appnexus/response.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "httpResponse": { - "body": { - "version": "3.0.0", - "tags": [ - { - "tag_id": 13232392, - "auction_id": "6917498423334366136", - "nobid": false, - "no_ad_url": "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QLBCKBBBAAAAwDWAAUBCNGcpvEFELjXrYmmhfn_Xxi7_-bKzp3kuD8qNgkAAAkCABEJBwgAABkJCQgkQCEJCQgAACkRCQAxCQn0gQEkQDCI0qcGOO1IQO1ISABQAFic8VtgAGjNunV4AIABAYoBAJIBA1VTRJgBrAKgAfoBqAEBsAEAuAEBwAEAyAEC0AEA2AEA4AEA8AEAigI7dWYoJ2EnLCAyNTI5ODg1LCAxNTc5NzgxNzEzKTt1ZigncicsIDk2ODQ2MDM1LCAxNTc5NzgxNzEzKTuSArUCITZEb2NyZ2lILWJ3S0VOT0JseTRZQUNDYzhWc3dBRGdBUUFSSTdVaFFpTktuQmxnQVlLc0dhQUJ3R25oaWdBR1lBWWdCWXBBQkFKZ0JBS0FCQWFnQkE3QUJBTGtCODYxcXBBQUFKRURCQWZPdGFxUUFBQ1JBeVFHQ1VBT2x6Q0xkUDlrQkFBQUFBQUFBOERfZ0FRRDFBUUFBQUFDWUFnQ2dBZ0MxQWdBQUFBQzlBZ0FBQUFEZ0FnRG9BZ0Q0QWdDQUF3R1lBd0dvQTRmNXZBcTZBd2xUU1U0ek9qUTNNem5nQV9nWmlBUUFrQVFBbUFRQndRUQFNCQEITWtFCQkBARhEWUJBRHhCAQsNASwtQVFBaUFXREpha0YNE0BBOEQ4LpoCiQEhOEE1YjlRaTI5ASRuUEZiSUFRb0FEFVhYa1FEb0pVMGxPTXpvME56TTVRUGdaU1ENTwxQQV9VEQwMQUFBVx0MAFkdDABhHQwAYx0M8EZlQUEuwgI1aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc2hvdy1tdWx0aS1mb3JtYXQtYWRzLmh0bWzYAgDgAq2YSOoCSw1ASHRlc3QubG9jYWxob3N0Ojk5OTkFFBgvcGFnZXMvBUYocGxlX2JpZGRlcnMFRvBAP3BianNfZGVidWc9dHJ1ZYADAIgDAZADAJgDF6ADAaoDAMADrALIAwDYAwDgAwDoAwD4AwGABACSBA0vdXQvdjMNtvBhmAQAogQOMTAzLjc5LjEwMC4xODCoBJ9EsgQSCAQQARisAiD6ASgBKAIwADgDuAQAwAQAyAQA0gQOOTMyNSNTSU4zOjQ3MznaBAIIAOAEAfAE04GXLogFAZgFAKAF______8BAxQBwAUAyQVpiBTwP9IFCQkJDHAAANgFAeAFAfAFAfoFBAgAEACQBgCYBgC4BgDBBgkjKPC_0Ab1L9oGFgoQCREZAVAQABgA4AYB8gYCCACABwGIBwCgBwE.&s=8d42ac30ca2d2a8a63215f5aba2a43bd23af0023", - "timeout_ms": 0, - "ad_profile_id": 1182765, - "rtb_video_fallback": false, - "ads": [ - { - "content_source": "rtb", - "ad_type": "banner", - "buyer_member_id": 9325, - "advertiser_id": 2529885, - "creative_id": 96846035, - "media_type_id": 1, - "media_subtype_id": 1, - "cpm": 10, - "cpm_publisher_currency": 10, - "publisher_currency_code": "$", - "brand_category_id": 0, - "client_initiated_ad_counting": true, - "rtb": { - "banner": { - "content": "
", - "width": 300, - "height": 250 - }, - "trackers": [ - { - "impression_urls": [ - "https://sin3-ib.adnxs.com/it?an_audit=0&referrer=http%3A%2F%2Ftest.localhost%3A9999%2Ftest%2Fpages%2Fmultiple_bidders.html%3Fpbjs_debug%3Dtrue&e=wqT_3QLJCKBJBAAAAwDWAAUBCNGcpvEFELjXrYmmhfn_Xxi7_-bKzp3kuD8qNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMIjSpwY47UhA7UhIAlDTgZcuWJzxW2AAaM26dXicuAWAAQGKAQNVU0SSAQEG8FKYAawCoAH6AagBAbABALgBAcABBMgBAtABANgBAOABAPABAIoCO3VmKCdhJywgMjUyOTg4NSwgMTU3OTc4MTcxMyk7dWYoJ3InLCA5Njg0NjAzNTYeAPCakgK1AiE2RG9jcmdpSC1id0tFTk9CbHk0WUFDQ2M4VnN3QURnQVFBUkk3VWhRaU5LbkJsZ0FZS3NHYUFCd0duaGlnQUdZQVlnQllwQUJBSmdCQUtBQkFhZ0JBN0FCQUxrQjg2MXFwQUFBSkVEQkFmT3RhcVFBQUNSQXlRR0NVQU9sekNMZFA5a0JBQUFBQUFBQThEX2dBUUQxQVEBDyxDWUFnQ2dBZ0MxQWcFEAA5CQjwQERnQWdEb0FnRDRBZ0NBQXdHWUF3R29BNGY1dkFxNkF3bFRTVTR6T2pRM016bmdBX2daaUFRQWtBUUFtQVFCd1FRAU0JAQhNa0UJCQEBGERZQkFEeEIBCw0BLC1BUUFpQVdESmFrRg0TPEE4RDgumgKJASE4QTViOVE2OQEkblBGYklBUW9BRBVYWGtRRG9KVTBsT016bzBOek01UVBnWlNRDU8MUEFfVREMDEFBQVcdDABZHQwAYR0MAGMdDPBGZUFBLsICNWh0dHA6Ly9wcmViaWQub3JnL2Rldi1kb2NzL3Nob3ctbXVsdGktZm9ybWF0LWFkcy5odG1s2AIA4AKtmEjqAksNQEh0ZXN0LmxvY2FsaG9zdDo5OTk5BRQYL3BhZ2VzLwVGKHBsZV9iaWRkZXJzBUbwQD9wYmpzX2RlYnVnPXRydWWAAwCIAwGQAwCYAxegAwGqAwDAA6wCyAMA2AMA4AMA6AMA-AMBgAQAkgQNL3V0L3YzDbbwYZgEAKIEDjEwMy43OS4xMDAuMTgwqASfRLIEEggEEAEYrAIg-gEoASgCMAA4A7gEAMAEAMgEANIEDjkzMjUjU0lOMzo0NzM52gQCCAHgBAHwBNOBly6IBQGYBQCgBf______AQMUAcAFAMkFaZAU8D_SBQkJCQxwAADYBQHgBQHwBQH6BQQIABAAkAYAmAYAuAYAwQYJIyjwP9AG9S_aBhYKEAkRGQFQEAAYAOAGAfIGAggAgAcBiAcAoAcB&s=6c6fb8a005b60bc5535b528c16ed74cd66c08dd0" - ], - "video_events": {} - } - ] - } - } - ] - } - ] - } - } -} \ No newline at end of file diff --git a/test/fake-server/index.js b/test/fake-server/index.js deleted file mode 100644 index 752648c6746..00000000000 --- a/test/fake-server/index.js +++ /dev/null @@ -1,37 +0,0 @@ -/* eslint-disable no-console */ - -const express = require('express'); -const morgan = require('morgan'); -const bodyParser = require('body-parser'); -const argv = require('yargs').argv; -const fakeResponder = require('./fake-responder.js'); - -const PORT = argv.port || '3000'; - -// Initialize express app -const app = express(); - -// Middlewares -app.use(bodyParser.urlencoded({ extended: false })); -app.use(bodyParser.json()); -app.use(bodyParser.text({ type: 'text/plain' })); -app.use(morgan('dev')); // used to log incoming requests - -// Allow Cross Origin request from 'test.localhost:9999' -app.use(function(req, res, next) { - res.header('Access-Control-Allow-Origin', req.headers.origin); - res.header('Access-Control-Allow-Credentials', true); - next(); -}); - -app.post('/', fakeResponder, (req, res) => { - res.send(); -}); - -app.use((req, res) => { - res.status(404).send('Not Found'); -}); - -app.listen(PORT, () => { - console.log(`fake-server listening on http://localhost:${PORT}`); -}); diff --git a/test/fixtures/ad-server-targeting.json b/test/fixtures/ad-server-targeting.json deleted file mode 100644 index 9c6774c1ed5..00000000000 --- a/test/fixtures/ad-server-targeting.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "/9968336/header-bid-tag-0": { - "hb_bidder": "rubicon", - "hb_adid": "13f44b0d3c", - "hb_pb": "1.50" - }, - "/9968336/header-bid-tag1": { - "hb_bidder": "openx", - "hb_adid": "147ac541a", - "hb_pb": "1.00" - } -} diff --git a/test/fixtures/bid-responses-cloned.json b/test/fixtures/bid-responses-cloned.json deleted file mode 100644 index 188518b4565..00000000000 --- a/test/fixtures/bid-responses-cloned.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "/123456/header-bid-tag-1": { - "bids": [] - }, - "/123456/header-bid-tag-0": { - "bids": [ - { - "bidderCode": "criteo", - "width": 0, - "height": 0, - "statusMessage": "Bid returned empty or error response", - "adId": "83fb6a073", - "requestTimestamp": 1454535718619, - "responseTimestamp": 1454535720575, - "timeToRespond": 1956, - "cpm": 0, - "adUnitCode": "/123456/header-bid-tag-0", - "bidder": "criteo" - }, - { - "bidderCode": "sovrn", - "width": 0, - "height": 0, - "statusMessage": "Bid returned empty or error response", - "adId": "9d64dde8c", - "requestTimestamp": 1454535718628, - "responseTimestamp": 1454535721135, - "timeToRespond": 2507, - "cpm": 0, - "adUnitCode": "/123456/header-bid-tag-0", - "bidder": "sovrn" - }, - { - "bidderCode": "pulsepoint", - "width": 0, - "height": 0, - "statusMessage": "Bid returned empty or error response", - "adId": "102e25872d", - "requestTimestamp": 1454535718629, - "responseTimestamp": 1454535721687, - "timeToRespond": 3058, - "cpm": 0, - "adUnitCode": "/123456/header-bid-tag-0", - "bidder": "pulsepoint" - }, - { - "bidderCode": "amazon", - "width": 0, - "height": 0, - "statusMessage": "Bid available", - "adId": "112cdb3eff", - "adUnitCode": "/123456/header-bid-tag-0", - "bidder": "amazon" - }, - { - "bidderCode": "yieldbot", - "width": 0, - "height": 0, - "statusMessage": "Bid returned empty or error response", - "adId": "1234cc92d8", - "requestTimestamp": 1454535718624, - "responseTimestamp": 1454535722273, - "timeToRespond": 3649, - "cpm": 0, - "adUnitCode": "/123456/header-bid-tag-0", - "bidder": "yieldbot" - }, - { - "bidderCode": "openx", - "width": 0, - "height": 0, - "statusMessage": "Bid returned empty or error response", - "adId": "1383ffde21", - "requestTimestamp": 1454535718611, - "responseTimestamp": 1454535724228, - "timeToRespond": 5617, - "cpm": 0, - "adUnitCode": "/123456/header-bid-tag-0", - "bidder": "openx" - }, - { - "bidderCode": "rubicon", - "width": "300", - "height": "250", - "statusMessage": "Bid available", - "adId": "148018fe5e", - "cpm": 0.537234, - "ad": "", - "ad_id": "3163950", - "sizeId": "15", - "requestTimestamp": 1454535718610, - "responseTimestamp": 1454535724863, - "timeToRespond": 6253, - "adUnitCode": "/123456/header-bid-tag-0", - "bidder": "rubicon", - "size": "300x250", - "adserverTargeting": { - "hb_bidder": "rubicon", - "hb_adid": "148018fe5e", - "hb_pb": "10.00", - "foobar": "300x250" - } - }, - { - "bidderCode": "pubmatic", - "width": "300", - "height": "250", - "statusMessage": "Bid available", - "adId": "15bea0b1db", - "adSlot": "39620189@300x250", - "cpm": 0.01, - "ad": "\n ", - "adUrl": "http://aktrack.pubmatic.com/AdServer/AdDisplayTrackerServlet?operId=1&pubId=39741&siteId=66156&adId=148827&adServerId=243&kefact=0.010000&kaxefact=0.010000&kadNetFrequecy=1&kadwidth=300&kadheight=250&kadsizeid=9&kltstamp=1454535719&indirectAdId=0&adServerOptimizerId=2&ranreq=0.052495126612484455&kpbmtpfact=0.011000&dcId=1&tldId=13890466&passback=0&imprId=529C7210-AB7A-4217-A9BD-A3190CA2382A&oid=529C7210-AB7A-4217-A9BD-A3190CA2382A&ias=272&fbs=1&campaignId=5400&creativeId=0&pctr=0.000000&wDSPByrId=1&pageURL=http%3A%2F%2Flocalhost%3A9999%2FintegrationExamples%2Fgpt%2Fgpt.html&lpu=www.xfinity.com", - "dealId": "", - "requestTimestamp": 1454535718617, - "responseTimestamp": 1454535725437, - "timeToRespond": 6820, - "adUnitCode": "/123456/header-bid-tag-0", - "bidder": "pubmatic", - "size": "300x250", - "adserverTargeting": { - "hb_bidder": "pubmatic", - "hb_adid": "15bea0b1db", - "hb_pb": "10.00", - "foobar": "300x250" - } - } - ] - } -} \ No newline at end of file diff --git a/test/fixtures/bid-responses.json b/test/fixtures/bid-responses.json deleted file mode 100644 index 35e55664cdc..00000000000 --- a/test/fixtures/bid-responses.json +++ /dev/null @@ -1,155 +0,0 @@ -{ - "/123456/header-bid-tag-1": { - "bids": [], - "allBidsAvailable": false, - "bidsReceivedCount": 0 - }, - "/123456/header-bid-tag-0": { - "bids": [ - { - "bidderCode": "criteo", - "width": 0, - "height": 0, - "statusMessage": "Bid returned empty or error response", - "adId": "83fb6a073", - "requestTimestamp": 1454535718619, - "responseTimestamp": 1454535720575, - "timeToRespond": 1956, - "cpm": 0, - "pbLg": "", - "pbMg": "", - "pbHg": "", - "adUnitCode": "/123456/header-bid-tag-0", - "bidder": "criteo" - }, - { - "bidderCode": "sovrn", - "width": 0, - "height": 0, - "statusMessage": "Bid returned empty or error response", - "adId": "9d64dde8c", - "requestTimestamp": 1454535718628, - "responseTimestamp": 1454535721135, - "timeToRespond": 2507, - "cpm": 0, - "pbLg": "", - "pbMg": "", - "pbHg": "", - "adUnitCode": "/123456/header-bid-tag-0", - "bidder": "sovrn" - }, - { - "bidderCode": "pulsepoint", - "width": 0, - "height": 0, - "statusMessage": "Bid returned empty or error response", - "adId": "102e25872d", - "requestTimestamp": 1454535718629, - "responseTimestamp": 1454535721687, - "timeToRespond": 3058, - "cpm": 0, - "pbLg": "", - "pbMg": "", - "pbHg": "", - "adUnitCode": "/123456/header-bid-tag-0", - "bidder": "pulsepoint" - }, - { - "bidderCode": "amazon", - "width": 0, - "height": 0, - "statusMessage": "Bid available", - "adId": "112cdb3eff", - "adUnitCode": "/123456/header-bid-tag-0", - "bidder": "amazon" - }, - { - "bidderCode": "yieldbot", - "width": 0, - "height": 0, - "statusMessage": "Bid returned empty or error response", - "adId": "1234cc92d8", - "requestTimestamp": 1454535718624, - "responseTimestamp": 1454535722273, - "timeToRespond": 3649, - "cpm": 0, - "pbLg": "", - "pbMg": "", - "pbHg": "", - "adUnitCode": "/123456/header-bid-tag-0", - "bidder": "yieldbot" - }, - { - "bidderCode": "openx", - "width": 0, - "height": 0, - "statusMessage": "Bid returned empty or error response", - "adId": "1383ffde21", - "requestTimestamp": 1454535718611, - "responseTimestamp": 1454535724228, - "timeToRespond": 5617, - "cpm": 0, - "pbLg": "", - "pbMg": "", - "pbHg": "", - "adUnitCode": "/123456/header-bid-tag-0", - "bidder": "openx" - }, - { - "bidderCode": "rubicon", - "width": "300", - "height": "250", - "statusMessage": "Bid available", - "adId": "148018fe5e", - "cpm": 0.537234, - "ad": "", - "ad_id": "3163950", - "sizeId": "15", - "requestTimestamp": 1454535718610, - "responseTimestamp": 1454535724863, - "timeToRespond": 6253, - "pbLg": "0.50", - "pbMg": "0.50", - "pbHg": "0.53", - "adUnitCode": "/123456/header-bid-tag-0", - "bidder": "rubicon", - "size": "300x250", - "adserverTargeting": { - "hb_bidder": "rubicon", - "hb_adid": "148018fe5e", - "hb_pb": "10.00", - "foobar": "300x250" - } - }, - { - "bidderCode": "pubmatic", - "width": "300", - "height": "250", - "statusMessage": "Bid available", - "adId": "15bea0b1db", - "adSlot": "39620189@300x250", - "cpm": 0.01, - "ad": "\n ", - "adUrl": "http://aktrack.pubmatic.com/AdServer/AdDisplayTrackerServlet?operId=1&pubId=39741&siteId=66156&adId=148827&adServerId=243&kefact=0.010000&kaxefact=0.010000&kadNetFrequecy=1&kadwidth=300&kadheight=250&kadsizeid=9&kltstamp=1454535719&indirectAdId=0&adServerOptimizerId=2&ranreq=0.052495126612484455&kpbmtpfact=0.011000&dcId=1&tldId=13890466&passback=0&imprId=529C7210-AB7A-4217-A9BD-A3190CA2382A&oid=529C7210-AB7A-4217-A9BD-A3190CA2382A&ias=272&fbs=1&campaignId=5400&creativeId=0&pctr=0.000000&wDSPByrId=1&pageURL=http%3A%2F%2Flocalhost%3A9999%2FintegrationExamples%2Fgpt%2Fgpt.html&lpu=www.xfinity.com", - "dealId": "", - "requestTimestamp": 1454535718617, - "responseTimestamp": 1454535725437, - "timeToRespond": 6820, - "pbLg": "0.00", - "pbMg": "0.00", - "pbHg": "0.01", - "adUnitCode": "/123456/header-bid-tag-0", - "bidder": "pubmatic", - "size": "300x250", - "adserverTargeting": { - "hb_bidder": "pubmatic", - "hb_adid": "15bea0b1db", - "hb_pb": "10.00", - "foobar": "300x250" - } - } - ], - "allBidsAvailable": false, - "bidsReceivedCount": 8 - } -} \ No newline at end of file diff --git a/test/fixtures/config.json b/test/fixtures/config.json deleted file mode 100644 index 053efe15f76..00000000000 --- a/test/fixtures/config.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "adUnitElementIDs": [ - "div-test-ad-0", - "div-test-ad-1", - "div-test-ad-2" - ], - "adUnitCodes": [ - "/19968336/header-bid-tag-0", - "/123456/header-bid-tag-1", - "/123456/header-bid-tag-2" - ] -} diff --git a/test/fixtures/cpmInputsOutputs.json b/test/fixtures/cpmInputsOutputs.json deleted file mode 100644 index 7569eef6e97..00000000000 --- a/test/fixtures/cpmInputsOutputs.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "cpmInputs": ["17.638", "19.836", "11.501", "14.384", "23.224", "21.279", "8.886", "16.555", "10.579", "1.331", "1.998", "14.988", "14.864", "10.369", "0.262", "5.269", "6.874", "5.598", "7.191", "15.218", "10.958", "4.420", "17.749", "23.808", "12.353", "21.726", "1.562", "18.085", "1.184", "15.470", "13.841", "17.966", "22.150", "9.088", "13.613", "18.384", "13.690", "23.639", "5.085", "5.779", "11.456", "0.315", "18.557", "20.813", "18.813", "10.202", "10.143", "2.483", "16.147", "2.909", "0.652","2.21","3.15","4.89","2.98","2.99","4.01","4.68","4.69"], - "priceStringOutputs": [{"low":"5.00","med":"17.60","high":"17.63","auto":"17.50","dense":"17.50","custom":""},{"low":"5.00","med":"19.80","high":"19.83","auto":"19.50","dense":"19.50","custom":""},{"low":"5.00","med":"11.50","high":"11.50","auto":"11.50","dense":"11.50","custom":""},{"low":"5.00","med":"14.30","high":"14.38","auto":"14.00","dense":"14.00","custom":""},{"low":"5.00","med":"20.00","high":"20.00","auto":"20.00","dense":"20.00","custom":""},{"low":"5.00","med":"20.00","high":"20.00","auto":"20.00","dense":"20.00","custom":""},{"low":"5.00","med":"8.80","high":"8.88","auto":"8.80","dense":"8.50","custom":""},{"low":"5.00","med":"16.50","high":"16.55","auto":"16.50","dense":"16.50","custom":""},{"low":"5.00","med":"10.50","high":"10.57","auto":"10.50","dense":"10.50","custom":""},{"low":"1.00","med":"1.30","high":"1.33","auto":"1.30","dense":"1.33","custom":""},{"low":"1.50","med":"1.90","high":"1.99","auto":"1.95","dense":"1.99","custom":""},{"low":"5.00","med":"14.90","high":"14.98","auto":"14.50","dense":"14.50","custom":""},{"low":"5.00","med":"14.80","high":"14.86","auto":"14.50","dense":"14.50","custom":""},{"low":"5.00","med":"10.30","high":"10.36","auto":"10.00","dense":"10.00","custom":""},{"low":"0.00","med":"0.20","high":"0.26","auto":"0.25","dense":"0.26","custom":""},{"low":"5.00","med":"5.20","high":"5.26","auto":"5.20","dense":"5.25","custom":""},{"low":"5.00","med":"6.80","high":"6.87","auto":"6.80","dense":"6.85","custom":""},{"low":"5.00","med":"5.50","high":"5.59","auto":"5.50","dense":"5.55","custom":""},{"low":"5.00","med":"7.10","high":"7.19","auto":"7.10","dense":"7.15","custom":""},{"low":"5.00","med":"15.20","high":"15.21","auto":"15.00","dense":"15.00","custom":""},{"low":"5.00","med":"10.90","high":"10.95","auto":"10.50","dense":"10.50","custom":""},{"low":"4.00","med":"4.40","high":"4.42","auto":"4.40","dense":"4.40","custom":""},{"low":"5.00","med":"17.70","high":"17.74","auto":"17.50","dense":"17.50","custom":""},{"low":"5.00","med":"20.00","high":"20.00","auto":"20.00","dense":"20.00","custom":""},{"low":"5.00","med":"12.30","high":"12.35","auto":"12.00","dense":"12.00","custom":""},{"low":"5.00","med":"20.00","high":"20.00","auto":"20.00","dense":"20.00","custom":""},{"low":"1.50","med":"1.50","high":"1.56","auto":"1.55","dense":"1.56","custom":""},{"low":"5.00","med":"18.00","high":"18.08","auto":"18.00","dense":"18.00","custom":""},{"low":"1.00","med":"1.10","high":"1.18","auto":"1.15","dense":"1.18","custom":""},{"low":"5.00","med":"15.40","high":"15.47","auto":"15.00","dense":"15.00","custom":""},{"low":"5.00","med":"13.80","high":"13.84","auto":"13.50","dense":"13.50","custom":""},{"low":"5.00","med":"17.90","high":"17.96","auto":"17.50","dense":"17.50","custom":""},{"low":"5.00","med":"20.00","high":"20.00","auto":"20.00","dense":"20.00","custom":""},{"low":"5.00","med":"9.00","high":"9.08","auto":"9.00","dense":"9.00","custom":""},{"low":"5.00","med":"13.60","high":"13.61","auto":"13.50","dense":"13.50","custom":""},{"low":"5.00","med":"18.30","high":"18.38","auto":"18.00","dense":"18.00","custom":""},{"low":"5.00","med":"13.60","high":"13.69","auto":"13.50","dense":"13.50","custom":""},{"low":"5.00","med":"20.00","high":"20.00","auto":"20.00","dense":"20.00","custom":""},{"low":"5.00","med":"5.00","high":"5.08","auto":"5.00","dense":"5.05","custom":""},{"low":"5.00","med":"5.70","high":"5.77","auto":"5.70","dense":"5.75","custom":""},{"low":"5.00","med":"11.40","high":"11.45","auto":"11.00","dense":"11.00","custom":""},{"low":"0.00","med":"0.30","high":"0.31","auto":"0.30","dense":"0.31","custom":""},{"low":"5.00","med":"18.50","high":"18.55","auto":"18.50","dense":"18.50","custom":""},{"low":"5.00","med":"20.00","high":"20.00","auto":"20.00","dense":"20.00","custom":""},{"low":"5.00","med":"18.80","high":"18.81","auto":"18.50","dense":"18.50","custom":""},{"low":"5.00","med":"10.20","high":"10.20","auto":"10.00","dense":"10.00","custom":""},{"low":"5.00","med":"10.10","high":"10.14","auto":"10.00","dense":"10.00","custom":""},{"low":"2.00","med":"2.40","high":"2.48","auto":"2.45","dense":"2.48","custom":""},{"low":"5.00","med":"16.10","high":"16.14","auto":"16.00","dense":"16.00","custom":""},{"low":"2.50","med":"2.90","high":"2.90","auto":"2.90","dense":"2.90","custom":""},{"low":"0.50","med":"0.60","high":"0.65","auto":"0.65","dense":"0.65","custom":""},{"low":"2.00","med":"2.20","high":"2.21","auto":"2.20","dense":"2.21","custom":""},{"low":"3.00","med":"3.10","high":"3.15","auto":"3.15","dense":"3.15","custom":""},{"low":"4.50","med":"4.80","high":"4.89","auto":"4.85","dense":"4.85","custom":""},{"low":"2.50","med":"2.90","high":"2.98","auto":"2.95","dense":"2.98","custom":""},{"low":"2.50","med":"2.90","high":"2.99","auto":"2.95","dense":"2.99","custom":""},{"low":"4.00","med":"4.00","high":"4.01","auto":"4.00","dense":"4.00","custom":""},{"low":"4.50","med":"4.60","high":"4.68","auto":"4.65","dense":"4.65","custom":""},{"low":"4.50","med":"4.60","high":"4.69","auto":"4.65","dense":"4.65","custom":""}] -} diff --git a/test/fixtures/fixtures.js b/test/fixtures/fixtures.js deleted file mode 100644 index 908382f8daa..00000000000 --- a/test/fixtures/fixtures.js +++ /dev/null @@ -1,1332 +0,0 @@ -// jscs:disable -import CONSTANTS from 'src/constants.json'; -const utils = require('src/utils.js'); - -function convertTargetingsFromOldToNew(targetings) { - var mapOfOldToNew = { - 'hb_bidder': CONSTANTS.TARGETING_KEYS.BIDDER, - 'hb_adid': CONSTANTS.TARGETING_KEYS.AD_ID, - 'hb_pb': CONSTANTS.TARGETING_KEYS.PRICE_BUCKET, - 'hb_size': CONSTANTS.TARGETING_KEYS.SIZE, - 'hb_deal': CONSTANTS.TARGETING_KEYS.DEAL, - 'hb_source': CONSTANTS.TARGETING_KEYS.SOURCE, - 'hb_format': CONSTANTS.TARGETING_KEYS.FORMAT - }; - var newTargetings = {}; - utils._each(targetings, function(value, currentKey) { - var replaced = false; - utils._each(mapOfOldToNew, function(newKey, oldKey) { - if (currentKey.indexOf(oldKey) === 0 && oldKey !== newKey) { - var updatedKey = currentKey.replace(oldKey, newKey); - newTargetings[updatedKey] = targetings[currentKey]; - replaced = true; - } - }); - if (!replaced) { - newTargetings[currentKey] = targetings[currentKey]; - } - }) - return newTargetings; -} - -export function getBidRequests() { - return [ - { - 'bidderCode': 'appnexus', - 'auctionId': '1863e370099523', - 'bidderRequestId': '2946b569352ef2', - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': '4799418', - 'test': 'me' - }, - 'adUnitCode': '/19968336/header-bid-tag1', - 'sizes': [ - [ - 728, - 90 - ], - [ - 970, - 90 - ] - ], - 'mediaTypes': { - 'banner': { - 'sizes': [[728, 90], [970, 90]] - } - }, - 'bidId': '392b5a6b05d648', - 'bidderRequestId': '2946b569352ef2', - 'auctionId': '1863e370099523', - 'transactionId': 'fsafsa' - }, - { - 'bidder': 'appnexus', - 'params': { - 'placementId': '4799418' - }, - 'adUnitCode': '/19968336/header-bid-tag-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'mediaTypes': { - 'banner': { - 'sizes': [[728, 90], [970, 90]] - } - }, - 'bidId': '4dccdc37746135', - 'bidderRequestId': '2946b569352ef2', - 'auctionId': '1863e370099523', - 'transactionId': 'fsafsa' - } - ], - 'start': 1462918897460 - }, - { - 'bidderCode': 'pubmatic', - 'auctionId': '1863e370099523', - 'bidderRequestId': '5e1525bae3eb11', - 'bids': [ - { - 'bidder': 'pubmatic', - 'params': { - 'publisherId': 39741, - 'adSlot': '39620189@300x250' - }, - 'adUnitCode': '/19968336/header-bid-tag-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'bidId': '6d11aa2d5b3659', - 'bidderRequestId': '5e1525bae3eb11', - 'auctionId': '1863e370099523', - 'transactionId': 'fsafsa' - } - ], - 'start': 1462918897463 - }, - { - 'bidderCode': 'rubicon', - 'auctionId': '1863e370099523', - 'bidderRequestId': '8778750ee15a77', - 'bids': [ - { - 'bidder': 'rubicon', - 'params': { - 'accountId': '14062', - 'siteId': '70608', - 'zoneId': '335918', - 'userId': '12346', - 'keywords': [ - 'a', - 'b', - 'c' - ], - 'inventory': { - 'rating': '5-star', - 'prodtype': 'tech' - }, - 'visitor': { - 'ucat': 'new', - 'search': 'iphone' - }, - 'sizes': [ - 15, - 10 - ], - }, - 'adUnitCode': '/19968336/header-bid-tag-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'mediaType': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'bidId': '96aff279720d39', - 'bidderRequestId': '8778750ee15a77', - 'auctionId': '1863e370099523', - 'transactionId': 'fsafsa' - } - ], - 'start': 1462918897474 - }, - { - 'bidderCode': 'triplelift', - 'auctionId': '1863e370099523', - 'bidderRequestId': '107f5e6e98dcf09', - 'bids': [ - { - 'bidder': 'triplelift', - 'params': { - 'inventoryCode': 'sortable_all_right_sports' - }, - 'adUnitCode': '/19968336/header-bid-tag-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'bidId': '1144e2f0de84363', - 'bidderRequestId': '107f5e6e98dcf09', - 'auctionId': '1863e370099523', - 'transactionId': 'fsafsa' - } - ], - 'start': 1462918897475 - }, - { - 'bidderCode': 'brightcom', - 'auctionId': '1863e370099523', - 'bidderRequestId': '12eeded736650b4', - 'bids': [ - { - 'bidder': 'brightcom', - 'params': { - 'tagId': 16577 - }, - 'adUnitCode': '/19968336/header-bid-tag-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'bidId': '135e89c039705da', - 'bidderRequestId': '12eeded736650b4', - 'auctionId': '1863e370099523', - 'transactionId': 'fsafsa' - } - ], - 'start': 1462918897477 - }, - { - 'bidderCode': 'brealtime', - 'auctionId': '1863e370099523', - 'bidderRequestId': '167c4d79b615948', - 'bids': [ - { - 'bidder': 'brealtime', - 'params': { - 'placementId': '4799418' - }, - 'adUnitCode': '/19968336/header-bid-tag-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'bidId': '17dd1d869bed44e', - 'bidderRequestId': '167c4d79b615948', - 'auctionId': '1863e370099523', - 'transactionId': 'fsafsa' - } - ], - 'start': 1462918897479 - }, - { - 'bidderCode': 'pagescience', - 'auctionId': '1863e370099523', - 'bidderRequestId': '18bed198c172a69', - 'bids': [ - { - 'bidder': 'pagescience', - 'params': { - 'placementId': '4799418' - }, - 'adUnitCode': '/19968336/header-bid-tag-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'bidId': '192c8c1df0f5d1d', - 'bidderRequestId': '18bed198c172a69', - 'auctionId': '1863e370099523', - 'transactionId': 'fsafsa' - } - ], - 'start': 1462918897480 - }, - { - 'bidderCode': 'amazon', - 'auctionId': '1863e370099523', - 'bidderRequestId': '20d0d30333715a7', - 'bids': [ - { - 'bidder': 'amazon', - 'params': { - 'aId': 3080 - }, - 'adUnitCode': '/19968336/header-bid-tag-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'bidId': '21ae8131ec04f6e', - 'bidderRequestId': '20d0d30333715a7', - 'auctionId': '1863e370099523', - 'transactionId': 'fsafsa' - } - ], - 'start': 1462918897482 - } - ]; -} - -export function getBidResponses() { - return [ - { - 'bidderCode': 'triplelift', - 'mediaType': 'banner', - 'width': 0, - 'height': 0, - 'statusMessage': 'Bid available', - 'adId': '222bb26f9e8bd', - 'cpm': 0.112256, - 'ad': "", - 'responseTimestamp': 1462919239337, - 'requestTimestamp': 1462919238936, - 'bidder': 'triplelift', - 'adUnitCode': '/19968336/header-bid-tag-0', - 'timeToRespond': 401, - 'pbLg': '0.00', - 'pbMg': '0.10', - 'pbHg': '0.11', - 'pbAg': '0.10', - 'size': '0x0', - 'auctionId': 123456, - 'requestId': '1144e2f0de84363', - 'adserverTargeting': convertTargetingsFromOldToNew({ - 'hb_bidder': 'triplelift', - 'hb_adid': '222bb26f9e8bd', - 'hb_pb': '10.00', - 'hb_size': '0x0', - 'foobar': '0x0' - }), - 'netRevenue': true, - 'currency': 'USD', - 'ttl': 300 - }, - { - 'bidderCode': 'appnexus', - 'mediaType': 'banner', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '233bcbee889d46d', - 'creative_id': 29681110, - 'cpm': 10, - 'adUrl': 'http://lax1-ib.adnxs.com/ab?e=wqT_3QL8BKh8AgAAAwDWAAUBCMjAybkFEMLLiJWTu9PsVxjL84KE1tzG-kkgASotCQAAAQII4D8RAQcQAADgPxkJCQjwPyEJCQjgPykRCaAwuvekAji-B0C-B0gCUNbLkw5YweAnYABokUB4190DgAEBigEDVVNEkgUG8FKYAawCoAH6AagBAbABALgBAcABA8gBANABANgBAOABAPABAIoCOnVmKCdhJywgNDk0NDcyLCAxNDYyOTE5MjQwKTt1ZigncicsIDI5NjgxMTEwLDIeAPBskgLZASFmU21rZ0FpNjBJY0VFTmJMa3c0WUFDREI0Q2N3QURnQVFBUkl2Z2RRdXZla0FsZ0FZSk1IYUFCd0EzZ0RnQUVEaUFFRGtBRUJtQUVCb0FFQnFBRURzQUVBdVFFQUFBQUFBQURnUDhFQgkMTEFBNERfSkFRMkxMcEVUMU93XzJRFSggd1AtQUJBUFVCBSxASmdDaW9EVTJnV2dBZ0MxQWcBFgRDOQkIqERBQWdQSUFnUFFBZ1BZQWdQZ0FnRG9BZ0Q0QWdDQUF3RS6aAiUhV1FrbmI63AAcd2VBbklBUW8JXPCVVS7YAugH4ALH0wHqAh9odHRwOi8vcHJlYmlkLm9yZzo5OTk5L2dwdC5odG1sgAMAiAMBkAMAmAMFoAMBqgMAsAMAuAMAwAOsAsgDANgDAOADAOgDAPgDA4AEAJIEBC9qcHSYBACiBAoxMC4xLjEzLjM3qAQAsgQICAAQABgAIAC4BADABADIBADSBAoxMC4wLjg1Ljkx&s=1bf15e8cdc7c0c8c119614c6386ab1496560da39&referrer=http%3A%2F%2Fprebid.org%3A9999%2Fgpt.html', - 'responseTimestamp': 1462919239340, - 'requestTimestamp': 1462919238919, - 'bidder': 'appnexus', - 'adUnitCode': '/19968336/header-bid-tag-0', - 'timeToRespond': 421, - 'pbLg': '5.00', - 'pbMg': '10.00', - 'pbHg': '10.00', - 'pbAg': '10.00', - 'size': '300x250', - 'alwaysUseBid': true, - 'auctionId': 123456, - 'requestId': '4dccdc37746135', - 'adserverTargeting': convertTargetingsFromOldToNew({ - 'hb_bidder': 'appnexus', - 'hb_adid': '233bcbee889d46d', - 'hb_pb': '10.00', - 'hb_size': '300x250', - 'foobar': '300x250' - }), - 'netRevenue': true, - 'currency': 'USD', - 'ttl': 300 - }, - { - 'bidderCode': 'appnexus', - 'mediaType': 'banner', - 'width': 728, - 'height': 90, - 'statusMessage': 'Bid available', - 'adId': '24bd938435ec3fc', - 'creative_id': 33989846, - 'cpm': 10, - 'adUrl': 'http://lax1-ib.adnxs.com/ab?e=wqT_3QLyBKhyAgAAAwDWAAUBCMjAybkFEOOryfjI7rGNWhjL84KE1tzG-kkgASotCQAAAQII4D8RAQcQAADgPxkJCQjwPyEJCQjgPykRCaAwuvekAji-B0C-B0gCUNbJmhBYweAnYABokUB4mt0CgAEBigEDVVNEkgUG8ECYAdgFoAFaqAEBsAEAuAEBwAEDyAEA0AEA2AEA4AEA8AEAigI6dWYoJ2EnLCA0OTQ0NzIsIDE0NjI5MTkyNDApOwEcLHInLCAzMzk4OTg0NjYeAPBvkgLNASFwU2Y1YUFpNjBJY0VFTmJKbWhBWUFDREI0Q2N3QURnQVFBUkl2Z2RRdXZla0FsZ0FZSk1IYUFCd3lnNTRDb0FCcGh5SUFRcVFBUUdZQVFHZ0FRR29BUU93QVFDNUFRQUFBQUFBQU9BX3dRRQkMSEFEZ1A4a0JJNTJDbGs5VjB6X1oVKCRQQV80QUVBOVFFBSw8bUFLS2dNQ0NENkFDQUxVQwUVBEwwCQh0T0FDQU9nQ0FQZ0NBSUFEQVEuLpoCJSFfZ2lqYXdpMtAA8KZ3ZUFuSUFRb2lvREFnZzgu2ALoB-ACx9MB6gIfaHR0cDovL3ByZWJpZC5vcmc6OTk5OS9ncHQuaHRtbIADAIgDAZADAJgDBaADAaoDALADALgDAMADrALIAwDYAwDgAwDoAwD4AwOABACSBAQvanB0mAQAogQKMTAuMS4xMy4zN6gEi-wJsgQICAAQABgAIAC4BADABADIBADSBAsxMC4wLjgwLjI0MA..&s=1f584d32c2d7ae3ce3662cfac7ca24e710bc7fd0&referrer=http%3A%2F%2Fprebid.org%3A9999%2Fgpt.html', - 'responseTimestamp': 1462919239342, - 'requestTimestamp': 1462919238919, - 'bidder': 'appnexus', - 'adUnitCode': '/19968336/header-bid-tag1', - 'timeToRespond': 423, - 'pbLg': '5.00', - 'pbMg': '10.00', - 'pbHg': '10.00', - 'pbAg': '10.00', - 'size': '728x90', - 'alwaysUseBid': true, - 'auctionId': 123456, - 'requestId': '392b5a6b05d648', - 'adserverTargeting': convertTargetingsFromOldToNew({ - 'hb_bidder': 'appnexus', - 'hb_adid': '24bd938435ec3fc', - 'hb_pb': '10.00', - 'hb_size': '728x90', - 'foobar': '728x90' - }), - 'netRevenue': true, - 'currency': 'USD', - 'ttl': 300 - }, - { - 'bidderCode': 'pagescience', - 'mediaType': 'banner', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '25bedd4813632d7', - 'creative_id': 29681110, - 'cpm': 0.5, - 'adUrl': 'http://lax1-ib.adnxs.com/ab?e=wqT_3QLzBKhzAgAAAwDWAAUBCMjAybkFEM7fioW41qjIQRjL84KE1tzG-kkgASotCQAAAQII4D8RAQcQAADgPxkJCQjwPyEJCQjgPykRCaAwuvekAji-B0C-B0gCUNbLkw5YweAnYABokUB4yIsEgAEBigEDVVNEkgUG8FKYAawCoAH6AagBAbABALgBAcABA8gBANABANgBAOABAPABAIoCOnVmKCdhJywgNDk0NDcyLCAxNDYyOTE5MjQwKTt1ZigncicsIDI5NjgxMTEwLDIeAPBvkgLNASFfeWVLYndpNjBJY0VFTmJMa3c0WUFDREI0Q2N3QURnQVFBUkl2Z2RRdXZla0FsZ0FZSk1IYUFCdzNBMTRDb0FCcGh5SUFRcVFBUUdZQVFHZ0FRR29BUU93QVFDNUFRQUFBQUFBQU9BX3dRRQkMSEFEZ1A4a0JSR3RLaGp1UTFEX1oVKCRQQV80QUVBOVFFBSw8bUFLS2dQVFNES0FDQUxVQwUVBEwwCQhwT0FDQU9nQ0FQZ0NBSUFEQVEuLpoCJSFlQWwtYkE20ADwpndlQW5JQVFvaW9EMDBndy7YAugH4ALH0wHqAh9odHRwOi8vcHJlYmlkLm9yZzo5OTk5L2dwdC5odG1sgAMAiAMBkAMAmAMFoAMBqgMAsAMAuAMAwAOsAsgDANgDAOADAOgDAPgDA4AEAJIEBC9qcHSYBACiBAoxMC4xLjEzLjM3qASL7AmyBAgIABAAGAAgALgEAMAEAMgEANIECzEwLjAuOTMuMjAy&s=1fd8d5650fa1fb8d918a2f403d6a1f97c10d7ec2&referrer=http%3A%2F%2Fprebid.org%3A9999%2Fgpt.html', - 'responseTimestamp': 1462919239343, - 'requestTimestamp': 1462919238943, - 'bidder': 'pagescience', - 'adUnitCode': '/19968336/header-bid-tag-0', - 'timeToRespond': 400, - 'pbLg': '0.50', - 'pbMg': '0.50', - 'pbHg': '0.50', - 'pbAg': '0.50', - 'size': '300x250', - 'auctionId': 123456, - 'requestId': '192c8c1df0f5d1d', - 'adserverTargeting': convertTargetingsFromOldToNew({ - 'hb_bidder': 'pagescience', - 'hb_adid': '25bedd4813632d7', - 'hb_pb': '10.00', - 'hb_size': '300x250', - 'foobar': '300x250' - }), - 'netRevenue': true, - 'currency': 'USD', - 'ttl': 300 - }, - { - 'bidderCode': 'brightcom', - 'mediaType': 'banner', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '26e0795ab963896', - 'cpm': 0.17, - 'ad': "", - 'responseTimestamp': 1462919239420, - 'requestTimestamp': 1462919238937, - 'bidder': 'brightcom', - 'adUnitCode': '/19968336/header-bid-tag-0', - 'timeToRespond': 483, - 'pbLg': '0.00', - 'pbMg': '0.10', - 'pbHg': '0.17', - 'pbAg': '0.15', - 'size': '300x250', - 'auctionId': 654321, - 'requestId': '135e89c039705da', - 'adserverTargeting': convertTargetingsFromOldToNew({ - 'hb_bidder': 'brightcom', - 'hb_adid': '26e0795ab963896', - 'hb_pb': '10.00', - 'hb_size': '300x250', - 'foobar': '300x250' - }), - 'netRevenue': true, - 'currency': 'USD', - 'ttl': 300 - }, - { - 'bidderCode': 'brealtime', - 'mediaType': 'banner', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '275bd666f5a5a5d', - 'creative_id': 29681110, - 'cpm': 0.5, - 'adUrl': 'http://lax1-ib.adnxs.com/ab?e=wqT_3QLzBKhzAgAAAwDWAAUBCMjAybkFEIPr4YfMvKLoQBjL84KE1tzG-kkgASotCQAAAQII4D8RAQcQAADgPxkJCQjwPyEJCQjgPykRCaAwuvekAji-B0C-B0gCUNbLkw5YweAnYABokUB4mo8EgAEBigEDVVNEkgUG8FKYAawCoAH6AagBAbABALgBAcABA8gBANABANgBAOABAPABAIoCOnVmKCdhJywgNDk0NDcyLCAxNDYyOTE5MjQwKTt1ZigncicsIDI5NjgxMTEwLDIeAPBvkgLNASFsU2NQWlFpNjBJY0VFTmJMa3c0WUFDREI0Q2N3QURnQVFBUkl2Z2RRdXZla0FsZ0FZSk1IYUFCdzNBMTRDb0FCcGh5SUFRcVFBUUdZQVFHZ0FRR29BUU93QVFDNUFRQUFBQUFBQU9BX3dRRQkMSEFEZ1A4a0JHZmNvazFBejFUX1oVKCRQQV80QUVBOVFFBSw8bUFLS2dOU0NEYUFDQUxVQwUVBEwwCQh0T0FDQU9nQ0FQZ0NBSUFEQVEuLpoCJSFDUWxfYXdpMtAA8KZ3ZUFuSUFRb2lvRFVnZzAu2ALoB-ACx9MB6gIfaHR0cDovL3ByZWJpZC5vcmc6OTk5OS9ncHQuaHRtbIADAIgDAZADAJgDBaADAaoDALADALgDAMADrALIAwDYAwDgAwDoAwD4AwOABACSBAQvanB0mAQAogQKMTAuMS4xMy4zN6gEi-wJsgQICAAQABgAIAC4BADABADIBADSBAsxMC4wLjg1LjIwOA..&s=975cfe6518f064683541240f0d780d93a5f973da&referrer=http%3A%2F%2Fprebid.org%3A9999%2Fgpt.html', - 'responseTimestamp': 1462919239486, - 'requestTimestamp': 1462919238941, - 'bidder': 'brealtime', - 'adUnitCode': '/19968336/header-bid-tag-0', - 'timeToRespond': 545, - 'pbLg': '0.50', - 'pbMg': '0.50', - 'pbHg': '0.50', - 'pbAg': '0.50', - 'size': '300x250', - 'auctionId': 654321, - 'requestId': '17dd1d869bed44e', - 'adserverTargeting': convertTargetingsFromOldToNew({ - 'hb_bidder': 'brealtime', - 'hb_adid': '275bd666f5a5a5d', - 'hb_pb': '10.00', - 'hb_size': '300x250', - 'foobar': '300x250' - }), - 'netRevenue': true, - 'currency': 'USD', - 'ttl': 300 - }, - { - 'bidderCode': 'pubmatic', - 'mediaType': 'banner', - 'width': '300', - 'height': '250', - 'statusMessage': 'Bid available', - 'adId': '28f4039c636b6a7', - 'adSlot': '39620189@300x250', - 'cpm': 5.9396, - 'ad': "\r
", - 'dealId': '', - 'responseTimestamp': 1462919239544, - 'requestTimestamp': 1462919238922, - 'bidder': 'pubmatic', - 'adUnitCode': '/19968336/header-bid-tag-0', - 'timeToRespond': 622, - 'pbLg': '5.00', - 'pbMg': '5.90', - 'pbHg': '5.93', - 'pbAg': '5.90', - 'size': '300x250', - 'auctionId': 654321, - 'requestId': '6d11aa2d5b3659', - 'adserverTargeting': convertTargetingsFromOldToNew({ - 'hb_bidder': 'pubmatic', - 'hb_adid': '28f4039c636b6a7', - 'hb_pb': '10.00', - 'hb_size': '300x250', - 'foobar': '300x250' - }), - 'netRevenue': true, - 'currency': 'USD', - 'ttl': 300 - }, - { - 'bidderCode': 'rubicon', - 'mediaType': 'banner', - 'width': 300, - 'height': 600, - 'statusMessage': 'Bid available', - 'adId': '29019e2ab586a5a', - 'cpm': 2.74, - 'ad': '', - 'responseTimestamp': 1462919239860, - 'requestTimestamp': 1462919238934, - 'bidder': 'rubicon', - 'adUnitCode': '/19968336/header-bid-tag-0', - 'timeToRespond': 926, - 'pbLg': '2.50', - 'pbMg': '2.70', - 'pbHg': '2.74', - 'pbAg': '2.70', - 'size': '300x600', - 'auctionId': 654321, - 'requestId': '96aff279720d39', - 'adserverTargeting': convertTargetingsFromOldToNew({ - 'hb_bidder': 'rubicon', - 'hb_adid': '29019e2ab586a5a', - 'hb_pb': '10.00', - 'hb_size': '300x600', - 'foobar': '300x600' - }), - 'netRevenue': true, - 'currency': 'USD', - 'ttl': 300 - } - ]; -} - -export function getSlotTargeting() { - return { - '/19968336/header-bid-tag-0': [ - convertTargetingsFromOldToNew({ - 'hb_bidder': [ - 'appnexus' - ] - }), - convertTargetingsFromOldToNew({ - 'hb_adid': [ - '233bcbee889d46d' - ] - }), - convertTargetingsFromOldToNew({ - 'hb_pb': [ - '10.00' - ] - }), - convertTargetingsFromOldToNew({ - 'hb_size': [ - '300x250' - ] - }), - { - 'foobar': [ - '300x250' - ] - } - ] - }; -} - -export function getAdUnits() { - return [ - { - 'code': '/19968336/header-bid-tag1', - 'mediaTypes': { - 'banner': { - 'sizes': [[728, 90], [970, 90]] - }, - }, - 'bids': [ - { - 'bidder': 'adequant', - 'params': { - 'publisher_id': '1234567', - 'bidfloor': 0.01 - } - }, - { - 'bidder': 'appnexus', - 'params': { - 'placementId': '543221', - } - }, - { - 'bidder': 'pubmatic', - 'params': { - 'publisherId': 1234567, - 'adSlot': '1234567@728x90' - } - } - ] - }, - { - 'code': '/19968336/header-bid-tag-0', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': '5324321' - } - }, - { - 'bidder': 'adequant', - 'params': { - 'publisher_id': '12353433', - 'bidfloor': 0.01 - } - }, - { - 'bidder': 'triplelift', - 'params': { - 'inventoryCode': 'inv_code_here' - } - }, - { - 'bidder': 'springserve', - 'params': { - 'impId': 1234, - 'supplyPartnerId': 1, - 'test': true - } - }, - { - 'bidder': 'rubicon', - 'params': { - 'accountId': '123456', - 'siteId': '345678', - 'zoneId': '234567', - 'userId': '12346', - 'keywords': [ - 'a', - 'b', - 'c' - ], - 'inventory': { - 'rating': '5-star', - 'prodtype': 'tech' - }, - 'visitor': { - 'ucat': 'new', - 'search': 'iphone' - }, - 'sizes': [ - 15, - 10 - ] - } - }, - { - 'bidder': 'openx', - 'params': { - 'jstag_url': 'http://servedbyopenx.com/w/1.0/jstag?nc=account_key', - 'unit': 2345677 - } - }, - { - 'bidder': 'pubmatic', - 'params': { - 'publisherId': 1234567, - 'adSlot': '1234567@300x250' - } - }, - { - 'bidder': 'pagescience', - 'params': { - 'placementId': '1234567' - } - }, - { - 'bidder': 'brealtime', - 'params': { - 'placementId': '1234567' - } - }, - { - 'bidder': 'indexExchange', - 'params': { - 'id': '1', - 'siteID': 123456, - 'timeout': 10000 - } - }, - { - 'bidder': 'adform', - 'params': { - 'adxDomain': 'adx.adform.net', - 'mid': 123456, - 'test': 1 - } - }, - { - 'bidder': 'amazon', - 'params': { - 'aId': 3080 - } - }, - { - 'bidder': 'aol', - 'params': { - 'network': '112345.45', - 'placement': 12345 - } - }, - { - 'bidder': 'sovrn', - 'params': { - 'tagid': '123556' - } - }, - { - 'bidder': 'pulsepoint', - 'params': { - 'cf': '300X250', - 'cp': 1233456, - 'ct': 12357 - } - }, - { - 'bidder': 'brightcom', - 'params': { - 'tagId': 75423 - } - } - ] - } - ]; -}; - -export function getBidResponsesFromAPI() { - return { - '/19968336/header-bid-tag-0': { - 'bids': [ - { - 'bidderCode': 'brightcom', - 'width': 300, - 'height': 250, - 'mediaType': 'banner', - 'statusMessage': 'Bid available', - 'adId': '26e0795ab963896', - 'cpm': 0.17, - 'ad': "", - 'responseTimestamp': 1462919239420, - 'requestTimestamp': 1462919238937, - 'bidder': 'brightcom', - 'adUnitCode': '/19968336/header-bid-tag-0', - 'timeToRespond': 483, - 'pbLg': '0.00', - 'pbMg': '0.10', - 'pbHg': '0.17', - 'pbAg': '0.15', - 'size': '300x250', - 'auctionId': 654321, - 'requestId': '135e89c039705da', - 'adserverTargeting': convertTargetingsFromOldToNew({ - 'hb_bidder': 'brightcom', - 'hb_adid': '26e0795ab963896', - 'hb_pb': '10.00', - 'hb_size': '300x250', - 'foobar': '300x250' - }), - 'netRevenue': true, - 'currency': 'USD', - 'ttl': 300 - }, - { - 'bidderCode': 'brealtime', - 'width': 300, - 'height': 250, - 'mediaType': 'banner', - 'statusMessage': 'Bid available', - 'adId': '275bd666f5a5a5d', - 'creative_id': 29681110, - 'cpm': 0.5, - 'adUrl': 'http://lax1-ib.adnxs.com/ab?e=wqT_3QLzBKhzAgAAAwDWAAUBCMjAybkFEIPr4YfMvKLoQBjL84KE1tzG-kkgASotCQAAAQII4D8RAQcQAADgPxkJCQjwPyEJCQjgPykRCaAwuvekAji-B0C-B0gCUNbLkw5YweAnYABokUB4mo8EgAEBigEDVVNEkgUG8FKYAawCoAH6AagBAbABALgBAcABA8gBANABANgBAOABAPABAIoCOnVmKCdhJywgNDk0NDcyLCAxNDYyOTE5MjQwKTt1ZigncicsIDI5NjgxMTEwLDIeAPBvkgLNASFsU2NQWlFpNjBJY0VFTmJMa3c0WUFDREI0Q2N3QURnQVFBUkl2Z2RRdXZla0FsZ0FZSk1IYUFCdzNBMTRDb0FCcGh5SUFRcVFBUUdZQVFHZ0FRR29BUU93QVFDNUFRQUFBQUFBQU9BX3dRRQkMSEFEZ1A4a0JHZmNvazFBejFUX1oVKCRQQV80QUVBOVFFBSw8bUFLS2dOU0NEYUFDQUxVQwUVBEwwCQh0T0FDQU9nQ0FQZ0NBSUFEQVEuLpoCJSFDUWxfYXdpMtAA8KZ3ZUFuSUFRb2lvRFVnZzAu2ALoB-ACx9MB6gIfaHR0cDovL3ByZWJpZC5vcmc6OTk5OS9ncHQuaHRtbIADAIgDAZADAJgDBaADAaoDALADALgDAMADrALIAwDYAwDgAwDoAwD4AwOABACSBAQvanB0mAQAogQKMTAuMS4xMy4zN6gEi-wJsgQICAAQABgAIAC4BADABADIBADSBAsxMC4wLjg1LjIwOA..&s=975cfe6518f064683541240f0d780d93a5f973da&referrer=http%3A%2F%2Fprebid.org%3A9999%2Fgpt.html', - 'responseTimestamp': 1462919239486, - 'requestTimestamp': 1462919238941, - 'bidder': 'brealtime', - 'adUnitCode': '/19968336/header-bid-tag-0', - 'timeToRespond': 545, - 'pbLg': '0.50', - 'pbMg': '0.50', - 'pbHg': '0.50', - 'pbAg': '0.50', - 'size': '300x250', - 'auctionId': 654321, - 'requestId': '17dd1d869bed44e', - 'adserverTargeting': convertTargetingsFromOldToNew({ - 'hb_bidder': 'brealtime', - 'hb_adid': '275bd666f5a5a5d', - 'hb_pb': '10.00', - 'hb_size': '300x250', - 'foobar': '300x250' - }), - 'netRevenue': true, - 'currency': 'USD', - 'ttl': 300 - }, - { - 'bidderCode': 'pubmatic', - 'width': '300', - 'height': '250', - 'mediaType': 'banner', - 'statusMessage': 'Bid available', - 'adId': '28f4039c636b6a7', - 'adSlot': '39620189@300x250', - 'cpm': 5.9396, - 'ad': "\r
", - 'dealId': '', - 'responseTimestamp': 1462919239544, - 'requestTimestamp': 1462919238922, - 'bidder': 'pubmatic', - 'adUnitCode': '/19968336/header-bid-tag-0', - 'timeToRespond': 622, - 'pbLg': '5.00', - 'pbMg': '5.90', - 'pbHg': '5.93', - 'pbAg': '5.90', - 'size': '300x250', - 'auctionId': 654321, - 'requestId': '6d11aa2d5b3659', - 'adserverTargeting': convertTargetingsFromOldToNew({ - 'hb_bidder': 'pubmatic', - 'hb_adid': '28f4039c636b6a7', - 'hb_pb': '10.00', - 'hb_size': '300x250', - 'foobar': '300x250' - }), - 'netRevenue': true, - 'currency': 'USD', - 'ttl': 300 - }, - { - 'bidderCode': 'rubicon', - 'width': 300, - 'height': 600, - 'mediaType': 'banner', - 'statusMessage': 'Bid available', - 'adId': '29019e2ab586a5a', - 'cpm': 2.74, - 'ad': '', - 'responseTimestamp': 1462919239860, - 'requestTimestamp': 1462919238934, - 'bidder': 'rubicon', - 'adUnitCode': '/19968336/header-bid-tag-0', - 'timeToRespond': 926, - 'pbLg': '2.50', - 'pbMg': '2.70', - 'pbHg': '2.74', - 'pbAg': '2.70', - 'size': '300x600', - 'auctionId': 654321, - 'requestId': '96aff279720d39', - 'adserverTargeting': convertTargetingsFromOldToNew({ - 'hb_bidder': 'rubicon', - 'hb_adid': '29019e2ab586a5a', - 'hb_pb': '10.00', - 'hb_size': '300x600', - 'foobar': '300x600' - }), - 'netRevenue': true, - 'currency': 'USD', - 'ttl': 300 - } - ] - } - }; -} - -// Ad server targeting when `setConfig({ enableSendAllBids: true })` is set. -export function getAdServerTargeting() { - return { - '/19968336/header-bid-tag-0': convertTargetingsFromOldToNew({ - 'foobar': '0x0,300x250,300x600', - 'hb_size': '300x250', - 'hb_pb': '10.00', - 'hb_adid': '233bcbee889d46d', - 'hb_bidder': 'appnexus', - 'hb_size_triplelift': '0x0', - 'hb_pb_triplelift': '10.00', - 'hb_adid_triplelift': '222bb26f9e8bd', - 'hb_bidder_triplelift': 'triplelift', - 'hb_size_appnexus': '300x250', - 'hb_pb_appnexus': '10.00', - 'hb_adid_appnexus': '233bcbee889d46d', - 'hb_bidder_appnexus': 'appnexus', - 'hb_size_pagescience': '300x250', - 'hb_pb_pagescience': '10.00', - 'hb_adid_pagescience': '25bedd4813632d7', - 'hb_bidder_pagescienc': 'pagescience', - 'hb_size_brightcom': '300x250', - 'hb_pb_brightcom': '10.00', - 'hb_adid_brightcom': '26e0795ab963896', - 'hb_bidder_brightcom': 'brightcom', - 'hb_size_brealtime': '300x250', - 'hb_pb_brealtime': '10.00', - 'hb_adid_brealtime': '275bd666f5a5a5d', - 'hb_bidder_brealtime': 'brealtime', - 'hb_size_pubmatic': '300x250', - 'hb_pb_pubmatic': '10.00', - 'hb_adid_pubmatic': '28f4039c636b6a7', - 'hb_bidder_pubmatic': 'pubmatic', - 'hb_size_rubicon': '300x600', - 'hb_pb_rubicon': '10.00', - 'hb_adid_rubicon': '29019e2ab586a5a', - 'hb_bidder_rubicon': 'rubicon' - }), - '/19968336/header-bid-tag1': convertTargetingsFromOldToNew({ - 'foobar': '728x90', - 'hb_size': '728x90', - 'hb_pb': '10.00', - 'hb_adid': '24bd938435ec3fc', - 'hb_bidder': 'appnexus', - 'hb_size_appnexus': '728x90', - 'hb_pb_appnexus': '10.00', - 'hb_adid_appnexus': '24bd938435ec3fc', - 'hb_bidder_appnexus': 'appnexus' - }) - }; -} - -// Key/values used to set ad server targeting. -export function getTargetingKeys() { - return [ - [ - CONSTANTS.TARGETING_KEYS.BIDDER, - 'appnexus' - ], - [ - CONSTANTS.TARGETING_KEYS.AD_ID, - '233bcbee889d46d' - ], - [ - CONSTANTS.TARGETING_KEYS.PRICE_BUCKET, - '10.00' - ], - [ - CONSTANTS.TARGETING_KEYS.SIZE, - '300x250' - ], - [ - 'foobar', - ['0x0', '300x250', '300x600'] - ] - ]; -} - -// Key/values used to set ad server targeting when bid landscape -// targeting is on. -export function getTargetingKeysBidLandscape() { - return [ - [ - CONSTANTS.TARGETING_KEYS.BIDDER, - 'appnexus' - ], - [ - CONSTANTS.TARGETING_KEYS.AD_ID + '_appnexus', - '233bcbee889d46d' - ], - [ - CONSTANTS.TARGETING_KEYS.PRICE_BUCKET, - '10.00' - ], - [ - CONSTANTS.TARGETING_KEYS.SIZE, - '300x250' - ], - [ - 'foobar', - ['0x0', '300x250', '300x600'] - ], - [ - CONSTANTS.TARGETING_KEYS.BIDDER + '_triplelift', - 'triplelift' - ], - [ - CONSTANTS.TARGETING_KEYS.AD_ID + '_triplelift', - '222bb26f9e8bd' - ], - [ - CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_triplelift', - '10.00' - ], - [ - CONSTANTS.TARGETING_KEYS.SIZE + '_triplelift', - '0x0' - ], - [ - CONSTANTS.TARGETING_KEYS.BIDDER + '_appnexus', - 'appnexus' - ], - [ - CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_appnexus', - '10.00' - ], - [ - CONSTANTS.TARGETING_KEYS.SIZE + '_appnexus', - '300x250' - ], - [ - CONSTANTS.TARGETING_KEYS.BIDDER + '_pagescienc', - 'pagescience' - ], - [ - CONSTANTS.TARGETING_KEYS.AD_ID + '_pagescience', - '25bedd4813632d7' - ], - [ - CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_pagescience', - '10.00' - ], - [ - CONSTANTS.TARGETING_KEYS.SIZE + '_pagescience', - '300x250' - ], - [ - CONSTANTS.TARGETING_KEYS.BIDDER + '_brightcom', - 'brightcom' - ], - [ - CONSTANTS.TARGETING_KEYS.AD_ID + '_brightcom', - '26e0795ab963896' - ], - [ - CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_brightcom', - '10.00' - ], - [ - CONSTANTS.TARGETING_KEYS.SIZE + '_brightcom', - '300x250' - ], - [ - CONSTANTS.TARGETING_KEYS.BIDDER + '_brealtime', - 'brealtime' - ], - [ - CONSTANTS.TARGETING_KEYS.AD_ID + '_brealtime', - '275bd666f5a5a5d' - ], - [ - CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_brealtime', - '10.00' - ], - [ - CONSTANTS.TARGETING_KEYS.SIZE + '_brealtime', - '300x250' - ], - [ - CONSTANTS.TARGETING_KEYS.BIDDER + '_pubmatic', - 'pubmatic' - ], - [ - CONSTANTS.TARGETING_KEYS.AD_ID + '_pubmatic', - '28f4039c636b6a7' - ], - [ - CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_pubmatic', - '10.00' - ], - [ - CONSTANTS.TARGETING_KEYS.SIZE + '_pubmatic', - '300x250' - ], - [ - CONSTANTS.TARGETING_KEYS.BIDDER + '_rubicon', - 'rubicon' - ], - [ - CONSTANTS.TARGETING_KEYS.AD_ID + '_rubicon', - '29019e2ab586a5a' - ], - [ - CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_rubicon', - '10.00' - ], - [ - CONSTANTS.TARGETING_KEYS.SIZE + '_rubicon', - '300x600' - ] - ]; -} - -export function getBidRequestedPayload() { - return { - 'bidderCode': 'adequant', - 'auctionId': '150f361b202aa8', - 'bidderRequestId': '2b193b7a6ff421', - 'bids': [ - { - 'bidder': 'adequant', - 'params': { - 'publisher_id': '5000563', - 'bidfloor': 0.01 - }, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ], - [ - 300, - 250 - ], - [ - 100, - 100 - ] - ], - 'bidId': '39032dc5c7e834', - 'bidderRequestId': '2b193b7a6ff421', - 'auctionId': '150f361b202aa8' - } - ], - 'start': 1465426155412 - }; -} - -export function getCurrencyRates() { - return { - 'dataAsOf': '2017-04-25', - 'conversions': { - 'GBP': { 'CNY': 8.8282, 'JPY': 141.7, 'USD': 1.2824 }, - 'USD': { 'CNY': 6.8842, 'GBP': 0.7798, 'JPY': 110.49 } - } - }; -} - -export function createBidReceived({bidder, cpm, auctionId, responseTimestamp, adUnitCode, adId, status, ttl, requestId}) { - let bid = { - 'bidderCode': bidder, - 'width': '300', - 'height': '250', - 'statusMessage': 'Bid available', - 'adId': adId, - 'cpm': cpm, - 'ad': 'markup', - 'ad_id': adId, - 'sizeId': '15', - 'requestTimestamp': 1454535718610, - 'responseTimestamp': responseTimestamp, - 'auctionId': auctionId, - 'requestId': requestId, - 'timeToRespond': 123, - 'pbLg': '0.50', - 'pbMg': '0.50', - 'pbHg': '0.53', - 'adUnitCode': adUnitCode, - 'bidder': bidder, - 'size': '300x250', - 'adserverTargeting': convertTargetingsFromOldToNew({ - 'hb_bidder': bidder, - 'hb_adid': adId, - 'hb_pb': cpm, - 'foobar': '300x250' - }), - 'netRevenue': true, - 'currency': 'USD', - 'ttl': (!ttl) ? 300 : ttl - }; - - if (typeof status !== 'undefined') { - bid.status = status; - } - return bid; -} - -export function getServerTestingsAds() { - return [ - { - code: 'test_div_1', - sizes: [[728, 90]], - bids: [ - { - 'bidSource': { 'client': 0, 'server': 100 }, - 'bidder': 'rubicon' - }, - { - 'bidSource': { 'client': 100, 'server': 0 }, - 'bidder': 'appnexus' - } - ] - }, - { - code: 'test_div_2', - sizes: [[300, 250]], - bids: [ - { - 'bidSource': { 'client': 100, 'server': 0 }, - 'bidder': 'rubicon' - }, - { - 'bidSource': { 'client': 100, 'server': 0 }, - 'bidder': 'appnexus' - } - ] - }, - { - code: 'test_div_3', - sizes: [[300, 250]], - bids: [{ bidder: 'adequant' }] - }, - { - code: 'test_div_4', - sizes: [[300, 250]], - bids: [{ bidder: 'openx' }] - } - ]; -}; - -export const getServerTestingConfig = (config, override = {}) => - Object.assign({}, config, { - enabled: true, - testing: true, - testServerOnly: true, - bidders: ['appnexus', 'rubicon', 'openx'], - bidderControl: { - rubicon: { - bidSource: { server: 100, client: 0 }, - includeSourceKvp: true - }, - appnexus: { - bidSource: { server: 0, client: 100 }, - includeSourceKvp: true - } - } - }, override); diff --git a/test/fixtures/googletag-slots.json b/test/fixtures/googletag-slots.json deleted file mode 100644 index 4c1347ba5e5..00000000000 --- a/test/fixtures/googletag-slots.json +++ /dev/null @@ -1,11 +0,0 @@ -[ - { - "getSlotElementId": "function(){ return \"div-gpt-ad-1438287399331-0\"; }" - }, - { - "getSlotElementId": "function(){ return \"div-gpt-ad-1438287399331-1\"; }" - }, - { - "getSlotElementId": "function(){ return \"div-gpt-ad-1438287399331-2\"; }" - } -] \ No newline at end of file diff --git a/test/fixtures/targeting-map.json b/test/fixtures/targeting-map.json deleted file mode 100644 index 1984c7cf4d5..00000000000 --- a/test/fixtures/targeting-map.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "/19968336/header-bid-tag-0": [ - { - "hb_bidder": [ - "appnexus" - ] - }, - { - "hb_adid": [ - "233bcbee889d46d" - ] - }, - { - "hb_pb": [ - "10.00" - ] - }, - { - "hb_size": [ - "300x250" - ] - }, - { - "foobar": [ - "300x250" - ] - } - ] -} \ No newline at end of file diff --git a/test/fixtures/video/adUnit.json b/test/fixtures/video/adUnit.json deleted file mode 100644 index 0773d7f3a62..00000000000 --- a/test/fixtures/video/adUnit.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "code": "video1", - "mediaTypes": { - "video": { - "context": "instream", - "playerSize": [640, 480] - } - }, - "bids": [ - { - "bidder": "appnexus", - "params": { - "placementId": "9333431", - "video": { - "skipppable": false, - "playback_methods": ["auto_play_sound_off"] - } - } - } - ] -} diff --git a/test/fixtures/video/bidRequest.json b/test/fixtures/video/bidRequest.json deleted file mode 100644 index 2a598c50183..00000000000 --- a/test/fixtures/video/bidRequest.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "auctionStart": 1462918897459, - "bidderCode": "appnexus", - "bidderRequestId": "2946b569352ef2", - "bids": [ - { - "bidder": "appnexus", - "params": { - "placementId": "9333431", - "video": { - "skipppable": false, - "playback_methods": ["auto_play_sound_off"] - } - }, - "placementCode": "video1", - "sizes": [640,480], - "bidId": "392b5a6b05d648", - "bidderRequestId": "2946b569352ef2", - "auctionId": "6172477f-987f-4523-a967-fa6d7a434ddf", - "startTime": 1462918897462 - } - ], - "auctionId": "6172477f-987f-4523-a967-fa6d7a434ddf", - "start": 1462918897460, - "timeout": 5000 -} diff --git a/test/fixtures/video/vastPayloadResponse.json b/test/fixtures/video/vastPayloadResponse.json deleted file mode 100644 index 2f72907817f..00000000000 --- a/test/fixtures/video/vastPayloadResponse.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "adUnitCode": "video1", - "bidder": "appnexus", - "bidderCode": "appnexus", - "code": "appnexus", - "dealId": "foo", - "cpm": 0.1, - "height": 480, - "mediaType": "video", - "auctionId": "6172477f-987f-4523-a967-fa6d7a434ddf", - "vastXml": "", - "width": 640 -} diff --git a/test/fixtures/video/vastUrlResponse.json b/test/fixtures/video/vastUrlResponse.json deleted file mode 100644 index a842ed10a71..00000000000 --- a/test/fixtures/video/vastUrlResponse.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "adUnitCode": "video1", - "bidder": "appnexus", - "bidderCode": "appnexus", - "code": "appnexus", - "dealId": "foo", - "cpm": 0.1, - "height": 480, - "mediaType": "video", - "auctionId": "6172477f-987f-4523-a967-fa6d7a434ddf", - "vastUrl": "www.myVastUrl.com", - "width": 640 -} diff --git a/test/helpers/index_adapter_utils.js b/test/helpers/index_adapter_utils.js deleted file mode 100644 index f01145b573d..00000000000 --- a/test/helpers/index_adapter_utils.js +++ /dev/null @@ -1,324 +0,0 @@ -var AllowedAdUnits = [[728, 90], [120, 600], [300, 250], [160, 600], [336, 280], [234, 60], [300, 600], [300, 50], [320, 50], [970, 250], [300, 1050], [970, 90], [180, 150]]; -var UnsupportedAdUnits = [[700, 100], [100, 600], [300, 200], [100, 600], [300, 200], [200, 60], [900, 200], [300, 1000], [900, 90], [100, 100]]; - -exports.supportedSizes = AllowedAdUnits; -exports.unsupportedSizes = UnsupportedAdUnits; - -var DefaultSiteID = 234567; -var DefaultPlacementCodePrefix = 'placementCode-'; -var DefaultCurrency = 'USD'; -var DefaultDspID = 124; -var DefaultTradingDeskID = 3456; -var DefaultCreativeID = 123234; -var DefaultBrandID = 123356; -var DefaultBrand = 'LA Tourism & Convention Board'; -var DefaultAdDoman = 2342342; -var DefaultPriceLevel = 1000; // only this is important? -var DefaultDeal = '515'; -var DefaultDealName = 'name: testdeal'; -var DefaultDealID = 'ixdl'; - -var ADAPTER_CODE = 'indexExchange'; - -exports.DefaultSiteID = DefaultSiteID; -exports.DefaultPlacementCodePrefix = DefaultPlacementCodePrefix; -exports.DefaultCurrency = DefaultCurrency; -exports.DefaultDspID = DefaultDspID; -exports.DefaultTradingDeskID = DefaultTradingDeskID; -exports.DefaultCreativeID = DefaultCreativeID; -exports.DefaultBrandID = DefaultBrandID; -exports.DefaultBrand = DefaultBrand; -exports.DefaultAdDoman = DefaultAdDoman; -exports.DefaultPriceLevel = DefaultPriceLevel; -exports.DefaultDeal = DefaultDeal; -exports.DefaultDealName = DefaultDealName; -exports.DefaultDealID = DefaultDealID; - -exports.ADAPTER_CODE = ADAPTER_CODE; - -function _createBidSlot(placementCode, indexSlotID, sizes, config) { - config = config || {}; - var bid = {}; - bid.bidder = ('bidder' in config) ? config.bidder : ADAPTER_CODE; - bid.placementCode = placementCode; - bid.params = {}; - bid.params.id = indexSlotID; - bid.params.siteID = ('siteID' in config) ? config.siteID : DefaultSiteID; - bid.sizes = sizes; - - // optional parameter - if (typeof config.timeout !== 'undefined') { - bid.params.timeout = config.timeout; - } - if (typeof config.tier2SiteID !== 'undefined') { - bid.params.tier2SiteID = config.tier2SiteID; - } - if (typeof config.tier3SiteID !== 'undefined') { - bid.params.tier3SiteID = config.tier3SiteID; - } - if (typeof config.slotSize !== 'undefined') { - bid.params.size = config.slotSize; - } - - // special parameter - if (typeof (config.missingSlotID) !== 'undefined') { - delete bid.params.id; - } - if (typeof (config.missingSiteID) !== 'undefined') { - delete bid.params.siteID; - } - - return bid; -} - -exports.createBidSlot = _createBidSlot; - -exports.createBidSlots = function(numSlot, numSize) { - if (typeof numSlot === 'undefined') numSlot = 1; - if (typeof numSize === 'undefined') numSize = 1; - - var bids = new Array(numSlot); - - var mkPlacementCode = function(i, j) { return DefaultPlacementCodePrefix + i + '_' + j; }; - for (var i = 0; i < bids.length; i++) { - var requestSizes = new Array(numSize); - for (var j = 0; j < requestSizes.length; j++) requestSizes[j] = AllowedAdUnits[(i + j) % AllowedAdUnits.length]; - - bids[i] = _createBidSlot(mkPlacementCode(i, j), 'slot-' + i, requestSizes, { - siteID: DefaultSiteID + i - }); - } - return bids; -} - -exports.parseIndexRequest = function(url) { - if (typeof url === 'undefined') return {}; - var uri = url.split('?')[1]; - var hashes = uri.split('&'); - var requestJSON = {}; - var hash; - for (var i = 0; i < hashes.length; i++) { - hash = hashes[i].split('='); - if (hash[0] === 'r') { - requestJSON[hash[0]] = JSON.parse(decodeURIComponent(hash[1])); - } else { - requestJSON[hash[0]] = decodeURIComponent(hash[1]); - } - } - return requestJSON; -} - -exports.getExpectedIndexSlots = function(bids) { - var size = 0; - for (var i = 0; i < bids.length; i++) { - size += bids[i].sizes.length; - } - return size; -} - -function clone(x) { - return JSON.parse(JSON.stringify(x)); -} - -// returns the difference(lhs, rhs), difference(rhs,lhs), and intersection(lhs, rhs) based on the object keys -function compareOnKeys(lhs, rhs) { - var lonly = []; - var ronly = []; - var both = []; - - for (var key in lhs) { - if (key in rhs) { - both.push({ left: lhs[key], right: rhs[key], name: key }); - } else { - lonly.push(lhs[key]); - } - } - - for (var key in rhs) { - if (key in lhs) { - } else { - ronly.push(rhs[key]); - } - } - - return { lhsOnly: lonly, rhsOnly: ronly, intersection: both }; -} - -function createObjectFromArray(arr) { - var obj = {}; - - for (var i = 0; i < arr.length; i++) { - var key = arr[i][0]; - if (key in obj) { - throw new Error('message: keys in object must by unique'); - } - obj[key] = arr[i][1]; - } - - return obj; -} - -exports.expandSizes = function(bid) { - var result = []; - for (var i = 0; i < bid.sizes.length; i++) { - var size = bid.sizes[i]; - var copy = clone(bid); - delete copy.sizes; - copy.size = size; - result.push(copy); - } - - return result; -} - -exports.matchOnPlacementCode = function(expected, prebid) { - var compared = compareOnKeys(expected, prebid); - - return { unmatched: { expected: compared.lhsOnly, prebid: compared.rhsOnly }, matched: compared.intersection.map(function(pair) { return { expected: pair.left, prebid: pair.right, placementCode: pair.name }; }) }; -}; - -exports.matchBidsOnSID = function(lhs, rhs) { - var lonly = []; - var ronly = []; - - var configured = []; - for (var i = 0; i < lhs.length; i++) { - var group = lhs[i]; - for (var j = 0; j < group.length; j++) { - var bid = group[j]; - configured.push([bid.params.id + '_' + (j + 1), bid]); - - if (typeof bid.params.tier2SiteID !== 'undefined') { - configured.push(['T1_' + bid.params.id + '_' + (j + 1), bid]); - } - if (typeof bid.params.tier3SiteID !== 'undefined') { - configured.push(['T2_' + bid.params.id + '_' + (j + 1), bid]); - } - } - } - - var lstore = createObjectFromArray(configured); - var rstore = createObjectFromArray(rhs.map(bid => [bid.ext.sid, bid])); - - var compared = compareOnKeys(lstore, rstore); - var matched = compared.intersection.map(function(pair) { return { configured: pair.left, sent: pair.right, name: pair.name } }); - - return { unmatched: { configured: compared.lhsOnly, sent: compared.rhsOnly }, matched: matched }; -} - -exports.matchBidsOnSize = function(lhs, rhs) { - var lonly = []; - var ronly = []; - - var configured = []; - for (var i = 0; i < lhs.length; i++) { - var group = lhs[i]; - for (var j = 0; j < group.length; j++) { - var bid = group[j]; - configured.push([bid.size[0] + 'x' + bid.size[1], bid]); - } - } - - var lstore = createObjectFromArray(configured); - 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 } }); - - return { unmatched: { configured: compared.lhsOnly, sent: compared.rhsOnly }, matched: matched }; -} - -exports.getBidResponse = function(configuredBids, urlJSON, optionalPriceLevel, optionalResponseIdentifier, optionalPassOnBid, optionalResponseParam) { - if (typeof configuredBids === 'undefined' || typeof urlJSON === 'undefined') return {}; - var response = {}; - - response.cur = DefaultCurrency; - response.id = urlJSON.r.id; - response.seatbid = []; - - optionalPassOnBid = optionalPassOnBid || []; - - var priceLevel = DefaultPriceLevel; - var adCount = 1; - - for (var i = 0; i < configuredBids.length; i++) { - var bidObj = {}; - bidObj.seat = (DefaultTradingDeskID + i).toString(); - bidObj.bid = []; - - var sizes = configuredBids[i].sizes; - var impressionID = 1; - for (var j = 0; j < sizes.length; j++) { - if (typeof optionalPassOnBid[i] !== 'undefined' && typeof optionalPassOnBid[i][j] !== 'undefined' && optionalPassOnBid[i][j]) continue; - - var bid = {}; - bid.adomain = [ (DefaultAdDoman + adCount).toString() ]; - bid.adid = (DefaultCreativeID + adCount).toString(); - bid.impid = adCount.toString(); - bid.id = adCount.toString(); - bid.adm = configuredBids[i].params.id + '_' + (j + 1); - if (typeof optionalResponseIdentifier !== 'undefined') bid.adm += '_' + optionalResponseIdentifier; - bid.ext = {}; - bid.ext.dspid = (DefaultDspID + adCount).toString(); - bid.ext.advbrandid = (DefaultBrandID + adCount).toString(); - bid.ext.advbrand = DefaultBrand; - - var optionalSlotParam; - if (typeof optionalResponseParam !== 'undefined' && typeof optionalResponseParam[i] !== 'undefined' && typeof optionalResponseParam[i][j] !== 'undefined') { - optionalSlotParam = optionalResponseParam[i][j]; - } - - if (typeof optionalSlotParam !== 'undefined' && typeof optionalSlotParam.ext !== 'undefined' && optionalSlotParam.ext.dealid !== 'undefined') { - bid.ext.dealid = optionalSlotParam.ext.dealid; - } - - priceLevel = priceLevel * 2; - if (typeof optionalPriceLevel !== 'undefined' && optionalPriceLevel[i].length !== 0) { - priceLevel = optionalPriceLevel[i][j]; - } - bid.ext.pricelevel = '_' + priceLevel; - adCount++; - bidObj.bid.push(bid); - } - - response.seatbid.push(bidObj); - } - return response; -} - -exports.getExpectedAdaptorResponse = function(configuredBids, asResponse) { - var asAllBids = asResponse.seatbid; - var expectedResponse = {}; - for (var m = 0; m < asAllBids.length; m++) { - var asBids = asAllBids[m].bid; - for (var i = 0; i < asBids.length; i++) { - var slotID = asBids[i].adm.split('_')[0]; - var sizeID = asBids[i].adm.split('_')[1] - 1; - - for (var j = 0; j < configuredBids.length; j++) { - if (configuredBids[j].params.id !== slotID) continue; - - var result = {}; - var placementCode = configuredBids[j].placementCode; - - result.siteID = configuredBids[j].params.siteID; - result.bidderCode = ADAPTER_CODE; - result.width = configuredBids[j].sizes[sizeID][0]; - result.height = configuredBids[j].sizes[sizeID][1]; - result.ad = asBids[i].adm; - result.cpm = asBids[i].ext.pricelevel.split('_')[1] / 100; - - if (typeof asBids[i].ext !== 'undefined' && typeof asBids[i].ext.dealid !== 'undefined') { - result.dealId = asBids[i].ext.dealid; - } - - if (typeof expectedResponse[placementCode] === 'undefined') { - expectedResponse[placementCode] = [ result ]; - } else { - expectedResponse[placementCode].push(result); - } - } - } - } - return expectedResponse; -} diff --git a/test/helpers/karma-init.js b/test/helpers/karma-init.js deleted file mode 100644 index 56e936aa741..00000000000 --- a/test/helpers/karma-init.js +++ /dev/null @@ -1,6 +0,0 @@ -(function (window) { - if (!window.parent.pbjsKarmaInitDone && window.location.pathname === '/context.html') { - window.parent.pbjsKarmaInitDone = true; - window.open('/debug.html', '_blank'); - } -})(window); diff --git a/test/helpers/pbjs-test-only.js b/test/helpers/pbjs-test-only.js deleted file mode 100644 index e7212d2741c..00000000000 --- a/test/helpers/pbjs-test-only.js +++ /dev/null @@ -1,10 +0,0 @@ -export const pbjsTestOnly = { - - getAdUnits() { - return $$PREBID_GLOBAL$$.adUnits; - }, - - clearAllAdUnits() { - $$PREBID_GLOBAL$$.adUnits = []; - } -}; diff --git a/test/helpers/prebidGlobal.js b/test/helpers/prebidGlobal.js deleted file mode 100644 index 597076ab0db..00000000000 --- a/test/helpers/prebidGlobal.js +++ /dev/null @@ -1,3 +0,0 @@ -window.$$PREBID_GLOBAL$$ = (window.$$PREBID_GLOBAL$$ || {}); -window.$$PREBID_GLOBAL$$.cmd = window.$$PREBID_GLOBAL$$.cmd || []; -window.$$PREBID_GLOBAL$$.que = window.$$PREBID_GLOBAL$$.que || []; diff --git a/test/helpers/testing-utils.js b/test/helpers/testing-utils.js deleted file mode 100644 index 76e2b652a79..00000000000 --- a/test/helpers/testing-utils.js +++ /dev/null @@ -1,13 +0,0 @@ -/* eslint-disable no-console */ -module.exports = { - host: (process.env.TEST_SERVER_HOST) ? process.env.TEST_SERVER_HOST : 'localhost', - protocol: (process.env.TEST_SERVER_PROTOCOL) ? 'https' : 'http', - waitForElement: function(elementRef, time = 2000) { - let element = $(elementRef); - element.waitForExist({timeout: time}); - }, - switchFrame: function(frameRef, frameName) { - let iframe = $(frameRef); - browser.switchToFrame(iframe); - } -} diff --git a/test/mocks/adloaderStub.js b/test/mocks/adloaderStub.js deleted file mode 100644 index 6e7f5756100..00000000000 --- a/test/mocks/adloaderStub.js +++ /dev/null @@ -1,23 +0,0 @@ - -import * as adloader from 'src/adloader.js'; - -// this export is for adloader's tests against actual implementation -export let loadExternalScript = adloader.loadExternalScript; - -export let loadExternalScriptStub = createStub(); - -function createStub() { - return sinon.stub(adloader, 'loadExternalScript').callsFake((...args) => { - if (typeof args[2] === 'function') { - args[2](); - } else if (typeof args[3] === 'function') { - args[3](); - } - return document.createElement('script'); - }); -} - -beforeEach(function() { - loadExternalScriptStub.restore(); - loadExternalScriptStub = createStub(); -}); diff --git a/test/mocks/fabrickId.json b/test/mocks/fabrickId.json deleted file mode 100644 index a8723ec88ec..00000000000 --- a/test/mocks/fabrickId.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "fabrickId": 1980 -} diff --git a/test/mocks/videoCacheStub.js b/test/mocks/videoCacheStub.js deleted file mode 100644 index 7ce899cae35..00000000000 --- a/test/mocks/videoCacheStub.js +++ /dev/null @@ -1,34 +0,0 @@ -import * as videoCache from 'src/videoCache.js'; - -/** - * Function which can be called from unit tests to stub out the video cache. - * - * @param {Object} responses - * @param {} responses.store If this is an Error, we'll stub out the store function so that it fails. - * If it's anything else, the store function will succeed, sending that value into the callback. - * - * @return {function} A function which returns the current stubs for the mocked functions. - */ -export default function useVideoCacheStub(responses) { - let storeStub; - - beforeEach(function () { - storeStub = sinon.stub(videoCache, 'store'); - - if (responses.store instanceof Error) { - storeStub.callsArgWith(1, responses.store); - } else { - storeStub.callsArgWith(1, null, responses.store); - } - }); - - afterEach(function () { - videoCache.store.restore(); - }); - - return function() { - return { - store: storeStub - }; - } -} diff --git a/test/mocks/xhr.js b/test/mocks/xhr.js deleted file mode 100644 index 9fb8fe87fa0..00000000000 --- a/test/mocks/xhr.js +++ /dev/null @@ -1,9 +0,0 @@ - -export let server = sinon.createFakeServer(); -export let xhr = global.XMLHttpRequest; - -beforeEach(function() { - server.restore(); - server = sinon.createFakeServer(); - xhr = global.XMLHttpRequest; -}); diff --git a/test/pages/banner.html b/test/pages/banner.html deleted file mode 100644 index 75993cefb39..00000000000 --- a/test/pages/banner.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - Prebid.js Banner Example - - - - - - - - - - - - - - - -

Prebid.js Banner Ad Unit Test

-
- -
-
- - - diff --git a/test/pages/bidderSettings.html b/test/pages/bidderSettings.html deleted file mode 100644 index 015ad3ca45f..00000000000 --- a/test/pages/bidderSettings.html +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - - - - - - -

Prebid.js Test

-
Div-1
-
- -
- - - \ No newline at end of file diff --git a/test/pages/consent_mgt_gdpr.html b/test/pages/consent_mgt_gdpr.html deleted file mode 100644 index 02b367b3c7c..00000000000 --- a/test/pages/consent_mgt_gdpr.html +++ /dev/null @@ -1,208 +0,0 @@ - - - - - - - - - - - - - - -

Prebid.js Test

-
Div-1
-
- -
- - - \ No newline at end of file diff --git a/test/pages/currency.html b/test/pages/currency.html deleted file mode 100644 index 7f196e60d5e..00000000000 --- a/test/pages/currency.html +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - - - - - - - -

Prebid.js Test

-
Div-1
-
- -
- - diff --git a/test/pages/instream.html b/test/pages/instream.html deleted file mode 100644 index c1e2358b754..00000000000 --- a/test/pages/instream.html +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - Prebid.js video adUnit example - - - - - - - - - - - - - - - - - - -

Prebid Video -- video.js

- -
-
- - -
- - - - diff --git a/test/pages/multiple_bidders.html b/test/pages/multiple_bidders.html deleted file mode 100644 index 0117f8f8371..00000000000 --- a/test/pages/multiple_bidders.html +++ /dev/null @@ -1,114 +0,0 @@ - - - - - - - - - - - - - - - - -

Multi-Format Ad Units

-

div-banner

-
- -
- - - \ No newline at end of file diff --git a/test/pages/native.html b/test/pages/native.html deleted file mode 100644 index dcee4e41d40..00000000000 --- a/test/pages/native.html +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - Prebid.js Native Example - - - - - - - - - - - - - - - -

Prebid.js Native Ad Unit Test

-
-

No response

- -
- - - diff --git a/test/pages/outstream.html b/test/pages/outstream.html deleted file mode 100644 index 262c15ed02a..00000000000 --- a/test/pages/outstream.html +++ /dev/null @@ -1,175 +0,0 @@ - - - - - - - Prebid.js Video Outstream Example - - - - - - - - - - - - -
-

- In scelerisque sem sed tortor posuere sagittis. Fusce scelerisque odio at tincidunt ultricies. Fusce egestas, erat - non finibus dictum, nulla arcu viverra nibh, at bibendum ligula nisi egestas magna. Nulla eu finibus nulla. - Pellentesque at mi eget turpis - consequat scelerisque. Sed lacinia, nisi sit amet egestas vestibulum, elit odio iaculis leo, et lacinia risus enim - non lacus. Cras nec neque eget nunc gravida maximus. Ut hendrerit convallis sollicitudin. Donec cursus erat vel - metus gravida, - et pretium justo iaculis. Curabitur condimentum blandit augue, quis interdum leo. Vivamus dapibus est nec dui - efficitur, eu imperdiet nulla sollicitudin. Suspendisse laoreet velit vitae arcu mollis, ac interdum lorem - venenatis. Aenean - nec purus varius, accumsan ex at, luctus arcu. Quisque consectetur tortor eros, placerat lacinia eros aliquam a. - Proin non porttitor libero. -

-

- Proin eget vulputate est. Nunc sit amet neque a tortor ullamcorper suscipit non eu neque. Quisque at massa in - metus feugiat rutrum. Nulla et orci orci. Aliquam erat volutpat. Cras tincidunt metus lectus, sed suscipit augue - mollis vitae. Sed quis condimentum - tortor, sit amet consectetur erat. Nulla pellentesque turpis lacus, eu venenatis massa fringilla at. Duis sed - pharetra turpis. Maecenas vel porttitor neque. Praesent quis felis sapien. Donec suscipit euismod dui, vitae - fermentum nisi ornare - in. -

-

- Suspendisse tempor felis accumsan orci finibus, imperdiet mollis arcu imperdiet. In eu dolor condimentum, pulvinar - nisl a, sollicitudin nunc. Ut vel lectus libero. Praesent rhoncus leo tortor, at mollis nulla sagittis eget. - Quisque tempus tempor augue - sed rutrum. Sed vitae volutpat quam. Proin vestibulum eros metus, a luctus erat condimentum eu. Vivamus - ullamcorper ultricies dui, ac malesuada leo finibus semper. Cras diam augue, imperdiet sed efficitur id, aliquam - sed purus. Praesent - eget turpis quis sapien interdum sagittis. Vivamus placerat nunc a tempus fermentum. Praesent laoreet leo at - tellus porta, ut viverra tortor pharetra. Quisque elit velit, eleifend eget imperdiet vel, suscipit ac nisi. - Aliquam egestas mauris - ut massa fringilla laoreet. -

-
-

Prebid Outstream Video Ad

- -
-

- Quisque ac luctus nisi, vitae ornare arcu. Proin fermentum sapien vitae odio vestibulum porta. Suspendisse - faucibus sapien enim, et faucibus urna tempus et. Integer porttitor justo sed faucibus blandit. Morbi semper - lectus vitae semper facilisis. Quisque - molestie accumsan arcu, eget bibendum dui euismod et. Sed in mattis lacus, nec lacinia sem. Fusce sed tortor - posuere, iaculis justo varius, elementum est. -

-

- Etiam condimentum, eros commodo semper tristique, lorem leo pharetra massa, eget cursus justo enim id urna. Sed - imperdiet mauris vitae ante bibendum elementum. Etiam eu dui porttitor leo imperdiet cursus. Maecenas consequat, - neque a dapibus viverra, nunc - velit volutpat nibh, ut cursus sem tortor ac arcu. Praesent convallis lacus vel nisi aliquam, in posuere libero - scelerisque. Curabitur et lacinia nisl. Nunc id ligula neque. Phasellus non eros et leo ultrices ultricies. Nulla - facilisi. - Donec ut augue urna. Suspendisse sodales nisi at ex faucibus, et tempus magna fermentum. Proin non arcu interdum, - pulvinar est at, vehicula odio. Morbi nec maximus sem. Ut eu tristique urna. -

-

- Pellentesque eget quam sem. Nam interdum eleifend leo, mattis sagittis metus ornare tristique. Cras pretium odio - lectus, vitae viverra massa consequat eget. Suspendisse porttitor pretium lectus in scelerisque. Phasellus euismod - porta lectus eget pharetra. - Ut et viverra mi, ut imperdiet lacus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere - cubilia Curae; Nunc tempus sapien sit amet tortor rhoncus dignissim. Sed at augue et sem lacinia feugiat. Nulla - vitae convallis - urna. Morbi scelerisque erat quis nibh pretium, non elementum elit consectetur. Proin in feugiat nisl. -

-

- Morbi et ipsum purus. Integer ut pulvinar metus. Fusce maximus ex nec purus sollicitudin gravida. Vivamus dapibus - volutpat erat nec tristique. Aliquam mi dolor, pretium non elementum quis, viverra non est. Pellentesque egestas, - lectus a posuere imperdiet, - nisi sem elementum neque, eu volutpat arcu turpis venenatis magna. Curabitur non neque consectetur, vulputate urna - sed, vestibulum lacus. Aenean mollis, risus non pulvinar egestas, lectus lectus finibus dui, sit amet pretium - metus mauris - vitae nibh. In non ultricies odio. -

-
- - - diff --git a/test/pages/priceGranularity.html b/test/pages/priceGranularity.html deleted file mode 100644 index 7eae83f673a..00000000000 --- a/test/pages/priceGranularity.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - - - - - - - - -

Prebid.js Test

-
Div-1
-
- -
- - - \ No newline at end of file diff --git a/test/pages/sizeConfig.html b/test/pages/sizeConfig.html deleted file mode 100644 index a4aef89e44a..00000000000 --- a/test/pages/sizeConfig.html +++ /dev/null @@ -1,144 +0,0 @@ - - - - - - - - - - - - - -

Prebid.js Test

-
Div-1
-
- -
- - - \ No newline at end of file diff --git a/test/pages/userSync.html b/test/pages/userSync.html deleted file mode 100644 index 3d848906ae3..00000000000 --- a/test/pages/userSync.html +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - - - - - -

Prebid.js Test

-
Div-1
-
- -
- - - \ No newline at end of file diff --git a/test/spec/AnalyticsAdapter_spec.js b/test/spec/AnalyticsAdapter_spec.js deleted file mode 100644 index 2b36848bd8f..00000000000 --- a/test/spec/AnalyticsAdapter_spec.js +++ /dev/null @@ -1,203 +0,0 @@ -import { expect } from 'chai'; -import events from 'src/events.js'; -import CONSTANTS from 'src/constants.json'; -import { server } from 'test/mocks/xhr.js'; - -const REQUEST_BIDS = CONSTANTS.EVENTS.REQUEST_BIDS; -const BID_REQUESTED = CONSTANTS.EVENTS.BID_REQUESTED; -const BID_RESPONSE = CONSTANTS.EVENTS.BID_RESPONSE; -const BID_WON = CONSTANTS.EVENTS.BID_WON; -const BID_TIMEOUT = CONSTANTS.EVENTS.BID_TIMEOUT; -const AD_RENDER_FAILED = CONSTANTS.EVENTS.AD_RENDER_FAILED; -const AUCTION_DEBUG = CONSTANTS.EVENTS.AUCTION_DEBUG; -const ADD_AD_UNITS = CONSTANTS.EVENTS.ADD_AD_UNITS; - -const AnalyticsAdapter = require('src/AnalyticsAdapter').default; -const config = { - url: 'https://localhost:9999/endpoint', - analyticsType: 'endpoint' -}; - -describe(` -FEATURE: Analytics Adapters API - SCENARIO: A publisher enables analytics - AND an \`example\` instance of \`AnalyticsAdapter\`\n`, () => { - let adapter; - - beforeEach(function () { - adapter = new AnalyticsAdapter(config); - }); - - afterEach(function () { - adapter.disableAnalytics(); - }); - - it(`SHOULD call the endpoint WHEN an event occurs that is to be tracked`, function () { - const eventType = BID_REQUESTED; - const args = { some: 'data' }; - - adapter.track({ eventType, args }); - - let result = JSON.parse(server.requests[0].requestBody); - expect(result).to.deep.equal({args: {some: 'data'}, eventType: 'bidRequested'}); - }); - - it(`SHOULD queue the event first and then track it WHEN an event occurs before tracking library is available`, function () { - const eventType = BID_RESPONSE; - const args = { wat: 'wot' }; - - events.emit(eventType, args); - adapter.enableAnalytics(); - - // As now AUCTION_DEBUG is triggered for WARNINGS too, the BID_RESPONSE goes last in the array - const index = server.requests.length - 1; - let result = JSON.parse(server.requests[index].requestBody); - expect(result).to.deep.equal({eventType: 'bidResponse', args: {wat: 'wot'}}); - }); - - describe(`WHEN an event occurs after enable analytics\n`, function () { - beforeEach(function () { - sinon.stub(events, 'getEvents').returns([]); // these tests shouldn't be affected by previous tests - }); - - afterEach(function () { - events.getEvents.restore(); - }); - - it('SHOULD call global when a bidWon event occurs', function () { - const eventType = BID_WON; - const args = { more: 'info' }; - - adapter.enableAnalytics(); - events.emit(eventType, args); - - let result = JSON.parse(server.requests[0].requestBody); - expect(result).to.deep.equal({args: {more: 'info'}, eventType: 'bidWon'}); - }); - - it('SHOULD call global when a adRenderFailed event occurs', function () { - const eventType = AD_RENDER_FAILED; - const args = { call: 'adRenderFailed' }; - - adapter.enableAnalytics(); - events.emit(eventType, args); - - let result = JSON.parse(server.requests[0].requestBody); - expect(result).to.deep.equal({args: {call: 'adRenderFailed'}, eventType: 'adRenderFailed'}); - }); - - it('SHOULD call global when an auction debug event occurs', function () { - const eventType = AUCTION_DEBUG; - const args = { call: 'auctionDebug' }; - - adapter.enableAnalytics(); - events.emit(eventType, args); - - let result = JSON.parse(server.requests[0].requestBody); - expect(result).to.deep.equal({args: {call: 'auctionDebug'}, eventType: 'auctionDebug'}); - }); - - it('SHOULD call global when an addAdUnits event occurs', function () { - const eventType = ADD_AD_UNITS; - const args = { call: 'addAdUnits' }; - - adapter.enableAnalytics(); - events.emit(eventType, args); - - let result = JSON.parse(server.requests[0].requestBody); - expect(result).to.deep.equal({args: {call: 'addAdUnits'}, eventType: 'addAdUnits'}); - }); - - it('SHOULD call global when a requestBids event occurs', function () { - const eventType = REQUEST_BIDS; - const args = { call: 'request' }; - - adapter.enableAnalytics(); - events.emit(eventType, args); - - let result = JSON.parse(server.requests[0].requestBody); - expect(result).to.deep.equal({args: {call: 'request'}, eventType: 'requestBids'}); - }); - - it('SHOULD call global when a bidRequest event occurs', function () { - const eventType = BID_REQUESTED; - const args = { call: 'request' }; - - adapter.enableAnalytics(); - events.emit(eventType, args); - - let result = JSON.parse(server.requests[0].requestBody); - expect(result).to.deep.equal({args: {call: 'request'}, eventType: 'bidRequested'}); - }); - - it('SHOULD call global when a bidResponse event occurs', function () { - const eventType = BID_RESPONSE; - const args = { call: 'response' }; - - adapter.enableAnalytics(); - events.emit(eventType, args); - - let result = JSON.parse(server.requests[0].requestBody); - expect(result).to.deep.equal({args: {call: 'response'}, eventType: 'bidResponse'}); - }); - - it('SHOULD call global when a bidTimeout event occurs', function () { - const eventType = BID_TIMEOUT; - const args = { call: 'timeout' }; - - adapter.enableAnalytics(); - events.emit(eventType, args); - - let result = JSON.parse(server.requests[0].requestBody); - expect(result).to.deep.equal({args: {call: 'timeout'}, eventType: 'bidTimeout'}); - }); - - it('SHOULD NOT call global again when adapter.enableAnalytics is called with previous timeout', function () { - const eventType = BID_TIMEOUT; - const args = { call: 'timeout' }; - - events.emit(eventType, args); - adapter.enableAnalytics(); - events.emit(eventType, args); - - expect(server.requests.length).to.equal(1); - }); - - describe(`AND sampling is enabled\n`, function () { - const eventType = BID_WON; - const args = { more: 'info' }; - - beforeEach(function () { - sinon.stub(Math, 'random').returns(0.5); - }); - - afterEach(function () { - Math.random.restore(); - }); - - it(`THEN should enable analytics when random number is in sample range`, function () { - adapter.enableAnalytics({ - options: { - sampling: 0.75 - } - }); - events.emit(eventType, args); - - expect(server.requests.length).to.equal(1); - let result = JSON.parse(server.requests[0].requestBody); - expect(result).to.deep.equal({args: {more: 'info'}, eventType: 'bidWon'}); - }); - - it(`THEN should disable analytics when random number is outside sample range`, function () { - adapter.enableAnalytics({ - options: { - sampling: 0.25 - } - }); - events.emit(eventType, args); - - expect(server.requests.length).to.equal(0); - }); - }); - }); -}); diff --git a/test/spec/adUnits_spec.js b/test/spec/adUnits_spec.js deleted file mode 100644 index baa5b4ac8c4..00000000000 --- a/test/spec/adUnits_spec.js +++ /dev/null @@ -1,132 +0,0 @@ -describe('Publisher API _ AdUnits', function () { - var assert = require('chai').assert; - var expect = require('chai').expect; - var pbjsTestOnly = require('../helpers/pbjs-test-only').pbjsTestOnly; - - before(function () { - var adUnits = [{ - code: '/1996833/slot-1', - sizes: [[300, 250], [728, 90]], - bids: [ - { - bidder: 'openx', - params: { - pgid: '2342353', - unit: '234234', - jstag_url: 'http://' - } - }, { - bidder: 'appnexus', - params: { - placementId: '234235' - } - } - ] - }, { - fpd: { - context: { - pbAdSlot: 'adSlotTest', - data: { - inventory: [4], - keywords: 'foo,bar', - visitor: [1, 2, 3], - } - } - }, - code: '/1996833/slot-2', - sizes: [[468, 60]], - bids: [ - { - bidder: 'rubicon', - params: { - rp_account: '4934', - rp_site: '13945', - rp_zonesize: '23948-15' - } - }, { - bidder: 'appnexus', - params: { - placementId: '827326' - } - } - ] - }]; - pbjsTestOnly.clearAllAdUnits(); - $$PREBID_GLOBAL$$.addAdUnits(adUnits); - }); - - after(function () { - pbjsTestOnly.clearAllAdUnits(); - }); - - describe('addAdUnits', function () { - var adUnits, adUnit1, bids1, adUnit2, bids2; - - it('should have two adUnits', function () { - adUnits = pbjsTestOnly.getAdUnits(); - adUnit1 = adUnits[0]; - bids1 = adUnit1.bids; - adUnit2 = adUnits[1]; - bids2 = adUnit2.bids; - }); - - it('the first adUnits value should be same with the adUnits that is added by $$PREBID_GLOBAL$$.addAdUnits();', function () { - assert.strictEqual(adUnit1.code, '/1996833/slot-1', 'adUnit1 code'); - assert.deepEqual(adUnit1.sizes, [[300, 250], [728, 90]], 'adUnit1 sizes'); - assert.strictEqual(bids1[0].bidder, 'openx', 'adUnit1 bids1 bidder'); - assert.strictEqual(bids1[0].params.pgid, '2342353', 'adUnit1 bids1 params.pgid'); - assert.strictEqual(bids1[0].params.unit, '234234', 'adUnit1 bids1 params.unit'); - assert.strictEqual(bids1[0].params.jstag_url, 'http://', 'adUnit1 bids1 params.jstag_url'); - - assert.strictEqual(bids1[1].bidder, 'appnexus', 'adUnit1 bids2 bidder'); - assert.strictEqual(bids1[1].params.placementId, '234235', 'adUnit1 bids2 params.placementId'); - - assert.strictEqual(adUnit2.code, '/1996833/slot-2', 'adUnit2 code'); - assert.deepEqual(adUnit2.sizes, [[468, 60]], 'adUnit2 sizes'); - 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'); - assert.strictEqual(bids2[0].params.rp_site, '13945', 'adUnit2 bids1 params.rp_site'); - - assert.strictEqual(bids2[1].bidder, 'appnexus', 'adUnit2 bids2 bidder'); - assert.strictEqual(bids2[1].params.placementId, '827326', 'adUnit2 bids2 params.placementId'); - }); - - it('the second adUnits value should be same with the adUnits that is added by $$PREBID_GLOBAL$$.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.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'); - assert.strictEqual(bids2[0].params.rp_site, '13945', 'adUnit2 bids1 params.rp_site'); - - assert.strictEqual(bids2[1].bidder, 'appnexus', 'adUnit2 bids2 bidder'); - assert.strictEqual(bids2[1].params.placementId, '827326', 'adUnit2 bids2 params.placementId'); - }); - }); - - describe('removeAdUnit', function () { - var adUnits, adUnit2, bids2; - - it('the first adUnit should be not existed', function () { - $$PREBID_GLOBAL$$.removeAdUnit('/1996833/slot-1'); - adUnits = pbjsTestOnly.getAdUnits(); - adUnit2 = adUnits[0]; - bids2 = adUnit2.bids; - expect(adUnits[1]).not.exist; - }); - - it('the second adUnit should be still existed', function () { - assert.strictEqual(adUnit2.code, '/1996833/slot-2', 'adUnit2 code'); - assert.deepEqual(adUnit2.sizes, [[468, 60]], 'adUnit2 sizes'); - 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'); - assert.strictEqual(bids2[0].params.rp_site, '13945', 'adUnit2 bids1 params.rp_site'); - - assert.strictEqual(bids2[1].bidder, 'appnexus', 'adUnit2 bids2 bidder'); - assert.strictEqual(bids2[1].params.placementId, '827326', 'adUnit2 bids2 params.placementId'); - }); - }); -}); diff --git a/test/spec/adloader_spec.js b/test/spec/adloader_spec.js deleted file mode 100644 index 0c46cd2f171..00000000000 --- a/test/spec/adloader_spec.js +++ /dev/null @@ -1,42 +0,0 @@ -import * as utils from 'src/utils.js'; -import * as adLoader from 'test/mocks/adloaderStub.js'; - -describe('adLoader', function () { - let utilsinsertElementStub; - let utilsLogErrorStub; - - beforeEach(function () { - utilsinsertElementStub = sinon.stub(utils, 'insertElement'); - utilsLogErrorStub = sinon.stub(utils, 'logError'); - }); - - afterEach(function () { - utilsinsertElementStub.restore(); - utilsLogErrorStub.restore(); - }); - - describe('loadExternalScript', function () { - it('requires moduleCode to be included on the request', function () { - adLoader.loadExternalScript('someURL'); - expect(utilsLogErrorStub.called).to.be.true; - expect(utilsinsertElementStub.called).to.be.false; - }); - - it('only allows whitelisted vendors to load scripts', function () { - adLoader.loadExternalScript('someURL', 'criteo'); - expect(utilsLogErrorStub.called).to.be.false; - expect(utilsinsertElementStub.called).to.be.true; - }); - - it('should not load cached script again', function() { - adLoader.loadExternalScript('someURL', 'criteo'); - expect(utilsinsertElementStub.called).to.be.false; - }); - - it('callback function can be passed to the function', function() { - let callback = function() {}; - adLoader.loadExternalScript('someURL1', 'criteo', callback); - expect(utilsinsertElementStub.called).to.be.true; - }); - }); -}); diff --git a/test/spec/aliasBidder_spec.js b/test/spec/aliasBidder_spec.js deleted file mode 100644 index 771d7fcdd46..00000000000 --- a/test/spec/aliasBidder_spec.js +++ /dev/null @@ -1,37 +0,0 @@ -import { pbjsTestOnly } from 'test/helpers/pbjs-test-only.js'; - -describe('Publisher API _ Alias Bidder', function () { - var assert = require('chai').assert; - var expect = require('chai').expect; - var should = require('chai').should(); - var prebid = require('../../src/prebid'); - - before(function () { - var topSlotCode = '/19968336/header-bid-tag1'; - var topSlotSizes = [[728, 90], [970, 90]]; - var adUnit = { - code: topSlotCode, - sizes: topSlotSizes, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: '5215561' - } - } - ] - }; - - $$PREBID_GLOBAL$$.addAdUnits(adUnit); - }); - - after(function () { - pbjsTestOnly.clearAllAdUnits(); - }); - - describe('set Alias Bidder', function () { - it('should have both of target bidder and alias bidder', function () { - $$PREBID_GLOBAL$$.aliasBidder('appnexus', 'bRealTime1'); - }); - }); -}); diff --git a/test/spec/api_spec.js b/test/spec/api_spec.js deleted file mode 100755 index cb6c7aa87a3..00000000000 --- a/test/spec/api_spec.js +++ /dev/null @@ -1,90 +0,0 @@ -var assert = require('chai').assert; -var prebid = require('../../src/prebid'); - -describe('Publisher API', function () { - // var assert = chai.assert; - - describe('api of command queue', function () { - it('should have a global variable $$PREBID_GLOBAL$$', function () { - assert.isObject($$PREBID_GLOBAL$$); - }); - - it('should have a global variable $$PREBID_GLOBAL$$.cmd as an array', function () { - assert.isArray($$PREBID_GLOBAL$$.cmd); - }); - - it('should have $$PREBID_GLOBAL$$.cmd.push function', function () { - assert.isFunction($$PREBID_GLOBAL$$.cmd.push); - }); - - it('should have a global variable $$PREBID_GLOBAL$$.que as an array', function () { - assert.isArray($$PREBID_GLOBAL$$.que); - }); - - it('should have $$PREBID_GLOBAL$$.que.push function', function () { - assert.isFunction($$PREBID_GLOBAL$$.que.push); - }); - - it('should have global pointer for PBJS global', function () { - assert.isArray(window._pbjsGlobals); - }); - }); - - describe('has function', function () { - it('should have function $$PREBID_GLOBAL$$.getAdserverTargeting', function () { - assert.isFunction($$PREBID_GLOBAL$$.getAdserverTargeting); - }); - - it('should have function $$PREBID_GLOBAL$$.getAdserverTargetingForAdUnitCode', function () { - assert.isFunction($$PREBID_GLOBAL$$.getAdserverTargetingForAdUnitCode); - }); - - it('should have function $$PREBID_GLOBAL$$.getBidResponses', function () { - assert.isFunction($$PREBID_GLOBAL$$.getBidResponses); - }); - - it('should have function $$PREBID_GLOBAL$$.getNoBids', function () { - assert.isFunction($$PREBID_GLOBAL$$.getNoBids); - }); - - it('should have function $$PREBID_GLOBAL$$.getNoBidsForAdUnitCode', function () { - assert.isFunction($$PREBID_GLOBAL$$.getNoBidsForAdUnitCode); - }); - - it('should have function $$PREBID_GLOBAL$$.getBidResponsesForAdUnitCode', function () { - assert.isFunction($$PREBID_GLOBAL$$.getBidResponsesForAdUnitCode); - }); - - it('should have function $$PREBID_GLOBAL$$.setTargetingForGPTAsync', function () { - assert.isFunction($$PREBID_GLOBAL$$.setTargetingForGPTAsync); - }); - - it('should have function $$PREBID_GLOBAL$$.renderAd', function () { - assert.isFunction($$PREBID_GLOBAL$$.renderAd); - }); - - it('should have function $$PREBID_GLOBAL$$.removeAdUnit', function () { - assert.isFunction($$PREBID_GLOBAL$$.removeAdUnit); - }); - - it('should have function $$PREBID_GLOBAL$$.requestBids', function () { - assert.isFunction($$PREBID_GLOBAL$$.requestBids); - }); - - it('should have function $$PREBID_GLOBAL$$.addAdUnits', function () { - assert.isFunction($$PREBID_GLOBAL$$.addAdUnits); - }); - - it('should have function $$PREBID_GLOBAL$$.aliasBidder', function () { - assert.isFunction($$PREBID_GLOBAL$$.aliasBidder); - }); - - it('should have function $$PREBID_GLOBAL$$.getAllWinningBids', function () { - assert.isFunction($$PREBID_GLOBAL$$.getAllWinningBids); - }); - - it('should have function $$PREBID_GLOBAL$$.getHighestUnusedBidResponseForAdUnitCode', function () { - assert.isFunction($$PREBID_GLOBAL$$.getHighestUnusedBidResponseForAdUnitCode); - }); - }); -}); diff --git a/test/spec/auctionmanager_spec.js b/test/spec/auctionmanager_spec.js deleted file mode 100644 index 69e34c4a07a..00000000000 --- a/test/spec/auctionmanager_spec.js +++ /dev/null @@ -1,1448 +0,0 @@ -import { - getKeyValueTargetingPairs, - auctionCallbacks, - AUCTION_COMPLETED, - adjustBids, - getMediaTypeGranularity, -} from 'src/auction.js'; -import CONSTANTS from 'src/constants.json'; -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 * as store from 'src/videoCache.js'; -import * as ajaxLib from 'src/ajax.js'; -import find from 'core-js-pure/features/array/find.js'; -import { server } from 'test/mocks/xhr.js'; - -var assert = require('assert'); - -/* use this method to test individual files instead of the whole prebid.js project */ - -// TODO refactor to use the spec files -var utils = require('../../src/utils'); -var fixtures = require('../fixtures/fixtures'); -var adapterManager = require('src/adapterManager').default; -var events = require('src/events'); - -const BIDDER_CODE = 'sampleBidder'; -const BIDDER_CODE1 = 'sampleBidder1'; - -const ADUNIT_CODE = 'adUnit-code'; -const ADUNIT_CODE1 = 'adUnit-code-1'; - -/** - * @param {Object} [opts] - * @returns {Bid} - */ -function mockBid(opts) { - let bidderCode = opts && opts.bidderCode; - - return { - 'ad': 'creative', - 'cpm': '1.99', - 'width': 300, - 'height': 250, - 'bidderCode': bidderCode || BIDDER_CODE, - 'requestId': utils.getUniqueIdentifierStr(), - 'creativeId': 'id', - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 360, - getSize: () => '300x250' - }; -} - -/** - * @param {Bid} bid - * @param {Object} [opts] - * @returns {BidRequest} - */ -function mockBidRequest(bid, opts) { - if (!bid) { - throw new Error('bid required'); - } - let bidderCode = opts && opts.bidderCode; - let adUnitCode = opts && opts.adUnitCode; - let defaultMediaType = { - banner: { - sizes: [[300, 250], [300, 600]] - } - } - let mediaType = (opts && opts.mediaType) ? opts.mediaType : defaultMediaType; - - let requestId = utils.getUniqueIdentifierStr(); - - return { - 'bidderCode': bidderCode || bid.bidderCode, - 'auctionId': '20882439e3238c', - 'bidderRequestId': requestId, - 'bids': [ - { - 'bidder': bidderCode || bid.bidderCode, - 'params': { - 'placementId': 'id' - }, - 'adUnitCode': adUnitCode || ADUNIT_CODE, - 'sizes': [[300, 250], [300, 600]], - 'bidId': bid.requestId, - 'bidderRequestId': requestId, - 'auctionId': '20882439e3238c', - 'mediaTypes': mediaType - } - ], - 'auctionStart': 1505250713622, - 'timeout': 3000 - }; -} - -function mockBidder(bidderCode, bids) { - let spec = { - code: bidderCode, - isBidRequestValid: sinon.stub(), - buildRequests: sinon.stub(), - interpretResponse: sinon.stub(), - getUserSyncs: sinon.stub() - }; - - spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); - spec.isBidRequestValid.returns(true); - spec.interpretResponse.returns(bids); - - return spec; -} - -const TEST_BIDS = [mockBid()]; -const TEST_BID_REQS = TEST_BIDS.map(mockBidRequest); - -function mockAjaxBuilder() { - return function(url, callback) { - const fakeResponse = sinon.stub(); - fakeResponse.returns('headerContent'); - callback.success('response body', { getResponseHeader: fakeResponse }); - }; -} - -describe('auctionmanager.js', function () { - describe('getKeyValueTargetingPairs', function () { - const DEFAULT_BID = { - cpm: 5.578, - pbLg: 5.50, - pbMg: 5.50, - pbHg: 5.57, - pbAg: 5.50, - - height: 300, - width: 250, - getSize() { - return this.height + 'x' + this.width; - }, - - adUnitCode: '12345', - bidderCode: 'appnexus', - adId: '1adId', - source: 'client', - mediaType: 'banner', - meta: { - advertiserDomains: ['adomain'] - } - }; - - /* return the expected response for a given bid, filter by keys if given */ - function getDefaultExpected(bid, keys) { - var expected = {}; - expected[ CONSTANTS.TARGETING_KEYS.BIDDER ] = bid.bidderCode; - expected[ CONSTANTS.TARGETING_KEYS.AD_ID ] = bid.adId; - expected[ CONSTANTS.TARGETING_KEYS.PRICE_BUCKET ] = bid.pbMg; - expected[ CONSTANTS.TARGETING_KEYS.SIZE ] = bid.getSize(); - expected[ CONSTANTS.TARGETING_KEYS.SOURCE ] = bid.source; - expected[ CONSTANTS.TARGETING_KEYS.FORMAT ] = bid.mediaType; - expected[ CONSTANTS.TARGETING_KEYS.ADOMAIN ] = bid.meta.advertiserDomains[0]; - if (bid.mediaType === 'video') { - expected[ CONSTANTS.TARGETING_KEYS.UUID ] = bid.videoCacheKey; - expected[ CONSTANTS.TARGETING_KEYS.CACHE_ID ] = bid.videoCacheKey; - expected[ CONSTANTS.TARGETING_KEYS.CACHE_HOST ] = 'prebid.adnxs.com'; - } - if (!keys) { - return expected; - } - - return keys.reduce((map, key) => { - map[key] = expected[key]; - return map; - }, {}); - } - - var bid = {}; - - before(function () { - bid = Object.assign({}, DEFAULT_BID); - }); - - it('No bidder level configuration defined - default', function () { - $$PREBID_GLOBAL$$.bidderSettings = {}; - let expected = getDefaultExpected(bid); - // remove hb_cache_host from expected - delete expected.hb_cache_host; - let response = getKeyValueTargetingPairs(bid.bidderCode, bid); - assert.deepEqual(response, expected); - }); - - it('No bidder level configuration defined - default for video', function () { - config.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }); - $$PREBID_GLOBAL$$.bidderSettings = {}; - let videoBid = utils.deepClone(bid); - videoBid.mediaType = 'video'; - videoBid.videoCacheKey = 'abc123def'; - - let expected = getDefaultExpected(videoBid); - let response = getKeyValueTargetingPairs(videoBid.bidderCode, videoBid); - assert.deepEqual(response, expected); - }); - - it('Custom configuration for all bidders', function () { - $$PREBID_GLOBAL$$.bidderSettings = - { - standard: { - adserverTargeting: [ - { - key: CONSTANTS.TARGETING_KEYS.BIDDER, - val: function (bidResponse) { - return bidResponse.bidderCode; - } - }, { - key: CONSTANTS.TARGETING_KEYS.AD_ID, - val: function (bidResponse) { - return bidResponse.adId; - } - }, { - key: CONSTANTS.TARGETING_KEYS.PRICE_BUCKET, - val: function (bidResponse) { - // change default here - return bidResponse.pbHg; - } - }, { - key: CONSTANTS.TARGETING_KEYS.SIZE, - val: function (bidResponse) { - return bidResponse.size; - } - }, - { - key: CONSTANTS.TARGETING_KEYS.SOURCE, - val: function (bidResponse) { - return bidResponse.source; - } - }, - { - key: CONSTANTS.TARGETING_KEYS.FORMAT, - val: function (bidResponse) { - return bidResponse.mediaType; - } - }, - { - key: CONSTANTS.TARGETING_KEYS.ADOMAIN, - val: function (bidResponse) { - return bidResponse.meta.advertiserDomains[0]; - } - } - ] - - } - }; - - var expected = getDefaultExpected(bid); - expected[CONSTANTS.TARGETING_KEYS.PRICE_BUCKET] = bid.pbHg; - - var response = getKeyValueTargetingPairs(bid.bidderCode, bid); - assert.deepEqual(response, expected); - }); - - it('Custom configuration for all bidders with video bid', function () { - config.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }); - let videoBid = utils.deepClone(bid); - videoBid.mediaType = 'video'; - videoBid.videoCacheKey = 'abc123def'; - - $$PREBID_GLOBAL$$.bidderSettings = - { - standard: { - adserverTargeting: [ - { - key: CONSTANTS.TARGETING_KEYS.BIDDER, - val: function (bidResponse) { - return bidResponse.bidderCode; - } - }, { - key: CONSTANTS.TARGETING_KEYS.AD_ID, - val: function (bidResponse) { - return bidResponse.adId; - } - }, { - key: CONSTANTS.TARGETING_KEYS.PRICE_BUCKET, - val: function (bidResponse) { - return bidResponse.pbMg; - } - }, { - key: CONSTANTS.TARGETING_KEYS.SIZE, - val: function (bidResponse) { - return bidResponse.size; - } - }, - { - key: CONSTANTS.TARGETING_KEYS.SOURCE, - val: function (bidResponse) { - return bidResponse.source; - } - }, - { - key: CONSTANTS.TARGETING_KEYS.FORMAT, - val: function (bidResponse) { - return bidResponse.mediaType; - } - }, - { - key: CONSTANTS.TARGETING_KEYS.UUID, - val: function (bidResponse) { - return bidResponse.videoCacheKey; - } - }, - { - key: CONSTANTS.TARGETING_KEYS.CACHE_ID, - val: function (bidResponse) { - return bidResponse.videoCacheKey; - } - }, - { - key: CONSTANTS.TARGETING_KEYS.ADOMAIN, - val: function (bidResponse) { - return bidResponse.meta.advertiserDomains[0]; - } - } - ] - - } - }; - - let expected = getDefaultExpected(videoBid); - - let response = getKeyValueTargetingPairs(videoBid.bidderCode, videoBid); - assert.deepEqual(response, expected); - }); - - it('Custom configuration for one bidder', function () { - $$PREBID_GLOBAL$$.bidderSettings = - { - appnexus: { - adserverTargeting: [ - { - key: CONSTANTS.TARGETING_KEYS.BIDDER, - val: function (bidResponse) { - return bidResponse.bidderCode; - } - }, { - key: CONSTANTS.TARGETING_KEYS.AD_ID, - val: function (bidResponse) { - return bidResponse.adId; - } - }, { - key: CONSTANTS.TARGETING_KEYS.PRICE_BUCKET, - val: function (bidResponse) { - // change default here - return bidResponse.pbHg; - } - }, { - key: CONSTANTS.TARGETING_KEYS.SIZE, - val: function (bidResponse) { - return bidResponse.size; - } - } - ] - - } - }; - - var expected = getDefaultExpected(bid); - expected[CONSTANTS.TARGETING_KEYS.PRICE_BUCKET] = bid.pbHg; - - var response = getKeyValueTargetingPairs(bid.bidderCode, bid); - assert.deepEqual(response, expected); - }); - - it('Custom configuration for one bidder - not matched', function () { - $$PREBID_GLOBAL$$.bidderSettings = - { - nonExistentBidder: { - adserverTargeting: [ - { - key: CONSTANTS.TARGETING_KEYS.BIDDER, - val: function (bidResponse) { - return bidResponse.bidderCode; - } - }, { - key: CONSTANTS.TARGETING_KEYS.AD_ID, - val: function (bidResponse) { - return bidResponse.adId; - } - }, { - key: CONSTANTS.TARGETING_KEYS.PRICE_BUCKET, - val: function (bidResponse) { - // change default here - return bidResponse.pbHg; - } - }, { - key: CONSTANTS.TARGETING_KEYS.SIZE, - val: function (bidResponse) { - return bidResponse.size; - } - } - ] - - } - }; - var expected = getDefaultExpected(bid); - - var response = getKeyValueTargetingPairs(bid.bidderCode, bid); - assert.deepEqual(response, expected); - }); - - it('Custom bidCpmAdjustment for one bidder and inherit standard but doesn\'t use standard bidCpmAdjustment', function () { - $$PREBID_GLOBAL$$.bidderSettings = - { - appnexus: { - bidCpmAdjustment: function (bidCpm) { - return bidCpm * 0.7; - }, - }, - standard: { - bidCpmAdjustment: function (bidCpm) { - return 200; - }, - adserverTargeting: [ - { - key: CONSTANTS.TARGETING_KEYS.BIDDER, - val: function (bidResponse) { - return bidResponse.bidderCode; - } - }, { - key: CONSTANTS.TARGETING_KEYS.AD_ID, - val: function (bidResponse) { - return bidResponse.adId; - } - }, { - key: CONSTANTS.TARGETING_KEYS.PRICE_BUCKET, - val: function (bidResponse) { - // change default here - return 10.00; - } - } - ] - - } - }; - var expected = getDefaultExpected(bid, [CONSTANTS.TARGETING_KEYS.BIDDER, CONSTANTS.TARGETING_KEYS.AD_ID]); - expected[CONSTANTS.TARGETING_KEYS.PRICE_BUCKET] = 10.0; - - var response = getKeyValueTargetingPairs(bid.bidderCode, bid); - assert.deepEqual(response, expected); - }); - - it('Standard bidCpmAdjustment changes the bid of any bidder', function () { - const bid = Object.assign({}, - createBid(2), - fixtures.getBidResponses()[5] - ); - - assert.equal(bid.cpm, 0.5); - - $$PREBID_GLOBAL$$.bidderSettings = - { - standard: { - bidCpmAdjustment: function (bidCpm) { - return bidCpm * 0.5; - } - } - }; - - adjustBids(bid) - assert.equal(bid.cpm, 0.25); - }); - - it('Custom bidCpmAdjustment AND custom configuration for one bidder and inherit standard settings', function () { - $$PREBID_GLOBAL$$.bidderSettings = - { - appnexus: { - bidCpmAdjustment: function (bidCpm) { - return bidCpm * 0.7; - }, - adserverTargeting: [ - { - key: CONSTANTS.TARGETING_KEYS.BIDDER, - val: function (bidResponse) { - return bidResponse.bidderCode; - } - }, { - key: CONSTANTS.TARGETING_KEYS.AD_ID, - val: function (bidResponse) { - return bidResponse.adId; - } - }, { - key: CONSTANTS.TARGETING_KEYS.PRICE_BUCKET, - val: function (bidResponse) { - // change default here - return 15.00; - } - } - ] - }, - standard: { - adserverTargeting: [ - { - key: CONSTANTS.TARGETING_KEYS.BIDDER, - val: function (bidResponse) { - return bidResponse.bidderCode; - } - }, { - key: CONSTANTS.TARGETING_KEYS.AD_ID, - val: function (bidResponse) { - return bidResponse.adId; - } - }, { - key: CONSTANTS.TARGETING_KEYS.PRICE_BUCKET, - val: function (bidResponse) { - // change default here - return 10.00; - }, - }, - { - key: CONSTANTS.TARGETING_KEYS.SIZE, - val: function (bidResponse) { - return bidResponse.size; - } - } - ] - - } - }; - var expected = getDefaultExpected(bid, [CONSTANTS.TARGETING_KEYS.BIDDER, CONSTANTS.TARGETING_KEYS.AD_ID, CONSTANTS.TARGETING_KEYS.SIZE]); - expected[CONSTANTS.TARGETING_KEYS.PRICE_BUCKET] = 15.0; - - var response = getKeyValueTargetingPairs(bid.bidderCode, bid); - assert.deepEqual(response, expected); - }); - - it('sendStandardTargeting=false, and inherit custom', function () { - $$PREBID_GLOBAL$$.bidderSettings = - { - appnexus: { - sendStandardTargeting: false, - adserverTargeting: [ - { - key: CONSTANTS.TARGETING_KEYS.BIDDER, - val: function (bidResponse) { - return bidResponse.bidderCode; - } - }, { - key: CONSTANTS.TARGETING_KEYS.AD_ID, - val: function (bidResponse) { - return bidResponse.adId; - } - }, { - key: CONSTANTS.TARGETING_KEYS.PRICE_BUCKET, - val: function (bidResponse) { - return bidResponse.pbHg; - } - } - ] - } - }; - var expected = getDefaultExpected(bid); - expected[CONSTANTS.TARGETING_KEYS.PRICE_BUCKET] = 5.57; - - var response = getKeyValueTargetingPairs(bid.bidderCode, bid); - assert.deepEqual(response, expected); - assert.equal(bid.sendStandardTargeting, false); - }); - - it('suppressEmptyKeys=true', function() { - $$PREBID_GLOBAL$$.bidderSettings = - { - standard: { - suppressEmptyKeys: true, - adserverTargeting: [ - { - key: 'aKeyWithAValue', - val: 42 - }, - { - key: 'aKeyWithAnEmptyValue', - val: '' - } - ] - } - }; - - var expected = { - 'aKeyWithAValue': 42 - }; - - var response = getKeyValueTargetingPairs(bid.bidderCode, bid); - assert.deepEqual(response, expected); - }); - }); - - describe('adjustBids', function () { - it('should adjust bids if greater than zero and pass copy of bid object', function () { - const bid = Object.assign({}, - createBid(2), - fixtures.getBidResponses()[5] - ); - - assert.equal(bid.cpm, 0.5); - - $$PREBID_GLOBAL$$.bidderSettings = - { - brealtime: { - bidCpmAdjustment: function (bidCpm, bidObj) { - assert.deepEqual(bidObj, bid); - if (bidObj.adUnitCode === 'negative') { - return bidCpm * -0.5; - } - if (bidObj.adUnitCode === 'zero') { - return 0; - } - return bidCpm * 0.5; - }, - }, - standard: { - adserverTargeting: [ - ] - } - }; - - // negative - bid.adUnitCode = 'negative'; - adjustBids(bid) - assert.equal(bid.cpm, 0.5); - - // positive - bid.adUnitCode = 'normal'; - adjustBids(bid) - assert.equal(bid.cpm, 0.25); - - // zero - bid.adUnitCode = 'zero'; - adjustBids(bid) - assert.equal(bid.cpm, 0); - - // reset bidderSettings so we don't mess up further tests - $$PREBID_GLOBAL$$.bidderSettings = {}; - }); - }); - - describe('addBidResponse', function () { - let createAuctionStub; - let adUnits; - let adUnitCodes; - let spec; - let auction; - let ajaxStub; - let bids = TEST_BIDS; - let makeRequestsStub; - - before(function () { - makeRequestsStub = sinon.stub(adapterManager, 'makeBidRequests'); - }); - - after(function () { - adapterManager.makeBidRequests.restore(); - }); - - describe('when auction timeout is 3000', function () { - before(function () { - ajaxStub = sinon.stub(ajaxLib, 'ajaxBuilder').callsFake(mockAjaxBuilder); - makeRequestsStub.returns(TEST_BID_REQS); - }); - beforeEach(function () { - adUnits = [{ - code: ADUNIT_CODE, - bids: [ - {bidder: BIDDER_CODE, params: {placementId: 'id'}}, - ] - }]; - adUnitCodes = [ADUNIT_CODE]; - auction = auctionModule.newAuction({adUnits, adUnitCodes, callback: function() {}, cbTimeout: 3000}); - createAuctionStub = sinon.stub(auctionModule, 'newAuction'); - createAuctionStub.returns(auction); - - spec = mockBidder(BIDDER_CODE, bids); - registerBidder(spec); - }); - - afterEach(function () { - auctionModule.newAuction.restore(); - }); - - after(function () { - ajaxStub.restore(); - }); - - function checkPbDg(cpm, expected, msg) { - return function() { - bids[0].cpm = cpm; - auction.callBids(); - - let registeredBid = auction.getBidsReceived().pop(); - assert.equal(registeredBid.pbDg, expected, msg); - }; - }; - - it('should return proper price bucket increments for dense mode when cpm is in range 0-3', - checkPbDg('1.99', '1.99', '0 - 3 hits at to 1 cent increment')); - - it('should return proper price bucket increments for dense mode when cpm is in range 3-8', - checkPbDg('4.39', '4.35', '3 - 8 hits at 5 cent increment')); - - it('should return proper price bucket increments for dense mode when cpm is in range 8-20', - checkPbDg('19.99', '19.50', '8 - 20 hits at 50 cent increment')); - - it('should return proper price bucket increments for dense mode when cpm is 20+', - checkPbDg('73.07', '20.00', '20+ caps at 20.00')); - - it('should place dealIds in adserver targeting', function () { - bids[0].dealId = 'test deal'; - auction.callBids(); - - let registeredBid = auction.getBidsReceived().pop(); - assert.equal(registeredBid.adserverTargeting[CONSTANTS.TARGETING_KEYS.DEAL], 'test deal', 'dealId placed in adserverTargeting'); - }); - - it('should pass through default adserverTargeting sent from adapter', function () { - bids[0].adserverTargeting = {}; - bids[0].adserverTargeting.extra = 'stuff'; - auction.callBids(); - - let registeredBid = auction.getBidsReceived().pop(); - assert.equal(registeredBid.adserverTargeting[CONSTANTS.TARGETING_KEYS.BIDDER], BIDDER_CODE); - assert.equal(registeredBid.adserverTargeting.extra, 'stuff'); - }); - - it('installs publisher-defined renderers on bids', function () { - let renderer = { - url: 'renderer.js', - render: (bid) => bid - }; - let bidRequests = [Object.assign({}, TEST_BID_REQS[0])]; - bidRequests[0].bids[0] = Object.assign({ renderer }, bidRequests[0].bids[0]); - makeRequestsStub.returns(bidRequests); - - let bids1 = Object.assign({}, - bids[0], - { - bidderCode: BIDDER_CODE, - mediaType: 'video-outstream', - } - ); - spec.interpretResponse.returns(bids1); - auction.callBids(); - const addedBid = auction.getBidsReceived().pop(); - assert.equal(addedBid.renderer.url, 'renderer.js'); - }); - - it('installs publisher-defined backup renderers on bids', function () { - let renderer = { - url: 'renderer.js', - backupOnly: true, - render: (bid) => bid - }; - let bidRequests = [Object.assign({}, TEST_BID_REQS[0])]; - bidRequests[0].bids[0] = Object.assign({ renderer }, bidRequests[0].bids[0]); - makeRequestsStub.returns(bidRequests); - - let bids1 = Object.assign({}, - bids[0], - { - bidderCode: BIDDER_CODE, - mediaType: 'video-outstream', - } - ); - spec.interpretResponse.returns(bids1); - auction.callBids(); - const addedBid = auction.getBidsReceived().pop(); - assert.equal(addedBid.renderer.url, 'renderer.js'); - }); - - it('installs publisher-defined renderers for a media type', function () { - const renderer = { - url: 'videoRenderer.js', - render: (bid) => bid - }; - let myBid = mockBid(); - let bidRequest = mockBidRequest(myBid); - - bidRequest.bids[0] = { - ...bidRequest.bids[0], - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - }, - video: { - context: 'outstream', - renderer - } - } - }; - makeRequestsStub.returns([bidRequest]); - - myBid.mediaType = 'video'; - spec.interpretResponse.returns(myBid); - auction.callBids(); - - const addedBid = auction.getBidsReceived().pop(); - assert.equal(addedBid.renderer.url, renderer.url); - }); - - it('installs bidder-defined renderer when onlyBackup is true in mediaTypes.video options ', function () { - const renderer = { - url: 'videoRenderer.js', - backupOnly: true, - render: (bid) => bid - }; - let myBid = mockBid(); - let bidRequest = mockBidRequest(myBid); - - bidRequest.bids[0] = { - ...bidRequest.bids[0], - mediaTypes: { - video: { - context: 'outstream', - renderer - } - } - }; - makeRequestsStub.returns([bidRequest]); - - myBid.mediaType = 'video'; - myBid.renderer = { - url: 'renderer.js', - render: sinon.spy() - }; - spec.interpretResponse.returns(myBid); - auction.callBids(); - - const addedBid = auction.getBidsReceived().pop(); - assert.strictEqual(addedBid.renderer.url, myBid.renderer.url); - }); - - it('bid for a regular unit and a video unit', function() { - let renderer = { - url: 'renderer.js', - render: (bid) => bid - }; - - // make sure that if the renderer is only on the second ad unit, prebid - // still correctly uses it - let bid = mockBid(); - let bidRequests = [mockBidRequest(bid)]; - - bidRequests[0].bids[1] = Object.assign({ - renderer, - bidId: utils.getUniqueIdentifierStr() - }, bidRequests[0].bids[0]); - bidRequests[0].bids[0].adUnitCode = ADUNIT_CODE1; - - makeRequestsStub.returns(bidRequests); - - // this should correspond with the second bid in the bidReq because of the ad unit code - bid.mediaType = 'video-outstream'; - spec.interpretResponse.returns(bid); - - auction.callBids(); - - const addedBid = find(auction.getBidsReceived(), bid => bid.adUnitCode == ADUNIT_CODE); - assert.equal(addedBid.renderer.url, 'renderer.js'); - }); - }); - - describe('when auction timeout is 20', function () { - let eventsEmitSpy; - - before(function () { - bids = [mockBid(), mockBid({ bidderCode: BIDDER_CODE1 })]; - let bidRequests = bids.map(bid => mockBidRequest(bid)); - - makeRequestsStub.returns(bidRequests); - }); - - beforeEach(function () { - adUnits = [{ - code: ADUNIT_CODE, - bids: [ - {bidder: BIDDER_CODE, params: {placementId: 'id'}}, - ] - }]; - adUnitCodes = [ADUNIT_CODE]; - - eventsEmitSpy = sinon.spy(events, 'emit'); - }); - afterEach(function () { - events.emit.restore(); - }); - - it('should emit BID_TIMEOUT and AUCTION_END for timed out bids', function (done) { - const spec1 = mockBidder(BIDDER_CODE, [bids[0]]); - registerBidder(spec1); - const spec2 = mockBidder(BIDDER_CODE1, [bids[1]]); - registerBidder(spec2); - - function respondToRequest(requestIndex) { - server.requests[requestIndex].respond(200, {}, 'response body'); - } - function auctionCallback() { - const bidTimeoutCall = eventsEmitSpy.withArgs(CONSTANTS.EVENTS.BID_TIMEOUT).getCalls()[0]; - const timedOutBids = bidTimeoutCall.args[1]; - assert.equal(timedOutBids.length, 1); - assert.equal(timedOutBids[0].bidder, BIDDER_CODE1); - - const auctionEndCall = eventsEmitSpy.withArgs(CONSTANTS.EVENTS.AUCTION_END).getCalls()[0]; - const auctionProps = auctionEndCall.args[1]; - assert.equal(auctionProps.adUnits, adUnits); - assert.equal(auctionProps.timeout, 20); - assert.equal(auctionProps.auctionStatus, AUCTION_COMPLETED) - done(); - } - auction = auctionModule.newAuction({adUnits, adUnitCodes, callback: auctionCallback, cbTimeout: 20}); - - auction.callBids(); - respondToRequest(0); - }); - it('should NOT emit BID_TIMEOUT when all bidders responded in time', function (done) { - const spec1 = mockBidder(BIDDER_CODE, [bids[0]]); - registerBidder(spec1); - const spec2 = mockBidder(BIDDER_CODE1, [bids[1]]); - registerBidder(spec2); - - function respondToRequest(requestIndex) { - server.requests[requestIndex].respond(200, {}, 'response body'); - } - function auctionCallback() { - assert.ok(eventsEmitSpy.withArgs(CONSTANTS.EVENTS.BID_TIMEOUT).notCalled, 'did not emit event BID_TIMEOUT'); - done(); - } - auction = auctionModule.newAuction({adUnits, adUnitCodes, callback: auctionCallback, cbTimeout: 20}); - - auction.callBids(); - respondToRequest(0); - respondToRequest(1); - }); - it('should NOT emit BID_TIMEOUT for bidders which responded in time but with an empty bid', function (done) { - const spec1 = mockBidder(BIDDER_CODE, []); - registerBidder(spec1); - const spec2 = mockBidder(BIDDER_CODE1, []); - registerBidder(spec2); - - function respondToRequest(requestIndex) { - server.requests[requestIndex].respond(200, {}, 'response body'); - } - function auctionCallback() { - const bidTimeoutCall = eventsEmitSpy.withArgs(CONSTANTS.EVENTS.BID_TIMEOUT).getCalls()[0]; - const timedOutBids = bidTimeoutCall.args[1]; - assert.equal(timedOutBids.length, 1); - assert.equal(timedOutBids[0].bidder, BIDDER_CODE1); - done(); - } - auction = auctionModule.newAuction({adUnits, adUnitCodes, callback: auctionCallback, cbTimeout: 20}); - - auction.callBids(); - respondToRequest(0); - }); - }); - }); - - describe('addBidResponse', function () { - let createAuctionStub; - let adUnits; - let adUnitCodes; - let spec; - let spec1; - let auction; - let ajaxStub; - - let bids = TEST_BIDS; - let bids1 = [mockBid({ bidderCode: BIDDER_CODE1 })]; - - before(function () { - let bidRequests = [ - mockBidRequest(bids[0]), - mockBidRequest(bids1[0], { adUnitCode: ADUNIT_CODE1 }) - ]; - let makeRequestsStub = sinon.stub(adapterManager, 'makeBidRequests'); - makeRequestsStub.returns(bidRequests); - - ajaxStub = sinon.stub(ajaxLib, 'ajaxBuilder').callsFake(mockAjaxBuilder); - }); - - after(function () { - ajaxStub.restore(); - adapterManager.makeBidRequests.restore(); - }); - - beforeEach(function () { - adUnits = [{ - code: ADUNIT_CODE, - bids: [ - {bidder: BIDDER_CODE, params: {placementId: 'id'}}, - ] - }, { - code: ADUNIT_CODE1, - bids: [ - {bidder: BIDDER_CODE1, params: {placementId: 'id'}}, - ] - }]; - adUnitCodes = adUnits.map(({ code }) => code); - auction = auctionModule.newAuction({adUnits, adUnitCodes, callback: function() {}, cbTimeout: 3000}); - createAuctionStub = sinon.stub(auctionModule, 'newAuction'); - createAuctionStub.returns(auction); - - spec = mockBidder(BIDDER_CODE, bids); - spec1 = mockBidder(BIDDER_CODE1, bids1); - - registerBidder(spec); - registerBidder(spec1); - }); - - afterEach(function () { - auctionModule.newAuction.restore(); - }); - - it('should not alter bid requestID', function () { - auction.callBids(); - - const addedBid2 = auction.getBidsReceived().pop(); - assert.equal(addedBid2.requestId, bids1[0].requestId); - const addedBid1 = auction.getBidsReceived().pop(); - assert.equal(addedBid1.requestId, bids[0].requestId); - }); - - it('should not add banner bids that have no width or height', function () { - bids1[0].width = undefined; - bids1[0].height = undefined; - - auction.callBids(); - - let length = auction.getBidsReceived().length; - const addedBid2 = auction.getBidsReceived().pop(); - assert.notEqual(addedBid2.adId, bids1[0].requestId); - assert.equal(length, 1); - }); - - it('should run auction after video bids have been cached', function () { - 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' })]; - - spec.interpretResponse.returns(bidsCopy); - spec1.interpretResponse.returns(bids1Copy); - - auction.callBids(); - - assert.equal(auction.getBidsReceived().length, 2); - assert.equal(auction.getAuctionStatus(), 'completed'); - - config.getConfig.restore(); - store.store.restore(); - }); - - it('runs auction after video responses with multiple bid objects have been cached', function () { - 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' }), - ]; - const bids1Copy = [ - Object.assign({}, bids1[0], { mediaType: 'video' }), - Object.assign({}, bids1[0], { mediaType: 'video' }), - ]; - - spec.interpretResponse.returns(bidsCopy); - spec1.interpretResponse.returns(bids1Copy); - - auction.callBids(); - - assert.equal(auction.getBidsReceived().length, 4); - assert.equal(auction.getAuctionStatus(), 'completed'); - - config.getConfig.restore(); - store.store.restore(); - }); - }); - - describe('addBidRequests', function () { - let createAuctionStub; - let adUnits; - let adUnitCodes; - let spec; - let spec1; - let auction; - let ajaxStub; - let logMessageStub; - let logInfoStub; - let logWarnStub; - let logErrorStub; - - let bids = TEST_BIDS; - let bids1 = [mockBid({ bidderCode: BIDDER_CODE1 })]; - - before(function () { - logMessageStub = sinon.stub(utils, 'logMessage'); - logInfoStub = sinon.stub(utils, 'logInfo'); - logWarnStub = sinon.stub(utils, 'logWarn'); - logErrorStub = sinon.stub(utils, 'logError'); - let bidRequests = [ - mockBidRequest(bids[0]), - mockBidRequest(bids1[0], { adUnitCode: ADUNIT_CODE1 }) - ]; - let makeRequestsStub = sinon.stub(adapterManager, 'makeBidRequests'); - makeRequestsStub.returns(bidRequests); - - ajaxStub = sinon.stub(ajaxLib, 'ajaxBuilder').callsFake(mockAjaxBuilder); - }); - - after(function () { - logMessageStub.restore(); - logInfoStub.restore(); - logWarnStub.restore(); - logErrorStub.restore(); - ajaxStub.restore(); - adapterManager.makeBidRequests.restore(); - }); - - beforeEach(function () { - config.setConfig({ - debugging: { - enabled: true, - bidRequests: [{ - bidderCode: BIDDER_CODE, - adUnitCode: ADUNIT_CODE, - storedAuctionResponse: '11111' - }] - } - }); - - adUnits = [{ - code: ADUNIT_CODE, - bids: [ - {bidder: BIDDER_CODE, params: {placementId: 'id'}}, - ] - }, { - code: ADUNIT_CODE1, - bids: [ - {bidder: BIDDER_CODE1, params: {placementId: 'id'}}, - ] - }]; - adUnitCodes = adUnits.map(({ code }) => code); - auction = auctionModule.newAuction({adUnits, adUnitCodes, callback: function() {}, cbTimeout: 3000}); - createAuctionStub = sinon.stub(auctionModule, 'newAuction'); - createAuctionStub.returns(auction); - - spec = mockBidder(BIDDER_CODE, bids); - spec1 = mockBidder(BIDDER_CODE1, bids1); - - registerBidder(spec); - registerBidder(spec1); - }); - - afterEach(function () { - logMessageStub.resetHistory(); - logInfoStub.resetHistory(); - logWarnStub.resetHistory(); - logErrorStub.resetHistory(); - auctionModule.newAuction.restore(); - config.resetConfig(); - }); - - it('should override bidRequest properties when config debugging has a matching bidRequest defined', function () { - auction.callBids(); - const auctionBidRequests = auction.getBidRequests(); - assert.equal(auctionBidRequests.length > 0, true); - assert.equal(Array.isArray(auctionBidRequests[0].bids), true); - - const bid = find(auctionBidRequests[0].bids, bid => bid.adUnitCode === ADUNIT_CODE); - assert.equal(typeof bid !== 'undefined', true); - assert.equal(bid.hasOwnProperty('storedAuctionResponse'), true); - assert.equal(bid.storedAuctionResponse, '11111'); - }); - }); - - describe('getMediaTypeGranularity', function () { - it('video', function () { - let bidReq = { - 'mediaTypes': { video: {id: '1'} } - }; - - // mediaType is video and video.context is undefined - expect(getMediaTypeGranularity('video', bidReq, { - banner: 'low', - video: 'medium' - })).to.equal('medium'); - - expect(getMediaTypeGranularity('video', {}, { - banner: 'low', - video: 'medium' - })).to.equal('medium'); - `` - expect(getMediaTypeGranularity('video', undefined, { - banner: 'low', - video: 'medium' - })).to.equal('medium'); - - // also when mediaTypes.video is undefined - bidReq = { - 'mediaTypes': { banner: {} } - }; - expect(getMediaTypeGranularity('video', bidReq, { - banner: 'low', - video: 'medium' - })).to.equal('medium'); - - // also when mediaTypes is undefined - expect(getMediaTypeGranularity('video', {}, { - banner: 'low', - video: 'medium' - })).to.equal('medium'); - }); - - it('video-outstream', function () { - let bidReq = { 'mediaTypes': { video: { context: 'outstream' } } }; - - expect(getMediaTypeGranularity('video', bidReq, { - 'banner': 'low', 'video': 'medium', 'video-outstream': 'high' - })).to.equal('high'); - }); - - it('video-instream', function () { - let bidReq = { 'mediaTypes': { video: { context: 'instream' } } }; - - expect(getMediaTypeGranularity('video', bidReq, { - banner: 'low', video: 'medium', 'video-instream': 'high' - })).to.equal('high'); - - // fall back to video if video-instream not found - expect(getMediaTypeGranularity('video', bidReq, { - banner: 'low', video: 'medium' - })).to.equal('medium'); - - expect(getMediaTypeGranularity('video', {mediaTypes: {banner: {}}}, { - banner: 'low', video: 'medium' - })).to.equal('medium'); - }); - - it('native', function () { - expect(getMediaTypeGranularity('native', {mediaTypes: {native: {}}}, { - banner: 'low', video: 'medium', native: 'high' - })).to.equal('high'); - }); - }); - - describe('auctionCallbacks', function() { - let bids = TEST_BIDS; - let bidRequests; - let doneSpy; - let auction = { - getBidRequests: () => bidRequests, - getAuctionId: () => '1', - addBidReceived: () => true, - getTimeout: () => 1000 - } - - beforeEach(() => { - doneSpy = sinon.spy(); - config.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }) - }); - - afterEach(() => { - doneSpy.resetHistory(); - config.resetConfig(); - }); - - it('should call auction done after bid is added to auction for mediaType banner', function () { - let ADUNIT_CODE2 = 'adUnitCode2'; - let BIDDER_CODE2 = 'sampleBidder2'; - - let bids1 = [mockBid({ bidderCode: BIDDER_CODE1 })]; - let bids2 = [mockBid({ bidderCode: BIDDER_CODE2 })]; - bidRequests = [ - mockBidRequest(bids[0]), - mockBidRequest(bids1[0], { adUnitCode: ADUNIT_CODE1 }), - mockBidRequest(bids2[0], { adUnitCode: ADUNIT_CODE2 }) - ]; - let cbs = auctionCallbacks(doneSpy, auction); - cbs.addBidResponse.call(bidRequests[0], ADUNIT_CODE, bids[0]); - cbs.adapterDone.call(bidRequests[0]); - cbs.addBidResponse.call(bidRequests[1], ADUNIT_CODE1, bids1[0]); - cbs.adapterDone.call(bidRequests[1]); - cbs.addBidResponse.call(bidRequests[2], ADUNIT_CODE2, bids2[0]); - cbs.adapterDone.call(bidRequests[2]); - assert.equal(doneSpy.callCount, 1); - }); - - it('should call auction done after prebid cache is complete for mediaType video', function() { - bids[0].mediaType = 'video'; - let bids1 = [mockBid({ bidderCode: BIDDER_CODE1 })]; - - let opts = { - mediaType: { - video: { - context: 'instream', - playerSize: [640, 480], - }, - } - }; - bidRequests = [ - mockBidRequest(bids[0], opts), - mockBidRequest(bids1[0], { adUnitCode: ADUNIT_CODE1 }), - ]; - - let cbs = auctionCallbacks(doneSpy, auction); - cbs.addBidResponse.call(bidRequests[0], ADUNIT_CODE, bids[0]); - cbs.adapterDone.call(bidRequests[0]); - cbs.addBidResponse.call(bidRequests[1], ADUNIT_CODE1, bids1[0]); - cbs.adapterDone.call(bidRequests[1]); - 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); - assert.equal(doneSpy.callCount, 1); - }) - }); - - describe('auctionOptions', function() { - let bidRequests; - let doneSpy; - let clock; - let auction = { - getBidRequests: () => bidRequests, - getAuctionId: () => '1', - addBidReceived: () => true, - getTimeout: () => 1000 - } - let requiredBidder = BIDDER_CODE; - let requiredBidder1 = BIDDER_CODE1; - let secondaryBidder = 'doNotWaitForMe'; - - beforeEach(() => { - clock = sinon.useFakeTimers(); - doneSpy = sinon.spy(); - config.setConfig({ - 'auctionOptions': { - secondaryBidders: [ secondaryBidder ] - } - }) - }); - - afterEach(() => { - doneSpy.resetHistory(); - config.resetConfig(); - clock.restore(); - }); - - it('should not wait to call auction done for secondary bidders', function () { - let bids1 = [mockBid({ bidderCode: requiredBidder })]; - let bids2 = [mockBid({ bidderCode: requiredBidder1 })]; - let bids3 = [mockBid({ bidderCode: secondaryBidder })]; - bidRequests = [ - mockBidRequest(bids1[0], { adUnitCode: ADUNIT_CODE1 }), - mockBidRequest(bids2[0], { adUnitCode: ADUNIT_CODE1 }), - mockBidRequest(bids3[0], { adUnitCode: ADUNIT_CODE1 }), - ]; - let cbs = auctionCallbacks(doneSpy, auction); - // required bidder responds immeaditely to auction - cbs.addBidResponse.call(bidRequests[0], ADUNIT_CODE1, bids1[0]); - cbs.adapterDone.call(bidRequests[0]); - assert.equal(doneSpy.callCount, 0); - - // auction waits for second required bidder to respond - clock.tick(100); - cbs.addBidResponse.call(bidRequests[1], ADUNIT_CODE1, bids2[0]); - cbs.adapterDone.call(bidRequests[1]); - - // auction done is reported and does not wait for secondaryBidder request - assert.equal(doneSpy.callCount, 1); - - cbs.addBidResponse.call(bidRequests[2], ADUNIT_CODE1, bids3[0]); - cbs.adapterDone.call(bidRequests[2]); - }); - - it('should wait for all bidders if they are all secondary', function () { - config.setConfig({ - 'auctionOptions': { - secondaryBidders: [requiredBidder, requiredBidder1, secondaryBidder] - } - }) - let bids1 = [mockBid({ bidderCode: requiredBidder })]; - let bids2 = [mockBid({ bidderCode: requiredBidder1 })]; - let bids3 = [mockBid({ bidderCode: secondaryBidder })]; - bidRequests = [ - mockBidRequest(bids1[0], { adUnitCode: ADUNIT_CODE1 }), - mockBidRequest(bids2[0], { adUnitCode: ADUNIT_CODE1 }), - mockBidRequest(bids3[0], { adUnitCode: ADUNIT_CODE1 }), - ]; - let cbs = auctionCallbacks(doneSpy, auction); - cbs.addBidResponse.call(bidRequests[0], ADUNIT_CODE1, bids1[0]); - cbs.adapterDone.call(bidRequests[0]); - clock.tick(100); - assert.equal(doneSpy.callCount, 0) - - cbs.addBidResponse.call(bidRequests[1], ADUNIT_CODE1, bids2[0]); - cbs.adapterDone.call(bidRequests[1]); - clock.tick(100); - assert.equal(doneSpy.callCount, 0); - - cbs.addBidResponse.call(bidRequests[2], ADUNIT_CODE1, bids3[0]); - cbs.adapterDone.call(bidRequests[2]); - assert.equal(doneSpy.callCount, 1); - }); - - it('should allow secondaryBidders to respond in auction before is is done', function () { - let bids1 = [mockBid({ bidderCode: requiredBidder })]; - let bids2 = [mockBid({ bidderCode: requiredBidder1 })]; - let bids3 = [mockBid({ bidderCode: secondaryBidder })]; - bidRequests = [ - mockBidRequest(bids1[0], { adUnitCode: ADUNIT_CODE1 }), - mockBidRequest(bids2[0], { adUnitCode: ADUNIT_CODE1 }), - mockBidRequest(bids3[0], { adUnitCode: ADUNIT_CODE1 }), - ]; - let cbs = auctionCallbacks(doneSpy, auction); - // secondaryBidder is first to respond - cbs.addBidResponse.call(bidRequests[2], ADUNIT_CODE1, bids3[0]); - cbs.adapterDone.call(bidRequests[2]); - clock.tick(100); - assert.equal(doneSpy.callCount, 0); - - cbs.addBidResponse.call(bidRequests[1], ADUNIT_CODE1, bids2[0]); - cbs.adapterDone.call(bidRequests[1]); - clock.tick(100); - assert.equal(doneSpy.callCount, 0); - - // first required bidder takes longest to respond, auction isn't marked as done until this occurs - cbs.addBidResponse.call(bidRequests[0], ADUNIT_CODE1, bids1[0]); - cbs.adapterDone.call(bidRequests[0]); - assert.equal(doneSpy.callCount, 1); - }); - }); -}); diff --git a/test/spec/config_spec.js b/test/spec/config_spec.js deleted file mode 100644 index 8161d9f1827..00000000000 --- a/test/spec/config_spec.js +++ /dev/null @@ -1,268 +0,0 @@ -import { expect } from 'chai'; -import { assert } from 'chai'; -import { newConfig } from 'src/config.js'; - -const utils = require('src/utils'); - -let getConfig; -let setConfig; -let getBidderConfig; -let setBidderConfig; -let setDefaults; - -describe('config API', function () { - let logErrorSpy; - let logWarnSpy; - beforeEach(function () { - const config = newConfig(); - getConfig = config.getConfig; - setConfig = config.setConfig; - getBidderConfig = config.getBidderConfig; - setBidderConfig = config.setBidderConfig; - setDefaults = config.setDefaults; - logErrorSpy = sinon.spy(utils, 'logError'); - logWarnSpy = sinon.spy(utils, 'logWarn'); - }); - - afterEach(function () { - utils.logError.restore(); - utils.logWarn.restore(); - }); - - it('setConfig is a function', function () { - expect(setConfig).to.be.a('function'); - }); - - it('getConfig returns an object', function () { - expect(getConfig()).to.be.a('object'); - }); - - it('sets and gets arbitrary configuration properties', function () { - setConfig({ baz: 'qux' }); - expect(getConfig('baz')).to.equal('qux'); - }); - - it('only accepts objects', function () { - setConfig('invalid'); - expect(getConfig('0')).to.not.equal('i'); - }); - - it('sets multiple config properties', function () { - setConfig({ foo: 'bar' }); - setConfig({ biz: 'buz' }); - var config = getConfig(); - expect(config.foo).to.equal('bar'); - expect(config.biz).to.equal('buz'); - }); - - it('overwrites existing config properties', function () { - setConfig({ foo: {biz: 'buz'} }); - setConfig({ foo: {baz: 'qux'} }); - expect(getConfig('foo')).to.eql({baz: 'qux'}); - }); - - it('moves fpd config into ortb2 properties', function () { - setConfig({fpd: {context: {keywords: 'foo,bar', data: {inventory: [1]}}}}); - expect(getConfig('ortb2')).to.eql({site: {keywords: 'foo,bar', ext: {data: {inventory: [1]}}}}); - expect(getConfig('fpd')).to.eql(undefined); - }); - - it('moves fpd bidderconfig into ortb2 properties', function () { - setBidderConfig({bidders: ['bidderA'], config: {fpd: {context: {keywords: 'foo,bar', data: {inventory: [1]}}}}}); - expect(getBidderConfig()).to.eql({'bidderA': {ortb2: {site: {keywords: 'foo,bar', ext: {data: {inventory: [1]}}}}}}); - }); - - it('sets debugging', function () { - setConfig({ debug: true }); - expect(getConfig('debug')).to.be.true; - }); - - it('sets bidderTimeout', function () { - setConfig({ bidderTimeout: 1000 }); - expect(getConfig('bidderTimeout')).to.be.equal(1000); - }); - - it('gets user-defined publisherDomain', function () { - setConfig({ publisherDomain: 'fc.kahuna' }); - expect(getConfig('publisherDomain')).to.equal('fc.kahuna'); - }); - - it('gets default userSync config', function () { - const DEFAULT_USERSYNC = { - syncEnabled: true, - pixelEnabled: true, - syncsPerBidder: 5, - syncDelay: 3000, - auctionDelay: 0 - }; - setDefaults({'userSync': DEFAULT_USERSYNC}); - expect(getConfig('userSync')).to.eql(DEFAULT_USERSYNC); - }); - - it('has subscribe functionality for adding listeners to config updates', function () { - const listener = sinon.spy(); - - getConfig(listener); - - setConfig({ foo: 'bar' }); - - sinon.assert.calledOnce(listener); - sinon.assert.calledWith(listener, { foo: 'bar' }); - }); - - it('subscribers can unsubscribe', function () { - const listener = sinon.spy(); - - const unsubscribe = getConfig(listener); - - unsubscribe(); - - setConfig({ logging: true }); - - sinon.assert.notCalled(listener); - }); - - it('subscribers can subscribe to topics', function () { - const listener = sinon.spy(); - - getConfig('logging', listener); - - setConfig({ logging: true, foo: 'bar' }); - - sinon.assert.calledOnce(listener); - sinon.assert.calledWithExactly(listener, { logging: true }); - }); - - it('topic subscribers are only called when that topic is changed', function () { - const listener = sinon.spy(); - const wildcard = sinon.spy(); - - getConfig('subject', listener); - getConfig(wildcard); - - setConfig({ foo: 'bar' }); - - sinon.assert.notCalled(listener); - sinon.assert.calledOnce(wildcard); - }); - - it('sets priceGranularity', function () { - setConfig({ priceGranularity: 'low' }); - expect(getConfig('priceGranularity')).to.be.equal('low'); - }); - - it('set mediaTypePriceGranularity', function () { - const customPriceGranularityVideo = { - 'buckets': [{ - 'max': 3, - 'increment': 0.01, - 'cap': true - }] - }; - const customPriceGranularityInstream = utils.deepClone(customPriceGranularityVideo); - const customPriceGranularityOutstream = utils.deepClone(customPriceGranularityVideo); - - setConfig({ - 'mediaTypePriceGranularity': { - 'banner': 'medium', - 'video': customPriceGranularityVideo, - 'video-instream': customPriceGranularityInstream, - 'video-outstream': customPriceGranularityOutstream, - 'native': 'high' - } - }); - - const configResult = getConfig('mediaTypePriceGranularity'); - expect(configResult.banner).to.be.equal('medium'); - expect(configResult.video).to.be.equal(customPriceGranularityVideo); - expect(configResult['video-instream']).to.be.equal(customPriceGranularityInstream); - expect(configResult['video-outstream']).to.be.equal(customPriceGranularityOutstream); - expect(configResult.native).to.be.equal('high'); - }); - - it('sets priceGranularity and customPriceBucket', function () { - const goodConfig = { - 'buckets': [{ - 'max': 3, - 'increment': 0.01, - 'cap': true - }] - }; - setConfig({ priceGranularity: goodConfig }); - expect(getConfig('priceGranularity')).to.be.equal('custom'); - expect(getConfig('customPriceBucket')).to.equal(goodConfig); - }); - - it('sets deviceAccess', function () { - // When the deviceAccess flag config option is not set, cookies may be read and set - expect(getConfig('deviceAccess')).to.be.equal(true); - - // When the deviceAccess flag config option is set to false, no cookies are read or set - setConfig({ - 'deviceAccess': false - }); - expect(getConfig('deviceAccess')).to.be.equal(false); - - // When the deviceAccess flag config option is set to true, cookies may be read and set - setConfig({ - 'deviceAccess': true - }); - expect(getConfig('deviceAccess')).to.be.equal(true); - }); - - it('sets maxNestedIframes', function () { - expect(getConfig('maxNestedIframes')).to.be.equal(10); - setConfig({ maxNestedIframes: 2 }); - expect(getConfig('maxNestedIframes')).to.be.equal(2); - }); - - it('should log error for invalid priceGranularity', function () { - setConfig({ priceGranularity: '' }); - const error = 'Prebid Error: no value passed to `setPriceGranularity()`'; - assert.ok(logErrorSpy.calledWith(error), 'expected error was logged'); - }); - - it('should log a warning on invalid values', function () { - setConfig({ bidderSequence: 'unrecognized sequence' }); - expect(logWarnSpy.calledOnce).to.equal(true); - }); - - it('should not log warnings when given recognized values', function () { - setConfig({ bidderSequence: 'fixed' }); - setConfig({ bidderSequence: 'random' }); - expect(logWarnSpy.called).to.equal(false); - }); - - it('sets auctionOptions', function () { - const auctionOptionsConfig = { - 'secondaryBidders': ['rubicon', 'appnexus'] - } - setConfig({ auctionOptions: auctionOptionsConfig }); - expect(getConfig('auctionOptions')).to.eql(auctionOptionsConfig); - }); - - it('should log warning for the wrong value passed to auctionOptions', function () { - setConfig({ auctionOptions: '' }); - expect(logWarnSpy.calledOnce).to.equal(true); - const warning = 'Auction Options must be an object'; - assert.ok(logWarnSpy.calledWith(warning), 'expected warning was logged'); - }); - - it('should log warning for invalid auctionOptions bidder values', function () { - 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 properties to auctionOptions', function () { - 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'); - }); -}); diff --git a/test/spec/cpmBucketManager_spec.js b/test/spec/cpmBucketManager_spec.js deleted file mode 100644 index 0b8635a4e3b..00000000000 --- a/test/spec/cpmBucketManager_spec.js +++ /dev/null @@ -1,195 +0,0 @@ -import { expect } from 'chai'; -import {getPriceBucketString, isValidPriceConfig} from 'src/cpmBucketManager.js'; -let cpmFixtures = require('test/fixtures/cpmInputsOutputs.json'); - -describe('cpmBucketManager', function () { - it('getPriceBucketString function generates the correct price strings', function () { - let input = cpmFixtures.cpmInputs; - for (let i = 0; i < input.length; i++) { - let output = getPriceBucketString(input[i]); - let jsonOutput = JSON.stringify(output); - expect(jsonOutput).to.deep.equal(JSON.stringify(cpmFixtures.priceStringOutputs[i])); - } - }); - - it('gets the correct custom bucket strings', function () { - let cpm = 16.50908; - let customConfig = { - 'buckets': [{ - 'precision': 4, - 'max': 3, - 'increment': 0.01, - }, - { - 'precision': 4, - 'max': 18, - 'increment': 0.05, - 'cap': true - } - ] - }; - let expected = '{"low":"5.00","med":"16.50","high":"16.50","auto":"16.50","dense":"16.50","custom":"16.5000"}'; - let output = getPriceBucketString(cpm, customConfig); - expect(JSON.stringify(output)).to.deep.equal(expected); - }); - - it('gets the correct custom bucket strings with irregular increment', function () { - let cpm = 14.50908; - let customConfig = { - 'buckets': [{ - 'precision': 4, - 'max': 4, - 'increment': 0.01, - }, - { - 'precision': 4, - 'max': 18, - 'increment': 0.3, - 'cap': true - } - ] - }; - let expected = '{"low":"5.00","med":"14.50","high":"14.50","auto":"14.50","dense":"14.50","custom":"14.5000"}'; - let output = getPriceBucketString(cpm, customConfig); - expect(JSON.stringify(output)).to.deep.equal(expected); - }); - - it('gets the correct custom bucket strings in non-USD currency', function () { - let cpm = 16.50908 * 110.49; - let customConfig = { - 'buckets': [{ - 'precision': 4, - 'max': 3, - 'increment': 0.01, - }, - { - 'precision': 4, - 'max': 18, - 'increment': 0.05, - 'cap': true - } - ] - }; - let expected = '{"low":"552.45","med":"1823.09","high":"1823.09","auto":"1823.09","dense":"1823.09","custom":"1823.0850"}'; - let output = getPriceBucketString(cpm, customConfig, 110.49); - expect(JSON.stringify(output)).to.deep.equal(expected); - }); - - it('gets the correct custom bucket strings with specific cpms that round oddly with certain increments', function () { - let customConfig = { - 'buckets': [{ - 'precision': 4, - 'max': 4, - 'increment': 0.10, - }] - }; - let cpm = 2.21; - let expected = '{"low":"2.00","med":"2.20","high":"2.21","auto":"2.20","dense":"2.21","custom":"2.2000"}'; - let output = getPriceBucketString(cpm, customConfig); - expect(JSON.stringify(output)).to.deep.equal(expected); - - cpm = 3.15; - expected = '{"low":"3.00","med":"3.10","high":"3.15","auto":"3.15","dense":"3.15","custom":"3.1000"}'; - output = getPriceBucketString(cpm, customConfig); - expect(JSON.stringify(output)).to.deep.equal(expected); - - customConfig = { - 'buckets': [{ - 'precision': 3, - 'max': 6, - 'increment': 0.08, - }] - }; - cpm = 4.89; - expected = '{"low":"4.50","med":"4.80","high":"4.89","auto":"4.85","dense":"4.85","custom":"4.880"}'; - output = getPriceBucketString(cpm, customConfig); - expect(JSON.stringify(output)).to.deep.equal(expected); - - customConfig = { - 'buckets': [{ - 'precision': 3, - 'max': 6, - 'increment': 0.05, - }] - }; - cpm = 2.98; - expected = '{"low":"2.50","med":"2.90","high":"2.98","auto":"2.95","dense":"2.98","custom":"2.950"}'; - output = getPriceBucketString(cpm, customConfig); - expect(JSON.stringify(output)).to.deep.equal(expected); - - cpm = 2.99; - expected = '{"low":"2.50","med":"2.90","high":"2.99","auto":"2.95","dense":"2.99","custom":"2.950"}'; - output = getPriceBucketString(cpm, customConfig); - expect(JSON.stringify(output)).to.deep.equal(expected); - - customConfig = { - 'buckets': [{ - 'precision': 2, - 'max': 6, - 'increment': 0.01, - }] - }; - cpm = 4.01; - expected = '{"low":"4.00","med":"4.00","high":"4.01","auto":"4.00","dense":"4.00","custom":"4.01"}'; - output = getPriceBucketString(cpm, customConfig); - expect(JSON.stringify(output)).to.deep.equal(expected); - - cpm = 4.68; - expected = '{"low":"4.50","med":"4.60","high":"4.68","auto":"4.65","dense":"4.65","custom":"4.68"}'; - output = getPriceBucketString(cpm, customConfig); - expect(JSON.stringify(output)).to.deep.equal(expected); - - cpm = 4.69; - expected = '{"low":"4.50","med":"4.60","high":"4.69","auto":"4.65","dense":"4.65","custom":"4.69"}'; - output = getPriceBucketString(cpm, customConfig); - expect(JSON.stringify(output)).to.deep.equal(expected); - }); - - it('gets custom bucket strings and it should honor 0', function () { - let cpm = 16.50908; - let customConfig = { - 'buckets': [ - { - 'precision': 0, - 'max': 18, - 'increment': 0.05, - } - ] - }; - let expected = '{"low":"5.00","med":"16.50","high":"16.50","auto":"16.50","dense":"16.50","custom":"17"}'; - let output = getPriceBucketString(cpm, customConfig); - expect(JSON.stringify(output)).to.deep.equal(expected); - }); - - it('gets the custom bucket strings without passing precision and it should honor the default precision', function () { - let cpm = 16.50908; - let customConfig = { - 'buckets': [ - { - 'max': 18, - 'increment': 0.05, - } - ] - }; - let expected = '{"low":"5.00","med":"16.50","high":"16.50","auto":"16.50","dense":"16.50","custom":"16.50"}'; - let output = getPriceBucketString(cpm, customConfig); - expect(JSON.stringify(output)).to.deep.equal(expected); - }); - - it('checks whether custom config is valid', function () { - let badConfig = { - 'buckets': [{ - 'max': 3, - 'increment': 0.01, - }, - { - 'max': 18, - // missing increment prop - 'cap': true - } - ] - }; - - expect(isValidPriceConfig(badConfig)).to.be.false; - }); -}); diff --git a/test/spec/debugging_spec.js b/test/spec/debugging_spec.js deleted file mode 100644 index bf49a579cbd..00000000000 --- a/test/spec/debugging_spec.js +++ /dev/null @@ -1,193 +0,0 @@ - -import { expect } from 'chai'; -import { sessionLoader, addBidResponseHook, addBidderRequestsHook, getConfig, disableOverrides, addBidResponseBound, addBidderRequestsBound } from 'src/debugging.js'; -import { addBidResponse, addBidderRequests } from 'src/auction.js'; -import { config } from 'src/config.js'; - -describe('bid overrides', function () { - let sandbox; - - beforeEach(function () { - sandbox = sinon.sandbox.create(); - }); - - afterEach(function () { - window.sessionStorage.clear(); - config.resetConfig(); - sandbox.restore(); - }); - - describe('initialization', function () { - beforeEach(function () { - sandbox.stub(config, 'setConfig'); - }); - - afterEach(function () { - disableOverrides(); - }); - - it('should happen when enabled with setConfig', function () { - getConfig({ - enabled: true - }); - - 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({ - getItem: () => ('{"enabled": true}') - }); - expect(addBidResponse.getHooks().some(hook => hook.hook === addBidResponseBound)).to.equal(true); - expect(addBidderRequests.getHooks().some(hook => hook.hook === addBidderRequestsBound)).to.equal(true); - }); - - it('should not throw if sessionStorage is inaccessible', function () { - expect(() => { - sessionLoader({ - getItem() { - throw new Error('test'); - } - }); - }).not.to.throw(); - }); - }); - - describe('bidResponse hook', function () { - let mockBids; - let bids; - - beforeEach(function () { - let baseBid = { - 'bidderCode': 'rubicon', - 'width': 970, - 'height': 250, - 'statusMessage': 'Bid available', - 'mediaType': 'banner', - 'source': 'client', - 'currency': 'USD', - 'cpm': 0.5, - 'ttl': 300, - 'netRevenue': false, - 'adUnitCode': '/19968336/header-bid-tag-0' - }; - mockBids = []; - mockBids.push(baseBid); - mockBids.push(Object.assign({}, baseBid, { - bidderCode: 'appnexus' - })); - - bids = []; - }); - - function run(overrides) { - mockBids.forEach(bid => { - let next = (adUnitCode, bid) => { - bids.push(bid); - }; - addBidResponseHook.bind(overrides)(next, bid.adUnitCode, bid); - }); - } - - it('should allow us to exclude bidders', function () { - run({ - enabled: true, - bidders: ['appnexus'] - }); - - expect(bids.length).to.equal(1); - expect(bids[0].bidderCode).to.equal('appnexus'); - }); - - it('should allow us to override all bids', function () { - run({ - enabled: true, - bids: [{ - cpm: 2 - }] - }); - - expect(bids.length).to.equal(2); - expect(bids[0].cpm).to.equal(2); - expect(bids[1].cpm).to.equal(2); - }); - - it('should allow us to override bids by bidder', function () { - run({ - enabled: true, - bids: [{ - bidder: 'rubicon', - cpm: 2 - }] - }); - - expect(bids.length).to.equal(2); - expect(bids[0].cpm).to.equal(2); - expect(bids[1].cpm).to.equal(0.5); - }); - - it('should allow us to override bids by adUnitCode', function () { - mockBids[1].adUnitCode = 'test'; - - run({ - enabled: true, - bids: [{ - adUnitCode: 'test', - cpm: 2 - }] - }); - - expect(bids.length).to.equal(2); - expect(bids[0].cpm).to.equal(0.5); - expect(bids[1].cpm).to.equal(2); - }); - }); - - describe('bidRequests hook', function () { - let mockBidRequests; - let bidderRequests; - - beforeEach(function () { - let baseBidderRequest = { - 'bidderCode': 'rubicon', - 'bids': [{ - 'width': 970, - 'height': 250, - 'statusMessage': 'Bid available', - 'mediaType': 'banner', - 'source': 'client', - 'currency': 'USD', - 'cpm': 0.5, - 'ttl': 300, - 'netRevenue': false, - 'adUnitCode': '/19968336/header-bid-tag-0' - }] - }; - mockBidRequests = []; - mockBidRequests.push(baseBidderRequest); - mockBidRequests.push(Object.assign({}, baseBidderRequest, { - bidderCode: 'appnexus' - })); - - bidderRequests = []; - }); - - function run(overrides) { - let next = (b) => { - bidderRequests = b; - }; - addBidderRequestsHook.bind(overrides)(next, mockBidRequests); - } - - it('should allow us to exclude bidders', function () { - run({ - enabled: true, - bidders: ['appnexus'] - }); - - expect(bidderRequests.length).to.equal(1); - expect(bidderRequests[0].bidderCode).to.equal('appnexus'); - }); - }); -}); diff --git a/test/spec/e2e/banner/basic_banner_ad.spec.js b/test/spec/e2e/banner/basic_banner_ad.spec.js deleted file mode 100644 index 7088bd3eade..00000000000 --- a/test/spec/e2e/banner/basic_banner_ad.spec.js +++ /dev/null @@ -1,50 +0,0 @@ -const expect = require('chai').expect; -const { host, protocol, waitForElement, switchFrame } = require('../../../helpers/testing-utils'); - -const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/banner.html?pbjs_debug=true`; -const CREATIVE_IFRAME_ID = 'google_ads_iframe_/19968336/header-bid-tag-0_0'; -const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="' + CREATIVE_IFRAME_ID + '"]'; - -const EXPECTED_TARGETING_KEYS = { - 'hb_format': 'banner', - 'hb_source': 'client', - 'hb_pb': '0.50', - 'hb_bidder': 'appnexus', - 'hb_format_appnexus': 'banner', - 'hb_source_appnexus': 'client', - 'hb_pb_appnexus': '0.50', - 'hb_bidder_appnexus': 'appnexus' -}; - -describe('Prebid.js Banner Ad Unit Test', function () { - this.retries(3); - before(function loadTestPage() { - browser.url(TEST_PAGE_URL); - browser.pause(3000); - try { - waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 3000); - } catch (e) { - // If creative Iframe didn't load, repeat the steps again! - // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js - loadTestPage(); - } - }); - - it('should load the targeting keys with correct values', function () { - const result = browser.execute(function () { - return window.pbjs.getAdserverTargeting('div-gpt-ad-1460505748561-1'); - }); - const targetingKeys = result['div-gpt-ad-1460505748561-1']; - - expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); - expect(targetingKeys.hb_adid).to.be.a('string'); - expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); - expect(targetingKeys.hb_size).to.satisfy((size) => size === '300x250' || '300x600'); - }); - - it('should render the Banner Ad on the page', function () { - switchFrame(CREATIVE_IFRAME_CSS_SELECTOR, CREATIVE_IFRAME_ID); - const ele = $('body > div[class="GoogleActiveViewElement"] > a > img'); - expect(ele.isExisting()).to.be.true; - }); -}); diff --git a/test/spec/e2e/instream/basic_instream_video_ad.spec.js b/test/spec/e2e/instream/basic_instream_video_ad.spec.js deleted file mode 100644 index b712f90bf63..00000000000 --- a/test/spec/e2e/instream/basic_instream_video_ad.spec.js +++ /dev/null @@ -1,48 +0,0 @@ -const expect = require('chai').expect; -const { host, protocol, waitForElement } = require('../../../helpers/testing-utils'); - -const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/instream.html?pbjs_debug=true`; -const ALERT_BOX_CSS_SELECTOR = 'div[id="event-window"] > p[id="statusText"]'; - -const EXPECTED_TARGETING_KEYS = { - hb_format: 'video', - hb_source: 'client', - hb_size: '640x480', - hb_pb: '10.00', - hb_bidder: 'appnexus', - hb_format_appnexus: 'video', - hb_source_appnexus: 'client', - hb_size_appnexus: '640x480', - hb_pb_appnexus: '10.00', - hb_bidder_appnexus: 'appnexus' -}; - -describe('Prebid.js Instream Video Ad Test', function () { - this.retries(3); - before(function loadTestPage() { - browser.url(TEST_PAGE_URL); - browser.pause(5000); - try { - waitForElement(ALERT_BOX_CSS_SELECTOR, 3000); - } catch (e) { - // If creative Iframe didn't load, repeat the steps again! - // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js - loadTestPage(); - } - }); - - it('should load the targeting keys with correct values', function () { - const result = browser.execute(function () { - return window.top.pbjs.getAdserverTargeting('video1'); - }); - - const targetingKeys = result['video1']; - expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); - expect(targetingKeys.hb_adid).to.be.a('string'); - expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); - expect(targetingKeys.hb_uuid).to.be.a('string'); - expect(targetingKeys.hb_cache_id).to.be.a('string'); - expect(targetingKeys.hb_uuid_appnexus).to.be.a('string'); - expect(targetingKeys.hb_cache_id_appnexus).to.be.a('string'); - }); -}); diff --git a/test/spec/e2e/longform/basic_w_bidderSettings.spec.js b/test/spec/e2e/longform/basic_w_bidderSettings.spec.js deleted file mode 100644 index d3443558316..00000000000 --- a/test/spec/e2e/longform/basic_w_bidderSettings.spec.js +++ /dev/null @@ -1,65 +0,0 @@ -const includes = require('core-js-pure/features/array/includes.js'); -const expect = require('chai').expect; -const { host, protocol, waitForElement } = require('../../../helpers/testing-utils'); - -const validDurations = ['15s', '30s']; -const validCats = ['Food', 'Retail Stores/Chains', 'Pet Food/Supplies', 'Travel/Hotels/Airlines', 'Automotive', 'Health Care Services']; -const validCpms = ['14.00', '13.00', '12.00', '9.00']; -const customKeyRegex = /\d{2}\.\d{2}_\d{1,3}_\d{2}s/; -const uuidRegex = /(\d|\w){8}-((\d|\w){4}-){3}(\d|\w){12}/; - -describe('longform ads not using requireExactDuration field', function() { - this.retries(3); - it('process the bids successfully', function() { - browser.url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_w_bidderSettings.html?pbjs_debug=true'); - browser.pause(7000); - - const loadPrebidBtnXpath = '//*[@id="loadPrebidRequestBtn"]'; - waitForElement(loadPrebidBtnXpath, 3000); - const prebidBtn = $(loadPrebidBtnXpath); - prebidBtn.click(); - browser.pause(5000); - - const listOfCpmsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[2]'; - const listOfCategoriesXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[3]'; - const listOfDurationsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[4]'; - - waitForElement(listOfCpmsXpath, 3000); - - let listOfCpms = $$(listOfCpmsXpath); - let listOfCats = $$(listOfCategoriesXpath); - let listOfDuras = $$(listOfDurationsXpath); - - expect(listOfCpms.length).to.equal(listOfCats.length).and.to.equal(listOfDuras.length); - for (let i = 0; i < listOfCpms.length; i++) { - let cpm = listOfCpms[i].getText(); - let cat = listOfCats[i].getText(); - let dura = listOfDuras[i].getText(); - expect(includes(validCpms, cpm), `Could not find CPM ${cpm} in accepted list`).to.equal(true); - expect(includes(validCats, cat), `Could not find Category ${cat} in accepted list`).to.equal(true); - expect(includes(validDurations, dura), `Could not find Duration ${dura} in accepted list`).to.equal(true); - } - }); - - it('formats the targeting keys properly', function () { - const listOfKeyElementsXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[1]'; - const listOfKeyValuesXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[2]'; - waitForElement(listOfKeyElementsXpath); - waitForElement(listOfKeyValuesXpath); - - let listOfKeyElements = $$(listOfKeyElementsXpath); - let listOfKeyValues = $$(listOfKeyValuesXpath); - - let firstKey = listOfKeyElements[0].getText(); - expect(firstKey).to.equal('hb_pb_cat_dur'); - - let firstKeyValue = listOfKeyValues[0].getText(); - expect(firstKeyValue).match(customKeyRegex); - - let lastKey = listOfKeyElements[listOfKeyElements.length - 1].getText(); - expect(lastKey).to.equal('hb_cache_id'); - - let lastKeyValue = listOfKeyValues[listOfKeyValues.length - 1].getText(); - expect(lastKeyValue).to.match(uuidRegex); - }); -}) diff --git a/test/spec/e2e/longform/basic_w_custom_adserver_translation.spec.js b/test/spec/e2e/longform/basic_w_custom_adserver_translation.spec.js deleted file mode 100644 index 9abe7295027..00000000000 --- a/test/spec/e2e/longform/basic_w_custom_adserver_translation.spec.js +++ /dev/null @@ -1,65 +0,0 @@ -const includes = require('core-js-pure/features/array/includes.js'); -const expect = require('chai').expect; -const { host, protocol, waitForElement } = require('../../../helpers/testing-utils'); - -const validDurations = ['15s', '30s']; -const validCats = ['Food', 'Retail Stores/Chains', 'Pet Food/Supplies', 'Travel/Hotels/Airlines', 'Automotive', 'Health Care Services']; -const validCpms = ['15.00', '14.00', '13.00', '10.00']; -const customKeyRegex = /\d{2}\.\d{2}_\d{1,3}_\d{2}s/; -const uuidRegex = /(\d|\w){8}-((\d|\w){4}-){3}(\d|\w){12}/; - -describe('longform ads using custom adserver translation file', function() { - this.retries(3); - it('process the bids successfully', function() { - browser.url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_w_custom_adserver_translation.html?pbjs_debug=true'); - browser.pause(7000); - - const loadPrebidBtnXpath = '//*[@id="loadPrebidRequestBtn"]'; - waitForElement(loadPrebidBtnXpath, 3000); - const prebidBtn = $(loadPrebidBtnXpath); - prebidBtn.click(); - browser.pause(5000); - - const listOfCpmsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[2]'; - const listOfCategoriesXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[3]'; - const listOfDurationsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[4]'; - - waitForElement(listOfCpmsXpath); - - let listOfCpms = $$(listOfCpmsXpath); - let listOfCats = $$(listOfCategoriesXpath); - let listOfDuras = $$(listOfDurationsXpath); - - expect(listOfCpms.length).to.equal(listOfCats.length).and.to.equal(listOfDuras.length); - for (let i = 0; i < listOfCpms.length; i++) { - let cpm = listOfCpms[i].getText(); - let cat = listOfCats[i].getText(); - let dura = listOfDuras[i].getText(); - expect(includes(validCpms, cpm), `Could not find CPM ${cpm} in accepted list`).to.equal(true); - expect(includes(validCats, cat), `Could not find Category ${cat} in accepted list`).to.equal(true); - expect(includes(validDurations, dura), `Could not find Duration ${dura} in accepted list`).to.equal(true); - } - }); - - it('formats the targeting keys properly', function () { - const listOfKeyElementsXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[1]'; - const listOfKeyValuesXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[2]'; - waitForElement(listOfKeyElementsXpath); - waitForElement(listOfKeyValuesXpath); - - let listOfKeyElements = $$(listOfKeyElementsXpath); - let listOfKeyValues = $$(listOfKeyValuesXpath); - - let firstKey = listOfKeyElements[0].getText(); - expect(firstKey).to.equal('hb_pb_cat_dur'); - - let firstKeyValue = listOfKeyValues[0].getText(); - expect(firstKeyValue).match(customKeyRegex); - - let lastKey = listOfKeyElements[listOfKeyElements.length - 1].getText(); - expect(lastKey).to.equal('hb_cache_id'); - - let lastKeyValue = listOfKeyValues[listOfKeyValues.length - 1].getText(); - expect(lastKeyValue).to.match(uuidRegex); - }); -}) diff --git a/test/spec/e2e/longform/basic_w_priceGran.spec.js b/test/spec/e2e/longform/basic_w_priceGran.spec.js deleted file mode 100644 index 5658595eef7..00000000000 --- a/test/spec/e2e/longform/basic_w_priceGran.spec.js +++ /dev/null @@ -1,65 +0,0 @@ -const includes = require('core-js-pure/features/array/includes.js'); -const expect = require('chai').expect; -const { host, protocol, waitForElement } = require('../../../helpers/testing-utils'); - -const validDurations = ['15s', '30s']; -const validCats = ['Food', 'Retail Stores/Chains', 'Pet Food/Supplies', 'Travel/Hotels/Airlines', 'Automotive', 'Health Care Services']; -const validCpms = ['15.00', '14.00', '13.00', '10.00']; -const customKeyRegex = /\d{2}\.\d{2}_\d{1,3}_\d{2}s/; -const uuidRegex = /(\d|\w){8}-((\d|\w){4}-){3}(\d|\w){12}/; - -describe('longform ads not using requireExactDuration field', function() { - this.retries(3); - it('process the bids successfully', function() { - browser.url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_w_priceGran.html?pbjs_debug=true'); - browser.pause(7000); - - const loadPrebidBtnXpath = '//*[@id="loadPrebidRequestBtn"]'; - waitForElement(loadPrebidBtnXpath); - const prebidBtn = $(loadPrebidBtnXpath); - prebidBtn.click(); - browser.pause(5000); - - const listOfCpmsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[2]'; - const listOfCategoriesXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[3]'; - const listOfDurationsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[4]'; - - waitForElement(listOfCpmsXpath); - - let listOfCpms = $$(listOfCpmsXpath); - let listOfCats = $$(listOfCategoriesXpath); - let listOfDuras = $$(listOfDurationsXpath); - - expect(listOfCpms.length).to.equal(listOfCats.length).and.to.equal(listOfDuras.length); - for (let i = 0; i < listOfCpms.length; i++) { - let cpm = listOfCpms[i].getText(); - let cat = listOfCats[i].getText(); - let dura = listOfDuras[i].getText(); - expect(includes(validCpms, cpm), `Could not find CPM ${cpm} in accepted list`).to.equal(true); - expect(includes(validCats, cat), `Could not find Category ${cat} in accepted list`).to.equal(true); - expect(includes(validDurations, dura), `Could not find Duration ${dura} in accepted list`).to.equal(true); - } - }); - - it('formats the targeting keys properly', function () { - const listOfKeyElementsXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[1]'; - const listOfKeyValuesXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[2]'; - waitForElement(listOfKeyElementsXpath); - waitForElement(listOfKeyValuesXpath); - - let listOfKeyElements = $$(listOfKeyElementsXpath); - let listOfKeyValues = $$(listOfKeyValuesXpath); - - let firstKey = listOfKeyElements[0].getText(); - expect(firstKey).to.equal('hb_pb_cat_dur'); - - let firstKeyValue = listOfKeyValues[0].getText(); - expect(firstKeyValue).match(customKeyRegex); - - let lastKey = listOfKeyElements[listOfKeyElements.length - 1].getText(); - expect(lastKey).to.equal('hb_cache_id'); - - let lastKeyValue = listOfKeyValues[listOfKeyValues.length - 1].getText(); - expect(lastKeyValue).to.match(uuidRegex); - }); -}) diff --git a/test/spec/e2e/longform/basic_w_requireExactDuration.spec.js b/test/spec/e2e/longform/basic_w_requireExactDuration.spec.js deleted file mode 100644 index 886daa3e320..00000000000 --- a/test/spec/e2e/longform/basic_w_requireExactDuration.spec.js +++ /dev/null @@ -1,65 +0,0 @@ -const includes = require('core-js-pure/features/array/includes.js'); -const expect = require('chai').expect; -const { host, protocol, waitForElement } = require('../../../helpers/testing-utils'); - -const validDurations = ['15s', '30s']; -const validCats = ['Food', 'Retail Stores/Chains', 'Pet Food/Supplies', 'Travel/Hotels/Airlines', 'Automotive', 'Health Care Services']; -const validCpms = ['15.00', '14.00', '13.00', '10.00']; -const customKeyRegex = /\d{2}\.\d{2}_\d{1,3}_\d{2}s/; -const uuidRegex = /(\d|\w){8}-((\d|\w){4}-){3}(\d|\w){12}/; - -describe('longform ads using requireExactDuration field', function() { - this.retries(3); - it('process the bids successfully', function() { - browser.url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_w_requireExactDuration.html?pbjs_debug=true'); - browser.pause(7000); - - const loadPrebidBtnXpath = '//*[@id="loadPrebidRequestBtn"]'; - waitForElement(loadPrebidBtnXpath); - const prebidBtn = $(loadPrebidBtnXpath); - prebidBtn.click(); - browser.pause(5000); - - const listOfCpmsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[2]'; - const listOfCategoriesXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[3]'; - const listOfDurationsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[4]'; - - waitForElement(listOfCpmsXpath); - - let listOfCpms = $$(listOfCpmsXpath); - let listOfCats = $$(listOfCategoriesXpath); - let listOfDuras = $$(listOfDurationsXpath); - - expect(listOfCpms.length).to.equal(listOfCats.length).and.to.equal(listOfDuras.length); - for (let i = 0; i < listOfCpms.length; i++) { - let cpm = listOfCpms[i].getText(); - let cat = listOfCats[i].getText(); - let dura = listOfDuras[i].getText(); - expect(includes(validCpms, cpm), `Could not find CPM ${cpm} in accepted list`).to.equal(true); - expect(includes(validCats, cat), `Could not find Category ${cat} in accepted list`).to.equal(true); - expect(includes(validDurations, dura), `Could not find Duration ${dura} in accepted list`).to.equal(true); - } - }); - - it('formats the targeting keys properly', function () { - const listOfKeyElementsXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[1]'; - const listOfKeyValuesXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[2]'; - waitForElement(listOfKeyElementsXpath); - waitForElement(listOfKeyValuesXpath); - - let listOfKeyElements = $$(listOfKeyElementsXpath); - let listOfKeyValues = $$(listOfKeyValuesXpath); - - let firstKey = listOfKeyElements[0].getText(); - expect(firstKey).to.equal('hb_pb_cat_dur'); - - let firstKeyValue = listOfKeyValues[0].getText(); - expect(firstKeyValue).match(customKeyRegex); - - let lastKey = listOfKeyElements[listOfKeyElements.length - 1].getText(); - expect(lastKey).to.equal('hb_cache_id'); - - let lastKeyValue = listOfKeyValues[listOfKeyValues.length - 1].getText(); - expect(lastKeyValue).to.match(uuidRegex); - }); -}) diff --git a/test/spec/e2e/longform/basic_wo_brandCategoryExclusion.spec.js b/test/spec/e2e/longform/basic_wo_brandCategoryExclusion.spec.js deleted file mode 100644 index e19f90b8c39..00000000000 --- a/test/spec/e2e/longform/basic_wo_brandCategoryExclusion.spec.js +++ /dev/null @@ -1,60 +0,0 @@ -const includes = require('core-js-pure/features/array/includes.js'); -const expect = require('chai').expect; -const { host, protocol, waitForElement } = require('../../../helpers/testing-utils'); - -const validDurations = ['15s', '30s']; -const validCpms = ['15.00', '14.00', '13.00', '10.00']; -const customKeyRegex = /\d{2}\.\d{2}_\d{2}s/; -const uuidRegex = /(\d|\w){8}-((\d|\w){4}-){3}(\d|\w){12}/; - -describe('longform ads without using brandCategoryExclusion', function() { - this.retries(3); - it('process the bids successfully', function() { - browser.url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_wo_brandCategoryExclusion.html?pbjs_debug=true'); - browser.pause(7000); - - const loadPrebidBtnXpath = '//*[@id="loadPrebidRequestBtn"]'; - waitForElement(loadPrebidBtnXpath); - const prebidBtn = $(loadPrebidBtnXpath); - prebidBtn.click(); - browser.pause(5000); - - const listOfCpmsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[2]'; - const listOfDurationsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[4]'; - - waitForElement(listOfCpmsXpath); - - let listOfCpms = $$(listOfCpmsXpath); - let listOfDuras = $$(listOfDurationsXpath); - - expect(listOfCpms.length).to.equal(listOfDuras.length); - for (let i = 0; i < listOfCpms.length; i++) { - let cpm = listOfCpms[i].getText(); - let dura = listOfDuras[i].getText(); - expect(includes(validCpms, cpm), `Could not find CPM ${cpm} in accepted list`).to.equal(true); - expect(includes(validDurations, dura), `Could not find Duration ${dura} in accepted list`).to.equal(true); - } - }); - - it('formats the targeting keys properly', function () { - const listOfKeyElementsXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[1]'; - const listOfKeyValuesXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[2]'; - waitForElement(listOfKeyElementsXpath); - waitForElement(listOfKeyValuesXpath); - - let listOfKeyElements = $$(listOfKeyElementsXpath); - let listOfKeyValues = $$(listOfKeyValuesXpath); - - let firstKey = listOfKeyElements[0].getText(); - expect(firstKey).to.equal('hb_pb_cat_dur'); - - let firstKeyValue = listOfKeyValues[0].getText(); - expect(firstKeyValue).match(customKeyRegex); - - let lastKey = listOfKeyElements[listOfKeyElements.length - 1].getText(); - expect(lastKey).to.equal('hb_cache_id'); - - let lastKeyValue = listOfKeyValues[listOfKeyValues.length - 1].getText(); - expect(lastKeyValue).to.match(uuidRegex); - }); -}) diff --git a/test/spec/e2e/longform/basic_wo_requireExactDuration.spec.js b/test/spec/e2e/longform/basic_wo_requireExactDuration.spec.js deleted file mode 100644 index cb1bcda93ff..00000000000 --- a/test/spec/e2e/longform/basic_wo_requireExactDuration.spec.js +++ /dev/null @@ -1,65 +0,0 @@ -const includes = require('core-js-pure/features/array/includes.js'); -const expect = require('chai').expect; -const { host, protocol, waitForElement } = require('../../../helpers/testing-utils'); - -const validDurations = ['15s', '30s']; -const validCats = ['Food', 'Retail Stores/Chains', 'Pet Food/Supplies', 'Travel/Hotels/Airlines', 'Automotive', 'Health Care Services']; -const validCpms = ['15.00', '14.00', '13.00', '10.00']; -const customKeyRegex = /\d{2}\.\d{2}_\d{1,3}_\d{2}s/; -const uuidRegex = /(\d|\w){8}-((\d|\w){4}-){3}(\d|\w){12}/; - -describe('longform ads not using requireExactDuration field', function() { - this.retries(3); - it('process the bids successfully', function() { - browser.url(protocol + '://' + host + ':9999/integrationExamples/longform/basic_wo_requireExactDuration.html?pbjs_debug=true'); - browser.pause(7000); - - const loadPrebidBtnXpath = '//*[@id="loadPrebidRequestBtn"]'; - waitForElement(loadPrebidBtnXpath); - const prebidBtn = $(loadPrebidBtnXpath); - prebidBtn.click(); - browser.pause(5000); - - const listOfCpmsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[2]'; - const listOfCategoriesXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[3]'; - const listOfDurationsXpath = '/html/body/div[1]/div/div/div/div[1]/div[2]/div/table/tbody/tr/td[4]'; - - waitForElement(listOfCpmsXpath); - - let listOfCpms = $$(listOfCpmsXpath); - let listOfCats = $$(listOfCategoriesXpath); - let listOfDuras = $$(listOfDurationsXpath); - - expect(listOfCpms.length).to.equal(listOfCats.length).and.to.equal(listOfDuras.length); - for (let i = 0; i < listOfCpms.length; i++) { - let cpm = listOfCpms[i].getText(); - let cat = listOfCats[i].getText(); - let dura = listOfDuras[i].getText(); - expect(includes(validCpms, cpm), `Could not find CPM ${cpm} in accepted list`).to.equal(true); - expect(includes(validCats, cat), `Could not find Category ${cat} in accepted list`).to.equal(true); - expect(includes(validDurations, dura), `Could not find Duration ${dura} in accepted list`).to.equal(true); - } - }); - - it('formats the targeting keys properly', function () { - const listOfKeyElementsXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[1]'; - const listOfKeyValuesXpath = '/html/body/div[1]/div/div/div/div[2]/div[2]/div/table/tbody/tr/td[2]'; - waitForElement(listOfKeyElementsXpath); - waitForElement(listOfKeyValuesXpath); - - let listOfKeyElements = $$(listOfKeyElementsXpath); - let listOfKeyValues = $$(listOfKeyValuesXpath); - - let firstKey = listOfKeyElements[0].getText(); - expect(firstKey).to.equal('hb_pb_cat_dur'); - - let firstKeyValue = listOfKeyValues[0].getText(); - expect(firstKeyValue).match(customKeyRegex); - - let lastKey = listOfKeyElements[listOfKeyElements.length - 1].getText(); - expect(lastKey).to.equal('hb_cache_id'); - - let lastKeyValue = listOfKeyValues[listOfKeyValues.length - 1].getText(); - expect(lastKeyValue).to.match(uuidRegex); - }); -}) diff --git a/test/spec/e2e/modules/e2e_bidderSettings.spec.js b/test/spec/e2e/modules/e2e_bidderSettings.spec.js deleted file mode 100644 index 2c0ba484654..00000000000 --- a/test/spec/e2e/modules/e2e_bidderSettings.spec.js +++ /dev/null @@ -1,61 +0,0 @@ -const expect = require('chai').expect; -const { host, protocol, waitForElement, switchFrame } = require('../../../helpers/testing-utils'); - -const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/bidderSettings.html?pbjs_debug=true`; -const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; - -const EXPECTED_TARGETING_KEYS = { - hb_source: 'client', - hb_source_appnexus: 'client', - hb_pb_appnexus: '10.00', - hb_native_title_appn: 'This is a Prebid Native Creative', - hb_native_linkurl: 'http://prebid.org/dev-docs/show-native-ads.html', - hb_format: 'native', - hb_native_brand: 'Prebid.org', - hb_size: '0x0', - hb_bidder_appnexus: 'appnexus', - hb_native_linkurl_ap: 'http://prebid.org/dev-docs/show-native-ads.html', - hb_native_title: 'This is a Prebid Native Creative', - hb_pb: '10.00', - hb_native_brand_appn: 'Prebid.org', - hb_bidder: 'appnexus', - hb_format_appnexus: 'native', - hb_size_appnexus: '0x0' -} - -describe('Prebid.js Bidder Settings Ad Unit Test', function () { - this.retries(3); - before(function loadTestPage() { - browser.url(TEST_PAGE_URL); - browser.pause(3000); - try { - waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 2000); - } catch (e) { - // If creative Iframe didn't load, repeat the steps again! - // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js - loadTestPage(); - } - }); - - it('should load the targeting keys with correct values', function () { - const result = browser.execute(function () { - return window.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); - }); - - const targetingKeys = result['/19968336/prebid_native_example_2']; - expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); - expect(targetingKeys.hb_adid).to.be.a('string'); - expect(targetingKeys.hb_native_body).to.be.a('string'); - expect(targetingKeys.hb_native_body_appne).to.be.a('string'); - expect(targetingKeys.hb_native_icon).to.be.a('string'); - expect(targetingKeys.hb_native_icon_appne).to.be.a('string'); - expect(targetingKeys.hb_native_image).to.be.a('string'); - expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); - }); - - it('should render the Banner Ad on the page', function () { - switchFrame(CREATIVE_IFRAME_CSS_SELECTOR); - const ele = $('body > div[class="GoogleActiveViewElement"] > a > img'); - expect(ele.isExisting()).to.be.true; - }); -}); diff --git a/test/spec/e2e/modules/e2e_consent_mgt_gdpr.spec.js b/test/spec/e2e/modules/e2e_consent_mgt_gdpr.spec.js deleted file mode 100644 index 4e0e7da49ea..00000000000 --- a/test/spec/e2e/modules/e2e_consent_mgt_gdpr.spec.js +++ /dev/null @@ -1,61 +0,0 @@ -const expect = require('chai').expect; -const { host, protocol, switchFrame, waitForElement } = require('../../../helpers/testing-utils'); - -const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/consent_mgt_gdpr.html?pbjs_debug=true`; -const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; - -const EXPECTED_TARGETING_KEYS = { - hb_source: 'client', - hb_source_appnexus: 'client', - hb_pb_appnexus: '10.00', - hb_native_title_appn: 'This is a Prebid Native Creative', - hb_native_linkurl: 'http://prebid.org/dev-docs/show-native-ads.html', - hb_format: 'native', - hb_native_brand: 'Prebid.org', - hb_size: '0x0', - hb_bidder_appnexus: 'appnexus', - hb_native_linkurl_ap: 'http://prebid.org/dev-docs/show-native-ads.html', - hb_native_title: 'This is a Prebid Native Creative', - hb_pb: '10.00', - hb_native_brand_appn: 'Prebid.org', - hb_bidder: 'appnexus', - hb_format_appnexus: 'native', - hb_size_appnexus: '0x0' -}; - -describe('Prebid.js GDPR Ad Unit Test', function () { - this.retries(3); - before(function loadTestPage() { - browser.url(TEST_PAGE_URL); - browser.pause(3000); - try { - waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 2000); - } catch (e) { - // If creative Iframe didn't load, repeat the steps again! - // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js - loadTestPage(); - } - }); - - it('should load the targeting keys with correct values', function () { - const result = browser.execute(function () { - return window.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); - }); - - const targetingKeys = result['/19968336/prebid_native_example_2']; - expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); - expect(targetingKeys.hb_adid).to.be.a('string'); - expect(targetingKeys.hb_native_body).to.be.a('string'); - expect(targetingKeys.hb_native_body_appne).to.be.a('string'); - expect(targetingKeys.hb_native_icon).to.be.a('string'); - expect(targetingKeys.hb_native_icon_appne).to.be.a('string'); - expect(targetingKeys.hb_native_image).to.be.a('string'); - expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); - }); - - it('should render the Banner Ad on the page', function () { - switchFrame(CREATIVE_IFRAME_CSS_SELECTOR); - const ele = $('body > div[class="GoogleActiveViewElement"] > a > img'); - expect(ele.isExisting()).to.be.true; - }); -}); diff --git a/test/spec/e2e/modules/e2e_currency.spec.js b/test/spec/e2e/modules/e2e_currency.spec.js deleted file mode 100644 index 8d8da5c5d45..00000000000 --- a/test/spec/e2e/modules/e2e_currency.spec.js +++ /dev/null @@ -1,61 +0,0 @@ -const expect = require('chai').expect; -const { host, protocol, waitForElement, switchFrame } = require('../../../helpers/testing-utils'); - -const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/currency.html?pbjs_debug=true`; -const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; - -const EXPECTED_TARGETING_KEYS = { - hb_source: 'client', - hb_source_appnexus: 'client', - hb_native_title_appn: 'This is a Prebid Native Creative', - hb_native_linkurl: 'http://prebid.org/dev-docs/show-native-ads.html', - hb_format: 'native', - hb_native_brand: 'Prebid.org', - hb_size: '0x0', - hb_bidder_appnexus: 'appnexus', - hb_native_linkurl_ap: 'http://prebid.org/dev-docs/show-native-ads.html', - hb_native_title: 'This is a Prebid Native Creative', - hb_native_brand_appn: 'Prebid.org', - hb_bidder: 'appnexus', - hb_format_appnexus: 'native', - hb_size_appnexus: '0x0' -} - -describe('Prebid.js Currency Ad Unit Test', function () { - this.retries(3); - before(function loadTestPage() { - browser.url(TEST_PAGE_URL); - browser.pause(5000); - try { - waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 2000); - } catch (e) { - // If creative Iframe didn't load, repeat the steps again! - // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js - loadTestPage(); - } - }); - - it('should load the targeting keys with correct values', function () { - const result = browser.execute(function () { - return window.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); - }); - - const targetingKeys = result['/19968336/prebid_native_example_2']; - expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); - expect(targetingKeys.hb_adid).to.be.a('string'); - expect(targetingKeys.hb_pb).to.be.a('string'); - expect(targetingKeys.hb_pb_appnexus).to.be.a('string'); - expect(targetingKeys.hb_native_body).to.be.a('string'); - expect(targetingKeys.hb_native_body_appne).to.be.a('string'); - expect(targetingKeys.hb_native_icon).to.be.a('string'); - expect(targetingKeys.hb_native_icon_appne).to.be.a('string'); - expect(targetingKeys.hb_native_image).to.be.a('string'); - expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); - }); - - it('should render the Banner Ad on the page', function () { - switchFrame(CREATIVE_IFRAME_CSS_SELECTOR); - const ele = $('body > div[class="GoogleActiveViewElement"] > a > img'); - expect(ele.isExisting()).to.be.true; - }); -}); diff --git a/test/spec/e2e/modules/e2e_priceGranularity.spec.js b/test/spec/e2e/modules/e2e_priceGranularity.spec.js deleted file mode 100644 index 157961d69ea..00000000000 --- a/test/spec/e2e/modules/e2e_priceGranularity.spec.js +++ /dev/null @@ -1,61 +0,0 @@ -const expect = require('chai').expect; -const { host, protocol, switchFrame, waitForElement } = require('../../../helpers/testing-utils'); - -const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/priceGranularity.html?pbjs_debug=true`; -const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; - -const EXPECTED_TARGETING_KEYS = { - hb_source: 'client', - hb_source_appnexus: 'client', - hb_pb_appnexus: '10.00', - hb_native_title_appn: 'This is a Prebid Native Creative', - hb_native_linkurl: 'http://prebid.org/dev-docs/show-native-ads.html', - hb_format: 'native', - hb_native_brand: 'Prebid.org', - hb_size: '0x0', - hb_bidder_appnexus: 'appnexus', - hb_native_linkurl_ap: 'http://prebid.org/dev-docs/show-native-ads.html', - hb_native_title: 'This is a Prebid Native Creative', - hb_pb: '10.00', - hb_native_brand_appn: 'Prebid.org', - hb_bidder: 'appnexus', - hb_format_appnexus: 'native', - hb_size_appnexus: '0x0' -} - -describe('Prebid.js Price Granularity Ad Unit Test', function () { - this.retries(3); - before(function loadTestPage() { - browser.url(TEST_PAGE_URL); - browser.pause(3000); - try { - waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 2000); - } catch (e) { - // If creative Iframe didn't load, repeat the steps again! - // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js - loadTestPage(); - } - }); - - it('should load the targeting keys with correct values', function () { - const result = browser.execute(function () { - return window.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); - }); - - const targetingKeys = result['/19968336/prebid_native_example_2']; - expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); - expect(targetingKeys.hb_adid).to.be.a('string'); - expect(targetingKeys.hb_native_body).to.be.a('string'); - expect(targetingKeys.hb_native_body_appne).to.be.a('string'); - expect(targetingKeys.hb_native_icon).to.be.a('string'); - expect(targetingKeys.hb_native_icon_appne).to.be.a('string'); - expect(targetingKeys.hb_native_image).to.be.a('string'); - expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); - }); - - it('should render the Banner Ad on the page', function () { - switchFrame(CREATIVE_IFRAME_CSS_SELECTOR); - const ele = $('body > div[class="GoogleActiveViewElement"] > a > img'); - expect(ele.isExisting()).to.be.true; - }); -}); diff --git a/test/spec/e2e/modules/e2e_sizeConfig.spec.js b/test/spec/e2e/modules/e2e_sizeConfig.spec.js deleted file mode 100644 index a37e6d49122..00000000000 --- a/test/spec/e2e/modules/e2e_sizeConfig.spec.js +++ /dev/null @@ -1,61 +0,0 @@ -const expect = require('chai').expect; -const { host, protocol, switchFrame, waitForElement } = require('../../../helpers/testing-utils'); - -const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/sizeConfig.html?pbjs_debug=true`; -const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; - -const EXPECTED_TARGETING_KEYS = { - hb_source: 'client', - hb_source_appnexus: 'client', - hb_pb_appnexus: '10.00', - hb_native_title_appn: 'This is a Prebid Native Creative', - hb_native_linkurl: 'http://prebid.org/dev-docs/show-native-ads.html', - hb_format: 'native', - hb_native_brand: 'Prebid.org', - hb_size: '0x0', - hb_bidder_appnexus: 'appnexus', - hb_native_linkurl_ap: 'http://prebid.org/dev-docs/show-native-ads.html', - hb_native_title: 'This is a Prebid Native Creative', - hb_pb: '10.00', - hb_native_brand_appn: 'Prebid.org', - hb_bidder: 'appnexus', - hb_format_appnexus: 'native', - hb_size_appnexus: '0x0' -} - -describe('Prebid.js Size Config Ad Unit Test', function () { - this.retries(3); - before(function loadTestPage() { - browser.url(TEST_PAGE_URL); - browser.pause(3000); - try { - waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 2000); - } catch (e) { - // If creative Iframe didn't load, repeat the steps again! - // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js - loadTestPage(); - } - }); - - it('should load the targeting keys with correct values', function () { - const result = browser.execute(function () { - return window.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); - }); - - const targetingKeys = result['/19968336/prebid_native_example_2']; - expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); - expect(targetingKeys.hb_adid).to.be.a('string'); - expect(targetingKeys.hb_native_body).to.be.a('string'); - expect(targetingKeys.hb_native_body_appne).to.be.a('string'); - expect(targetingKeys.hb_native_icon).to.be.a('string'); - expect(targetingKeys.hb_native_icon_appne).to.be.a('string'); - expect(targetingKeys.hb_native_image).to.be.a('string'); - expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); - }); - - it('should render the Banner Ad on the page', function () { - switchFrame(CREATIVE_IFRAME_CSS_SELECTOR); - const ele = $('body > div[class="GoogleActiveViewElement"] > a > img'); - expect(ele.isExisting()).to.be.true; - }); -}); diff --git a/test/spec/e2e/modules/e2e_userSync.spec.js b/test/spec/e2e/modules/e2e_userSync.spec.js deleted file mode 100644 index d945bfd3278..00000000000 --- a/test/spec/e2e/modules/e2e_userSync.spec.js +++ /dev/null @@ -1,61 +0,0 @@ -const expect = require('chai').expect; -const { host, protocol, switchFrame, waitForElement } = require('../../../helpers/testing-utils'); - -const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/userSync.html?pbjs_debug=true`; -const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; - -const EXPECTED_TARGETING_KEYS = { - hb_source: 'client', - hb_source_appnexus: 'client', - hb_pb_appnexus: '10.00', - hb_native_title_appn: 'This is a Prebid Native Creative', - hb_native_linkurl: 'http://prebid.org/dev-docs/show-native-ads.html', - hb_format: 'native', - hb_native_brand: 'Prebid.org', - hb_size: '0x0', - hb_bidder_appnexus: 'appnexus', - hb_native_linkurl_ap: 'http://prebid.org/dev-docs/show-native-ads.html', - hb_native_title: 'This is a Prebid Native Creative', - hb_pb: '10.00', - hb_native_brand_appn: 'Prebid.org', - hb_bidder: 'appnexus', - hb_format_appnexus: 'native', - hb_size_appnexus: '0x0' -} - -describe('Prebid.js User Sync Ad Unit Test', function () { - this.retries(3); - before(function loadTestPage() { - browser.url(TEST_PAGE_URL); - browser.pause(3000); - try { - waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 2000); - } catch (e) { - // If creative Iframe didn't load, repeat the steps again! - // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js - loadTestPage(); - } - }); - - it('should load the targeting keys with correct values', function () { - const result = browser.execute(function () { - return window.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); - }); - - const targetingKeys = result['/19968336/prebid_native_example_2']; - expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); - expect(targetingKeys.hb_adid).to.be.a('string'); - expect(targetingKeys.hb_native_body).to.be.a('string'); - expect(targetingKeys.hb_native_body_appne).to.be.a('string'); - expect(targetingKeys.hb_native_icon).to.be.a('string'); - expect(targetingKeys.hb_native_icon_appne).to.be.a('string'); - expect(targetingKeys.hb_native_image).to.be.a('string'); - expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); - }); - - it('should render the Banner Ad on the page', function () { - switchFrame(CREATIVE_IFRAME_CSS_SELECTOR); - const ele = $('body > div[class="GoogleActiveViewElement"] > a > img'); - expect(ele.isExisting()).to.be.true; - }); -}); diff --git a/test/spec/e2e/multi-bidder/e2e_multiple_bidders.spec.js b/test/spec/e2e/multi-bidder/e2e_multiple_bidders.spec.js deleted file mode 100644 index a67e2bd6db5..00000000000 --- a/test/spec/e2e/multi-bidder/e2e_multiple_bidders.spec.js +++ /dev/null @@ -1,67 +0,0 @@ -const expect = require('chai').expect; -const { host, protocol, waitForElement, switchFrame } = require('../../../helpers/testing-utils'); - -const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/multiple_bidders.html?pbjs_debug=true`; -const CREATIVE_BANNER_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/prebid_multiformat_test_0"]'; - -const EXPECTED_TARGETING_KEYS = { - hb_source: 'client', - hb_source_adasta: 'client', - hb_pb_adasta: '10.00', - hb_native_title_adas: 'This is a Prebid Native Creative', - hb_native_linkurl: 'http://prebid.org/dev-docs/show-multi-format-ads.html', - hb_format: 'native', - hb_native_brand: 'Prebid.org', - hb_size: '0x0', - hb_bidder_adasta: 'adasta', - hb_native_linkurl_ad: 'http://prebid.org/dev-docs/show-multi-format-ads.html', - hb_native_title: 'This is a Prebid Native Creative', - hb_pb: '10.00', - hb_native_brand_adas: 'Prebid.org', - hb_bidder: 'adasta', - hb_format_adasta: 'native', - hb_size_adasta: '0x0' -}; - -describe('Prebid.js Multiple Bidder Ad Unit Test', function () { - this.retries(3); - before(function loadTestPage() { - browser.url(TEST_PAGE_URL); - browser.pause(5000); - try { - waitForElement(CREATIVE_BANNER_CSS_SELECTOR, 3000); - } catch (e) { - // If creative Iframe didn't load, repeat the steps again! - // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js - loadTestPage(); - } - }); - - it('should load the targeting keys with correct values', function () { - const result = browser.execute(function () { - return window.pbjs.getAdserverTargeting('div-banner-native-2'); - }); - - const targetingKeys = result['div-banner-native-2']; - expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); - expect(targetingKeys.hb_adid).to.be.a('string'); - expect(targetingKeys.hb_native_image).to.be.a('string'); - expect(targetingKeys.hb_native_image_adas).to.be.a('string'); - expect(targetingKeys.hb_adid_adasta).to.be.a('string'); - }); - - it('should render the Banner Ad on the page', function () { - switchFrame(CREATIVE_BANNER_CSS_SELECTOR); - let ele = $('body > div[class="GoogleActiveViewElement"] > a > img'); - expect(ele.isExisting()).to.be.true; - }); - - // it('should render the native ad on the page', function () { - // browser.switchToParentFrame(); - // waitForElement(CREATIVE_NATIVE_CSS_SELECTOR, 3000); - // switchFrame(CREATIVE_NATIVE_CSS_SELECTOR); - - // let ele = $('body > div[class="GoogleActiveViewElement"] > div[class="card"]'); - // expect(ele.isExisting()).to.be.true; - // }); -}); diff --git a/test/spec/e2e/native/basic_native_ad.spec.js b/test/spec/e2e/native/basic_native_ad.spec.js deleted file mode 100644 index 418bcf271a3..00000000000 --- a/test/spec/e2e/native/basic_native_ad.spec.js +++ /dev/null @@ -1,61 +0,0 @@ -const expect = require('chai').expect; -const { host, protocol, switchFrame, waitForElement } = require('../../../helpers/testing-utils'); - -const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/native.html`; -const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/prebid_native_example_1_0"]'; - -const EXPECTED_TARGETING_KEYS = { - hb_source: 'client', - hb_source_appnexus: 'client', - hb_pb_appnexus: '10.00', - hb_native_title_appn: 'This is a Prebid Native Creative', - hb_native_linkurl: 'http://prebid.org/dev-docs/show-native-ads.html', - hb_format: 'native', - hb_native_brand: 'Prebid.org', - hb_size: '0x0', - hb_bidder_appnexus: 'appnexus', - hb_native_linkurl_ap: 'http://prebid.org/dev-docs/show-native-ads.html', - hb_native_title: 'This is a Prebid Native Creative', - hb_pb: '10.00', - hb_native_brand_appn: 'Prebid.org', - hb_bidder: 'appnexus', - hb_format_appnexus: 'native', - hb_size_appnexus: '0x0' -} - -describe('Prebid.js Native Ad Unit Test', function () { - this.retries(3); - before(function loadTestPage() { - browser.url(TEST_PAGE_URL); - browser.pause(3000); - try { - waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 2000); - } catch (e) { - // If creative Iframe didn't load, repeat the steps again! - // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js - loadTestPage(); - } - }); - - it('should load the targeting keys with correct values', function () { - const result = browser.execute(function () { - return window.pbjs.getAdserverTargeting('/19968336/prebid_native_example_2'); - }); - - const targetingKeys = result['/19968336/prebid_native_example_2']; - expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); - expect(targetingKeys.hb_adid).to.be.a('string'); - expect(targetingKeys.hb_native_body).to.be.a('string'); - expect(targetingKeys.hb_native_body_appne).to.be.a('string'); - expect(targetingKeys.hb_native_icon).to.be.a('string'); - expect(targetingKeys.hb_native_icon_appne).to.be.a('string'); - expect(targetingKeys.hb_native_image).to.be.a('string'); - expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); - }); - - it('should render the native ad on the page', function () { - switchFrame(CREATIVE_IFRAME_CSS_SELECTOR); - const ele = $('body > div[class="GoogleActiveViewElement"] > div[class="card"]'); - expect(ele.isExisting()).to.be.true; - }); -}); diff --git a/test/spec/e2e/outstream/basic_outstream_video_ad.spec.js b/test/spec/e2e/outstream/basic_outstream_video_ad.spec.js deleted file mode 100644 index 0240b094f5e..00000000000 --- a/test/spec/e2e/outstream/basic_outstream_video_ad.spec.js +++ /dev/null @@ -1,59 +0,0 @@ -const expect = require('chai').expect; -const { host, protocol, waitForElement, switchFrame } = require('../../../helpers/testing-utils'); - -const TEST_PAGE_URL = `${protocol}://${host}:9999/test/pages/outstream.html`; -const CREATIVE_IFRAME_CSS_SELECTOR = 'div[id="video_ad_unit_1"] > div:nth-child(2) > iframe:nth-child(1)'; - -const EXPECTED_TARGETING_KEYS = { - hb_cache_id: '', - hb_uuid: '', - hb_format: 'video', - hb_source: 'client', - hb_size: '640x480', - hb_pb: '10.00', - hb_bidder: 'appnexus', - hb_format_appnexus: 'video', - hb_source_appnexus: 'client', - hb_size_appnexus: '640x480', - hb_pb_appnexus: '10.00', - hb_bidder_appnexus: 'appnexus' -}; - -describe('Prebid.js Outstream Video Ad Test', function () { - this.retries(3); - before(function loadTestPage() { - browser.url(TEST_PAGE_URL); - browser.execute(function () { - return window.scrollBy(0, 300); - }); - browser.pause(3000); - try { - waitForElement(CREATIVE_IFRAME_CSS_SELECTOR, 5000); - } catch (e) { - // If creative Iframe didn't load, repeat the steps again! - // Due to some reason if the Ad server doesn't respond, the test case will time out after 60000 ms as defined in file wdio.conf.js - loadTestPage(); - } - }); - - it('should load the targeting keys with correct values', function () { - const result = browser.execute(function () { - return window.pbjs.getAdserverTargeting('video_ad_unit_2'); - }); - - const targetingKeys = result['video_ad_unit_2']; - expect(targetingKeys).to.include(EXPECTED_TARGETING_KEYS); - expect(targetingKeys.hb_adid).to.be.a('string'); - expect(targetingKeys.hb_adid_appnexus).to.be.a('string'); - }); - - it('should render the native ad on the page', function() { - // skipping test in Edge due to wdio bug: https://github.com/webdriverio/webdriverio/issues/3880 - // the iframe for the video does not have a name property and id is generated automatically... - if (browser.capabilities.browserName !== 'edge') { - switchFrame(CREATIVE_IFRAME_CSS_SELECTOR); - const ele = $('body > div[id*="an_video_ad_player"] > video'); - expect(ele.isExisting()).to.be.true; - } - }); -}); diff --git a/test/spec/integration/faker/fixtures.js b/test/spec/integration/faker/fixtures.js deleted file mode 100644 index a11bd126d61..00000000000 --- a/test/spec/integration/faker/fixtures.js +++ /dev/null @@ -1,42 +0,0 @@ -import faker from 'faker'; -import { makeSlot } from './googletag.js'; - -export function makeAdSlot(overrides = {}) { - return Object.assign(makeSlot( - { - code: overrides.code, - divId: overrides.divId - }), overrides); -} - -export function makeAdUnit(overrides = {}) { - return Object.assign({ - code: `ad-unit-code-${randomFive()}`, - sizes: [[300, 250], [300, 600]], - bids: [] - }, overrides); -} - -export function makeBidder(overrides = {}) { - let adapter; - adapter = Object.assign({ - bidder: `${faker.company.bsBuzz()}Media`, - params: { - abc: faker.random.alphaNumeric(10), - xyz: faker.random.number({ max: 10, precision: 2 }) - }, - callBids: sinon.spy() - }, overrides); - - return adapter; -} - -export function makeRequest(overrides = {}) { - return Object.assign({ - adUnits: overrides.adUnits, - bidsBackHandler: sinon.spy(), - timeout: 2000 - }, overrides); -} - -export function randomFive() { return faker.random.number({ min: 10000, max: 99999 }); } diff --git a/test/spec/integration/faker/googletag.js b/test/spec/integration/faker/googletag.js deleted file mode 100644 index 9d91bf315d9..00000000000 --- a/test/spec/integration/faker/googletag.js +++ /dev/null @@ -1,94 +0,0 @@ -import faker from 'faker'; -import { randomFive } from './fixtures.js'; - -var Slot = function Slot({ code, divId }) { - code = code || `ad-slot-code-${randomFive()}`; - divId = divId || `div-id-${randomFive()}`; - - var slot = { - targeting: [], - getSlotElementId: function getSlotElementId() { - return divId; - }, - - getAdUnitPath: function getAdUnitPath() { - return code; - }, - - setTargeting: function setTargeting(key, value) { - var obj = []; - obj[key] = value; - this.targeting.push(obj); - }, - - getTargeting: function getTargeting() { - return this.targeting; - }, - - getTargetingKeys: function getTargetingKeys() { - return []; - }, - - clearTargeting: function clearTargeting() { - return window.googletag.pubads().getSlots(); - } - }; - slot.spySetTargeting = sinon.spy(slot, 'setTargeting'); - return slot; -}; - -export function makeSlot() { - const slot = new Slot(...arguments); - window.googletag._slots.push(slot); - return slot; -} - -export function emitEvent(eventName, params) { - (window.googletag._callbackMap[eventName] || []).forEach(eventCb => eventCb({...params, eventName})); -} - -export function enable() { - window.googletag = { - _slots: [], - _callbackMap: {}, - pubads: function () { - var self = this; - return { - getSlots: function () { - return self._slots; - }, - - setSlots: function (slots) { - self._slots = slots; - }, - - setTargeting: function(key, arrayOfValues) { - self._targeting[key] = Array.isArray(arrayOfValues) ? arrayOfValues : [arrayOfValues]; - }, - - getTargeting: function(key) { - return self._targeting[key] || []; - }, - - getTargetingKeys: function() { - return Object.getOwnPropertyNames(self._targeting); - }, - - clearTargeting: function() { - self._targeting = {}; - }, - - addEventListener: function (eventName, cb) { - self._callbackMap[eventName] = self._callbackMap[eventName] || []; - self._callbackMap[eventName].push(cb); - } - }; - } - }; -} - -export function disable() { - window.googletag = undefined; -} - -enable(); diff --git a/test/spec/modules/1ad4goodBidAdapter_spec.js b/test/spec/modules/1ad4goodBidAdapter_spec.js deleted file mode 100644 index b9cd86a4cf7..00000000000 --- a/test/spec/modules/1ad4goodBidAdapter_spec.js +++ /dev/null @@ -1,548 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/1ad4goodBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import * as bidderFactory from 'src/adapters/bidderFactory.js'; -import { deepClone } from 'src/utils.js'; -import { config } from 'src/config.js'; - -const ENDPOINT = 'https://hb.1ad4good.org/prebid'; - -describe('AdforgoodAdapter', 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 () { - let bid = { - 'bidder': '1ad4good', - 'params': { - 'placementId': '10433394' - }, - '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(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'placementId': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [ - { - 'bidder': '1ad4good', - 'params': { - 'placementId': '10433394' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - it('should parse out private sizes', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - privateSizes: [300, 250] - } - } - ); - - const request = spec.buildRequests([bidRequest]); - 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}]); - }); - - it('should add source and verison to the tag', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.sdk).to.exist; - expect(payload.sdk).to.deep.equal({ - source: 'pbjs', - version: '$prebid.version$' - }); - }); - - it('should populate the ad_types array on all requests', function () { - ['banner', 'video'].forEach(type => { - const bidRequest = Object.assign({}, bidRequests[0]); - bidRequest.mediaTypes = {}; - bidRequest.mediaTypes[type] = {}; - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].ad_types).to.deep.equal([type]); - }); - }); - - it('should populate the ad_types array on outstream requests', function () { - const bidRequest = Object.assign({}, bidRequests[0]); - bidRequest.mediaTypes = {}; - bidRequest.mediaTypes.video = {context: 'outstream'}; - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].ad_types).to.deep.equal(['video']); - }); - - it('sends bid request to ENDPOINT via POST', function () { - const request = spec.buildRequests(bidRequests); - expect(request.url).to.equal(ENDPOINT); - expect(request.method).to.equal('POST'); - }); - - it('should attach valid video params to the tag', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - video: { - id: 123, - minduration: 100, - foobar: 'invalid' - } - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - expect(payload.tags[0].video).to.deep.equal({ - id: 123, - minduration: 100 - }); - }); - - it('should add video property when adUnit includes a renderer', function () { - const videoData = { - mediaTypes: { - video: { - context: 'outstream', - mimes: ['video/mp4'] - } - }, - params: { - placementId: '10433394', - video: { - skippable: true, - playback_method: ['auto_play_sound_off'] - } - } - }; - - let bidRequest1 = deepClone(bidRequests[0]); - bidRequest1 = Object.assign({}, bidRequest1, videoData, { - renderer: { - url: 'http://test.renderer.url', - render: function () {} - } - }); - - let bidRequest2 = deepClone(bidRequests[0]); - bidRequest2.adUnitCode = 'adUnit_code_2'; - bidRequest2 = Object.assign({}, bidRequest2, videoData); - - const request = spec.buildRequests([bidRequest1, bidRequest2]); - const payload = JSON.parse(request.data); - expect(payload.tags[0].video).to.deep.equal({ - skippable: true, - playback_method: ['auto_play_sound_off'], - custom_renderer_present: true - }); - expect(payload.tags[1].video).to.deep.equal({ - skippable: true, - playback_method: ['auto_play_sound_off'] - }); - }); - - it('should attach valid user params to the tag', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - user: { - externalUid: '123', - foobar: 'invalid' - } - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.user).to.exist; - expect(payload.user).to.deep.equal({ - externalUid: '123', - }); - }); - - // it('should always populated tags[].sizes with 1,1 for native if otherwise not defined', function () { - // let bidRequest = Object.assign({}, - // bidRequests[0], - // { - // mediaType: 'native', - // nativeParams: { - // image: { required: true } - // } - // } - // ); - // bidRequest.sizes = [[150, 100], [300, 250]]; - - // 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}]); - - // delete bidRequest.sizes; - - // request = spec.buildRequests([bidRequest]); - // payload = JSON.parse(request.data); - - // 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 () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - keywords: { - single: 'val', - singleArr: ['val'], - singleArrNum: [5], - multiValMixed: ['value1', 2, 'value3'], - singleValNum: 123, - emptyStr: '', - emptyArr: [''], - badValue: {'foo': 'bar'} // should be dropped - } - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].keywords).to.deep.equal([{ - 'key': 'single', - 'value': ['val'] - }, { - 'key': 'singleArr', - 'value': ['val'] - }, { - 'key': 'singleArrNum', - 'value': ['5'] - }, { - 'key': 'multiValMixed', - 'value': ['value1', '2', 'value3'] - }, { - 'key': 'singleValNum', - 'value': ['123'] - }, { - 'key': 'emptyStr' - }, { - 'key': 'emptyArr' - }]); - }); - - it('should add payment rules to the request', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - usePaymentRule: true - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].use_pmt_rule).to.equal(true); - }); - - it('should add gdpr consent information to the request', function () { - let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - let bidderRequest = { - 'bidderCode': '1ad4good', - 'auctionId': '1d1a030790a475', - 'bidderRequestId': '22edbae2733bf6', - 'timeout': 3000, - 'gdprConsent': { - consentString: consentString, - gdprApplies: true - } - }; - bidderRequest.bids = bidRequests; - - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.gdpr_consent).to.exist; - expect(payload.gdpr_consent.consent_string).to.exist.and.to.equal(consentString); - expect(payload.gdpr_consent.consent_required).to.exist.and.to.be.true; - }); - - it('supports sending hybrid mobile app parameters', function () { - let appRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - app: { - id: 'B1O2W3M4AN.com.prebid.webview', - geo: { - lat: 40.0964439, - lng: -75.3009142 - }, - device_id: { - idfa: '4D12078D-3246-4DA4-AD5E-7610481E7AE', // Apple advertising identifier - aaid: '38400000-8cf0-11bd-b23e-10b96e40000d', // Android advertising identifier - md5udid: '5756ae9022b2ea1e47d84fead75220c8', // MD5 hash of the ANDROID_ID - sha1udid: '4DFAA92388699AC6539885AEF1719293879985BF', // SHA1 hash of the ANDROID_ID - windowsadid: '750c6be243f1c4b5c9912b95a5742fc5' // Windows advertising identifier - } - } - } - } - ); - const request = spec.buildRequests([appRequest]); - const payload = JSON.parse(request.data); - expect(payload.app).to.exist; - expect(payload.app).to.deep.equal({ - appid: 'B1O2W3M4AN.com.prebid.webview' - }); - expect(payload.device.device_id).to.exist; - expect(payload.device.device_id).to.deep.equal({ - aaid: '38400000-8cf0-11bd-b23e-10b96e40000d', - idfa: '4D12078D-3246-4DA4-AD5E-7610481E7AE', - md5udid: '5756ae9022b2ea1e47d84fead75220c8', - sha1udid: '4DFAA92388699AC6539885AEF1719293879985BF', - windowsadid: '750c6be243f1c4b5c9912b95a5742fc5' - }); - expect(payload.device.geo).to.exist; - expect(payload.device.geo).to.deep.equal({ - lat: 40.0964439, - lng: -75.3009142 - }); - }); - - it('should add referer info to payload', function () { - const bidRequest = Object.assign({}, bidRequests[0]) - const bidderRequest = { - refererInfo: { - referer: 'http://example.com/page.html', - reachedTop: true, - numIframes: 2, - stack: [ - 'http://example.com/page.html', - 'http://example.com/iframe1.html', - 'http://example.com/iframe2.html' - ] - } - } - const request = spec.buildRequests([bidRequest], bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.referrer_detection).to.exist; - expect(payload.referrer_detection).to.deep.equal({ - rd_ref: 'http%3A%2F%2Fexample.com%2Fpage.html', - rd_top: true, - rd_ifs: 2, - rd_stk: bidderRequest.refererInfo.stack.map((url) => encodeURIComponent(url)).join(',') - }); - }); - }) - - describe('interpretResponse', function () { - let bfStub; - before(function() { - bfStub = sinon.stub(bidderFactory, 'getIabSubCategory'); - }); - - after(function() { - bfStub.restore(); - }); - - let response = { - 'version': '3.0.0', - 'tags': [ - { - 'uuid': '3db3773286ee59', - 'tag_id': 10433394, - 'auction_id': '4534722592064951574', - 'nobid': false, - 'no_ad_url': 'http://lax1-ib.adnxs.com/no-ad', - 'timeout_ms': 10000, - 'ad_profile_id': 27079, - 'ads': [ - { - 'content_source': 'rtb', - 'ad_type': 'banner', - 'buyer_member_id': 958, - 'creative_id': 29681110, - 'media_type_id': 1, - 'media_subtype_id': 1, - 'cpm': 0.5, - 'cpm_publisher_currency': 0.5, - 'publisher_currency_code': '$', - 'client_initiated_ad_counting': true, - 'viewability': { - 'config': '' - }, - 'rtb': { - 'banner': { - 'content': '', - 'width': 300, - 'height': 250 - }, - 'trackers': [ - { - 'impression_urls': [ - 'http://lax1-ib.adnxs.com/impression' - ], - 'video_events': {} - } - ] - } - } - ] - } - ] - }; - - it('should get correct bid response', function () { - let expectedResponse = [ - { - 'requestId': '3db3773286ee59', - 'cpm': 0.5, - 'creativeId': 29681110, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '', - 'mediaType': 'banner', - 'currency': 'USD', - 'ttl': 300, - 'netRevenue': true, - 'adUnitCode': 'code', - 'ads4good': { - 'buyerMemberId': 958 - } - } - ]; - let bidderRequest = { - bids: [{ - bidId: '3db3773286ee59', - adUnitCode: 'code' - }] - } - let result = spec.interpretResponse({ body: response }, {bidderRequest}); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('handles nobid responses', function () { - let response = { - 'version': '0.0.1', - 'tags': [{ - 'uuid': '84ab500420319d', - 'tag_id': 5976557, - 'auction_id': '297492697822162468', - 'nobid': true - }] - }; - let bidderRequest; - - let result = spec.interpretResponse({ body: response }, {bidderRequest}); - expect(result.length).to.equal(0); - }); - - it('handles non-banner media responses', function () { - let response = { - 'tags': [{ - 'uuid': '84ab500420319d', - 'ads': [{ - 'ad_type': 'video', - 'cpm': 0.500000, - 'notify_url': 'imptracker.com', - 'rtb': { - 'video': { - 'content': '' - } - }, - 'javascriptTrackers': '' - }] - }] - }; - let bidderRequest = { - bids: [{ - bidId: '84ab500420319d', - adUnitCode: 'code' - }] - } - - let 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'); - }); - - it('should add deal_priority and deal_code', function() { - let responseWithDeal = deepClone(response); - responseWithDeal.tags[0].ads[0].deal_priority = 'high'; - responseWithDeal.tags[0].ads[0].deal_code = '123'; - - let bidderRequest = { - bids: [{ - bidId: '3db3773286ee59', - adUnitCode: 'code' - }] - } - let result = spec.interpretResponse({ body: responseWithDeal }, {bidderRequest}); - expect(Object.keys(result[0].ads4good)).to.include.members(['buyerMemberId', 'dealPriority', 'dealCode']); - }); - - it('should add advertiser id', function() { - let responseAdvertiserId = deepClone(response); - responseAdvertiserId.tags[0].ads[0].advertiser_id = '123'; - - let bidderRequest = { - bids: [{ - bidId: '3db3773286ee59', - adUnitCode: 'code' - }] - } - let result = spec.interpretResponse({ body: responseAdvertiserId }, {bidderRequest}); - expect(Object.keys(result[0].meta)).to.include.members(['advertiserId']); - }) - }); -}); diff --git a/test/spec/modules/33acrossBidAdapter_spec.js b/test/spec/modules/33acrossBidAdapter_spec.js deleted file mode 100644 index b5443cdd5c2..00000000000 --- a/test/spec/modules/33acrossBidAdapter_spec.js +++ /dev/null @@ -1,1841 +0,0 @@ -import { expect } from 'chai'; - -import * as utils from 'src/utils.js'; -import { config } from 'src/config.js'; - -import { spec } from 'modules/33acrossBidAdapter.js'; - -function validateBuiltServerRequest(builtReq, expectedReq) { - expect(builtReq.url).to.equal(expectedReq.url); - expect(builtReq.options).to.deep.equal(expectedReq.options); - expect(JSON.parse(builtReq.data)).to.deep.equal( - JSON.parse(expectedReq.data) - ) -} - -describe('33acrossBidAdapter:', function () { - const BIDDER_CODE = '33across'; - const SITE_ID = 'sample33xGUID123456789'; - const PRODUCT_ID = 'siab'; - const END_POINT = 'https://ssc.33across.com/api/v1/hb'; - - let element, win; - let bidRequests; - let sandbox; - - function TtxRequestBuilder() { - const ttxRequest = { - imp: [{}], - site: { - id: SITE_ID - }, - id: 'b1', - regs: { - ext: { - gdpr: 0 - } - }, - ext: { - ttx: { - prebidStartedAt: 1, - caller: [{ - 'name': 'prebidjs', - 'version': '$prebid.version$' - }] - } - } - }; - - this.withBanner = () => { - Object.assign(ttxRequest.imp[0], { - banner: { - format: [ - { - w: 300, - h: 250 - }, - { - w: 728, - h: 90 - } - ], - ext: { - ttx: { - viewability: { - amount: 100 - } - } - } - } - }); - - return this; - }; - - this.withBannerSizes = this.withSizes = sizes => { - Object.assign(ttxRequest.imp[0].banner, { format: sizes }); - return this; - }; - - this.withVideo = (params = {}) => { - Object.assign(ttxRequest.imp[0], { - video: { - w: 300, - h: 250, - placement: 2, - ...params - } - }); - - return this; - }; - - this.withViewability = (viewability, format = 'banner') => { - Object.assign(ttxRequest.imp[0][format], { - ext: { - ttx: { viewability } - } - }); - return this; - }; - - this.withProduct = (prod = PRODUCT_ID) => { - Object.assign(ttxRequest.imp[0], { - ext: { - ttx: { - prod - } - } - }); - - return this; - }; - - this.withGdprConsent = (consent, gdpr) => { - Object.assign(ttxRequest, { - user: { - ext: { consent } - } - }); - Object.assign(ttxRequest, { - regs: { - ext: Object.assign( - {}, - ttxRequest.regs.ext, - { gdpr } - ) - } - }); - return this; - }; - - this.withUspConsent = (consent) => { - Object.assign(ttxRequest, { - regs: { - ext: Object.assign( - {}, - ttxRequest.regs.ext, - { us_privacy: consent } - ) - } - }); - - return this; - }; - - this.withSite = site => { - Object.assign(ttxRequest, { site }); - return this; - }; - - this.withPageUrl = pageUrl => { - Object.assign(ttxRequest.site, { - page: pageUrl - }); - - return this; - }; - - this.withSchain = schain => { - Object.assign(ttxRequest, { - source: { - ext: { - schain - } - } - }); - - return this; - }; - - this.withFloors = this.withFormatFloors = (mediaType, floors) => { - switch (mediaType) { - case 'banner': - const format = ttxRequest.imp[0].banner.format.map((fm, i) => { - return Object.assign(fm, { - ext: { - ttx: { - bidfloors: [ floors[i] ] - } - } - }) - }); - - ttxRequest.imp[0].banner.format = format; - break; - case 'video': - Object.assign(ttxRequest.imp[0].video, { - ext: { - ttx: { - bidfloors: floors - } - } - }); - break; - } - - return this; - }; - - this.withUserIds = (eids) => { - Object.assign(ttxRequest, { - user: { - ext: { - eids - } - } - }); - - return this; - } - - this.build = () => ttxRequest; - } - - function ServerRequestBuilder() { - const serverRequest = { - 'method': 'POST', - 'url': `${END_POINT}?guid=${SITE_ID}`, - 'data': null, - 'options': { - 'contentType': 'text/plain', - 'withCredentials': true - } - }; - - this.withData = data => { - serverRequest['data'] = JSON.stringify(data); - return this; - }; - - this.withUrl = url => { - serverRequest['url'] = url; - return this; - }; - - this.withOptions = options => { - serverRequest['options'] = options; - return this; - }; - - this.build = () => serverRequest; - } - - function BidRequestsBuilder() { - const bidRequests = [ - { - bidId: 'b1', - bidder: '33across', - bidderRequestId: 'b1a', - params: { - siteId: SITE_ID, - productId: PRODUCT_ID - }, - adUnitCode: 'div-id', - auctionId: 'r1', - mediaTypes: {}, - transactionId: 't1' - } - ]; - - this.withBanner = () => { - bidRequests[0].mediaTypes.banner = { - sizes: [ - [300, 250], - [728, 90] - ] - }; - - return this; - }; - - this.withProduct = (prod) => { - bidRequests[0].params.productId = prod; - - return this; - }; - - this.withVideo = (params) => { - bidRequests[0].mediaTypes.video = { - playerSize: [[300, 250]], - context: 'outstream', - ...params - }; - - return this; - } - - this.withUserIds = (eids) => { - bidRequests[0].userIdAsEids = eids; - - return this; - }; - - this.build = () => bidRequests; - } - - beforeEach(function() { - element = { - x: 0, - y: 0, - - width: 0, - height: 0, - - getBoundingClientRect: () => { - return { - width: element.width, - height: element.height, - - left: element.x, - top: element.y, - right: element.x + element.width, - bottom: element.y + element.height - }; - } - }; - win = { - document: { - visibilityState: 'visible' - }, - - innerWidth: 800, - innerHeight: 600 - }; - - bidRequests = ( - new BidRequestsBuilder() - .withBanner() - .build() - ); - - sandbox = sinon.sandbox.create(); - sandbox.stub(Date, 'now').returns(1); - sandbox.stub(document, 'getElementById').withArgs('div-id').returns(element); - sandbox.stub(utils, 'getWindowTop').returns(win); - sandbox.stub(utils, 'getWindowSelf').returns(win); - }); - - afterEach(function() { - sandbox.restore(); - }); - - describe('isBidRequestValid:', function() { - context('basic validation', function() { - it('returns true for valid guid values', function() { - // NOTE: We ignore whitespace at the start and end since - // in our experience these are common typos - const validGUIDs = [ - `${SITE_ID}`, - `${SITE_ID} `, - ` ${SITE_ID}`, - ` ${SITE_ID} ` - ]; - - validGUIDs.forEach((siteId) => { - const bid = { - bidder: '33across', - params: { - siteId - } - }; - - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - }); - - it('returns false for invalid guid values', function() { - const invalidGUIDs = [ - undefined, - 'siab' - ]; - - invalidGUIDs.forEach((siteId) => { - const bid = { - bidder: '33across', - params: { - siteId - } - }; - - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - }); - - context('banner validation', function() { - it('returns true when banner mediaType does not exist', function() { - const bid = { - bidder: '33across', - params: { - siteId: 'cxBE0qjUir6iopaKkGJozW' - } - }; - - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - - it('returns true when banner sizes are defined', function() { - const bid = { - bidder: '33across', - mediaTypes: { - banner: { - sizes: [[250, 300]] - } - }, - params: { - siteId: 'cxBE0qjUir6iopaKkGJozW' - } - }; - - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - - it('returns false when banner sizes are invalid', function() { - const invalidSizes = [ - undefined, - '16:9', - 300, - 'foo' - ]; - - invalidSizes.forEach((sizes) => { - const bid = { - bidder: '33across', - mediaTypes: { - banner: { - sizes - } - }, - params: { - siteId: 'cxBE0qjUir6iopaKkGJozW' - } - }; - - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - }); - - context('video validation', function() { - beforeEach(function() { - // Basic Valid BidRequest - this.bid = { - bidder: '33across', - mediaTypes: { - video: { - playerSize: [[300, 50]], - context: 'outstream', - mimes: ['foo', 'bar'], - protocols: [1, 2] - } - }, - params: { - siteId: `${SITE_ID}` - } - }; - }); - - it('returns true when video mediaType does not exist', function() { - const bid = { - bidder: '33across', - params: { - siteId: `${SITE_ID}` - } - }; - - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - - it('returns true when valid video mediaType is defined', function() { - expect(spec.isBidRequestValid(this.bid)).to.be.true; - }); - - it('returns false when video context is not defined', function() { - delete this.bid.mediaTypes.video.context; - - expect(spec.isBidRequestValid(this.bid)).to.be.false; - }); - - it('returns false when video playserSize is invalid', function() { - const invalidSizes = [ - undefined, - '16:9', - 300, - 'foo' - ]; - - invalidSizes.forEach((playerSize) => { - this.bid.mediaTypes.video.playerSize = playerSize; - expect(spec.isBidRequestValid(this.bid)).to.be.false; - }); - }); - - it('returns false when video mimes is invalid', function() { - const invalidMimes = [ - undefined, - 'foo', - 1, - [] - ] - - invalidMimes.forEach((mimes) => { - this.bid.mediaTypes.video.mimes = mimes; - expect(spec.isBidRequestValid(this.bid)).to.be.false; - }) - }); - - it('returns false when video protocols is invalid', function() { - const invalidMimes = [ - undefined, - 'foo', - 1, - [] - ] - - invalidMimes.forEach((protocols) => { - this.bid.mediaTypes.video.protocols = protocols; - expect(spec.isBidRequestValid(this.bid)).to.be.false; - }) - }); - - it('returns false when video placement is invalid', function() { - const invalidPlacement = [ - [], - '1', - {}, - 'foo' - ]; - - invalidPlacement.forEach((placement) => { - this.bid.mediaTypes.video.placement = placement; - expect(spec.isBidRequestValid(this.bid)).to.be.false; - }); - }); - - it('returns false when video startdelay is invalid for instream context', function() { - const bidRequests = ( - new BidRequestsBuilder() - .withVideo({context: 'instream', protocols: [1, 2], mimes: ['foo', 'bar']}) - .build() - ); - - const invalidStartdelay = [ - [], - '1', - {}, - 'foo' - ]; - - invalidStartdelay.forEach((startdelay) => { - bidRequests[0].mediaTypes.video.startdelay = startdelay; - expect(spec.isBidRequestValid(bidRequests[0])).to.be.false; - }); - }); - - it('returns true when video startdelay is invalid for outstream context', function() { - const bidRequests = ( - new BidRequestsBuilder() - .withVideo({context: 'outstream', protocols: [1, 2], mimes: ['foo', 'bar']}) - .build() - ); - - const invalidStartdelay = [ - [], - '1', - {}, - 'foo' - ]; - - invalidStartdelay.forEach((startdelay) => { - bidRequests[0].mediaTypes.video.startdelay = startdelay; - expect(spec.isBidRequestValid(bidRequests[0])).to.be.true; - }); - }); - }) - }); - - describe('buildRequests:', function() { - context('when element is fully in view', function() { - it('returns 100', function() { - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .withViewability({amount: 100}) - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - - Object.assign(element, { width: 600, height: 400 }); - - const [ buildRequest ] = spec.buildRequests(bidRequests); - validateBuiltServerRequest(buildRequest, serverRequest); - }); - }); - - context('when element is out of view', function() { - it('returns 0', function() { - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .withViewability({amount: 0}) - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - - Object.assign(element, { x: -300, y: 0, width: 207, height: 320 }); - - const [ buildRequest ] = spec.buildRequests(bidRequests); - validateBuiltServerRequest(buildRequest, serverRequest); - }); - }); - - context('when element is partially in view', function() { - it('returns percentage', function() { - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .withViewability({amount: 75}) - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - - Object.assign(element, { width: 800, height: 800 }); - - const [ buildRequest ] = spec.buildRequests(bidRequests); - validateBuiltServerRequest(buildRequest, serverRequest); - }); - }); - - context('when width or height of the element is zero', function() { - it('try to use alternative values', function() { - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .withSizes([{ w: 800, h: 2400 }]) - .withViewability({amount: 25}) - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - - Object.assign(element, { width: 0, height: 0 }); - bidRequests[0].mediaTypes.banner.sizes = [[800, 2400]]; - - const [ buildRequest ] = spec.buildRequests(bidRequests); - validateBuiltServerRequest(buildRequest, serverRequest); - }); - }); - - context('when nested iframes', function() { - it('returns \'nm\'', function() { - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .withViewability({amount: spec.NON_MEASURABLE}) - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - - Object.assign(element, { width: 600, height: 400 }); - - utils.getWindowTop.restore(); - utils.getWindowSelf.restore(); - sandbox.stub(utils, 'getWindowTop').returns({}); - sandbox.stub(utils, 'getWindowSelf').returns(win); - - const [ buildRequest ] = spec.buildRequests(bidRequests); - validateBuiltServerRequest(buildRequest, serverRequest); - }); - }); - - context('when tab is inactive', function() { - it('returns 0', function() { - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .withViewability({amount: 0}) - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - - Object.assign(element, { width: 600, height: 400 }); - - utils.getWindowTop.restore(); - win.document.visibilityState = 'hidden'; - sandbox.stub(utils, 'getWindowTop').returns(win); - - const [ buildRequest ] = spec.buildRequests(bidRequests); - validateBuiltServerRequest(buildRequest, serverRequest); - }); - }); - - context('when gdpr consent data exists', function() { - let bidderRequest; - - beforeEach(function() { - bidderRequest = { - gdprConsent: { - consentString: 'foobarMyPreference', - gdprApplies: true - } - } - }); - - it('returns corresponding server requests with gdpr consent data', function() { - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .withGdprConsent('foobarMyPreference', 1) - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - - it('returns corresponding test server requests with gdpr consent data', function() { - sandbox.stub(config, 'getConfig').callsFake(() => { - return { - 'url': 'https://foo.com/hb/' - } - }); - - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .withGdprConsent('foobarMyPreference', 1) - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .withUrl('https://foo.com/hb/') - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - }); - - context('when gdpr consent data does not exist', function() { - let bidderRequest; - - beforeEach(function() { - bidderRequest = {}; - }); - - it('returns corresponding server requests with default gdpr consent data', function() { - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - - it('returns corresponding test server requests with default gdpr consent data', function() { - sandbox.stub(config, 'getConfig').callsFake(() => { - return { - 'url': 'https://foo.com/hb/' - } - }); - - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .withUrl('https://foo.com/hb/') - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - }); - - context('when us_privacy consent data exists', function() { - let bidderRequest; - - beforeEach(function() { - bidderRequest = { - uspConsent: 'foo' - } - }); - - it('returns corresponding server requests with us_privacy consent data', function() { - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .withUspConsent('foo') - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - - it('returns corresponding test server requests with us_privacy consent data', function() { - sandbox.stub(config, 'getConfig').callsFake(() => { - return { - 'url': 'https://foo.com/hb/' - } - }); - - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .withUspConsent('foo') - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .withUrl('https://foo.com/hb/') - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - }); - - context('when us_privacy consent data does not exist', function() { - let bidderRequest; - - beforeEach(function() { - bidderRequest = {}; - }); - - it('returns corresponding server requests with default us_privacy data', function() { - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - - it('returns corresponding test server requests with default us_privacy consent data', function() { - sandbox.stub(config, 'getConfig').callsFake(() => { - return { - 'url': 'https://foo.com/hb/' - } - }); - - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .withUrl('https://foo.com/hb/') - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - }); - - context('when referer value is available', function() { - it('returns corresponding server requests with site.page set', function() { - const bidderRequest = { - refererInfo: { - referer: 'http://foo.com/bar' - } - }; - - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .withPageUrl('http://foo.com/bar') - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - }); - - context('when referer value is not available', function() { - it('returns corresponding server requests without site.page set', function() { - const bidderRequest = { - refererInfo: {} - }; - - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - }); - - context('when there is schain object in the bidRequest', function() { - it('builds request with schain info in source', function() { - const schainValues = [ - { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'bidderA.com', - 'sid': '00001', - 'hp': 1 - } - ] - }, - { - 'ver': '1.0', - 'complete': 1, - }, - { - 'ver': '1.0', - 'complete': 1, - 'nodes': [] - }, - { - 'ver': '1.0', - 'complete': '1', - 'nodes': [ - { - 'asi': 'bidderA.com', - 'sid': '00001', - 'hp': 1 - } - ] - } - ]; - - schainValues.forEach((schain) => { - bidRequests[0].schain = schain; - - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .withSchain(schain) - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - }); - }); - - context('when there no schain object is passed', function() { - it('does not set source field', function() { - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .build(); - - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - }); - - context('when price floor module is not enabled for banner in bidRequest', function() { - it('does not set any bidfloors in ttxRequest', function() { - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - }); - - context('when price floor module is enabled for banner in bidRequest', function() { - it('does not set any bidfloors in ttxRequest if there is no floor', function() { - bidRequests[0].getFloor = () => ({}); - - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .build(); - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - - it('sets bidfloors in ttxRequest if there is a floor', function() { - bidRequests[0].getFloor = ({size, currency, mediaType}) => { - const floor = (size[0] === 300 && size[1] === 250) ? 1.0 : 0.10 - return ( - { - floor, - currency: 'USD' - } - ); - }; - - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .withFormatFloors('banner', [ 1.0, 0.10 ]) - .build(); - - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - }); - - context('when mediaType has video only and context is instream', function() { - it('builds instream request with default params', function() { - const bidRequests = ( - new BidRequestsBuilder() - .withVideo({context: 'instream'}) - .build() - ); - - const ttxRequest = new TtxRequestBuilder() - .withVideo() - .withProduct('instream') - .build(); - - ttxRequest.imp[0].video.placement = 1; - ttxRequest.imp[0].video.startdelay = 0; - - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - - it('builds instream request with params passed', function() { - const bidRequests = ( - new BidRequestsBuilder() - .withVideo({context: 'instream', startdelay: -2}) - .build() - ); - - const ttxRequest = new TtxRequestBuilder() - .withVideo({startdelay: -2, placement: 1}) - .withProduct('instream') - .build(); - - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - expect(JSON.parse(builtServerRequest.data)).to.deep.equal(ttxRequest); - }); - }); - - context('when mediaType has video only and context is outstream', function() { - it('builds siab request with video only with default params', function() { - const bidRequests = ( - new BidRequestsBuilder() - .withVideo({context: 'outstream'}) - .build() - ); - - const ttxRequest = new TtxRequestBuilder() - .withVideo() - .withProduct('siab') - .build(); - - ttxRequest.imp[0].video.placement = 2; - - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - - it('builds siab request with video params passed', function() { - const bidRequests = ( - new BidRequestsBuilder() - .withVideo({context: 'outstream', placement: 3, playbackmethod: [2]}) - .build() - ); - - const ttxRequest = new TtxRequestBuilder() - .withVideo({placement: 3, playbackmethod: [2]}) - .withProduct('siab') - .build(); - - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - }); - - context('when mediaType has banner only', function() { - it('builds default siab request', function() { - const bidRequests = ( - new BidRequestsBuilder() - .withBanner() - .build() - ); - - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct('siab') - .build(); - - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - - it('builds default inview request when product is set as such', function() { - const bidRequests = ( - new BidRequestsBuilder() - .withBanner() - .withProduct('inview') - .build() - ); - - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct('inview') - .build(); - - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - }); - - context('when mediaType has banner and video', function() { - it('builds siab request with banner and outstream video', function() { - const bidRequests = ( - new BidRequestsBuilder() - .withBanner() - .withVideo({context: 'outstream'}) - .build() - ); - - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withVideo() - .withProduct('siab') - .build(); - - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - - it('builds siab request with banner and outstream video even when context is instream', function() { - const bidRequests = ( - new BidRequestsBuilder() - .withBanner() - .withVideo({context: 'instream'}) - .build() - ); - - const ttxRequest = new TtxRequestBuilder() - .withBanner() - .withVideo() - .withProduct('siab') - .build(); - - ttxRequest.imp[0].video.placement = 2; - - const serverRequest = new ServerRequestBuilder() - .withData(ttxRequest) - .build(); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - validateBuiltServerRequest(builtServerRequest, serverRequest); - }); - }); - - context('when price floor module is enabled for video in bidRequest', function() { - it('does not set any bidfloors in video if there is no floor', function() { - const bidRequests = ( - new BidRequestsBuilder() - .withVideo({context: 'outstream'}) - .build() - ); - - bidRequests[0].getFloor = () => ({}); - - const ttxRequest = new TtxRequestBuilder() - .withVideo() - .withProduct() - .build(); - - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - expect(JSON.parse(builtServerRequest.data)).to.deep.equal(ttxRequest); - }); - - it('sets bidfloors in video if there is a floor', function() { - const bidRequests = ( - new BidRequestsBuilder() - .withVideo({context: 'outstream'}) - .build() - ); - - bidRequests[0].getFloor = ({size, currency, mediaType}) => { - const floor = (mediaType === 'video') ? 1.0 : 0.10 - return ( - { - floor, - currency: 'USD' - } - ); - }; - - const ttxRequest = new TtxRequestBuilder() - .withVideo() - .withProduct() - .withFloors('video', [ 1.0 ]) - .build(); - - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - expect(JSON.parse(builtServerRequest.data)).to.deep.equal(ttxRequest); - }); - }); - - context('when user ID data exists as userIdAsEids Array in bidRequest', function() { - it('passes userIds in eids field in ORTB request', function() { - const eids = [ - { - 'source': 'x-device-vendor-x.com', - 'uids': [ - { - 'id': 'yyy', - 'atype': 1 - }, - { - 'id': 'zzz', - 'atype': 1 - }, - { - 'id': 'DB700403-9A24-4A4B-A8D5-8A0B4BE777D2', - 'atype': 2 - } - ], - 'ext': { - 'foo': 'bar' - } - } - ]; - - const bidRequests = ( - new BidRequestsBuilder() - .withUserIds(eids) - .build() - ); - - const ttxRequest = new TtxRequestBuilder() - .withUserIds(eids) - .withProduct() - .build(); - - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - expect(JSON.parse(builtServerRequest.data)).to.deep.equal(ttxRequest); - }); - - it('does not validate eids ORTB', function() { - const eids = [1, 2, 3]; - - const bidRequests = ( - new BidRequestsBuilder() - .withUserIds(eids) - .build() - ); - - const ttxRequest = new TtxRequestBuilder() - .withUserIds(eids) - .withProduct() - .build(); - - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - expect(JSON.parse(builtServerRequest.data)).to.deep.equal(ttxRequest); - }); - }); - - context('when user IDs do not exist under the userIdAsEids field in bidRequest as a non-empty Array', function() { - it('does not pass user IDs in the bidRequest ORTB', function() { - const eidsScenarios = [ - 'foo', - [], - {foo: 1} - ]; - - eidsScenarios.forEach((eids) => { - const bidRequests = ( - new BidRequestsBuilder() - .withUserIds(eids) - .build() - ); - bidRequests.userId = { - 'vendorx': { - 'source': 'x-device-vendor-x.com', - 'uids': [ - { - 'id': 'yyy', - 'atype': 1 - }, - { - 'id': 'zzz', - 'atype': 1 - }, - { - 'id': 'DB700403-9A24-4A4B-A8D5-8A0B4BE777D2', - 'atype': 2 - } - ], - 'ext': { - 'foo': 'bar' - } - } - }; - - const ttxRequest = new TtxRequestBuilder() - .withProduct() - .build(); - - const [ builtServerRequest ] = spec.buildRequests(bidRequests, {}); - - expect(JSON.parse(builtServerRequest.data)).to.deep.equal(ttxRequest); - }); - }); - }); - }); - - describe('interpretResponse', function() { - let ttxRequest, serverRequest; - - beforeEach(function() { - ttxRequest = new TtxRequestBuilder() - .withBanner() - .withProduct() - .withSite({ - id: SITE_ID, - page: 'https://test-url.com' - }) - .build(); - serverRequest = new ServerRequestBuilder() - .withUrl('https://staging-ssc.33across.com/api/v1/hb') - .withData(ttxRequest) - .withOptions({ - contentType: 'text/plain', - withCredentials: false - }) - .build(); - }); - - context('when exactly one bid is returned', function() { - it('interprets and returns the single banner bid response', function() { - const serverResponse = { - cur: 'USD', - ext: {}, - id: 'b1', - seatbid: [ - { - bid: [{ - id: '1', - adm: '

I am an ad

', - crid: 1, - h: 250, - w: 300, - price: 0.0938, - adomain: ['advertiserdomain.com'] - }] - } - ] - }; - const bidResponse = { - requestId: 'b1', - bidderCode: BIDDER_CODE, - cpm: 0.0938, - width: 300, - height: 250, - ad: '

I am an ad

', - ttl: 60, - creativeId: 1, - mediaType: 'banner', - currency: 'USD', - netRevenue: true, - meta: { - advertiserDomains: ['advertiserdomain.com'] - } - }; - - expect(spec.interpretResponse({ body: serverResponse }, serverRequest)).to.deep.equal([bidResponse]); - }); - - it('interprets and returns the single video bid response', function() { - const videoBid = ''; - const serverResponse = { - cur: 'USD', - ext: {}, - id: 'b1', - seatbid: [ - { - bid: [{ - id: '1', - adm: videoBid, - ext: { - ttx: { - mediaType: 'video', - vastType: 'xml' - } - }, - crid: 1, - h: 250, - w: 300, - price: 0.0938, - adomain: ['advertiserdomain.com'] - }] - } - ] - }; - const bidResponse = { - requestId: 'b1', - bidderCode: BIDDER_CODE, - cpm: 0.0938, - width: 300, - height: 250, - ad: videoBid, - ttl: 60, - creativeId: 1, - mediaType: 'video', - currency: 'USD', - netRevenue: true, - vastXml: videoBid, - meta: { - advertiserDomains: ['advertiserdomain.com'] - } - }; - - expect(spec.interpretResponse({ body: serverResponse }, serverRequest)).to.deep.equal([bidResponse]); - }); - - context('when the list of advertiser domains for block list checking is empty', function() { - it('doesn\'t include the empty list in the interpreted response', function() { - const serverResponse = { - cur: 'USD', - ext: {}, - id: 'b1', - seatbid: [ - { - bid: [{ - id: '1', - adm: '

I am an ad

', - crid: 1, - h: 250, - w: 300, - price: 0.0938, - adomain: [] // Empty list - }] - } - ] - }; - - // Bid response below doesn't contain meta.advertiserDomains - const bidResponse = { - requestId: 'b1', - bidderCode: BIDDER_CODE, - cpm: 0.0938, - width: 300, - height: 250, - ad: '

I am an ad

', - ttl: 60, - creativeId: 1, - mediaType: 'banner', - currency: 'USD', - netRevenue: true - }; - - expect(spec.interpretResponse({ body: serverResponse }, serverRequest)).to.deep.equal([bidResponse]); - }); - }); - }); - - context('when no bids are returned', function() { - it('interprets and returns empty array', function() { - const serverResponse = { - cur: 'USD', - ext: {}, - id: 'b1', - seatbid: [] - }; - - expect(spec.interpretResponse({ body: serverResponse }, serverRequest)).to.deep.equal([]); - }); - }); - - context('when more than one bids are returned', function() { - it('interprets and returns the the first bid of the first seatbid', function() { - const serverResponse = { - cur: 'USD', - ext: {}, - id: 'b1', - seatbid: [ - { - bid: [{ - id: '1', - adm: '

I am an ad

', - crid: 1, - h: 250, - w: 300, - price: 0.0940 - }, - { - id: '2', - adm: '

I am an ad

', - crid: 2, - h: 250, - w: 300, - price: 0.0938 - } - ] - }, - { - bid: [{ - id: '3', - adm: '

I am an ad

', - crid: 3, - h: 250, - w: 300, - price: 0.0938 - }] - } - ] - }; - const bidResponse = { - requestId: 'b1', - bidderCode: BIDDER_CODE, - cpm: 0.0940, - width: 300, - height: 250, - ad: '

I am an ad

', - ttl: 60, - creativeId: 1, - mediaType: 'banner', - currency: 'USD', - netRevenue: true - }; - - expect(spec.interpretResponse({ body: serverResponse }, serverRequest)).to.deep.equal([bidResponse]); - }); - }); - }); - - describe('getUserSyncs', function() { - let syncs; - - beforeEach(function() { - syncs = [ - { - type: 'iframe', - url: 'https://ssc-cms.33across.com/ps/?m=xch&rt=html&ru=deb&id=id1' - }, - { - type: 'iframe', - url: 'https://ssc-cms.33across.com/ps/?m=xch&rt=html&ru=deb&id=id2' - }, - ]; - bidRequests = [ - { - bidId: 'b1', - bidder: '33across', - bidderRequestId: 'b1a', - params: { - siteId: 'id1', - productId: 'foo' - }, - adUnitCode: 'div-id', - auctionId: 'r1', - mediaTypes: { - banner: { - sizes: [ - [300, 250] - ] - } - }, - transactionId: 't1' - }, - { - bidId: 'b2', - bidder: '33across', - bidderRequestId: 'b2a', - params: { - siteId: 'id2', - productId: 'foo' - }, - adUnitCode: 'div-id', - auctionId: 'r1', - mediaTypes: { - banner: { - sizes: [ - [300, 250] - ] - } - }, - transactionId: 't2' - } - ]; - }); - - context('when iframe is not enabled', function() { - it('returns empty sync array', function() { - const syncOptions = {}; - - spec.buildRequests(bidRequests); - - expect(spec.getUserSyncs(syncOptions)).to.deep.equal([]); - }); - }); - - context('when iframe is enabled', function() { - let syncOptions; - beforeEach(function() { - syncOptions = { - iframeEnabled: true - }; - }); - - context('when there is no gdpr consent data', function() { - it('returns sync urls with undefined consent string as param', function() { - spec.buildRequests(bidRequests); - - const syncResults = spec.getUserSyncs(syncOptions, {}, undefined); - const expectedSyncs = [ - { - type: 'iframe', - url: `${syncs[0].url}&gdpr_consent=undefined&us_privacy=undefined` - }, - { - type: 'iframe', - url: `${syncs[1].url}&gdpr_consent=undefined&us_privacy=undefined` - } - ] - - expect(syncResults).to.deep.equal(expectedSyncs); - }) - }); - - context('when gdpr applies but there is no consent string', function() { - it('returns sync urls with undefined consent string as param and gdpr=1', function() { - spec.buildRequests(bidRequests); - - const syncResults = spec.getUserSyncs(syncOptions, {}, {gdprApplies: true}); - const expectedSyncs = [ - { - type: 'iframe', - url: `${syncs[0].url}&gdpr_consent=undefined&us_privacy=undefined&gdpr=1` - }, - { - type: 'iframe', - url: `${syncs[1].url}&gdpr_consent=undefined&us_privacy=undefined&gdpr=1` - } - ]; - - expect(syncResults).to.deep.equal(expectedSyncs); - }); - }); - - context('when gdpr applies and there is consent string', function() { - it('returns sync urls with gdpr_consent=consent string as param and gdpr=1', function() { - spec.buildRequests(bidRequests); - - const syncResults = spec.getUserSyncs(syncOptions, {}, {gdprApplies: true, consentString: 'consent123A'}); - const expectedSyncs = [ - { - type: 'iframe', - url: `${syncs[0].url}&gdpr_consent=consent123A&us_privacy=undefined&gdpr=1` - }, - { - type: 'iframe', - url: `${syncs[1].url}&gdpr_consent=consent123A&us_privacy=undefined&gdpr=1` - } - ]; - - expect(syncResults).to.deep.equal(expectedSyncs); - }); - }); - - context('when gdpr does not apply and there is no consent string', function() { - it('returns sync urls with undefined consent string as param and gdpr=0', function() { - spec.buildRequests(bidRequests); - - const syncResults = spec.getUserSyncs(syncOptions, {}, {gdprApplies: false}); - const expectedSyncs = [ - { - type: 'iframe', - url: `${syncs[0].url}&gdpr_consent=undefined&us_privacy=undefined&gdpr=0` - }, - { - type: 'iframe', - url: `${syncs[1].url}&gdpr_consent=undefined&us_privacy=undefined&gdpr=0` - } - ]; - expect(syncResults).to.deep.equal(expectedSyncs); - }); - }); - - context('when gdpr is unknown and there is consent string', function() { - it('returns sync urls with only consent string as param', function() { - spec.buildRequests(bidRequests); - - const syncResults = spec.getUserSyncs(syncOptions, {}, {consentString: 'consent123A'}); - const expectedSyncs = [ - { - type: 'iframe', - url: `${syncs[0].url}&gdpr_consent=consent123A&us_privacy=undefined` - }, - { - type: 'iframe', - url: `${syncs[1].url}&gdpr_consent=consent123A&us_privacy=undefined` - } - ]; - expect(syncResults).to.deep.equal(expectedSyncs); - }); - }); - - context('when gdpr does not apply and there is consent string (yikes!)', function() { - it('returns sync urls with consent string as param and gdpr=0', function() { - spec.buildRequests(bidRequests); - - const syncResults = spec.getUserSyncs(syncOptions, {}, {gdprApplies: false, consentString: 'consent123A'}); - const expectedSyncs = [ - { - type: 'iframe', - url: `${syncs[0].url}&gdpr_consent=consent123A&us_privacy=undefined&gdpr=0` - }, - { - type: 'iframe', - url: `${syncs[1].url}&gdpr_consent=consent123A&us_privacy=undefined&gdpr=0` - } - ]; - expect(syncResults).to.deep.equal(expectedSyncs); - }); - }); - - context('when there is no usPrivacy data', function() { - it('returns sync urls with undefined consent string as param', function() { - spec.buildRequests(bidRequests); - - const syncResults = spec.getUserSyncs(syncOptions, {}); - const expectedSyncs = [ - { - type: 'iframe', - url: `${syncs[0].url}&gdpr_consent=undefined&us_privacy=undefined` - }, - { - type: 'iframe', - url: `${syncs[1].url}&gdpr_consent=undefined&us_privacy=undefined` - } - ] - - expect(syncResults).to.deep.equal(expectedSyncs); - }) - }); - - context('when there is usPrivacy data', function() { - it('returns sync urls with consent string as param', function() { - spec.buildRequests(bidRequests); - - const syncResults = spec.getUserSyncs(syncOptions, {}, {}, 'foo'); - const expectedSyncs = [ - { - type: 'iframe', - url: `${syncs[0].url}&gdpr_consent=undefined&us_privacy=foo` - }, - { - type: 'iframe', - url: `${syncs[1].url}&gdpr_consent=undefined&us_privacy=foo` - } - ]; - - expect(syncResults).to.deep.equal(expectedSyncs); - }); - }); - - context('when user sync is invoked without a bid request phase', function() { - it('results in an empty syncs array', function() { - const syncResults = spec.getUserSyncs(syncOptions, {}, {}, 'foo'); - - expect(syncResults).to.deep.equal([]); - }); - }); - }); - }); -}); diff --git a/test/spec/modules/7xbidBidAdapter_spec.js b/test/spec/modules/7xbidBidAdapter_spec.js deleted file mode 100644 index bed2c604349..00000000000 --- a/test/spec/modules/7xbidBidAdapter_spec.js +++ /dev/null @@ -1,160 +0,0 @@ -import {expect} from 'chai'; -import {spec, _getUrlVars} from 'modules/7xbidBidAdapter.js'; -import * as utils from 'src/utils.js'; - -const BASE_URI = '//bidder.7xbid.com/api/v1/prebid/banner' -const NATIVE_BASE_URI = '//bidder.7xbid.com/api/v1/prebid/native' - -describe('7xbid adapter', function() { - let bidRequests; - let nativeBidRequests; - - beforeEach(function() { - bidRequests = [ - { - bidder: '7xbid', - params: { - placementId: 1425292, - currency: 'USD' - } - } - ] - - nativeBidRequests = [ - { - bidder: '7xbid', - params: { - placementId: 1429695, - currency: 'USD' - }, - nativeParams: { - title: { - required: true, - len: 80 - }, - image: { - required: true, - sizes: [150, 50] - }, - sponsoredBy: { - required: true - } - } - } - ] - }) - describe('isBidRequestValid', function () { - it('valid bid case', function () { - let validBid = { - bidder: '7xbid', - params: { - placementId: 1425292, - currency: 'USD' - } - } - let isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(true); - }); - - it('invalid bid case: placementId is not passed', function() { - let validBid = { - bidder: '7xbid', - params: { - } - } - let isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(false); - }) - - it('invalid bid case: currency is not support', function() { - let validBid = { - bidder: '7xbid', - params: { - placementId: 1108295, - currency: 'AUD' - } - } - let isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(false); - }) - }) - - describe('buildRequests', function () { - it('sends bid request to ENDPOINT via GET', function () { - const request = spec.buildRequests(bidRequests)[0]; - expect(request.url).to.equal(BASE_URI); - expect(request.method).to.equal('GET'); - }); - - it('sends native bid request to ENDPOINT via GET', function () { - const request = spec.buildRequests(nativeBidRequests)[0]; - expect(request.url).to.equal(NATIVE_BASE_URI); - expect(request.method).to.equal('GET'); - }); - - it('buildRequests function should not modify original bidRequests object', function () { - let originalBidRequests = utils.deepClone(bidRequests); - let request = spec.buildRequests(bidRequests); - expect(bidRequests).to.deep.equal(originalBidRequests); - }); - - it('buildRequests function should not modify original nativeBidRequests object', function () { - let originalBidRequests = utils.deepClone(nativeBidRequests); - let request = spec.buildRequests(nativeBidRequests); - expect(nativeBidRequests).to.deep.equal(originalBidRequests); - }); - - it('Request params check', function() { - let request = spec.buildRequests(bidRequests)[0]; - const data = _getUrlVars(request.data) - expect(parseInt(data.placementid)).to.exist.and.to.equal(bidRequests[0].params.placementId); - expect(data.cur).to.exist.and.to.equal(bidRequests[0].params.currency); - }) - - it('Native request params check', function() { - let request = spec.buildRequests(nativeBidRequests)[0]; - const data = _getUrlVars(request.data) - expect(parseInt(data.placementid)).to.exist.and.to.equal(nativeBidRequests[0].params.placementId); - expect(data.cur).to.exist.and.to.equal(nativeBidRequests[0].params.currency); - }) - }) - - describe('interpretResponse', function () { - let response = { - 1425292: - { - 'creativeId': '', - 'cur': 'USD', - 'price': 0.0920, - 'width': 300, - 'height': 250, - 'requestid': '2e42361a6172bf', - 'adm': '' - } - } - - it('should get correct bid response', function () { - let expectedResponse = [ - { - 'requestId': '2e42361a6172bf', - 'cpm': 0.0920, - 'width': 300, - 'height': 250, - 'netRevenue': true, - 'currency': 'USD', - 'creativeId': '', - 'ttl': 700, - 'ad': '' - } - ]; - let request = spec.buildRequests(bidRequests)[0]; - let 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); - expect(result[0].ad).to.not.equal(null); - expect(result[0].currency).to.equal('USD'); - expect(result[0].netRevenue).to.equal(true); - }); - }) -}) diff --git a/test/spec/modules/a4gBidAdapter_spec.js b/test/spec/modules/a4gBidAdapter_spec.js deleted file mode 100644 index cb05fa62ab6..00000000000 --- a/test/spec/modules/a4gBidAdapter_spec.js +++ /dev/null @@ -1,219 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/a4gBidAdapter.js'; -import * as utils from 'src/utils.js'; - -describe('a4gAdapterTests', function () { - describe('bidRequestValidity', function () { - it('bidRequest with zoneId and deliveryUrl params', function () { - expect(spec.isBidRequestValid({ - bidder: 'a4g', - params: { - zoneId: 59304, - deliveryUrl: 'http://dev01.ad4game.com/v1/bid' - } - })).to.equal(true); - }); - - it('bidRequest with only zoneId', function () { - expect(spec.isBidRequestValid({ - bidder: 'a4g', - params: { - zoneId: 59304 - } - })).to.equal(true); - }); - - it('bidRequest with only deliveryUrl', function () { - expect(spec.isBidRequestValid({ - bidder: 'a4g', - params: { - deliveryUrl: 'http://dev01.ad4game.com/v1/bid' - } - })).to.equal(false); - }); - }); - - describe('bidRequest', function () { - const DEFAULT_OPTION = { - refererInfo: { - referer: 'https://www.prebid.org', - canonicalUrl: 'https://www.prebid.org/the/link/to/the/page' - } - }; - - const bidRequests = [{ - 'bidder': 'a4g', - 'bidId': '51ef8751f9aead', - 'params': { - 'zoneId': 59304, - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - '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' - }, { - 'bidder': 'a4g', - 'bidId': '51ef8751f9aead', - 'params': { - 'zoneId': 59354, - 'deliveryUrl': '//dev01.ad4game.com/v1/bid' - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 50], [300, 250], [300, 600]] - } - }, - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757' - }]; - - it('bidRequest method', function () { - const request = spec.buildRequests(bidRequests, DEFAULT_OPTION); - expect(request.method).to.equal('GET'); - }); - - it('bidRequest url', function () { - const request = spec.buildRequests(bidRequests, DEFAULT_OPTION); - expect(request.url).to.match(new RegExp(`${bidRequests[1].params.deliveryUrl}`)); - }); - - it('bidRequest data', function () { - const request = spec.buildRequests(bidRequests, DEFAULT_OPTION); - expect(request.data).to.exist; - }); - - it('bidRequest zoneIds', function () { - const request = spec.buildRequests(bidRequests, DEFAULT_OPTION); - expect(request.data.zoneId).to.equal('59304;59354'); - }); - - it('bidRequest gdpr consent', function () { - const consentString = 'consentString'; - const bidderRequest = { - bidderCode: 'a4g', - auctionId: '18fd8b8b0bd757', - bidderRequestId: '418b37f85e772c', - timeout: 3000, - gdprConsent: { - consentString: consentString, - gdprApplies: true - }, - refererInfo: { - referer: 'https://www.prebid.org', - canonicalUrl: 'https://www.prebid.org/the/link/to/the/page' - } - }; - - const request = spec.buildRequests(bidRequests, bidderRequest); - - expect(request.data.gdpr).to.exist; - expect(request.data.gdpr.applies).to.exist.and.to.be.true; - expect(request.data.gdpr.consent).to.exist.and.to.equal(consentString); - }); - }); - - describe('interpretResponse', function () { - const bidRequest = [{ - 'bidder': 'a4g', - 'bidId': '51ef8751f9aead', - 'params': { - 'zoneId': 59304, - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 50], [300, 250], [300, 600]] - } - }, - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757' - }]; - - const bidResponse = { - body: [{ - 'id': '51ef8751f9aead', - 'ad': 'test ad', - 'width': 320, - 'height': 250, - 'cpm': 5.2, - 'crid': '111' - }], - headers: {} - }; - - it('should get correct bid response for banner ad', function () { - const expectedParse = [ - { - requestId: '51ef8751f9aead', - cpm: 5.2, - creativeId: '111', - width: 320, - height: 250, - ad: 'test ad', - currency: 'USD', - ttl: 120, - netRevenue: true - } - ]; - const result = spec.interpretResponse(bidResponse, bidRequest); - expect(result[0]).to.deep.equal(expectedParse[0]); - }); - - it('should set creativeId to default value if not provided', function () { - const bidResponseWithoutCrid = utils.deepClone(bidResponse); - delete bidResponseWithoutCrid.body[0].crid; - const expectedParse = [ - { - requestId: '51ef8751f9aead', - cpm: 5.2, - creativeId: '51ef8751f9aead', - width: 320, - height: 250, - ad: 'test ad', - currency: 'USD', - ttl: 120, - netRevenue: true - } - ]; - const result = spec.interpretResponse(bidResponseWithoutCrid, bidRequest); - expect(result[0]).to.deep.equal(expectedParse[0]); - }) - - it('required keys', function () { - const result = spec.interpretResponse(bidResponse, bidRequest); - - let requiredKeys = [ - 'requestId', - 'creativeId', - 'adId', - 'cpm', - 'width', - 'height', - 'currency', - 'netRevenue', - 'ttl', - 'ad' - ]; - - let resultKeys = Object.keys(result[0]); - resultKeys.forEach(function(key) { - expect(requiredKeys.indexOf(key) !== -1).to.equal(true); - }); - }) - - it('adId should not be equal to requestId', function () { - const result = spec.interpretResponse(bidResponse, bidRequest); - - expect(result[0].requestId).to.not.equal(result[0].adId); - }) - }); -}); diff --git a/test/spec/modules/aardvarkBidAdapter_spec.js b/test/spec/modules/aardvarkBidAdapter_spec.js deleted file mode 100644 index 9671f961407..00000000000 --- a/test/spec/modules/aardvarkBidAdapter_spec.js +++ /dev/null @@ -1,569 +0,0 @@ -import { expect } from 'chai'; -import * as utils from 'src/utils.js'; -import { spec, resetUserSync } from 'modules/aardvarkBidAdapter.js'; - -describe('aardvarkAdapterTest', function () { - describe('forming valid bidRequests', function () { - it('should accept valid bidRequests', function () { - expect(spec.isBidRequestValid({ - bidder: 'aardvark', - params: { - ai: 'xiby', - sc: 'TdAx', - }, - sizes: [[300, 250]] - })).to.equal(true); - }); - - it('should reject invalid bidRequests', function () { - expect(spec.isBidRequestValid({ - bidder: 'aardvark', - params: { - ai: 'xiby', - }, - sizes: [[300, 250]] - })).to.equal(false); - }); - }); - - describe('executing network requests', function () { - const bidRequests = [{ - bidder: 'aardvark', - params: { - ai: 'xiby', - sc: 'TdAx', - }, - adUnitCode: 'aaa', - transactionId: '1b8389fe-615c-482d-9f1a-177fb8f7d5b0', - sizes: [300, 250], - bidId: '1abgs362e0x48a8', - bidderRequestId: '70deaff71c281d', - auctionId: '5c66da22-426a-4bac-b153-77360bef5337', - userId: { tdid: 'eff98622-b5fd-44fa-9a49-6e846922d532' } - }, - { - bidder: 'aardvark', - params: { - ai: 'xiby', - sc: 'RAZd', - host: 'adzone.pub.com' - }, - adUnitCode: 'bbb', - transactionId: '193995b4-7122-4739-959b-2463282a138b', - sizes: [[800, 600]], - bidId: '22aidtbx5eabd9', - bidderRequestId: '70deaff71c281d', - auctionId: 'e97cafd0-ebfc-4f5c-b7c9-baa0fd335a4a' - }]; - - const bidderRequest = { - refererInfo: { - referer: 'https://example.com' - } - }; - - it('should use HTTP GET method', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - requests.forEach(function (requestItem) { - expect(requestItem.method).to.equal('GET'); - }); - }); - - it('should call the correct bidRequest url', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests.length).to.equal(1); - expect(requests[0].url).to.match(new RegExp('^https:\/\/adzone.pub.com/xiby/TdAx_RAZd/aardvark\?')); - }); - - it('should have correct data', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests.length).to.equal(1); - expect(requests[0].data.version).to.equal(1); - expect(requests[0].data.jsonp).to.equal(false); - expect(requests[0].data.TdAx).to.equal('1abgs362e0x48a8'); - expect(requests[0].data.rtkreferer).to.not.be.undefined; - expect(requests[0].data.RAZd).to.equal('22aidtbx5eabd9'); - }); - - it('should have tdid, it is available in bidRequest', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - requests.forEach(function (requestItem) { - expect(requestItem.data.tdid).to.equal('eff98622-b5fd-44fa-9a49-6e846922d532'); - }); - }); - }); - - describe('splitting multi-auction ad units into own requests', function () { - const bidRequests = [{ - bidder: 'aardvark', - params: { - ai: 'Toby', - sc: 'TdAx', - categories: ['cat1', 'cat2'] - }, - adUnitCode: 'aaa', - transactionId: '1b8389fe-615c-482d-9f1a-177fb8f7d5b0', - sizes: [300, 250], - bidId: '1abgs362e0x48a8', - bidderRequestId: '70deaff71c281d', - auctionId: '5c66da22-426a-4bac-b153-77360bef5337' - }, - { - bidder: 'aardvark', - params: { - ai: 'xiby', - sc: 'RAZd', - host: 'adzone.pub.com' - }, - adUnitCode: 'bbb', - transactionId: '193995b4-7122-4739-959b-2463282a138b', - sizes: [[800, 600]], - bidId: '22aidtbx5eabd9', - bidderRequestId: '70deaff71c281d', - auctionId: 'e97cafd0-ebfc-4f5c-b7c9-baa0fd335a4a' - }]; - - const bidderRequest = { - refererInfo: { - referer: 'https://example.com' - } - }; - - it('should use HTTP GET method', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - requests.forEach(function (requestItem) { - expect(requestItem.method).to.equal('GET'); - }); - }); - - it('should call the correct bidRequest urls for each auction', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests[0].url).to.match(new RegExp('^https:\/\/bidder.rtk.io/Toby/TdAx/aardvark\?')); - expect(requests[0].data.categories.length).to.equal(2); - expect(requests[1].url).to.match(new RegExp('^https:\/\/adzone.pub.com/xiby/RAZd/aardvark\?')); - }); - - it('should have correct data', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests.length).to.equal(2); - expect(requests[0].data.version).to.equal(1); - expect(requests[0].data.jsonp).to.equal(false); - expect(requests[0].data.TdAx).to.equal('1abgs362e0x48a8'); - expect(requests[0].data.rtkreferer).to.not.be.undefined; - expect(requests[0].data.RAZd).to.be.undefined; - expect(requests[1].data.version).to.equal(1); - expect(requests[1].data.jsonp).to.equal(false); - expect(requests[1].data.TdAx).to.be.undefined; - expect(requests[1].data.rtkreferer).to.not.be.undefined; - expect(requests[1].data.RAZd).to.equal('22aidtbx5eabd9'); - }); - - it('should have no tdid, it is not available in bidRequest', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - requests.forEach(function (requestItem) { - expect(requestItem.data.tdid).to.be.undefined; - }); - }); - }); - - describe('GDPR conformity', function () { - const bidRequests = [{ - bidder: 'aardvark', - params: { - ai: 'xiby', - sc: 'TdAx', - }, - adUnitCode: 'aaa', - transactionId: '1b8389fe-615c-482d-9f1a-177fb8f7d5b0', - sizes: [300, 250], - bidId: '1abgs362e0x48a8', - bidderRequestId: '70deaff71c281d', - auctionId: '5c66da22-426a-4bac-b153-77360bef5337' - }]; - - const bidderRequest = { - gdprConsent: { - consentString: 'awefasdfwefasdfasd', - gdprApplies: true - }, - refererInfo: { - referer: 'https://example.com' - } - }; - - it('should transmit correct data', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests.length).to.equal(1); - expect(requests[0].data.gdpr).to.equal(true); - expect(requests[0].data.consent).to.equal('awefasdfwefasdfasd'); - }); - }); - - describe('GDPR absence conformity', function () { - const bidRequests = [{ - bidder: 'aardvark', - params: { - ai: 'xiby', - sc: 'TdAx', - }, - adUnitCode: 'aaa', - transactionId: '1b8389fe-615c-482d-9f1a-177fb8f7d5b0', - sizes: [300, 250], - bidId: '1abgs362e0x48a8', - bidderRequestId: '70deaff71c281d', - auctionId: '5c66da22-426a-4bac-b153-77360bef5337' - }]; - - const bidderRequest = { - gdprConsent: undefined, - refererInfo: { - referer: 'https://example.com' - } - }; - - it('should transmit correct data', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests.length).to.equal(1); - expect(requests[0].data.gdpr).to.be.undefined; - expect(requests[0].data.consent).to.be.undefined; - }); - }); - - describe('CCPA conformity', function () { - const bidRequests = [{ - bidder: 'aardvark', - params: { - ai: 'xiby', - sc: 'TdAx', - }, - adUnitCode: 'aaa', - transactionId: '1b8389fe-615c-482d-9f1a-177fb8f7d5b0', - sizes: [300, 250], - bidId: '1abgs362e0x48a8', - bidderRequestId: '70deaff71c281d', - auctionId: '5c66da22-426a-4bac-b153-77360bef5337' - }]; - - it('should transmit us_privacy data', function () { - const usp = '1NY-'; - const bidderRequest = { - gdprConsent: { - consentString: 'awefasdfwefasdfasd', - gdprApplies: true - }, - refererInfo: { - referer: 'http://example.com' - }, - uspConsent: usp - }; - const requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests.length).to.equal(1); - expect(requests[0].data.gdpr).to.equal(true); - expect(requests[0].data.consent).to.equal('awefasdfwefasdfasd'); - expect(requests[0].data.us_privacy).to.equal(usp); - }); - - it('should not send us_privacy', function () { - const bidderRequest = { - refererInfo: { - referer: 'http://example.com' - } - }; - const requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests.length).to.equal(1); - expect(requests[0].data.gdpr).to.be.undefined; - expect(requests[0].data.consent).to.be.undefined; - expect(requests[0].data.us_privacy).to.be.undefined; - }); - }); - - describe('interpretResponse', function () { - it('should handle bid responses', function () { - const serverResponse = { - body: [ - { - media: 'banner', - nurl: 'https://www.nurl.com/0', - cpm: 0.09, - width: 300, - height: 250, - cid: '22aidtbx5eabd9', - adm: '', - dealId: 'dealing', - ttl: 200, - }, - { - media: 'banner', - nurl: 'https://www.nurl.com/1', - cpm: 0.19, - width: 300, - height: 250, - cid: '1abgs362e0x48a8', - adm: '', - ttl: 200, - ex: 'extraproperty' - } - ], - headers: {} - }; - - const result = spec.interpretResponse(serverResponse, {}); - expect(result.length).to.equal(2); - - expect(result[0].requestId).to.equal('22aidtbx5eabd9'); - expect(result[0].cpm).to.equal(0.09); - expect(result[0].width).to.equal(300); - expect(result[0].height).to.equal(250); - expect(result[0].currency).to.equal('USD'); - expect(result[0].ttl).to.equal(200); - expect(result[0].dealId).to.equal('dealing'); - expect(result[0].ex).to.be.undefined; - expect(result[0].ad).to.not.be.undefined; - - expect(result[1].requestId).to.equal('1abgs362e0x48a8'); - expect(result[1].cpm).to.equal(0.19); - expect(result[1].width).to.equal(300); - expect(result[1].height).to.equal(250); - expect(result[1].currency).to.equal('USD'); - expect(result[1].ttl).to.equal(200); - expect(result[1].ad).to.not.be.undefined; - expect(result[1].ex).to.equal('extraproperty'); - }); - - it('should handle nobid responses', function () { - var emptyResponse = [{ - nurl: '', - cid: '9e5a09319e18f1', - media: 'banner', - error: 'No bids received for 9DgF', - adm: '', - id: '9DgF', - cpm: 0.00 - }]; - - var result = spec.interpretResponse({ body: emptyResponse }, {}); - expect(result.length).to.equal(0); - }); - }); - - describe('getUserSyncs', function () { - const syncOptions = { - iframeEnabled: true - }; - - it('should produce sync url', function () { - const syncs = spec.getUserSyncs(syncOptions); - expect(syncs.length).to.equal(1); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.equal('https://sync.rtk.io/cs'); - }); - - it('should return empty, as we sync only once', function () { - const syncs = spec.getUserSyncs(syncOptions); - expect(syncs.length).to.equal(0); - }); - - it('should reset hasSynced flag, allowing another sync', function () { - resetUserSync(); - - const syncs = spec.getUserSyncs(syncOptions); - expect(syncs.length).to.equal(1); - }); - - it('should return empty when iframe disallowed', function () { - resetUserSync(); - - const noIframeOptions = { iframeEnabled: false }; - const syncs = spec.getUserSyncs(noIframeOptions); - expect(syncs.length).to.equal(0); - }); - - it('should produce sync url with gdpr params', function () { - const gdprConsent = { - gdprApplies: true, - consentString: 'BOEFEAyOEFEAyAHABDENAI4AAAB9vABAASA' - }; - - resetUserSync(); - - const syncs = spec.getUserSyncs(syncOptions, null, gdprConsent); - expect(syncs.length).to.equal(1); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.equal('https://sync.rtk.io/cs?g=1&c=BOEFEAyOEFEAyAHABDENAI4AAAB9vABAASA'); - }); - - it('should produce sync url with ccpa params', function () { - resetUserSync(); - - const syncs = spec.getUserSyncs(syncOptions, null, {}, '1YYN'); - expect(syncs.length).to.equal(1); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.equal('https://sync.rtk.io/cs?us_privacy=1YYN'); - }); - }); - - describe('reading window.top properties', function () { - const bidCategories = ['bcat1', 'bcat2', 'bcat3']; - const bidRequests = [{ - bidder: 'aardvark', - params: { - ai: 'xiby', - sc: 'TdAx', - host: 'adzone.pub.com', - categories: bidCategories - }, - adUnitCode: 'RTK_aaaa', - transactionId: '1b8389fe-615c-482d-9f1a-177fb8f7d5b0', - sizes: [300, 250], - bidId: '1abgs362e0x48a8', - bidderRequestId: '70deaff71c281d', - auctionId: '5c66da22-426a-4bac-b153-77360bef5337', - userId: { tdid: 'eff98622-b5fd-44fa-9a49-6e846922d532' } - }]; - - const bidderRequest = { - refererInfo: { - referer: 'https://example.com' - } - }; - - const topWin = { - innerWidth: 1366, - innerHeight: 768, - rtkcategories: ['cat1', 'cat2', 'cat3'] - }; - - let sandbox; - beforeEach(function () { - sandbox = sinon.createSandbox(); - }); - - afterEach(function () { - sandbox.restore(); - }); - - it('should have window.top dimensions', function () { - sandbox.stub(utils, 'getWindowTop').returns(topWin); - - const requests = spec.buildRequests(bidRequests, bidderRequest); - requests.forEach(function (requestItem) { - expect(requestItem.data.w).to.equal(topWin.innerWidth); - expect(requestItem.data.h).to.equal(topWin.innerHeight); - }); - }); - - it('should have window dimensions, as backup', function () { - sandbox.stub(utils, 'getWindowTop').returns(undefined); - - const requests = spec.buildRequests(bidRequests, bidderRequest); - requests.forEach(function (requestItem) { - expect(requestItem.data.w).to.equal(window.innerWidth); - expect(requestItem.data.h).to.equal(window.innerHeight); - }); - }); - - it('should have window.top & bid categories', function () { - sandbox.stub(utils, 'getWindowTop').returns(topWin); - - const requests = spec.buildRequests(bidRequests, bidderRequest); - requests.forEach(function (requestItem) { - utils._each(topWin.categories, function (cat) { - expect(requestItem.data.categories).to.contain(cat); - }); - utils._each(bidCategories, function (cat) { - expect(requestItem.data.categories).to.contain(cat); - }); - }); - }); - }); - - describe('schain support', function() { - const nodePropsOrder = ['asi', 'sid', 'hp', 'rid', 'name', 'domain']; - let schainConfig = { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'rtk.io', - sid: '1234', - hp: 1, - rid: 'bid-request-1', - name: 'first pub', - domain: 'first.com' - }, - { - asi: 'rtk.io', - sid: '5678', - hp: 1, - rid: 'bid-request-2', - name: 'second pub', - domain: 'second.com' - } - ] - }; - - const bidRequests = [{ - bidder: 'aardvark', - params: { - ai: 'xiby', - sc: 'TdAx', - }, - adUnitCode: 'aaa', - transactionId: '1b8389fe-615c-482d-9f1a-177fb8f7d5b0', - sizes: [300, 250], - bidId: '1abgs362e0x48a8', - bidderRequestId: '70deaff71c281d', - auctionId: '5c66da22-426a-4bac-b153-77360bef5337', - schain: schainConfig, - }]; - - const bidderRequest = { - gdprConsent: undefined, - refererInfo: { - referer: 'https://example.com' - } - }; - - it('should properly serialize schain object with correct delimiters', () => { - const results = spec.buildRequests(bidRequests, bidderRequest); - const numNodes = schainConfig.nodes.length; - - const schain = results[0].data.schain; - - // each node serialization should start with an ! - expect(schain.match(/!/g).length).to.equal(numNodes); - - // 5 commas per node plus 1 for version - expect(schain.match(/,/g).length).to.equal(numNodes * 5 + 1); - }); - - it('should send the proper version for the schain', () => { - const results = spec.buildRequests(bidRequests, bidderRequest); - const schain = decodeURIComponent(results[0].data.schain).split('!'); - const version = schain.shift().split(',')[0]; - expect(version).to.equal(bidRequests[0].schain.ver); - }); - - it('should send the correct value for complete in schain', () => { - const results = spec.buildRequests(bidRequests, bidderRequest); - const schain = decodeURIComponent(results[0].data.schain).split('!'); - const complete = schain.shift().split(',')[1]; - expect(complete).to.equal(String(bidRequests[0].schain.complete)); - }); - - it('should send available params in the right order', () => { - const results = spec.buildRequests(bidRequests, bidderRequest); - const schain = decodeURIComponent(results[0].data.schain).split('!'); - schain.shift(); - - schain.forEach((serializeNode, nodeIndex) => { - const nodeProps = serializeNode.split(','); - nodeProps.forEach((nodeProp, propIndex) => { - const node = schainConfig.nodes[nodeIndex]; - const key = nodePropsOrder[propIndex]; - expect(nodeProp).to.equal(node[key] ? String(node[key]) : ''); - }); - }); - }); - }); -}); diff --git a/test/spec/modules/ablidaBidAdapter_spec.js b/test/spec/modules/ablidaBidAdapter_spec.js deleted file mode 100644 index 73109d8cf16..00000000000 --- a/test/spec/modules/ablidaBidAdapter_spec.js +++ /dev/null @@ -1,151 +0,0 @@ -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'; - -describe('ablidaBidAdapter', function () { - const adapter = newBidder(spec); - describe('isBidRequestValid', function () { - let bid = { - adUnitCode: 'adunit-code', - auctionId: '69e8fef8-5105-4a99-b011-d5669f3bc7f0', - bidRequestsCount: 1, - bidder: 'ablida', - bidderRequestId: '14d2939272a26a', - bidderRequestsCount: 1, - bidderWinsCount: 0, - bidId: '1234asdf1234', - mediaTypes: {banner: {sizes: [[300, 250]]}}, - params: { - placementId: 123 - }, - sizes: [ - [300, 250] - ], - src: 'client', - transactionId: '4781e6ac-93c4-42ba-86fe-ab5f278863cf' - }; - it('should return true where required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - }); - describe('buildRequests', function () { - let bidRequests = [ - { - adUnitCode: 'adunit-code', - auctionId: '69e8fef8-5105-4a99-b011-d5669f3bc7f0', - bidId: '23beaa6af6cdde', - bidRequestsCount: 1, - bidder: 'ablida', - bidderRequestId: '14d2939272a26a', - bidderRequestsCount: 1, - bidderWinsCount: 0, - mediaTypes: {banner: {sizes: [[300, 250]]}}, - params: { - placementId: 123 - }, - sizes: [ - [300, 250] - ], - src: 'client', - transactionId: '4781e6ac-93c4-42ba-86fe-ab5f278863cf' - } - ]; - - let bidderRequests = { - refererInfo: { - canonicalUrl: '', - numIframes: 0, - reachedTop: true, - referer: 'http://example.com', - stack: ['http://example.com'] - } - }; - - const request = spec.buildRequests(bidRequests, bidderRequests); - it('sends bid request via POST', function () { - expect(request[0].method).to.equal('POST'); - }); - }); - - describe('interpretResponse', function () { - let bidRequest = { - method: 'POST', - url: ENDPOINT_URL, - data: { - adapterVersion: 5, - bidId: '2b8c4de0116e54', - categories: undefined, - device: 'desktop', - gdprConsent: undefined, - jaySupported: true, - mediaTypes: {banner: {sizes: [[300, 250]]}}, - placementId: 'testPlacementId', - width: 300, - height: 200, - referer: 'www.example.com' - } - }; - let serverResponse = { - body: [{ - ad: '', - cpm: 1.00, - creativeId: '2b8c4de0116e54', - currency: 'EUR', - height: 250, - mediaType: 'banner', - meta: {}, - netRevenue: true, - nurl: 'https://example.com/some-tracker', - originalCpm: '0.10', - originalCurrency: 'EUR', - requestId: '2b8c4de0116e54', - ttl: 3000, - width: 300 - }] - }; - it('should get the correct bid response', function () { - let expectedResponse = [{ - ad: '', - cpm: 1.00, - creativeId: '2b8c4de0116e54', - currency: 'EUR', - height: 250, - mediaType: 'banner', - meta: {}, - netRevenue: true, - nurl: 'https://example.com/some-tracker', - originalCpm: '0.10', - originalCurrency: 'EUR', - requestId: '2b8c4de0116e54', - ttl: 3000, - width: 300 - }]; - let result = spec.interpretResponse(serverResponse, bidRequest[0]); - expect(Object.keys(result)).to.deep.equal(Object.keys(expectedResponse)); - }); - }); - - describe('onBidWon', function() { - beforeEach(function() { - sinon.stub(utils, 'triggerPixel'); - }); - afterEach(function() { - utils.triggerPixel.restore(); - }); - - it('Should not trigger pixel if bid does not contain nurl', function() { - const result = spec.onBidWon({}); - expect(utils.triggerPixel.callCount).to.equal(0) - }) - - it('Should trigger pixel if bid nurl', function() { - const result = spec.onBidWon({ - nurl: 'https://example.com/some-tracker' - }); - expect(utils.triggerPixel.callCount).to.equal(1) - }) - }) -}); diff --git a/test/spec/modules/adWMGAnalyticsAdapter_spec.js b/test/spec/modules/adWMGAnalyticsAdapter_spec.js deleted file mode 100644 index ab8336c7126..00000000000 --- a/test/spec/modules/adWMGAnalyticsAdapter_spec.js +++ /dev/null @@ -1,176 +0,0 @@ -import adWMGAnalyticsAdapter from 'modules/adWMGAnalyticsAdapter.js'; -import { expect } from 'chai'; -import { server } from 'test/mocks/xhr.js'; -let adapterManager = require('src/adapterManager').default; -let events = require('src/events'); -let constants = require('src/constants.json'); - -describe('adWMG Analytics', function () { - let timestamp = new Date() - 256; - let auctionId = '5018eb39-f900-4370-b71e-3bb5b48d324f'; - let timeout = 1500; - - let bidTimeoutArgs = [ - { - bidId: '2baa51527bd015', - bidder: 'bidderA', - adUnitCode: '/19968336/header-bid-tag-0', - auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f' - }, - { - bidId: '6fe3b4c2c23092', - bidder: 'bidderB', - adUnitCode: '/19968336/header-bid-tag-0', - auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f' - } - ]; - - const bidResponse = { - bidderCode: 'bidderA', - adId: '208750227436c1', - mediaTypes: ['banner'], - cpm: 0.015, - auctionId: auctionId, - responseTimestamp: 1509369418832, - requestTimestamp: 1509369418389, - bidder: 'bidderA', - timeToRespond: 443, - size: '300x250', - width: 300, - height: 250, - }; - - let wonRequest = { - 'adId': '4587fec4900b81', - 'mediaType': 'banner', - 'requestId': '4587fec4900b81', - 'cpm': 1.962, - 'creativeId': 2126, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 302, - 'auctionId': '914bedad-b145-4e46-ba58-51365faea6cb', - 'statusMessage': 'Bid available', - 'responseTimestamp': 1530628534437, - 'requestTimestamp': 1530628534219, - 'bidder': 'bidderB', - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'sizes': [[300, 250]], - 'size': [300, 250], - }; - - let expectedBidWonData = { - publisher_id: '5abd0543ba45723db49d97ea', - site: 'test.com', - ad_unit_size: ['300,250'], - ad_unit_type: ['banner'], - c_timeout: 1500, - events: [ - { - status: 'bidWon', - bids: [ - { - bidder: 'bidderB', - auction_id: '914bedad-b145-4e46-ba58-51365faea6cb', - ad_unit_code: 'div-gpt-ad-1438287399331-0', - transaction_id: '', - bid_size: ['300,250'], - bid_type: ['banner'], - time_ms: 256, - cur: 'USD', - price: '1.96', - cur_native: '', - price_native: '' - } - ] - } - ] - } - - let adUnits = [{ - code: 'ad-slot-1', - sizes: [[300, 250]], - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [ - { - bidder: 'bidderA', - params: { - placement: '1000' - } - }, - { - bidder: 'bidderB', - params: { - placement: '56656' - } - } - ] - }]; - - after(function () { - adWMGAnalyticsAdapter.disableAnalytics(); - }); - - describe('main test flow', function () { - beforeEach(function () { - sinon.stub(events, 'getEvents').returns([]); - }); - - afterEach(function () { - events.getEvents.restore(); - }); - - it('should catch all events', function () { - sinon.spy(adWMGAnalyticsAdapter, 'track'); - - adapterManager.registerAnalyticsAdapter({ - code: 'adWMG', - adapter: adWMGAnalyticsAdapter - }); - - adapterManager.enableAnalytics({ - provider: 'adWMG', - options: { - site: 'test.com', - publisher_id: '5abd0543ba45723db49d97ea' - } - }); - - events.emit(constants.EVENTS.AUCTION_INIT, {timestamp, auctionId, timeout, adUnits}); - events.emit(constants.EVENTS.BID_REQUESTED, {}); - events.emit(constants.EVENTS.BID_RESPONSE, bidResponse); - events.emit(constants.EVENTS.NO_BID, {}); - events.emit(constants.EVENTS.BID_TIMEOUT, bidTimeoutArgs); - events.emit(constants.EVENTS.AUCTION_END, {}); - events.emit(constants.EVENTS.BID_WON, wonRequest); - sinon.assert.callCount(adWMGAnalyticsAdapter.track, 7); - }); - - it('should be two xhr requests', function () { - events.emit(constants.EVENTS.AUCTION_END, {}); - events.emit(constants.EVENTS.BID_WON, wonRequest); - expect(server.requests.length).to.equal(2); - }); - - it('second request should be bidWon', function () { - events.emit(constants.EVENTS.AUCTION_END, {}); - events.emit(constants.EVENTS.BID_WON, wonRequest); - expect(JSON.parse(server.requests[1].requestBody).events[0].status).to.equal(expectedBidWonData.events[0].status); - }); - - it('check bidWon data', function () { - events.emit(constants.EVENTS.AUCTION_END, {}); - events.emit(constants.EVENTS.BID_WON, wonRequest); - let realBidWonData = JSON.parse(server.requests[1].requestBody); - expect(realBidWonData.publisher_id).to.equal(expectedBidWonData.publisher_id); - expect(realBidWonData.site).to.equal(expectedBidWonData.site); - expect(realBidWonData.ad_unit_type[0]).to.equal(expectedBidWonData.ad_unit_type[0]); - expect(realBidWonData.ad_unit_size[0]).to.equal(expectedBidWonData.ad_unit_size[0]); - expect(realBidWonData.events[0].bids[0].bidder).to.equal(expectedBidWonData.events[0].bids[0].bidder); - }); - }); -}); diff --git a/test/spec/modules/adWMGBidAdapter_spec.js b/test/spec/modules/adWMGBidAdapter_spec.js deleted file mode 100644 index 8b927ace84c..00000000000 --- a/test/spec/modules/adWMGBidAdapter_spec.js +++ /dev/null @@ -1,332 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/adWMGBidAdapter.js'; -import { config } from 'src/config.js'; - -describe('adWMGBidAdapter', function () { - describe('isBidRequestValid', function () { - let bid; - beforeEach(function() { - bid = { - bidder: 'adWMG', - params: { - publisherId: '5cebea3c9eea646c7b623d5e' - }, - mediaTypes: { - banner: { - size: [[300, 250]] - } - } - }; - }); - - it('should return true when valid bid request is set', function() { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when bidder is not set to "adWMG"', function() { - bid.bidder = 'bidder'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when \'publisherId\' param are not set', function() { - delete bid.params.publisherId; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('parseUserAgent', function() { - let ua_desktop, ua_mobile, ua_tv, ua_tablet; - beforeEach(function() { - ua_desktop = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36'; - ua_tv = 'Mozilla/5.0 (Linux; NetCast; U) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.31 SmartTV/7.0'; - ua_mobile = 'Mozilla/5.0 (Linux; Android 7.0; SAMSUNG SM-G610M Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/7.2 Chrome/59.0.3071.125 Mobile Safari/537.36'; - ua_tablet = 'Mozilla/5.0 (iPad; CPU OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D257 Safari/9537.53'; - }); - - it('should return correct device type: desktop', function() { - let userDeviceInfo = spec.parseUserAgent(ua_desktop); - expect(userDeviceInfo.devicetype).to.equal(2); - }); - - it('should return correct device type: TV', function() { - let userDeviceInfo = spec.parseUserAgent(ua_tv); - expect(userDeviceInfo.devicetype).to.equal(3); - }); - - it('should return correct device type: mobile', function() { - let userDeviceInfo = spec.parseUserAgent(ua_mobile); - expect(userDeviceInfo.devicetype).to.equal(4); - }); - - it('should return correct device type: tablet', function() { - let userDeviceInfo = spec.parseUserAgent(ua_tablet); - expect(userDeviceInfo.devicetype).to.equal(5); - }); - - it('should return correct OS name', function() { - let userDeviceInfo = spec.parseUserAgent(ua_desktop); - expect(userDeviceInfo.os).to.equal('Windows'); - }); - - it('should return correct OS version', function() { - let userDeviceInfo = spec.parseUserAgent(ua_desktop); - expect(userDeviceInfo.osv).to.equal('10.0'); - }); - }); - - describe('buildRequests', function () { - let bidRequests; - beforeEach(function() { - bidRequests = [ - { - bidder: 'adWMG', - adUnitCode: 'adwmg-test-ad', - auctionId: 'test-auction-id', - bidId: 'test-bid-id', - bidRequestsCount: 1, - bidderRequestId: 'bidderrequestid123', - transactionId: 'transaction-id-123', - sizes: [[300, 250]], - requestId: 'requestid123', - params: { - floorPrice: 100, - currency: 'USD' - }, - mediaTypes: { - banner: { - size: [[300, 250]] - } - }, - userId: { - pubcid: 'pubc-id-123' - } - }, { - bidder: 'adWMG', - adUnitCode: 'adwmg-test-ad-2', - auctionId: 'test-auction-id-2', - bidId: 'test-bid-id-2', - bidRequestsCount: 1, - bidderRequestId: 'bidderrequestid456', - transactionId: 'transaction-id-456', - sizes: [[320, 50]], - requestId: 'requestid456', - params: { - floorPrice: 100, - currency: 'USD' - }, - mediaTypes: { - banner: { - size: [[320, 50]] - } - }, - userId: { - pubcid: 'pubc-id-456' - } - } - ]; - }); - - let bidderRequest = { - refererInfo: { - referer: 'https://test.com' - }, - gdprConsent: { - consentString: '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', - vendorData: {}, - gdprApplies: true, - apiVersion: 2 - } - }; - - it('should not contain a sizes when sizes is not set', function() { - delete bidRequests[0].sizes; - delete bidRequests[1].sizes; - let requests = spec.buildRequests(bidRequests, bidderRequest); - expect(JSON.parse(requests[0].data).sizes).to.be.an('undefined'); - expect(JSON.parse(requests[1].data).sizes).to.be.an('undefined'); - }); - - it('should not contain a userId when userId is not set', function() { - delete bidRequests[0].userId; - delete bidRequests[1].userId; - let requests = spec.buildRequests(bidRequests, bidderRequest); - expect(JSON.parse(requests[0].data).userId).to.be.an('undefined'); - expect(JSON.parse(requests[1].data).userId).to.be.an('undefined'); - }); - - it('should have a post method', function() { - let requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests[0].method).to.equal('POST'); - expect(requests[1].method).to.equal('POST'); - }); - - it('should contain a request id equals to the bid id', function() { - let requests = spec.buildRequests(bidRequests, bidderRequest); - expect(JSON.parse(requests[0].data).requestId).to.equal(bidRequests[0].bidId); - expect(JSON.parse(requests[1].data).requestId).to.equal(bidRequests[1].bidId); - }); - - it('should have an url that match the default endpoint', function() { - let requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests[0].url).to.equal('https://hb.adwmg.com/hb'); - expect(requests[1].url).to.equal('https://hb.adwmg.com/hb'); - }); - - it('should contain GDPR consent data if GDPR set', function() { - let requests = spec.buildRequests(bidRequests, bidderRequest); - expect(JSON.parse(requests[0].data).gdpr.applies).to.be.true; - expect(JSON.parse(requests[0].data).gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); - expect(JSON.parse(requests[1].data).gdpr.applies).to.be.true; - expect(JSON.parse(requests[1].data).gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); - }) - - it('should not contain GDPR consent data if GDPR not set', function() { - delete bidderRequest.gdprConsent; - let requests = spec.buildRequests(bidRequests, bidderRequest); - expect(JSON.parse(requests[0].data).gdpr).to.be.an('undefined'); - expect(JSON.parse(requests[1].data).gdpr).to.be.an('undefined'); - }) - - it('should set debug mode in requests if enabled', function() { - sinon.stub(config, 'getConfig').withArgs('debug').returns(true); - let requests = spec.buildRequests(bidRequests, bidderRequest); - expect(JSON.parse(requests[0].data).debug).to.be.true; - expect(JSON.parse(requests[1].data).debug).to.be.true; - config.getConfig.restore(); - }) - }); - - describe('interpretResponse', function () { - let serverResponse; - beforeEach(function() { - serverResponse = { - body: { - 'requestId': 'request-id', - 'cpm': 100, - 'width': 300, - 'height': 250, - 'ad': '
ad
', - 'ttl': 300, - 'creativeId': 'creative-id', - 'netRevenue': true, - 'currency': 'USD' - } - }; - }); - - it('should return a valid response', () => { - var responses = spec.interpretResponse(serverResponse); - expect(responses).to.be.an('array').that.is.not.empty; - - let response = responses[0]; - expect(response).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency'); - expect(response.requestId).to.equal('request-id'); - expect(response.cpm).to.equal(100); - expect(response.width).to.equal(300); - expect(response.height).to.equal(250); - expect(response.ad).to.equal('
ad
'); - expect(response.ttl).to.equal(300); - expect(response.creativeId).to.equal('creative-id'); - expect(response.netRevenue).to.be.true; - expect(response.currency).to.equal('USD'); - }); - - it('should return an empty array when serverResponse is empty', () => { - serverResponse = {}; - var responses = spec.interpretResponse(serverResponse); - expect(responses).to.deep.equal([]); - }); - }); - - describe('getUserSyncs', function () { - it('should return nothing when sync is disabled', function () { - const syncOptions = { - 'iframeEnabled': false, - 'pixelEnabled': false - }; - - let syncs = spec.getUserSyncs(syncOptions); - expect(syncs).to.deep.equal([]); - }); - - it('should register iframe sync when only iframe is enabled', function () { - const syncOptions = { - 'iframeEnabled': true, - 'pixelEnabled': false - }; - - let syncs = spec.getUserSyncs(syncOptions); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).includes('https://hb.adwmg.com/cphb.html?'); - }); - - it('should register iframe sync when iframe and image are enabled', function () { - const syncOptions = { - 'iframeEnabled': true, - 'pixelEnabled': true - }; - - let syncs = spec.getUserSyncs(syncOptions); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).includes('https://hb.adwmg.com/cphb.html?'); - }); - - it('should send GDPR consent if enabled', function() { - const syncOptions = { - 'iframeEnabled': true, - 'pixelEnabled': true - }; - const gdprConsent = { - consentString: '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', - vendorData: {}, - gdprApplies: true, - apiVersion: 2 - }; - const serverResponse = {}; - let syncs = spec.getUserSyncs(syncOptions, serverResponse, gdprConsent); - expect(syncs[0].url).includes('gdpr=1'); - expect(syncs[0].url).includes(`gdpr_consent=${gdprConsent.consentString}`); - }); - - it('should not add GDPR consent params twice', function() { - const syncOptions = { - 'iframeEnabled': true, - 'pixelEnabled': true - }; - const gdprConsent = { - consentString: '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', - vendorData: {}, - gdprApplies: true, - apiVersion: 2 - }; - const gdprConsent2 = { - consentString: 'CO9rhBTO9rhBTAcABBENBCCsAP_AAH_AACiQHItf_7_fb3_j-_59_9t0eY1f9_7_v20zjgeds-8Nyd_X_L8X42M7vB36pq4KuR4Eu3LBIQdlHOHcTUmw6IkVqTPsbk2Mr7NKJ7PEinMbe2dYGH9_n9XTuZKY79_s___z__-__v__7_f_r-3_3_vp9V---3YHIgEmGpfARZiWOBJNGlUKIEIVxIdACACihGFomsICVwU7K4CP0EDABAagIwIgQYgoxZBAAAAAElEQEgB4IBEARAIAAQAqQEIACNAEFgBIGAQACgGhYARQBCBIQZHBUcpgQESLRQTyVgCUXexhhCGUUANAg4AA.YAAAAAAAAAAA', - vendorData: {}, - gdprApplies: true, - apiVersion: 2 - }; - const serverResponse = {}; - let syncs = spec.getUserSyncs(syncOptions, serverResponse, gdprConsent); - syncs = spec.getUserSyncs(syncOptions, serverResponse, gdprConsent2); - expect(syncs[0].url.match(/gdpr/g).length).to.equal(2); // gdpr + gdpr_consent - expect(syncs[0].url.match(/gdpr_consent/g).length).to.equal(1); - }); - - it('should delete \'&\' symbol at the end of usersync URL', function() { - const syncOptions = { - 'iframeEnabled': true, - 'pixelEnabled': true - }; - const gdprConsent = { - consentString: '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', - vendorData: {}, - gdprApplies: true, - apiVersion: 2 - }; - const serverResponse = {}; - let syncs = spec.getUserSyncs(syncOptions, serverResponse, gdprConsent); - expect(syncs[0].url.slice(-1)).to.not.equal('&'); - }); - }); -}); diff --git a/test/spec/modules/adagioAnalyticsAdapter_spec.js b/test/spec/modules/adagioAnalyticsAdapter_spec.js deleted file mode 100644 index aee85412104..00000000000 --- a/test/spec/modules/adagioAnalyticsAdapter_spec.js +++ /dev/null @@ -1,183 +0,0 @@ -import adagioAnalyticsAdapter from 'modules/adagioAnalyticsAdapter.js'; -import { expect } from 'chai'; -import * as utils from 'src/utils.js'; - -let adapterManager = require('src/adapterManager').default; -let events = require('src/events'); -let constants = require('src/constants.json'); - -describe('adagio analytics adapter', () => { - let sandbox; - let adagioQueuePushSpy; - - beforeEach(() => { - sandbox = sinon.createSandbox(); - - sandbox.stub(events, 'getEvents').returns([]); - - const w = utils.getWindowTop(); - - adapterManager.registerAnalyticsAdapter({ - code: 'adagio', - adapter: adagioAnalyticsAdapter - }); - - w.ADAGIO = w.ADAGIO || {}; - w.ADAGIO.queue = w.ADAGIO.queue || []; - - adagioQueuePushSpy = sandbox.spy(w.ADAGIO.queue, 'push'); - }); - - afterEach(() => { - sandbox.restore(); - }); - - describe('track', () => { - beforeEach(() => { - adapterManager.enableAnalytics({ - provider: 'adagio' - }); - }); - - afterEach(() => { - adagioAnalyticsAdapter.disableAnalytics(); - }); - - it('builds and sends auction data', () => { - const w = utils.getWindowTop(); - - let bidRequest = { - bids: [{ - adUnitCode: 'div-1', - params: { - features: { - siteId: '2', - placement: 'pave_top', - pagetype: 'article', - category: 'IAB12,IAB12-2', - device: '2', - } - } - }, { - adUnitCode: 'div-2', - params: { - features: { - siteId: '2', - placement: 'ban_top', - pagetype: 'article', - category: 'IAB12,IAB12-2', - device: '2', - } - }, - }], - }; - let bidResponse = { - bidderCode: 'adagio', - width: 300, - height: 250, - statusMessage: 'Bid available', - cpm: 6.2189757658226075, - currency: '', - netRevenue: false, - adUnitCode: 'div-1', - timeToRespond: 132, - }; - - // Step 1: Send bid requested event - events.emit(constants.EVENTS.BID_REQUESTED, bidRequest); - - // Step 2: Send bid response event - events.emit(constants.EVENTS.BID_RESPONSE, bidResponse); - - // Step 3: Send auction end event - events.emit(constants.EVENTS.AUCTION_END, {}); - - sandbox.assert.callCount(adagioQueuePushSpy, 3); - - const call0 = adagioQueuePushSpy.getCall(0); - expect(call0.args[0].action).to.equal('pb-analytics-event'); - expect(call0.args[0].ts).to.not.be.undefined; - expect(call0.args[0].data).to.not.be.undefined; - expect(call0.args[0].data).to.deep.equal({eventName: constants.EVENTS.BID_REQUESTED, args: bidRequest}); - - const call1 = adagioQueuePushSpy.getCall(1); - expect(call1.args[0].action).to.equal('pb-analytics-event'); - expect(call1.args[0].ts).to.not.be.undefined; - expect(call1.args[0].data).to.not.be.undefined; - expect(call1.args[0].data).to.deep.equal({eventName: constants.EVENTS.BID_RESPONSE, args: bidResponse}); - - const call2 = adagioQueuePushSpy.getCall(2); - expect(call2.args[0].action).to.equal('pb-analytics-event'); - expect(call2.args[0].ts).to.not.be.undefined; - expect(call2.args[0].data).to.not.be.undefined; - expect(call2.args[0].data).to.deep.equal({eventName: constants.EVENTS.AUCTION_END, args: {}}); - }); - }); - - describe('no track', () => { - beforeEach(() => { - sandbox.stub(utils, 'getWindowTop').throws(); - - adapterManager.enableAnalytics({ - provider: 'adagio' - }); - }); - - afterEach(() => { - adagioAnalyticsAdapter.disableAnalytics(); - sandbox.restore(); - }); - - it('builds and sends auction data', () => { - let bidRequest = { - bids: [{ - adUnitCode: 'div-1', - params: { - features: { - siteId: '2', - placement: 'pave_top', - pagetype: 'article', - category: 'IAB12,IAB12-2', - device: '2', - } - } - }, { - adUnitCode: 'div-2', - params: { - features: { - siteId: '2', - placement: 'ban_top', - pagetype: 'article', - category: 'IAB12,IAB12-2', - device: '2', - } - }, - }], - }; - let bidResponse = { - bidderCode: 'adagio', - width: 300, - height: 250, - statusMessage: 'Bid available', - cpm: 6.2189757658226075, - currency: '', - netRevenue: false, - adUnitCode: 'div-1', - timeToRespond: 132, - }; - - // Step 1: Send bid requested event - events.emit(constants.EVENTS.BID_REQUESTED, bidRequest); - - // Step 2: Send bid response event - events.emit(constants.EVENTS.BID_RESPONSE, bidResponse); - - // Step 3: Send auction end event - events.emit(constants.EVENTS.AUCTION_END, {}); - - utils.getWindowTop.restore(); - - sandbox.assert.callCount(adagioQueuePushSpy, 0); - }); - }); -}); diff --git a/test/spec/modules/adagioBidAdapter_spec.js b/test/spec/modules/adagioBidAdapter_spec.js deleted file mode 100644 index 6ee42e47950..00000000000 --- a/test/spec/modules/adagioBidAdapter_spec.js +++ /dev/null @@ -1,1624 +0,0 @@ -import find from 'core-js-pure/features/array/find.js'; -import { expect, util } from 'chai'; -import { - _features, - internal as adagio, - adagioScriptFromLocalStorageCb, - getAdagioScript, - storage, - spec, - ENDPOINT, - VERSION, - RENDERER_URL -} from '../../../modules/adagioBidAdapter.js'; -import { loadExternalScript } from '../../../src/adloader.js'; -import * as utils from '../../../src/utils.js'; -import { config } from '../../../src/config.js'; -import { NATIVE } from '../../../src/mediaTypes.js'; - -const BidRequestBuilder = function BidRequestBuilder(options) { - const defaults = { - request: { - auctionId: '4fd1ca2d-846c-4211-b9e5-321dfe1709c9', - adUnitCode: 'adunit-code', - bidder: 'adagio' - }, - params: { - organizationId: '1000', - placement: 'PAVE_ATF', - site: 'SITE-NAME', - adUnitElementId: 'gpt-adunit-code' - }, - sizes: [[300, 250], [300, 600]], - }; - - const request = { - ...defaults.request, - ...options - }; - - this.withParams = (options) => { - request.params = { - ...defaults.params, - ...options - }; - return this; - }; - - this.build = () => request; -}; - -const BidderRequestBuilder = function BidderRequestBuilder(options) { - const defaults = { - bidderCode: 'adagio', - auctionId: '4fd1ca2d-846c-4211-b9e5-321dfe1709c9', - bidderRequestId: '7g36s867Tr4xF90X', - timeout: 3000, - refererInfo: { - numIframes: 0, - reachedTop: true, - referer: 'http://test.io/index.html?pbjs_debug=true' - } - }; - - const request = { - ...defaults, - ...options - }; - - this.build = () => request; -}; - -describe('Adagio bid adapter', () => { - let adagioMock; - let utilsMock; - let sandbox; - - const fixtures = { - getElementById(width, height, x, y) { - const obj = { - x: x || 800, - y: y || 300, - width: width || 300, - height: height || 250, - }; - - return { - ...obj, - getBoundingClientRect: () => { - return { - width: obj.width, - height: obj.height, - left: obj.x, - top: obj.y, - right: obj.x + obj.width, - bottom: obj.y + obj.height - }; - } - }; - } - }; - - // safeFrame implementation - const $sf = { - ext: { - geom: function() {} - } - }; - - beforeEach(() => { - window.ADAGIO = {}; - window.ADAGIO.adUnits = {}; - window.ADAGIO.pbjsAdUnits = []; - window.ADAGIO.queue = []; - window.ADAGIO.versions = {}; - window.ADAGIO.versions.adagioBidderAdapter = VERSION; - window.ADAGIO.pageviewId = 'dda61753-4059-4f75-b0bf-3f60bd2c4d9a'; - - adagioMock = sinon.mock(adagio); - utilsMock = sinon.mock(utils); - - sandbox = sinon.createSandbox(); - }); - - afterEach(() => { - window.ADAGIO = undefined; - - adagioMock.restore(); - utilsMock.restore(); - - sandbox.restore(); - }); - - describe('isBidRequestValid()', function() { - it('should return true when required params have been found', function() { - const bid = new BidRequestBuilder().withParams().build(); - - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false if bid.params is missing', function() { - sandbox.spy(utils, 'logWarn'); - const bid01 = new BidRequestBuilder().build(); - - expect(spec.isBidRequestValid(bid01)).to.equal(false); - sinon.assert.callCount(utils.logWarn, 1); - }); - - 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(); - - expect(spec.isBidRequestValid(bid01)).to.equal(true); - expect(bid01.params.adUnitElementId).to.equal('adunit-code'); - expect(bid01.params.placement).to.equal('adunit-code'); - }) - - it('should return false when a required param is missing', function() { - const bid01 = new BidRequestBuilder({ params: { - organizationId: '1000', - placement: 'PAVE_ATF' - }}).build(); - - const bid02 = new BidRequestBuilder({ params: { - organizationId: '1000', - site: 'SITE-NAME' - }}).build(); - - const bid03 = new BidRequestBuilder({ params: { - placement: 'PAVE_ATF', - site: 'SITE-NAME' - }}).build(); - - expect(spec.isBidRequestValid(bid01)).to.equal(false); - expect(spec.isBidRequestValid(bid02)).to.equal(false); - expect(spec.isBidRequestValid(bid03)).to.equal(false); - }); - - it('should return false when refererInfo.reachedTop is false', function() { - sandbox.spy(utils, 'logWarn'); - sandbox.stub(adagio, 'getRefererInfo').returns({ reachedTop: false }); - const bid = new BidRequestBuilder().withParams().build(); - - expect(spec.isBidRequestValid(bid)).to.equal(false); - sinon.assert.callCount(utils.logWarn, 1); - sinon.assert.calledWith(utils.logWarn, 'Adagio: the main page url is unreachabled.'); - }); - - it('should log warning and enqueue the bid object in ADAGIO.queue when isBidRequestValid is false', function() { - sandbox.stub(Date, 'now').returns(12345); - sandbox.spy(utils, 'logWarn'); - sandbox.spy(adagio, 'enqueue'); - - const bid = new BidRequestBuilder({'params': { - organizationId: '1000', - placement: 'PAVE_ATF' - }}).build(); - - const expectedEnqueued = { - action: 'pb-dbg', - ts: 12345, - data: { bid } - }; - - spec.isBidRequestValid(bid); - - sinon.assert.calledWith(adagio.enqueue, expectedEnqueued); - sinon.assert.callCount(utils.logWarn, 1); - }); - - describe('Store ADAGIO global in window.top or window.self depending on context', function() { - const bid01 = new BidRequestBuilder({ - adUnitCode: 'adunit-code-01', - sizes: [[300, 250], [300, 600]] - }).withParams().build(); - - const bid02 = new BidRequestBuilder({ - adUnitCode: 'adunit-code-02', - mediaTypes: { - banner: { sizes: [[300, 250]] } - }, - }).withParams().build(); - - const bid03 = new BidRequestBuilder({ - adUnitCode: 'adunit-code-02', - mediaTypes: { - banner: { sizes: [[300, 600]] } - }, - }).withParams().build(); - - const expected = [ - { - code: 'adunit-code-01', - sizes: [[300, 250], [300, 600]], - mediaTypes: {}, - bids: [{ - bidder: 'adagio', - params: { - organizationId: '1000', - placement: 'PAVE_ATF', - site: 'SITE-NAME', - adUnitElementId: 'gpt-adunit-code', - environment: 'desktop', - supportIObs: true - } - }], - auctionId: '4fd1ca2d-846c-4211-b9e5-321dfe1709c9', - pageviewId: 'dda61753-4059-4f75-b0bf-3f60bd2c4d9a', - printNumber: 1, - }, - { - code: 'adunit-code-02', - sizes: [[300, 600]], - mediaTypes: { - banner: { sizes: [[300, 600]] } - }, - bids: [{ - bidder: 'adagio', - params: { - organizationId: '1000', - placement: 'PAVE_ATF', - site: 'SITE-NAME', - adUnitElementId: 'gpt-adunit-code', - environment: 'desktop', - supportIObs: true - } - }], - auctionId: '4fd1ca2d-846c-4211-b9e5-321dfe1709c9', - pageviewId: 'dda61753-4059-4f75-b0bf-3f60bd2c4d9a', - printNumber: 2, - } - ]; - - it('should store bids config once by bid in window.top if it accessible', function() { - sandbox.stub(adagio, 'getCurrentWindow').returns(window.top); - sandbox.stub(adagio, 'supportIObs').returns(true); - - // replace by the values defined in beforeEach - window.top.ADAGIO = { - ...window.ADAGIO - }; - - spec.isBidRequestValid(bid01); - spec.isBidRequestValid(bid02); - spec.isBidRequestValid(bid03); - - expect(find(window.top.ADAGIO.pbjsAdUnits, aU => aU.code === 'adunit-code-01')).to.deep.eql(expected[0]); - expect(find(window.top.ADAGIO.pbjsAdUnits, aU => aU.code === 'adunit-code-02')).to.deep.eql(expected[1]); - }); - - it('should detect IntersectionObserver support', function() { - sandbox.stub(adagio, 'getCurrentWindow').returns(window.top); - sandbox.stub(adagio, 'supportIObs').returns(false); - - window.top.ADAGIO = { - ...window.ADAGIO - }; - - spec.isBidRequestValid(bid01); - const validBidReq = find(window.top.ADAGIO.pbjsAdUnits, aU => aU.code === 'adunit-code-01'); - expect(validBidReq.bids[0].params.supportIObs).to.equal(false); - }); - - it('should store bids config once by bid in current window', function() { - sandbox.stub(adagio, 'getCurrentWindow').returns(window.self); - sandbox.stub(adagio, 'supportIObs').returns(true); - - spec.isBidRequestValid(bid01); - spec.isBidRequestValid(bid02); - spec.isBidRequestValid(bid03); - - expect(find(window.ADAGIO.pbjsAdUnits, aU => aU.code === 'adunit-code-01')).to.deep.eql(expected[0]); - expect(find(window.ADAGIO.pbjsAdUnits, aU => aU.code === 'adunit-code-02')).to.deep.eql(expected[1]); - }); - }); - }); - - describe('buildRequests()', function() { - const expectedDataKeys = [ - 'id', - 'organizationId', - 'secure', - 'device', - 'site', - 'pageviewId', - 'adUnits', - 'regs', - 'user', - 'schain', - 'prebidVersion', - 'adapterVersion', - 'featuresVersion', - 'data' - ]; - - it('groups requests by organizationId', function() { - const bid01 = new BidRequestBuilder().withParams().build(); - const bid02 = new BidRequestBuilder().withParams().build(); - const bid03 = new BidRequestBuilder().withParams({ - organizationId: '1002' - }).build(); - - const bidderRequest = new BidderRequestBuilder().build(); - - const requests = spec.buildRequests([bid01, bid02, bid03], bidderRequest); - - expect(requests).to.have.lengthOf(2); - - expect(requests[0].data.organizationId).to.equal('1000'); - expect(requests[0].data.adUnits).to.have.lengthOf(2); - - expect(requests[1].data.organizationId).to.equal('1002'); - expect(requests[1].data.adUnits).to.have.lengthOf(1); - }); - - it('should send bid request to ENDPOINT_PB via POST', function() { - sandbox.stub(adagio, 'getDevice').returns({ a: 'a' }); - sandbox.stub(adagio, 'getSite').returns({ domain: 'adagio.io', 'page': 'https://adagio.io/hb' }); - sandbox.stub(adagio, 'getPageviewId').returns('1234-567'); - sandbox.stub(adagio, 'getFeatures').returns({}); - - const bid01 = new BidRequestBuilder().withParams().build(); - const bidderRequest = new BidderRequestBuilder().build(); - - const requests = spec.buildRequests([bid01], bidderRequest); - - expect(requests).to.have.lengthOf(1); - expect(requests[0].method).to.equal('POST'); - expect(requests[0].url).to.equal(ENDPOINT); - expect(requests[0].options.contentType).to.eq('text/plain'); - expect(requests[0].data).to.have.all.keys(expectedDataKeys); - }); - - it('should enqueue computed features for collect usage', function() { - sandbox.stub(Date, 'now').returns(12345); - - for (const prop in _features) { - sandbox.stub(_features, prop).returns(''); - } - - adagioMock.expects('enqueue').withExactArgs({ - action: 'features', - ts: 12345, - data: { - 'gpt-adunit-code': { - features: {}, - version: '1' - } - } - }).atLeast(1); - - const bid01 = new BidRequestBuilder().withParams().build(); - const bidderRequest = new BidderRequestBuilder().build(); - - const requests = spec.buildRequests([bid01], bidderRequest); - - expect(requests[0].data).to.have.all.keys(expectedDataKeys); - - adagioMock.verify(); - }); - - it('should filter some props in case refererDetection.reachedTop is false', function() { - const bid01 = new BidRequestBuilder().withParams().build(); - const bidderRequest = new BidderRequestBuilder({ - refererInfo: { - numIframes: 2, - reachedTop: false, - referer: 'http://example.com/iframe1.html', - stack: [ - null, - 'http://example.com/iframe1.html', - 'http://example.com/iframe2.html' - ], - canonicalUrl: '' - } - }).build(); - - const requests = spec.buildRequests([bid01], bidderRequest); - - expect(requests).to.have.lengthOf(1); - expect(requests[0].data).to.have.all.keys(expectedDataKeys); - expect(requests[0].data.adUnits[0].features).to.exist; - expect(requests[0].data.adUnits[0].features.url).to.not.exist; - }); - - describe('With video mediatype', function() { - context('Outstream video', function() { - it('should logWarn if user does not set renderer.backupOnly: true', function() { - sandbox.spy(utils, 'logWarn'); - const bid01 = new BidRequestBuilder({ - adUnitCode: 'adunit-code-01', - mediaTypes: { - banner: { sizes: [[300, 250]] }, - video: { - context: 'outstream', - playerSize: [[300, 250]], - renderer: { - url: 'https://url.tld', - render: () => true - } - } - }, - }).withParams().build(); - const bidderRequest = new BidderRequestBuilder().build(); - const request = spec.buildRequests([bid01], bidderRequest)[0]; - - expect(request.data.adUnits[0].mediaTypes.video.playerName).to.equal('other'); - sinon.assert.calledWith(utils.logWarn, 'Adagio: renderer.backupOnly has not been set. Adagio recommends to use its own player to get expected behavior.'); - }); - }); - - it('Update mediaTypes.video with OpenRTB options. Validate and sanitize whitelisted OpenRTB', function() { - sandbox.spy(utils, 'logWarn'); - const bid01 = new BidRequestBuilder({ - adUnitCode: 'adunit-code-01', - mediaTypes: { - banner: { sizes: [[300, 250]] }, - video: { - context: 'outstream', - playerSize: [[300, 250]], - mimes: ['video/mp4'], - api: 5, // will be removed because invalid - playbackmethod: [7], // will be removed because invalid - } - }, - }).withParams({ - // options in video, will overide - video: { - skip: 1, - skipafter: 4, - minduration: 10, - maxduration: 30, - placement: [3], - protocols: [8] - } - }).build(); - - const bidderRequest = new BidderRequestBuilder().build(); - const expected = { - context: 'outstream', - playerSize: [[300, 250]], - playerName: 'adagio', - mimes: ['video/mp4'], - skip: 1, - skipafter: 4, - minduration: 10, - maxduration: 30, - placement: [3], - protocols: [8], - w: 300, - h: 250 - }; - - const requests = spec.buildRequests([bid01], bidderRequest); - expect(requests).to.have.lengthOf(1); - expect(requests[0].data.adUnits[0].mediaTypes.video).to.deep.equal(expected); - sinon.assert.calledTwice(utils.logWarn); - }); - }); - - describe('with sChain', function() { - const schain = { - ver: '1.0', - complete: 1, - nodes: [{ - asi: 'ssp.test', - sid: '00001', - hp: 1 - }] - }; - - it('should add the schain if available at bidder level', function() { - const bid01 = new BidRequestBuilder({ schain }).withParams().build(); - const bidderRequest = new BidderRequestBuilder().build(); - - const requests = spec.buildRequests([bid01], bidderRequest); - - expect(requests[0].data).to.have.all.keys(expectedDataKeys); - expect(requests[0].data.schain).to.deep.equal(schain); - }); - - it('Schain should not be added to the request', function() { - const bid01 = new BidRequestBuilder().withParams().build(); - const bidderRequest = new BidderRequestBuilder().build(); - - const requests = spec.buildRequests([bid01], bidderRequest); - - expect(requests[0].data.schain).to.not.exist; - }); - }); - - describe('with GDPR', function() { - const bid01 = new BidRequestBuilder().withParams().build(); - - const consentString = 'BOJ/P2HOJ/P2HABABMAAAAAZ+A=='; - - const gdprConsentBuilderTCF1 = function gdprConsentBuilderTCF1(applies, allows) { - return { - consentString, - gdprApplies: applies, - allowAuctionWithoutConsent: allows, - apiVersion: 1 - }; - }; - - const gdprConsentBuilderTCF2 = function gdprConsentBuilderTCF2(applies) { - return { - consentString, - gdprApplies: applies, - apiVersion: 2 - }; - }; - - context('When GDPR applies', function() { - it('send data.gdpr object to the server from TCF v.1.1 cmp', function() { - const bidderRequest = new BidderRequestBuilder({ - gdprConsent: gdprConsentBuilderTCF1(true, true) - }).build(); - - const expected = { - consentString, - allowAuctionWithoutConsent: 1, - consentRequired: 1, - apiVersion: 1 - }; - - const requests = spec.buildRequests([bid01], bidderRequest); - - expect(requests[0].data.regs.gdpr).to.deep.equal(expected); - }); - - it('send data.gdpr object to the server from TCF v.2 cmp', function() { - const bidderRequest = new BidderRequestBuilder({ - gdprConsent: gdprConsentBuilderTCF2(true) - }).build(); - - const expected = { - consentString, - consentRequired: 1, - apiVersion: 2 - }; - - const requests = spec.buildRequests([bid01], bidderRequest); - - expect(requests[0].data.regs.gdpr).to.deep.equal(expected); - }); - }); - - context('When GDPR does not applies', function() { - it('send data.gdpr object to the server from TCF v.1.1 cmp', function() { - const bidderRequest = new BidderRequestBuilder({ - gdprConsent: gdprConsentBuilderTCF1(false, true) - }).build(); - - const expected = { - consentString, - allowAuctionWithoutConsent: 1, - consentRequired: 0, - apiVersion: 1 - }; - - const requests = spec.buildRequests([bid01], bidderRequest); - - expect(requests[0].data.regs.gdpr).to.deep.equal(expected); - }); - - it('send data.gdpr object to the server from TCF v.2 cmp', function() { - const bidderRequest = new BidderRequestBuilder({ - gdprConsent: gdprConsentBuilderTCF2(false) - }).build(); - - const expected = { - consentString, - consentRequired: 0, - apiVersion: 2 - }; - - const requests = spec.buildRequests([bid01], bidderRequest); - - expect(requests[0].data.regs.gdpr).to.deep.equal(expected); - }); - }); - - context('When GDPR is undefined in bidderRequest', function() { - it('send an empty data.gdpr to the server', function() { - const bidderRequest = new BidderRequestBuilder().build(); - const requests = spec.buildRequests([bid01], bidderRequest); - - expect(requests[0].data.regs.gdpr).to.be.empty; - }); - }); - }); - - describe('with COPPA', function() { - const bid01 = new BidRequestBuilder().withParams().build(); - - it('should send the Coppa "required" flag set to "1" in the request', function () { - const bidderRequest = new BidderRequestBuilder().build(); - - sinon.stub(config, 'getConfig') - .withArgs('coppa') - .returns(true); - - const requests = spec.buildRequests([bid01], bidderRequest); - - expect(requests[0].data.regs.coppa.required).to.equal(1); - - config.getConfig.restore(); - }); - }); - - describe('without COPPA', function() { - const bid01 = new BidRequestBuilder().withParams().build(); - - it('should send the Coppa "required" flag set to "0" in the request', function () { - const bidderRequest = new BidderRequestBuilder().build(); - - const requests = spec.buildRequests([bid01], bidderRequest); - - expect(requests[0].data.regs.coppa.required).to.equal(0); - }); - }); - - describe('with USPrivacy', function() { - const bid01 = new BidRequestBuilder().withParams().build(); - - const consent = 'Y11N'; - - it('should send the USPrivacy "ccpa.uspConsent" in the request', function () { - const bidderRequest = new BidderRequestBuilder({ - uspConsent: consent - }).build(); - - const requests = spec.buildRequests([bid01], bidderRequest); - - expect(requests[0].data.regs.ccpa.uspConsent).to.equal(consent); - }); - }); - - describe('without USPrivacy', function() { - const bid01 = new BidRequestBuilder().withParams().build(); - - it('should have an empty "ccpa" field in the request', function () { - const bidderRequest = new BidderRequestBuilder().build(); - - const requests = spec.buildRequests([bid01], bidderRequest); - - expect(requests[0].data.regs.ccpa).to.be.empty; - }); - }); - - describe('with userID modules', function() { - const userId = { - sharedid: {id: '01EAJWWNEPN3CYMM5N8M5VXY22', third: '01EAJWWNEPN3CYMM5N8M5VXY22'}, - unsuported: '666' - }; - - it('should send "user.eids" in the request for Prebid.js supported modules only', function() { - const bid01 = new BidRequestBuilder({ - userId - }).withParams().build(); - - const bidderRequest = new BidderRequestBuilder().build(); - - const requests = spec.buildRequests([bid01], bidderRequest); - - const expected = [{ - source: 'sharedid.org', - uids: [ - { - atype: 1, - ext: { - third: '01EAJWWNEPN3CYMM5N8M5VXY22' - }, - id: '01EAJWWNEPN3CYMM5N8M5VXY22' - } - ] - }]; - - expect(requests[0].data.user.eids).to.have.lengthOf(1); - expect(requests[0].data.user.eids).to.deep.equal(expected); - }); - - it('should send an empty "user.eids" array in the request if userId module is unsupported', function() { - const bid01 = new BidRequestBuilder({ - userId: { - unsuported: '666' - } - }).withParams().build(); - - const bidderRequest = new BidderRequestBuilder().build(); - - const requests = spec.buildRequests([bid01], bidderRequest); - - expect(requests[0].data.user.eids).to.be.empty; - }); - }); - }); - - describe('interpretResponse()', function() { - let serverResponse = { - body: { - data: { - pred: 1 - }, - bids: [{ - ad: '
', - cpm: 1, - creativeId: 'creativeId', - currency: 'EUR', - height: 250, - netRevenue: true, - requestId: 'c180kg4267tyqz', - ttl: 360, - width: 300, - aDomain: ['advertiser.com'], - mediaType: 'banner', - meta: { - advertiserId: '80', - advertiserName: 'An Advertiser', - networkId: '110' - } - }] - } - }; - - let bidRequest = { - data: { - adUnits: [{ - bidder: 'adagio', - params: { - organizationId: '1000', - placement: 'PAVE_ATF', - site: 'SITE-NAME', - adUnitElementId: 'gpt-adunit-code', - pagetype: 'ARTICLE', - category: 'NEWS', - subcategory: 'SPORT', - environment: 'desktop', - supportIObs: true - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { sizes: [[300, 250], [300, 600]] } - }, - bidId: 'c180kg4267tyqz', - bidderRequestId: '8vfscuixrovn8i', - auctionId: 'lel4fhp239i9km', - pageviewId: 'd8c4fl2k39i0wn', - }] - } - }; - - it('should return an empty response array if body is empty', function() { - expect(spec.interpretResponse({ - body: null - }, bidRequest)).to.be.an('array').length(0); - - expect(spec.interpretResponse({ - body: {} - }, bidRequest)).to.be.an('array').length(0); - }); - - it('should return an empty response array if bids array is empty', function() { - expect(spec.interpretResponse({ - body: { - bids: [] - } - }, bidRequest)).to.be.an('array').length(0); - }); - - it('should handle properly a correct bid response', function() { - let expectedResponse = [{ - ad: '
', - cpm: 1, - creativeId: 'creativeId', - currency: 'EUR', - height: 250, - netRevenue: true, - requestId: 'c180kg4267tyqz', - ttl: 360, - width: 300, - placement: 'PAVE_ATF', - site: 'SITE-NAME', - pagetype: 'ARTICLE', - category: 'NEWS', - subcategory: 'SPORT', - environment: 'desktop', - aDomain: ['advertiser.com'], - mediaType: 'banner', - meta: { - advertiserId: '80', - advertiserName: 'An Advertiser', - advertiserDomains: ['advertiser.com'], - networkId: '110', - mediaType: 'banner' - } - }]; - - expect(spec.interpretResponse(serverResponse, bidRequest)).to.be.an('array'); - expect(spec.interpretResponse(serverResponse, bidRequest)).to.deep.equal(expectedResponse); - }); - - it('Meta props should be limited if no bid.meta is provided', function() { - const altServerResponse = utils.deepClone(serverResponse); - delete altServerResponse.body.bids[0].meta; - - let expectedResponse = [{ - ad: '
', - cpm: 1, - creativeId: 'creativeId', - currency: 'EUR', - height: 250, - netRevenue: true, - requestId: 'c180kg4267tyqz', - ttl: 360, - width: 300, - placement: 'PAVE_ATF', - site: 'SITE-NAME', - pagetype: 'ARTICLE', - category: 'NEWS', - subcategory: 'SPORT', - environment: 'desktop', - aDomain: ['advertiser.com'], - mediaType: 'banner', - meta: { - advertiserDomains: ['advertiser.com'], - mediaType: 'banner' - } - }]; - - expect(spec.interpretResponse(altServerResponse, bidRequest)).to.deep.equal(expectedResponse); - }); - - it('should populate ADAGIO queue with ssp-data', function() { - sandbox.stub(Date, 'now').returns(12345); - - adagioMock.expects('enqueue').withExactArgs({ - action: 'ssp-data', - ts: 12345, - data: serverResponse.body.data - }).once(); - - spec.interpretResponse(serverResponse, bidRequest); - - adagioMock.verify(); - }); - - it('should properly try-catch an exception and return an empty array', function() { - sandbox.stub(adagio, 'enqueue').throws(); - utilsMock.expects('logError').once(); - - expect(spec.interpretResponse(serverResponse, bidRequest)).to.be.an('array').length(0); - - utilsMock.verify(); - }); - - describe('Response with video outstream', () => { - const bidRequestWithOutstream = utils.deepClone(bidRequest); - bidRequestWithOutstream.data.adUnits[0].mediaTypes.video = { - context: 'outstream', - playerSize: [[300, 250]], - mimes: ['video/mp4'], - skip: true - }; - - const serverResponseWithOutstream = utils.deepClone(serverResponse); - serverResponseWithOutstream.body.bids[0].vastXml = ''; - serverResponseWithOutstream.body.bids[0].mediaType = 'video'; - serverResponseWithOutstream.body.bids[0].outstream = { - bvwUrl: 'https://foo.baz', - impUrl: 'https://foo.bar' - }; - - it('should set a renderer in video outstream context', function() { - const bidResponse = spec.interpretResponse(serverResponseWithOutstream, bidRequestWithOutstream)[0]; - expect(bidResponse).to.have.any.keys('outstream', 'renderer', 'mediaType'); - expect(bidResponse.renderer).to.be.a('object'); - expect(bidResponse.renderer.url).to.equal(RENDERER_URL); - expect(bidResponse.renderer.config.bvwUrl).to.be.ok; - expect(bidResponse.renderer.config.impUrl).to.be.ok; - expect(bidResponse.renderer.loaded).to.not.be.ok; - expect(bidResponse.width).to.equal(300); - expect(bidResponse.height).to.equal(250); - expect(bidResponse.vastUrl).to.match(/^data:text\/xml;/) - }); - }); - - describe('Response with native add', () => { - const serverResponseWithNative = utils.deepClone(serverResponse) - serverResponseWithNative.body.bids[0].mediaType = 'native'; - serverResponseWithNative.body.bids[0].admNative = { - ver: '1.2', - link: { - url: 'https://i.am.a.click.url', - clickTrackers: [ - 'https://i.am.a.clicktracker.url' - ] - }, - privacy: 'http://www.myprivacyurl.url', - ext: { - bvw: 'test' - }, - eventtrackers: [ - { - event: 1, - method: 1, - url: 'https://eventrack.local/impression' - }, - { - event: 1, - method: 2, - url: 'https://eventrack.local/impression' - }, - { - event: 2, - method: 1, - url: 'https://eventrack.local/viewable-mrc50' - } - ], - assets: [ - { - required: 1, - title: { - text: 'My title' - } - }, - { - img: { - url: 'https://images.local/image.jpg', - w: 100, - h: 250 - } - }, - { - img: { - type: 1, - url: 'https://images.local/icon.png', - w: 40, - h: 40 - } - }, - { - data: { - type: 1, // sponsored - value: 'Adagio' - } - }, - { - data: { - type: 2, // desc / body - value: 'The super ad text' - } - }, - { - data: { - type: 3, // rating - value: '10 from 10' - } - }, - { - data: { - type: 11, // displayUrl - value: 'https://i.am.a.display.url' - } - } - ] - }; - - const bidRequestNative = utils.deepClone(bidRequest) - bidRequestNative.mediaTypes = { - native: { - sendTargetingKeys: false, - - clickUrl: { - required: true, - }, - title: { - required: true, - }, - body: { - required: true, - }, - sponsoredBy: { - required: false - }, - image: { - required: true - }, - icon: { - required: true - }, - privacyLink: { - required: false - }, - ext: { - adagio_bvw: {} - } - } - }; - - it('Should ignore native parsing due to missing raw admNative property', () => { - const alternateServerResponse = utils.deepClone(serverResponseWithNative); - delete alternateServerResponse.body.bids[0].admNative - const r = spec.interpretResponse(alternateServerResponse, bidRequestNative); - expect(r[0].mediaType).to.equal(NATIVE); - expect(r[0].native).not.ok; - utilsMock.expects('logError').once(); - }); - - it('Should ignore native parsing due to invalid raw admNative.assets property', () => { - const alternateServerResponse = utils.deepClone(serverResponseWithNative); - alternateServerResponse.body.bids[0].admNative.assets = { title: { text: 'test' } }; - const r = spec.interpretResponse(alternateServerResponse, bidRequestNative); - expect(r[0].mediaType).to.equal(NATIVE); - expect(r[0].native).not.ok; - utilsMock.expects('logError').once(); - }); - - it('Should handle and return a formated Native ad', () => { - const r = spec.interpretResponse(serverResponseWithNative, bidRequestNative); - const expected = { - displayUrl: 'https://i.am.a.display.url', - sponsoredBy: 'Adagio', - body: 'The super ad text', - rating: '10 from 10', - clickUrl: 'https://i.am.a.click.url', - title: 'My title', - impressionTrackers: [ - 'https://eventrack.local/impression' - ], - javascriptTrackers: '', - clickTrackers: [ - 'https://i.am.a.clicktracker.url' - ], - image: { - url: 'https://images.local/image.jpg', - width: 100, - height: 250 - }, - icon: { - url: 'https://images.local/icon.png', - width: 40, - height: 40 - }, - ext: { - adagio_bvw: 'test' - }, - privacyLink: 'http://www.myprivacyurl.url' - } - expect(r[0].mediaType).to.equal(NATIVE); - expect(r[0].native).ok; - expect(r[0].native).to.deep.equal(expected); - }); - }); - }); - - describe('getUserSyncs()', function() { - const syncOptions = { - syncEnabled: false - }; - - it('should handle user syncs if data is in the server response ', function() { - const serverResponses = [{ - body: { - userSyncs: [ - { t: 'i', u: 'https://test.url.com/setuid' }, - { t: 'p', u: 'https://test.url.com/setuid' } - ] - } - }]; - - let result = spec.getUserSyncs(syncOptions, serverResponses); - - expect(result[0].type).to.equal('iframe'); - expect(result[0].url).contain('setuid'); - - expect(result[1].type).to.equal('image'); - expect(result[1].url).contain('setuid'); - }); - - it('should return false if data is not in server response', function() { - const serverResponse = [{ body: '' }]; - const result = spec.getUserSyncs(syncOptions, serverResponse); - expect(result).to.equal(false); - }); - }); - - describe('Adagio features', function() { - it('should return all expected features when all expected bidder params are available', function() { - sandbox.stub(window.top.document, 'getElementById').returns( - fixtures.getElementById() - ); - sandbox.stub(window.top, 'getComputedStyle').returns({ display: 'block' }); - - const bidRequest = new BidRequestBuilder({ - 'mediaTypes': { - banner: { sizes: [[300, 250]] } - } - }).withParams().build(); - - const bidderRequest = new BidderRequestBuilder().build(); - - const result = adagio.getFeatures(bidRequest, bidderRequest); - - expect(result.adunit_position).to.match(/^[\d]+x[\d]+$/); - expect(result.page_dimensions).to.match(/^[\d]+x[\d]+$/); - expect(result.viewport_dimensions).to.match(/^[\d]+x[\d]+$/); - expect(result.print_number).to.be.a('String'); - expect(result.dom_loading).to.be.a('String'); - expect(result.user_timestamp).to.be.a('String'); - expect(result.url).to.be.a('String'); - expect(result.device).to.be.a('String'); - expect(result.os).to.be.a('String'); - expect(result.browser).to.be.a('String'); - }); - - it('should return all expected features when `adUnitElementId` param is not available', function() { - const bidRequest = new BidRequestBuilder({ - params: { - organizationId: '1000', - placement: 'PAVE_ATF', - site: 'SITE-NAME' - }, - 'mediaTypes': { - banner: { sizes: [[300, 250]] } - } - }).build(); - - const bidderRequest = new BidderRequestBuilder().build(); - - const result = adagio.getFeatures(bidRequest, bidderRequest); - - expect(result.adunit_position).to.not.exist; - expect(result.page_dimensions).to.be.a('String'); - expect(result.viewport_dimensions).to.be.a('String'); - expect(result.print_number).to.be.a('String'); - expect(result.dom_loading).to.be.a('String'); - expect(result.user_timestamp).to.be.a('String'); - expect(result.url).to.be.a('String'); - expect(result.device).to.be.a('String'); - expect(result.os).to.be.a('String'); - expect(result.browser).to.be.a('String'); - }); - - it('should not return feature with an empty value', function() { - sandbox.stub(_features, 'getDomLoadingDuration').returns(''); - sandbox.stub(_features, 'getUrl').returns(''); - sandbox.stub(_features, 'getBrowser').returns(''); - - const bidRequest = new BidRequestBuilder({ - 'mediaTypes': { - banner: { sizes: [[300, 250]] } - } - }).withParams().build(); - - const bidderRequest = new BidderRequestBuilder().build(); - - const result = adagio.getFeatures(bidRequest, bidderRequest); - - expect(result.adunit_position).to.not.exist; - expect(result.page_dimensions).to.exist; - expect(result.viewport_dimensions).to.exist; - expect(result.print_number).to.exist; - expect(result.dom_loading).to.not.exist; - expect(result.user_timestamp).to.exist; - expect(result.url).to.not.exist; - expect(result.device).to.exist; - expect(result.os).to.exist; - expect(result.browser).to.not.exist; - }); - - describe('getPageDimensions feature', function() { - afterEach(() => { - delete window.$sf; - }); - - it('should not compute the page dimensions in cross-origin iframe', function() { - sandbox.stub(utils, 'getWindowTop').throws(); - const result = _features.getPageDimensions(); - expect(result).to.eq(''); - }); - - it('should not compute the page dimensions even with safeFrame api', function() { - window.$sf = $sf; - const result = _features.getPageDimensions(); - expect(result).to.eq(''); - }); - - it('should not compute the page dimensions if is not in the DOM', function() { - sandbox.stub(window.top.document, 'querySelector').withArgs('body').returns(null); - const result = _features.getPageDimensions(); - expect(result).to.eq(''); - }); - - it('should compute the page dimensions based on body and viewport dimensions', function() { - sandbox.stub(window.top.document, 'querySelector').withArgs('body').returns({ scrollWidth: 1360, offsetWidth: 1280, scrollHeight: 2000, offsetHeight: 1000 }); - const result = _features.getPageDimensions(); - expect(result).to.eq('1360x2000'); - }); - }); - - describe('getViewPortDimensions feature', function() { - afterEach(() => { - delete window.$sf; - }); - - it('should not compute the viewport dimensions in cross-origin iframe', function() { - sandbox.stub(utils, 'getWindowTop').throws(); - const result = _features.getViewPortDimensions(); - expect(result).to.eq(''); - }); - - it('should compute the viewport dimensions in cross-origin iframe w/ safeFrame api', function() { - window.$sf = $sf; - sandbox.stub(window.$sf.ext, 'geom').returns({ - 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}, - }); - const result = _features.getViewPortDimensions(); - expect(result).to.eq('1920x1177'); - }); - - it('should not compute the viewport dimensions if safeFrame api is misimplemented', function() { - window.$sf = { - ext: { geom: 'nothing' } - }; - const result = _features.getViewPortDimensions(); - expect(result).to.eq(''); - }); - - it('should not compute the viewport dimensions if is not in the DOM', function() { - const querySelectorSpy = sandbox.spy(() => null); - sandbox.stub(utils, 'getWindowTop').returns({ - location: { href: 'https://mytest.io' }, - document: { querySelector: querySelectorSpy } - }); - const result = _features.getViewPortDimensions(); - expect(result).to.eq(''); - }); - - it('should compute the viewport dimensions based on window', function() { - sandbox.stub(utils, 'getWindowTop').returns({ - location: { href: 'https://mytest.io' }, - innerWidth: 960, - innerHeight: 3000 - }); - const result = _features.getViewPortDimensions(); - expect(result).to.eq('960x3000'); - }); - - it('should compute the viewport dimensions based on body', function() { - const querySelectorSpy = sandbox.spy(() => ({ clientWidth: 1024, clientHeight: 2000 })); - sandbox.stub(utils, 'getWindowTop').returns({ - location: { href: 'https://mytest.io' }, - document: { querySelector: querySelectorSpy } - }); - const result = _features.getViewPortDimensions(); - expect(result).to.eq('1024x2000'); - }); - }); - - describe('getSlotPosition feature', function() { - let getElementByIdStub; - let getComputedStyleStub; - - beforeEach(() => { - getElementByIdStub = sandbox.stub(window.top.document, 'getElementById'); - getElementByIdStub.returns(fixtures.getElementById()); - getComputedStyleStub = sandbox.stub(window.top, 'getComputedStyle'); - getComputedStyleStub.returns({ display: 'block' }); - }); - - afterEach(() => { - delete window.$sf; - getElementByIdStub.restore(); - getComputedStyleStub.restore(); - }); - - it('should not compute the slot position in cross-origin iframe', function() { - sandbox.stub(utils, 'getWindowTop').throws(); - const result = _features.getSlotPosition({ adUnitElementId: 'gpt-adunit-code', postBid: false }); - expect(result).to.eq(''); - }); - - it('should compute the slot position in cross-origin iframe w/ safeFrame api', function() { - window.$sf = $sf; - sandbox.stub(window.$sf.ext, 'geom').returns({ - 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}, - }); - const result = _features.getSlotPosition({ adUnitElementId: 'gpt-adunit-code', postBid: false }); - expect(result).to.eq('210x859'); - }); - - it('should not compute the slot position if safeFrame api is misimplemented', function() { - window.$sf = { - ext: { geom: 'nothing' } - }; - utilsMock.expects('logWarn').once(); - const result = _features.getSlotPosition({ adUnitElementId: 'gpt-adunit-code', postBid: false }); - expect(result).to.eq(''); - utilsMock.verify(); - }); - - it('should not compute the slot position due to unreachable adUnitElementId', function() { - getElementByIdStub.returns(null); - const result = _features.getSlotPosition({ adUnitElementId: 'gpt-adunit-code', postBid: false }); - expect(result).to.eq(''); - }); - - it('should use a quick switch to display slot and compute position', function() { - getComputedStyleStub.returns({ display: 'none' }); - const result = _features.getSlotPosition({ adUnitElementId: 'gpt-adunit-code', postBid: false }); - expect(result).to.eq('800x300'); - }); - - it('should compute the slot position based on window.top w/o postBid param', function() { - const result = _features.getSlotPosition({ adUnitElementId: 'gpt-adunit-code', postBid: false }); - expect(result).to.eq('800x300'); - }); - - it.skip('should compute the slot position inside the parent window (window.top) when safeFrame is not available and postBid params is `true`', function() { - const result = _features.getSlotPosition({ adUnitElementId: 'gpt-adunit-code', postBid: true }); - // expect(result).to.eq('800x300'); - }); - }); - }); - - describe('optional params auto detection', function() { - it('should auto detect environment', function() { - const getDeviceStub = sandbox.stub(_features, 'getDevice'); - - getDeviceStub.returns(5); - expect(adagio.autoDetectEnvironment()).to.eq('tablet'); - - getDeviceStub.returns(4); - expect(adagio.autoDetectEnvironment()).to.eq('mobile'); - - getDeviceStub.returns(2); - expect(adagio.autoDetectEnvironment()).to.eq('desktop'); - }); - - it('should auto detect adUnitElementId when GPT is used', function() { - sandbox.stub(utils, 'getGptSlotInfoForAdUnitCode').withArgs('banner').returns({divId: 'gpt-banner'}); - expect(adagio.autoDetectAdUnitElementId('banner')).to.eq('gpt-banner'); - }); - }); - - describe('print number handling', function() { - it('should return 1 if no adunit-code found. This means it is the first auction', function() { - sandbox.stub(adagio, 'getPageviewId').returns('abc-def'); - expect(adagio.computePrintNumber('adunit-code')).to.eql(1); - }); - - it('should increment the adunit print number when the adunit-code has already been used for an other auction', function() { - sandbox.stub(adagio, 'getPageviewId').returns('abc-def'); - - window.top.ADAGIO.adUnits['adunit-code'] = { - pageviewId: 'abc-def', - printNumber: 1, - }; - - expect(adagio.computePrintNumber('adunit-code')).to.eql(2); - }); - }); - - describe('site information using refererDetection or window.top', function() { - it('should returns domain, page and window.referrer in a window.top context', function() { - sandbox.stub(utils, 'getWindowTop').returns({ - location: { - hostname: 'test.io', - href: 'https://test.io/article/a.html' - }, - document: { - referrer: 'https://google.com' - } - }); - - const bidderRequest = new BidderRequestBuilder({ - refererInfo: { - numIframes: 0, - reachedTop: true, - referer: 'http://test.io/index.html?pbjs_debug=true' - } - }).build(); - - expect(adagio.getSite(bidderRequest)).to.deep.equal({ - domain: 'test.io', - page: 'https://test.io/article/a.html', - referrer: 'https://google.com' - }); - }); - - it('should returns domain and page in a cross-domain w/ top domain reached context', function() { - sandbox.stub(utils, 'getWindowTop').throws(); - - const info = { - numIframes: 0, - reachedTop: true, - referer: 'http://level.io/', - stack: [ - 'http://level.io/', - 'http://example.com/iframe1.html', - 'http://example.com/iframe2.html' - ], - canonicalUrl: '' - }; - - const bidderRequest = new BidderRequestBuilder({ - refererInfo: info - }).build(); - - expect(adagio.getSite(bidderRequest)).to.deep.equal({ - domain: 'level.io', - page: 'http://level.io/', - referrer: '' - }); - }); - - it('should not return anything in a cross-domain w/o top domain reached and w/o ancestor context', function() { - sandbox.stub(utils, 'getWindowTop').throws(); - - const info = { - numIframes: 2, - reachedTop: false, - referer: 'http://example.com/iframe1.html', - stack: [ - null, - 'http://example.com/iframe1.html', - 'http://example.com/iframe2.html' - ], - canonicalUrl: '' - }; - - const bidderRequest = new BidderRequestBuilder({ - refererInfo: info - }).build(); - - expect(adagio.getSite(bidderRequest)).to.deep.equal({ - domain: '', - page: '', - referrer: '' - }); - }); - - it('should return domain only in a cross-domain w/o top domain reached and w/ ancestors context', function() { - sandbox.stub(utils, 'getWindowTop').throws(); - - const info = { - numIframes: 2, - reachedTop: false, - referer: 'http://example.com/iframe1.html', - stack: [ - 'http://mytest.com/', - 'http://example.com/iframe1.html', - 'http://example.com/iframe2.html' - ], - canonicalUrl: '' - }; - - const bidderRequest = new BidderRequestBuilder({ - refererInfo: info - }).build(); - - expect(adagio.getSite(bidderRequest)).to.deep.equal({ - domain: 'mytest.com', - page: '', - referrer: '' - }); - }); - }); - - describe('adagioScriptFromLocalStorageCb()', function() { - const VALID_HASH = 'Lddcw3AADdQDrPtbRJkKxvA+o1CtScGDIMNRpHB3NnlC/FYmy/9RKXelKrYj/sjuWusl5YcOpo+lbGSkk655i8EKuDiOvK6ae/imxSrmdziIp+S/TA6hTFJXcB8k1Q9OIp4CMCT52jjXgHwX6G0rp+uYoCR25B1jHaHnpH26A6I='; - const INVALID_HASH = 'invalid'; - const VALID_SCRIPT_CONTENT = 'var _ADAGIO=function(){};(_ADAGIO)();\n'; - const INVALID_SCRIPT_CONTENT = 'var _ADAGIO=function(){//corrupted};(_ADAGIO)();\n'; - const ADAGIO_LOCALSTORAGE_KEY = 'adagioScript'; - - beforeEach(function() { - localStorage.removeItem(ADAGIO_LOCALSTORAGE_KEY); - }); - - describe('getAdagioScript', function() { - it('should run storage.getDataFromLocalStorage callback and call adagioScriptFromLocalStorageCb() ', function() { - sandbox.spy(adagio, 'adagioScriptFromLocalStorageCb'); - const getDataFromLocalStorageStub = sandbox.stub(storage, 'getDataFromLocalStorage').callsArg(1); - localStorage.setItem(ADAGIO_LOCALSTORAGE_KEY, '// hash: ' + VALID_HASH + '\n' + VALID_SCRIPT_CONTENT); - - getAdagioScript(); - - sinon.assert.callCount(getDataFromLocalStorageStub, 1); - sinon.assert.callCount(adagio.adagioScriptFromLocalStorageCb, 1); - }); - - it('should load external script if the user consent', function() { - sandbox.stub(storage, 'localStorageIsEnabled').callsArgWith(0, true); - getAdagioScript(); - - expect(loadExternalScript.called).to.be.true; - }); - - it('should not load external script if the user does not consent', function() { - sandbox.stub(storage, 'localStorageIsEnabled').callsArgWith(0, false); - getAdagioScript(); - - expect(loadExternalScript.called).to.be.false; - }); - - it('should remove the localStorage key if exists and the user does not consent', function() { - sandbox.stub(storage, 'localStorageIsEnabled').callsArgWith(0, false); - localStorage.setItem(ADAGIO_LOCALSTORAGE_KEY, 'the script'); - - getAdagioScript(); - - expect(loadExternalScript.called).to.be.false; - expect(localStorage.getItem(ADAGIO_LOCALSTORAGE_KEY)).to.be.null; - }); - }); - - it('should verify valid hash with valid script', function () { - localStorage.setItem(ADAGIO_LOCALSTORAGE_KEY, '// hash: ' + VALID_HASH + '\n' + VALID_SCRIPT_CONTENT); - - utilsMock.expects('logInfo').withExactArgs('Adagio: start script.').once(); - utilsMock.expects('logWarn').withExactArgs('Adagio: no hash found.').never(); - utilsMock.expects('logWarn').withExactArgs('Adagio: invalid script found.').never(); - - adagioScriptFromLocalStorageCb(localStorage.getItem(ADAGIO_LOCALSTORAGE_KEY)); - - expect(localStorage.getItem(ADAGIO_LOCALSTORAGE_KEY)).to.equals('// hash: ' + VALID_HASH + '\n' + VALID_SCRIPT_CONTENT); - utilsMock.verify(); - }); - - it('should verify valid hash with invalid script', function () { - localStorage.setItem(ADAGIO_LOCALSTORAGE_KEY, '// hash: ' + VALID_HASH + '\n' + INVALID_SCRIPT_CONTENT); - - utilsMock.expects('logInfo').withExactArgs('Adagio: start script').never(); - utilsMock.expects('logWarn').withExactArgs('Adagio: no hash found.').never(); - utilsMock.expects('logWarn').withExactArgs('Adagio: invalid script found.').once(); - - adagioScriptFromLocalStorageCb(localStorage.getItem(ADAGIO_LOCALSTORAGE_KEY)); - - expect(localStorage.getItem(ADAGIO_LOCALSTORAGE_KEY)).to.be.null; - utilsMock.verify(); - }); - - it('should verify invalid hash with valid script', function () { - localStorage.setItem(ADAGIO_LOCALSTORAGE_KEY, '// hash: ' + INVALID_HASH + '\n' + VALID_SCRIPT_CONTENT); - - utilsMock.expects('logInfo').withExactArgs('Adagio: start script').never(); - utilsMock.expects('logWarn').withExactArgs('Adagio: no hash found.').never(); - utilsMock.expects('logWarn').withExactArgs('Adagio: invalid script found.').once(); - - adagioScriptFromLocalStorageCb(localStorage.getItem(ADAGIO_LOCALSTORAGE_KEY)); - - expect(localStorage.getItem(ADAGIO_LOCALSTORAGE_KEY)).to.be.null; - utilsMock.verify(); - }); - - it('should verify missing hash', function () { - localStorage.setItem(ADAGIO_LOCALSTORAGE_KEY, VALID_SCRIPT_CONTENT); - - utilsMock.expects('logInfo').withExactArgs('Adagio: start script').never(); - utilsMock.expects('logWarn').withExactArgs('Adagio: no hash found.').once(); - utilsMock.expects('logWarn').withExactArgs('Adagio: invalid script found.').never(); - - adagioScriptFromLocalStorageCb(localStorage.getItem(ADAGIO_LOCALSTORAGE_KEY)); - - expect(localStorage.getItem(ADAGIO_LOCALSTORAGE_KEY)).to.be.null; - utilsMock.verify(); - }); - - it('should return false if content script does not exist in localStorage', function() { - sandbox.spy(utils, 'logWarn'); - expect(adagioScriptFromLocalStorageCb(null)).to.be.undefined; - sinon.assert.callCount(utils.logWarn, 1); - sinon.assert.calledWith(utils.logWarn, 'Adagio: script not found.'); - }); - }); -}); diff --git a/test/spec/modules/adbutlerBidAdapter_spec.js b/test/spec/modules/adbutlerBidAdapter_spec.js deleted file mode 100644 index 6dedce321d8..00000000000 --- a/test/spec/modules/adbutlerBidAdapter_spec.js +++ /dev/null @@ -1,231 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/adbutlerBidAdapter.js'; - -describe('AdButler adapter', function () { - let bidRequests; - - beforeEach(function () { - bidRequests = [ - { - bidder: 'adbutler', - params: { - accountID: '167283', - zoneID: '210093', - keyword: 'red', - minCPM: '1.00', - maxCPM: '5.00', - extra: { - foo: 'bar', - } - }, - placementCode: '/19968336/header-bid-tag-1', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - }, - }, - bidId: '23acc48ad47af5', - auctionId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - } - ]; - }); - - describe('implementation', function () { - describe('for requests', function () { - it('should accept valid bid', function () { - let validBid = { - bidder: 'adbutler', - params: { - accountID: '167283', - zoneID: '210093' - } - }, - isValid = spec.isBidRequestValid(validBid); - - expect(isValid).to.equal(true); - }); - - it('should reject invalid bid', function () { - let invalidBid = { - bidder: 'adbutler', - params: { - accountID: '167283', - } - }, - isValid = spec.isBidRequestValid(invalidBid); - - expect(isValid).to.equal(false); - }); - - it('should use custom domain string', function () { - let bidRequests = [ - { - bidId: '3c9408cdbf2f68', - sizes: [[300, 250]], - bidder: 'adbutler', - params: { - accountID: '107878', - zoneID: '86133', - domain: 'servedbyadbutler.com.dan.test' - }, - auctionId: '10b327aa396609', - placementCode: '/123456/header-bid-tag-1' - } - ], - requests = spec.buildRequests(bidRequests), - requestURL = requests[0].url; - - expect(requestURL).to.have.string('.dan.test'); - }); - - it('should set default domain', function () { - let requests = spec.buildRequests(bidRequests), - request = requests[0]; - - let [domain] = request.url.split('/adserve/'); - - expect(domain).to.equal('https://servedbyadbutler.com'); - }); - - it('should set the keyword parameter', function () { - let requests = spec.buildRequests(bidRequests), - requestURL = requests[0].url; - - expect(requestURL).to.have.string(';kw=red;'); - }); - - it('should set the extra parameter', () => { - let requests = spec.buildRequests(bidRequests); - let requestURL = requests[0].url; - - expect(requestURL).to.have.string(';foo=bar;'); - }); - - it('should increment the count for the same zone', function () { - let bidRequests = [ - { - sizes: [[300, 250]], - bidder: 'adbutler', - params: { - accountID: '107878', - zoneID: '86133', - } - }, { - sizes: [[300, 250]], - bidder: 'adbutler', - params: { - accountID: '107878', - zoneID: '86133', - } - }, - ], - requests = spec.buildRequests(bidRequests), - firstRequest = requests[0].url, - secondRequest = requests[1].url; - - expect(firstRequest).to.have.string(';place=0;'); - expect(secondRequest).to.have.string(';place=1;'); - }); - }); - - describe('bid responses', function () { - it('should return complete bid response', function () { - let serverResponse = { - body: { - status: 'SUCCESS', - account_id: 167283, - zone_id: 210093, - cpm: 1.5, - width: 300, - height: 250, - place: 0, - ad_code: '', - tracking_pixels: [ - 'http://tracking.pixel.com/params=info' - ] - } - }, - bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); - - expect(bids).to.be.lengthOf(1); - - expect(bids[0].bidderCode).to.equal('adbutler'); - expect(bids[0].cpm).to.equal(1.5); - expect(bids[0].width).to.equal(300); - expect(bids[0].height).to.equal(250); - expect(bids[0].currency).to.equal('USD'); - expect(bids[0].netRevenue).to.equal(true); - expect(bids[0].ad).to.have.length.above(1); - expect(bids[0].ad).to.have.string('http://tracking.pixel.com/params=info'); - }); - - it('should return empty bid response', function () { - let serverResponse = { - body: { - status: 'NO_ELIGIBLE_ADS', - zone_id: 210083, - width: 300, - height: 250, - place: 0 - } - }, - bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); - - expect(bids).to.be.lengthOf(0); - }); - - it('should return empty bid response on incorrect size', function () { - let serverResponse = { - body: { - status: 'SUCCESS', - account_id: 167283, - zone_id: 210083, - cpm: 1.5, - width: 728, - height: 90, - place: 0 - } - }, - bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); - - expect(bids).to.be.lengthOf(0); - }); - - it('should return empty bid response with CPM too low', function () { - let serverResponse = { - body: { - status: 'SUCCESS', - account_id: 167283, - zone_id: 210093, - cpm: 0.75, - width: 300, - height: 250, - place: 0 - } - }, - bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); - - expect(bids).to.be.lengthOf(0); - }); - - it('should return empty bid response with CPM too high', function () { - let serverResponse = { - body: { - status: 'SUCCESS', - account_id: 167283, - zone_id: 210093, - cpm: 7, - width: 300, - height: 250, - place: 0 - } - }, - bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); - - expect(bids).to.be.lengthOf(0); - }); - }); - }); -}); diff --git a/test/spec/modules/addefendBidAdapter_spec.js b/test/spec/modules/addefendBidAdapter_spec.js deleted file mode 100644 index ac01750e98f..00000000000 --- a/test/spec/modules/addefendBidAdapter_spec.js +++ /dev/null @@ -1,184 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/addefendBidAdapter.js'; - -describe('addefendBidAdapter', () => { - const defaultBidRequest = { - bidId: 'd66fa86787e0b0ca900a96eacfd5f0bb', - auctionId: 'ccc4c7cdfe11cfbd74065e6dd28413d8', - transactionId: 'd58851660c0c4461e4aa06344fc9c0c6', - sizes: [[300, 250], [300, 600]], - params: { - pageId: 'stringid1', - placementId: 'stringid2' - } - }; - - const deepClone = function (val) { - return JSON.parse(JSON.stringify(val)); - }; - - const buildRequest = (buildRequest, bidderRequest) => { - if (!Array.isArray(buildRequest)) { - buildRequest = [buildRequest]; - } - - return spec.buildRequests(buildRequest, { - ...bidderRequest || {}, - refererInfo: { - referer: 'https://referer.example.com' - } - })[0]; - }; - - describe('isBidRequestValid', () => { - it('should return true when required params found', () => { - const bidRequest = deepClone(defaultBidRequest); - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }); - - it('pageId performs type checking', () => { - const bidRequest = deepClone(defaultBidRequest); - bidRequest.params.pageId = 1; // supposed to be a string - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('placementId performs type checking', () => { - const bidRequest = deepClone(defaultBidRequest); - bidRequest.params.placementId = 1; // supposed to be a string - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when required params are not passed', () => { - const bidRequest = deepClone(defaultBidRequest); - delete bidRequest.params; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - }); - - describe('buildRequests', () => { - const bidRequest = deepClone(defaultBidRequest); - const request = buildRequest(bidRequest); - - it('sends bid request to endpoint via https using post', () => { - expect(request.method).to.equal('POST'); - expect(request.url.indexOf('https://')).to.equal(0); - expect(request.url).to.equal(`${spec.hostname}/bid`); - }); - - it('contains prebid version parameter', () => { - expect(request.data.v).to.equal($$PREBID_GLOBAL$$.version); - }); - - it('contains correct referer', () => { - expect(request.data.referer).to.equal('https://referer.example.com'); - }); - - it('contains auctionId', () => { - expect(request.data.auctionId).to.equal('ccc4c7cdfe11cfbd74065e6dd28413d8'); - }); - - it('contains pageId', () => { - expect(request.data.pageId).to.equal('stringid1'); - }); - - it('sends correct bid parameters', () => { - const bidRequest = deepClone(defaultBidRequest); - expect(request.data.bids).to.deep.equal([ { - bidId: bidRequest.bidId, - placementId: bidRequest.params.placementId, - sizes: [ '300x250', '300x600' ], - transactionId: 'd58851660c0c4461e4aa06344fc9c0c6' - } ]); - }); - - it('handles empty gdpr object', () => { - const bidRequest = deepClone(defaultBidRequest); - const request = buildRequest(bidRequest, { - gdprConsent: {} - }); - expect(request.data.gdpr_consent).to.be.equal(''); - }); - - it('handles non-existent gdpr object', () => { - const bidRequest = deepClone(defaultBidRequest); - const request = buildRequest(bidRequest, { - gdprConsent: null - }); - expect(request.data.gdpr_consent).to.be.equal(''); - }); - - it('handles properly filled gdpr string', () => { - const bidRequest = deepClone(defaultBidRequest); - const consentString = 'GDPR_CONSENT_STRING'; - const request = buildRequest(bidRequest, { - gdprConsent: { - gdprApplies: true, - consentString: consentString - } - }); - - expect(request.data.gdpr_consent).to.be.equal(consentString); - }); - }); - - describe('interpretResponse', () => { - it('should get correct bid response', () => { - const serverResponse = [ - { - 'width': 300, - 'height': 250, - 'creativeId': '29681110', - 'ad': '', - 'cpm': 0.5, - 'requestId': 'ccc4c7cdfe11cfbd74065e6dd28413d8', - 'ttl': 120, - 'netRevenue': true, - 'currency': 'EUR', - 'advertiserDomains': ['advertiser.example.com'] - } - ]; - - const expectedResponse = [ - { - 'requestId': 'ccc4c7cdfe11cfbd74065e6dd28413d8', - 'cpm': 0.5, - 'creativeId': '29681110', - 'width': 300, - 'height': 250, - 'ttl': 120, - 'currency': 'EUR', - 'ad': '', - 'netRevenue': true, - 'advertiserDomains': ['advertiser.example.com'] - } - ]; - - 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]); - }); - }); - - it('handles incomplete server response', () => { - const serverResponse = [ - { - 'ad': '', - 'cpm': 0.5, - 'requestId': 'ccc4c7cdfe11cfbd74065e6dd28413d8', - 'ttl': 60 - } - ]; - const result = spec.interpretResponse({body: serverResponse}); - - expect(result.length).to.equal(0); - }); - - it('handles nobid responses', () => { - const 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 deleted file mode 100644 index 2c141d31bf8..00000000000 --- a/test/spec/modules/adfBidAdapter_spec.js +++ /dev/null @@ -1,682 +0,0 @@ -// jshint esversion: 6, es3: false, node: true -import {assert, expect} from 'chai'; -import {spec} from 'modules/adfBidAdapter.js'; -import { NATIVE } from 'src/mediaTypes.js'; -import { config } from 'src/config.js'; -import { createEidsArray } from 'modules/userId/eids.js'; - -describe('Adf adapter', function () { - let serverResponse, bidRequest, bidResponses; - let bids = []; - - describe('backwards-compatibility', function () { - it('should have adformOpenRTB alias defined', function () { - assert.equal(spec.aliases[0].code, 'adformOpenRTB'); - assert.equal(spec.aliases[0].gvlid, 50); - }); - }); - - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'adformOpenRTB', - 'params': { - 'mid': '19910113' - } - }; - - it('should return true when required params found', function () { - assert(spec.isBidRequestValid(bid)); - }); - - it('should return false when required params are missing', function () { - bid.params = { adxDomain: 'adx.adform.net' }; - assert.isFalse(spec.isBidRequestValid(bid)); - }); - }); - - describe('buildRequests', function () { - it('should send request with correct structure', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: { - siteId: 'siteId', - adxDomain: '10.8.57.207' - } - }]; - let request = spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }); - - assert.equal(request.method, 'POST'); - assert.equal(request.url, 'https://10.8.57.207/adx/openrtb'); - assert.deepEqual(request.options, {contentType: 'application/json'}); - assert.ok(request.data); - }); - - describe('user privacy', function () { - it('should send GDPR Consent data to adform if gdprApplies', function () { - let validBidRequests = [{ bidId: 'bidId', params: { siteId: 'siteId', test: 1 } }]; - let bidderRequest = { gdprConsent: { gdprApplies: true, consentString: 'consentDataString' }, refererInfo: { referer: 'page' } }; - let request = JSON.parse(spec.buildRequests(validBidRequests, bidderRequest).data); - - assert.equal(request.user.ext.consent, bidderRequest.gdprConsent.consentString); - assert.equal(request.regs.ext.gdpr, bidderRequest.gdprConsent.gdprApplies); - assert.equal(typeof request.regs.ext.gdpr, 'number'); - }); - - it('should send gdpr as number', function () { - let validBidRequests = [{ bidId: 'bidId', params: { siteId: 'siteId', test: 1 } }]; - let bidderRequest = { gdprConsent: { gdprApplies: true, consentString: 'consentDataString' }, refererInfo: { referer: 'page' } }; - let request = JSON.parse(spec.buildRequests(validBidRequests, bidderRequest).data); - - assert.equal(typeof request.regs.ext.gdpr, 'number'); - assert.equal(request.regs.ext.gdpr, 1); - }); - - it('should send CCPA Consent data to adform', function () { - let validBidRequests = [{ bidId: 'bidId', params: { siteId: 'siteId', test: 1 } }]; - let bidderRequest = { uspConsent: '1YA-', refererInfo: { referer: 'page' } }; - let request = JSON.parse(spec.buildRequests(validBidRequests, bidderRequest).data); - - assert.equal(request.regs.ext.us_privacy, '1YA-'); - - bidderRequest = { uspConsent: '1YA-', gdprConsent: { gdprApplies: true, consentString: 'consentDataString' }, refererInfo: { referer: 'page' } }; - request = JSON.parse(spec.buildRequests(validBidRequests, bidderRequest).data); - - assert.equal(request.regs.ext.us_privacy, '1YA-'); - assert.equal(request.user.ext.consent, 'consentDataString'); - assert.equal(request.regs.ext.gdpr, 1); - }); - - it('should not send GDPR Consent data to adform if gdprApplies is undefined', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId' } - }]; - let bidderRequest = {gdprConsent: {gdprApplies: false, consentString: 'consentDataString'}, refererInfo: { referer: 'page' }}; - let request = JSON.parse(spec.buildRequests(validBidRequests, bidderRequest).data); - - assert.equal(request.user.ext.consent, 'consentDataString'); - assert.equal(request.regs.ext.gdpr, 0); - - bidderRequest = {gdprConsent: {consentString: 'consentDataString'}, refererInfo: { referer: 'page' }}; - request = JSON.parse(spec.buildRequests(validBidRequests, bidderRequest).data); - - assert.equal(request.user, undefined); - assert.equal(request.regs, undefined); - }); - it('should send default GDPR Consent data to adform', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId' } - }]; - let request = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data); - - assert.equal(request.user, undefined); - assert.equal(request.regs, undefined); - }); - }); - - it('should add test and is_debug to request, if test is set in parameters', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId', test: 1 } - }]; - let request = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data); - - assert.ok(request.is_debug); - assert.equal(request.test, 1); - }); - - it('should have default request structure', function () { - let keys = 'site,device,source,ext,imp'.split(','); - let validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId' } - }]; - let request = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data); - let data = Object.keys(request); - - assert.deepEqual(keys, data); - }); - - it('should set request keys correct values', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId' }, - transactionId: 'transactionId' - }]; - let request = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data); - - assert.equal(request.source.tid, validBidRequests[0].transactionId); - assert.equal(request.source.fd, 1); - }); - - it('should send info about device', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId' } - }]; - let request = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data); - - assert.equal(request.device.ua, navigator.userAgent); - }); - it('should send info about the site', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId', publisher: {id: '123123', domain: 'publisher.domain.com', name: 'publisher\'s name'} } - }]; - let refererInfo = { referer: 'page' }; - let request = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo }).data); - - assert.deepEqual(request.site, { - page: refererInfo.referer, - publisher: validBidRequests[0].params.publisher, - id: validBidRequests[0].params.siteId - }); - }); - - it('should pass extended ids', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: {}, - userIdAsEids: createEidsArray({ - tdid: 'TTD_ID_FROM_USER_ID_MODULE', - pubcid: 'pubCommonId_FROM_USER_ID_MODULE' - }) - }]; - - let request = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data); - assert.deepEqual(request.user.ext.eids, [ - { 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 } ] } - ]); - }); - - it('should send currency if defined', function () { - config.setConfig({ currency: { adServerCurrency: 'EUR' } }); - let validBidRequests = [{ params: {} }]; - let refererInfo = { referer: 'page' }; - let request = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo }).data); - - assert.deepEqual(request.cur, [ 'EUR' ]); - }); - - describe('priceType', function () { - it('should send default priceType', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId' } - }]; - let request = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data); - - assert.equal(request.ext.pt, 'net'); - }); - it('should send correct priceType value', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId', priceType: 'net' } - }]; - let request = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data); - - assert.equal(request.ext.pt, 'net'); - }); - }); - - describe('bids', function () { - it('should add more than one bid to the request', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId' } - }, { - bidId: 'bidId2', - params: { siteId: 'siteId' } - }]; - let request = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data); - - assert.equal(request.imp.length, 2); - }); - it('should add incrementing values of id', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId' } - }, { - bidId: 'bidId2', - params: { siteId: 'siteId' } - }, { - bidId: 'bidId3', - params: { siteId: 'siteId' } - }]; - let imps = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data).imp; - - for (let i = 0; i < 3; i++) { - assert.equal(imps[i].id, i + 1); - } - }); - - it('should add mid', function () { - let validBidRequests = [{ bidId: 'bidId', params: { siteId: 'siteId', mid: 1000 } }, - { bidId: 'bidId2', params: { siteId: 'siteId', mid: 1001 } }, - { bidId: 'bidId3', params: { siteId: 'siteId', mid: 1002 } }]; - let imps = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data).imp; - for (let i = 0; i < 3; i++) { - assert.equal(imps[i].tagid, validBidRequests[i].params.mid); - } - }); - - describe('native', function () { - describe('assets', function () { - it('should set correct asset id', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId', mid: 1000 }, - nativeParams: { - title: { required: true, len: 140 }, - image: { required: false, wmin: 836, hmin: 627, w: 325, h: 300, mimes: ['image/jpg', 'image/gif'] }, - body: { len: 140 } - } - }]; - let assets = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data).imp[0].native.request.assets; - - assert.equal(assets[0].id, 0); - assert.equal(assets[1].id, 3); - assert.equal(assets[2].id, 4); - }); - it('should add required key if it is necessary', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId', mid: 1000 }, - nativeParams: { - title: { required: true, len: 140 }, - image: { required: false, wmin: 836, hmin: 627, w: 325, h: 300, mimes: ['image/jpg', 'image/gif'] }, - body: { len: 140 }, - sponsoredBy: { required: true, len: 140 } - } - }]; - - let assets = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data).imp[0].native.request.assets; - - assert.equal(assets[0].required, 1); - assert.ok(!assets[1].required); - assert.ok(!assets[2].required); - assert.equal(assets[3].required, 1); - }); - - it('should map img and data assets', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId', mid: 1000 }, - nativeParams: { - title: { required: true, len: 140 }, - image: { required: true, sizes: [150, 50] }, - icon: { required: false, sizes: [50, 50] }, - body: { required: false, len: 140 }, - sponsoredBy: { required: true }, - cta: { required: false }, - clickUrl: { required: false } - } - }]; - - let assets = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data).imp[0].native.request.assets; - assert.ok(assets[0].title); - assert.equal(assets[0].title.len, 140); - assert.deepEqual(assets[1].img, { type: 3, w: 150, h: 50 }); - assert.deepEqual(assets[2].img, { type: 1, w: 50, h: 50 }); - assert.deepEqual(assets[3].data, { type: 2, len: 140 }); - assert.deepEqual(assets[4].data, { type: 1 }); - assert.deepEqual(assets[5].data, { type: 12 }); - assert.ok(!assets[6]); - }); - - describe('icon/image sizing', function () { - it('should flatten sizes and utilise first pair', function () { - const validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId', mid: 1000 }, - nativeParams: { - image: { - sizes: [[200, 300], [100, 200]] - }, - } - }]; - - let assets = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data).imp[0].native.request.assets; - assert.ok(assets[0].img); - assert.equal(assets[0].img.w, 200); - assert.equal(assets[0].img.h, 300); - }); - }); - - it('should utilise aspect_ratios', function () { - const validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId', mid: 1000 }, - nativeParams: { - image: { - aspect_ratios: [{ - min_width: 100, - ratio_height: 3, - ratio_width: 1 - }] - }, - icon: { - aspect_ratios: [{ - min_width: 10, - ratio_height: 5, - ratio_width: 2 - }] - } - } - }]; - - let assets = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data).imp[0].native.request.assets; - assert.ok(assets[0].img); - assert.equal(assets[0].img.wmin, 100); - assert.equal(assets[0].img.hmin, 300); - - assert.ok(assets[1].img); - assert.equal(assets[1].img.wmin, 10); - assert.equal(assets[1].img.hmin, 25); - }); - - it('should not throw error if aspect_ratios config is not defined', function () { - const validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId', mid: 1000 }, - nativeParams: { - image: { - aspect_ratios: [] - }, - icon: { - aspect_ratios: [] - } - } - }]; - - assert.doesNotThrow(() => spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } })); - }); - }); - - it('should expect any dimensions if min_width not passed', function () { - const validBidRequests = [{ - bidId: 'bidId', - params: { siteId: 'siteId', mid: 1000 }, - nativeParams: { - image: { - aspect_ratios: [{ - ratio_height: 3, - ratio_width: 1 - }] - } - } - }]; - - let assets = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data).imp[0].native.request.assets; - assert.ok(assets[0].img); - assert.equal(assets[0].img.wmin, 0); - assert.equal(assets[0].img.hmin, 0); - assert.ok(!assets[1]); - }); - }); - }); - }); - - describe('interpretResponse', function () { - it('should return if no body in response', function () { - let serverResponse = {}; - let bidRequest = {}; - - assert.ok(!spec.interpretResponse(serverResponse, bidRequest)); - }); - it('should return more than one bids', function () { - let serverResponse = { - body: { - seatbid: [{ - bid: [{impid: '1', native: {ver: '1.1', link: { url: 'link' }, assets: [{id: 1, title: {text: 'Asset title text'}}]}}] - }, { - bid: [{impid: '2', native: {ver: '1.1', link: { url: 'link' }, assets: [{id: 1, data: {value: 'Asset title text'}}]}}] - }] - } - }; - let bidRequest = { - data: {}, - bids: [ - { - bidId: 'bidId1', - params: { siteId: 'siteId', mid: 1000 }, - nativeParams: { - title: { required: true, len: 140 }, - image: { required: false, wmin: 836, hmin: 627, w: 325, h: 300, mimes: ['image/jpg', 'image/gif'] }, - body: { len: 140 } - } - }, - { - bidId: 'bidId2', - params: { siteId: 'siteId', mid: 1000 }, - nativeParams: { - title: { required: true, len: 140 }, - image: { required: false, wmin: 836, hmin: 627, w: 325, h: 300, mimes: ['image/jpg', 'image/gif'] }, - body: { len: 140 } - } - } - ] - }; - - bids = spec.interpretResponse(serverResponse, bidRequest); - assert.equal(spec.interpretResponse(serverResponse, bidRequest).length, 2); - }); - - it('should parse seatbids', function () { - let serverResponse = { - body: { - seatbid: [{ - bid: [ - {impid: '1', native: {ver: '1.1', link: { url: 'link1' }, assets: [{id: 1, 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: 1, data: {value: 'Asset title text'}}]}}] - }] - } - }; - let bidRequest = { - data: {}, - bids: [ - { - bidId: 'bidId1', - params: { siteId: 'siteId', mid: 1000 }, - nativeParams: { - title: { required: true, len: 140 }, - image: { required: false, wmin: 836, hmin: 627, w: 325, h: 300, mimes: ['image/jpg', 'image/gif'] }, - body: { len: 140 } - } - }, - { - bidId: 'bidId2', - params: { siteId: 'siteId', mid: 1000 }, - nativeParams: { - title: { required: true, len: 140 }, - image: { required: false, wmin: 836, hmin: 627, w: 325, h: 300, mimes: ['image/jpg', 'image/gif'] }, - body: { len: 140 } - } - }, - { - bidId: 'bidId3', - params: { siteId: 'siteId', mid: 1000 }, - nativeParams: { - title: { required: true, len: 140 }, - image: { required: false, wmin: 836, hmin: 627, w: 325, h: 300, mimes: ['image/jpg', 'image/gif'] }, - body: { len: 140 } - } - }, - { - bidId: 'bidId4', - params: { siteId: 'siteId', mid: 1000 }, - nativeParams: { - title: { required: true, len: 140 }, - image: { required: false, wmin: 836, hmin: 627, w: 325, h: 300, mimes: ['image/jpg', 'image/gif'] }, - body: { len: 140 } - } - } - ] - }; - - bids = spec.interpretResponse(serverResponse, bidRequest).map(bid => { - const { requestId, native: { clickUrl } } = bid; - return [ requestId, clickUrl ]; - }); - - assert.equal(bids.length, 3); - assert.deepEqual(bids, [[ 'bidId1', 'link1' ], [ 'bidId2', 'link2' ], [ 'bidId4', 'link4' ]]); - }); - - it('should set correct values to bid', function () { - let serverResponse = { - body: { - id: null, - bidid: null, - seatbid: [{ - bid: [ - { - impid: '1', - price: 93.1231, - crid: '12312312', - native: { - assets: [], - link: { url: 'link' }, - imptrackers: ['imptrackers url1', 'imptrackers url2'] - } - } - ] - }], - cur: 'NOK' - } - }; - let bidRequest = { - data: {}, - bids: [ - { - bidId: 'bidId1', - params: { siteId: 'siteId', mid: 1000 }, - nativeParams: { - title: { required: true, len: 140 }, - image: { required: false, wmin: 836, hmin: 627, w: 325, h: 300, mimes: ['image/jpg', 'image/gif'] }, - body: { len: 140 } - } - } - ] - }; - - const bids = spec.interpretResponse(serverResponse, bidRequest); - const bid = serverResponse.body.seatbid[0].bid[0]; - assert.deepEqual(bids[0].requestId, bidRequest.bids[0].bidId); - assert.deepEqual(bids[0].cpm, bid.price); - assert.deepEqual(bids[0].creativeId, bid.crid); - assert.deepEqual(bids[0].ttl, 360); - assert.deepEqual(bids[0].netRevenue, false); - assert.deepEqual(bids[0].currency, serverResponse.body.cur); - assert.deepEqual(bids[0].mediaType, 'native'); - }); - it('should set correct native params', function () { - const bid = [ - { - impid: '1', - price: 93.1231, - crid: '12312312', - native: { - assets: [ - { - data: null, - id: 0, - img: null, - required: 0, - title: {text: 'title', len: null}, - video: null - }, { - data: null, - id: 2, - img: {type: null, url: 'test.url.com/Files/58345/308185.jpg?bv=1', w: 30, h: 10}, - required: 0, - title: null, - video: null - }, { - data: null, - id: 3, - img: {type: null, url: 'test.url.com/Files/58345/308200.jpg?bv=1', w: 100, h: 100}, - required: 0, - title: null, - video: null - }, { - data: {type: null, len: null, value: 'body'}, - id: 4, - img: null, - required: 0, - title: null, - video: null - }, { - data: {type: null, len: null, value: 'cta'}, - id: 1, - img: null, - required: 0, - title: null, - video: null - }, { - data: {type: null, len: null, value: 'sponsoredBy'}, - id: 5, - img: null, - required: 0, - title: null, - video: null - } - ], - link: { url: 'clickUrl', clicktrackers: ['clickTracker1', 'clickTracker2'] }, - imptrackers: ['imptrackers url1', 'imptrackers url2'], - jstracker: 'jstracker' - } - } - ]; - const serverResponse = { - body: { - id: null, - bidid: null, - seatbid: [{ bid }], - cur: 'NOK' - } - }; - let bidRequest = { - data: {}, - bids: [{ bidId: 'bidId1' }] - }; - - const result = spec.interpretResponse(serverResponse, bidRequest)[0].native; - const native = bid[0].native; - const assets = native.assets; - assert.deepEqual({ - clickUrl: native.link.url, - clickTrackers: native.link.clicktrackers, - impressionTrackers: native.imptrackers, - javascriptTrackers: [ native.jstracker ], - title: assets[0].title.text, - icon: {url: assets[1].img.url, width: assets[1].img.w, height: assets[1].img.h}, - image: {url: assets[2].img.url, width: assets[2].img.w, height: assets[2].img.h}, - body: assets[3].data.value, - cta: assets[4].data.value, - sponsoredBy: assets[5].data.value - }, result); - }); - it('should return empty when there is no bids in response', function () { - const serverResponse = { - body: { - id: null, - bidid: null, - seatbid: [{ bid: [] }], - cur: 'NOK' - } - }; - let bidRequest = { - data: {}, - bids: [{ bidId: 'bidId1' }] - }; - const result = spec.interpretResponse(serverResponse, bidRequest)[0]; - assert.ok(!result); - }); - }); -}); diff --git a/test/spec/modules/adfinityBidAdapter_spec.js b/test/spec/modules/adfinityBidAdapter_spec.js deleted file mode 100644 index 479a2303dd5..00000000000 --- a/test/spec/modules/adfinityBidAdapter_spec.js +++ /dev/null @@ -1,151 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/adfinityBidAdapter.js'; - -describe('AdfinityAdapter', function () { - let bid = { - bidId: '2dd581a2b6281d', - bidder: 'adfinity', - bidderRequestId: '145e1d6a7837c9', - params: { - placement_id: 0 - }, - placementCode: 'placementid_0', - auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e62', - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '0', - hp: 1, - rid: 'bidrequestid', - domain: 'example.com' - } - ] - } - }; - let bidderRequest = { - bidderCode: 'adfinity', - auctionId: 'fffffff-ffff-ffff-ffff-ffffffffffff', - bidderRequestId: 'ffffffffffffff', - start: 1472239426002, - auctionStart: 1472239426000, - timeout: 5000, - uspConsent: '1YN-', - refererInfo: { - referer: 'http://www.example.com', - reachedTop: true, - }, - bids: [bid] - } - - describe('isBidRequestValid', function () { - it('Should return true when placement_id can be cast to a number', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false when placement_id is not a number', function () { - bid.params.placement_id = 'aaa'; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid], 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://stat.adfinity.pro/?c=o&m=multi'); - }); - - it('Returns valid data if array of bids is valid', function () { - let data = serverRequest.data; - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); - 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'); - let placements = data['placements']; - for (let i = 0; i < placements.length; i++) { - let placement = placements[i]; - expect(placement).to.have.all.keys('placementId', 'bidId', 'traffic', 'sizes', 'schain'); - expect(placement.schain).to.be.an('object') - expect(placement.placementId).to.be.a('number'); - expect(placement.bidId).to.be.a('string'); - expect(placement.traffic).to.be.a('string'); - expect(placement.sizes).to.be.an('array'); - } - }); - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); - }); - describe('interpretResponse', function () { - let resObject = { - body: [ { - requestId: '123', - mediaType: 'banner', - cpm: 0.3, - width: 320, - height: 50, - ad: '

Hello ad

', - ttl: 1000, - creativeId: '123asd', - netRevenue: true, - currency: 'USD' - } ] - }; - 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++) { - let dataItem = serverResponses[i]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'mediaType'); - 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.mediaType).to.be.a('string'); - } - 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; - }); - }); - }); - - describe('getUserSyncs', function () { - let userSync = spec.getUserSyncs(); - it('Returns valid URL and type', function () { - expect(userSync).to.be.an('array').with.lengthOf(1); - expect(userSync[0].type).to.exist; - expect(userSync[0].url).to.exist; - expect(userSync[0].type).to.be.equal('image'); - expect(userSync[0].url).to.be.equal('https://stat.adfinity.pro/?c=o&m=cookie'); - }); - }); -}); diff --git a/test/spec/modules/adformBidAdapter_spec.js b/test/spec/modules/adformBidAdapter_spec.js deleted file mode 100644 index 79ea76da8dd..00000000000 --- a/test/spec/modules/adformBidAdapter_spec.js +++ /dev/null @@ -1,550 +0,0 @@ -import {assert, expect} from 'chai'; -import {spec} from 'modules/adformBidAdapter.js'; -import { BANNER, VIDEO } from 'src/mediaTypes.js'; -import { config } from 'src/config.js'; -import { createEidsArray } from 'modules/userId/eids.js'; - -describe('Adform adapter', function () { - let serverResponse, bidRequest, bidResponses; - let bids = []; - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'adform', - 'params': { - 'mid': '19910113' - } - }; - - it('should return true when required params found', function () { - assert(spec.isBidRequestValid(bid)); - }); - - it('should return false when required params are missing', function () { - bid.params = { - adxDomain: 'adx.adform.net' - }; - assert.isFalse(spec.isBidRequestValid(bid)); - }); - }); - - describe('buildRequests', function () { - it('should pass multiple bids via single request', function () { - let request = spec.buildRequests(bids); - let parsedUrl = parseUrl(request.url); - assert.lengthOf(parsedUrl.items, 7); - }); - - it('should handle global request parameters', function () { - let parsedUrl = parseUrl(spec.buildRequests([bids[0]]).url); - let query = parsedUrl.query; - - assert.equal(parsedUrl.path, 'https://newDomain/adx'); - assert.equal(query.tid, 45); - assert.equal(query.rp, 4); - assert.equal(query.fd, 1); - assert.equal(query.stid, '7aefb970-2045'); - assert.equal(query.url, encodeURIComponent('some// there')); - }); - - it('should set correct request method', function () { - let request = spec.buildRequests([bids[0]]); - assert.equal(request.method, 'GET'); - }); - - it('should pass request currency from config', function () { - config.setConfig({ currency: { adServerCurrency: 'PLN' } }); - let request = parseUrl(spec.buildRequests(bids).url); - - request.items.forEach(item => { - assert.equal(item.rcur, 'PLN'); - }); - }); - - it('should prefer bid currency over global config', function () { - config.setConfig({ currency: { adServerCurrency: 'PLN' } }); - bids[0].params.rcur = 'USD'; - let request = parseUrl(spec.buildRequests(bids).url); - const currencies = request.items.map(item => item.rcur); - - assert.deepEqual(currencies, [ 'USD', 'PLN', 'PLN', 'PLN', 'PLN', 'PLN', 'PLN' ]); - }); - - it('should correctly form bid items', function () { - let bidList = bids; - let request = spec.buildRequests(bidList); - let parsedUrl = parseUrl(request.url); - assert.deepEqual(parsedUrl.items, [ - { - mid: '1', - transactionId: '5f33781f-9552-4ca1' - }, - { - mid: '2', - someVar: 'someValue', - pt: 'gross', - transactionId: '5f33781f-9552-4iuy' - }, - { - mid: '3', - pdom: 'home', - transactionId: '5f33781f-9552-7ev3' - }, - { - mid: '3', - pdom: 'home', - transactionId: '5f33781f-9552-7ev3' - }, - { - mid: '3', - pdom: 'home', - transactionId: '5f33781f-9552-7ev3' - }, - { - mid: '5', - pt: 'net', - transactionId: '5f33781f-9552-7ev3', - }, - { - mid: '6', - pt: 'gross', - transactionId: '5f33781f-9552-7ev3' - } - ]); - }); - - it('should not change original validBidRequests object', function () { - var resultBids = JSON.parse(JSON.stringify(bids[0])); - let request = spec.buildRequests([bids[0]]); - assert.deepEqual(resultBids, bids[0]); - }); - - it('should set gross to the request, if there is any gross priceType', function () { - let request = spec.buildRequests([bids[5], bids[5]]); - let parsedUrl = parseUrl(request.url); - - assert.equal(parsedUrl.query.pt, 'net'); - - request = spec.buildRequests([bids[4], bids[3]]); - parsedUrl = parseUrl(request.url); - - assert.equal(parsedUrl.query.pt, 'gross'); - }); - - it('should pass extended ids', function () { - bids[0].userIdAsEids = createEidsArray({ - tdid: 'TTD_ID_FROM_USER_ID_MODULE', - pubcid: 'pubCommonId_FROM_USER_ID_MODULE' - }); - let request = spec.buildRequests(bids); - let eids = parseUrl(request.url).query.eids; - - assert.equal(eids, 'eyJhZHNlcnZlci5vcmciOnsiVFREX0lEX0ZST01fVVNFUl9JRF9NT0RVTEUiOlsxXX0sInB1YmNpZC5vcmciOnsicHViQ29tbW9uSWRfRlJPTV9VU0VSX0lEX01PRFVMRSI6WzFdfX0%3D'); - assert.deepEqual(JSON.parse(atob(decodeURIComponent(eids))), { - 'adserver.org': { - 'TTD_ID_FROM_USER_ID_MODULE': [1] - }, - 'pubcid.org': { - 'pubCommonId_FROM_USER_ID_MODULE': [1] - } - }); - }); - - it('should allow to pass custom extended ids', function () { - bids[0].params.eids = 'some_id_value'; - let request = spec.buildRequests(bids); - let eids = parseUrl(request.url).query.eids; - - assert.equal(eids, 'some_id_value'); - }); - - it('should add parameter to global parameters if it exists in all bids', function () { - const _bids = []; - _bids.push(bids[0]); - _bids.push(bids[1]); - _bids.push(bids[2]); - _bids[0].params.mkv = 'key:value,key1:value1'; - _bids[1].params.mkv = 'key:value,key1:value1,keyR:removed'; - _bids[2].params.mkv = 'key:value,key1:value1,keyR:removed,key8:value1'; - _bids[0].params.mkw = 'targeting'; - _bids[1].params.mkw = 'targeting'; - _bids[2].params.mkw = 'targeting,targeting2'; - _bids[0].params.msw = 'search:word,search:word2'; - _bids[1].params.msw = 'search:word'; - _bids[2].params.msw = 'search:word,search:word5'; - let bidList = _bids; - let request = spec.buildRequests(bidList); - let parsedUrl = parseUrl(request.url); - assert.equal(parsedUrl.query.mkv, encodeURIComponent('key:value,key1:value1')); - assert.equal(parsedUrl.query.mkw, 'targeting'); - assert.equal(parsedUrl.query.msw, encodeURIComponent('search:word')); - assert.ok(!parsedUrl.items[0].mkv); - assert.ok(!parsedUrl.items[0].mkw); - assert.equal(parsedUrl.items[0].msw, 'search:word2'); - assert.equal(parsedUrl.items[1].mkv, 'keyR:removed'); - assert.ok(!parsedUrl.items[1].mkw); - assert.ok(!parsedUrl.items[1].msw); - assert.equal(parsedUrl.items[2].mkv, 'keyR:removed,key8:value1'); - assert.equal(parsedUrl.items[2].mkw, 'targeting2'); - assert.equal(parsedUrl.items[2].msw, 'search:word5'); - }); - - describe('user privacy', function () { - it('should send GDPR Consent data to adform if gdprApplies', function () { - let request = spec.buildRequests([bids[0]], {gdprConsent: {gdprApplies: true, consentString: 'concentDataString'}}); - let parsedUrl = parseUrl(request.url).query; - - assert.equal(parsedUrl.gdpr, '1'); - assert.equal(parsedUrl.gdpr_consent, 'concentDataString'); - }); - - it('should not send GDPR Consent data to adform if gdprApplies is undefined', function () { - let request = spec.buildRequests([bids[0]], {gdprConsent: {gdprApplies: false, consentString: 'concentDataString'}}); - let parsedUrl = parseUrl(request.url).query; - - assert.equal(parsedUrl.gdpr, '0'); - assert.equal(parsedUrl.gdpr_consent, 'concentDataString'); - - request = spec.buildRequests([bids[0]], {gdprConsent: {gdprApplies: undefined, consentString: 'concentDataString'}}); - parsedUrl = parseUrl(request.url).query; - 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'}}); - - assert.deepEqual(request.gdpr, { - gdpr: true, - gdpr_consent: 'concentDataString' - }); - - request = spec.buildRequests([bids[0]]); - assert.ok(!request.gdpr); - }); - - it('should send CCPA Consent data to adform', function () { - const request = spec.buildRequests([bids[0]], {uspConsent: '1YA-'}); - const parsedUrl = parseUrl(request.url).query; - - assert.equal(parsedUrl.us_privacy, '1YA-'); - }); - }); - }); - - describe('interpretResponse', function () { - it('should respond with empty response when there is empty serverResponse', function () { - let result = spec.interpretResponse({ body: {} }, {}); - assert.deepEqual(result, []); - }); - it('should respond with empty response when response from server is not banner', function () { - serverResponse.body[0].response = 'not banner'; - serverResponse.body = [serverResponse.body[0]]; - bidRequest.bids = [bidRequest.bids[0]]; - let result = spec.interpretResponse(serverResponse, bidRequest); - - assert.deepEqual(result, []); - }); - it('should interpret server response correctly with one bid', function () { - serverResponse.body = [serverResponse.body[0]]; - bidRequest.bids = [bidRequest.bids[0]]; - let result = spec.interpretResponse(serverResponse, bidRequest)[0]; - - assert.equal(result.requestId, '2a0cf4e'); - assert.equal(result.cpm, 13.9); - assert.equal(result.width, 300); - assert.equal(result.height, 250); - assert.equal(result.creativeId, '2a0cf4e'); - assert.equal(result.dealId, '123abc'); - assert.equal(result.currency, 'EUR'); - assert.equal(result.netRevenue, true); - assert.equal(result.ttl, 360); - assert.deepEqual(result.meta.advertiserDomains, []) - assert.equal(result.ad, ''); - assert.equal(result.bidderCode, 'adform'); - assert.equal(result.transactionId, '5f33781f-9552-4ca1'); - }); - - it('should set correct netRevenue', function () { - serverResponse.body = [serverResponse.body[0]]; - bidRequest.bids = [bidRequest.bids[1]]; - bidRequest.netRevenue = 'gross'; - let result = spec.interpretResponse(serverResponse, bidRequest)[0]; - - assert.equal(result.netRevenue, false); - }); - - it('should create bid response item for every requested item', function () { - let result = spec.interpretResponse(serverResponse, bidRequest); - assert.lengthOf(result, 5); - }); - - it('should create bid response with vast xml', function () { - const result = spec.interpretResponse(serverResponse, bidRequest)[3]; - assert.equal(result.vastXml, ''); - }); - - it('should create bid response with vast url', function () { - const result = spec.interpretResponse(serverResponse, bidRequest)[4]; - assert.equal(result.vastUrl, 'vast://url'); - }); - - it('should set mediaType on bid response', function () { - 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]); - } - }); - - it('should set default netRevenue as gross', function () { - bidRequest.netRevenue = 'gross'; - const result = spec.interpretResponse(serverResponse, bidRequest); - for (let i = 0; i < result.length; i++) { - assert.equal(result[i].netRevenue, false); - } - }); - - it('should set gdpr if it exist in bidRequest', function () { - bidRequest.gdpr = { - gdpr: true, - gdpr_consent: 'ERW342EIOWT34234KMGds' - }; - let result = spec.interpretResponse(serverResponse, bidRequest); - for (let i = 0; i < result.length; i++) { - assert.equal(result[i].gdpr, true); - assert.equal(result[i].gdpr_consent, 'ERW342EIOWT34234KMGds'); - } - - bidRequest.gdpr = undefined; - result = spec.interpretResponse(serverResponse, bidRequest); - for (let i = 0; i < result.length; i++) { - assert.ok(!result[i].gdpr); - assert.ok(!result[i].gdpr_consent); - } - }); - - it('should set a renderer only for an outstream context', function () { - serverResponse.body = [serverResponse.body[3], serverResponse.body[2]]; - bidRequest.bids = [bidRequest.bids[6], bidRequest.bids[6]]; - let result = spec.interpretResponse(serverResponse, bidRequest); - assert.ok(result[0].renderer); - assert.equal(result[1].renderer, undefined); - }); - - describe('verifySizes', function () { - it('should respond with empty response when sizes doesn\'t match', function () { - serverResponse.body[0].response = 'banner'; - serverResponse.body[0].width = 100; - serverResponse.body[0].height = 150; - - serverResponse.body = [serverResponse.body[0]]; - bidRequest.bids = [bidRequest.bids[0]]; - let result = spec.interpretResponse(serverResponse, bidRequest); - - assert.equal(serverResponse.body.length, 1); - assert.equal(serverResponse.body[0].response, 'banner'); - assert.deepEqual(result, []); - }); - it('should respond with empty response when sizes as a strings doesn\'t match', function () { - serverResponse.body[0].response = 'banner'; - serverResponse.body[0].width = 100; - serverResponse.body[0].height = 150; - - serverResponse.body = [serverResponse.body[0]]; - bidRequest.bids = [bidRequest.bids[0]]; - - bidRequest.bids[0].sizes = [['101', '150']]; - let result = spec.interpretResponse(serverResponse, bidRequest); - - assert.equal(serverResponse.body.length, 1); - assert.equal(serverResponse.body[0].response, 'banner'); - assert.deepEqual(result, []); - }); - it('should support size dimensions as a strings', function () { - serverResponse.body[0].response = 'banner'; - serverResponse.body[0].width = 300; - serverResponse.body[0].height = 600; - - serverResponse.body = [serverResponse.body[0]]; - bidRequest.bids = [bidRequest.bids[0]]; - - bidRequest.bids[0].sizes = [['300', '250'], ['250', '300'], ['300', '600'], ['600', '300']]; - let result = spec.interpretResponse(serverResponse, bidRequest); - - assert.equal(result[0].width, 300); - assert.equal(result[0].height, 600); - }); - }); - }); - - beforeEach(function () { - config.setConfig({ currency: {} }); - - let sizes = [[250, 300], [300, 250], [300, 600], [600, 300]]; - let placementCode = ['div-01', 'div-02', 'div-03', 'div-04', 'div-05']; - let mediaTypes = [{video: {context: 'outstream'}, banner: {sizes: sizes[3]}}]; - let params = [{ mid: 1, url: 'some// there' }, {adxDomain: null, mid: 2, someVar: 'someValue', pt: 'gross'}, { adxDomain: null, mid: 3, pdom: 'home' }, {mid: 5, pt: 'net'}, {mid: 6, pt: 'gross'}]; - bids = [ - { - adUnitCode: placementCode[0], - auctionId: '7aefb970-2045', - bidId: '2a0cf4e', - bidder: 'adform', - bidderRequestId: '1ab8d9', - params: params[0], - adxDomain: 'newDomain', - tid: 45, - placementCode: placementCode[0], - sizes: [[300, 250], [250, 300], [300, 600], [600, 300]], - transactionId: '5f33781f-9552-4ca1' - }, - { - adUnitCode: placementCode[1], - auctionId: '7aefb970-2045', - bidId: '2a0cf5b', - bidder: 'adform', - bidderRequestId: '1ab8d9', - params: params[1], - placementCode: placementCode[1], - sizes: [[300, 250], [250, 300], [300, 600], [600, 300]], - transactionId: '5f33781f-9552-4iuy' - }, - { - adUnitCode: placementCode[2], - auctionId: '7aefb970-2045', - bidId: '2a0cf6n', - bidder: 'adform', - bidderRequestId: '1ab8d9', - params: params[2], - placementCode: placementCode[2], - sizes: [[300, 250], [250, 300], [300, 600], [600, 300]], - transactionId: '5f33781f-9552-7ev3' - }, - { - adUnitCode: placementCode[3], - auctionId: '7aefb970-2045', - bidId: '2a0cf6n', - bidder: 'adform', - bidderRequestId: '1ab8d9', - params: params[2], - placementCode: placementCode[2], - sizes: [], - transactionId: '5f33781f-9552-7ev3' - }, - { - adUnitCode: placementCode[4], - auctionId: '7aefb970-2045', - bidId: '2a0cf6n', - bidder: 'adform', - bidderRequestId: '1ab8d9', - params: params[2], - placementCode: placementCode[2], - sizes: [], - transactionId: '5f33781f-9552-7ev3' - }, - { - adUnitCode: placementCode[4], - auctionId: '7aefb970-2045', - bidId: '2a0cf6n', - bidder: 'adform', - bidderRequestId: '1ab8d9', - params: params[3], - placementCode: placementCode[2], - sizes: [], - transactionId: '5f33781f-9552-7ev3' - }, - { - adUnitCode: placementCode[4], - auctionId: '7aefb970-2045', - bidId: '2a0cf6n', - bidder: 'adform', - bidderRequestId: '1ab8d9', - params: params[4], - placementCode: placementCode[2], - sizes: [], - mediaTypes: mediaTypes[0], - transactionId: '5f33781f-9552-7ev3' - } - ]; - serverResponse = { - body: [ - { - banner: '', - deal_id: '123abc', - height: 250, - response: 'banner', - width: 300, - win_bid: 13.9, - win_cur: 'EUR' - }, - { - banner: '', - deal_id: '123abc', - height: 300, - response: 'banner', - width: 250, - win_bid: 13.9, - win_cur: 'EUR' - }, - { - banner: '', - deal_id: '123abc', - height: 300, - response: 'banner', - width: 600, - win_bid: 10, - win_cur: 'EUR' - }, - { - deal_id: '123abc', - height: 300, - response: 'vast_content', - width: 600, - win_bid: 10, - win_cur: 'EUR', - vast_content: '' - }, - { - deal_id: '123abc', - height: 300, - response: 'vast_url', - width: 600, - win_bid: 10, - win_cur: 'EUR', - vast_url: 'vast://url' - } - ], - headers: {} - }; - bidRequest = { - bidder: 'adform', - bids: bids, - method: 'GET', - url: 'url', - netRevenue: 'net' - }; - }); -}); - -function parseUrl(url) { - const parts = url.split('/'); - const query = parts.pop().split('&'); - return { - path: parts.join('/'), - items: query - .filter((i) => !~i.indexOf('=')) - .map((i) => atob(decodeURIComponent(i)) - .split('&') - .reduce(toObject, {})), - query: query - .filter((i) => ~i.indexOf('=')) - .map((i) => i.replace('?', '')) - .reduce(toObject, {}) - }; -} - -function toObject(cache, string) { - const keyValue = string.split('='); - cache[keyValue[0]] = keyValue[1]; - return cache; -} diff --git a/test/spec/modules/adgenerationBidAdapter_spec.js b/test/spec/modules/adgenerationBidAdapter_spec.js deleted file mode 100644 index 927e7910723..00000000000 --- a/test/spec/modules/adgenerationBidAdapter_spec.js +++ /dev/null @@ -1,407 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/adgenerationBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {NATIVE} from 'src/mediaTypes.js'; -import {config} from 'src/config.js'; -import prebid from '../../../package.json'; - -describe('AdgenerationAdapter', function () { - const adapter = newBidder(spec); - const ENDPOINT = ['https://api-test.scaleout.jp/adsv/v1', 'https://d.socdm.com/adsv/v1']; - - 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 bid = { - 'bidder': 'adg', - 'params': { - id: '58278', // banner - } - }; - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const bidRequests = [ - { // banner - bidder: 'adg', - params: { - id: '58278', - currency: 'JPY', - }, - adUnitCode: 'adunit-code', - sizes: [[300, 250], [320, 100]], - bidId: '2f6ac468a9c15e', - bidderRequestId: '14a9f773e30243', - auctionId: '4aae9f05-18c6-4fcd-80cf-282708cd584a', - transactionTd: 'f76f6dfd-d64f-4645-a29f-682bac7f431a' - }, - { // native - bidder: 'adg', - params: { - id: '58278', - currency: 'JPY', - }, - mediaTypes: { - native: { - image: { - required: true - }, - title: { - required: true, - len: 80 - }, - sponsoredBy: { - required: true - }, - clickUrl: { - required: true - }, - body: { - required: true - }, - icon: { - required: true - } - }, - }, - adUnitCode: 'adunit-code', - sizes: [[1, 1]], - bidId: '2f6ac468a9c15e', - bidderRequestId: '14a9f773e30243', - auctionId: '4aae9f05-18c6-4fcd-80cf-282708cd584a', - transactionTd: 'f76f6dfd-d64f-4645-a29f-682bac7f431a' - } - ]; - const bidderRequest = { - refererInfo: { - referer: 'https://example.com' - } - }; - const data = { - banner: `posall=SSPLOC&id=58278&sdktype=0&hb=true&t=json3&sizes=300x250%2C320x100¤cy=JPY&pbver=${prebid.version}&sdkname=prebidjs&adapterver=1.0.1&imark=1&tp=https%3A%2F%2Fexample.com`, - bannerUSD: `posall=SSPLOC&id=58278&sdktype=0&hb=true&t=json3&sizes=300x250%2C320x100¤cy=USD&pbver=${prebid.version}&sdkname=prebidjs&adapterver=1.0.1&imark=1&tp=https%3A%2F%2Fexample.com`, - native: 'posall=SSPLOC&id=58278&sdktype=0&hb=true&t=json3&sizes=1x1¤cy=JPY&pbver=' + prebid.version + '&sdkname=prebidjs&adapterver=1.0.1&tp=https%3A%2F%2Fexample.com' - }; - it('sends bid request to ENDPOINT via GET', function () { - const request = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(request.url).to.equal(ENDPOINT[1]); - expect(request.method).to.equal('GET'); - }); - - it('sends bid request to debug ENDPOINT via GET', function () { - bidRequests[0].params.debug = true; - const request = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(request.url).to.equal(ENDPOINT[0]); - expect(request.method).to.equal('GET'); - }); - - it('should attache params to the banner request', function () { - const request = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(request.data).to.equal(data.banner); - }); - - it('should attache params to the native request', function () { - const request = spec.buildRequests(bidRequests, bidderRequest)[1]; - expect(request.data).to.equal(data.native); - }); - it('allows setConfig to set bidder currency for JPY', function () { - config.setConfig({ - currency: { - adServerCurrency: 'JPY' - } - }); - const request = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(request.data).to.equal(data.banner); - config.resetConfig(); - }); - it('allows setConfig to set bidder currency for USD', function () { - config.setConfig({ - currency: { - adServerCurrency: 'USD' - } - }); - const request = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(request.data).to.equal(data.bannerUSD); - config.resetConfig(); - }); - }); - describe('interpretResponse', function () { - const bidRequests = { - banner: { - bidRequest: { - bidder: 'adg', - params: { - id: '58278', // banner - }, - adUnitCode: 'adunit-code', - sizes: [[320, 100]], - bidId: '2f6ac468a9c15e', - bidderRequestId: '14a9f773e30243', - auctionId: '4aae9f05-18c6-4fcd-80cf-282708cd584a', - transactionTd: 'f76f6dfd-d64f-4645-a29f-682bac7f431a' - }, - }, - native: { - bidRequest: { - bidder: 'adg', - params: { - id: '58278', // banner - }, - mediaTypes: { - native: { - image: { - required: true - }, - title: { - required: true, - len: 80 - }, - sponsoredBy: { - required: true - }, - clickUrl: { - required: true - }, - body: { - required: true - }, - icon: { - required: true - } - } - }, - adUnitCode: 'adunit-code', - sizes: [[1, 1]], - bidId: '2f6ac468a9c15e', - bidderRequestId: '14a9f773e30243', - auctionId: '4aae9f05-18c6-4fcd-80cf-282708cd584a', - transactionTd: 'f76f6dfd-d64f-4645-a29f-682bac7f431a' - }, - }, - }; - - const serverResponse = { - noAd: { - results: [], - }, - banner: { - ad: '
', - beacon: '', - cpm: 36.0008, - displaytype: '1', - ids: {}, - w: 320, - h: 100, - location_params: null, - locationid: '58279', - rotation: '0', - scheduleid: '512603', - sdktype: '0', - creativeid: '1k2kv35vsa5r', - dealid: 'fd5sa5fa7f', - ttl: 1000, - results: [ - {ad: '
'}, - ] - }, - native: { - ad: '↵ ↵ ↵ ↵ ↵
↵ ', - beacon: '', - cpm: 36.0008, - displaytype: '1', - ids: {}, - location_params: null, - locationid: '58279', - native_ad: { - assets: [ - { - data: { - label: 'accompanying_text', - value: 'AD' - }, - id: 501 - }, - { - data: { - label: 'optout_url', - value: 'https://supership.jp/optout/#' - }, - id: 502 - }, - { - data: { - ext: { - black_back: 'https://i.socdm.com/sdk/img/icon_adg_optout_26x26_white.png', - }, - label: 'information_icon_url', - value: 'https://i.socdm.com/sdk/img/icon_adg_optout_26x26_gray.png', - id: 503 - } - }, - { - id: 1, - required: 1, - title: {text: 'Title'} - }, - { - id: 2, - img: { - h: 250, - url: 'https://sdk-temp.s3-ap-northeast-1.amazonaws.com/adg-sample-ad/img/300x250.png', - w: 300 - }, - required: 1 - }, - { - id: 3, - img: { - h: 300, - url: 'https://placehold.jp/300x300.png', - w: 300 - }, - required: 1 - }, - { - data: {value: 'Description'}, - id: 5, - required: 0 - }, - { - data: {value: 'CTA'}, - id: 6, - required: 0 - }, - { - data: {value: 'Sponsored'}, - id: 4, - required: 0 - } - ], - imptrackers: ['https://adg-dummy-dsp.s3-ap-northeast-1.amazonaws.com/1x1.gif'], - link: { - clicktrackers: [ - 'https://adg-dummy-dsp.s3-ap-northeast-1.amazonaws.com/1x1_clicktracker_access.gif' - ], - url: 'https://supership.jp' - }, - }, - results: [ - {ad: 'Creative<\/body>'} - ], - rotation: '0', - scheduleid: '512603', - sdktype: '0', - creativeid: '1k2kv35vsa5r', - dealid: 'fd5sa5fa7f', - ttl: 1000 - } - }; - - const bidResponses = { - banner: { - requestId: '2f6ac468a9c15e', - cpm: 36.0008, - width: 320, - height: 100, - creativeId: '1k2kv35vsa5r', - dealId: 'fd5sa5fa7f', - currency: 'JPY', - netRevenue: true, - ttl: 1000, - ad: '
', - }, - native: { - requestId: '2f6ac468a9c15e', - cpm: 36.0008, - width: 1, - height: 1, - creativeId: '1k2kv35vsa5r', - dealId: 'fd5sa5fa7f', - currency: 'JPY', - netRevenue: true, - ttl: 1000, - ad: '↵
', - native: { - title: 'Title', - image: { - url: 'https://sdk-temp.s3-ap-northeast-1.amazonaws.com/adg-sample-ad/img/300x250.png', - height: 250, - width: 300 - }, - icon: { - url: 'https://placehold.jp/300x300.png', - height: 300, - width: 300 - }, - sponsoredBy: 'Sponsored', - body: 'Description', - cta: 'CTA', - privacyLink: 'https://supership.jp/optout/#', - clickUrl: 'https://supership.jp', - clickTrackers: ['https://adg-dummy-dsp.s3-ap-northeast-1.amazonaws.com/1x1_clicktracker_access.gif'], - impressionTrackers: ['https://adg-dummy-dsp.s3-ap-northeast-1.amazonaws.com/1x1.gif'] - }, - mediaType: NATIVE - } - }; - - it('no bid responses', function () { - const result = spec.interpretResponse({body: serverResponse.noAd}, bidRequests.banner); - expect(result.length).to.equal(0); - }); - - it('handles banner responses', function () { - const result = spec.interpretResponse({body: serverResponse.banner}, bidRequests.banner)[0]; - expect(result.requestId).to.equal(bidResponses.banner.requestId); - expect(result.width).to.equal(bidResponses.banner.width); - expect(result.height).to.equal(bidResponses.banner.height); - expect(result.creativeId).to.equal(bidResponses.banner.creativeId); - expect(result.dealId).to.equal(bidResponses.banner.dealId); - expect(result.currency).to.equal(bidResponses.banner.currency); - expect(result.netRevenue).to.equal(bidResponses.banner.netRevenue); - expect(result.ttl).to.equal(bidResponses.banner.ttl); - expect(result.ad).to.equal(bidResponses.banner.ad); - }); - - it('handles native responses', function () { - const result = spec.interpretResponse({body: serverResponse.native}, bidRequests.native)[0]; - expect(result.requestId).to.equal(bidResponses.native.requestId); - expect(result.width).to.equal(bidResponses.native.width); - expect(result.height).to.equal(bidResponses.native.height); - expect(result.creativeId).to.equal(bidResponses.native.creativeId); - expect(result.dealId).to.equal(bidResponses.native.dealId); - expect(result.currency).to.equal(bidResponses.native.currency); - expect(result.netRevenue).to.equal(bidResponses.native.netRevenue); - expect(result.ttl).to.equal(bidResponses.native.ttl); - expect(result.native.title).to.equal(bidResponses.native.native.title); - expect(result.native.image.url).to.equal(bidResponses.native.native.image.url); - expect(result.native.image.height).to.equal(bidResponses.native.native.image.height); - expect(result.native.image.width).to.equal(bidResponses.native.native.image.width); - expect(result.native.icon.url).to.equal(bidResponses.native.native.icon.url); - expect(result.native.icon.width).to.equal(bidResponses.native.native.icon.width); - expect(result.native.icon.height).to.equal(bidResponses.native.native.icon.height); - expect(result.native.sponsoredBy).to.equal(bidResponses.native.native.sponsoredBy); - expect(result.native.body).to.equal(bidResponses.native.native.body); - expect(result.native.cta).to.equal(bidResponses.native.native.cta); - expect(decodeURIComponent(result.native.privacyLink)).to.equal(bidResponses.native.native.privacyLink); - expect(result.native.clickUrl).to.equal(bidResponses.native.native.clickUrl); - expect(result.native.impressionTrackers[0]).to.equal(bidResponses.native.native.impressionTrackers[0]); - expect(result.native.clickTrackers[0]).to.equal(bidResponses.native.native.clickTrackers[0]); - expect(result.mediaType).to.equal(bidResponses.native.mediaType); - }); - }); -}); diff --git a/test/spec/modules/adglareBidAdapter_spec.js b/test/spec/modules/adglareBidAdapter_spec.js deleted file mode 100644 index d0dbe891f9d..00000000000 --- a/test/spec/modules/adglareBidAdapter_spec.js +++ /dev/null @@ -1,138 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/adglareBidAdapter.js'; - -describe('AdGlare Adapter Tests', function () { - let bidRequests; - - beforeEach(function () { - bidRequests = [ - { - bidder: 'adglare', - params: { - domain: 'try.engine.adglare.net', - zID: '475579334', - type: 'banner' - }, - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - }, - }, - bidId: '23acc48ad47af5', - auctionId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - } - ]; - }); - - describe('implementation', function () { - describe('for requests', function () { - it('should accept valid bid', function () { - let validBid = { - bidder: 'adglare', - params: { - domain: 'try.engine.adglare.net', - zID: '475579334', - type: 'banner' - } - }, - isValid = spec.isBidRequestValid(validBid); - - expect(isValid).to.equal(true); - }); - - it('should reject invalid bid', function () { - let invalidBid = { - bidder: 'adglare', - params: { - domain: 'somedomain.com', - zID: 'not an integer', - type: 'unsupported' - } - }, - isValid = spec.isBidRequestValid(invalidBid); - - expect(isValid).to.equal(false); - }); - - it('should build a valid endpoint URL', function () { - let bidRequests = [ - { - bidder: 'adglare', - params: { - domain: 'try.engine.adglare.net', - zID: '475579334', - type: 'banner' - }, - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - }, - }, - bidId: '23acc48ad47af5', - auctionId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - } - ], - bidderRequest = { - bidderCode: 'adglare', - auctionID: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - auctionStart: 1581497568252, - timeout: 5000, - refererInfo: { - referer: 'https://www.somedomain.com', - reachedTop: true, - numFrames: 0 - }, - start: 1581497568254 - }, - requests = spec.buildRequests(bidRequests, bidderRequest), - requestURL = requests[0].url; - - expect(requestURL).to.have.string('https://try.engine.adglare.net/?475579334'); - }); - }); - - describe('bid responses', function () { - it('should return complete bid response', function () { - let serverResponse = { - body: { - status: 'OK', - zID: 475579334, - cID: 501658124, - crID: 442123173, - cpm: 1.5, - ttl: 3600, - currency: 'USD', - width: 300, - height: 250, - adhtml: 'I am an ad.' - } - }, - bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); - - expect(bids).to.be.lengthOf(1); - expect(bids[0].bidderCode).to.equal('adglare'); - expect(bids[0].cpm).to.equal(1.5); - expect(bids[0].width).to.equal(300); - expect(bids[0].height).to.equal(250); - expect(bids[0].currency).to.equal('USD'); - expect(bids[0].netRevenue).to.equal(true); - }); - - it('should return empty bid response', function () { - let serverResponse = { - body: { - status: 'NOADS' - } - }, - bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); - - expect(bids).to.be.lengthOf(0); - }); - }); - }); -}); diff --git a/test/spec/modules/adhashBidAdapter_spec.js b/test/spec/modules/adhashBidAdapter_spec.js deleted file mode 100644 index ab4df84c093..00000000000 --- a/test/spec/modules/adhashBidAdapter_spec.js +++ /dev/null @@ -1,155 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/adhashBidAdapter.js'; - -describe('adhashBidAdapter', function () { - describe('isBidRequestValid', function () { - const validBid = { - bidder: 'adhash', - params: { - publisherId: '0xc3b09b27e9c6ef73957901aa729b9e69e5bbfbfb', - platformURL: 'https://adhash.org/p/struma/' - }, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - adUnitCode: 'adunit-code', - sizes: [[300, 250]], - bidId: '12345678901234', - bidderRequestId: '98765432109876', - auctionId: '01234567891234', - }; - - it('should return true when all mandatory parameters are there', function () { - expect(spec.isBidRequestValid(validBid)).to.equal(true); - }); - - it('should return false when there are no params', function () { - const bid = { ...validBid }; - delete bid.params; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when unsupported media type is requested', function () { - const bid = { ...validBid }; - bid.mediaTypes = { native: { sizes: [[300, 250]] } }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when publisherId is not a string', function () { - const bid = { ...validBid }; - bid.params.publisherId = 123; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when publisherId is not valid', function () { - const bid = { ...validBid }; - bid.params.publisherId = 'short string'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when publisherId is not a string', function () { - const bid = { ...validBid }; - bid.params.platformURL = 123; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when publisherId is not valid', function () { - const bid = { ...validBid }; - bid.params.platformURL = 'https://'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const bidRequest = { - params: { - publisherId: '0xc3b09b27e9c6ef73957901aa729b9e69e5bbfbfb' - }, - sizes: [[300, 250]], - adUnitCode: 'adUnitCode' - }; - it('should build the request correctly', function () { - const result = spec.buildRequests( - [ bidRequest ], - { gdprConsent: true, refererInfo: { referer: 'http://example.com/' } } - ); - expect(result.length).to.equal(1); - expect(result[0].method).to.equal('POST'); - expect(result[0].url).to.equal('https://bidder.adhash.org/rtb?version=1.0&prebid=true'); - expect(result[0].bidRequest).to.equal(bidRequest); - expect(result[0].data).to.have.property('timezone'); - expect(result[0].data).to.have.property('location'); - expect(result[0].data).to.have.property('publisherId'); - expect(result[0].data).to.have.property('size'); - expect(result[0].data).to.have.property('navigator'); - expect(result[0].data).to.have.property('creatives'); - expect(result[0].data).to.have.property('blockedCreatives'); - expect(result[0].data).to.have.property('currentTimestamp'); - expect(result[0].data).to.have.property('recentAds'); - }); - it('should build the request correctly without referer', function () { - const result = spec.buildRequests([ bidRequest ], { gdprConsent: true }); - expect(result.length).to.equal(1); - expect(result[0].method).to.equal('POST'); - expect(result[0].url).to.equal('https://bidder.adhash.org/rtb?version=1.0&prebid=true'); - expect(result[0].bidRequest).to.equal(bidRequest); - expect(result[0].data).to.have.property('timezone'); - expect(result[0].data).to.have.property('location'); - expect(result[0].data).to.have.property('publisherId'); - expect(result[0].data).to.have.property('size'); - expect(result[0].data).to.have.property('navigator'); - expect(result[0].data).to.have.property('creatives'); - expect(result[0].data).to.have.property('blockedCreatives'); - expect(result[0].data).to.have.property('currentTimestamp'); - expect(result[0].data).to.have.property('recentAds'); - }); - }); - - describe('interpretResponse', function () { - const request = { - data: { some: 'data' }, - bidRequest: { - bidId: '12345678901234', - adUnitCode: 'adunit-code', - sizes: [[300, 250]], - params: { - platformURL: 'https://adhash.org/p/struma/' - } - } - }; - - it('should interpret the response correctly', function () { - const serverResponse = { - body: { - creatives: [{ - costEUR: 1.234 - }] - } - }; - const result = spec.interpretResponse(serverResponse, request); - expect(result.length).to.equal(1); - expect(result[0].requestId).to.equal('12345678901234'); - expect(result[0].cpm).to.equal(1.234); - expect(result[0].width).to.equal(300); - expect(result[0].height).to.equal(250); - expect(result[0].creativeId).to.equal('adunit-code'); - expect(result[0].netRevenue).to.equal(true); - expect(result[0].currency).to.equal('EUR'); - expect(result[0].ttl).to.equal(60); - }); - - it('should return empty array when there are no creatives returned', function () { - 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); - }); - - it('should return empty array when something is not right', function () { - expect(spec.interpretResponse(null, request).length).to.equal(0); - }); - }); -}); diff --git a/test/spec/modules/adheseBidAdapter_spec.js b/test/spec/modules/adheseBidAdapter_spec.js deleted file mode 100644 index 526102c51fe..00000000000 --- a/test/spec/modules/adheseBidAdapter_spec.js +++ /dev/null @@ -1,509 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/adheseBidAdapter.js'; - -const BID_ID = 456; -const TTL = 360; -const NET_REVENUE = true; - -let minimalBid = function() { - return { - 'bidId': BID_ID, - 'bidder': 'adhese', - 'params': { - account: 'demo', - location: '_main_page_', - format: 'leaderboard' - } - } -}; - -let bidWithParams = function(data) { - let bid = minimalBid(); - bid.params.data = data; - return bid; -}; - -describe('AdheseAdapter', function () { - describe('getUserSyncs', function () { - const serverResponses = [{ - account: 'demo' - }]; - const gdprConsent = { - gdprApplies: true, - consentString: 'CONSENT_STRING' - }; - it('should return empty when iframe disallowed', function () { - expect(spec.getUserSyncs({ iframeEnabled: false }, serverResponses, gdprConsent)).to.be.empty; - }); - it('should return empty when no serverResponses present', function () { - expect(spec.getUserSyncs({ iframeEnabled: true }, [], gdprConsent)).to.be.empty; - }); - it('should return empty when no account info present in the response', function () { - expect(spec.getUserSyncs({ iframeEnabled: true }, [{}], gdprConsent)).to.be.empty; - }); - it('should return usersync url when iframe allowed', function () { - expect(spec.getUserSyncs({ iframeEnabled: true }, serverResponses, gdprConsent)).to.deep.equal([{ type: 'iframe', url: 'https://user-sync.adhese.com/iframe/user_sync.html?account=demo&gdpr=1&consentString=CONSENT_STRING' }]); - }); - }); - - describe('isBidRequestValid', function () { - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(minimalBid())).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, minimalBid()); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString: 'CONSENT_STRING' - }, - refererInfo: { - referer: 'http://prebid.org/dev-docs/subjects?_d=1' - } - }; - - it('should include requested slots', function () { - let 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 () { - let req = spec.buildRequests([ bidWithParams({ 'ag': '25' }) ], bidderRequest); - - expect(JSON.parse(req.data).slots[0].parameters).to.deep.include({ 'ag': [ '25' ] }); - }); - - it('should assign bid params per slot', function () { - let 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' ] }); - }); - - it('should split multiple target values', function () { - let 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' ] }); - }); - - it('should filter out empty params', function () { - let req = spec.buildRequests([ bidWithParams({ 'aa': [], 'bb': null, 'cc': '', 'dd': [ '', '' ], 'ee': [ 0, 1, null ], 'ff': 0, 'gg': [ 'x', 'y', '' ] }) ], bidderRequest); - - let 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' ] }); - }); - - it('should include gdpr consent param', function () { - let req = spec.buildRequests([ minimalBid() ], bidderRequest); - - expect(JSON.parse(req.data).parameters).to.deep.include({ 'xt': [ 'CONSENT_STRING' ] }); - }); - - it('should include referer param in base64url format', function () { - let req = spec.buildRequests([ minimalBid() ], bidderRequest); - - expect(JSON.parse(req.data).parameters).to.deep.include({ 'xf': [ 'aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc3ViamVjdHM_X2Q9MQ' ] }); - }); - - it('should include eids', function () { - let bid = minimalBid(); - bid.userIdAsEids = [{ source: 'id5-sync.com', uids: [{ id: 'ID5@59sigaS-...' }] }]; - - let 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 () { - let req = spec.buildRequests([ minimalBid() ], bidderRequest); - - expect(JSON.parse(req.data)).to.not.have.key('eids'); - }); - - it('should request vast content as url', function () { - let req = spec.buildRequests([ minimalBid() ], bidderRequest); - - expect(JSON.parse(req.data).vastContentAsUrl).to.equal(true); - }); - - it('should include bids', function () { - let bid = minimalBid(); - let req = spec.buildRequests([ bid ], bidderRequest); - - expect(req.bids).to.deep.equal([ bid ]); - }); - - it('should make a POST request', function () { - let req = spec.buildRequests([ minimalBid() ], bidderRequest); - - expect(req.method).to.equal('POST'); - }); - - it('should request the json endpoint', function () { - let req = spec.buildRequests([ minimalBid() ], bidderRequest); - - expect(req.url).to.equal('https://ads-demo.adhese.com/json'); - }); - }); - - describe('interpretResponse', () => { - let bidRequest = { - bids: [ minimalBid() ] - }; - - it('should get correct ssp banner response', () => { - let sspBannerResponse = { - body: [ - { - origin: 'APPNEXUS', - originInstance: '', - ext: 'js', - slotID: '10', - slotName: '_main_page_-leaderboard', - adType: 'leaderboard', - originData: { - seatbid: [{ - bid: [{ - crid: '60613369', - dealid: null - }], - seat: '958' - }] - }, - width: '728', - height: '90', - 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'} - } - ] - }; - - let expectedResponse = [{ - requestId: BID_ID, - ad: '
', - cpm: 1, - currency: 'USD', - creativeId: '60613369', - dealId: '', - width: 728, - height: 90, - mediaType: 'banner', - netRevenue: NET_REVENUE, - ttl: TTL, - adhese: { - origin: 'APPNEXUS', - originInstance: '', - originData: { - adType: 'leaderboard', - seatbid: [ - { - bid: [ { crid: '60613369', dealid: null } ], - seat: '958' - } - ], - slotId: '10', - slotName: '_main_page_-leaderboard' - } - } - }]; - expect(spec.interpretResponse(sspBannerResponse, bidRequest)).to.deep.equal(expectedResponse); - }); - - it('should get correct ssp video response', () => { - let sspVideoResponse = { - body: [ - { - origin: 'RUBICON', - ext: 'js', - slotName: '_main_page_-leaderboard', - adType: 'leaderboard', - width: '640', - height: '350', - body: '', - extension: {'prebid': {'cpm': {'amount': '2.1', 'currency': 'USD'}}, mediaType: 'video'} - } - ] - }; - - let expectedResponse = [{ - requestId: BID_ID, - vastXml: '', - cpm: 2.1, - currency: 'USD', - creativeId: 'RUBICON', - dealId: '', - width: 640, - height: 350, - mediaType: 'video', - netRevenue: NET_REVENUE, - ttl: TTL, - adhese: { - origin: 'RUBICON', - originInstance: '', - originData: {} - } - }]; - expect(spec.interpretResponse(sspVideoResponse, bidRequest)).to.deep.equal(expectedResponse); - }); - - it('should get correct ssp cache video response', () => { - let sspCachedVideoResponse = { - body: [ - { - origin: 'RUBICON', - ext: 'js', - slotName: '_main_page_-leaderboard', - adType: 'leaderboard', - 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'} - } - ] - }; - - let expectedResponse = [{ - requestId: BID_ID, - vastUrl: 'https://ads-demo.adhese.com/content/38983ccc-4083-4c24-932c-96f798d969b3', - cpm: 2.1, - currency: 'USD', - creativeId: 'RUBICON', - dealId: '', - width: 640, - height: 350, - mediaType: 'video', - netRevenue: NET_REVENUE, - ttl: TTL, - adhese: { - origin: 'RUBICON', - originInstance: '', - originData: {} - } - }]; - expect(spec.interpretResponse(sspCachedVideoResponse, bidRequest)).to.deep.equal(expectedResponse); - }); - - it('should get correct Adhese banner response', () => { - const adheseBannerResponse = { - body: [ - { - adType: 'largeleaderboard', // it can differ from the requested slot - adFormat: 'largeleaderboard', - timeStamp: '1544009030000', - orderId: '22051', - adspaceId: '162363', - body: '', - tag: '', - tracker: 'https://hosts-demo.adhese.com/track/tracker', - altText: '', - height: '150', - width: '840', - tagUrl: 'https://pool-demo.adhese.com/pool/lib/90511.js', - libId: '90511', - id: '742898', - advertiserId: '2081', - ext: 'js', - url: 'https://hosts-demo.adhese.com/raylene/url', - clickTag: 'https://hosts-demo.adhese.com/raylene/clickTag', - poolPath: 'https://hosts-demo.adhese.com/pool/lib/', - orderName: 'Luminus boiler comodity-Pareto -201812', - creativeName: 'nl_demo _network_ron_dlbd_840x150_fix_dir_asv_std_dis_brd_nrt_na_red', - slotName: '_main_page_-leaderboard', - slotID: '29306', - impressionCounter: 'https://hosts-demo.adhese.com/track/742898', - origin: 'JERLICIA', - originData: {}, - auctionable: true, - extension: { - prebid: { - cpm: { - amount: '5.96', - currency: 'USD' - } - }, - mediaType: 'banner' - } - } - ] - }; - - let expectedResponse = [{ - requestId: BID_ID, - ad: '', - adhese: { - origin: '', - originInstance: '', - originData: { - adFormat: 'largeleaderboard', - adId: '742898', - adType: 'largeleaderboard', - adspaceId: '162363', - libId: '90511', - orderProperty: undefined, - priority: undefined, - viewableImpressionCounter: undefined, - slotId: '29306', - slotName: '_main_page_-leaderboard', - advertiserId: '2081' - } - }, - cpm: 5.96, - currency: 'USD', - creativeId: '742898', - dealId: '22051', - width: 840, - height: 150, - mediaType: 'banner', - netRevenue: NET_REVENUE, - ttl: TTL, - }]; - expect(spec.interpretResponse(adheseBannerResponse, bidRequest)).to.deep.equal(expectedResponse); - }); - - it('should get correct Adhese video response', () => { - const adheseVideoResponse = { - body: [ - { - adType: 'preroll', - adFormat: '', - orderId: '22248', - adspaceId: '164196', - body: '', - height: '360', - width: '640', - tag: "", - libId: '89860', - id: '742470', - advertiserId: '2263', - ext: 'advar', - orderName: 'Smartphoto EOY-20181112', - creativeName: 'PREROLL', - slotName: '_main_page_-leaderboard', - slotID: '41711', - impressionCounter: 'https://hosts-demo.adhese.com/track/742898', - origin: 'JERLICIA', - originData: {}, - auctionable: true, - extension: { - mediaType: 'video' - } - } - ] - }; - - let expectedResponse = [{ - requestId: BID_ID, - vastXml: '', - adhese: { - origin: '', - originInstance: '', - originData: { - adFormat: '', - adId: '742470', - adType: 'preroll', - adspaceId: '164196', - libId: '89860', - orderProperty: undefined, - priority: undefined, - viewableImpressionCounter: undefined, - slotId: '41711', - slotName: '_main_page_-leaderboard', - advertiserId: '2263', - } - }, - cpm: 0, - currency: 'USD', - creativeId: '742470', - dealId: '22248', - width: 640, - height: 360, - mediaType: 'video', - netRevenue: NET_REVENUE, - ttl: TTL, - }]; - expect(spec.interpretResponse(adheseVideoResponse, bidRequest)).to.deep.equal(expectedResponse); - }); - - it('should get correct Adhese cached video response', () => { - const adheseVideoResponse = { - body: [ - { - adType: 'preroll', - adFormat: '', - orderId: '22248', - adspaceId: '164196', - body: '', - height: '360', - width: '640', - extension: { - mediaType: 'video' - }, - cachedBodyUrl: 'https://ads-demo.adhese.com/content/38983ccc-4083-4c24-932c-96f798d969b3', - libId: '89860', - id: '742470', - advertiserId: '2263', - ext: 'advar', - orderName: 'Smartphoto EOY-20181112', - creativeName: 'PREROLL', - slotName: '_main_page_-leaderboard', - slotID: '41711', - impressionCounter: 'https://hosts-demo.adhese.com/track/742898', - origin: 'JERLICIA', - originData: {}, - auctionable: true - } - ] - }; - - let expectedResponse = [{ - requestId: BID_ID, - vastUrl: 'https://ads-demo.adhese.com/content/38983ccc-4083-4c24-932c-96f798d969b3', - adhese: { - origin: '', - originInstance: '', - originData: { - adFormat: '', - adId: '742470', - adType: 'preroll', - adspaceId: '164196', - libId: '89860', - orderProperty: undefined, - priority: undefined, - viewableImpressionCounter: undefined, - slotId: '41711', - slotName: '_main_page_-leaderboard', - advertiserId: '2263', - } - }, - cpm: 0, - currency: 'USD', - creativeId: '742470', - dealId: '22248', - width: 640, - height: 360, - mediaType: 'video', - netRevenue: NET_REVENUE, - ttl: TTL, - }]; - expect(spec.interpretResponse(adheseVideoResponse, bidRequest)).to.deep.equal(expectedResponse); - }); - - it('should return no bids for empty adserver response', () => { - let adserverResponse = { body: [] }; - expect(spec.interpretResponse(adserverResponse, bidRequest)).to.be.empty; - }); - }); -}); diff --git a/test/spec/modules/adkernelAdnAnalytics_spec.js b/test/spec/modules/adkernelAdnAnalytics_spec.js deleted file mode 100644 index 7af96c9321c..00000000000 --- a/test/spec/modules/adkernelAdnAnalytics_spec.js +++ /dev/null @@ -1,277 +0,0 @@ -import analyticsAdapter, {ExpiringQueue, getUmtSource, storage} from 'modules/adkernelAdnAnalyticsAdapter'; -import {expect} from 'chai'; -import adapterManager from 'src/adapterManager'; -import CONSTANTS from 'src/constants.json'; - -const events = require('../../../src/events'); - -const DIRECT = { - source: '(direct)', - medium: '(direct)', - campaign: '(direct)' -}; -const REFERRER = { - source: 'lander.com', - medium: '(referral)', - campaign: '(referral)', - content: '/lander.html' -}; -const GOOGLE_ORGANIC = { - source: 'google', - medium: '(organic)', - campaign: '(organic)' -}; -const CAMPAIGN = { - source: 'adkernel', - medium: 'email', - campaign: 'new_campaign', - c1: '1', - c2: '2', - c3: '3', - c4: '4', - c5: '5' - -}; -describe('', function () { - let sandbox; - - before(function () { - sandbox = sinon.sandbox.create(); - }); - - after(function () { - sandbox.restore(); - analyticsAdapter.disableAnalytics(); - }); - - describe('UTM source parser', function () { - let stubSetItem; - let stubGetItem; - - before(function () { - stubSetItem = sandbox.stub(storage, 'setItem'); - stubGetItem = sandbox.stub(storage, 'getItem'); - }); - - afterEach(function () { - sandbox.reset(); - }); - - it('should parse first direct visit as (direct)', function () { - stubGetItem.withArgs('adk_dpt_analytics').returns(undefined); - stubSetItem.returns(undefined); - let source = getUmtSource('http://example.com'); - expect(source).to.be.eql(DIRECT); - }); - - it('should respect past campaign visits before direct', function () { - stubGetItem.withArgs('adk_dpt_analytics').returns(JSON.stringify(CAMPAIGN)); - stubSetItem.returns(undefined); - let source = getUmtSource('http://example.com'); - expect(source).to.be.eql(CAMPAIGN); - }); - - it('should parse visit from google as organic', function () { - stubGetItem.withArgs('adk_dpt_analytics').returns(undefined); - stubSetItem.returns(undefined); - let source = getUmtSource('http://example.com', 'https://www.google.com/search?q=pikachu'); - expect(source).to.be.eql(GOOGLE_ORGANIC); - }); - - it('should respect previous campaign visit before organic', function () { - stubGetItem.withArgs('adk_dpt_analytics').returns(JSON.stringify(CAMPAIGN)); - stubSetItem.returns(undefined); - let source = getUmtSource('http://example.com', 'https://www.google.com/search?q=pikachu'); - expect(source).to.be.eql(CAMPAIGN); - }); - - it('should parse referral visit', function () { - stubGetItem.withArgs('adk_dpt_analytics').returns(undefined); - stubSetItem.returns(undefined); - let source = getUmtSource('http://example.com', 'http://lander.com/lander.html'); - expect(source).to.be.eql(REFERRER); - }); - - it('should respect previous campaign visit before referral', function () { - stubGetItem.withArgs('adk_dpt_analytics').returns(JSON.stringify(CAMPAIGN)); - stubSetItem.returns(undefined); - let source = getUmtSource('http://example.com', 'https://www.google.com/search?q=pikachu'); - expect(source).to.be.eql(CAMPAIGN); - }); - - it('should parse referral visit from same domain as direct', function () { - stubGetItem.withArgs('adk_dpt_analytics').returns(undefined); - stubSetItem.returns(undefined); - let source = getUmtSource('http://lander.com/news.html', 'http://lander.com/lander.html'); - expect(source).to.be.eql(DIRECT); - }); - - it('should parse campaign visit', function () { - stubGetItem.withArgs('adk_dpt_analytics').returns(undefined); - stubSetItem.returns(undefined); - let source = getUmtSource('http://lander.com/index.html?utm_campaign=new_campaign&utm_source=adkernel&utm_medium=email&utm_c1=1&utm_c2=2&utm_c3=3&utm_c4=4&utm_c5=5'); - expect(source).to.be.eql(CAMPAIGN); - }); - }); - - describe('ExpiringQueue', function () { - let timer; - before(function () { - timer = sandbox.useFakeTimers(0); - }); - after(function () { - timer.restore(); - }); - - it('should notify after timeout period', (done) => { - let queue = new ExpiringQueue(() => { - let elements = queue.popAll(); - expect(elements).to.be.eql([1, 2, 3, 4]); - elements = queue.popAll(); - expect(elements).to.have.lengthOf(0); - expect(Date.now()).to.be.equal(200); - done(); - }, 100); - - queue.push(1); - setTimeout(() => { - queue.push([2, 3]); - timer.tick(50); - }, 50); - setTimeout(() => { - queue.push([4]); - timer.tick(100); - }, 100); - timer.tick(50); - }); - }); - - const REQUEST = { - bidderCode: 'adapter', - auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f', - bidderRequestId: '1a6fc81528d0f6', - bids: [{ - bidder: 'adapter', - params: {}, - adUnitCode: 'container-1', - transactionId: 'de90df62-7fd0-4fbc-8787-92d133a7dc06', - sizes: [[300, 250]], - bidId: '208750227436c1', - bidderRequestId: '1a6fc81528d0f6', - auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f', - gdprConsent: { - consentString: 'CONSENT', - gdprApplies: true, - apiVersion: 2 - }, - uspConsent: '1---' - }], - auctionStart: 1509369418387, - timeout: 3000 - }; - - const RESPONSE = { - bidderCode: 'adapter', - width: 300, - height: 250, - statusMessage: 'Bid available', - adId: '208750227436c1', - mediaType: 'banner', - cpm: 0.015, - ad: '', - auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f', - responseTimestamp: 1509369418832, - requestTimestamp: 1509369418389, - bidder: 'adapter', - adUnitCode: 'container-1', - timeToRespond: 443, - size: '300x250' - }; - - describe('Analytics adapter', function () { - let ajaxStub; - let timer; - - before(function () { - ajaxStub = sandbox.stub(analyticsAdapter, 'ajaxCall'); - timer = sandbox.useFakeTimers(0); - }); - - beforeEach(function () { - sandbox.stub(events, 'getEvents').callsFake(() => { - return [] - }); - }); - - afterEach(function () { - events.getEvents.restore(); - }); - - after(function() { - sandbox.restore(); - }); - - it('should be configurable', function () { - adapterManager.registerAnalyticsAdapter({ - code: 'adkernelAdn', - adapter: analyticsAdapter - }); - - adapterManager.enableAnalytics({ - provider: 'adkernelAdn', - options: { - pubId: 777, - queueTimeout: 1000 - } - }); - - expect(analyticsAdapter.context).to.have.property('host', 'tag.adkernel.com'); - expect(analyticsAdapter.context).to.have.property('pubId', 777); - }); - - it('should handle auction init event', function () { - events.emit(CONSTANTS.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'}); - }); - - it('should handle bid request event', function () { - events.emit(CONSTANTS.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'}); - }); - - it('should handle bid response event', function () { - events.emit(CONSTANTS.EVENTS.BID_RESPONSE, RESPONSE); - const ev = analyticsAdapter.context.queue.peekAll(); - expect(ev).to.have.length(3); - expect(ev[2]).to.be.eql({ - event: 'bidResponse', - adapter: 'adapter', - tagid: 'container-1', - val: 0.015, - time: 0.443 - }); - }); - - it('should handle auction end event', function () { - timer.tick(447); - events.emit(CONSTANTS.EVENTS.AUCTION_END, RESPONSE); - let ev = analyticsAdapter.context.queue.peekAll(); - 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}); - }); - - it('should handle winning bid', function () { - events.emit(CONSTANTS.EVENTS.BID_WON, RESPONSE); - timer.tick(4500); - expect(ajaxStub.calledTwice).to.be.equal(true); - let 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}); - }); - }); -}); diff --git a/test/spec/modules/adkernelAdnBidAdapter_spec.js b/test/spec/modules/adkernelAdnBidAdapter_spec.js deleted file mode 100644 index d3c9a2cf816..00000000000 --- a/test/spec/modules/adkernelAdnBidAdapter_spec.js +++ /dev/null @@ -1,420 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/adkernelAdnBidAdapter'; -import {config} from 'src/config'; - -describe('AdkernelAdn adapter', function () { - const bid1_pub1 = { - bidder: 'adkernelAdn', - transactionId: 'transact0', - bidderRequestId: 'req0', - auctionId: '5c66da22-426a-4bac-b153-77360bef5337', - bidId: 'bidid_1', - params: { - pubId: 1, - host: 'tag.adkernel.com' - }, - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 200]] - } - }, - adUnitCode: 'ad-unit-1', - }, bid2_pub1 = { - bidder: 'adkernelAdn', - transactionId: 'transact0', - bidderRequestId: 'req0', - auctionId: '5c66da22-426a-4bac-b153-77360bef5337', - bidId: 'bidid_2', - params: { - pubId: 1 - }, - adUnitCode: 'ad-unit-2', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - } - }, bid1_pub2 = { - bidder: 'adkernelAdn', - transactionId: 'transact2', - bidderRequestId: 'req1', - auctionId: '5c66da22-426a-4bac-b153-77360bef5337', - bidId: 'bidid_3', - params: { - pubId: 7, - host: 'dps-test.com' - }, - adUnitCode: 'ad-unit-2', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - } - }, bid_video1 = { - bidder: 'adkernelAdn', - transactionId: 'transact3', - bidderRequestId: 'req1', - auctionId: '5c66da22-426a-4bac-b153-77360bef5337', - bidId: 'bidid_4', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 300], - mimes: ['video/mp4', 'video/webm'], - api: [1, 2], - protocols: [5, 6] - } - }, - adUnitCode: 'video_wrapper', - params: { - pubId: 7 - } - }, bid_video2 = { - bidder: 'adkernelAdn', - transactionId: 'transact3', - bidderRequestId: 'req1', - auctionId: '5c66da22-426a-4bac-b153-77360bef5337', - bidId: 'bidid_5', - mediaTypes: { - video: { - playerSize: [1920, 1080], - context: 'instream' - } - }, - adUnitCode: 'video_wrapper2', - params: { - pubId: 7 - } - }, bid_multiformat = { - bidder: 'adkernelAdn', - transactionId: 'f82c64b8-c602-42a4-9791-4a268f6559ed', - bidderRequestId: 'req-001', - auctionId: 'auc-001', - bidId: 'Bid_01', - mediaTypes: { - banner: {sizes: [[300, 250], [300, 200]]}, - video: {context: 'instream', playerSize: [[640, 480]]} - }, - adUnitCode: 'ad-unit-1', - params: {pubId: 7} - }; - - const response = { - tags: [{ - id: 'ad-unit-1', - impid: '2c5e951baeeadd', - crid: '108_159810', - bid: 5.0, - tag: '', - w: 300, - h: 250 - }, { - id: 'ad-unit-2', - impid: '31d798477126c4', - crid: '108_21226', - bid: 2.5, - tag: '', - w: 300, - h: 250 - }, { - id: 'video_wrapper', - impid: '57d602ad1c9545', - crid: '108_158802', - bid: 10.0, - vast_url: 'https://vast.com/vast.xml' - }], - syncpages: ['https://dsp.adkernel.com/sync'] - }, usersyncOnlyResponse = { - syncpages: ['https://dsp.adkernel.com/sync'] - }; - - const defaultBidderRequest = { - bidderCode: 'adkernelAdn', - bids: [], - auctionStart: 1545836987704, - timeout: 3000, - refererInfo: { - referer: 'https://example.com/index.html', - reachedTop: true, - numIframes: 0, - stack: ['https://example.com/index.html'] - }, - start: 1545836987707 - }; - - describe('input parameters validation', () => { - it('empty request shouldn\'t generate exception', () => { - expect(spec.isBidRequestValid({ - bidderCode: 'adkernelAdn' - })).to.be.equal(false); - }); - - it('request without pubid should be ignored', () => { - expect(spec.isBidRequestValid({ - bidder: 'adkernelAdn', - params: {}, - placementCode: 'ad-unit-0', - sizes: [[300, 250]] - })).to.be.equal(false); - }); - - it('request with invalid pubid should be ignored', () => { - expect(spec.isBidRequestValid({ - bidder: 'adkernelAdn', - params: { - pubId: 'invalid id' - }, - placementCode: 'ad-unit-0', - sizes: [[300, 250]] - })).to.be.equal(false); - }); - - it('request with totally invalid host should be ignored', () => { - expect(spec.isBidRequestValid({ - bidder: 'adkernelAdn', - params: { - pubId: 1, - host: 1 - }, - placementCode: 'ad-unit-0', - sizes: [[300, 250]] - })).to.be.equal(false); - }); - - it('valid request should be accepted', () => { - expect(spec.isBidRequestValid({ - bidder: 'adkernelAdn', - params: { - pubId: 1, - host: 'network.com' - }, - placementCode: 'ad-unit-0', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 200]] - } - } - })).to.be.equal(true); - }); - }); - - function buildRequest(bidRequests, bidderRequestAugments = {}) { - let fullBidderRequest = Object.assign(defaultBidderRequest, bidderRequestAugments); - fullBidderRequest.auctionId = bidRequests[0].auctionId; - fullBidderRequest.transactionId = bidRequests[0].transactionId; - fullBidderRequest.bidderRequestId = bidRequests[0].bidderRequestId; - fullBidderRequest.bids = bidRequests; - let pbRequests = spec.buildRequests(bidRequests, fullBidderRequest); - let tagRequests = pbRequests.map(r => JSON.parse(r.data)); - return [pbRequests, tagRequests]; - } - - describe('banner request building', function () { - let [_, tagRequests] = buildRequest([bid1_pub1]); - let tagRequest = tagRequests[0]; - - it('should have request id', function () { - expect(tagRequest).to.have.property('id'); - }); - - it('should have transaction id', function () { - expect(tagRequest).to.have.property('tid'); - }); - - it('should have sizes', function () { - expect(tagRequest.imp[0].banner).to.have.property('format'); - expect(tagRequest.imp[0].banner.format).to.be.eql(['300x250', '300x200']); - }); - - it('should have impression id', function () { - expect(tagRequest.imp[0]).to.have.property('id', 'bidid_1'); - }); - - it('should have tagid', function () { - expect(tagRequest.imp[0]).to.have.property('tagid', 'ad-unit-1'); - }); - - it('should create proper site block', function () { - expect(tagRequest.site).to.have.property('page', 'https://example.com/index.html'); - expect(tagRequest.site).to.have.property('secure', 1); - }); - - it('should not have user object', function () { - expect(tagRequest).to.not.have.property('user'); - }); - - it('shouldn\'t contain gdpr nor ccpa information for default request', function () { - let [_, tagRequests] = buildRequest([bid1_pub1]); - expect(tagRequests[0]).to.not.have.property('user'); - }); - - it('should contain gdpr and ccpa information if consent is configured', function () { - let [_, bidRequests] = buildRequest([bid1_pub1], - {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'); - expect(bidRequests[0].user).to.have.property('us_privacy', '1YNN'); - }); - - it('should\'t contain consent string if gdpr isn\'t applied', function () { - let [_, 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}); - let [_, bidRequests] = buildRequest([bid1_pub1]); - config.resetConfig(); - expect(bidRequests[0]).to.have.property('user'); - expect(bidRequests[0].user).to.have.property('coppa', 1); - }); - - it('should set bidfloor if configured', function() { - let bid = Object.assign({}, bid1_pub1); - bid.getFloor = function() { - return { - currency: 'USD', - floor: 0.145 - } - }; - let [, tagRequests] = buildRequest([bid]); - expect(tagRequests[0].imp[0]).to.have.property('bidfloor', 0.145); - }); - }); - - describe('video request building', () => { - let [_, tagRequests] = buildRequest([bid_video1, bid_video2]); - let tagRequest = tagRequests[0]; - - it('should have video object', () => { - expect(tagRequest.imp[0]).to.have.property('video'); - expect(tagRequest.imp[1]).to.have.property('video'); - }); - - it('should have tagid', () => { - expect(tagRequest.imp[0]).to.have.property('tagid', 'video_wrapper'); - expect(tagRequest.imp[1]).to.have.property('tagid', 'video_wrapper2'); - }); - - it('should have size', () => { - expect(tagRequest.imp[0].video).to.have.property('w', 640); - expect(tagRequest.imp[0].video).to.have.property('h', 300); - expect(tagRequest.imp[1].video).to.have.property('w', 1920); - expect(tagRequest.imp[1].video).to.have.property('h', 1080); - }); - - it('should have video params', () => { - expect(tagRequest.imp[0].video).to.have.property('mimes'); - expect(tagRequest.imp[0].video.mimes).to.be.eql(['video/mp4', 'video/webm']); - expect(tagRequest.imp[0].video).to.have.property('api'); - expect(tagRequest.imp[0].video.api).to.be.eql([1, 2]); - expect(tagRequest.imp[0].video).to.have.property('protocols'); - expect(tagRequest.imp[0].video.protocols).to.be.eql([5, 6]); - }); - }); - - describe('multiformat request building', function () { - let [_, tagRequests] = buildRequest([bid_multiformat]); - - it('should contain single request', function () { - expect(tagRequests).to.have.length(1); - expect(tagRequests[0].imp).to.have.length(1); - }); - - it('should contain banner-only impression', function () { - expect(tagRequests[0].imp).to.have.length(1); - expect(tagRequests[0].imp[0]).to.have.property('banner'); - expect(tagRequests[0].imp[0]).to.not.have.property('video'); - }); - }); - - describe('requests routing', function () { - it('should issue a request for each publisher', function () { - let [pbRequests, tagRequests] = buildRequest([bid1_pub1, bid_video1]); - expect(pbRequests).to.have.length(2); - expect(pbRequests[0].url).to.have.string(`account=${bid1_pub1.params.pubId}`); - expect(pbRequests[1].url).to.have.string(`account=${bid1_pub2.params.pubId}`); - expect(tagRequests[0].imp).to.have.length(1); - expect(tagRequests[1].imp).to.have.length(1); - }); - - it('should issue a request for each host', function () { - let [pbRequests, tagRequests] = buildRequest([bid1_pub1, bid1_pub2]); - expect(pbRequests).to.have.length(2); - expect(pbRequests[0].url).to.have.string('https://tag.adkernel.com/tag'); - expect(pbRequests[1].url).to.have.string(`https://${bid1_pub2.params.host}/tag`); - expect(tagRequests[0].imp).to.have.length(1); - expect(tagRequests[1].imp).to.have.length(1); - }); - }); - - describe('responses processing', function () { - let responses; - - before(function () { - responses = spec.interpretResponse({body: response}); - }); - - it('should parse all responses', function () { - expect(responses).to.have.length(3); - }); - - it('should return fully-initialized bid-response', function () { - let resp = responses[0]; - expect(resp).to.have.property('bidderCode', 'adkernelAdn'); - expect(resp).to.have.property('requestId', '2c5e951baeeadd'); - expect(resp).to.have.property('cpm', 5.0); - expect(resp).to.have.property('width', 300); - expect(resp).to.have.property('height', 250); - expect(resp).to.have.property('creativeId', '108_159810'); - expect(resp).to.have.property('currency'); - expect(resp).to.have.property('ttl'); - expect(resp).to.have.property('mediaType', 'banner'); - expect(resp).to.have.property('ad'); - expect(resp.ad).to.have.string(''); - }); - - it('should return fully-initialized video bid-response', function () { - let resp = responses[2]; - expect(resp).to.have.property('bidderCode', 'adkernelAdn'); - expect(resp).to.have.property('requestId', '57d602ad1c9545'); - expect(resp).to.have.property('cpm', 10.0); - expect(resp).to.have.property('creativeId', '108_158802'); - expect(resp).to.have.property('currency'); - expect(resp).to.have.property('ttl'); - expect(resp).to.have.property('mediaType', 'video'); - expect(resp).to.have.property('vastUrl', 'https://vast.com/vast.xml'); - expect(resp).to.not.have.property('ad'); - }); - - it('should perform usersync', function () { - let syncs = spec.getUserSyncs({iframeEnabled: false}, [{body: response}]); - expect(syncs).to.have.length(0); - 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'); - }); - - it('should handle user-sync only response', function () { - let [pbRequests, tagRequests] = buildRequest([bid1_pub1]); - let resp = spec.interpretResponse({body: usersyncOnlyResponse}, pbRequests[0]); - expect(resp).to.have.length(0); - }); - - it('shouldn\' fail on empty response', function () { - let syncs = spec.getUserSyncs({iframeEnabled: true}, [{body: ''}]); - expect(syncs).to.have.length(0); - }); - }); - - describe('adapter configuration', () => { - it('should have aliases', () => { - expect(spec.aliases).to.have.lengthOf(1); - expect(spec.aliases[0]).to.be.equal('engagesimply'); - }); - }); -}); diff --git a/test/spec/modules/adkernelBidAdapter_spec.js b/test/spec/modules/adkernelBidAdapter_spec.js deleted file mode 100644 index b9d647238bf..00000000000 --- a/test/spec/modules/adkernelBidAdapter_spec.js +++ /dev/null @@ -1,634 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/adkernelBidAdapter'; -import * as utils from 'src/utils'; -import {NATIVE, BANNER, VIDEO} from 'src/mediaTypes'; -import {config} from 'src/config'; - -describe('Adkernel adapter', function () { - const bid1_zone1 = { - bidder: 'adkernel', - params: {zoneId: 1, host: 'rtb.adkernel.com'}, - adUnitCode: 'ad-unit-1', - bidId: 'Bid_01', - bidderRequestId: 'req-001', - auctionId: 'auc-001', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 200]] - } - } - }, bid2_zone2 = { - bidder: 'adkernel', - params: {zoneId: 2, host: 'rtb.adkernel.com'}, - adUnitCode: 'ad-unit-2', - bidId: 'Bid_02', - bidderRequestId: 'req-001', - auctionId: 'auc-001', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - } - }, bid3_host2 = { - bidder: 'adkernel', - params: {zoneId: 1, host: 'rtb-private.adkernel.com'}, - adUnitCode: 'ad-unit-2', - bidId: 'Bid_02', - bidderRequestId: 'req-001', - auctionId: 'auc-001', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - } - }, bid_without_zone = { - bidder: 'adkernel', - params: {host: 'rtb-private.adkernel.com'}, - adUnitCode: 'ad-unit-1', - bidId: 'Bid_W', - bidderRequestId: 'req-002', - auctionId: 'auc-002', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - } - }, bid_without_host = { - bidder: 'adkernel', - params: {zoneId: 1}, - adUnitCode: 'ad-unit-1', - bidId: 'Bid_W', - bidderRequestId: 'req-002', - auctionId: 'auc-002', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - } - }, bid_with_wrong_zoneId = { - bidder: 'adkernel', - params: {zoneId: 'wrong id', host: 'rtb.adkernel.com'}, - adUnitCode: 'ad-unit-2', - bidId: 'Bid_02', - bidderRequestId: 'req-002', - auctionId: 'auc-002', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - } - }, bid_video = { - bidder: 'adkernel', - transactionId: '866394b8-5d37-4d49-803e-f1bdb595f73e', - bidId: 'Bid_Video', - bidderRequestId: '18b2a61ea5d9a7', - auctionId: 'de45acf1-9109-4e52-8013-f2b7cf5f6766', - params: { - zoneId: 1, - host: 'rtb.adkernel.com', - video: {api: [1, 2]} - }, - mediaTypes: { - video: { - context: 'instream', - playerSize: [[640, 480]] - } - }, - adUnitCode: 'ad-unit-1' - }, bid_multiformat = { - bidder: 'adkernel', - params: {zoneId: 1, host: 'rtb.adkernel.com'}, - mediaTypes: { - banner: {sizes: [[300, 250], [300, 200]]}, - video: {context: 'instream', playerSize: [[640, 480]]} - }, - adUnitCode: 'ad-unit-1', - transactionId: 'f82c64b8-c602-42a4-9791-4a268f6559ed', - bidId: 'Bid_01', - bidderRequestId: 'req-001', - auctionId: 'auc-001' - }, bid_native = { - bidder: 'adkernel', - params: {zoneId: 1, host: 'rtb.adkernel.com'}, - mediaTypes: { - native: { - title: { - required: true, - len: 80 - }, - body: { - required: true - }, - body2: { - required: true - }, - icon: { - required: true, - aspect_ratios: [{min_width: 50, min_height: 50}] - }, - image: { - required: true, - sizes: [300, 200] - }, - clickUrl: { - required: true - }, - rating: { - required: false - }, - price: { - required: false - }, - privacyLink: { - required: false - }, - cta: { - required: false - }, - sponsoredBy: { - required: false - }, - displayUrl: { - required: false - } - } - }, - adUnitCode: 'ad-unit-1', - transactionId: 'f82c64b8-c602-42a4-9791-4a268f6559ed', - bidId: 'Bid_01', - bidderRequestId: 'req-001', - auctionId: 'auc-001' - }; - - const bidResponse1 = { - id: 'bid1', - seatbid: [{ - bid: [{ - id: '1', - impid: 'Bid_01', - crid: '100_001', - price: 3.01, - nurl: 'https://rtb.com/win?i=ZjKoPYSFI3Y_0', - adm: '', - w: 300, - h: 250, - dealid: 'deal' - }] - }], - ext: { - adk_usersync: [{type: 1, url: 'https://adk.sync.com/sync'}] - } - }, videoBidResponse = { - id: '47ce4badcf7482', - seatbid: [{ - bid: [{ - id: 'sZSYq5zYMxo_0', - impid: 'Bid_Video', - crid: '100_003', - price: 0.00145, - adid: '158801', - nurl: 'https://rtb.com/win?i=sZSYq5zYMxo_0&f=nurl', - cid: '16855' - }] - }], - }, usersyncOnlyResponse = { - id: 'nobid1', - ext: { - adk_usersync: [{type: 2, url: 'https://adk.sync.com/sync'}] - } - }, nativeResponse = { - id: '56fbc713-b737-4651-9050-13376aed9818', - seatbid: [{ - bid: [{ - id: 'someid_01', - impid: 'Bid_01', - price: 2.25, - adid: '4', - 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'}} - ], - link: {url: 'http://rtb.com/click?i=pTuOlf5KHUo_0'}, - imptrackers: ['http://rtb.com/win?i=pTuOlf5KHUo_0&f=imp'] - } - }), - adomain: ['displayurl.com'], - cat: ['IAB1-4', 'IAB8-16', 'IAB25-5'], - cid: '1', - crid: '4', - ext: { - 'advertiser_id': 777, - 'advertiser_name': 'advertiser', - 'agency_name': 'agency' - } - }] - }], - bidid: 'pTuOlf5KHUo', - cur: 'EUR' - }; - - var sandbox; - beforeEach(function () { - sandbox = sinon.sandbox.create(); - }); - - afterEach(function () { - sandbox.restore(); - config.resetConfig(); - }); - - function buildBidderRequest(url = 'https://example.com/index.html', params = {}) { - return Object.assign({}, params, {refererInfo: {referer: url, reachedTop: true}, timeout: 3000, bidderCode: 'adkernel'}); - } - const DEFAULT_BIDDER_REQUEST = buildBidderRequest(); - - function buildRequest(bidRequests, bidderRequest = DEFAULT_BIDDER_REQUEST, dnt = true) { - let dntmock = sandbox.stub(utils, 'getDNT').callsFake(() => dnt); - let pbRequests = spec.buildRequests(bidRequests, bidderRequest); - dntmock.restore(); - let rtbRequests = pbRequests.map(r => JSON.parse(r.data)); - return [pbRequests, rtbRequests]; - } - - describe('input parameters validation', function () { - it('empty request shouldn\'t generate exception', function () { - expect(spec.isBidRequestValid({ - bidderCode: 'adkernel' - })).to.be.equal(false); - }); - - it('request without zone shouldn\'t issue a request', function () { - expect(spec.isBidRequestValid(bid_without_zone)).to.be.equal(false); - }); - - it('request without host shouldn\'t issue a request', function () { - expect(spec.isBidRequestValid(bid_without_host)).to.be.equal(false); - }); - - it('empty request shouldn\'t generate exception', function () { - expect(spec.isBidRequestValid(bid_with_wrong_zoneId)).to.be.equal(false); - }); - - it('valid native requests should pass', () => { - expect(spec.isBidRequestValid(bid_native)).to.be.equal(true); - }) - }); - - describe('banner request building', function () { - let bidRequest, bidRequests, _; - before(function () { - [_, bidRequests] = buildRequest([bid1_zone1]); - bidRequest = bidRequests[0]; - }); - - it('should be a first-price auction', function () { - expect(bidRequest).to.have.property('at', 1); - }); - - it('should have banner object', function () { - expect(bidRequest.imp[0]).to.have.property('banner'); - }); - - it('should have id', function () { - expect(bidRequest.imp[0]).to.have.property('id'); - expect(bidRequest.imp[0].id).to.be.eql('Bid_01'); - }); - - 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}]); - }); - - it('should respect secure connection', function () { - expect(bidRequest.imp[0]).to.have.property('secure', 1); - }); - - it('should have tagid', function () { - expect(bidRequest.imp[0]).to.have.property('tagid', 'ad-unit-1'); - }); - - it('should create proper site block', function () { - expect(bidRequest.site).to.have.property('domain', 'example.com'); - expect(bidRequest.site).to.have.property('page', 'https://example.com/index.html'); - }); - - it('should fill device with caller macro', function () { - expect(bidRequest).to.have.property('device'); - expect(bidRequest.device).to.have.property('ip', 'caller'); - expect(bidRequest.device).to.have.property('ipv6', 'caller'); - expect(bidRequest.device).to.have.property('ua', 'caller'); - expect(bidRequest.device).to.have.property('dnt', 1); - }); - - it('shouldn\'t contain gdpr nor ccpa information for default request', function () { - let [_, bidRequests] = buildRequest([bid1_zone1]); - expect(bidRequests[0]).to.not.have.property('regs'); - expect(bidRequests[0]).to.not.have.property('user'); - }); - - it('should contain gdpr-related information if consent is configured', function () { - let [_, bidRequests] = buildRequest([bid1_zone1], - buildBidderRequest('https://example.com/index.html', - {gdprConsent: {gdprApplies: true, consentString: 'test-consent-string', vendorData: {}}, uspConsent: '1YNN'})); - let bidRequest = bidRequests[0]; - expect(bidRequest).to.have.property('regs'); - expect(bidRequest.regs.ext).to.be.eql({'gdpr': 1, 'us_privacy': '1YNN'}); - expect(bidRequest).to.have.property('user'); - expect(bidRequest.user.ext).to.be.eql({'consent': 'test-consent-string'}); - }); - - it('should contain coppa if configured', function () { - config.setConfig({coppa: true}); - let [_, bidRequests] = buildRequest([bid1_zone1]); - let bidRequest = bidRequests[0]; - expect(bidRequest).to.have.property('regs'); - expect(bidRequest.regs).to.have.property('coppa', 1); - }); - - it('should\'t contain consent string if gdpr isn\'t applied', function () { - let [_, bidRequests] = buildRequest([bid1_zone1], buildBidderRequest('https://example.com/index.html', {gdprConsent: {gdprApplies: false}})); - let bidRequest = bidRequests[0]; - expect(bidRequest).to.have.property('regs'); - expect(bidRequest.regs.ext).to.be.eql({'gdpr': 0}); - expect(bidRequest).to.not.have.property('user'); - }); - - it('should\'t pass dnt if state is unknown', function () { - let [_, bidRequests] = buildRequest([bid1_zone1], DEFAULT_BIDDER_REQUEST, false); - expect(bidRequests[0].device).to.not.have.property('dnt'); - }); - - it('should forward default bidder timeout', function() { - let [_, bidRequests] = buildRequest([bid1_zone1]); - expect(bidRequests[0]).to.have.property('tmax', 3000); - }); - - it('should set bidfloor if configured', function() { - let bid = Object.assign({}, bid1_zone1); - bid.getFloor = function() { - return { - currency: 'USD', - floor: 0.145 - } - }; - let [_, bidRequests] = buildRequest([bid]); - expect(bidRequests[0].imp[0]).to.have.property('bidfloor', 0.145); - }); - }); - - describe('video request building', function () { - let _, bidRequests; - before(function () { - [_, bidRequests] = buildRequest([bid_video]); - }); - - it('should have video object', function () { - expect(bidRequests[0].imp[0]).to.have.property('video'); - }); - - it('should have h/w', function () { - expect(bidRequests[0].imp[0].video).to.have.property('w', 640); - expect(bidRequests[0].imp[0].video).to.have.property('h', 480); - }); - - it('should have tagid', function () { - expect(bidRequests[0].imp[0]).to.have.property('tagid', 'ad-unit-1'); - }); - - it('should have openrtb video impression parameters', function() { - expect(bidRequests[0].imp[0].video).to.have.property('api'); - expect(bidRequests[0].imp[0].video.api).to.be.eql([1, 2]); - }); - }); - - describe('multiformat request building', function () { - let _, bidRequests; - before(function () { - [_, bidRequests] = buildRequest([bid_multiformat]); - }); - it('should contain single request', function () { - expect(bidRequests).to.have.length(1); - expect(bidRequests[0].imp).to.have.length(1); - }); - it('should contain banner-only impression', function () { - expect(bidRequests[0].imp).to.have.length(1); - expect(bidRequests[0].imp[0]).to.have.property('banner'); - expect(bidRequests[0].imp[0]).to.not.have.property('video'); - }); - }); - - describe('requests routing', function () { - it('should issue a request for each host', function () { - let [pbRequests, _] = buildRequest([bid1_zone1, bid3_host2]); - expect(pbRequests).to.have.length(2); - expect(pbRequests[0].url).to.have.string(`https://${bid1_zone1.params.host}/`); - expect(pbRequests[1].url).to.have.string(`https://${bid3_host2.params.host}/`); - }); - - it('should issue a request for each zone', function () { - let [pbRequests, _] = buildRequest([bid1_zone1, bid2_zone2]); - expect(pbRequests).to.have.length(2); - expect(pbRequests[0].url).to.include(`zone=${bid1_zone1.params.zoneId}`); - expect(pbRequests[1].url).to.include(`zone=${bid2_zone2.params.zoneId}`); - }); - }); - - describe('User sync request signals', function() { - it('should respect syncEnabled option', function() { - config.setConfig({ - userSync: { - syncEnabled: false, - filterSettings: { - all: { - bidders: '*', - filter: 'include' - } - } - } - }); - let [pbRequests, bidRequests] = buildRequest([bid1_zone1]); - expect(bidRequests).to.have.length(1); - expect(bidRequests[0]).to.not.have.property('ext'); - }); - - it('should respect all config node', function() { - config.setConfig({ - userSync: { - syncEnabled: true, - filterSettings: { - all: { - bidders: '*', - filter: 'include' - } - } - } - }); - let [pbRequests, bidRequests] = buildRequest([bid1_zone1]); - expect(bidRequests).to.have.length(1); - expect(bidRequests[0].ext).to.have.property('adk_usersync', 1); - }); - - it('should respect exclude filter', function() { - config.setConfig({ - userSync: { - syncEnabled: true, - filterSettings: { - image: { - bidders: '*', - filter: 'include' - }, - iframe: { - bidders: ['adkernel'], - filter: 'exclude' - } - } - } - }); - let [pbRequests, bidRequests] = buildRequest([bid1_zone1]); - expect(bidRequests).to.have.length(1); - expect(bidRequests[0].ext).to.have.property('adk_usersync', 2); - }); - - it('should respect total exclusion', function() { - config.setConfig({ - userSync: { - syncEnabled: true, - filterSettings: { - image: { - bidders: ['adkernel'], - filter: 'exclude' - }, - iframe: { - bidders: ['adkernel'], - filter: 'exclude' - } - } - } - }); - let [pbRequests, bidRequests] = buildRequest([bid1_zone1]); - expect(bidRequests).to.have.length(1); - expect(bidRequests[0]).to.not.have.property('ext'); - }); - }); - - describe('responses processing', function () { - it('should return fully-initialized banner bid-response', function () { - let [pbRequests, _] = buildRequest([bid1_zone1]); - let resp = spec.interpretResponse({body: bidResponse1}, 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); - expect(resp).to.have.property('height', 250); - expect(resp).to.have.property('creativeId', '100_001'); - expect(resp).to.have.property('currency'); - expect(resp).to.have.property('ttl'); - expect(resp).to.have.property('mediaType', BANNER); - expect(resp).to.have.property('ad'); - expect(resp).to.have.property('dealId', 'deal'); - expect(resp.ad).to.have.string(''); - }); - - it('should return fully-initialized video bid-response', function () { - let [pbRequests, _] = buildRequest([bid_video]); - let 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); - expect(resp.vastUrl).to.equal('https://rtb.com/win?i=sZSYq5zYMxo_0&f=nurl'); - expect(resp.width).to.equal(640); - expect(resp.height).to.equal(480); - }); - - it('should add nurl as pixel for banner response', function () { - let [pbRequests, _] = buildRequest([bid1_zone1]); - let resp = spec.interpretResponse({body: bidResponse1}, pbRequests[0])[0]; - let expectedNurl = bidResponse1.seatbid[0].bid[0].nurl + '&px=1'; - expect(resp.ad).to.have.string(expectedNurl); - }); - - it('should handle bidresponse with user-sync only', function () { - let [pbRequests, _] = buildRequest([bid1_zone1]); - let 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}, []); - expect(syncs).to.have.length(0); - syncs = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}, [{body: bidResponse1}]); - expect(syncs).to.have.length(0); - syncs = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [{body: bidResponse1}]); - 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}]); - 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'); - }); - }); - - describe('adapter configuration', () => { - it('should have aliases', () => { - expect(spec.aliases).to.be.an('array').that.is.not.empty; - }); - }); - - describe('native support', () => { - let _, bidRequests; - before(function () { - [_, bidRequests] = buildRequest([bid_native]); - }); - - it('native request building', () => { - expect(bidRequests[0].imp).to.have.length(1); - expect(bidRequests[0].imp[0]).to.have.property('native'); - expect(bidRequests[0].imp[0].native).to.have.property('request'); - let request = JSON.parse(bidRequests[0].imp[0].native.request); - expect(request).to.have.property('ver', '1.1'); - 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: 3, required: 1, data: {type: 2}}); - expect(request.assets[2]).to.be.eql({id: 4, required: 1, data: {type: 10}}); - expect(request.assets[3]).to.be.eql({id: 1, required: 1, img: {wmin: 50, hmin: 50, type: 1}}); - expect(request.assets[4]).to.be.eql({id: 2, required: 1, img: {w: 300, h: 200, type: 3}}); - expect(request.assets[5]).to.be.eql({id: 11, required: 0, data: {type: 3}}); - expect(request.assets[6]).to.be.eql({id: 8, required: 0, data: {type: 6}}); - expect(request.assets[7]).to.be.eql({id: 10, required: 0, data: {type: 12}}); - expect(request.assets[8]).to.be.eql({id: 5, required: 0, data: {type: 1}}); - expect(request.assets[9]).to.be.eql({id: 14, required: 0, data: {type: 11}}); - }); - - it('native response processing', () => { - let [pbRequests, _] = buildRequest([bid_native]); - let 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'); - expect(resp).to.have.property('meta'); - expect(resp.meta.advertiserId).to.be.eql(777); - expect(resp.meta.advertiserName).to.be.eql('advertiser'); - expect(resp.meta.agencyName).to.be.eql('agency'); - expect(resp.meta.advertiserDomains).to.be.eql(['displayurl.com']); - expect(resp.meta.secondaryCatIds).to.be.eql(['IAB1-4', 'IAB8-16', 'IAB25-5']); - expect(resp).to.have.property('mediaType', NATIVE); - expect(resp).to.have.property('native'); - expect(resp.native).to.have.property('clickUrl', 'http://rtb.com/click?i=pTuOlf5KHUo_0'); - expect(resp.native.impressionTrackers).to.be.eql(['http://rtb.com/win?i=pTuOlf5KHUo_0&f=imp']); - expect(resp.native).to.have.property('title', 'Title'); - expect(resp.native).to.have.property('body', 'Description'); - expect(resp.native).to.have.property('body2', 'Additional description'); - expect(resp.native.icon).to.be.eql({url: 'http://rtb.com/thumbnail?i=pTuOlf5KHUo_0&imgt=icon', width: 50, height: 50}); - expect(resp.native.image).to.be.eql({url: 'http://rtb.com/thumbnail?i=pTuOlf5KHUo_0', width: 300, height: 200}); - expect(resp.native).to.have.property('sponsoredBy', 'Sponsor.com'); - expect(resp.native).to.have.property('displayUrl', 'displayurl.com'); - }); - }); -}); diff --git a/test/spec/modules/adliveBidAdapter_spec.js b/test/spec/modules/adliveBidAdapter_spec.js deleted file mode 100644 index ddf8f82f20f..00000000000 --- a/test/spec/modules/adliveBidAdapter_spec.js +++ /dev/null @@ -1,78 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/adliveBidAdapter.js'; - -describe('adliveBidAdapterTests', function() { - let bidRequestData = { - bids: [ - { - bidId: 'transaction_1234', - bidder: 'adlive', - params: { - hashes: ['1e100887dd614b0909bf6c49ba7f69fdd1360437'] - }, - sizes: [[300, 250]] - } - ] - }; - let request = []; - - it('validate_pub_params', function() { - expect( - spec.isBidRequestValid({ - bidder: 'adlive', - params: { - hashes: ['1e100887dd614b0909bf6c49ba7f69fdd1360437'] - } - }) - ).to.equal(true); - }); - - it('validate_generated_params', function() { - request = spec.buildRequests(bidRequestData.bids); - let req_data = JSON.parse(request[0].data); - - expect(req_data.transaction_id).to.equal('transaction_1234'); - }); - - it('validate_response_params', function() { - let serverResponse = { - body: [ - { - hash: '1e100887dd614b0909bf6c49ba7f69fdd1360437', - content: 'Ad html', - price: 1.12, - size: [300, 250], - is_passback: 0 - } - ] - }; - - let bids = spec.interpretResponse(serverResponse, bidRequestData.bids[0]); - expect(bids).to.have.lengthOf(1); - - let bid = bids[0]; - - expect(bid.creativeId).to.equal('1e100887dd614b0909bf6c49ba7f69fdd1360437'); - expect(bid.ad).to.equal('Ad html'); - expect(bid.cpm).to.equal(1.12); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.currency).to.equal('USD'); - }); - - it('validate_response_params_with passback', function() { - let serverResponse = { - body: [ - { - hash: '1e100887dd614b0909bf6c49ba7f69fdd1360437', - content: 'Ad html passback', - size: [300, 250], - is_passback: 1 - } - ] - }; - let bids = spec.interpretResponse(serverResponse, bidRequestData.bids[0]); - - expect(bids).to.have.lengthOf(0); - }); -}); diff --git a/test/spec/modules/adlooxAnalyticsAdapter_spec.js b/test/spec/modules/adlooxAnalyticsAdapter_spec.js deleted file mode 100644 index 9cc9c4ded4d..00000000000 --- a/test/spec/modules/adlooxAnalyticsAdapter_spec.js +++ /dev/null @@ -1,229 +0,0 @@ -import adapterManager from 'src/adapterManager.js'; -import analyticsAdapter, { command as analyticsCommand, COMMAND } from 'modules/adlooxAnalyticsAdapter.js'; -import { AUCTION_COMPLETED } from 'src/auction.js'; -import { expect } from 'chai'; -import events from 'src/events.js'; -import { EVENTS } from 'src/constants.json'; -import * as utils from 'src/utils.js'; -import { loadExternalScriptStub } from 'test/mocks/adloaderStub.js'; - -const analyticsAdapterName = 'adloox'; - -describe('Adloox Analytics Adapter', function () { - let sandbox; - - const esplode = 'esplode'; - - const bid = { - bidder: 'dummy', - adUnitCode: 'ad-slot-1', - mediaType: 'display' - }; - - const auctionDetails = { - auctionStatus: AUCTION_COMPLETED, - bidsReceived: [ - bid - ] - }; - - const analyticsOptions = { - js: 'https://j.adlooxtracking.com/ads/js/tfav_adl_%%clientid%%.js', - client: 'adlooxtest', - clientid: 127, - platformid: 0, - tagid: 0, - params: { - dummy1: '%%client%%', - dummy2: '%%pbAdSlot%%', - dummy3: function(bid) { throw new Error(esplode) } - } - }; - - adapterManager.registerAnalyticsAdapter({ - code: analyticsAdapterName, - adapter: analyticsAdapter - }); - describe('enableAnalytics', function () { - describe('invalid options', function () { - it('should require options', function (done) { - adapterManager.enableAnalytics({ - provider: analyticsAdapterName - }); - expect(analyticsAdapter.context).is.null; - - done(); - }); - - it('should reject non-string options.js', function (done) { - const analyticsOptionsLocal = utils.deepClone(analyticsOptions); - analyticsOptionsLocal.js = function () { }; - - adapterManager.enableAnalytics({ - provider: analyticsAdapterName, - options: analyticsOptionsLocal - }); - expect(analyticsAdapter.context).is.null; - - done(); - }); - - it('should reject non-function options.toselector', function (done) { - const analyticsOptionsLocal = utils.deepClone(analyticsOptions); - analyticsOptionsLocal.toselector = esplode; - - adapterManager.enableAnalytics({ - provider: analyticsAdapterName, - options: analyticsOptionsLocal - }); - expect(analyticsAdapter.context).is.null; - - done(); - }); - - [ 'client', 'clientid', 'platformid', 'tagid' ].forEach(function (o) { - it('should require options.' + o, function (done) { - const analyticsOptionsLocal = utils.deepClone(analyticsOptions); - delete analyticsOptionsLocal[o]; - - adapterManager.enableAnalytics({ - provider: analyticsAdapterName, - options: analyticsOptionsLocal - }); - expect(analyticsAdapter.context).is.null; - - done(); - }); - }); - - it('should reject non-object options.params', function (done) { - const analyticsOptionsLocal = utils.deepClone(analyticsOptions); - analyticsOptionsLocal.params = esplode; - - adapterManager.enableAnalytics({ - provider: analyticsAdapterName, - options: analyticsOptionsLocal - }); - expect(analyticsAdapter.context).is.null; - - done(); - }); - }); - }); - - describe('process', function () { - beforeEach(function() { - sandbox = sinon.sandbox.create(); - - sandbox.stub(events, 'getEvents').returns([]); - - adapterManager.enableAnalytics({ - provider: analyticsAdapterName, - options: utils.deepClone(analyticsOptions) - }); - - expect(analyticsAdapter.context).is.not.null; - }); - - afterEach(function () { - analyticsAdapter.disableAnalytics(); - expect(analyticsAdapter.context).is.null; - - sandbox.restore(); - sandbox = undefined; - }); - - describe('event', function () { - it('should preload the script on AUCTION_END only once', function (done) { - const insertElementStub = sandbox.stub(utils, 'insertElement'); - - const uri = utils.parseUrl(analyticsAdapter.url(analyticsOptions.js)); - const isLinkPreloadAsScript = function(arg) { - const href_uri = utils.parseUrl(arg.href); // IE11 requires normalisation (hostname always includes port) - return arg.tagName === 'LINK' && arg.getAttribute('rel') === 'preload' && arg.getAttribute('as') === 'script' && href_uri.href === uri.href; - }; - - events.emit(EVENTS.AUCTION_END, auctionDetails); - expect(insertElementStub.calledWith(sinon.match(isLinkPreloadAsScript))).to.true; - - events.emit(EVENTS.AUCTION_END, auctionDetails); - expect(insertElementStub.callCount).to.equal(1); - - done(); - }); - - it('should inject verification JS on BID_WON', function (done) { - const url = analyticsAdapter.url(`${analyticsOptions.js}#`); - - const parent = document.createElement('div'); - - const slot = document.createElement('div'); - slot.id = bid.adUnitCode; - parent.appendChild(slot); - - const dummy = document.createElement('div'); - parent.appendChild(dummy); - - const querySelectorStub = sandbox.stub(document, 'querySelector'); - querySelectorStub.withArgs(`#${bid.adUnitCode}`).returns(slot); - - events.emit(EVENTS.BID_WON, bid); - - const [urlInserted, moduleCode] = loadExternalScriptStub.getCall(0).args; - - expect(urlInserted.substr(0, url.length)).to.equal(url); - expect(moduleCode).to.equal(analyticsAdapterName); - expect(/[#&]creatype=2(&|$)/.test(urlInserted)).is.true; // prebid 'display' -> adloox '2' - expect(new RegExp('[#&]dummy3=' + encodeURIComponent('ERROR: ' + esplode) + '(&|$)').test(urlInserted)).is.true; - - done(); - }); - }); - - describe('command', function () { - it('should return config', function (done) { - const expected = utils.deepClone(analyticsOptions); - delete expected.js; - delete expected.toselector; - delete expected.params; - - analyticsCommand(COMMAND.CONFIG, null, function (response) { - expect(utils.deepEqual(response, expected)).is.true; - - done(); - }); - }); - - it('should return expanded URL', function (done) { - const data = { - url: 'https://example.com?', - args: [ - [ 'client', '%%client%%' ] - ], - bid: bid, - ids: true - }; - const expected = `${data.url}${data.args[0][0]}=${analyticsOptions.client}`; - - analyticsCommand(COMMAND.URL, data, function (response) { - expect(response.substr(0, expected.length)).is.equal(expected); - - done(); - }); - }); - - it('should inject tracking event', function (done) { - const data = { - eventType: EVENTS.BID_WON, - args: bid - }; - - analyticsCommand(COMMAND.TRACK, data, function (response) { - expect(response).is.undefined; - - done(); - }); - }); - }); - }); -}); diff --git a/test/spec/modules/admanBidAdapter_spec.js b/test/spec/modules/admanBidAdapter_spec.js deleted file mode 100644 index f3212dec2f5..00000000000 --- a/test/spec/modules/admanBidAdapter_spec.js +++ /dev/null @@ -1,231 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/admanBidAdapter.js'; - -describe('AdmanMediaBidAdapter', function () { - let bid = { - bidId: '23fhj33i987f', - bidder: 'adman', - params: { - placementId: 0, - traffic: 'banner' - } - }; - - describe('isBidRequestValid', function () { - it('Should return true if there are bidId, params and placementId parameters present', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false if at least one of parameters is not present', function () { - delete bid.params.placementId; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid]); - 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://pub.admanmedia.com/?c=o&m=multi'); - }); - it('Returns valid data if array of bids is valid', function () { - let data = serverRequest.data; - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); - 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'); - let placement = data['placements'][0]; - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes'); - expect(placement.placementId).to.equal(0); - expect(placement.bidId).to.equal('23fhj33i987f'); - expect(placement.traffic).to.equal('banner'); - }); - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); - }); - 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' - }] - }; - let bannerResponses = spec.interpretResponse(banner); - expect(bannerResponses).to.be.an('array').that.is.not.empty; - let dataItem = bannerResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - expect(dataItem.requestId).to.equal('23fhj33i987f'); - expect(dataItem.cpm).to.equal(0.4); - expect(dataItem.width).to.equal(300); - expect(dataItem.height).to.equal(250); - expect(dataItem.ad).to.equal('Test'); - expect(dataItem.ttl).to.equal(120); - expect(dataItem.creativeId).to.equal('2'); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal('USD'); - }); - 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' - }] - }; - let videoResponses = spec.interpretResponse(video); - expect(videoResponses).to.be.an('array').that.is.not.empty; - - let dataItem = videoResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - 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'); - }); - 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', - }] - }; - let nativeResponses = spec.interpretResponse(native); - expect(nativeResponses).to.be.an('array').that.is.not.empty; - - let dataItem = nativeResponses[0]; - expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); - 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'); - }); - 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' - }] - }; - - let 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' - }] - }; - let 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', - }] - }; - let 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' - }] - }; - let serverResponses = spec.interpretResponse(invalid); - expect(serverResponses).to.be.an('array').that.is.empty; - }); - }); - describe('getUserSyncs', function () { - let userSync = spec.getUserSyncs(); - it('Returns valid URL and type', function () { - expect(userSync).to.be.an('array').with.lengthOf(1); - expect(userSync[0].type).to.exist; - expect(userSync[0].url).to.exist; - expect(userSync[0].type).to.be.equal('image'); - expect(userSync[0].url).to.be.equal('https://pub.admanmedia.com/?c=o&m=sync'); - }); - }); -}); diff --git a/test/spec/modules/admediaBidAdapter_spec.js b/test/spec/modules/admediaBidAdapter_spec.js deleted file mode 100644 index 5dc7b9a02a8..00000000000 --- a/test/spec/modules/admediaBidAdapter_spec.js +++ /dev/null @@ -1,138 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/admediaBidAdapter.js'; - -describe('admediaAdapterTests', function () { - describe('bidRequestValidity', function () { - it('bidRequest with aid', function () { - expect(spec.isBidRequestValid({ - bidder: 'admedia', - params: { - aid: 86858, - } - })).to.equal(true); - }); - - it('bidRequest without aid', function () { - expect(spec.isBidRequestValid({ - bidder: 'a4g', - params: { - key: 86858 - } - })).to.equal(false); - }); - }); - - describe('bidRequest', function () { - const validBidRequests = [{ - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'auctionId': 'e3010a3c-5b95-4475-9ba2-1b004c737c30', - 'bidId': '2758de47c84ab58', - 'bidRequestsCount': 1, - 'bidder': 'admedia', - 'bidderRequestId': '1033407c6af0c7', - 'params': { - 'aid': 86858, - }, - 'sizes': [[300, 250], [300, 600]], - 'transactionId': '5851b2cf-ee2d-4022-abd2-d581ef01604e' - }, { - 'adUnitCode': 'div-gpt-ad-1460505748561-1', - 'auctionId': 'e3010a3c-5b95-4475-9ba2-1b004c737c30', - 'bidId': '3d2aaa400371fa', - 'bidRequestsCount': 1, - 'bidder': 'admedia', - 'bidderRequestId': '1033407c6af0c7', - 'params': { - 'aid': 84977, - }, - 'sizes': [[728, 90]], - 'transactionId': 'f8b5247e-7715-4e60-9d51-33153e78c190' - }]; - - const bidderRequest = { - 'auctionId': 'e3010a3c-5b95-4475-9ba2-1b004c737c30', - 'bidderCode': 'admedia', - 'bidderRequestId': '1033407c6af0c7', - 'refererInfo': { - 'numIframes': 0, - 'reachedTop': true, - 'referer': 'https://test.com/index.html?pbjs_debug=true' - } - - }; - - const request = spec.buildRequests(validBidRequests, bidderRequest); - - it('bidRequest method', function () { - expect(request.method).to.equal('POST'); - }); - - it('bidRequest url', function () { - expect(request.url).to.equal('https://prebid.admedia.com/bidder/'); - }); - - it('bidRequest data', function () { - const data = JSON.parse(request.data); - expect(decodeURIComponent(data.referer)).to.be.eql(bidderRequest.refererInfo.referer); - expect(data.tags).to.be.an('array'); - expect(data.tags[0].aid).to.be.eql(validBidRequests[0].params.aid); - expect(data.tags[0].id).to.be.eql(validBidRequests[0].bidId); - expect(data.tags[0].sizes).to.be.eql(validBidRequests[0].sizes); - expect(data.tags[1].aid).to.be.eql(validBidRequests[1].params.aid); - expect(data.tags[1].id).to.be.eql(validBidRequests[1].bidId); - expect(data.tags[1].sizes).to.be.eql(validBidRequests[1].sizes); - }); - }); - - describe('interpretResponse', function () { - const serverResponse = { - body: { - tags: [ - { - ad: '', - cpm: 0.9, - height: 250, - id: '5582180864bc41', - width: 300, - }, - { - error: 'Error message', - id: '6dc6ee4e157749' - }, - { - ad: '', - cpm: 0, - height: 728, - id: '5762180864bc41', - width: 90, - } - ] - }, - headers: {} - }; - - const bidRequest = {}; - - const result = spec.interpretResponse(serverResponse, bidRequest); - - it('Should return an empty array if empty or no tags in response', function () { - expect(spec.interpretResponse({body: ''}, {}).length).to.equal(0); - }); - - it('Should have only one bid', function () { - expect(result.length).to.equal(1); - }); - - it('Should have required keys', function () { - expect(result[0].requestId).to.be.eql(serverResponse.body.tags[0].id); - expect(result[0].cpm).to.be.eql(serverResponse.body.tags[0].cpm); - expect(result[0].width).to.be.eql(serverResponse.body.tags[0].width); - expect(result[0].height).to.be.eql(serverResponse.body.tags[0].height); - expect(result[0].creativeId).to.be.eql(serverResponse.body.tags[0].id); - expect(result[0].dealId).to.be.eql(serverResponse.body.tags[0].id); - expect(result[0].netRevenue).to.be.eql(true); - expect(result[0].ttl).to.be.eql(120); - expect(result[0].ad).to.be.eql(serverResponse.body.tags[0].ad); - }) - }); -}); diff --git a/test/spec/modules/admixerBidAdapter_spec.js b/test/spec/modules/admixerBidAdapter_spec.js deleted file mode 100644 index 030e98d23f9..00000000000 --- a/test/spec/modules/admixerBidAdapter_spec.js +++ /dev/null @@ -1,171 +0,0 @@ -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 ENDPOINT_URL = 'https://inv-nets.admixer.net/prebid.1.1.aspx'; -const ENDPOINT_URL_CUSTOM = 'https://custom.admixer.net/prebid.aspx'; -const ZONE_ID = '2eb6bd58-865c-47ce-af7f-a918108c3fd2'; - -describe('AdmixerAdapter', function () { - const adapter = newBidder(spec); - - describe('inherited functions', function () { - it('exists and is a function', function () { - expect(adapter.callBids).to.be.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - let bid = { - 'bidder': BIDDER_CODE, - 'params': { - 'zone': ZONE_ID - }, - '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(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'placementId': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let validRequest = [ - { - 'bidder': BIDDER_CODE, - 'params': { - 'zone': ZONE_ID - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - let bidderRequest = { - bidderCode: BIDDER_CODE, - refererInfo: { - referer: 'https://example.com' - } - }; - - it('should add referrer and imp to be equal bidRequest', function () { - const request = spec.buildRequests(validRequest, bidderRequest); - const payload = JSON.parse(request.data.substr(5)); - expect(payload.referrer).to.not.be.undefined; - expect(payload.imps[0]).to.deep.equal(validRequest[0]); - }); - - it('sends bid request to ENDPOINT via GET', function () { - const request = spec.buildRequests(validRequest, bidderRequest); - expect(request.url).to.equal(ENDPOINT_URL); - expect(request.method).to.equal('GET'); - }); - - it('sends bid request to CUSTOM_ENDPOINT via GET', function () { - config.setBidderConfig({ - bidders: [BIDDER_CODE], // one or more bidders - config: {[BIDDER_CODE]: {endpoint_url: ENDPOINT_URL_CUSTOM}} - }); - const request = config.runWithBidder(BIDDER_CODE, () => spec.buildRequests(validRequest, bidderRequest)); - expect(request.url).to.equal(ENDPOINT_URL_CUSTOM); - expect(request.method).to.equal('GET'); - }); - }); - - describe('interpretResponse', function () { - let response = { - body: { - ads: [{ - 'currency': 'USD', - 'cpm': 6.210000, - 'ad': '
ad
', - 'width': 300, - 'height': 600, - 'creativeId': 'ccca3e5e-0c54-4761-9667-771322fbdffc', - 'ttl': 360, - 'netRevenue': false, - 'bidId': '5e4e763b6bc60b', - 'dealId': 'asd123', - 'meta': {'advertiserId': 123, 'networkId': 123, 'advertiserDomains': ['test.com']} - }] - } - }; - - it('should get correct bid response', function () { - const ads = response.body.ads; - let expectedResponse = [ - { - 'requestId': ads[0].bidId, - 'cpm': ads[0].cpm, - 'creativeId': ads[0].creativeId, - 'width': ads[0].width, - 'height': ads[0].height, - 'ad': ads[0].ad, - 'vastUrl': undefined, - 'currency': ads[0].currency, - 'netRevenue': ads[0].netRevenue, - 'ttl': ads[0].ttl, - 'dealId': ads[0].dealId, - 'meta': {'advertiserId': 123, 'networkId': 123, 'advertiserDomains': ['test.com']} - } - ]; - - let result = spec.interpretResponse(response); - expect(result[0]).to.deep.equal(expectedResponse[0]); - }); - - it('handles nobid responses', function () { - let response = []; - - let result = spec.interpretResponse(response); - expect(result.length).to.equal(0); - }); - }); - - describe('getUserSyncs', function () { - let imgUrl = 'https://example.com/img1'; - let frmUrl = 'https://example.com/frm2'; - let responses = [{ - body: { - cm: { - pixels: [ - imgUrl - ], - iframes: [ - frmUrl - ], - } - } - }]; - - it('Returns valid values', function () { - let userSyncAll = spec.getUserSyncs({pixelEnabled: true, iframeEnabled: true}, responses); - let userSyncImg = spec.getUserSyncs({pixelEnabled: true, iframeEnabled: false}, responses); - let 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); - expect(userSyncImg[0].type).to.be.equal('image'); - expect(userSyncFrm).to.be.an('array').with.lengthOf(1); - expect(userSyncFrm[0].url).to.be.equal(frmUrl); - expect(userSyncFrm[0].type).to.be.equal('iframe'); - }); - }); -}); diff --git a/test/spec/modules/admixerIdSystem_spec.js b/test/spec/modules/admixerIdSystem_spec.js deleted file mode 100644 index 18107b780db..00000000000 --- a/test/spec/modules/admixerIdSystem_spec.js +++ /dev/null @@ -1,81 +0,0 @@ -import {admixerIdSubmodule} from 'modules/admixerIdSystem.js'; -import * as utils from 'src/utils.js'; -import {server} from 'test/mocks/xhr.js'; -import {getStorageManager} from '../../../src/storageManager.js'; - -export const storage = getStorageManager(); - -const pid = '4D393FAC-B6BB-4E19-8396-0A4813607316'; -const getIdParams = {params: {pid: pid}}; -describe('admixerId tests', function () { - let logErrorStub; - - beforeEach(function () { - logErrorStub = sinon.stub(utils, 'logError'); - }); - - afterEach(function () { - logErrorStub.restore(); - }); - - it('should log an error if pid configParam was not passed when getId', function () { - admixerIdSubmodule.getId(); - expect(logErrorStub.callCount).to.be.equal(1); - - admixerIdSubmodule.getId({}); - expect(logErrorStub.callCount).to.be.equal(2); - - admixerIdSubmodule.getId({params: {}}); - expect(logErrorStub.callCount).to.be.equal(3); - - 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 () { - let submoduleCallback = admixerIdSubmodule.getId(getIdParams, { gdprApplies: true }); - expect(submoduleCallback).to.be.undefined; - }); - - it('should call the admixer id endpoint', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = admixerIdSubmodule.getId(getIdParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq(`https://inv-nets.admixer.net/cntcm.aspx?ssp=${pid}`); - request.respond( - 200, - {}, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should call callback with user id', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = admixerIdSubmodule.getId(getIdParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq(`https://inv-nets.admixer.net/cntcm.aspx?ssp=${pid}`); - request.respond( - 200, - {}, - JSON.stringify({setData: {visitorid: '571058d70bce453b80e6d98b4f8a81e3'}}) - ); - expect(callBackSpy.calledOnce).to.be.true; - expect(callBackSpy.args[0][0]).to.be.eq('571058d70bce453b80e6d98b4f8a81e3'); - }); - - it('should continue to callback if ajax response 204', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = admixerIdSubmodule.getId(getIdParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq(`https://inv-nets.admixer.net/cntcm.aspx?ssp=${pid}`); - request.respond( - 204 - ); - expect(callBackSpy.calledOnce).to.be.true; - expect(callBackSpy.args[0][0]).to.be.undefined; - }); -}); diff --git a/test/spec/modules/adnowBidAdapter_spec.js b/test/spec/modules/adnowBidAdapter_spec.js deleted file mode 100644 index a8013e3fa04..00000000000 --- a/test/spec/modules/adnowBidAdapter_spec.js +++ /dev/null @@ -1,163 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/adnowBidAdapter.js'; - -describe('adnowBidAdapter', function () { - describe('isBidRequestValid', function () { - it('Should return true', function() { - expect(spec.isBidRequestValid({ - bidder: 'adnow', - params: { - codeId: 12345 - } - })).to.equal(true); - }); - - it('Should return false when required params is not passed', function() { - expect(spec.isBidRequestValid({ - bidder: 'adnow', - params: {} - })).to.equal(false); - }); - }); - - describe('buildRequests', function() { - it('Common settings', function() { - const bidRequestData = [{ - bidId: 'bid12345', - params: { - codeId: 12345 - } - }]; - - const req = spec.buildRequests(bidRequestData); - const reqData = req[0].data; - - expect(reqData) - .to.match(/Id=12345/) - .to.match(/mediaType=native/) - .to.match(/out=prebid/) - .to.match(/requestid=bid12345/) - .to.match(/d_user_agent=.+/); - }); - - it('Banner sizes', function () { - const bidRequestData = [{ - bidId: 'bid12345', - params: { - codeId: 12345 - }, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - } - }]; - - const req = spec.buildRequests(bidRequestData); - const reqData = req[0].data; - - expect(reqData).to.match(/sizes=300x250/); - }); - - it('Native sizes', function () { - const bidRequestData = [{ - bidId: 'bid12345', - params: { - codeId: 12345 - }, - mediaTypes: { - native: { - image: { - sizes: [100, 100] - } - } - } - }]; - - const req = spec.buildRequests(bidRequestData); - const reqData = req[0].data; - - expect(reqData) - .to.match(/width=100/) - .to.match(/height=100/); - }); - }); - - describe('interpretResponse', function() { - const request = { - bidRequest: { - bidId: 'bid12345' - } - }; - - it('Response with native bid', function() { - const response = { - currency: 'USD', - cpm: 0.5, - native: { - title: 'Title', - body: 'Body', - sponsoredBy: 'AdNow', - clickUrl: '//click.url', - image: { - url: '//img.url', - height: 200, - width: 200 - } - }, - meta: { - mediaType: 'native' - } - }; - - const bids = spec.interpretResponse({ body: response }, request); - expect(bids).to.be.an('array').that.is.not.empty; - - const bid = bids[0]; - expect(bid).to.have.keys('requestId', 'cpm', 'currency', 'native', 'creativeId', 'netRevenue', 'meta', 'ttl'); - - const nativePart = bid.native; - - expect(nativePart.title).to.be.equal('Title'); - expect(nativePart.body).to.be.equal('Body'); - expect(nativePart.clickUrl).to.be.equal('//click.url'); - expect(nativePart.image.url).to.be.equal('//img.url'); - expect(nativePart.image.height).to.be.equal(200); - expect(nativePart.image.width).to.be.equal(200); - }); - - it('Response with banner bid', function() { - const response = { - currency: 'USD', - cpm: 0.5, - ad: '
Banner
', - meta: { - mediaType: 'banner' - } - }; - - const bids = spec.interpretResponse({ body: response }, request); - expect(bids).to.be.an('array').that.is.not.empty; - - const bid = bids[0]; - expect(bid).to.have.keys( - 'requestId', 'cpm', 'currency', 'ad', 'creativeId', 'netRevenue', 'meta', 'ttl', 'width', 'height' - ); - - expect(bid.ad).to.be.equal('
Banner
'); - }); - - it('Response with no bid should return an empty array', function() { - const noBidResponses = [ - false, - {}, - {body: false}, - {body: {}} - ]; - - noBidResponses.forEach(response => { - return expect(spec.interpretResponse(response, request)).to.be.an('array').that.is.empty; - }); - }); - }); -}); diff --git a/test/spec/modules/adnuntiusBidAdapter_spec.js b/test/spec/modules/adnuntiusBidAdapter_spec.js deleted file mode 100644 index 62073fc6aaa..00000000000 --- a/test/spec/modules/adnuntiusBidAdapter_spec.js +++ /dev/null @@ -1,139 +0,0 @@ -// import or require modules necessary for the test, e.g.: -import { expect } from 'chai'; // may prefer 'assert' in place of 'expect' -import { spec } from 'modules/adnuntiusBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('adnuntiusBidAdapter', function () { - const tzo = new Date().getTimezoneOffset(); - const ENDPOINT_URL = `https://delivery.adnuntius.com/i?tzo=${tzo}&format=json`; - const adapter = newBidder(spec); - - const bidRequests = [ - { - bidId: '123', - bidder: 'adnuntius', - params: { - auId: '8b6bc', - network: 'adnuntius', - }, - - } - ] - - const singleBidRequest = { - bid: [ - { - bidId: '123', - } - ] - } - - const serverResponse = { - body: { - 'adUnits': [ - { - 'auId': '000000000008b6bc', - 'targetId': '123', - 'html': '

hi!

', - 'matchedAdCount': 1, - 'responseId': 'adn-rsp-1460129238', - 'ads': [ - { - 'destinationUrlEsc': 'https%3A%2F%2Fdelivery.adnuntius.com%2Fc%2F52AHNuxCqxB_Y9ZP9ERWkMBPCOha4zuV3aKn5cog5jsAAAAQCtjQz9kbGWD4nuZy3q6HaHGLB4-k_fySWECIOOmHKY6iokgHNFH-U57ew_-1QHlKnFr2NT8y4QK1oU5HxnDLbYPz-GmQ3C2JyxLGpKmIb-P-3bm7HYPEreNjPdhjRG51A8NGuc4huUhns7nEUejHuOjOHE5sV1zfYxCRWRx9wPDN9EUCC7KN%3Fct%3D2501%26r%3Dhttp%253A%252F%252Fgoogle.com', - 'assets': { - 'image': { - 'cdnId': 'https://assets.adnuntius.com/oEmZa5uYjxENfA1R692FVn6qIveFpO8wUbpyF2xSOCc.jpg', - 'width': '980', - 'height': '120' - } - }, - 'clickUrl': 'https://delivery.adnuntius.com/c/52AHNuxCqxB_Y9ZP9ERWkMBPCOha4zuV3aKn5cog5jsAAAAQCtjQz9kbGWD4nuZy3q6HaHGLB4-k_fySWECIOOmHKY6iokgHNFH-U57ew_-1QHlKnFr2NT8y4QK1oU5HxnDLbYPz-GmQ3C2JyxLGpKmIb-P-3bm7HYPEreNjPdhjRG51A8NGuc4huUhns7nEUejHuOjOHE5sV1zfYxCRWRx9wPDN9EUCC7KN', - 'urls': { - 'destination': 'https://delivery.adnuntius.com/c/52AHNuxCqxB_Y9ZP9ERWkMBPCOha4zuV3aKn5cog5jsAAAAQCtjQz9kbGWD4nuZy3q6HaHGLB4-k_fySWECIOOmHKY6iokgHNFH-U57ew_-1QHlKnFr2NT8y4QK1oU5HxnDLbYPz-GmQ3C2JyxLGpKmIb-P-3bm7HYPEreNjPdhjRG51A8NGuc4huUhns7nEUejHuOjOHE5sV1zfYxCRWRx9wPDN9EUCC7KN?ct=2501&r=http%3A%2F%2Fgoogle.com' - }, - 'urlsEsc': { - 'destination': 'https%3A%2F%2Fdelivery.adnuntius.com%2Fc%2F52AHNuxCqxB_Y9ZP9ERWkMBPCOha4zuV3aKn5cog5jsAAAAQCtjQz9kbGWD4nuZy3q6HaHGLB4-k_fySWECIOOmHKY6iokgHNFH-U57ew_-1QHlKnFr2NT8y4QK1oU5HxnDLbYPz-GmQ3C2JyxLGpKmIb-P-3bm7HYPEreNjPdhjRG51A8NGuc4huUhns7nEUejHuOjOHE5sV1zfYxCRWRx9wPDN9EUCC7KN%3Fct%3D2501%26r%3Dhttp%253A%252F%252Fgoogle.com' - }, - 'destinationUrls': { - 'destination': 'http://google.com' - }, - 'cpm': { 'amount': 5.0, 'currency': 'NOK' }, - 'bid': { 'amount': 0.005, 'currency': 'NOK' }, - 'cost': { 'amount': 0.005, 'currency': 'NOK' }, - 'impressionTrackingUrls': [], - 'impressionTrackingUrlsEsc': [], - 'adId': 'adn-id-1347343135', - 'selectedColumn': '0', - 'selectedColumnPosition': '0', - 'renderedPixel': 'https://delivery.adnuntius.com/b/52AHNuxCqxB_Y9ZP9ERWkMBPCOha4zuV3aKn5cog5jsAAAAQCtjQz9kbGWD4nuZy3q6HaHGLB4-k_fySWECIOOmHKY6iokgHNFH-U57ew_-1QHlKnFr2NT8y4QK1oU5HxnDLbYPz-GmQ3C2JyxLGpKmIb-P-3bm7HYPEreNjPdhjRG51A8NGuc4huUhns7nEUejHuOjOHE5sV1zfYxCRWRx9wPDN9EUCC7KN.html', - 'renderedPixelEsc': 'https%3A%2F%2Fdelivery.adnuntius.com%2Fb%2F52AHNuxCqxB_Y9ZP9ERWkMBPCOha4zuV3aKn5cog5jsAAAAQCtjQz9kbGWD4nuZy3q6HaHGLB4-k_fySWECIOOmHKY6iokgHNFH-U57ew_-1QHlKnFr2NT8y4QK1oU5HxnDLbYPz-GmQ3C2JyxLGpKmIb-P-3bm7HYPEreNjPdhjRG51A8NGuc4huUhns7nEUejHuOjOHE5sV1zfYxCRWRx9wPDN9EUCC7KN.html', - 'visibleUrl': 'https://delivery.adnuntius.com/s?rt=52AHNuxCqxB_Y9ZP9ERWkMBPCOha4zuV3aKn5cog5jsAAAAQCtjQz9kbGWD4nuZy3q6HaHGLB4-k_fySWECIOOmHKY6iokgHNFH-U57ew_-1QHlKnFr2NT8y4QK1oU5HxnDLbYPz-GmQ3C2JyxLGpKmIb-P-3bm7HYPEreNjPdhjRG51A8NGuc4huUhns7nEUejHuOjOHE5sV1zfYxCRWRx9wPDN9EUCC7KN', - 'visibleUrlEsc': 'https%3A%2F%2Fdelivery.adnuntius.com%2Fs%3Frt%3D52AHNuxCqxB_Y9ZP9ERWkMBPCOha4zuV3aKn5cog5jsAAAAQCtjQz9kbGWD4nuZy3q6HaHGLB4-k_fySWECIOOmHKY6iokgHNFH-U57ew_-1QHlKnFr2NT8y4QK1oU5HxnDLbYPz-GmQ3C2JyxLGpKmIb-P-3bm7HYPEreNjPdhjRG51A8NGuc4huUhns7nEUejHuOjOHE5sV1zfYxCRWRx9wPDN9EUCC7KN', - 'viewUrl': 'https://delivery.adnuntius.com/v?rt=52AHNuxCqxB_Y9ZP9ERWkMBPCOha4zuV3aKn5cog5jsAAAAQCtjQz9kbGWD4nuZy3q6HaHGLB4-k_fySWECIOOmHKY6iokgHNFH-U57ew_-1QHlKnFr2NT8y4QK1oU5HxnDLbYPz-GmQ3C2JyxLGpKmIb-P-3bm7HYPEreNjPdhjRG51A8NGuc4huUhns7nEUejHuOjOHE5sV1zfYxCRWRx9wPDN9EUCC7KN', - 'viewUrlEsc': 'https%3A%2F%2Fdelivery.adnuntius.com%2Fv%3Frt%3D52AHNuxCqxB_Y9ZP9ERWkMBPCOha4zuV3aKn5cog5jsAAAAQCtjQz9kbGWD4nuZy3q6HaHGLB4-k_fySWECIOOmHKY6iokgHNFH-U57ew_-1QHlKnFr2NT8y4QK1oU5HxnDLbYPz-GmQ3C2JyxLGpKmIb-P-3bm7HYPEreNjPdhjRG51A8NGuc4huUhns7nEUejHuOjOHE5sV1zfYxCRWRx9wPDN9EUCC7KN', - 'rt': '52AHNuxCqxB_Y9ZP9ERWkMBPCOha4zuV3aKn5cog5jsAAAAQCtjQz9kbGWD4nuZy3q6HaHGLB4-k_fySWECIOOmHKY6iokgHNFH-U57ew_-1QHlKnFr2NT8y4QK1oU5HxnDLbYPz-GmQ3C2JyxLGpKmIb-P-3bm7HYPEreNjPdhjRG51A8NGuc4huUhns7nEUejHuOjOHE5sV1zfYxCRWRx9wPDN9EUCC7KN', - 'creativeWidth': '980', - 'creativeHeight': '120', - 'creativeId': 'wgkq587vgtpchsx1', - 'lineItemId': 'scyjdyv3mzgdsnpf', - 'layoutId': 'sw6gtws2rdj1kwby', - 'layoutName': 'Responsive image' - }, - - ] - }, - { - 'auId': '000000000008b6bc', - 'targetId': '456', - 'matchedAdCount': 0, - 'responseId': 'adn-rsp-1460129238', - } - ] - } - } - - describe('inherited functions', function () { - it('exists and is a function', function () { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bidRequests[0])).to.equal(true); - }); - }); - - describe('buildRequests', function () { - it('Test requests', function () { - const request = spec.buildRequests(bidRequests); - expect(request.length).to.equal(1); - expect(request[0]).to.have.property('bid'); - const bid = request[0].bid[0] - expect(bid).to.have.property('bidId'); - expect(request[0]).to.have.property('url'); - expect(request[0].url).to.equal(ENDPOINT_URL); - expect(request[0]).to.have.property('data'); - expect(request[0].data).to.equal('{\"adUnits\":[{\"auId\":\"8b6bc\",\"targetId\":\"123\"}]}'); - }); - }); - - describe('interpretResponse', function () { - it('should return valid response when passed valid server response', function () { - const interpretedResponse = spec.interpretResponse(serverResponse, singleBidRequest); - const ad = serverResponse.body.adUnits[0].ads[0] - expect(interpretedResponse).to.have.lengthOf(1); - expect(interpretedResponse[0].cpm).to.equal(ad.cpm.amount); - expect(interpretedResponse[0].width).to.equal(Number(ad.creativeWidth)); - expect(interpretedResponse[0].height).to.equal(Number(ad.creativeHeight)); - expect(interpretedResponse[0].creativeId).to.equal(ad.creativeId); - expect(interpretedResponse[0].currency).to.equal(ad.bid.currency); - expect(interpretedResponse[0].netRevenue).to.equal(false); - expect(interpretedResponse[0].meta).to.have.property('advertiserDomains'); - expect(interpretedResponse[0].meta.advertiserDomains).to.have.lengthOf(1); - expect(interpretedResponse[0].meta.advertiserDomains[0]).to.equal('google.com'); - expect(interpretedResponse[0].ad).to.equal(serverResponse.body.adUnits[0].html); - expect(interpretedResponse[0].ttl).to.equal(360); - }); - }); -}); diff --git a/test/spec/modules/adoceanBidAdapter_spec.js b/test/spec/modules/adoceanBidAdapter_spec.js deleted file mode 100644 index 2b4b7d711e1..00000000000 --- a/test/spec/modules/adoceanBidAdapter_spec.js +++ /dev/null @@ -1,218 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/adoceanBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import { deepClone } from 'src/utils.js'; - -describe('AdoceanAdapter', 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 bid = { - 'bidder': 'adocean', - 'params': { - 'masterId': 'tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7', - 'slaveId': 'adoceanmyaozpniqismex', - 'emiter': 'myao.adocean.pl' - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - const bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'masterId': 0 - }; - - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const bidRequests = [ - { - 'bidder': 'adocean', - 'params': { - 'masterId': 'tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7', - 'slaveId': 'adoceanmyaozpniqismex', - 'emiter': 'myao.adocean.pl' - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }, - { - 'bidder': 'adocean', - 'params': { - 'masterId': 'tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7', - 'slaveId': 'adoceanmyaozpniqismex', - 'emiter': 'myao.adocean.pl' - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 200], [600, 250]] - } - }, - 'bidId': '30b31c1838de1f', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - const bidderRequest = { - gdprConsent: { - consentString: 'BOQHk-4OSlWKFBoABBPLBd-AAAAgWAHAACAAsAPQBSACmgFTAOkA', - gdprApplies: true - } - }; - - it('should send two requests if slave is duplicated', function () { - const nrOfRequests = spec.buildRequests(bidRequests, bidderRequest).length; - expect(nrOfRequests).to.equal(2); - }); - - it('should add bidIdMap with correct slaveId => bidId mapping', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (let i = 0; i < bidRequests.length; i++) { - expect(requests[i]).to.exist; - expect(requests[i].bidIdMap).to.exist; - expect(requests[i].bidIdMap[bidRequests[i].params.slaveId]).to.equal(bidRequests[i].bidId); - } - }); - - it('sends bid request to url via GET', function () { - const request = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(request.method).to.equal('GET'); - expect(request.url).to.match(new RegExp(`^https://${bidRequests[0].params.emiter}/_[0-9]*/ad.json`)); - }); - - it('should attach id to url', function () { - const request = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(request.url).to.include('id=' + bidRequests[0].params.masterId); - }); - - it('should attach consent information to url', function () { - const request = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(request.url).to.include('gdpr=1'); - expect(request.url).to.include('gdpr_consent=' + bidderRequest.gdprConsent.consentString); - }); - - it('should attach sizes information to url', function () { - let requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests[0].url).to.include('aosspsizes=myaozpniqismex~300x250_300x600'); - expect(requests[1].url).to.include('aosspsizes=myaozpniqismex~300x200_600x250'); - - const differentSlavesBids = deepClone(bidRequests); - differentSlavesBids[1].params.slaveId = 'adoceanmyaowafpdwlrks'; - requests = spec.buildRequests(differentSlavesBids, bidderRequest); - expect(requests.length).to.equal(1); - expect(requests[0].url).to.include('aosspsizes=myaozpniqismex~300x250_300x600-myaowafpdwlrks~300x200_600x250'); - expect((requests[0].url.match(/aosspsizes=/g) || []).length).to.equal(1); - }); - }) - - describe('interpretResponse', function () { - const response = { - 'body': [ - { - 'id': 'adoceanmyaozpniqismex', - 'price': '0.019000', - 'winurl': '', - 'statsUrl': '', - 'code': '%3C!--%20Creative%20--%3E', - 'currency': 'EUR', - 'minFloorPrice': '0.01', - 'width': '300', - 'height': '250', - 'crid': '0af345b42983cc4bc0', - 'ttl': '300' - } - ], - 'headers': { - 'get': function() {} - } - }; - - const bidRequest = { - 'bidder': 'adocean', - 'params': { - 'masterId': 'tmYF.DMl7ZBq.Nqt2Bq4FutQTJfTpxCOmtNPZoQUDcL.G7', - 'slaveId': 'adoceanmyaozpniqismex', - 'emiter': 'myao.adocean.pl' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250]], - 'bidIdMap': { - 'adoceanmyaozpniqismex': '30b31c1838de1e' - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - - it('should get correct bid response', function () { - const expectedResponse = [ - { - 'requestId': '30b31c1838de1e', - 'cpm': 0.019000, - 'currency': 'EUR', - 'width': 300, - 'height': 250, - 'ad': '', - 'creativeId': '0af345b42983cc4bc0', - 'ttl': 300, - 'netRevenue': false - } - ]; - - const result = spec.interpretResponse(response, bidRequest); - expect(result).to.have.lengthOf(1); - let resultKeys = Object.keys(result[0]); - expect(resultKeys.sort()).to.deep.equal(Object.keys(expectedResponse[0]).sort()); - resultKeys.forEach(function(k) { - if (k === 'ad') { - expect(result[0][k]).to.match(/$/); - } else { - expect(result[0][k]).to.equal(expectedResponse[0][k]); - } - }); - }); - - it('handles nobid responses', function () { - response.body = [ - { - 'id': 'adoceanmyaolafpjwftbz', - 'error': 'true' - } - ]; - - const result = spec.interpretResponse(response, bidRequest); - expect(result).to.have.lengthOf(0); - }); - }); -}); diff --git a/test/spec/modules/adomikAnalyticsAdapter_spec.js b/test/spec/modules/adomikAnalyticsAdapter_spec.js deleted file mode 100644 index 1414b2402b9..00000000000 --- a/test/spec/modules/adomikAnalyticsAdapter_spec.js +++ /dev/null @@ -1,143 +0,0 @@ -import adomikAnalytics from 'modules/adomikAnalyticsAdapter.js'; -import {expect} from 'chai'; -let events = require('src/events'); -let adapterManager = require('src/adapterManager').default; -let constants = require('src/constants.json'); - -describe('Adomik Prebid Analytic', function () { - let sendEventStub; - let sendWonEventStub; - let clock; - before(function () { - clock = sinon.useFakeTimers(); - }); - after(function () { - clock.restore(); - }); - - describe('enableAnalytics', function () { - beforeEach(function () { - sinon.spy(adomikAnalytics, 'track'); - sendEventStub = sinon.stub(adomikAnalytics, 'sendTypedEvent'); - sendWonEventStub = sinon.stub(adomikAnalytics, 'sendWonEvent'); - sinon.stub(events, 'getEvents').returns([]); - }); - - afterEach(function () { - adomikAnalytics.track.restore(); - sendEventStub.restore(); - sendWonEventStub.restore(); - events.getEvents.restore(); - }); - - after(function () { - adomikAnalytics.disableAnalytics(); - }); - - it('should catch all events', function (done) { - adapterManager.registerAnalyticsAdapter({ - code: 'adomik', - adapter: adomikAnalytics - }); - - const initOptions = { - id: '123456', - url: 'testurl', - }; - - const bid = { - bidderCode: 'adomik_test_bid', - width: 10, - height: 10, - statusMessage: 'Bid available', - adId: '1234', - auctionId: '', - responseTimestamp: 1496410856397, - requestTimestamp: 1496410856295, - cpm: 0.1, - bidder: 'biddertest', - adUnitCode: '0000', - timeToRespond: 100, - placementCode: 'placementtest' - } - - // Step 1: Initialize adapter - adapterManager.enableAnalytics({ - provider: 'adomik', - options: initOptions - }); - expect(adomikAnalytics.currentContext).to.deep.equal({ - uid: '123456', - url: 'testurl', - id: '', - timeouted: false - }); - - // Step 2: Send init auction event - events.emit(constants.EVENTS.AUCTION_INIT, {config: initOptions, auctionId: 'test-test-test'}); - - expect(adomikAnalytics.currentContext).to.deep.equal({ - uid: '123456', - url: 'testurl', - id: 'test-test-test', - timeouted: false - }); - - // Step 3: Send bid requested event - events.emit(constants.EVENTS.BID_REQUESTED, { bids: [bid] }); - - expect(adomikAnalytics.bucketEvents.length).to.equal(1); - expect(adomikAnalytics.bucketEvents[0]).to.deep.equal({ - type: 'request', - event: { - bidder: 'BIDDERTEST', - placementCode: 'placementtest', - } - }); - - // Step 4: Send bid response event - events.emit(constants.EVENTS.BID_RESPONSE, bid); - - expect(adomikAnalytics.bucketEvents.length).to.equal(2); - expect(adomikAnalytics.bucketEvents[1]).to.deep.equal({ - type: 'response', - event: { - bidder: 'ADOMIK_TEST_BID', - placementCode: '0000', - id: '1234', - status: 'VALID', - cpm: 0.1, - size: { - width: 10, - height: 10 - }, - timeToRespond: 100, - afterTimeout: false, - } - }); - - // Step 5: Send bid won event - events.emit(constants.EVENTS.BID_WON, bid); - - expect(adomikAnalytics.bucketEvents.length).to.equal(2); - - // Step 6: Send bid timeout event - events.emit(constants.EVENTS.BID_TIMEOUT, {}); - - expect(adomikAnalytics.currentContext.timeouted).to.equal(true); - - // Step 7: Send auction end event - events.emit(constants.EVENTS.AUCTION_END, {}); - - setTimeout(function() { - sinon.assert.callCount(sendEventStub, 1); - sinon.assert.callCount(sendWonEventStub, 1); - done(); - }, 3000); - - clock.tick(5000); - - sinon.assert.callCount(adomikAnalytics.track, 6); - }); - }); -}); diff --git a/test/spec/modules/adotBidAdapter_spec.js b/test/spec/modules/adotBidAdapter_spec.js deleted file mode 100644 index d580cd763a4..00000000000 --- a/test/spec/modules/adotBidAdapter_spec.js +++ /dev/null @@ -1,3136 +0,0 @@ -import { expect } from 'chai'; -import { executeRenderer } from 'src/Renderer.js'; -import * as utils from 'src/utils.js'; -import { spec } from 'modules/adotBidAdapter.js'; - -const BIDDER_URL = 'https://dsp.adotmob.com/headerbidding/bidrequest'; - -describe('Adot Adapter', function () { - const examples = { - adUnit_banner: { - adUnitCode: 'ad_unit_banner', - bidder: 'adot', - bidderRequestId: 'bid_request_id', - bidId: 'bid_id', - params: {}, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - } - }, - - adUnit_video_outstream: { - adUnitCode: 'ad_unit_video_outstream', - bidder: 'adot', - bidderRequestId: 'bid_request_id', - bidId: 'bid_id', - params: { - video: { - mimes: ['video/mp4'], - minDuration: 5, - maxDuration: 30, - protocols: [2, 3] - } - }, - mediaTypes: { - video: { - context: 'outstream', - playerSize: [[300, 250]] - } - } - }, - - adUnit_video_instream: { - adUnitCode: 'ad_unit_video_instream', - bidder: 'adot', - bidderRequestId: 'bid_request_id', - bidId: 'bid_id', - params: { - video: { - instreamContext: 'pre-roll', - mimes: ['video/mp4'], - minDuration: 5, - maxDuration: 30, - protocols: [2, 3] - } - }, - mediaTypes: { - video: { - context: 'instream', - playerSize: [[300, 250]] - } - } - }, - - adUnitContext: { - refererInfo: { - referer: 'https://we-are-adot.com/test', - }, - gdprConsent: { - consentString: 'consent_string', - gdprApplies: true - } - }, - - adUnit_position: { - adUnitCode: 'ad_unit_position', - bidder: 'adot', - bidderRequestId: 'bid_request_id', - bidId: 'bid_id', - params: { - position: 1 - }, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - } - }, - - adUnit_native: { - adUnitCode: 'ad_unit_native', - bidder: 'adot', - bidderRequestId: 'bid_request_id', - bidId: 'bid_id', - params: {}, - mediaTypes: { - native: { - title: {required: true, len: 140}, - icon: {required: true, sizes: [50, 50]}, - image: {required: false, sizes: [320, 200]}, - sponsoredBy: {required: false}, - body: {required: false}, - cta: {required: true} - } - } - }, - - serverRequest_banner: { - method: 'POST', - url: 'https://we-are-adot.com/bidrequest', - data: { - id: 'bid_request_id', - imp: [ - { - id: 'imp_id_banner_0_0', - banner: { - format: [{ - w: 300, - h: 200 - }] - }, - video: null - } - ], - site: { - page: 'https://we-are-adot.com/test', - domain: 'we-are-adot.com', - name: 'we-are-adot.com' - }, - device: { - ua: '', - language: 'en' - }, - user: null, - regs: null, - at: 1, - ext: { - adot: { - 'adapter_version': 'v1.0.0' - } - } - }, - _adot_internal: { - impressions: [ - { - impressionId: 'imp_id_banner_0_0', - adUnitCode: 'ad_unit_banner', - bidId: 'imp_id_banner' - } - ] - } - }, - - serverRequest_banner_twoImps: { - method: 'POST', - url: 'https://we-are-adot.com/bidrequest', - data: { - id: 'bid_request_id', - imp: [ - { - id: 'imp_id_banner_0_0', - banner: { - format: [{ - w: 300, - h: 200 - }] - }, - video: null - }, - { - id: 'imp_id_banner_2_0_0', - banner: { - format: [{ - w: 300, - h: 200 - }] - }, - video: null - } - ], - site: { - page: 'https://we-are-adot.com/test', - domain: 'we-are-adot.com', - name: 'we-are-adot.com' - }, - device: { - ua: '', - language: 'en' - }, - user: null, - regs: null, - at: 1, - ext: { - adot: { - 'adapter_version': 'v1.0.0' - } - } - }, - _adot_internal: { - impressions: [ - { - impressionId: 'imp_id_banner_0_0', - adUnitCode: 'ad_unit_banner', - bidId: 'imp_id_banner' - }, - { - impressionId: 'imp_id_banner_2_0_0', - adUnitCode: 'ad_unit_banner_2', - bidId: 'imp_id_banner_2' - } - ] - } - }, - - serverRequest_video_instream: { - method: 'POST', - url: 'https://we-are-adot.com/bidrequest', - data: { - id: 'bid_request_id', - imp: [ - { - id: 'imp_id_video_instream_0', - banner: null, - video: { - mimes: ['video/mp4'], - w: 300, - h: 200, - startdelay: 0, - minduration: 5, - maxduration: 35, - protocols: [2, 3] - } - } - ], - site: { - page: 'https://we-are-adot.com/test', - domain: 'we-are-adot.com', - name: 'we-are-adot.com' - }, - device: { - ua: '', - language: 'en' - }, - user: null, - regs: null, - at: 1, - ext: { - adot: { - 'adapter_version': 'v1.0.0' - } - } - }, - _adot_internal: { - impressions: [ - { - impressionId: 'imp_id_video_instream_0', - adUnitCode: 'ad_unit_video_instream', - bidId: 'imp_id_video_instream' - } - ] - } - }, - - serverRequest_video_outstream: { - method: 'POST', - url: 'https://we-are-adot.com/bidrequest', - data: { - id: 'bid_request_id', - imp: [ - { - id: 'imp_id_video_outstream_0', - banner: null, - video: { - mimes: ['video/mp4'], - w: 300, - h: 200, - startdelay: null, - minduration: 5, - maxduration: 35, - protocols: [2, 3] - } - } - ], - site: { - page: 'https://we-are-adot.com/test', - domain: 'we-are-adot.com', - name: 'we-are-adot.com' - }, - device: { - ua: '', - language: 'en' - }, - user: null, - regs: null, - at: 1, - ext: { - adot: { - 'adapter_version': 'v1.0.0' - } - } - }, - _adot_internal: { - impressions: [ - { - impressionId: 'imp_id_video_outstream_0', - adUnitCode: 'ad_unit_video_outstream', - bidId: 'imp_id_video_outstream' - } - ] - } - }, - - serverRequest_video_instream_outstream: { - method: 'POST', - url: 'https://we-are-adot.com/bidrequest', - data: { - id: 'bid_request_id', - imp: [ - { - id: 'imp_id_video_instream_0', - banner: null, - video: { - mimes: ['video/mp4'], - w: 300, - h: 200, - startdelay: 0, - minduration: 5, - maxduration: 35, - protocols: [2, 3] - } - }, - { - id: 'imp_id_video_outstream_0', - banner: null, - video: { - mimes: ['video/mp4'], - w: 300, - h: 200, - startdelay: null, - minduration: 5, - maxduration: 35, - protocols: [2, 3] - } - } - ], - site: { - page: 'https://we-are-adot.com/test', - domain: 'we-are-adot.com', - name: 'we-are-adot.com' - }, - device: { - ua: '', - language: 'en' - }, - user: null, - regs: null, - at: 1, - ext: { - adot: { - 'adapter_version': 'v1.0.0' - } - } - }, - _adot_internal: { - impressions: [ - { - impressionId: 'imp_id_video_instream_0', - adUnitCode: 'ad_unit_video_instream', - bidId: 'imp_id_video_instream' - }, - { - impressionId: 'imp_id_video_outstream_0', - adUnitCode: 'ad_unit_video_outstream', - bidId: 'imp_id_video_outstream' - } - ] - } - }, - - serverRequest_position: { - method: 'POST', - url: 'https://we-are-adot.com/bidrequest', - data: { - id: 'bid_request_id', - imp: [ - { - id: 'imp_id_banner', - banner: { - format: [{ - w: 300, - h: 200 - }], - position: 1 - }, - video: null - } - ], - site: { - page: 'https://we-are-adot.com/test', - domain: 'we-are-adot.com', - name: 'we-are-adot.com' - }, - device: { - ua: '', - language: 'en' - }, - user: null, - regs: null, - at: 1, - ext: { - adot: { - 'adapter_version': 'v1.0.0' - } - } - }, - _adot_internal: { - impressions: [ - { - impressionId: 'imp_id_banner', - adUnitCode: 'ad_unit_position' - } - ] - } - }, - - serverRequest_native: { - method: 'POST', - url: 'https://we-are-adot.com/bidrequest', - data: { - id: 'bid_request_id', - imp: [ - { - id: 'imp_id_native_0', - native: { - request: { - assets: [ - { - id: 1, - required: true, - title: { - len: 140 - } - }, - { - id: 2, - required: true, - img: { - type: 1, - wmin: 50, - hmin: 50 - } - }, - { - id: 3, - required: false, - img: { - type: 3, - wmin: 320, - hmin: 200 - } - }, - { - id: 4, - required: false, - data: { - type: 1 - } - }, - { - id: 5, - required: false, - data: { - type: 2 - } - }, - { - id: 6, - required: true, - data: { - type: 12 - } - } - ] - } - }, - video: null, - banner: null - } - ], - site: { - page: 'https://we-are-adot.com/test', - domain: 'we-are-adot.com', - name: 'we-are-adot.com' - }, - device: { - ua: '', - language: 'en' - }, - user: null, - regs: null, - at: 1, - ext: { - adot: { - 'adapter_version': 'v1.0.0' - } - } - }, - _adot_internal: { - impressions: [ - { - impressionId: 'imp_id_native_0', - adUnitCode: 'ad_unit_native', - bidId: 'imp_id_native' - } - ] - } - }, - - serverResponse_banner: { - body: { - cur: 'EUR', - seatbid: [ - { - bid: [ - { - impid: 'imp_id_banner_0_0', - crid: 'creative_id', - adm: 'creative_data_${AUCTION_PRICE}', - nurl: 'win_notice_url_${AUCTION_PRICE}', - price: 1.5, - h: 350, - w: 300, - ext: { - adot: { - media_type: 'banner' - } - } - } - ] - } - ] - } - }, - - serverResponse_banner_twoBids: { - body: { - cur: 'EUR', - seatbid: [ - { - bid: [ - { - impid: 'imp_id_banner_0_0', - crid: 'creative_id', - adm: 'creative_data_${AUCTION_PRICE}', - nurl: 'win_notice_url_${AUCTION_PRICE}', - price: 1.5, - h: 350, - w: 300, - ext: { - adot: { - media_type: 'banner' - } - } - }, - { - impid: 'imp_id_banner_2_0_0', - crid: 'creative_id_2', - adm: 'creative_data_2_${AUCTION_PRICE}', - nurl: 'win_notice_url_2_${AUCTION_PRICE}', - price: 2.5, - h: 400, - w: 350, - ext: { - adot: { - media_type: 'banner' - } - } - } - ] - } - ] - } - }, - - serverResponse_video_instream: { - body: { - cur: 'EUR', - seatbid: [ - { - bid: [ - { - impid: 'imp_id_video_instream_0', - crid: 'creative_id', - adm: 'creative_data_${AUCTION_PRICE}', - nurl: 'win_notice_url_${AUCTION_PRICE}', - price: 1.5, - ext: { - adot: { - media_type: 'video' - } - } - } - ] - } - ] - } - }, - - serverResponse_video_outstream: { - body: { - cur: 'EUR', - seatbid: [ - { - bid: [ - { - impid: 'imp_id_video_outstream_0', - crid: 'creative_id', - adm: 'creative_data_${AUCTION_PRICE}', - nurl: 'win_notice_url_${AUCTION_PRICE}', - price: 1.5, - ext: { - adot: { - media_type: 'video' - } - } - } - ] - } - ] - } - }, - - serverResponse_video_instream_outstream: { - body: { - cur: 'EUR', - seatbid: [ - { - bid: [ - { - impid: 'imp_id_video_instream_0', - crid: 'creative_id', - adm: 'creative_data_${AUCTION_PRICE}', - nurl: 'win_notice_url_${AUCTION_PRICE}', - price: 1.5, - ext: { - adot: { - media_type: 'video' - } - } - }, - { - impid: 'imp_id_video_outstream_0', - crid: 'creative_id', - adm: 'creative_data_${AUCTION_PRICE}', - nurl: 'win_notice_url_${AUCTION_PRICE}', - price: 1.5, - ext: { - adot: { - media_type: 'video' - } - } - } - ] - } - ] - } - }, - - serverResponse_native: { - body: { - cur: 'EUR', - seatbid: [ - { - bid: [ - { - impid: 'imp_id_native_0', - crid: 'creative_id', - adm: '{"native":{"assets":[{"id":1,"title":{"len":140,"text":"Hi everyone"}},{"id":2,"img":{"url":"https://adotmob.com","type":1,"w":50,"h":50}},{"id":3,"img":{"url":"https://adotmob.com","type":3,"w":320,"h":200}},{"id":4,"data":{"type":1,"value":"adotmob"}},{"id":5,"data":{"type":2,"value":"This is a test ad"}},{"id":6,"data":{"type":12,"value":"Click to buy"}}],"link":{"url":"https://adotmob.com?auction=${AUCTION_PRICE}"}}}', - nurl: 'win_notice_url_${AUCTION_PRICE}', - price: 1.5, - ext: { - adot: { - media_type: 'native' - } - } - } - ] - } - ] - } - } - }; - - describe('isBidRequestValid', function () { - describe('General', function () { - it('should return false when not given an ad unit', function () { - const adUnit = undefined; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an invalid ad unit', function () { - const adUnit = 'bad_bid'; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit without bidder code', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.bidder = undefined; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with a bad bidder code', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.bidder = 'unknownBidder'; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit without ad unit code', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.adUnitCode = undefined; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid ad unit code', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.adUnitCode = {}; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit without bid request identifier', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.bidderRequestId = undefined; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid bid request identifier', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.bidderRequestId = {}; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit without impression identifier', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.bidId = undefined; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid impression identifier', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.bidId = {}; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit without media types', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.mediaTypes = undefined; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with empty media types', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.mediaTypes = {}; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with invalid media types', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.mediaTypes = 'bad_media_types'; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - }); - - describe('Banner', function () { - it('should return true when given a valid ad unit', function () { - const adUnit = examples.adUnit_banner; - - expect(spec.isBidRequestValid(adUnit)).to.equal(true); - }); - - it('should return true when given a valid ad unit without bidder parameters', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.params = undefined; - - expect(spec.isBidRequestValid(adUnit)).to.equal(true); - }); - - it('should return false when given an ad unit without size', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.mediaTypes.banner.sizes = undefined; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid size', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.mediaTypes.banner.sizes = 'bad_banner_size'; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an empty size', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.mediaTypes.banner.sizes = []; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid size value', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.mediaTypes.banner.sizes = ['bad_banner_size_value']; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with a size value with less than 2 dimensions', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.mediaTypes.banner.sizes = [[300]]; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with a size value with more than 2 dimensions', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.mediaTypes.banner.sizes = [[300, 250, 30]]; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with a negative width value', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.mediaTypes.banner.sizes = [[-300, 250]]; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with a negative height value', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.mediaTypes.banner.sizes = [[300, -250]]; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid width value', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.mediaTypes.banner.sizes = [[false, 250]]; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid height value', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.mediaTypes.banner.sizes = [[300, {}]]; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - }); - - describe('Video', function () { - it('should return true when given a valid outstream ad unit', function () { - const adUnit = examples.adUnit_video_outstream; - - expect(spec.isBidRequestValid(adUnit)).to.equal(true); - }); - - it('should return true when given a valid pre-roll instream ad unit', function () { - const adUnit = utils.deepClone(examples.adUnit_video_instream); - adUnit.params.video.instreamContext = 'pre-roll'; - - expect(spec.isBidRequestValid(adUnit)).to.equal(true); - }); - - it('should return true when given a valid mid-roll instream ad unit', function () { - const adUnit = utils.deepClone(examples.adUnit_video_instream); - adUnit.params.video.instreamContext = 'mid-roll'; - - expect(spec.isBidRequestValid(adUnit)).to.equal(true); - }); - - it('should return true when given a valid post-roll instream ad unit', function () { - const adUnit = utils.deepClone(examples.adUnit_video_instream); - adUnit.params.video.instreamContext = 'post-roll'; - - expect(spec.isBidRequestValid(adUnit)).to.equal(true); - }); - - it('should return true when given an ad unit without size', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.mediaTypes.video.playerSize = undefined; - - expect(spec.isBidRequestValid(adUnit)).to.equal(true); - }); - - it('should return true when given an ad unit with an empty size', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.mediaTypes.video.playerSize = []; - - expect(spec.isBidRequestValid(adUnit)).to.equal(true); - }); - - it('should return true when given an ad unit without minimum duration parameter', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params.video.minDuration = undefined; - - expect(spec.isBidRequestValid(adUnit)).to.equal(true); - }); - - it('should return true when given an ad unit without maximum duration parameter', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params.video.maxDuration = undefined; - - expect(spec.isBidRequestValid(adUnit)).to.equal(true); - }); - - it('should return false when given an ad unit without bidder parameters', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params = undefined; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with invalid bidder parameters', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params = 'bad_bidder_parameters'; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit without video parameters', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params.video = undefined; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with invalid video parameters', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params.video = 'bad_bidder_parameters'; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit without mime types parameter', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params.video.mimes = undefined; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid mime types parameter', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params.video.mimes = 'bad_mime_types'; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an empty mime types parameter', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params.video.mimes = []; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid mime types parameter value', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params.video.mimes = [200]; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid minimum duration parameter', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params.video.minDuration = 'bad_min_duration'; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid maximum duration parameter', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params.video.maxDuration = 'bad_max_duration'; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit without protocols parameter', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params.video.protocols = undefined; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid protocols parameter', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params.video.protocols = 'bad_protocols'; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an empty protocols parameter', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params.video.protocols = []; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid protocols parameter value', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params.video.protocols = ['bad_protocols_value']; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an instream ad unit without instream context', function () { - const adUnit = utils.deepClone(examples.adUnit_video_instream); - adUnit.params.video.instreamContext = undefined; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an instream ad unit with an invalid instream context', function () { - const adUnit = utils.deepClone(examples.adUnit_video_instream); - adUnit.params.video.instreamContext = 'bad_instream_context'; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit without context', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.mediaTypes.video.context = undefined; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid context', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.mediaTypes.video.context = []; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an adpod ad unit', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.mediaTypes.video.context = 'adpod'; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an unknown context', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.mediaTypes.video.context = 'invalid_context'; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid size', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.mediaTypes.video.playerSize = 'bad_video_size'; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid size value', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.mediaTypes.video.playerSize = ['bad_video_size_value']; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with a size value with less than 2 dimensions', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.mediaTypes.video.playerSize = [[300]]; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with a size value with more than 2 dimensions', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.mediaTypes.video.playerSize = [[300, 250, 30]]; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with a negative width value', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.mediaTypes.video.playerSize = [[-300, 250]]; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with a negative height value', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.mediaTypes.video.playerSize = [[300, -250]]; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid width value', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.mediaTypes.video.playerSize = [[false, 250]]; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - - it('should return false when given an ad unit with an invalid height value', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.mediaTypes.video.playerSize = [[300, {}]]; - - expect(spec.isBidRequestValid(adUnit)).to.equal(false); - }); - }); - }); - - describe('buildRequests', function () { - describe('ServerRequest', function () { - it('should return a server request when given a valid ad unit and a valid ad unit context', function () { - const adUnits = [examples.adUnit_banner]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.length(1); - expect(serverRequests[0].method).to.exist.and.to.be.a('string').and.to.equal('POST'); - expect(serverRequests[0].url).to.exist.and.to.be.a('string').and.to.equal(BIDDER_URL); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0]._adot_internal).to.exist.and.to.be.an('object'); - expect(serverRequests[0]._adot_internal.impressions).to.exist.and.to.be.an('array').and.to.have.length(1); - expect(serverRequests[0]._adot_internal.impressions[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0]._adot_internal.impressions[0].impressionId).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0_0`); - expect(serverRequests[0]._adot_internal.impressions[0].adUnitCode).to.exist.and.to.be.a('string').and.to.equal(adUnits[0].adUnitCode); - }); - - it('should return a server request containing a position when given a valid ad unit and a valid ad unit context and a position in the bidder params', function () { - const adUnits = [examples.adUnit_position]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.length(1); - expect(serverRequests[0].method).to.exist.and.to.be.a('string').and.to.equal('POST'); - expect(serverRequests[0].url).to.exist.and.to.be.a('string').and.to.equal(BIDDER_URL); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0]._adot_internal).to.exist.and.to.be.an('object'); - expect(serverRequests[0]._adot_internal.impressions).to.exist.and.to.be.an('array').and.to.have.length(1); - expect(serverRequests[0]._adot_internal.impressions[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0]._adot_internal.impressions[0].impressionId).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0_0`); - expect(serverRequests[0]._adot_internal.impressions[0].adUnitCode).to.exist.and.to.be.a('string').and.to.equal(adUnits[0].adUnitCode); - expect(serverRequests[0].data.imp[0].banner.pos).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.position); - }); - - it('should return a server request when given two valid ad units and a valid ad unit context', function () { - const adUnits_1 = utils.deepClone(examples.adUnit_banner); - adUnits_1.bidId = 'bid_id_1'; - adUnits_1.adUnitCode = 'ad_unit_banner_1'; - - const adUnits_2 = utils.deepClone(examples.adUnit_banner); - adUnits_2.bidId = 'bid_id_2'; - adUnits_2.adUnitCode = 'ad_unit_banner_2'; - - const adUnits = [adUnits_1, adUnits_2]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.length(1); - expect(serverRequests[0].method).to.exist.and.to.be.a('string').and.to.equal('POST'); - expect(serverRequests[0].url).to.exist.and.to.be.a('string').and.to.equal(BIDDER_URL); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0]._adot_internal).to.exist.and.to.be.an('object'); - expect(serverRequests[0]._adot_internal.impressions).to.exist.and.to.be.an('array').and.to.have.length(2); - expect(serverRequests[0]._adot_internal.impressions[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0]._adot_internal.impressions[0].impressionId).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0_0`); - expect(serverRequests[0]._adot_internal.impressions[0].adUnitCode).to.exist.and.to.be.a('string').and.to.equal(adUnits[0].adUnitCode); - expect(serverRequests[0]._adot_internal.impressions[1]).to.exist.and.to.be.an('object'); - expect(serverRequests[0]._adot_internal.impressions[1].impressionId).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[1].bidId}_0_0`); - expect(serverRequests[0]._adot_internal.impressions[1].adUnitCode).to.exist.and.to.be.a('string').and.to.equal(adUnits[1].adUnitCode); - }); - - it('should return an empty server request list when given an empty ad unit list and a valid ad unit context', function () { - const adUnits = []; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.length(0); - }); - - it('should not return a server request when given no ad unit and a valid ad unit context', function () { - const serverRequests = spec.buildRequests(null, examples.adUnitContext); - - expect(serverRequests).to.equal(null); - }); - - it('should not return a server request when given a valid ad unit and no ad unit context', function () { - const adUnits = [examples.adUnit_banner]; - - const serverRequests = spec.buildRequests(adUnits, null); - - expect(serverRequests).to.be.an('array').and.to.have.length(1); - }); - - it('should not return a server request when given a valid ad unit and an invalid ad unit context', function () { - const adUnits = [examples.adUnit_banner]; - - const serverRequests = spec.buildRequests(adUnits, {}); - - expect(serverRequests).to.be.an('array').and.to.have.length(1); - }); - }); - - describe('BidRequest', function () { - it('should return a valid server request when given a valid ad unit', function () { - const adUnits = [examples.adUnit_banner]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.id).to.exist.and.to.be.a('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.at).to.exist.and.to.be.a('number').and.to.equal(1); - expect(serverRequests[0].data.ext).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.ext.adot).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.ext.adot.adapter_version).to.exist.and.to.be.a('string').and.to.equal('v1.0.0'); - }); - - it('should return one server request when given one valid ad unit', function () { - const adUnits = [examples.adUnit_banner]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.id).to.exist.and.to.be.a('string').and.to.equal(adUnits[0].bidderRequestId); - }); - - it('should return one server request when given two valid ad units with different impression identifiers', function () { - const adUnit_1 = utils.deepClone(examples.adUnit_banner); - adUnit_1.bidId = 'bid_id_1'; - - const adUnit_2 = utils.deepClone(examples.adUnit_banner); - adUnit_2.bidId = 'bid_id_2'; - - const adUnits = [adUnit_1, adUnit_2]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.id).to.exist.and.to.be.a('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.id).to.exist.and.to.be.a('string').and.to.equal(adUnits[1].bidderRequestId); - }); - - it('should return two server requests when given two valid ad units with different bid request identifiers', function () { - const adUnit_1 = utils.deepClone(examples.adUnit_banner); - adUnit_1.bidderRequestId = 'bidder_request_id_1'; - - const adUnit_2 = utils.deepClone(examples.adUnit_banner); - adUnit_2.bidderRequestId = 'bidder_request_id_2'; - - const adUnits = [adUnit_1, adUnit_2]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(2); - expect(serverRequests[0].data.id).to.exist.and.to.be.a('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[1].data.id).to.exist.and.to.be.a('string').and.to.equal(adUnits[1].bidderRequestId); - }); - }); - - describe('Impression', function () { - describe('Banner', function () { - it('should return a server request with one impression when given a valid ad unit', function () { - const adUnits = [examples.adUnit_banner]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0_0`); - expect(serverRequests[0].data.imp[0].banner).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].banner.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.banner.sizes[0][0]); - expect(serverRequests[0].data.imp[0].banner.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.banner.sizes[0][1]); - expect(serverRequests[0].data.imp[0].banner.format).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[0].banner.format[0]).to.exist.and.to.be.an('object').and.to.deep.equal({ - w: adUnits[0].mediaTypes.banner.sizes[0][0], - h: adUnits[0].mediaTypes.banner.sizes[0][1] - }); - }); - - it('should return a server request with two impressions containing one banner formats when given a valid ad unit with two banner sizes', function () { - const adUnit = utils.deepClone(examples.adUnit_banner); - adUnit.mediaTypes.banner.sizes = [ - [300, 250], - [350, 300] - ]; - - const adUnits = [adUnit]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(2); - - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0_0`); - expect(serverRequests[0].data.imp[0].banner).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].banner.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.banner.sizes[0][0]); - expect(serverRequests[0].data.imp[0].banner.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.banner.sizes[0][1]); - expect(serverRequests[0].data.imp[0].banner.format).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[0].banner.format[0]).to.exist.and.to.be.an('object').and.to.deep.equal({ - w: adUnits[0].mediaTypes.banner.sizes[0][0], - h: adUnits[0].mediaTypes.banner.sizes[0][1] - }); - - expect(serverRequests[0].data.imp[1]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[1].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0_1`); - expect(serverRequests[0].data.imp[1].banner).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[1].banner.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.banner.sizes[1][0]); - expect(serverRequests[0].data.imp[1].banner.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.banner.sizes[1][1]); - expect(serverRequests[0].data.imp[1].banner.format).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[1].banner.format[0]).to.exist.and.to.be.an('object').and.to.deep.equal({ - w: adUnits[0].mediaTypes.banner.sizes[1][0], - h: adUnits[0].mediaTypes.banner.sizes[1][1] - }); - }); - - it('should return a server request with two impressions when given two valid ad units with different impression identifiers', function () { - const adUnit_1 = utils.deepClone(examples.adUnit_banner); - adUnit_1.bidId = 'bid_id_1'; - - const adUnit_2 = utils.deepClone(examples.adUnit_banner); - adUnit_2.bidId = 'bid_id_2'; - - const adUnits = [adUnit_1, adUnit_2]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(2); - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0_0`); - expect(serverRequests[0].data.imp[0].banner).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].banner.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.banner.sizes[0][0]); - expect(serverRequests[0].data.imp[0].banner.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.banner.sizes[0][1]); - expect(serverRequests[0].data.imp[0].banner.format).to.exist.and.to.be.an('array'); - expect(serverRequests[0].data.imp[0].banner.format[0]).to.exist.and.to.be.an('object').and.to.deep.equal({ - w: adUnits[0].mediaTypes.banner.sizes[0][0], - h: adUnits[0].mediaTypes.banner.sizes[0][1] - }); - expect(serverRequests[0].data.imp[1]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[1].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[1].bidId}_0_0`); - expect(serverRequests[0].data.imp[1].banner).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[1].banner.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.banner.sizes[0][0]); - expect(serverRequests[0].data.imp[1].banner.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.banner.sizes[0][1]); - expect(serverRequests[0].data.imp[1].banner.format).to.exist.and.to.be.an('array'); - expect(serverRequests[0].data.imp[1].banner.format[0]).to.exist.and.to.be.an('object').and.to.deep.equal({ - w: adUnits[1].mediaTypes.banner.sizes[0][0], - h: adUnits[1].mediaTypes.banner.sizes[0][1] - }); - }); - - it('should return a server request with one overriden impression when given two valid ad units with identical identifiers', function () { - const adUnit_1 = utils.deepClone(examples.adUnit_banner); - adUnit_1.mediaTypes.banner.sizes = [[300, 250]]; - - const adUnit_2 = utils.deepClone(examples.adUnit_banner); - adUnit_2.mediaTypes.banner.sizes = [[350, 300]]; - - const adUnits = [adUnit_1, adUnit_2]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[1].bidId}_0_0`); - expect(serverRequests[0].data.imp[0].banner).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].banner.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.banner.sizes[0][0]); - expect(serverRequests[0].data.imp[0].banner.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.banner.sizes[0][1]); - expect(serverRequests[0].data.imp[0].banner.format).to.exist.and.to.be.an('array'); - expect(serverRequests[0].data.imp[0].banner.format[0]).to.exist.and.to.be.an('object').and.to.deep.equal({ - w: adUnits[1].mediaTypes.banner.sizes[0][0], - h: adUnits[1].mediaTypes.banner.sizes[0][1] - }); - }); - - it('should return two server requests with one impression when given two valid ad units with different bid request identifiers', function () { - const adUnit_1 = utils.deepClone(examples.adUnit_banner); - adUnit_1.bidderRequestId = 'bidder_request_id_1'; - - const adUnit_2 = utils.deepClone(examples.adUnit_banner); - adUnit_2.bidderRequestId = 'bidder_request_id_2'; - - const adUnits = [adUnit_1, adUnit_2]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(2); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0_0`); - expect(serverRequests[0].data.imp[0].banner).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].banner.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.banner.sizes[0][0]); - expect(serverRequests[0].data.imp[0].banner.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.banner.sizes[0][1]); - expect(serverRequests[0].data.imp[0].banner.format).to.exist.and.to.be.an('array'); - expect(serverRequests[0].data.imp[0].banner.format[0]).to.exist.and.to.be.an('object').and.to.deep.equal({ - w: adUnits[0].mediaTypes.banner.sizes[0][0], - h: adUnits[0].mediaTypes.banner.sizes[0][1] - }); - expect(serverRequests[1].data).to.exist.and.to.be.an('object'); - expect(serverRequests[1].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[1].bidderRequestId); - expect(serverRequests[1].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[1].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[1].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[1].bidId}_0_0`); - expect(serverRequests[1].data.imp[0].banner).to.exist.and.to.be.an('object'); - expect(serverRequests[1].data.imp[0].banner.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.banner.sizes[0][0]); - expect(serverRequests[1].data.imp[0].banner.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.banner.sizes[0][1]); - expect(serverRequests[1].data.imp[0].banner.format).to.exist.and.to.be.an('array'); - expect(serverRequests[1].data.imp[0].banner.format[0]).to.exist.and.to.be.an('object').and.to.deep.equal({ - w: adUnits[1].mediaTypes.banner.sizes[0][0], - h: adUnits[1].mediaTypes.banner.sizes[0][1] - }); - }); - }); - - describe('Video', function () { - it('should return a server request with one impression when given a valid outstream ad unit', function () { - const adUnit = examples.adUnit_video_outstream; - - const adUnits = [adUnit]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); - expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); - expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); - expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); - expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); - expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); - expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); - expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); - }); - - it('should return a server request with one impression when given a valid pre-roll instream ad unit', function () { - const adUnit = utils.deepClone(examples.adUnit_video_instream); - adUnit.params.video.instreamContext = 'pre-roll'; - - const adUnits = [adUnit]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); - expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); - expect(serverRequests[0].data.imp[0].video.startdelay).to.exist.and.to.be.a('number').and.to.equal(0); - expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); - expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); - expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); - expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); - expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); - }); - - it('should return a server request with one impression when given a valid mid-roll instream ad unit', function () { - const adUnit = utils.deepClone(examples.adUnit_video_instream); - adUnit.params.video.instreamContext = 'mid-roll'; - - const adUnits = [adUnit]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); - expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); - expect(serverRequests[0].data.imp[0].video.startdelay).to.exist.and.to.be.a('number').and.to.equal(-1); - expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); - expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); - expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); - expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); - expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); - }); - - it('should return a server request with one impression when given a valid post-roll instream ad unit', function () { - const adUnit = utils.deepClone(examples.adUnit_video_instream); - adUnit.params.video.instreamContext = 'post-roll'; - - const adUnits = [adUnit]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); - expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); - expect(serverRequests[0].data.imp[0].video.startdelay).to.exist.and.to.be.a('number').and.to.equal(-2); - expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); - expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); - expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); - expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); - expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); - }); - - it('should return a server request with one impression when given a valid ad unit without player size', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.mediaTypes.video.playerSize = undefined; - - const adUnits = [adUnit]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); - expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); - expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); - expect(serverRequests[0].data.imp[0].video.w).to.equal(null); - expect(serverRequests[0].data.imp[0].video.h).to.equal(null); - expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); - expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); - expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); - }); - - it('should return a server request with one impression when given a valid ad unit with an empty player size', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.mediaTypes.video.playerSize = []; - - const adUnits = [adUnit]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); - expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); - expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); - expect(serverRequests[0].data.imp[0].video.w).to.equal(null); - expect(serverRequests[0].data.imp[0].video.h).to.equal(null); - expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); - expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); - expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); - }); - - it('should return a server request with one impression when given a valid ad unit with multiple player sizes', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.mediaTypes.video.playerSize = [[350, 300], [400, 350]]; - - const adUnits = [adUnit]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); - expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); - expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); - expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); - expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); - expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); - expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); - expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); - }); - - it('should return a server request with one impression when given a valid ad unit without minimum duration', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params.video.minDuration = undefined; - - const adUnits = [adUnit]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); - expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); - expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); - expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); - expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); - expect(serverRequests[0].data.imp[0].video.minduration).to.equal(null); - expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); - expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); - }); - - it('should return a server request with one impression when given a valid ad unit without maximum duration', function () { - const adUnit = utils.deepClone(examples.adUnit_video_outstream); - adUnit.params.video.maxDuration = undefined; - - const adUnits = [adUnit]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); - expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); - expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); - expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); - expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); - expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); - expect(serverRequests[0].data.imp[0].video.maxduration).to.equal(null); - expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); - }); - - it('should return a server request with two impressions when given two valid ad units with different impression identifiers', function () { - const adUnit_1 = utils.deepClone(examples.adUnit_video_outstream); - adUnit_1.bidId = 'bid_id_1'; - - const adUnit_2 = utils.deepClone(examples.adUnit_video_outstream); - adUnit_2.bidId = 'bid_id_2'; - - const adUnits = [adUnit_1, adUnit_2]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(2); - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); - expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); - expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); - expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); - expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); - expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); - expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); - expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); - expect(serverRequests[0].data.imp[1]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[1].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[1].bidId}_0`); - expect(serverRequests[0].data.imp[1].video).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[1].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); - expect(serverRequests[0].data.imp[1].video.startdelay).to.equal(null); - expect(serverRequests[0].data.imp[1].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.video.playerSize[0][0]); - expect(serverRequests[0].data.imp[1].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.video.playerSize[0][1]); - expect(serverRequests[0].data.imp[1].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].params.video.minDuration); - expect(serverRequests[0].data.imp[1].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].params.video.maxDuration); - expect(serverRequests[0].data.imp[1].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[1].params.video.protocols); - }); - - it('should return a server request with one overridden impression when given two valid ad units with identical identifiers', function () { - const adUnit_1 = utils.deepClone(examples.adUnit_video_outstream); - adUnit_1.params.video.minDuration = 10; - - const adUnit_2 = utils.deepClone(examples.adUnit_video_outstream); - adUnit_2.params.video.minDuration = 15; - - const adUnits = [adUnit_1, adUnit_2]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[1].bidId}_0`); - expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); - expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); - expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.video.playerSize[0][0]); - expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.video.playerSize[0][1]); - expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].params.video.minDuration); - expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].params.video.maxDuration); - expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[1].params.video.protocols); - }); - - it('should return two server requests with one impression when given two valid ad units with different bid request identifiers', function () { - const adUnit_1 = utils.deepClone(examples.adUnit_video_outstream); - adUnit_1.bidderRequestId = 'bidder_request_id_1'; - - const adUnit_2 = utils.deepClone(examples.adUnit_video_outstream); - adUnit_2.bidderRequestId = 'bidder_request_id_2'; - - const adUnits = [adUnit_1, adUnit_2]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(2); - - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); - expect(serverRequests[0].data.imp[0].video).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); - expect(serverRequests[0].data.imp[0].video.startdelay).to.equal(null); - expect(serverRequests[0].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][0]); - expect(serverRequests[0].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].mediaTypes.video.playerSize[0][1]); - expect(serverRequests[0].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.minDuration); - expect(serverRequests[0].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[0].params.video.maxDuration); - expect(serverRequests[0].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.protocols); - expect(serverRequests[1].data).to.exist.and.to.be.an('object'); - expect(serverRequests[1].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[1].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[1].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[1].bidId}_0`); - expect(serverRequests[1].data.imp[0].video).to.exist.and.to.be.an('object'); - expect(serverRequests[1].data.imp[0].video.mimes).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[0].params.video.mimes); - expect(serverRequests[1].data.imp[0].video.startdelay).to.equal(null); - expect(serverRequests[1].data.imp[0].video.w).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.video.playerSize[0][0]); - expect(serverRequests[1].data.imp[0].video.h).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].mediaTypes.video.playerSize[0][1]); - expect(serverRequests[1].data.imp[0].video.minduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].params.video.minDuration); - expect(serverRequests[1].data.imp[0].video.maxduration).to.exist.and.to.be.a('number').and.to.equal(adUnits[1].params.video.maxDuration); - expect(serverRequests[1].data.imp[0].video.protocols).to.exist.and.to.be.an('array').and.to.deep.equal(adUnits[1].params.video.protocols); - }); - }); - - describe('Native', function () { - it('should return a server request with one impression when given a valid ad unit', function () { - const adUnits = [examples.adUnit_native]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnit_native); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data.imp[0]).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].id).to.exist.and.to.be.a('string').and.to.equal(`${adUnits[0].bidId}_0`); - expect(serverRequests[0].data.imp[0].native).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.imp[0].native.request).to.exist.and.to.be.a('string').and.to.equal(JSON.stringify(examples.serverRequest_native.data.imp[0].native.request)) - }); - }); - }); - - describe('Site', function () { - it('should return a server request with site information when given a valid ad unit and a valid ad unit context', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = examples.adUnitContext; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.site).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.site.page).to.exist.and.to.be.an('string').and.to.equal(adUnitContext.refererInfo.referer); - expect(serverRequests[0].data.site.id).to.equal(undefined); - expect(serverRequests[0].data.site.domain).to.exist.and.to.be.an('string').and.to.equal('we-are-adot.com'); - expect(serverRequests[0].data.site.name).to.exist.and.to.be.an('string').and.to.equal('we-are-adot.com'); - }); - - it('should return a server request without site information when not given an ad unit context', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = undefined; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.site).to.equal(null); - }); - - it('should return a server request without site information when given an ad unit context without referer information', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = utils.deepClone(examples.adUnitContext); - adUnitContext.refererInfo = undefined; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.site).to.equal(null); - }); - - it('should return a server request without site information when given an ad unit context with invalid referer information', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = utils.deepClone(examples.adUnitContext); - adUnitContext.refererInfo = 'bad_referer_information'; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.site).to.equal(null); - }); - - it('should return a server request without site information when given an ad unit context without referer', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = utils.deepClone(examples.adUnitContext); - adUnitContext.refererInfo.referer = undefined; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.site).to.equal(null); - }); - - it('should return a server request without site information when given an ad unit context with an invalid referer', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = utils.deepClone(examples.adUnitContext); - adUnitContext.refererInfo.referer = {}; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.site).to.equal(null); - }); - - it('should return a server request without site information when given an ad unit context with a misformatted referer', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = utils.deepClone(examples.adUnitContext); - adUnitContext.refererInfo.referer = 'we-are-adot'; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.site).to.equal(null); - }); - }); - - describe('Device', function () { - it('should return a server request with device information when given a valid ad unit and a valid ad unit context', function () { - const adUnits = [examples.adUnit_banner]; - - const serverRequests = spec.buildRequests(adUnits, examples.adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.device).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.device.ua).to.exist.and.to.be.a('string'); - expect(serverRequests[0].data.device.language).to.exist.and.to.be.a('string'); - }); - }); - - describe('Regs', function () { - it('should return a server request with regulations information when given a valid ad unit and a valid ad unit context with GDPR applying', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = examples.adUnitContext; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.regs).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.regs.ext).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.regs.ext.gdpr).to.exist.and.to.be.a('boolean').and.to.equal(adUnitContext.gdprConsent.gdprApplies); - }); - - it('should return a server request with regulations information when given a valid ad unit and a valid ad unit context with GDPR not applying', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = utils.deepClone(examples.adUnitContext); - adUnitContext.gdprConsent.gdprApplies = false; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.regs).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.regs.ext).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.regs.ext.gdpr).to.exist.and.to.be.a('boolean').and.to.equal(adUnitContext.gdprConsent.gdprApplies); - }); - - it('should return a server request without regulations information when not given an ad unit context', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = undefined; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.regs).to.equal(null); - }); - - it('should return a server request without regulations information when given an ad unit context without GDPR information', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = utils.deepClone(examples.adUnitContext); - adUnitContext.gdprConsent = undefined; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.regs).to.equal(null); - }); - - it('should return a server request without regulations information when given an ad unit context with invalid GDPR information', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = utils.deepClone(examples.adUnitContext); - adUnitContext.gdprConsent = 'bad_gdpr_consent'; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.regs).to.equal(null); - }); - - it('should return a server request without regulations information when given an ad unit context with invalid GDPR application information', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = utils.deepClone(examples.adUnitContext); - adUnitContext.gdprConsent.gdprApplies = 'bad_gdpr_applies'; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.regs).to.equal(null); - }); - }); - - describe('User', function () { - it('should return a server request with user information when given a valid ad unit and a valid ad unit context', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = examples.adUnitContext; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.user).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.user.ext).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.user.ext.consent).to.exist.and.to.be.a('string').and.to.equal(adUnitContext.gdprConsent.consentString); - }); - - it('should return a server request without user information when not given an ad unit context', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = undefined; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.user).to.equal(null); - }); - - it('should return a server request without user information when given an ad unit context without GDPR information', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = utils.deepClone(examples.adUnitContext); - adUnitContext.gdprConsent = undefined; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.user).to.equal(null); - }); - - it('should return a server request without user information when given an ad unit context with invalid GDPR information', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = utils.deepClone(examples.adUnitContext); - adUnitContext.gdprConsent = 'bad_gdpr_consent'; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.user).to.equal(null); - }); - - it('should return a server request without user information when given an ad unit context with an invalid consent string', function () { - const adUnits = [examples.adUnit_banner]; - - const adUnitContext = utils.deepClone(examples.adUnitContext); - adUnitContext.gdprConsent.consentString = true; - - const serverRequests = spec.buildRequests(adUnits, adUnitContext); - - expect(serverRequests).to.be.an('array').and.to.have.lengthOf(1); - expect(serverRequests[0].data).to.exist.and.to.be.an('object'); - expect(serverRequests[0].data.id).to.exist.and.to.be.an('string').and.to.equal(adUnits[0].bidderRequestId); - expect(serverRequests[0].data.user).to.equal(null); - }); - }); - }); - - describe('interpretResponse', function () { - describe('General', function () { - it('should return an ad when given a valid server response with one bid with USD currency', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.cur = 'USD'; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - const admWithAuctionPriceReplaced = utils.replaceAuctionPrice(serverResponse.body.seatbid[0].bid[0].adm, serverResponse.body.seatbid[0].bid[0].price); - - expect(ads).to.be.an('array').and.to.have.length(1); - expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); - expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(admWithAuctionPriceReplaced); - expect(ads[0].adUrl).to.equal(null); - expect(ads[0].vastXml).to.equal(null); - expect(ads[0].vastUrl).to.equal(null); - expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); - expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[0].height).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].h); - expect(ads[0].width).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].w); - expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('banner'); - expect(ads[0].renderer).to.equal(null); - }); - - it('should return two ads when given a valid server response with two bids', function () { - const serverRequest = examples.serverRequest_banner_twoImps; - - const serverResponse = examples.serverResponse_banner_twoBids; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - const admWithAuctionPriceReplaced = utils.replaceAuctionPrice(serverResponse.body.seatbid[0].bid[0].adm, serverResponse.body.seatbid[0].bid[0].price); - const adm2WithAuctionPriceReplaced = utils.replaceAuctionPrice(serverResponse.body.seatbid[0].bid[1].adm, serverResponse.body.seatbid[0].bid[1].price); - - expect(ads).to.be.an('array').and.to.have.length(2); - - expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); - expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(admWithAuctionPriceReplaced); - expect(ads[0].adUrl).to.equal(null); - expect(ads[0].vastXml).to.equal(null); - expect(ads[0].vastUrl).to.equal(null); - expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); - expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[0].height).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].h); - expect(ads[0].width).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].w); - expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('banner'); - expect(ads[0].renderer).to.equal(null); - expect(ads[1].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[1].bidId); - expect(ads[1].ad).to.exist.and.to.be.a('string').and.to.have.string(adm2WithAuctionPriceReplaced); - expect(ads[1].adUrl).to.equal(null); - expect(ads[1].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[1].crid); - expect(ads[1].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[1].price); - expect(ads[1].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[1].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[1].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[1].height).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[1].h); - expect(ads[1].width).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[1].w); - expect(ads[1].mediaType).to.exist.and.to.be.a('string').and.to.equal('banner'); - expect(ads[1].renderer).to.equal(null); - }); - - it('should return no ad when not given a server response', function () { - const ads = spec.interpretResponse(null); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when not given a server response body', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body = undefined; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given an invalid server response body', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body = 'invalid_body'; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response without seat bids', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid = undefined; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with invalid seat bids', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid = 'invalid_seat_bids'; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with an empty seat bids array', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid = []; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with an invalid seat bid', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid = 'invalid_bids'; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with an empty bids array', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid = []; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with an invalid bid', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid = ['invalid_bid']; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid without currency', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.cur = undefined; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid with an invalid currency', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.cur = {}; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid without impression identifier', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].impid = undefined; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid with an invalid impression identifier', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].impid = {}; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid without creative identifier', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].crid = undefined; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid with an invalid creative identifier', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].crid = {}; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid without ad markup and ad serving URL', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].adm = undefined; - serverResponse.body.seatbid[0].bid[0].nurl = undefined; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid with an invalid ad markup', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].adm = {}; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid with an ad markup without auction price macro', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].adm = 'creative_data'; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid with an invalid ad serving URL', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].nurl = {}; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid with an ad serving URL without auction price macro', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].nurl = 'win_notice_url'; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid without bid price', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].price = undefined; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid with an invalid bid price', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].price = {}; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid without extension', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].ext = undefined; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid with an invalid extension', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].ext = 'bad_ext'; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid without adot extension', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].ext.adot = undefined; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid with an invalid adot extension', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].ext.adot = 'bad_adot_ext'; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid without media type', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].ext.adot.media_type = undefined; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid with an invalid media type', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].ext.adot.media_type = {}; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid with an unknown media type', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].ext.adot.media_type = 'unknown_media_type'; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a valid server response and no server request', function () { - const serverRequest = undefined; - - const serverResponse = examples.serverResponse_banner; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a valid server response and an invalid server request', function () { - const serverRequest = 'bad_server_request'; - - const serverResponse = examples.serverResponse_banner; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a valid server response and a server request without bid request', function () { - const serverRequest = utils.deepClone(examples.serverRequest_banner); - serverRequest.data = undefined; - - const serverResponse = examples.serverResponse_banner; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a valid server response and a server request with an invalid bid request', function () { - const serverRequest = utils.deepClone(examples.serverRequest_banner); - serverRequest.data = 'bad_bid_request'; - - const serverResponse = examples.serverResponse_banner; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a valid server response and a server request without impression', function () { - const serverRequest = utils.deepClone(examples.serverRequest_banner); - serverRequest.data.imp = undefined; - - const serverResponse = examples.serverResponse_banner; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a valid server response and a server request with an invalid impression field', function () { - const serverRequest = utils.deepClone(examples.serverRequest_banner); - serverRequest.data.imp = 'invalid_impressions'; - - const serverResponse = examples.serverResponse_banner; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a valid server response and a server request without matching impression', function () { - const serverRequest = utils.deepClone(examples.serverRequest_banner); - serverRequest.data.imp[0].id = 'unknown_imp_id'; - - const serverResponse = examples.serverResponse_banner; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a valid server response and a server request without internal data', function () { - const serverRequest = utils.deepClone(examples.serverRequest_banner); - serverRequest._adot_internal = undefined; - - const serverResponse = examples.serverResponse_banner; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a valid server response and a server request with invalid internal data', function () { - const serverRequest = utils.deepClone(examples.serverRequest_banner); - serverRequest._adot_internal = 'bad_internal_data'; - - const serverResponse = examples.serverResponse_banner; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a valid server response and a server request without internal impression data', function () { - const serverRequest = utils.deepClone(examples.serverRequest_banner); - serverRequest._adot_internal.impressions = undefined; - - const serverResponse = examples.serverResponse_banner; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a valid server response and a server request with invalid internal impression data', function () { - const serverRequest = utils.deepClone(examples.serverRequest_banner); - serverRequest._adot_internal.impressions = 'bad_internal_impression_data'; - - const serverResponse = examples.serverResponse_banner; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a valid server response and a server request without matching internal impression', function () { - const serverRequest = utils.deepClone(examples.serverRequest_banner); - serverRequest._adot_internal.impressions[0].impressionId = 'unknown_imp_id'; - - const serverResponse = examples.serverResponse_banner; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a valid server response and a server request without internal impression ad unit code', function () { - const serverRequest = utils.deepClone(examples.serverRequest_banner); - serverRequest._adot_internal.impressions[0].adUnitCode = undefined; - - const serverResponse = examples.serverResponse_banner; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a valid server response and a server request with an invalid internal impression ad unit code', function () { - const serverRequest = utils.deepClone(examples.serverRequest_banner); - serverRequest._adot_internal.impressions[0].adUnitCode = {}; - - const serverResponse = examples.serverResponse_banner; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - }); - - describe('Banner', function () { - it('should return an ad when given a valid server response with one bid', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = examples.serverResponse_banner; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - const admWithAuctionPriceReplaced = utils.replaceAuctionPrice(serverResponse.body.seatbid[0].bid[0].adm, serverResponse.body.seatbid[0].bid[0].price); - - expect(ads).to.be.an('array').and.to.have.length(1); - expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); - expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(admWithAuctionPriceReplaced); - expect(ads[0].adUrl).to.equal(null); - expect(ads[0].vastXml).to.equal(null); - expect(ads[0].vastUrl).to.equal(null); - expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); - expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[0].height).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].h); - expect(ads[0].width).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].w); - expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('banner'); - expect(ads[0].renderer).to.equal(null); - }); - - it('should return an ad when given a valid server response with one bid without a win notice URL', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].nurl = undefined; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - const admWithAuctionPriceReplaced = utils.replaceAuctionPrice(serverResponse.body.seatbid[0].bid[0].adm, serverResponse.body.seatbid[0].bid[0].price); - - expect(ads).to.be.an('array').and.to.have.length(1); - expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); - expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.equal(admWithAuctionPriceReplaced); - expect(ads[0].adUrl).to.equal(null); - expect(ads[0].vastXml).to.equal(null); - expect(ads[0].vastUrl).to.equal(null); - expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); - expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[0].height).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].h); - expect(ads[0].width).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].w); - expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('banner'); - expect(ads[0].renderer).to.equal(null); - }); - - it('should return an ad when given a valid server response with one bid using an ad serving URL', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].adm = undefined; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - const nurlWithAuctionPriceReplaced = utils.replaceAuctionPrice(serverResponse.body.seatbid[0].bid[0].nurl, serverResponse.body.seatbid[0].bid[0].price); - - expect(ads).to.be.an('array').and.to.have.length(1); - expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); - expect(ads[0].ad).to.equal(null); - expect(ads[0].adUrl).to.exist.and.to.be.a('string').and.to.equal(nurlWithAuctionPriceReplaced); - expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); - expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[0].height).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].h); - expect(ads[0].width).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].w); - expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('banner'); - expect(ads[0].renderer).to.equal(null); - }); - - it('should return no ad when given a server response with a bid without height', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].h = undefined; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid with an invalid height', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].h = {}; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid without width', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].w = undefined; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid with an invalid width', function () { - const serverRequest = examples.serverRequest_banner; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - serverResponse.body.seatbid[0].bid[0].w = {}; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a valid server response and a server request without banner impression', function () { - const serverRequest = utils.deepClone(examples.serverRequest_banner); - serverRequest.data.imp[0].banner = undefined; - - const serverResponse = utils.deepClone(examples.serverResponse_banner); - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - }); - - describe('Video', function () { - it('should return an ad when given a valid server response with one bid on an instream impression', function () { - const serverRequest = examples.serverRequest_video_instream; - - const serverResponse = examples.serverResponse_video_instream; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - const admWithAuctionPriceReplaced = utils.replaceAuctionPrice(serverResponse.body.seatbid[0].bid[0].adm, serverResponse.body.seatbid[0].bid[0].price); - - expect(ads).to.be.an('array').and.to.have.length(1); - expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); - expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(admWithAuctionPriceReplaced); - expect(ads[0].adUrl).to.equal(null); - expect(ads[0].vastXml).to.equal(admWithAuctionPriceReplaced); - expect(ads[0].vastUrl).to.equal(null); - expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); - expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[0].height).to.equal(serverRequest.data.imp[0].video.h); - expect(ads[0].width).to.equal(serverRequest.data.imp[0].video.w); - expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); - expect(ads[0].renderer).to.equal(null); - }); - - it('should return an ad when given a valid server response with one bid on an outstream impression', function () { - const serverRequest = examples.serverRequest_video_outstream; - - const serverResponse = examples.serverResponse_video_outstream; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - const admWithAuctionPriceReplaced = utils.replaceAuctionPrice(serverResponse.body.seatbid[0].bid[0].adm, serverResponse.body.seatbid[0].bid[0].price); - - expect(ads).to.be.an('array').and.to.have.length(1); - expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); - expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(admWithAuctionPriceReplaced); - expect(ads[0].adUrl).to.equal(null); - expect(ads[0].vastXml).to.equal(admWithAuctionPriceReplaced); - expect(ads[0].vastUrl).to.equal(null); - expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); - expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[0].height).to.equal(serverRequest.data.imp[0].video.h); - expect(ads[0].width).to.equal(serverRequest.data.imp[0].video.w); - expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); - expect(ads[0].renderer).to.be.an('object'); - }); - - it('should return two ads when given a valid server response with two bids on both instream and outstream impressions', function () { - const serverRequest = examples.serverRequest_video_instream_outstream; - - const serverResponse = examples.serverResponse_video_instream_outstream; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - const admWithAuctionPriceReplaced = utils.replaceAuctionPrice(serverResponse.body.seatbid[0].bid[0].adm, serverResponse.body.seatbid[0].bid[0].price); - const adm2WithAuctionPriceReplaced = utils.replaceAuctionPrice(serverResponse.body.seatbid[0].bid[1].adm, serverResponse.body.seatbid[0].bid[1].price); - - expect(ads).to.be.an('array').and.to.have.length(2); - expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); - expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(admWithAuctionPriceReplaced); - expect(ads[0].adUrl).to.equal(null); - expect(ads[0].vastXml).to.equal(admWithAuctionPriceReplaced); - expect(ads[0].vastUrl).to.equal(null); - expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); - expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[0].height).to.equal(serverRequest.data.imp[0].video.h); - expect(ads[0].width).to.equal(serverRequest.data.imp[0].video.w); - expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); - expect(ads[0].renderer).to.equal(null); - expect(ads[1].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[1].bidId); - expect(ads[1].ad).to.exist.and.to.be.a('string').and.to.have.string(adm2WithAuctionPriceReplaced); - expect(ads[1].adUrl).to.equal(null); - expect(ads[1].vastXml).to.equal(adm2WithAuctionPriceReplaced); - expect(ads[1].vastUrl).to.equal(null); - expect(ads[1].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[1].crid); - expect(ads[1].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[1].price); - expect(ads[1].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[1].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[1].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[0].height).to.equal(serverRequest.data.imp[1].video.h); - expect(ads[0].width).to.equal(serverRequest.data.imp[1].video.w); - expect(ads[1].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); - expect(ads[1].renderer).to.be.an('object'); - }); - - it('should return an ad when given a valid server response with one bid without a win notice URL', function () { - const serverRequest = examples.serverRequest_video_instream; - - const serverResponse = utils.deepClone(examples.serverResponse_video_instream); - serverResponse.body.seatbid[0].bid[0].nurl = undefined; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - const admWithAuctionPriceReplaced = utils.replaceAuctionPrice(serverResponse.body.seatbid[0].bid[0].adm, serverResponse.body.seatbid[0].bid[0].price); - - expect(ads).to.be.an('array').and.to.have.length(1); - expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); - expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(admWithAuctionPriceReplaced); - expect(ads[0].adUrl).to.equal(null); - expect(ads[0].vastXml).to.equal(admWithAuctionPriceReplaced); - expect(ads[0].vastUrl).to.equal(null); - expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); - expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[0].height).to.equal(serverRequest.data.imp[0].video.h); - expect(ads[0].width).to.equal(serverRequest.data.imp[0].video.w); - expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); - expect(ads[0].renderer).to.equal(null); - }); - - it('should return an ad when given a valid server response with one bid using an ad serving URL', function () { - const serverRequest = examples.serverRequest_video_instream; - - const serverResponse = utils.deepClone(examples.serverResponse_video_instream); - serverResponse.body.seatbid[0].bid[0].adm = undefined; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - const nurlWithAuctionPriceReplaced = utils.replaceAuctionPrice(serverResponse.body.seatbid[0].bid[0].nurl, serverResponse.body.seatbid[0].bid[0].price); - - expect(ads).to.be.an('array').and.to.have.length(1); - expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); - expect(ads[0].ad).to.equal(null); - expect(ads[0].adUrl).to.exist.and.to.be.a('string').and.to.have.string(nurlWithAuctionPriceReplaced); - expect(ads[0].vastXml).to.equal(null); - expect(ads[0].vastUrl).to.equal(nurlWithAuctionPriceReplaced); - expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); - expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[0].height).to.equal(serverRequest.data.imp[0].video.h); - expect(ads[0].width).to.equal(serverRequest.data.imp[0].video.w); - expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); - expect(ads[0].renderer).to.equal(null); - }); - - it('should return an ad when given a valid server response with a bid with a video height', function () { - const serverRequest = examples.serverRequest_video_instream; - - const serverResponse = utils.deepClone(examples.serverResponse_video_instream); - serverResponse.body.seatbid[0].bid[0].h = 500; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - const admWithAuctionPriceReplaced = utils.replaceAuctionPrice(serverResponse.body.seatbid[0].bid[0].adm, serverResponse.body.seatbid[0].bid[0].price); - - expect(ads).to.be.an('array').and.to.have.length(1); - expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); - expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(admWithAuctionPriceReplaced); - expect(ads[0].adUrl).to.equal(null); - expect(ads[0].vastXml).to.equal(admWithAuctionPriceReplaced); - expect(ads[0].vastUrl).to.equal(null); - expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); - expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[0].height).to.equal(serverRequest.data.imp[0].video.h); - expect(ads[0].width).to.equal(serverRequest.data.imp[0].video.w); - expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); - expect(ads[0].renderer).to.equal(null); - }); - - it('should return an ad when given a valid server response with a bid with a video width', function () { - const serverRequest = examples.serverRequest_video_instream; - - const serverResponse = utils.deepClone(examples.serverResponse_video_instream); - serverResponse.body.seatbid[0].bid[0].w = 500; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - const admWithAuctionPriceReplaced = utils.replaceAuctionPrice(serverResponse.body.seatbid[0].bid[0].adm, serverResponse.body.seatbid[0].bid[0].price); - - expect(ads).to.be.an('array').and.to.have.length(1); - expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); - expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(admWithAuctionPriceReplaced); - expect(ads[0].adUrl).to.equal(null); - expect(ads[0].vastXml).to.equal(admWithAuctionPriceReplaced); - expect(ads[0].vastUrl).to.equal(null); - expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); - expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[0].height).to.equal(serverRequest.data.imp[0].video.h); - expect(ads[0].width).to.equal(serverRequest.data.imp[0].video.w); - expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); - expect(ads[0].renderer).to.equal(null); - }); - - it('should return an ad when given a valid server response with a bid with a video width and height', function () { - const serverRequest = examples.serverRequest_video_instream; - - const serverResponse = utils.deepClone(examples.serverResponse_video_instream); - serverResponse.body.seatbid[0].bid[0].w = 500; - serverResponse.body.seatbid[0].bid[0].h = 400; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - const admWithAuctionPriceReplaced = utils.replaceAuctionPrice(serverResponse.body.seatbid[0].bid[0].adm, serverResponse.body.seatbid[0].bid[0].price); - - expect(ads).to.be.an('array').and.to.have.length(1); - expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); - expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(admWithAuctionPriceReplaced); - expect(ads[0].adUrl).to.equal(null); - expect(ads[0].vastXml).to.equal(admWithAuctionPriceReplaced); - expect(ads[0].vastUrl).to.equal(null); - expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); - expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[0].height).to.equal(serverResponse.body.seatbid[0].bid[0].h); - expect(ads[0].width).to.equal(serverResponse.body.seatbid[0].bid[0].w); - expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); - expect(ads[0].renderer).to.equal(null); - }); - - it('should return an ad when given a valid server response and server request with a video impression without width', function () { - const serverRequest = utils.deepClone(examples.serverRequest_video_instream); - serverRequest.data.imp[0].video.w = null; - - const serverResponse = utils.deepClone(examples.serverResponse_video_instream); - - const ads = spec.interpretResponse(serverResponse, serverRequest); - const admWithAuctionPriceReplaced = utils.replaceAuctionPrice(serverResponse.body.seatbid[0].bid[0].adm, serverResponse.body.seatbid[0].bid[0].price); - - expect(ads).to.be.an('array').and.to.have.length(1); - expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); - expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(admWithAuctionPriceReplaced); - expect(ads[0].adUrl).to.equal(null); - expect(ads[0].vastXml).to.equal(admWithAuctionPriceReplaced); - expect(ads[0].vastUrl).to.equal(null); - expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); - expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[0].height).to.equal(null); - expect(ads[0].width).to.equal(null); - expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); - expect(ads[0].renderer).to.equal(null); - }); - - it('should return an ad when given a valid server response and server request with a video impression without height', function () { - const serverRequest = utils.deepClone(examples.serverRequest_video_instream); - serverRequest.data.imp[0].video.h = null; - - const serverResponse = utils.deepClone(examples.serverResponse_video_instream); - - const ads = spec.interpretResponse(serverResponse, serverRequest); - const admWithAuctionPriceReplaced = utils.replaceAuctionPrice(serverResponse.body.seatbid[0].bid[0].adm, serverResponse.body.seatbid[0].bid[0].price); - - expect(ads).to.be.an('array').and.to.have.length(1); - expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); - expect(ads[0].ad).to.exist.and.to.be.a('string').and.to.have.string(admWithAuctionPriceReplaced); - expect(ads[0].adUrl).to.equal(null); - expect(ads[0].vastXml).to.equal(admWithAuctionPriceReplaced); - expect(ads[0].vastUrl).to.equal(null); - expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); - expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[0].height).to.equal(null); - expect(ads[0].width).to.equal(null); - expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('video'); - expect(ads[0].renderer).to.equal(null); - }); - - it('should return no ad when given a server response with a bid with an invalid height', function () { - const serverRequest = examples.serverRequest_video_instream; - - const serverResponse = utils.deepClone(examples.serverResponse_video_instream); - serverResponse.body.seatbid[0].bid[0].h = {}; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a server response with a bid with an invalid width', function () { - const serverRequest = examples.serverRequest_video_instream; - - const serverResponse = utils.deepClone(examples.serverResponse_video_instream); - serverResponse.body.seatbid[0].bid[0].w = {}; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - it('should return no ad when given a valid server response and a server request without video impression', function () { - const serverRequest = utils.deepClone(examples.serverRequest_video_instream); - serverRequest.data.imp[0].video = undefined; - - const serverResponse = utils.deepClone(examples.serverResponse_video_instream); - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(0); - }); - - describe('Outstream renderer', function () { - function spyAdRenderingQueue(ad) { - const spy = sinon.spy(ad.renderer, 'push'); - - this.sinonSpies.push(spy); - } - - function executeAdRenderer(ad, onRendererExecution, done) { - executeRenderer(ad.renderer, ad); - - setTimeout(() => { - try { - onRendererExecution(); - } catch (err) { - done(err); - } - - done() - }, 100); - } - - before('Bind helper functions to the Mocha context', function () { - this.spyAdRenderingQueue = spyAdRenderingQueue.bind(this); - - window.VASTPlayer = function VASTPlayer() {}; - window.VASTPlayer.prototype.loadXml = function loadXml() { - return new Promise((resolve, reject) => resolve()) - }; - window.VASTPlayer.prototype.load = function load() { - return new Promise((resolve, reject) => resolve()) - }; - window.VASTPlayer.prototype.on = function on(event, callback) {}; - window.VASTPlayer.prototype.startAd = function startAd() {}; - }); - - beforeEach('Initialize the Sinon spies list', function () { - this.sinonSpies = []; - }); - - afterEach('Clear the registered Sinon spies', function () { - this.sinonSpies.forEach(spy => spy.restore()); - }); - - after('clear data', () => { - window.VASTPlayer = null; - }); - - it('should return an ad with valid renderer', function () { - const serverRequest = examples.serverRequest_video_outstream; - const serverResponse = examples.serverResponse_video_outstream; - - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(1); - expect(ads[0].renderer).to.be.an('object'); - }); - - it('should append a command to the ad rendering queue when executing the renderer', function (done) { - const serverRequest = examples.serverRequest_video_outstream; - const serverResponse = examples.serverResponse_video_outstream; - - const [ad] = spec.interpretResponse(serverResponse, serverRequest); - - this.spyAdRenderingQueue(ad); - - executeAdRenderer(ad, () => { - expect(ad.renderer.push.calledOnce).to.equal(true); - expect(ad.renderer.push.firstCall.args[0]).to.exist.and.to.be.a('function'); - }, done); - }); - }); - }); - - describe('Native', function () { - it('should return an ad when given a valid server response with one bid', function () { - const serverRequest = examples.serverRequest_native; - const serverResponse = examples.serverResponse_native; - const native = JSON.parse(serverResponse.body.seatbid[0].bid[0].adm).native; - const {link, assets} = native; - const ads = spec.interpretResponse(serverResponse, serverRequest); - - expect(ads).to.be.an('array').and.to.have.length(1); - expect(ads[0].requestId).to.exist.and.to.be.a('string').and.to.equal(serverRequest._adot_internal.impressions[0].bidId); - expect(ads[0].creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].crid); - expect(ads[0].cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(ads[0].currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.cur); - expect(ads[0].netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(true); - expect(ads[0].ttl).to.exist.and.to.be.a('number').and.to.equal(10); - expect(ads[0].mediaType).to.exist.and.to.be.a('string').and.to.equal('native'); - expect(ads[0].native).to.exist.and.to.be.an('object'); - expect(Object.keys(ads[0].native)).to.have.length(10); - expect(ads[0].native.title).to.equal(assets[0].title.text); - expect(ads[0].native.icon.url).to.equal(assets[1].img.url); - expect(ads[0].native.icon.width).to.equal(assets[1].img.w); - expect(ads[0].native.icon.height).to.equal(assets[1].img.h); - expect(ads[0].native.image.url).to.equal(assets[2].img.url); - expect(ads[0].native.image.width).to.equal(assets[2].img.w); - expect(ads[0].native.image.height).to.equal(assets[2].img.h); - expect(ads[0].native.sponsoredBy).to.equal(assets[3].data.value); - expect(ads[0].native.body).to.equal(assets[4].data.value); - expect(ads[0].native.cta).to.equal(assets[5].data.value); - expect(ads[0].native.clickUrl).to.equal(link.url); - }); - }); - }); -}); diff --git a/test/spec/modules/adpartnerBidAdapter_spec.js b/test/spec/modules/adpartnerBidAdapter_spec.js deleted file mode 100644 index d30ef7ebf71..00000000000 --- a/test/spec/modules/adpartnerBidAdapter_spec.js +++ /dev/null @@ -1,234 +0,0 @@ -import {expect} from 'chai'; -import {spec, ENDPOINT_PROTOCOL, ENDPOINT_DOMAIN, ENDPOINT_PATH} from 'modules/adpartnerBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; - -const BIDDER_CODE = 'adpartner'; - -describe('AdpartnerAdapter', function () { - const adapter = newBidder(spec); - - describe('inherited functions', function () { - it('exists and is a function', function () { - expect(adapter.callBids).to.be.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - it('should return true when required params found', function () { - let validRequest = { - 'params': { - 'unitId': 123 - } - }; - expect(spec.isBidRequestValid(validRequest)).to.equal(true); - }); - - it('should return true when required params is srting', function () { - let validRequest = { - 'params': { - 'unitId': '456' - } - }; - expect(spec.isBidRequestValid(validRequest)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let validRequest = { - 'params': { - 'unknownId': 123 - } - }; - expect(spec.isBidRequestValid(validRequest)).to.equal(false); - }); - - it('should return false when required params is 0', function () { - let validRequest = { - 'params': { - 'unitId': 0 - } - }; - expect(spec.isBidRequestValid(validRequest)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let validEndpoint = ENDPOINT_PROTOCOL + '://' + ENDPOINT_DOMAIN + ENDPOINT_PATH + '?tag=123,456&sizes=300x250|300x600,728x90&referer=https%3A%2F%2Ftest.domain'; - - let validRequest = [ - { - 'bidder': BIDDER_CODE, - 'params': { - 'unitId': 123 - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e' - }, - { - 'bidder': BIDDER_CODE, - 'params': { - 'unitId': '456' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '22aidtbx5eabd9' - } - ]; - - let bidderRequest = { - refererInfo: { - referer: 'https://test.domain' - } - }; - - it('bidRequest HTTP method', function () { - const request = spec.buildRequests(validRequest, bidderRequest); - expect(request.method).to.equal('POST'); - }); - - it('bidRequest url', function () { - const request = spec.buildRequests(validRequest, bidderRequest); - expect(request.url).to.equal(validEndpoint); - }); - - it('bidRequest data', function () { - const request = spec.buildRequests(validRequest, bidderRequest); - const payload = JSON.parse(request.data); - expect(payload[0].unitId).to.equal(123); - expect(payload[0].sizes).to.deep.equal([[300, 250], [300, 600]]); - expect(payload[0].bidId).to.equal('30b31c1838de1e'); - expect(payload[1].unitId).to.equal(456); - expect(payload[1].sizes).to.deep.equal([[728, 90]]); - expect(payload[1].bidId).to.equal('22aidtbx5eabd9'); - }); - }); - - describe('joinSizesToString', function () { - it('success convert sizes list to string', function () { - const sizesStr = spec.joinSizesToString([[300, 250], [300, 600]]); - expect(sizesStr).to.equal('300x250|300x600'); - }); - }); - - describe('interpretResponse', function () { - const bidRequest = { - 'method': 'POST', - 'url': ENDPOINT_PROTOCOL + '://' + ENDPOINT_DOMAIN + ENDPOINT_PATH + '?tag=123,456&code=adunit-code-1,adunit-code-2&bid=30b31c1838de1e,22aidtbx5eabd9&sizes=300x250|300x600,728x90&referer=https%3A%2F%2Ftest.domain', - 'data': '[{"unitId": 13144370,"adUnitCode": "div-gpt-ad-1460505748561-0","sizes": [[300, 250], [300, 600]],"bidId": "2bdcb0b203c17d","referer": "https://test.domain/index.html"},{"unitId": 13144370,"adUnitCode":"div-gpt-ad-1460505748561-1","sizes": [[768, 90]],"bidId": "3dc6b8084f91a8","referer": "https://test.domain/index.html"}]' - }; - - const bidResponse = { - body: { - 'div-gpt-ad-1460505748561-0': - { - 'ad': '
ad
', - 'width': 300, - 'height': 250, - 'creativeId': '8:123456', - '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'} - ], - 'winNotification': [ - { - '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 - } - } - ], - 'cpm': 0.01, - 'currency': 'USD', - 'netRevenue': true - } - }, - headers: {} - }; - - it('result is correct', function () { - const result = spec.interpretResponse(bidResponse, bidRequest); - expect(result[0].requestId).to.equal('2bdcb0b203c17d'); - expect(result[0].cpm).to.equal(0.01); - expect(result[0].width).to.equal(300); - expect(result[0].height).to.equal(250); - expect(result[0].creativeId).to.equal('8:123456'); - expect(result[0].currency).to.equal('USD'); - expect(result[0].ttl).to.equal(60); - 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}}); - }); - }); - - describe('adResponse', function () { - const bid = { - 'unitId': 13144370, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '2bdcb0b203c17d', - 'referer': 'https://test.domain/index.html' - }; - const ad = { - 'ad': '
ad
', - 'width': 300, - 'height': 250, - 'creativeId': '8:123456', - 'syncs': [], - 'winNotification': [], - 'cpm': 0.01, - 'currency': 'USD', - 'netRevenue': true - }; - - it('fill ad for response', function () { - const result = spec.adResponse(bid, ad); - expect(result.requestId).to.equal('2bdcb0b203c17d'); - expect(result.cpm).to.equal(0.01); - expect(result.width).to.equal(300); - expect(result.height).to.equal(250); - expect(result.creativeId).to.equal('8:123456'); - expect(result.currency).to.equal('USD'); - expect(result.ttl).to.equal(60); - }); - }); - - describe('onBidWon', function () { - const bid = { - winNotification: [ - { - 'method': 'POST', - 'path': '/hb/bid_won?test=1', - 'data': { - 'ad': [ - {'dsp': 8, 'id': 800008, 'cost': 0.01, 'nurl': 'http://test.domain/'} - ], - 'unit_id': 1234, - 'site_id': 123 - } - } - ] - }; - - let ajaxStub; - - beforeEach(() => { - ajaxStub = sinon.stub(spec, 'postRequest') - }) - - afterEach(() => { - ajaxStub.restore() - }) - - it('calls adpartner\'s callback endpoint', () => { - const result = spec.onBidWon(bid); - expect(result).to.equal(true); - expect(ajaxStub.calledOnce).to.equal(true); - expect(ajaxStub.firstCall.args[0]).to.equal(ENDPOINT_PROTOCOL + '://' + ENDPOINT_DOMAIN + '/hb/bid_won?test=1'); - expect(ajaxStub.firstCall.args[1]).to.deep.equal(JSON.stringify(bid.winNotification[0].data)); - }); - }); -}); diff --git a/test/spec/modules/adpod_spec.js b/test/spec/modules/adpod_spec.js deleted file mode 100644 index 5e4bcce1fe6..00000000000 --- a/test/spec/modules/adpod_spec.js +++ /dev/null @@ -1,1306 +0,0 @@ -import * as utils from 'src/utils.js'; -import { config } from 'src/config.js'; -import * as videoCache from 'src/videoCache.js'; -import * as auction from 'src/auction.js'; -import { ADPOD } from 'src/mediaTypes.js'; - -import { callPrebidCacheHook, checkAdUnitSetupHook, checkVideoBidSetupHook, adpodSetConfig, sortByPricePerSecond } from 'modules/adpod.js'; - -let expect = require('chai').expect; - -describe('adpod.js', function () { - let logErrorStub; - let logWarnStub; - let logInfoStub; - - describe('callPrebidCacheHook', function () { - let callbackResult; - let clock; - let addBidToAuctionStub; - let doCallbacksIfTimedoutStub; - let storeStub; - let afterBidAddedSpy; - let auctionBids = []; - - let callbackFn = function() { - callbackResult = true; - }; - - let auctionInstance = { - getAuctionStatus: function() { - return auction.AUCTION_IN_PROGRESS; - } - } - - const fakeStoreFn = function(bids, callback) { - let payload = []; - bids.forEach(bid => payload.push({uuid: bid.customCacheKey})); - callback(null, payload); - }; - - beforeEach(function() { - callbackResult = null; - afterBidAddedSpy = sinon.spy(); - storeStub = sinon.stub(videoCache, 'store'); - logWarnStub = sinon.stub(utils, 'logWarn'); - logInfoStub = sinon.stub(utils, 'logInfo'); - addBidToAuctionStub = sinon.stub(auction, 'addBidToAuction').callsFake(function (auctionInstance, bid) { - auctionBids.push(bid); - }); - doCallbacksIfTimedoutStub = sinon.stub(auction, 'doCallbacksIfTimedout'); - clock = sinon.useFakeTimers(); - config.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }); - }); - - afterEach(function() { - storeStub.restore(); - logWarnStub.restore(); - logInfoStub.restore(); - addBidToAuctionStub.restore(); - doCallbacksIfTimedoutStub.restore(); - clock.restore(); - config.resetConfig(); - auctionBids = []; - }) - - it('should redirect back to the original function if bid is not an adpod video', function () { - let bid = { - adId: 'testAdId_123', - mediaType: 'video' - }; - - let bidderRequest = { - adUnitCode: 'adUnit_123', - mediaTypes: { - video: { - context: 'outstream' - } - } - } - - callPrebidCacheHook(callbackFn, auctionInstance, bid, function () {}, bidderRequest); - expect(callbackResult).to.equal(true); - }); - - it('should immediately add the adpod bid to auction if adpod.deferCaching in config is true', function() { - config.setConfig({ - adpod: { - deferCaching: true, - brandCategoryExclusion: true - } - }); - - let bidResponse1 = { - adId: 'adId01277', - auctionId: 'no_defer_123', - mediaType: 'video', - cpm: 5, - pbMg: '5.00', - adserverTargeting: { - hb_pb: '5.00' - }, - meta: { - adServerCatId: 'test' - }, - video: { - context: ADPOD, - durationSeconds: 15, - durationBucket: 15 - } - }; - - let bidResponse2 = { - adId: 'adId46547', - auctionId: 'no_defer_123', - mediaType: 'video', - cpm: 12, - pbMg: '12.00', - adserverTargeting: { - hb_pb: '12.00' - }, - meta: { - adServerCatId: 'value' - }, - video: { - context: ADPOD, - durationSeconds: 15, - durationBucket: 15 - } - }; - - let bidderRequest = { - adUnitCode: 'adpod_1', - auctionId: 'no_defer_123', - mediaTypes: { - video: { - context: ADPOD, - playerSize: [[300, 300]], - adPodDurationSec: 300, - durationRangeSec: [15, 30, 45], - requireExactDuration: false - } - }, - }; - - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse1, afterBidAddedSpy, bidderRequest); - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse2, afterBidAddedSpy, bidderRequest); - - // check if bid adsereverTargeting is setup - expect(callbackResult).to.be.null; - expect(storeStub.called).to.equal(false); - expect(afterBidAddedSpy.calledTwice).to.equal(true); - expect(auctionBids.length).to.equal(2); - expect(auctionBids[0].adId).to.equal(bidResponse1.adId); - expect(auctionBids[0].customCacheKey).to.exist.and.to.match(/^5\.00_test_15s_.*/); - expect(auctionBids[0].adserverTargeting.hb_pb_cat_dur).to.equal('5.00_test_15s'); - expect(auctionBids[0].adserverTargeting.hb_cache_id).to.exist; - expect(auctionBids[0].videoCacheKey).to.exist.and.to.equal(auctionBids[0].adserverTargeting.hb_cache_id) - expect(auctionBids[1].adId).to.equal(bidResponse2.adId); - expect(auctionBids[1].customCacheKey).to.exist.and.to.match(/^12\.00_value_15s_.*/); - expect(auctionBids[1].adserverTargeting.hb_pb_cat_dur).to.equal('12.00_value_15s'); - expect(auctionBids[1].adserverTargeting.hb_cache_id).to.exist; - expect(auctionBids[1].adserverTargeting.hb_cache_id).to.equal(auctionBids[0].adserverTargeting.hb_cache_id); - expect(auctionBids[1].videoCacheKey).to.exist.and.to.equal(auctionBids[0].adserverTargeting.hb_cache_id); - }); - - it('should send prebid cache call once bid queue is full', function () { - storeStub.callsFake(fakeStoreFn); - - config.setConfig({ - adpod: { - bidQueueSizeLimit: 2, - deferCaching: false, - brandCategoryExclusion: true - } - }); - - let bidResponse1 = { - adId: 'adId123', - auctionId: 'full_abc123', - mediaType: 'video', - cpm: 10, - pbMg: '10.00', - adserverTargeting: { - hb_pb: '10.00' - }, - meta: { - adServerCatId: 'airline' - }, - video: { - context: ADPOD, - durationSeconds: 20, - durationBucket: 30 - } - }; - let bidResponse2 = { - adId: 'adId234', - auctionId: 'full_abc123', - mediaType: 'video', - cpm: 15, - pbMg: '15.00', - adserverTargeting: { - hb_pb: '15.00' - }, - meta: { - adServerCatId: 'airline' - }, - video: { - context: ADPOD, - durationSeconds: 25, - durationBucket: 30 - } - }; - let bidderRequest = { - adUnitCode: 'adpod_1', - auctionId: 'full_abc123', - mediaTypes: { - video: { - context: ADPOD, - playerSize: [[300, 300]], - adPodDurationSec: 120, - durationRangeSec: [15, 30], - requireExactDuration: false - } - } - }; - - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse1, afterBidAddedSpy, bidderRequest); - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse2, afterBidAddedSpy, bidderRequest); - - expect(callbackResult).to.be.null; - expect(afterBidAddedSpy.calledTwice).to.equal(true); - expect(auctionBids.length).to.equal(2); - expect(auctionBids[0].adId).to.equal('adId123'); - expect(auctionBids[0].customCacheKey).to.exist.and.to.match(/^10\.00_airline_30s_.*/); - expect(auctionBids[0].adserverTargeting.hb_pb_cat_dur).to.equal('10.00_airline_30s'); - expect(auctionBids[0].adserverTargeting.hb_cache_id).to.exist; - expect(auctionBids[0].videoCacheKey).to.exist.and.to.equal(auctionBids[0].adserverTargeting.hb_cache_id) - expect(auctionBids[1].adId).to.equal('adId234'); - expect(auctionBids[1].customCacheKey).to.exist.and.to.match(/^15\.00_airline_30s_.*/); - expect(auctionBids[1].adserverTargeting.hb_pb_cat_dur).to.equal('15.00_airline_30s'); - expect(auctionBids[1].adserverTargeting.hb_cache_id).to.exist; - expect(auctionBids[1].videoCacheKey).to.exist.and.to.equal(auctionBids[0].adserverTargeting.hb_cache_id) - }); - - it('should send prebid cache call after set period of time (even if queue is not full)', function () { - storeStub.callsFake(fakeStoreFn); - - config.setConfig({ - adpod: { - bidQueueSizeLimit: 2, - bidQueueTimeDelay: 30, - deferCaching: false, - brandCategoryExclusion: true - } - }); - - let bidResponse = { - adId: 'adId234', - auctionId: 'timer_abc234', - mediaType: 'video', - cpm: 15, - pbMg: '15.00', - adserverTargeting: { - hb_pb: '15.00' - }, - meta: { - adServerCatId: 'airline' - }, - video: { - context: ADPOD, - durationSeconds: 30, - durationBucket: 30 - } - }; - let bidderRequest = { - adUnitCode: 'adpod_2', - auctionId: 'timer_abc234', - mediaTypes: { - video: { - context: ADPOD, - playerSize: [[300, 300]], - adPodDurationSec: 120, - durationRangeSec: [15, 30], - requireExactDuration: true - } - } - }; - - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse, afterBidAddedSpy, bidderRequest); - clock.tick(31); - - expect(callbackResult).to.be.null; - expect(afterBidAddedSpy.calledOnce).to.equal(true); - expect(auctionBids.length).to.equal(1); - expect(auctionBids[0].adId).to.equal('adId234'); - expect(auctionBids[0].customCacheKey).to.exist.and.to.match(/^15\.00_airline_30s_.*/); - expect(auctionBids[0].adserverTargeting.hb_pb_cat_dur).to.equal('15.00_airline_30s'); - expect(auctionBids[0].adserverTargeting.hb_cache_id).to.exist; - expect(auctionBids[0].videoCacheKey).to.exist.and.to.equal(auctionBids[0].adserverTargeting.hb_cache_id) - }); - - it('should execute multiple prebid cache calls when number of bids exceeds queue size', function () { - storeStub.callsFake(fakeStoreFn); - - config.setConfig({ - adpod: { - bidQueueSizeLimit: 2, - bidQueueTimeDelay: 30, - deferCaching: false, - brandCategoryExclusion: true - } - }); - - let bidResponse1 = { - adId: 'multi_ad1', - auctionId: 'multi_call_abc345', - mediaType: 'video', - cpm: 15, - pbMg: '15.00', - adserverTargeting: { - hb_pb: '15.00' - }, - meta: { - adServerCatId: 'airline' - }, - video: { - context: ADPOD, - durationSeconds: 15, - durationBucket: 15 - } - }; - let bidResponse2 = { - adId: 'multi_ad2', - auctionId: 'multi_call_abc345', - mediaType: 'video', - cpm: 15, - pbMg: '15.00', - adserverTargeting: { - hb_pb: '15.00' - }, - meta: { - adServerCatId: 'news' - }, - video: { - context: ADPOD, - durationSeconds: 15, - durationBucket: 15 - } - }; - let bidResponse3 = { - adId: 'multi_ad3', - auctionId: 'multi_call_abc345', - mediaType: 'video', - cpm: 10, - pbMg: '10.00', - adserverTargeting: { - hb_pb: '10.00' - }, - meta: { - adServerCatId: 'sports' - }, - video: { - context: ADPOD, - durationSeconds: 15, - durationBucket: 15 - } - }; - - let bidderRequest = { - adUnitCode: 'adpod_3', - auctionId: 'multi_call_abc345', - mediaTypes: { - video: { - context: ADPOD, - playerSize: [[300, 300]], - adPodDurationSec: 45, - durationRangeSec: [15, 30], - requireExactDuration: false - } - } - }; - - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse1, afterBidAddedSpy, bidderRequest); - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse2, afterBidAddedSpy, bidderRequest); - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse3, afterBidAddedSpy, bidderRequest); - clock.next(); - - expect(callbackResult).to.be.null; - expect(afterBidAddedSpy.calledThrice).to.equal(true); - expect(storeStub.calledTwice).to.equal(true); - expect(auctionBids.length).to.equal(3); - expect(auctionBids[0].adId).to.equal('multi_ad1'); - expect(auctionBids[0].customCacheKey).to.exist.and.to.match(/^15\.00_airline_15s_.*/); - expect(auctionBids[0].adserverTargeting.hb_pb_cat_dur).to.equal('15.00_airline_15s'); - expect(auctionBids[0].adserverTargeting.hb_cache_id).to.exist; - expect(auctionBids[0].videoCacheKey).to.exist.and.to.equal(auctionBids[0].adserverTargeting.hb_cache_id) - expect(auctionBids[1].adId).to.equal('multi_ad2'); - expect(auctionBids[1].customCacheKey).to.exist.and.to.match(/^15\.00_news_15s_.*/); - expect(auctionBids[1].adserverTargeting.hb_pb_cat_dur).to.equal('15.00_news_15s'); - expect(auctionBids[1].adserverTargeting.hb_cache_id).to.exist.and.to.equal(auctionBids[0].adserverTargeting.hb_cache_id); - expect(auctionBids[1].videoCacheKey).to.exist.and.to.equal(auctionBids[0].adserverTargeting.hb_cache_id) - expect(auctionBids[2].adId).to.equal('multi_ad3'); - expect(auctionBids[2].customCacheKey).to.exist.and.to.match(/^10\.00_sports_15s_.*/); - expect(auctionBids[2].adserverTargeting.hb_pb_cat_dur).to.equal('10.00_sports_15s'); - expect(auctionBids[2].adserverTargeting.hb_cache_id).to.exist.and.to.equal(auctionBids[0].adserverTargeting.hb_cache_id); - expect(auctionBids[2].videoCacheKey).to.exist.and.to.equal(auctionBids[0].adserverTargeting.hb_cache_id) - }); - - it('should cache the bids with a shortened custom key when adpod.brandCategoryExclusion is false', function() { - storeStub.callsFake(fakeStoreFn); - - config.setConfig({ - adpod: { - bidQueueSizeLimit: 2, - bidQueueTimeDelay: 30, - deferCaching: false, - brandCategoryExclusion: false - } - }); - - let bidResponse1 = { - adId: 'nocat_ad1', - auctionId: 'no_category_abc345', - mediaType: 'video', - cpm: 10, - pbMg: '10.00', - adserverTargeting: { - hb_pb: '10.00' - }, - meta: { - adServerCatId: undefined - }, - video: { - context: ADPOD, - durationSeconds: 15, - durationBucket: 15 - } - }; - let bidResponse2 = { - adId: 'nocat_ad2', - auctionId: 'no_category_abc345', - mediaType: 'video', - cpm: 15, - pbMg: '15.00', - adserverTargeting: { - hb_pb: '15.00' - }, - meta: { - adServerCatId: undefined - }, - video: { - context: ADPOD, - durationSeconds: 15, - durationBucket: 15 - } - }; - - let bidderRequest = { - adUnitCode: 'adpod_4', - auctionId: 'no_category_abc345', - mediaTypes: { - video: { - context: ADPOD, - playerSize: [[300, 300]], - adPodDurationSec: 45, - durationRangeSec: [15, 30], - requireExactDuration: false - } - } - }; - - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse1, afterBidAddedSpy, bidderRequest); - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse2, afterBidAddedSpy, bidderRequest); - - expect(callbackResult).to.be.null; - expect(afterBidAddedSpy.calledTwice).to.equal(true); - expect(storeStub.calledOnce).to.equal(true); - expect(auctionBids.length).to.equal(2); - expect(auctionBids[0].adId).to.equal('nocat_ad1'); - expect(auctionBids[0].customCacheKey).to.exist.and.to.match(/^10\.00_15s_.*/); - expect(auctionBids[0].adserverTargeting.hb_pb_cat_dur).to.equal('10.00_15s'); - expect(auctionBids[0].adserverTargeting.hb_cache_id).to.exist; - expect(auctionBids[0].videoCacheKey).to.exist.and.to.equal(auctionBids[0].adserverTargeting.hb_cache_id) - expect(auctionBids[1].adId).to.equal('nocat_ad2'); - expect(auctionBids[1].customCacheKey).to.exist.and.to.match(/^15\.00_15s_.*/); - expect(auctionBids[1].adserverTargeting.hb_pb_cat_dur).to.equal('15.00_15s'); - expect(auctionBids[1].adserverTargeting.hb_cache_id).to.exist.and.to.equal(auctionBids[0].adserverTargeting.hb_cache_id); - expect(auctionBids[1].videoCacheKey).to.exist.and.to.equal(auctionBids[0].adserverTargeting.hb_cache_id) - }); - - it('should not add bid to auction when config adpod.brandCategoryExclusion is true but bid is missing adServerCatId', function() { - storeStub.callsFake(fakeStoreFn); - - config.setConfig({ - adpod: { - bidQueueSizeLimit: 2, - bidQueueTimeDelay: 30, - deferCaching: false, - brandCategoryExclusion: true - } - }); - - let bidResponse1 = { - adId: 'missingCat_ad1', - auctionId: 'missing_category_abc345', - mediaType: 'video', - cpm: 10, - meta: { - adServerCatId: undefined - }, - video: { - context: ADPOD, - durationSeconds: 15, - durationBucket: 15 - } - }; - - let bidderRequest = { - adUnitCode: 'adpod_5', - auctionId: 'missing_category_abc345', - mediaTypes: { - video: { - context: ADPOD, - playerSize: [[300, 300]], - adPodDurationSec: 45, - durationRangeSec: [15, 30], - requireExactDuration: false - } - } - }; - - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse1, afterBidAddedSpy, bidderRequest); - - expect(callbackResult).to.be.null; - expect(afterBidAddedSpy.calledOnce).to.equal(true); - expect(storeStub.called).to.equal(false); - expect(logWarnStub.calledOnce).to.equal(true); - expect(auctionBids.length).to.equal(0); - }); - - it('should not add bid to auction when Prebid Cache detects an existing key', function () { - storeStub.callsFake(function(bids, callback) { - let payload = []; - 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 = ''; - callback(null, payload); - }); - - config.setConfig({ - adpod: { - bidQueueSizeLimit: 2, - deferCaching: false, - brandCategoryExclusion: true - } - }); - - let bidResponse1 = { - adId: 'dup_ad_1', - auctionId: 'duplicate_def123', - mediaType: 'video', - cpm: 5, - pbMg: '5.00', - adserverTargeting: { - hb_pb: '5.00' - }, - meta: { - adServerCatId: 'tech' - }, - video: { - context: ADPOD, - durationSeconds: 45, - durationBucket: 45 - } - }; - let bidResponse2 = { - adId: 'dup_ad_2', - auctionId: 'duplicate_def123', - mediaType: 'video', - cpm: 5, - pbMg: '5.00', - adserverTargeting: { - hb_pb: '5.00' - }, - meta: { - adServerCatId: 'tech' - }, - video: { - context: ADPOD, - durationSeconds: 45, - durationBucket: 45 - } - }; - let bidderRequest = { - adUnitCode: 'adpod_4', - auctionId: 'duplicate_def123', - mediaTypes: { - video: { - context: ADPOD, - playerSize: [[300, 300]], - adPodDurationSec: 120, - durationRangeSec: [15, 30, 45], - requireExactDuration: false - } - } - }; - - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse1, afterBidAddedSpy, bidderRequest); - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse2, afterBidAddedSpy, bidderRequest); - - expect(callbackResult).to.be.null; - expect(afterBidAddedSpy.calledTwice).to.equal(true); - expect(storeStub.calledOnce).to.equal(true); - expect(logInfoStub.calledOnce).to.equal(true); - expect(auctionBids.length).to.equal(1); - expect(auctionBids[0].adId).to.equal('dup_ad_1'); - expect(auctionBids[0].customCacheKey).to.exist.and.to.match(/^5\.00_tech_45s_.*/); - expect(auctionBids[0].adserverTargeting.hb_pb_cat_dur).to.equal('5.00_tech_45s'); - expect(auctionBids[0].adserverTargeting.hb_cache_id).to.exist; - expect(auctionBids[0].videoCacheKey).to.exist.and.to.equal(auctionBids[0].adserverTargeting.hb_cache_id) - }); - - it('should not add bids to auction if PBC returns an error', function() { - storeStub.callsFake(function(bids, callback) { - let payload = []; - let errmsg = 'invalid json'; - - callback(errmsg, payload); - }); - - config.setConfig({ - adpod: { - bidQueueSizeLimit: 2, - deferCaching: false, - brandCategoryExclusion: true - } - }); - - let bidResponse1 = { - adId: 'err_ad_1', - auctionId: 'error_xyz123', - mediaType: 'video', - cpm: 5, - meta: { - adServerCatId: 'tech' - }, - video: { - context: ADPOD, - durationSeconds: 30, - durationBucket: 30 - } - }; - let bidResponse2 = { - adId: 'err_ad_2', - auctionId: 'error_xyz123', - mediaType: 'video', - cpm: 5, - meta: { - adServerCatId: 'tech' - }, - video: { - context: ADPOD, - durationSeconds: 30, - durationBucket: 30 - } - }; - let bidderRequest = { - adUnitCode: 'adpod_5', - auctionId: 'error_xyz123', - mediaTypes: { - video: { - context: ADPOD, - playerSize: [[300, 300]], - adPodDurationSec: 120, - durationRangeSec: [15, 30, 45], - requireExactDuration: false - } - } - }; - - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse1, afterBidAddedSpy, bidderRequest); - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse2, afterBidAddedSpy, bidderRequest); - - expect(doCallbacksIfTimedoutStub.calledTwice).to.equal(true); - expect(logWarnStub.calledOnce).to.equal(true); - expect(auctionBids.length).to.equal(0); - }); - - it('should use bid.adserverTargeting.hb_pb when custom price granularity is configured', function() { - storeStub.callsFake(fakeStoreFn); - - const customConfigObject = { - 'buckets': [{ - 'precision': 2, // default is 2 if omitted - means 2.1234 rounded to 2 decimal places = 2.12 - 'max': 5, - 'increment': 0.01 // from $0 to $5, 1-cent increments - }, - { - 'precision': 2, - 'max': 8, - 'increment': 0.05 // from $5 to $8, round down to the previous 5-cent increment - }, - { - 'precision': 2, - 'max': 40, - 'increment': 0.5 // from $8 to $40, round down to the previous 50-cent increment - }] - }; - config.setConfig({ - priceGranularity: customConfigObject, - adpod: { - brandCategoryExclusion: true - } - }); - - let bidResponse1 = { - adId: 'cat_ad1', - auctionId: 'test_category_abc345', - mediaType: 'video', - cpm: 15, - pbAg: '15.00', - pbCg: '15.00', - pbDg: '15.00', - pbHg: '15.00', - pbLg: '5.00', - pbMg: '15.00', - adserverTargeting: { - hb_pb: '15.00', - }, - meta: { - adServerCatId: 'test' - }, - video: { - context: ADPOD, - durationSeconds: 15, - durationBucket: 15 - } - }; - - let bidderRequest = { - adUnitCode: 'adpod_5', - auctionId: 'test_category_abc345', - mediaTypes: { - video: { - context: ADPOD, - playerSize: [[300, 300]], - adPodDurationSec: 45, - durationRangeSec: [15, 30], - requireExactDuration: false - } - } - }; - - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse1, afterBidAddedSpy, bidderRequest); - - expect(callbackResult).to.be.null; - expect(afterBidAddedSpy.calledOnce).to.equal(true); - expect(storeStub.called).to.equal(false); - expect(auctionBids.length).to.equal(1); - }); - - it('should set deal tier in place of cpm when prioritzeDeals is true', function() { - config.setConfig({ - adpod: { - deferCaching: true, - brandCategoryExclusion: true, - prioritizeDeals: true, - dealTier: { - 'appnexus': { - 'prefix': 'tier', - 'minDealTier': 5 - } - } - } - }); - - let bidResponse1 = { - adId: 'adId01277', - auctionId: 'no_defer_123', - mediaType: 'video', - bidderCode: 'appnexus', - cpm: 5, - pbMg: '5.00', - adserverTargeting: { - hb_pb: '5.00' - }, - meta: { - adServerCatId: 'test' - }, - video: { - context: ADPOD, - durationSeconds: 15, - durationBucket: 15, - dealTier: 7 - } - }; - - let bidResponse2 = { - adId: 'adId46547', - auctionId: 'no_defer_123', - mediaType: 'video', - bidderCode: 'appnexus', - cpm: 12, - pbMg: '12.00', - adserverTargeting: { - hb_pb: '12.00' - }, - meta: { - adServerCatId: 'value' - }, - video: { - context: ADPOD, - durationSeconds: 15, - durationBucket: 15 - } - }; - - let bidderRequest = { - adUnitCode: 'adpod_1', - auctionId: 'no_defer_123', - mediaTypes: { - video: { - context: ADPOD, - playerSize: [[300, 300]], - adPodDurationSec: 300, - durationRangeSec: [15, 30, 45], - requireExactDuration: false - } - }, - }; - - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse1, afterBidAddedSpy, bidderRequest); - callPrebidCacheHook(callbackFn, auctionInstance, bidResponse2, afterBidAddedSpy, bidderRequest); - - expect(auctionBids[0].adserverTargeting.hb_pb_cat_dur).to.equal('tier7_test_15s'); - expect(auctionBids[1].adserverTargeting.hb_pb_cat_dur).to.equal('12.00_value_15s'); - }) - }); - - describe('checkAdUnitSetupHook', function () { - let results; - let callbackFn = function (adUnits) { - results = adUnits; - }; - - beforeEach(function () { - logWarnStub = sinon.stub(utils, 'logWarn'); - results = null; - }); - - afterEach(function() { - utils.logWarn.restore(); - }); - - it('removes an incorrectly setup adpod adunit - required fields are missing', function() { - let adUnits = [{ - code: 'test1', - mediaTypes: { - video: { - context: ADPOD - } - } - }, { - code: 'test2', - mediaTypes: { - video: { - context: 'instream' - } - } - }]; - - checkAdUnitSetupHook(callbackFn, adUnits); - - expect(results).to.deep.equal([{ - code: 'test2', - mediaTypes: { - video: { - context: 'instream' - } - } - }]); - expect(logWarnStub.calledOnce).to.equal(true); - }); - - it('removes an incorrectly setup adpod adunit - required fields are using invalid values', function() { - let adUnits = [{ - code: 'test1', - mediaTypes: { - video: { - context: ADPOD, - durationRangeSec: [-5, 15, 30, 45], - adPodDurationSec: 300 - } - } - }]; - - checkAdUnitSetupHook(callbackFn, adUnits); - - expect(results).to.deep.equal([]); - expect(logWarnStub.calledOnce).to.equal(true); - - adUnits[0].mediaTypes.video.durationRangeSec = [15, 30, 45]; - adUnits[0].mediaTypes.video.adPodDurationSec = 0; - - checkAdUnitSetupHook(callbackFn, adUnits); - - expect(results).to.deep.equal([]); - expect(logWarnStub.calledTwice).to.equal(true); - }); - - it('removes an incorrectly setup adpod adunit - attempting to use multi-format adUnit', function() { - let adUnits = [{ - code: 'multi_test1', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - }, - video: { - context: 'adpod', - playerSize: [[300, 250]], - durationRangeSec: [15, 30, 45], - adPodDurationSec: 300 - } - } - }]; - - checkAdUnitSetupHook(callbackFn, adUnits); - - expect(results).to.deep.equal([]); - expect(logWarnStub.calledOnce).to.equal(true); - }); - - it('accepts mixed set of adunits', function() { - let adUnits = [{ - code: 'test3', - mediaTypes: { - video: { - context: ADPOD, - playerSize: [[300, 300]], - adPodDurationSec: 360, - durationRangeSec: [15, 30, 45], - requireExactDuration: true - } - } - }, { - code: 'test4', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - } - }]; - - checkAdUnitSetupHook(callbackFn, adUnits); - - expect(results).to.deep.equal(adUnits); - expect(logWarnStub.called).to.equal(false); - }); - }); - - describe('checkVideoBidSetupHook', function () { - let callbackResult; - let bailResult; - const callbackFn = { - call: function(context, bid) { - callbackResult = bid; - }, - bail: function(result) { - bailResult = result; - } - } - const adpodTestBid = { - video: { - context: ADPOD, - durationSeconds: 15, - durationBucket: 15 - }, - meta: { - primaryCatId: 'testCategory_123' - }, - vastXml: 'test XML here' - }; - const bidderRequestNoExact = { - mediaTypes: { - video: { - context: ADPOD, - playerSize: [[300, 400]], - durationRangeSec: [15, 45], - requireExactDuration: false, - adPodDurationSec: 300 - } - } - }; - const bidderRequestWithExact = { - mediaTypes: { - video: { - context: ADPOD, - playerSize: [[300, 400]], - durationRangeSec: [15, 30, 45, 60], - requireExactDuration: true, - adPodDurationSec: 300 - } - } - }; - - beforeEach(function() { - callbackResult = null; - bailResult = null; - config.setConfig({ - cache: { - url: 'http://test.cache.url/endpoint' - }, - adpod: { - brandCategoryExclusion: true - } - }); - logWarnStub = sinon.stub(utils, 'logWarn'); - logErrorStub = sinon.stub(utils, 'logError'); - }); - - afterEach(function() { - config.resetConfig(); - logWarnStub.restore(); - logErrorStub.restore(); - }) - - it('redirects to original function for non-adpod type video bids', function() { - let bannerTestBid = { - mediaType: 'video' - }; - checkVideoBidSetupHook(callbackFn, bannerTestBid, {}, {}, 'instream'); - expect(callbackResult).to.deep.equal(bannerTestBid); - expect(bailResult).to.be.null; - expect(logErrorStub.called).to.equal(false); - }); - - it('returns true when adpod bid is properly setup', function() { - config.setConfig({ - cache: { - url: 'http://test.cache.url/endpoint' - }, - adpod: { - brandCategoryExclusion: false - } - }); - - let goodBid = utils.deepClone(adpodTestBid); - goodBid.meta.primaryCatId = undefined; - checkVideoBidSetupHook(callbackFn, goodBid, bidderRequestNoExact, {}, ADPOD); - expect(callbackResult).to.be.null; - expect(bailResult).to.equal(true); - expect(logErrorStub.called).to.equal(false); - }); - - it('returns true when adpod bid is missing iab category while brandCategoryExclusion in config is false', function() { - let goodBid = utils.deepClone(adpodTestBid); - checkVideoBidSetupHook(callbackFn, goodBid, bidderRequestNoExact, {}, ADPOD); - expect(callbackResult).to.be.null; - expect(bailResult).to.equal(true); - expect(logErrorStub.called).to.equal(false); - }); - - it('returns false when a required property from an adpod bid is missing', function() { - function testInvalidAdpodBid(badTestBid, shouldErrorBeLogged) { - checkVideoBidSetupHook(callbackFn, badTestBid, bidderRequestNoExact, {}, ADPOD); - expect(callbackResult).to.be.null; - expect(bailResult).to.equal(false); - expect(logErrorStub.called).to.equal(shouldErrorBeLogged); - } - - let noCatBid = utils.deepClone(adpodTestBid); - noCatBid.meta.primaryCatId = undefined; - testInvalidAdpodBid(noCatBid, false); - - let noContextBid = utils.deepClone(adpodTestBid); - delete noContextBid.video.context; - testInvalidAdpodBid(noContextBid, false); - - let wrongContextBid = utils.deepClone(adpodTestBid); - wrongContextBid.video.context = 'instream'; - testInvalidAdpodBid(wrongContextBid, false); - - let noDurationBid = utils.deepClone(adpodTestBid); - delete noDurationBid.video.durationSeconds; - testInvalidAdpodBid(noDurationBid, false); - - config.resetConfig(); - let noCacheUrlBid = utils.deepClone(adpodTestBid); - testInvalidAdpodBid(noCacheUrlBid, true); - }); - - describe('checkBidDuration', function() { - const basicBid = { - video: { - context: ADPOD, - durationSeconds: 30 - }, - meta: { - primaryCatId: 'testCategory_123' - }, - vastXml: '' - }; - - it('when requireExactDuration is true', function() { - let goodBid = utils.deepClone(basicBid); - checkVideoBidSetupHook(callbackFn, goodBid, bidderRequestWithExact, {}, ADPOD); - - expect(callbackResult).to.be.null; - expect(goodBid.video.durationBucket).to.equal(30); - expect(bailResult).to.equal(true); - expect(logWarnStub.called).to.equal(false); - - let badBid = utils.deepClone(basicBid); - badBid.video.durationSeconds = 14; - checkVideoBidSetupHook(callbackFn, badBid, bidderRequestWithExact, {}, ADPOD); - - expect(callbackResult).to.be.null; - expect(badBid.video.durationBucket).to.be.undefined; - expect(bailResult).to.equal(false); - expect(logWarnStub.calledOnce).to.equal(true); - }); - - it('when requireExactDuration is false and bids are bucketed properly', function() { - function testRoundingForGoodBId(bid, bucketValue) { - checkVideoBidSetupHook(callbackFn, bid, bidderRequestNoExact, {}, ADPOD); - expect(callbackResult).to.be.null; - expect(bid.video.durationBucket).to.equal(bucketValue); - expect(bailResult).to.equal(true); - expect(logWarnStub.called).to.equal(false); - } - - let goodBid45 = utils.deepClone(basicBid); - goodBid45.video.durationSeconds = 45; - testRoundingForGoodBId(goodBid45, 45); - - let goodBid30 = utils.deepClone(basicBid); - goodBid30.video.durationSeconds = 30; - testRoundingForGoodBId(goodBid30, 45); - - let goodBid10 = utils.deepClone(basicBid); - goodBid10.video.durationSeconds = 10; - testRoundingForGoodBId(goodBid10, 15); - - let goodBid16 = utils.deepClone(basicBid); - goodBid16.video.durationSeconds = 16; - testRoundingForGoodBId(goodBid16, 15); - - let goodBid47 = utils.deepClone(basicBid); - goodBid47.video.durationSeconds = 47; - testRoundingForGoodBId(goodBid47, 45); - }); - - it('when requireExactDuration is false and bid duration exceeds listed buckets', function() { - function testRoundingForBadBid(bid) { - checkVideoBidSetupHook(callbackFn, bid, bidderRequestNoExact, {}, ADPOD); - expect(callbackResult).to.be.null; - expect(bid.video.durationBucket).to.be.undefined; - expect(bailResult).to.equal(false); - expect(logWarnStub.called).to.equal(true); - } - - let badBid100 = utils.deepClone(basicBid); - badBid100.video.durationSeconds = 100; - testRoundingForBadBid(badBid100); - - let badBid48 = utils.deepClone(basicBid); - badBid48.video.durationSeconds = 48; - testRoundingForBadBid(badBid48); - }); - }); - }); - - describe('adpodSetConfig', function () { - let logWarnStub; - beforeEach(function() { - logWarnStub = sinon.stub(utils, 'logWarn'); - }); - - afterEach(function () { - logWarnStub.restore(); - }); - - it('should log a warning when values other than numbers are used in setConfig', function() { - adpodSetConfig({ - bidQueueSizeLimit: '2', - bidQueueTimeDelay: '50' - }); - expect(logWarnStub.calledTwice).to.equal(true); - }); - - it('should log a warning when numbers less than or equal to zero are used in setConfig', function() { - adpodSetConfig({ - bidQueueSizeLimit: 0, - bidQueueTimeDelay: -2 - }); - expect(logWarnStub.calledTwice).to.equal(true); - }); - - it('should not log any warning when using a valid config', function() { - adpodSetConfig({ - bidQueueSizeLimit: 10 - }); - expect(logWarnStub.called).to.equal(false); - - adpodSetConfig({ - bidQueueTimeDelay: 100, - bidQueueSizeLimit: 20 - }); - expect(logWarnStub.called).to.equal(false); - }) - }); - - describe('adpod utils', function() { - it('should sort bids array', function() { - let bids = [{ - cpm: 10.12345, - adserverTargeting: { - hb_pb: '10.00', - }, - video: { - durationBucket: 15 - } - }, { - cpm: 15, - adserverTargeting: { - hb_pb: '15.00', - }, - video: { - durationBucket: 15 - } - }, { - cpm: 15.00, - adserverTargeting: { - hb_pb: '15.00', - }, - video: { - durationBucket: 30 - } - }, { - cpm: 5.45, - adserverTargeting: { - hb_pb: '5.00', - }, - video: { - durationBucket: 5 - } - }, { - cpm: 20.1234567, - adserverTargeting: { - hb_pb: '20.10', - }, - video: { - durationBucket: 60 - } - }] - bids.sort(sortByPricePerSecond); - let sortedBids = [{ - cpm: 15, - adserverTargeting: { - hb_pb: '15.00', - }, - video: { - durationBucket: 15 - } - }, { - cpm: 5.45, - adserverTargeting: { - hb_pb: '5.00', - }, - video: { - durationBucket: 5 - } - }, { - cpm: 10.12345, - adserverTargeting: { - hb_pb: '10.00', - }, - video: { - durationBucket: 15 - } - }, { - cpm: 15.00, - adserverTargeting: { - hb_pb: '15.00', - }, - video: { - durationBucket: 30 - } - }, { - cpm: 20.1234567, - adserverTargeting: { - hb_pb: '20.10', - }, - video: { - durationBucket: 60 - } - }] - expect(bids).to.include.deep.ordered.members(sortedBids); - }); - }) -}); diff --git a/test/spec/modules/adponeBidAdapter_spec.js b/test/spec/modules/adponeBidAdapter_spec.js deleted file mode 100644 index 92fd672df47..00000000000 --- a/test/spec/modules/adponeBidAdapter_spec.js +++ /dev/null @@ -1,218 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/adponeBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import * as utils from 'src/utils.js'; - -const EMPTY_ARRAY = []; -describe('adponeBidAdapter', function () { - let bid = { - bidder: 'adpone', - adUnitCode: 'adunit-code', - sizes: [[300, 250]], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - params: { - placementId: '1', - } - }; - - describe('build requests', () => { - it('sends bid request to ENDPOINT via POST', function () { - const request = spec.buildRequests([ - { - bidder: 'adpone', - adUnitCode: 'adunit-code', - sizes: [[300, 250]], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - params: { - placementId: '1', - } - } - ]); - expect(request[0].method).to.equal('POST'); - }); - it('sends bid request to adpone endpoint', function () { - const request = spec.buildRequests([ - { - bidder: 'adpone', - adUnitCode: 'adunit-code', - sizes: [[300, 250]], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - params: { - placementId: '1', - } - } - ]); - expect(request[0].url).to.equal('https://rtb.adpone.com/bid-request?pid=1'); - }); - }); - - describe('inherited functions', () => { - const adapter = newBidder(spec); - it('exists and is a function', () => { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - it('should return true when necessary information is found', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - - it('should return false when necessary information is not found', function () { - // empty bid - expect(spec.isBidRequestValid({bidId: '', params: {}})).to.be.false; - - // empty bidId - bid.bidId = ''; - expect(spec.isBidRequestValid(bid)).to.be.false; - - // empty placementId - bid.bidId = '30b31c1838de1e'; - bid.params.placementId = ''; - expect(spec.isBidRequestValid(bid)).to.be.false; - - bid.adUnitCode = 'adunit-code'; - }); - - it('returns false when bidder not set to "adpone"', function() { - const invalidBid = { - bidder: 'enopda', - adUnitCode: 'adunit-code', - sizes: [[300, 250]], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - params: { - placementId: '1', - } - }; - expect(spec.isBidRequestValid(invalidBid)).to.be.false; - }); - - it('returns false when placementId is not set in params', function() { - const invalidBid = { - bidder: 'adpone', - adUnitCode: 'adunit-code', - sizes: [[300, 250]], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - params: { - } - }; - - expect(spec.isBidRequestValid(invalidBid)).to.be.false; - }); - }); - describe('interpretResponse', function () { - let serverResponse; - let bidRequest = { data: {id: '1234'} }; - - beforeEach(function () { - serverResponse = { - body: { - id: '2579e20c0bb89', - seatbid: [ - { - bid: [ - { - id: '613673EF-A07C-4486-8EE9-3FC71A7DC73D', - impid: '2579e20c0bb89_0', - price: 1, - adm: '', - meta: { - adomain: [ - 'adpone.com' - ] - }, - iurl: 'https://localhost11', - crid: 'creative111', - h: 250, - w: 300, - ext: { - dspid: 6 - } - } - ], - seat: 'adpone' - } - ], - cur: 'USD' - }, - }; - }); - - it('validate_response_params', function() { - const newResponse = spec.interpretResponse(serverResponse, bidRequest); - expect(newResponse[0].id).to.be.equal('613673EF-A07C-4486-8EE9-3FC71A7DC73D'); - expect(newResponse[0].requestId).to.be.equal('1234'); - expect(newResponse[0].cpm).to.be.equal(1); - expect(newResponse[0].width).to.be.equal(300); - expect(newResponse[0].height).to.be.equal(250); - expect(newResponse[0].currency).to.be.equal('USD'); - expect(newResponse[0].netRevenue).to.be.equal(true); - expect(newResponse[0].ttl).to.be.equal(300); - expect(newResponse[0].ad).to.be.equal(''); - }); - - it('should correctly reorder the server response', function () { - const newResponse = spec.interpretResponse(serverResponse, bidRequest); - expect(newResponse.length).to.be.equal(1); - expect(newResponse[0]).to.deep.equal({ - id: '613673EF-A07C-4486-8EE9-3FC71A7DC73D', - meta: { - advertiserDomains: [ - 'adpone.com' - ] - }, - requestId: '1234', - cpm: 1, - width: 300, - height: 250, - creativeId: 'creative111', - currency: 'USD', - netRevenue: true, - ttl: 300, - ad: '' - }); - }); - - it('should not add responses if the cpm is 0 or null', function () { - serverResponse.body.seatbid[0].bid[0].price = 0; - let response = spec.interpretResponse(serverResponse, bidRequest); - expect(response).to.deep.equal([]); - - serverResponse.body.seatbid[0].bid[0].price = null; - response = spec.interpretResponse(serverResponse, bidRequest); - expect(response).to.deep.equal([]) - }); - it('should add responses if the cpm is valid', function () { - serverResponse.body.seatbid[0].bid[0].price = 0.5; - let response = spec.interpretResponse(serverResponse, bidRequest); - expect(response).to.not.deep.equal([]); - }); - }); - - describe('test onBidWon function', function () { - beforeEach(function() { - sinon.stub(utils, 'triggerPixel'); - }); - afterEach(function() { - utils.triggerPixel.restore(); - }); - it('exists and is a function', () => { - expect(spec.onBidWon).to.exist.and.to.be.a('function'); - }); - it('should return nothing', function () { - var response = spec.onBidWon({}); - expect(response).to.be.an('undefined') - expect(utils.triggerPixel.called).to.equal(true); - }); - }); -}); diff --git a/test/spec/modules/adprimeBidAdapter_spec.js b/test/spec/modules/adprimeBidAdapter_spec.js deleted file mode 100644 index 8627941dc80..00000000000 --- a/test/spec/modules/adprimeBidAdapter_spec.js +++ /dev/null @@ -1,297 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/adprimeBidAdapter.js'; -import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; - -describe('AdprimebBidAdapter', function () { - const bid = { - bidId: '23fhj33i987f', - bidder: 'adprime', - params: { - placementId: 0, - traffic: BANNER - } - }; - - const bidderRequest = { - refererInfo: { - referer: 'test.com' - } - }; - - describe('isBidRequestValid', function () { - it('Should return true if there are bidId, params and placementId parameters present', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false if at least one of parameters is not present', function () { - delete bid.params.placementId; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid], 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://delta.adprime.com/?c=o&m=multi'); - }); - it('Returns valid data if array of bids is valid', function () { - let data = serverRequest.data; - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); - 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.gdpr).to.not.exist; - expect(data.ccpa).to.not.exist; - let placement = data['placements'][0]; - expect(placement).to.have.keys('placementId', 'bidId', 'identeties', 'traffic', 'sizes', 'hPlayer', 'wPlayer', 'schain', 'keywords'); - expect(placement.placementId).to.equal(0); - expect(placement.bidId).to.equal('23fhj33i987f'); - expect(placement.traffic).to.equal(BANNER); - expect(placement.schain).to.be.an('object'); - }); - - it('Returns valid data for mediatype video', function () { - const playerSize = [300, 300]; - bid.mediaTypes = {}; - bid.params.traffic = VIDEO; - bid.mediaTypes[VIDEO] = { - playerSize - }; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data).to.be.an('object'); - let placement = data['placements'][0]; - expect(placement).to.be.an('object'); - expect(placement.traffic).to.equal(VIDEO); - expect(placement.wPlayer).to.equal(playerSize[0]); - expect(placement.hPlayer).to.equal(playerSize[1]); - }); - - it('Returns data with gdprConsent and without uspConsent', function () { - bidderRequest.gdprConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data.gdpr).to.exist; - expect(data.gdpr).to.be.a('string'); - expect(data.gdpr).to.equal(bidderRequest.gdprConsent); - expect(data.ccpa).to.not.exist; - delete bidderRequest.gdprConsent; - }); - - it('Returns data with uspConsent and without gdprConsent', function () { - bidderRequest.uspConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); - let 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; - }); - - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); - }); - describe('buildRequests with user ids', function () { - bid.userId = {} - bid.userId.idl_env = 'idl_env123'; - let serverRequest = spec.buildRequests([bid], bidderRequest); - it('Return bids with user identeties', function () { - let data = serverRequest.data; - let placements = data['placements']; - expect(data).to.be.an('object'); - for (let i = 0; i < placements.length; i++) { - let placement = placements[i]; - expect(placement).to.have.property('identeties') - expect(placement.identeties).to.be.an('object') - expect(placement.identeties).to.have.property('identityLink') - expect(placement.identeties.identityLink).to.be.equal('idl_env123') - } - }); - }); - 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' - }] - }; - let bannerResponses = spec.interpretResponse(banner); - expect(bannerResponses).to.be.an('array').that.is.not.empty; - let dataItem = bannerResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - expect(dataItem.requestId).to.equal('23fhj33i987f'); - expect(dataItem.cpm).to.equal(0.4); - expect(dataItem.width).to.equal(300); - expect(dataItem.height).to.equal(250); - expect(dataItem.ad).to.equal('Test'); - expect(dataItem.ttl).to.equal(120); - expect(dataItem.creativeId).to.equal('2'); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal('USD'); - }); - 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' - }] - }; - let videoResponses = spec.interpretResponse(video); - expect(videoResponses).to.be.an('array').that.is.not.empty; - - let dataItem = videoResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - 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'); - }); - 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', - }] - }; - let nativeResponses = spec.interpretResponse(native); - expect(nativeResponses).to.be.an('array').that.is.not.empty; - - let dataItem = nativeResponses[0]; - expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); - 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'); - }); - 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' - }] - }; - - let 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' - }] - }; - let 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', - }] - }; - let 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' - }] - }; - let serverResponses = spec.interpretResponse(invalid); - expect(serverResponses).to.be.an('array').that.is.empty; - }); - }); - describe('getUserSyncs', function () { - let userSync = spec.getUserSyncs(); - it('Returns valid URL and type', function () { - expect(userSync).to.be.an('array').with.lengthOf(1); - expect(userSync[0].type).to.exist; - expect(userSync[0].url).to.exist; - expect(userSync[0].type).to.be.equal('image'); - expect(userSync[0].url).to.be.equal('https://delta.adprime.com/?c=rtb&m=sync'); - }); - }); -}); diff --git a/test/spec/modules/adrelevantisBidAdapter_spec.js b/test/spec/modules/adrelevantisBidAdapter_spec.js deleted file mode 100644 index 596f3bade5d..00000000000 --- a/test/spec/modules/adrelevantisBidAdapter_spec.js +++ /dev/null @@ -1,771 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/adrelevantisBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import * as bidderFactory from 'src/adapters/bidderFactory.js'; -import { deepClone } from 'src/utils.js'; -import { config } from 'src/config.js'; - -const ENDPOINT = 'https://ssp.adrelevantis.com/prebid'; - -describe('AdrelevantisAdapter', 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 () { - let bid = { - 'bidder': 'adrelevantis', - 'params': { - 'placementId': '10433394' - }, - '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(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'placementId': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [ - { - 'bidder': 'adrelevantis', - 'params': { - 'placementId': '10433394' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - it('should parse out private sizes', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - privateSizes: [300, 250] - } - } - ); - - const request = spec.buildRequests([bidRequest]); - 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}]); - }); - - it('should add source and verison to the tag', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.sdk).to.exist; - expect(payload.sdk).to.deep.equal({ - source: 'pbjs', - version: '$prebid.version$' - }); - }); - - it('should populate the ad_types array on all requests', function () { - ['banner', 'video', 'native'].forEach(type => { - const bidRequest = Object.assign({}, bidRequests[0]); - bidRequest.mediaTypes = {}; - bidRequest.mediaTypes[type] = {}; - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].ad_types).to.deep.equal([type]); - }); - }); - - it('should populate the ad_types array on outstream requests', function () { - const bidRequest = Object.assign({}, bidRequests[0]); - bidRequest.mediaTypes = {}; - bidRequest.mediaTypes.video = {context: 'outstream'}; - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].ad_types).to.deep.equal(['video']); - }); - - it('sends bid request to ENDPOINT via POST', function () { - const request = spec.buildRequests(bidRequests); - expect(request.url).to.equal(ENDPOINT); - expect(request.method).to.equal('POST'); - }); - - it('should attach valid video params to the tag', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - video: { - id: 123, - minduration: 100, - foobar: 'invalid' - } - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - expect(payload.tags[0].video).to.deep.equal({ - id: 123, - minduration: 100 - }); - }); - - it('should add video property when adUnit includes a renderer', function () { - const videoData = { - mediaTypes: { - video: { - context: 'outstream', - mimes: ['video/mp4'] - } - }, - params: { - placementId: '10433394', - video: { - skippable: true, - playback_method: ['auto_play_sound_off'] - } - } - }; - - let bidRequest1 = deepClone(bidRequests[0]); - bidRequest1 = Object.assign({}, bidRequest1, videoData, { - renderer: { - url: 'http://test.renderer.url', - render: function () {} - } - }); - - let bidRequest2 = deepClone(bidRequests[0]); - bidRequest2.adUnitCode = 'adUnit_code_2'; - bidRequest2 = Object.assign({}, bidRequest2, videoData); - - const request = spec.buildRequests([bidRequest1, bidRequest2]); - const payload = JSON.parse(request.data); - expect(payload.tags[0].video).to.deep.equal({ - skippable: true, - playback_method: ['auto_play_sound_off'], - custom_renderer_present: true - }); - expect(payload.tags[1].video).to.deep.equal({ - skippable: true, - playback_method: ['auto_play_sound_off'] - }); - }); - - it('should attach valid user params to the tag', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - user: { - externalUid: '123', - foobar: 'invalid' - } - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.user).to.exist; - expect(payload.user).to.deep.equal({ - externalUid: '123', - }); - }); - - it('should contain hb_source value for other media', function() { - let bidRequest = Object.assign({}, - bidRequests[0], - { - mediaType: 'banner', - params: { - sizes: [[300, 250], [300, 600]], - placementId: 10433394 - } - } - ); - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - expect(payload.tags[0].hb_source).to.deep.equal(1); - }); - - it('adds context data (category and keywords) to request when set', function() { - let bidRequest = Object.assign({}, bidRequests[0]); - sinon - .stub(config, 'getConfig') - .withArgs('ortb2') - .returns({ - site: { - keywords: 'US Open', - ext: { - data: { - category: 'sports/tennis' - } - } - } - }); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.fpd.keywords).to.equal('US Open'); - expect(payload.fpd.category).to.equal('sports/tennis'); - - config.getConfig.restore(); - }); - - it('should attach native params to the request', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - 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} - } - } - ); - - const request = spec.buildRequests([bidRequest]); - 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}, - privacy_supported: true - }); - expect(payload.tags[0].hb_source).to.equal(1); - }); - - it('should always populated tags[].sizes with 1,1 for native if otherwise not defined', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - mediaType: 'native', - nativeParams: { - image: { required: true } - } - } - ); - bidRequest.sizes = [[150, 100], [300, 250]]; - - 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}]); - - delete bidRequest.sizes; - - request = spec.buildRequests([bidRequest]); - payload = JSON.parse(request.data); - - 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 () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - keywords: { - single: 'val', - singleArr: ['val'], - singleArrNum: [5], - multiValMixed: ['value1', 2, 'value3'], - singleValNum: 123, - emptyStr: '', - emptyArr: [''], - badValue: {'foo': 'bar'} // should be dropped - } - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].keywords).to.deep.equal([{ - 'key': 'single', - 'value': ['val'] - }, { - 'key': 'singleArr', - 'value': ['val'] - }, { - 'key': 'singleArrNum', - 'value': ['5'] - }, { - 'key': 'multiValMixed', - 'value': ['value1', '2', 'value3'] - }, { - 'key': 'singleValNum', - 'value': ['123'] - }, { - 'key': 'emptyStr' - }, { - 'key': 'emptyArr' - }]); - }); - - it('should add payment rules to the request', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - usePaymentRule: true - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].use_pmt_rule).to.equal(true); - }); - - it('should add gdpr consent information to the request', function () { - let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - let bidderRequest = { - 'bidderCode': 'adrelevantis', - 'auctionId': '1d1a030790a475', - 'bidderRequestId': '22edbae2733bf6', - 'timeout': 3000, - 'gdprConsent': { - consentString: consentString, - gdprApplies: true - } - }; - bidderRequest.bids = bidRequests; - - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.gdpr_consent).to.exist; - expect(payload.gdpr_consent.consent_string).to.exist.and.to.equal(consentString); - expect(payload.gdpr_consent.consent_required).to.exist.and.to.be.true; - }); - - it('supports sending hybrid mobile app parameters', function () { - let appRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - app: { - id: 'B1O2W3M4AN.com.prebid.webview', - geo: { - lat: 40.0964439, - lng: -75.3009142 - }, - device_id: { - idfa: '4D12078D-3246-4DA4-AD5E-7610481E7AE', // Apple advertising identifier - aaid: '38400000-8cf0-11bd-b23e-10b96e40000d', // Android advertising identifier - md5udid: '5756ae9022b2ea1e47d84fead75220c8', // MD5 hash of the ANDROID_ID - sha1udid: '4DFAA92388699AC6539885AEF1719293879985BF', // SHA1 hash of the ANDROID_ID - windowsadid: '750c6be243f1c4b5c9912b95a5742fc5' // Windows advertising identifier - } - } - } - } - ); - const request = spec.buildRequests([appRequest]); - const payload = JSON.parse(request.data); - expect(payload.app).to.exist; - expect(payload.app).to.deep.equal({ - appid: 'B1O2W3M4AN.com.prebid.webview' - }); - expect(payload.device.device_id).to.exist; - expect(payload.device.device_id).to.deep.equal({ - aaid: '38400000-8cf0-11bd-b23e-10b96e40000d', - idfa: '4D12078D-3246-4DA4-AD5E-7610481E7AE', - md5udid: '5756ae9022b2ea1e47d84fead75220c8', - sha1udid: '4DFAA92388699AC6539885AEF1719293879985BF', - windowsadid: '750c6be243f1c4b5c9912b95a5742fc5' - }); - expect(payload.device.geo).to.exist; - expect(payload.device.geo).to.deep.equal({ - lat: 40.0964439, - lng: -75.3009142 - }); - }); - - it('should add referer info to payload', function () { - const bidRequest = Object.assign({}, bidRequests[0]) - const bidderRequest = { - refererInfo: { - referer: 'http://example.com/page.html', - reachedTop: true, - numIframes: 2, - stack: [ - 'http://example.com/page.html', - 'http://example.com/iframe1.html', - 'http://example.com/iframe2.html' - ] - } - } - const request = spec.buildRequests([bidRequest], bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.referrer_detection).to.exist; - expect(payload.referrer_detection).to.deep.equal({ - rd_ref: 'http%3A%2F%2Fexample.com%2Fpage.html', - rd_top: true, - rd_ifs: 2, - rd_stk: bidderRequest.refererInfo.stack.map((url) => encodeURIComponent(url)).join(',') - }); - }); - - it('should populate coppa if set in config', function () { - let bidRequest = Object.assign({}, bidRequests[0]); - sinon.stub(config, 'getConfig') - .withArgs('coppa') - .returns(true); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.user.coppa).to.equal(true); - - config.getConfig.restore(); - }); - }) - - describe('interpretResponse', function () { - let bfStub; - before(function() { - bfStub = sinon.stub(bidderFactory, 'getIabSubCategory'); - }); - - after(function() { - bfStub.restore(); - }); - - let response = { - 'version': '3.0.0', - 'tags': [ - { - 'uuid': '3db3773286ee59', - 'tag_id': 10433394, - 'auction_id': '4534722592064951574', - 'nobid': false, - 'no_ad_url': 'http://lax1-ib.adnxs.com/no-ad', - 'timeout_ms': 10000, - 'ad_profile_id': 27079, - 'ads': [ - { - 'content_source': 'rtb', - 'ad_type': 'banner', - 'buyer_member_id': 958, - 'creative_id': 29681110, - 'media_type_id': 1, - 'media_subtype_id': 1, - 'cpm': 0.5, - 'cpm_publisher_currency': 0.5, - 'publisher_currency_code': '$', - 'client_initiated_ad_counting': true, - 'viewability': { - 'config': '' - }, - 'rtb': { - 'banner': { - 'content': '', - 'width': 300, - 'height': 250 - }, - 'trackers': [ - { - 'impression_urls': [ - 'http://lax1-ib.adnxs.com/impression' - ], - 'video_events': {} - } - ] - } - } - ] - } - ] - }; - - it('should get correct bid response', function () { - let expectedResponse = [ - { - 'requestId': '3db3773286ee59', - 'cpm': 0.5, - 'creativeId': 29681110, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '', - 'mediaType': 'banner', - 'currency': 'USD', - 'ttl': 300, - 'netRevenue': true, - 'adUnitCode': 'code', - 'adrelevantis': { - 'buyerMemberId': 958 - } - } - ]; - let bidderRequest = { - bids: [{ - bidId: '3db3773286ee59', - adUnitCode: 'code' - }] - } - let result = spec.interpretResponse({ body: response }, {bidderRequest}); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('handles nobid responses', function () { - let response = { - 'version': '0.0.1', - 'tags': [{ - 'uuid': '84ab500420319d', - 'tag_id': 5976557, - 'auction_id': '297492697822162468', - 'nobid': true - }] - }; - let bidderRequest; - - let result = spec.interpretResponse({ body: response }, {bidderRequest}); - expect(result.length).to.equal(0); - }); - - it('handles outstream video responses', function () { - let response = { - 'tags': [{ - 'uuid': '84ab500420319d', - 'ads': [{ - 'ad_type': 'video', - 'cpm': 0.500000, - 'notify_url': 'imptracker.com', - 'rtb': { - 'video': { - 'content': '' - } - }, - 'javascriptTrackers': '' - }] - }] - }; - let bidderRequest = { - bids: [{ - bidId: '84ab500420319d', - adUnitCode: 'code', - mediaTypes: { - video: { - context: 'outstream' - } - } - }] - } - - let 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'); - }); - - it('handles instream video responses', function () { - let response = { - 'tags': [{ - 'uuid': '84ab500420319d', - 'ads': [{ - 'ad_type': 'video', - 'cpm': 0.500000, - 'notify_url': 'imptracker.com', - 'rtb': { - 'video': { - 'asset_url': 'https://sample.vastURL.com/here/vid' - } - }, - 'javascriptTrackers': '' - }] - }] - }; - let bidderRequest = { - bids: [{ - bidId: '84ab500420319d', - adUnitCode: 'code', - mediaTypes: { - video: { - context: 'instream' - } - } - }] - } - - let 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'); - }); - - it('handles native responses', function () { - let response1 = deepClone(response); - response1.tags[0].ads[0].ad_type = 'native'; - response1.tags[0].ads[0].rtb.native = { - 'title': 'Native Creative', - 'desc': 'Cool description great stuff', - 'desc2': 'Additional body text', - 'ctatext': 'Do it', - 'sponsored': 'AppNexus', - 'icon': { - 'width': 0, - 'height': 0, - 'url': 'https://cdn.adnxs.com/icon.png' - }, - 'main_img': { - 'width': 2352, - 'height': 1516, - 'url': 'https://cdn.adnxs.com/img.png' - }, - 'link': { - 'url': 'https://www.appnexus.com', - 'fallback_url': '', - 'click_trackers': ['https://nym1-ib.adnxs.com/click'] - }, - 'impression_trackers': ['https://example.com'], - 'rating': '5', - 'displayurl': 'https://AppNexus.com/?url=display_url', - 'likes': '38908320', - 'downloads': '874983', - 'price': '9.99', - 'saleprice': 'FREE', - 'phone': '1234567890', - 'address': '28 W 23rd St, New York, NY 10010', - 'privacy_link': 'https://appnexus.com/?url=privacy_url', - 'javascriptTrackers': '' - }; - let bidderRequest = { - bids: [{ - bidId: '3db3773286ee59', - adUnitCode: 'code' - }] - } - - let 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'); - expect(result[0].native.image.url).to.equal('https://cdn.adnxs.com/img.png'); - }); - - it('supports configuring outstream renderers', function () { - const outstreamResponse = deepClone(response); - outstreamResponse.tags[0].ads[0].rtb.video = {}; - outstreamResponse.tags[0].ads[0].renderer_url = 'renderer.js'; - - const bidderRequest = { - bids: [{ - bidId: '3db3773286ee59', - renderer: { - options: { - adText: 'configured' - } - }, - mediaTypes: { - video: { - context: 'outstream' - } - } - }] - }; - - const result = spec.interpretResponse({ body: outstreamResponse }, {bidderRequest}); - expect(result[0].renderer.config).to.deep.equal( - bidderRequest.bids[0].renderer.options - ); - }); - - it('should add deal_priority and deal_code', function() { - let responseWithDeal = deepClone(response); - responseWithDeal.tags[0].ads[0].deal_priority = 'high'; - responseWithDeal.tags[0].ads[0].deal_code = '123'; - - let bidderRequest = { - bids: [{ - bidId: '3db3773286ee59', - adUnitCode: 'code' - }] - } - let result = spec.interpretResponse({ body: responseWithDeal }, {bidderRequest}); - expect(Object.keys(result[0].adrelevantis)).to.include.members(['buyerMemberId', 'dealPriority', 'dealCode']); - }); - - it('should add advertiser id', function() { - let responseAdvertiserId = deepClone(response); - responseAdvertiserId.tags[0].ads[0].advertiser_id = '123'; - - let bidderRequest = { - bids: [{ - bidId: '3db3773286ee59', - adUnitCode: 'code' - }] - } - let result = spec.interpretResponse({ body: responseAdvertiserId }, {bidderRequest}); - expect(Object.keys(result[0].meta)).to.include.members(['advertiserId']); - }) - }); -}); diff --git a/test/spec/modules/adriverBidAdapter_spec.js b/test/spec/modules/adriverBidAdapter_spec.js deleted file mode 100644 index c16bc5df5cb..00000000000 --- a/test/spec/modules/adriverBidAdapter_spec.js +++ /dev/null @@ -1,323 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/adriverBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import * as bidderFactory from 'src/adapters/bidderFactory.js'; -import { auctionManager } from 'src/auctionManager.js'; -const ENDPOINT = 'https://pb.adriver.ru/cgi-bin/bid.cgi'; - -describe('adriverAdapter', 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 () { - let bid = { - 'bidder': 'adriver', - 'params': { - 'placementId': '55:test_placement', - 'siteid': 'testSiteID' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600], [300, 250]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - }); - - describe('buildRequests', function () { - let getAdUnitsStub; - const floor = 3; - - let bidRequests = [ - { - 'bidder': 'adriver', - 'params': { - 'placementId': '55:test_placement', - 'siteid': 'testSiteID', - 'dealid': 'dealidTest' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600], [300, 250]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'transactionId': '04f2659e-c005-4eb1-a57c-fa93145e3843' - } - ]; - - let floorTestData = { - 'currency': 'USD', - 'floor': floor - }; - bidRequests[0].getFloor = _ => { - return floorTestData; - }; - - beforeEach(function() { - getAdUnitsStub = sinon.stub(auctionManager, 'getAdUnits').callsFake(function() { - return []; - }); - }); - - afterEach(function() { - getAdUnitsStub.restore(); - }); - - it('should exist currency', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - - expect(payload.cur).to.exist; - }); - - it('should exist at', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - - expect(payload.at).to.exist; - expect(payload.at).to.deep.equal(1); - }); - - it('should parse imp', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - - expect(payload.imp[0]).to.exist; - expect(payload.imp[0].id).to.deep.equal('55:test_placement'); - - expect(payload.imp[0].ext).to.exist; - expect(payload.imp[0].ext.query).to.deep.equal('bn=15&custom=111=' + '30b31c1838de1e'); - - expect(payload.imp[0].banner).to.exist; - expect(payload.imp[0].banner.w).to.deep.equal(300); - expect(payload.imp[0].banner.h).to.deep.equal(250); - }); - - it('should parse pmp', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - - expect(payload.imp[0].pmp).to.exist; - - expect(payload.imp[0].pmp.deals).to.exist; - - expect(payload.imp[0].pmp.deals[0].bidfloor).to.exist; - expect(payload.imp[0].pmp.deals[0].bidfloor).to.deep.equal(3); - - expect(payload.imp[0].pmp.deals[0].bidfloorcur).to.exist; - expect(payload.imp[0].pmp.deals[0].bidfloorcur).to.deep.equal('RUB'); - }); - - it('sends bid request to ENDPOINT via POST', function () { - const request = spec.buildRequests(bidRequests); - expect(request.url).to.equal(ENDPOINT); - expect(request.method).to.equal('POST'); - }); - }); - - describe('interpretResponse', function () { - let bfStub; - before(function() { - bfStub = sinon.stub(bidderFactory, 'getIabSubCategory'); - }); - - after(function() { - bfStub.restore(); - }); - - let response = { - 'id': '221594457-1615288400-1-46-', - 'bidid': 'D8JW8XU8-L5m7qFMNQGs7i1gcuPvYMEDOKsktw6e9uLy5Eebo9HftVXb0VpKj4R2dXa93i6QmRhjextJVM4y1SqodMAh5vFOb_eVkHA', - 'seatbid': [{ - 'bid': [{ - 'id': '1', - 'impid': '/19968336/header-bid-tag-0', - 'price': 4.29, - 'h': 250, - 'w': 300, - 'adid': '7121351', - 'adomain': ['http://ikea.com'], - 'nurl': 'https://ad.adriver.ru/cgi-bin/erle.cgi?expid=D8JW8XU8-L5m7qFMNQGs7i1gcuPvYMEDOKsktw6e9uLy5Eebo9HftVXb0VpKj4R2dXa93i6QmRhjextJVM4y1SqodMAh5vFOb_eVkHA&bid=7121351&wprc=4.29&tuid=-1&custom=207=/19968336/header-bid-tag-0', - 'cid': '717570', - 'ext': '2c262a7058758d' - }] - }, { - 'bid': [{ - 'id': '1', - 'impid': '/19968336/header-bid-tag-0', - 'price': 17.67, - 'h': 600, - 'w': 300, - 'adid': '7121369', - 'adomain': ['http://ikea.com'], - 'nurl': 'https://ad.adriver.ru/cgi-bin/erle.cgi?expid=DdtToXX5cpTaMMxrJSEsOsUIXt3WmC3jOvuNI5DguDrY8edFG60Jg1M-iMkVNKQ4OiAdHSLPJLQQXMUXZfI9VbjMoGCb-zzOTPiMpshI&bid=7121369&wprc=17.67&tuid=-1&custom=207=/19968336/header-bid-tag-0', - 'cid': '717570', - 'ext': '2c262a7058758d' - }] - }], - 'cur': 'RUB' - }; - - it('should get correct bid response', function () { - let expectedResponse = [ - { - requestId: '2c262a7058758d', - cpm: 4.29, - width: 300, - height: 250, - creativeId: '/19968336/header-bid-tag-0', - currency: 'RUB', - netRevenue: true, - ttl: 3000, - meta: { - advertiserDomains: ['http://ikea.com'] - }, - ad: '' - } - ]; - let bidderRequest = { - bids: [{ - bidId: '3db3773286ee59', - adUnitCode: 'code' - }] - }; - let result = spec.interpretResponse({ body: response }, {bidderRequest}); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('handles nobid responses', function () { - let response = { - 'version': '0.0.1', - 'tags': [{ - 'uuid': '84ab500420319d', - 'tag_id': 5976557, - 'auction_id': '297492697822162468', - 'nobid': true - }] - }; - let bidderRequest; - - let result = spec.interpretResponse({ body: response }, {bidderRequest}); - expect(result.length).to.equal(0); - }); - }); - - describe('function _getFloor', function () { - let bidRequests = [ - { - bidder: 'adriver', - params: { - placementId: '55:test_placement', - siteid: 'testSiteID', - dealid: 'dealidTest', - }, - adUnitCode: 'adunit-code', - sizes: [[300, 250], [300, 600], [300, 250]], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - transactionId: '04f2659e-c005-4eb1-a57c-fa93145e3843' - } - ]; - - const floorTestData = { - 'currency': 'RUB', - 'floor': 1.50 - }; - - const bitRequestStandard = JSON.parse(JSON.stringify(bidRequests)); - - bitRequestStandard[0].getFloor = () => { - return floorTestData; - }; - - it('valid BidRequests', function () { - const request = spec.buildRequests(bitRequestStandard); - const payload = JSON.parse(request.data); - - expect(typeof bitRequestStandard[0].getFloor).to.equal('function'); - expect(payload.imp[0].bidfloor).to.equal(1.50); - expect(payload.imp[0].bidfloorcur).to.equal('RUB'); - }); - - const bitRequestEmptyCurrency = JSON.parse(JSON.stringify(bidRequests)); - - const floorTestDataEmptyCurrency = { - 'currency': 'RUB', - 'floor': 1.50 - }; - - bitRequestEmptyCurrency[0].getFloor = () => { - return floorTestDataEmptyCurrency; - }; - - it('empty currency', function () { - const request = spec.buildRequests(bitRequestEmptyCurrency); - const payload = JSON.parse(request.data); - - expect(payload.imp[0].bidfloor).to.equal(1.50); - expect(payload.imp[0].bidfloorcur).to.equal('RUB'); - }); - - const bitRequestFloorNull = JSON.parse(JSON.stringify(bidRequests)); - - const floorTestDataFloorNull = { - 'currency': '', - 'floor': null - }; - - bitRequestFloorNull[0].getFloor = () => { - return floorTestDataFloorNull; - }; - - it('empty floor', function () { - const request = spec.buildRequests(bitRequestFloorNull); - const payload = JSON.parse(request.data); - - expect(payload.imp[0].bidfloor).to.equal(0); - }); - - const bitRequestGetFloorNotFunction = JSON.parse(JSON.stringify(bidRequests)); - - bitRequestGetFloorNotFunction[0].getFloor = 0; - - it('bid.getFloor is not a function', function () { - const request = spec.buildRequests(bitRequestGetFloorNotFunction); - const payload = JSON.parse(request.data); - - expect(payload.imp[0].bidfloor).to.equal(0); - expect(payload.imp[0].bidfloorcur).to.equal('RUB'); - }); - - const bitRequestGetFloorBySized = JSON.parse(JSON.stringify(bidRequests)); - - bitRequestGetFloorBySized[0].getFloor = (requestParams = {currency: 'USD', mediaType: '*', size: '*'}) => { - if (requestParams.size.length === 2 && requestParams.size[0] === 300 && requestParams.size[1] === 250) { - return { - 'currency': 'RUB', - 'floor': 3.33 - } - } else { - return {} - } - }; - - it('bid.getFloor get size', function () { - const request = spec.buildRequests(bitRequestGetFloorBySized); - const payload = JSON.parse(request.data); - - expect(payload.imp[0].bidfloor).to.equal(3.33); - expect(payload.imp[0].bidfloorcur).to.equal('RUB'); - expect(payload.imp[0].bidfloorcur).to.equal('RUB'); - }); - }); -}); diff --git a/test/spec/modules/adtargetBidAdapter_spec.js b/test/spec/modules/adtargetBidAdapter_spec.js deleted file mode 100644 index 5a867e7dd52..00000000000 --- a/test/spec/modules/adtargetBidAdapter_spec.js +++ /dev/null @@ -1,338 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/adtargetBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import { config } from 'src/config.js'; - -const DISPLAY_REQUEST = { - 'bidder': 'adtarget', - 'params': { - 'aid': 12345 - }, - 'schain': { ver: 1 }, - 'userId': { criteo: 2 }, - 'mediaTypes': { 'banner': { 'sizes': [300, 250] } }, - 'bidderRequestId': '7101db09af0db2', - 'auctionId': '2e41f65424c87c', - 'adUnitCode': 'adunit-code', - 'bidId': '84ab500420319d', -}; - -const VIDEO_REQUEST = { - 'bidder': 'adtarget', - 'mediaTypes': { - 'video': { - 'playerSize': [[480, 360], [640, 480]] - } - }, - 'params': { - 'aid': 12345 - }, - 'bidderRequestId': '7101db09af0db2', - 'auctionId': '2e41f65424c87c', - 'adUnitCode': 'adunit-code', - 'bidId': '84ab500420319d' -}; - -const SERVER_VIDEO_RESPONSE = { - 'source': { 'aid': 12345, 'pubId': 54321 }, - 'bids': [{ - 'vastUrl': 'https://rtb.adtarget.com/vast/?adid=44F2AEB9BFC881B3', - 'requestId': '2e41f65424c87c', - 'url': '44F2AEB9BFC881B3', - 'creative_id': 342516, - 'durationSeconds': 30, - 'cmpId': 342516, - 'height': 480, - 'cur': 'USD', - 'width': 640, - 'cpm': 0.9 - }] -}; -const SERVER_DISPLAY_RESPONSE = { - 'source': { 'aid': 12345, 'pubId': 54321 }, - 'bids': [{ - 'ad': '', - 'requestId': '2e41f65424c87c', - 'creative_id': 342516, - 'cmpId': 342516, - 'height': 250, - 'cur': 'USD', - 'width': 300, - 'cpm': 0.9 - }], - 'cookieURLs': ['link1', 'link2'] -}; -const SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS = { - 'source': { 'aid': 12345, 'pubId': 54321 }, - 'bids': [{ - 'ad': '', - 'requestId': '2e41f65424c87c', - 'creative_id': 342516, - 'cmpId': 342516, - 'height': 250, - 'cur': 'USD', - 'width': 300, - 'cpm': 0.9 - }], - 'cookieURLs': ['link3', 'link4'], - 'cookieURLSTypes': ['image', 'iframe'] -}; -const videoBidderRequest = { - bidderCode: 'bidderCode', - bids: [{ mediaTypes: { video: {} }, bidId: '2e41f65424c87c' }] -}; - -const displayBidderRequest = { - bidderCode: 'bidderCode', - bids: [{ bidId: '2e41f65424c87c' }] -}; - -const displayBidderRequestWithConsents = { - bidderCode: 'bidderCode', - bids: [{ bidId: '2e41f65424c87c' }], - gdprConsent: { - gdprApplies: true, - consentString: 'test' - }, - uspConsent: 'iHaveIt' -}; - -const videoEqResponse = [{ - vastUrl: 'https://rtb.adtarget.com/vast/?adid=44F2AEB9BFC881B3', - requestId: '2e41f65424c87c', - creativeId: 342516, - mediaType: 'video', - netRevenue: true, - currency: 'USD', - height: 480, - width: 640, - ttl: 300, - cpm: 0.9 -}]; - -const displayEqResponse = [{ - requestId: '2e41f65424c87c', - creativeId: 342516, - mediaType: 'banner', - netRevenue: true, - currency: 'USD', - ad: '', - height: 250, - width: 300, - ttl: 300, - cpm: 0.9 -}]; - -describe('adtargetBidAdapter', () => { - const adapter = newBidder(spec); - describe('inherited functions', () => { - it('exists and is a function', () => { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('user syncs', () => { - describe('as image', () => { - it('should be returned if pixel enabled', () => { - const syncs = spec.getUserSyncs({ pixelEnabled: true }, [{ body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS }]); - - expect(syncs.map(s => s.url)).to.deep.equal([SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS.cookieURLs[0]]); - expect(syncs.map(s => s.type)).to.deep.equal(['image']); - }) - }) - - describe('as iframe', () => { - it('should be returned if iframe enabled', () => { - const syncs = spec.getUserSyncs({ iframeEnabled: true }, [{ body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS }]); - - expect(syncs.map(s => s.url)).to.deep.equal([SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS.cookieURLs[1]]); - expect(syncs.map(s => s.type)).to.deep.equal(['iframe']); - }) - }) - - describe('user sync', () => { - it('should not be returned if passed syncs where already used', () => { - const syncs = spec.getUserSyncs({ - iframeEnabled: true, - pixelEnabled: true - }, [{ body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS }]); - - expect(syncs).to.deep.equal([]); - }) - - it('should not be returned if pixel not set', () => { - const syncs = spec.getUserSyncs({}, [{ body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS }]); - - expect(syncs).to.be.empty; - }); - }); - describe('user syncs with both types', () => { - it('should be returned if pixel and iframe enabled', () => { - const mockedServerResponse = Object.assign({}, SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS, { 'cookieURLs': ['link5', 'link6'] }); - const syncs = spec.getUserSyncs({ - iframeEnabled: true, - pixelEnabled: true - }, [{ body: mockedServerResponse }]); - - expect(syncs.map(s => s.url)).to.deep.equal(mockedServerResponse.cookieURLs); - expect(syncs.map(s => s.type)).to.deep.equal(mockedServerResponse.cookieURLSTypes); - }); - }); - }); - - describe('isBidRequestValid', () => { - it('should return true when required params found', () => { - expect(spec.isBidRequestValid(VIDEO_REQUEST)).to.equal(true); - }); - - it('should return false when required params are not passed', () => { - let bid = Object.assign({}, VIDEO_REQUEST); - delete bid.params; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', () => { - let videoBidRequests = [VIDEO_REQUEST]; - let displayBidRequests = [DISPLAY_REQUEST]; - let videoAndDisplayBidRequests = [DISPLAY_REQUEST, VIDEO_REQUEST]; - const displayRequest = spec.buildRequests(displayBidRequests, {}); - const videoRequest = spec.buildRequests(videoBidRequests, {}); - const videoAndDisplayRequests = spec.buildRequests(videoAndDisplayBidRequests, {}); - - it('building requests as arrays', () => { - expect(videoRequest).to.be.a('array'); - expect(displayRequest).to.be.a('array'); - expect(videoAndDisplayRequests).to.be.a('array'); - }) - - it('sending as POST', () => { - const postActionMethod = 'POST' - const comparator = br => br.method === postActionMethod; - expect(videoRequest.every(comparator)).to.be.true; - expect(displayRequest.every(comparator)).to.be.true; - expect(videoAndDisplayRequests.every(comparator)).to.be.true; - }); - - it('sends correct video bid parameters', () => { - const data = videoRequest[0].data; - - const eq = { - CallbackId: '84ab500420319d', - AdType: 'video', - Aid: 12345, - Sizes: '480x360,640x480' - }; - expect(data.BidRequests[0]).to.deep.equal(eq); - }); - - it('sends correct display bid parameters', () => { - const data = displayRequest[0].data; - - const eq = { - CallbackId: '84ab500420319d', - AdType: 'display', - Aid: 12345, - Sizes: '300x250' - }; - - expect(data.BidRequests[0]).to.deep.equal(eq); - }); - - it('sends correct video and display bid parameters', () => { - const bidRequests = videoAndDisplayRequests[0].data; - const expectedBidReqs = [{ - CallbackId: '84ab500420319d', - AdType: 'display', - Aid: 12345, - Sizes: '300x250' - }, { - CallbackId: '84ab500420319d', - AdType: 'video', - Aid: 12345, - Sizes: '480x360,640x480' - }] - - expect(bidRequests.BidRequests).to.deep.equal(expectedBidReqs); - }); - - describe('publisher environment', () => { - const sandbox = sinon.sandbox.create(); - sandbox.stub(config, 'getConfig').callsFake((key) => { - const config = { - 'coppa': true - }; - return config[key]; - }); - const bidRequestWithPubSettingsData = spec.buildRequests([DISPLAY_REQUEST], displayBidderRequestWithConsents)[0].data; - sandbox.restore(); - it('sets GDPR', () => { - expect(bidRequestWithPubSettingsData.GDPR).to.be.equal(1); - expect(bidRequestWithPubSettingsData.GDPRConsent).to.be.equal(displayBidderRequestWithConsents.gdprConsent.consentString); - }); - it('sets USP', () => { - expect(bidRequestWithPubSettingsData.USP).to.be.equal(displayBidderRequestWithConsents.uspConsent); - }) - it('sets Coppa', () => { - expect(bidRequestWithPubSettingsData.Coppa).to.be.equal(1); - }) - it('sets Schain', () => { - expect(bidRequestWithPubSettingsData.Schain).to.be.deep.equal(DISPLAY_REQUEST.schain); - }) - it('sets UserId\'s', () => { - expect(bidRequestWithPubSettingsData.UserIds).to.be.deep.equal(DISPLAY_REQUEST.userId); - }) - }) - }); - - describe('interpretResponse', () => { - let serverResponse; - let adapterRequest; - let eqResponse; - - afterEach(() => { - serverResponse = null; - adapterRequest = null; - eqResponse = null; - }); - - it('should get correct video bid response', () => { - serverResponse = SERVER_VIDEO_RESPONSE; - adapterRequest = videoBidderRequest; - eqResponse = videoEqResponse; - - bidServerResponseCheck(); - }); - - it('should get correct display bid response', () => { - serverResponse = SERVER_DISPLAY_RESPONSE; - adapterRequest = displayBidderRequest; - eqResponse = displayEqResponse; - - bidServerResponseCheck(); - }); - - function bidServerResponseCheck() { - const result = spec.interpretResponse({ body: serverResponse }, { adapterRequest }); - - expect(result).to.deep.equal(eqResponse); - } - - function nobidServerResponseCheck() { - const noBidServerResponse = { bids: [] }; - const noBidResult = spec.interpretResponse({ body: noBidServerResponse }, { adapterRequest }); - - expect(noBidResult.length).to.equal(0); - } - - it('handles video nobid responses', () => { - adapterRequest = videoBidderRequest; - nobidServerResponseCheck(); - }); - - it('handles display nobid responses', () => { - adapterRequest = displayBidderRequest; - nobidServerResponseCheck(); - }); - }); -}); diff --git a/test/spec/modules/adtelligentBidAdapter_spec.js b/test/spec/modules/adtelligentBidAdapter_spec.js deleted file mode 100644 index e6916997133..00000000000 --- a/test/spec/modules/adtelligentBidAdapter_spec.js +++ /dev/null @@ -1,434 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/adtelligentBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import { config } from 'src/config.js'; -import { deepClone } from 'src/utils.js'; - -const EXPECTED_ENDPOINTS = [ - 'https://ghb.adtelligent.com/v2/auction/', - 'https://ghb1.adtelligent.com/v2/auction/', - 'https://ghb2.adtelligent.com/v2/auction/', - 'https://ghb.adtelligent.com/v2/auction/' -]; -const aliasEP = { - appaloosa: 'https://ghb.hb.appaloosa.media/v2/auction/', - appaloosa_publisherSuffix: 'https://ghb.hb.appaloosa.media/v2/auction/', - onefiftytwomedia: 'https://ghb.ads.152media.com/v2/auction/', - mediafuse: 'https://ghb.hbmp.mediafuse.com/v2/auction/', - navelix: 'https://ghb.hb.navelix.com/v2/auction/', - bidsxchange: 'https://ghb.hbd.bidsxchange.com/v2/auction/', -}; - -const DEFAULT_ADATPER_REQ = { bidderCode: 'adtelligent' }; -const DISPLAY_REQUEST = { - 'bidder': 'adtelligent', - 'params': { - 'aid': 12345 - }, - 'schain': { ver: 1 }, - 'userId': { criteo: 2 }, - 'mediaTypes': { 'banner': { 'sizes': [300, 250] } }, - 'bidderRequestId': '7101db09af0db2', - 'auctionId': '2e41f65424c87c', - 'adUnitCode': 'adunit-code', - 'bidId': '84ab500420319d', -}; - -const VIDEO_REQUEST = { - 'bidder': 'adtelligent', - 'mediaTypes': { - 'video': { - 'playerSize': [[480, 360], [640, 480]] - } - }, - 'params': { - 'aid': 12345 - }, - 'bidderRequestId': '7101db09af0db2', - 'auctionId': '2e41f65424c87c', - 'adUnitCode': 'adunit-code', - 'bidId': '84ab500420319d' -}; - -const ADPOD_REQUEST = { - 'bidder': 'adtelligent', - 'mediaTypes': { - 'video': { - 'context': 'adpod', - 'playerSize': [[640, 480]], - 'anyField': 10 - } - }, - 'params': { - 'aid': 12345 - }, - 'bidderRequestId': '7101db09af0db2', - 'auctionId': '2e41f65424c87c', - 'adUnitCode': 'adunit-code', - 'bidId': '2e41f65424c87c' -}; - -const SERVER_VIDEO_RESPONSE = { - 'source': { 'aid': 12345, 'pubId': 54321 }, - 'bids': [{ - 'vastUrl': 'http://rtb.adtelligent.com/vast/?adid=44F2AEB9BFC881B3', - 'requestId': '2e41f65424c87c', - 'url': '44F2AEB9BFC881B3', - 'creative_id': 342516, - 'durationSeconds': 30, - 'cmpId': 342516, - 'height': 480, - 'cur': 'USD', - 'width': 640, - 'cpm': 0.9 - } - ] -}; -const SERVER_OUSTREAM_VIDEO_RESPONSE = SERVER_VIDEO_RESPONSE; -const SERVER_DISPLAY_RESPONSE = { - 'source': { 'aid': 12345, 'pubId': 54321 }, - 'bids': [{ - 'ad': '', - 'adUrl': 'adUrl', - 'requestId': '2e41f65424c87c', - 'creative_id': 342516, - 'cmpId': 342516, - 'height': 250, - 'cur': 'USD', - 'width': 300, - 'cpm': 0.9 - }], - 'cookieURLs': ['link1', 'link2'] -}; -const SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS = { - 'source': { 'aid': 12345, 'pubId': 54321 }, - 'bids': [{ - 'ad': '', - 'requestId': '2e41f65424c87c', - 'creative_id': 342516, - 'cmpId': 342516, - 'height': 250, - 'cur': 'USD', - 'width': 300, - 'cpm': 0.9 - }], - 'cookieURLs': ['link3', 'link4'], - 'cookieURLSTypes': ['image', 'iframe'] -}; -const outstreamVideoBidderRequest = { - bidderCode: 'bidderCode', - bids: [{ - 'params': { - 'aid': 12345, - 'outstream': { - 'video_controls': 'show' - } - }, - mediaTypes: { - video: { - context: 'outstream', - playerSize: [640, 480] - } - }, - bidId: '2e41f65424c87c' - }] -}; -const videoBidderRequest = { - bidderCode: 'bidderCode', - bids: [{ mediaTypes: { video: {} }, bidId: '2e41f65424c87c' }] -}; - -const displayBidderRequest = { - bidderCode: 'bidderCode', - bids: [{ bidId: '2e41f65424c87c' }] -}; - -const displayBidderRequestWithConsents = { - bidderCode: 'bidderCode', - bids: [{ bidId: '2e41f65424c87c' }], - gdprConsent: { - gdprApplies: true, - consentString: 'test' - }, - uspConsent: 'iHaveIt' -}; - -const videoEqResponse = [{ - vastUrl: 'http://rtb.adtelligent.com/vast/?adid=44F2AEB9BFC881B3', - requestId: '2e41f65424c87c', - creativeId: 342516, - mediaType: 'video', - netRevenue: true, - currency: 'USD', - height: 480, - width: 640, - ttl: 300, - cpm: 0.9 -}]; - -const displayEqResponse = [{ - requestId: '2e41f65424c87c', - creativeId: 342516, - mediaType: 'banner', - netRevenue: true, - currency: 'USD', - ad: '', - adUrl: 'adUrl', - height: 250, - width: 300, - ttl: 300, - cpm: 0.9 -}]; - -describe('adtelligentBidAdapter', () => { - const adapter = newBidder(spec); - describe('inherited functions', () => { - it('exists and is a function', () => { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('user syncs', () => { - describe('as image', () => { - it('should be returned if pixel enabled', () => { - const syncs = spec.getUserSyncs({ pixelEnabled: true }, [{ body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS }]); - - expect(syncs.map(s => s.url)).to.deep.equal([SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS.cookieURLs[0]]); - expect(syncs.map(s => s.type)).to.deep.equal(['image']); - }) - }) - - describe('as iframe', () => { - it('should be returned if iframe enabled', () => { - const syncs = spec.getUserSyncs({ iframeEnabled: true }, [{ body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS }]); - - expect(syncs.map(s => s.url)).to.deep.equal([SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS.cookieURLs[1]]); - expect(syncs.map(s => s.type)).to.deep.equal(['iframe']); - }) - }) - - describe('user sync', () => { - it('should not be returned if passed syncs where already used', () => { - const syncs = spec.getUserSyncs({ - iframeEnabled: true, - pixelEnabled: true - }, [{ body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS }]); - - expect(syncs).to.deep.equal([]); - }) - - it('should not be returned if pixel not set', () => { - const syncs = spec.getUserSyncs({}, [{ body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS }]); - - expect(syncs).to.be.empty; - }); - }); - describe('user syncs with both types', () => { - it('should be returned if pixel and iframe enabled', () => { - const mockedServerResponse = Object.assign({}, SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS, { 'cookieURLs': ['link5', 'link6'] }); - const syncs = spec.getUserSyncs({ - iframeEnabled: true, - pixelEnabled: true - }, [{ body: mockedServerResponse }]); - - expect(syncs.map(s => s.url)).to.deep.equal(mockedServerResponse.cookieURLs); - expect(syncs.map(s => s.type)).to.deep.equal(mockedServerResponse.cookieURLSTypes); - }); - }); - }); - - describe('isBidRequestValid', () => { - it('should return true when required params found', () => { - expect(spec.isBidRequestValid(VIDEO_REQUEST)).to.equal(true); - }); - - it('should return false when required params are not passed', () => { - let bid = Object.assign({}, VIDEO_REQUEST); - delete bid.params; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', () => { - let videoBidRequests = [VIDEO_REQUEST]; - let displayBidRequests = [DISPLAY_REQUEST]; - let videoAndDisplayBidRequests = [DISPLAY_REQUEST, VIDEO_REQUEST]; - const displayRequest = spec.buildRequests(displayBidRequests, DEFAULT_ADATPER_REQ); - const videoRequest = spec.buildRequests(videoBidRequests, DEFAULT_ADATPER_REQ); - const videoAndDisplayRequests = spec.buildRequests(videoAndDisplayBidRequests, DEFAULT_ADATPER_REQ); - const rotatingRequest = spec.buildRequests(displayBidRequests, DEFAULT_ADATPER_REQ); - it('rotates endpoints', () => { - const bidReqUrls = [displayRequest[0], videoRequest[0], videoAndDisplayRequests[0], rotatingRequest[0]].map(br => br.url); - expect(bidReqUrls).to.deep.equal(EXPECTED_ENDPOINTS); - }) - - it('makes correct host for aliases', () => { - for (const alias in aliasEP) { - const bidReq = deepClone(DISPLAY_REQUEST) - bidReq.bidder = alias; - const [bidderRequest] = spec.buildRequests([bidReq], { bidderCode: alias }); - expect(bidderRequest.url).to.equal(aliasEP[alias]); - } - }) - - it('building requests as arrays', () => { - expect(videoRequest).to.be.a('array'); - expect(displayRequest).to.be.a('array'); - expect(videoAndDisplayRequests).to.be.a('array'); - }) - - it('sending as POST', () => { - const postActionMethod = 'POST' - const comparator = br => br.method === postActionMethod; - expect(videoRequest.every(comparator)).to.be.true; - expect(displayRequest.every(comparator)).to.be.true; - expect(videoAndDisplayRequests.every(comparator)).to.be.true; - }); - it('forms correct ADPOD request', () => { - const pbBidReqData = spec.buildRequests([ADPOD_REQUEST], DEFAULT_ADATPER_REQ)[0].data; - const impRequest = pbBidReqData.BidRequests[0] - expect(impRequest.AdType).to.be.equal('video'); - expect(impRequest.Adpod).to.be.a('object'); - expect(impRequest.Adpod.anyField).to.be.equal(10); - }) - it('sends correct video bid parameters', () => { - const data = videoRequest[0].data; - - const eq = { - CallbackId: '84ab500420319d', - AdType: 'video', - Aid: 12345, - Sizes: '480x360,640x480', - PlacementId: 'adunit-code' - }; - expect(data.BidRequests[0]).to.deep.equal(eq); - }); - - it('sends correct display bid parameters', () => { - const data = displayRequest[0].data; - - const eq = { - CallbackId: '84ab500420319d', - AdType: 'display', - Aid: 12345, - Sizes: '300x250', - PlacementId: 'adunit-code' - }; - - expect(data.BidRequests[0]).to.deep.equal(eq); - }); - - it('sends correct video and display bid parameters', () => { - const bidRequests = videoAndDisplayRequests[0].data; - const expectedBidReqs = [{ - CallbackId: '84ab500420319d', - AdType: 'display', - Aid: 12345, - Sizes: '300x250', - PlacementId: 'adunit-code' - }, { - CallbackId: '84ab500420319d', - AdType: 'video', - Aid: 12345, - Sizes: '480x360,640x480', - PlacementId: 'adunit-code' - }] - - expect(bidRequests.BidRequests).to.deep.equal(expectedBidReqs); - }); - - describe('publisher environment', () => { - const sandbox = sinon.sandbox.create(); - sandbox.stub(config, 'getConfig').callsFake((key) => { - const config = { - 'coppa': true - }; - return config[key]; - }); - const bidRequestWithPubSettingsData = spec.buildRequests([DISPLAY_REQUEST], displayBidderRequestWithConsents)[0].data; - sandbox.restore(); - it('sets GDPR', () => { - expect(bidRequestWithPubSettingsData.GDPR).to.be.equal(1); - expect(bidRequestWithPubSettingsData.GDPRConsent).to.be.equal(displayBidderRequestWithConsents.gdprConsent.consentString); - }); - it('sets USP', () => { - expect(bidRequestWithPubSettingsData.USP).to.be.equal(displayBidderRequestWithConsents.uspConsent); - }) - it('sets Coppa', () => { - expect(bidRequestWithPubSettingsData.Coppa).to.be.equal(1); - }) - it('sets Schain', () => { - expect(bidRequestWithPubSettingsData.Schain).to.be.deep.equal(DISPLAY_REQUEST.schain); - }) - it('sets UserId\'s', () => { - expect(bidRequestWithPubSettingsData.UserIds).to.be.deep.equal(DISPLAY_REQUEST.userId); - }) - }) - }); - - describe('interpretResponse', () => { - let serverResponse; - let adapterRequest; - let eqResponse; - - afterEach(() => { - serverResponse = null; - adapterRequest = null; - eqResponse = null; - }); - - it('should get correct video bid response', () => { - serverResponse = SERVER_VIDEO_RESPONSE; - adapterRequest = videoBidderRequest; - eqResponse = videoEqResponse; - - bidServerResponseCheck(); - }); - - it('should get correct display bid response', () => { - serverResponse = SERVER_DISPLAY_RESPONSE; - adapterRequest = displayBidderRequest; - eqResponse = displayEqResponse; - - bidServerResponseCheck(); - }); - - function bidServerResponseCheck() { - const result = spec.interpretResponse({ body: serverResponse }, { adapterRequest }); - - expect(result).to.deep.equal(eqResponse); - } - - function nobidServerResponseCheck() { - const noBidServerResponse = { bids: [] }; - const noBidResult = spec.interpretResponse({ body: noBidServerResponse }, { adapterRequest }); - - expect(noBidResult.length).to.equal(0); - } - - it('handles video nobid responses', () => { - adapterRequest = videoBidderRequest; - - nobidServerResponseCheck(); - }); - - it('handles display nobid responses', () => { - adapterRequest = displayBidderRequest; - - nobidServerResponseCheck(); - }); - - it('forms correct ADPOD response', () => { - const videoBids = spec.interpretResponse({ body: SERVER_VIDEO_RESPONSE }, { adapterRequest: { bids: [ADPOD_REQUEST] } }); - expect(videoBids[0].video.durationSeconds).to.be.equal(30); - expect(videoBids[0].video.context).to.be.equal('adpod'); - }) - describe('outstream setup', () => { - const videoBids = spec.interpretResponse({ body: SERVER_OUSTREAM_VIDEO_RESPONSE }, { adapterRequest: outstreamVideoBidderRequest }); - it('should return renderer with expected outstream params config', () => { - expect(!!videoBids[0].renderer).to.be.true; - expect(videoBids[0].renderer.getConfig().video_controls).to.equal('show'); - }) - }) - }); -}); diff --git a/test/spec/modules/adtrueBidAdapter_spec.js b/test/spec/modules/adtrueBidAdapter_spec.js deleted file mode 100644 index 8e1c872d460..00000000000 --- a/test/spec/modules/adtrueBidAdapter_spec.js +++ /dev/null @@ -1,431 +0,0 @@ -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'; - -describe('AdTrueBidAdapter', function () { - const adapter = newBidder(spec) - let bidRequests; - let bidResponses; - let bidResponses2; - beforeEach(function () { - bidRequests = [ - { - bidder: 'adtrue', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - params: { - publisherId: '1212', - zoneId: '21423', - reserve: 0.2 - }, - placementCode: 'adunit-code-1', - sizes: [[300, 250]], - bidId: '23acc48ad47af5', - requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729', - schain: { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'indirectseller.com', - 'sid': '00001', - 'hp': 1 - }, - - { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 2 - } - ] - } - } - ]; - bidResponses = { - body: { - id: '1610681506302', - seatbid: [ - { - bid: [ - { - id: '1', - impid: '201fb513ca24e9', - price: 2.880000114440918, - burl: 'https://hb.adtrue.com/prebid/win-notify?impid=1610681506302&wp=${AUCTION_PRICE}', - adm: '', - adid: '1610681506302', - adomain: [ - 'adtrue.com' - ], - cid: 'f6l0r6n', - crid: 'abc77au4', - attr: [], - w: 300, - h: 250 - } - ], - seat: 'adtrue', - group: 0 - } - ], - bidid: '1610681506302', - cur: 'USD', - ext: { - cookie_sync: [ - { - type: 1, - url: 'https://hb.adtrue.com/prebid/usersync?bidder=adtrue' - } - ] - } - } - }; - bidResponses2 = { - body: { - id: '1610681506302', - seatbid: [ - { - bid: [ - { - id: '1', - impid: '201fb513ca24e9', - price: 2.880000114440918, - burl: 'https://hb.adtrue.com/prebid/win-notify?impid=1610681506302&wp=${AUCTION_PRICE}', - adm: '', - adid: '1610681506302', - adomain: [ - 'adtrue.com' - ], - cid: 'f6l0r6n', - crid: 'abc77au4', - attr: [], - w: 300, - h: 250 - } - ], - seat: 'adtrue', - group: 0 - } - ], - bidid: '1610681506302', - cur: 'USD', - ext: { - cookie_sync: [ - { - type: 2, - url: 'https://hb.adtrue.com/prebid/usersync?bidder=adtrue&type=image' - }, - { - type: 1, - url: 'https://hb.adtrue.com/prebid/usersync?bidder=appnexus' - } - ] - } - } - }; - }); - - describe('.code', function () { - it('should return a bidder code of adtrue', function () { - expect(spec.code).to.equal('adtrue') - }) - }) - - describe('inherited functions', function () { - it('should exist and be a function', function () { - expect(adapter.callBids).to.exist.and.to.be.a('function') - }) - }) - describe('implementation', function () { - describe('Bid validations', function () { - it('valid bid case', function () { - let validBid = { - bidder: 'adtrue', - params: { - zoneId: '21423', - publisherId: '1212' - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(true); - }); - it('invalid bid case: publisherId not passed', function () { - let validBid = { - bidder: 'adtrue', - params: { - zoneId: '21423' - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(false); - }); - it('valid bid case: zoneId is not passed', function () { - let validBid = { - bidder: 'adtrue', - params: { - publisherId: '1212' - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(false); - }); - it('should return false if there are no params', () => { - const bid = { - 'bidder': 'adtrue', - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - banner: { - sizes: [[300, 250]] - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - it('should return false if there is no publisherId param', () => { - const bid = { - 'bidder': 'adtrue', - 'adUnitCode': 'adunit-code', - params: { - zoneId: '21423', - }, - 'mediaTypes': { - banner: { - sizes: [[300, 250]] - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - it('should return false if there is no zoneId param', () => { - const bid = { - 'bidder': 'adtrue', - 'adUnitCode': 'adunit-code', - params: { - publisherId: '1212', - }, - 'mediaTypes': { - banner: { - sizes: [[300, 250]] - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - it('should return true if the bid is valid', () => { - const bid = { - 'bidder': 'adtrue', - 'adUnitCode': 'adunit-code', - params: { - zoneId: '21423', - publisherId: '1212', - }, - 'mediaTypes': { - banner: { - sizes: [[300, 250]] - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - }); - describe('Request formation', function () { - it('buildRequests function should not modify original bidRequests object', function () { - let originalBidRequests = utils.deepClone(bidRequests); - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - expect(bidRequests).to.deep.equal(originalBidRequests); - }); - - it('Endpoint/method checking', function () { - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - expect(request.url).to.equal('https://hb.adtrue.com/prebid/auction'); - expect(request.method).to.equal('POST'); - }); - - it('test flag not sent when adtrueTest=true is absent in page url', function () { - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.test).to.equal(undefined); - }); - it('Request params check', function () { - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.at).to.equal(1); // auction type - expect(data.cur[0]).to.equal('USD'); // currency - expect(data.site.domain).to.be.a('string'); // domain should be set - expect(data.site.publisher.id).to.equal(bidRequests[0].params.publisherId); // publisher Id - expect(data.ext.wrapper.transactionId).to.equal(bidRequests[0].transactionId); // Prebid TransactionId - expect(data.source.tid).to.equal(bidRequests[0].transactionId); // Prebid TransactionId - expect(data.imp[0].id).to.equal(bidRequests[0].bidId); // Prebid bid id is passed as id - expect(data.imp[0].bidfloor).to.equal(bidRequests[0].params.reserve); // reverse - expect(data.imp[0].tagid).to.equal(bidRequests[0].params.zoneId); // zoneId - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(250); // height - expect(data.source.ext.schain).to.deep.equal(bidRequests[0].schain); - }); - it('Request params check with GDPR Consent', function () { - let bidRequest = { - gdprConsent: { - consentString: 'kjfdniwjnifwenrif3', - gdprApplies: true - } - }; - let request = spec.buildRequests(bidRequests, bidRequest); - let data = JSON.parse(request.data); - expect(data.user.ext.consent).to.equal('kjfdniwjnifwenrif3'); - expect(data.at).to.equal(1); // auction type - expect(data.cur[0]).to.equal('USD'); // currency - expect(data.site.domain).to.be.a('string'); // domain should be set - expect(data.site.publisher.id).to.equal(bidRequests[0].params.publisherId); // publisher Id - expect(data.ext.wrapper.transactionId).to.equal(bidRequests[0].transactionId); // Prebid TransactionId - expect(data.source.tid).to.equal(bidRequests[0].transactionId); // Prebid TransactionId - expect(data.imp[0].id).to.equal(bidRequests[0].bidId); // Prebid bid id is passed as id - expect(data.imp[0].bidfloor).to.equal(parseFloat(bidRequests[0].params.reserve)); // reverse - expect(data.imp[0].tagid).to.equal(bidRequests[0].params.zoneId); // zoneId - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(250); // height - expect(data.source.ext.schain).to.deep.equal(bidRequests[0].schain); - }); - it('Request params check with USP/CCPA Consent', function () { - let bidRequest = { - uspConsent: '1NYN' - }; - let request = spec.buildRequests(bidRequests, bidRequest); - let data = JSON.parse(request.data); - expect(data.regs.ext.us_privacy).to.equal('1NYN');// USP/CCPAs - expect(data.at).to.equal(1); // auction type - expect(data.cur[0]).to.equal('USD'); // currency - expect(data.site.domain).to.be.a('string'); // domain should be set - expect(data.site.publisher.id).to.equal(bidRequests[0].params.publisherId); // publisher Id - expect(data.ext.wrapper.transactionId).to.equal(bidRequests[0].transactionId); // Prebid TransactionId - expect(data.source.tid).to.equal(bidRequests[0].transactionId); // Prebid TransactionId - expect(data.imp[0].id).to.equal(bidRequests[0].bidId); // Prebid bid id is passed as id - expect(data.imp[0].bidfloor).to.equal(parseFloat(bidRequests[0].params.reserve)); // reverse - expect(data.imp[0].tagid).to.equal(bidRequests[0].params.zoneId); // zoneId - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(250); // height - expect(data.source.ext.schain).to.deep.equal(bidRequests[0].schain); - }); - - it('should NOT include coppa flag in bid request if coppa config is not present', () => { - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - if (data.regs) { - // in case GDPR is set then data.regs will exist - expect(data.regs.coppa).to.equal(undefined); - } else { - expect(data.regs).to.equal(undefined); - } - }); - it('should include coppa flag in bid request if coppa is set to true', () => { - let sandbox = sinon.sandbox.create(); - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - 'coppa': true - }; - return config[key]; - }); - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.regs.coppa).to.equal(1); - sandbox.restore(); - }); - it('should NOT include coppa flag in bid request if coppa is set to false', () => { - let sandbox = sinon.sandbox.create(); - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - 'coppa': false - }; - return config[key]; - }); - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - if (data.regs) { - // in case GDPR is set then data.regs will exist - expect(data.regs.coppa).to.equal(undefined); - } else { - expect(data.regs).to.equal(undefined); - } - sandbox.restore(); - }); - }); - }); - describe('Response checking', function () { - it('should check for valid response values', function () { - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - let response = spec.interpretResponse(bidResponses, request); - expect(response).to.be.an('array').with.length.above(0); - expect(response[0].requestId).to.equal(bidResponses.body.seatbid[0].bid[0].impid); - expect(response[0].width).to.equal(bidResponses.body.seatbid[0].bid[0].w); - expect(response[0].height).to.equal(bidResponses.body.seatbid[0].bid[0].h); - if (bidResponses.body.seatbid[0].bid[0].crid) { - expect(response[0].creativeId).to.equal(bidResponses.body.seatbid[0].bid[0].crid); - } else { - expect(response[0].creativeId).to.equal(bidResponses.body.seatbid[0].bid[0].id); - } - expect(response[0].currency).to.equal('USD'); - expect(response[0].ttl).to.equal(300); - expect(response[0].meta.clickUrl).to.equal('adtrue.com'); - expect(response[0].meta.advertiserDomains[0]).to.equal('adtrue.com'); - expect(response[0].ad).to.equal(bidResponses.body.seatbid[0].bid[0].adm); - expect(response[0].partnerImpId).to.equal(bidResponses.body.seatbid[0].bid[0].id); - }); - }); - describe('getUserSyncs', function () { - let sandbox; - beforeEach(function () { - sandbox = sinon.sandbox.create(); - }); - afterEach(function () { - sandbox.restore(); - }); - it('execute as per config', function () { - 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([ - { - 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' - }, - { - type: 'iframe', - url: 'https://hb.adtrue.com/prebid/usersync?bidder=appnexus&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 deleted file mode 100644 index 1e39e0cfc8b..00000000000 --- a/test/spec/modules/aduptechBidAdapter_spec.js +++ /dev/null @@ -1,502 +0,0 @@ -import { expect } from 'chai'; -import { - BIDDER_CODE, - PUBLISHER_PLACEHOLDER, - ENDPOINT_URL, - ENDPOINT_METHOD, - spec, - extractGdprFromBidderRequest, - extractParamsFromBidRequest, - extractSizesFromBidRequest, - extractTopWindowReferrerFromBidRequest, - extractTopWindowUrlFromBidRequest -} from '../../../modules/aduptechBidAdapter.js'; -import { newBidder } from '../../../src/adapters/bidderFactory.js'; - -describe('AduptechBidAdapter', () => { - describe('extractGdprFromBidderRequest', () => { - it('should handle empty bidder request', () => { - const bidderRequest = null; - expect(extractGdprFromBidderRequest(bidderRequest)).to.be.null; - }); - - it('should handle missing gdprConsent in bidder request', () => { - const bidderRequest = {}; - expect(extractGdprFromBidderRequest(bidderRequest)).to.be.null; - }); - - it('should handle gdprConsent in bidder request', () => { - const bidderRequest = { - gdprConsent: { - consentString: 'consentString', - gdprApplies: true - } - }; - - expect(extractGdprFromBidderRequest(bidderRequest)).to.deep.equal({ - consentString: bidderRequest.gdprConsent.consentString, - consentRequired: true - }); - }); - }); - - describe('extractParamsFromBidRequest', () => { - it('should handle empty bid request', () => { - const bidRequest = null; - expect(extractParamsFromBidRequest(bidRequest)).to.be.null; - }); - - it('should handle missing params in bid request', () => { - const bidRequest = {}; - expect(extractParamsFromBidRequest(bidRequest)).to.be.null; - }); - - it('should handle params in bid request', () => { - const bidRequest = { - params: { - foo: '123', - bar: 456 - } - }; - expect(extractParamsFromBidRequest(bidRequest)).to.deep.equal(bidRequest.params); - }); - }); - - describe('extractSizesFromBidRequest', () => { - it('should handle empty bid request', () => { - const bidRequest = null; - expect(extractSizesFromBidRequest(bidRequest)).to.deep.equal([]); - }); - - it('should handle missing sizes in bid request', () => { - const bidRequest = {}; - expect(extractSizesFromBidRequest(bidRequest)).to.deep.equal([]); - }); - - it('should handle sizes in bid request', () => { - const bidRequest = { - mediaTypes: { - banner: { - sizes: [[12, 34], [56, 78]] - } - } - }; - expect(extractSizesFromBidRequest(bidRequest)).to.deep.equal(bidRequest.mediaTypes.banner.sizes); - }); - - it('should handle sizes in bid request (backward compatibility)', () => { - const bidRequest = { - sizes: [[12, 34], [56, 78]] - }; - expect(extractSizesFromBidRequest(bidRequest)).to.deep.equal(bidRequest.sizes); - }); - - it('should prefer sizes in mediaTypes.banner', () => { - const bidRequest = { - sizes: [[12, 34]], - mediaTypes: { - banner: { - sizes: [[56, 78]] - } - } - }; - expect(extractSizesFromBidRequest(bidRequest)).to.deep.equal(bidRequest.mediaTypes.banner.sizes); - }); - }); - - describe('extractTopWindowReferrerFromBidRequest', () => { - it('should use fallback if bid request is empty', () => { - const bidRequest = null; - expect(extractTopWindowReferrerFromBidRequest(bidRequest)).to.equal(window.top.document.referrer); - }); - - it('should use fallback if refererInfo in bid request is missing', () => { - const bidRequest = {}; - expect(extractTopWindowReferrerFromBidRequest(bidRequest)).to.equal(window.top.document.referrer); - }); - - it('should use fallback if refererInfo.referer in bid request is missing', () => { - const bidRequest = { - refererInfo: {} - }; - expect(extractTopWindowReferrerFromBidRequest(bidRequest)).to.equal(window.top.document.referrer); - }); - - it('should use fallback if refererInfo.referer in bid request is empty', () => { - const bidRequest = { - refererInfo: { - referer: '' - } - }; - expect(extractTopWindowReferrerFromBidRequest(bidRequest)).to.equal(window.top.document.referrer); - }); - - it('should use refererInfo.referer from bid request ', () => { - const bidRequest = { - refererInfo: { - referer: 'foobar' - } - }; - expect(extractTopWindowReferrerFromBidRequest(bidRequest)).to.equal(bidRequest.refererInfo.referer); - }); - }); - - describe('extractTopWindowUrlFromBidRequest', () => { - it('should use fallback if bid request is empty', () => { - const bidRequest = null; - expect(extractTopWindowUrlFromBidRequest(bidRequest)).to.equal(window.top.location.href); - }); - - it('should use fallback if refererInfo in bid request is missing', () => { - const bidRequest = {}; - expect(extractTopWindowUrlFromBidRequest(bidRequest)).to.equal(window.top.location.href); - }); - - it('should use fallback if refererInfo.canonicalUrl in bid request is missing', () => { - const bidRequest = { - refererInfo: {} - }; - expect(extractTopWindowUrlFromBidRequest(bidRequest)).to.equal(window.top.location.href); - }); - - it('should use fallback if refererInfo.canonicalUrl in bid request is empty', () => { - const bidRequest = { - refererInfo: { - canonicalUrl: '' - } - }; - expect(extractTopWindowUrlFromBidRequest(bidRequest)).to.equal(window.top.location.href); - }); - - it('should use refererInfo.canonicalUrl from bid request ', () => { - const bidRequest = { - refererInfo: { - canonicalUrl: 'foobar' - } - }; - expect(extractTopWindowUrlFromBidRequest(bidRequest)).to.equal(bidRequest.refererInfo.canonicalUrl); - }); - }); - - describe('spec', () => { - let adapter; - - beforeEach(() => { - adapter = newBidder(spec); - }); - - describe('inherited functions', () => { - it('exists and is a function', () => { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', () => { - it('should return true when necessary information is given', () => { - expect(spec.isBidRequestValid({ - mediaTypes: { - banner: { - sizes: [[100, 200]] - } - }, - params: { - publisher: 'test', - placement: '1234' - } - })).to.be.true; - }); - - it('should return true when necessary information is given (backward compatibility)', () => { - expect(spec.isBidRequestValid({ - sizes: [[100, 200]], - params: { - publisher: 'test', - placement: '1234' - } - })).to.be.true; - }); - - it('should return false on empty bid', () => { - expect(spec.isBidRequestValid({})).to.be.false; - }); - - it('should return false on missing sizes', () => { - expect(spec.isBidRequestValid({ - params: { - publisher: 'test', - placement: '1234' - } - })).to.be.false; - }); - - it('should return false on empty sizes', () => { - expect(spec.isBidRequestValid({ - mediaTypes: { - banner: { - sizes: [] - } - }, - params: { - publisher: 'test', - placement: '1234' - } - })).to.be.false; - }); - - it('should return false on empty sizes (backward compatibility)', () => { - expect(spec.isBidRequestValid({ - sizes: [], - params: { - publisher: 'test', - placement: '1234' - } - })).to.be.false; - }); - - it('should return false on missing params', () => { - expect(spec.isBidRequestValid({ - mediaTypes: { - banner: { - sizes: [[100, 200]] - } - }, - })).to.be.false; - }); - - it('should return false on invalid params', () => { - expect(spec.isBidRequestValid({ - mediaTypes: { - banner: { - sizes: [[100, 200]] - } - }, - params: 'bar' - })).to.be.false; - }); - - it('should return false on empty params', () => { - expect(spec.isBidRequestValid({ - mediaTypes: { - banner: { - sizes: [[100, 200]] - } - }, - params: {} - })).to.be.false; - }); - - it('should return false on missing publisher', () => { - expect(spec.isBidRequestValid({ - mediaTypes: { - banner: { - sizes: [[100, 200]] - } - }, - params: { - placement: '1234' - } - })).to.be.false; - }); - - it('should return false on missing placement', () => { - expect(spec.isBidRequestValid({ - mediaTypes: { - banner: { - sizes: [[100, 200]] - } - }, - params: { - publisher: 'test' - } - })).to.be.false; - }); - }); - - describe('buildRequests', () => { - it('should send one bid request per ad unit to the endpoint via POST', () => { - const bidRequests = [ - { - bidder: BIDDER_CODE, - bidId: 'bidId1', - adUnitCode: 'adUnitCode1', - transactionId: 'transactionId1', - auctionId: 'auctionId1', - mediaTypes: { - banner: { - sizes: [[100, 200], [300, 400]] - } - }, - params: { - publisher: 'publisher1', - placement: 'placement1' - } - }, - { - bidder: BIDDER_CODE, - bidId: 'bidId2', - adUnitCode: 'adUnitCode2', - transactionId: 'transactionId2', - auctionId: 'auctionId2', - mediaTypes: { - banner: { - sizes: [[500, 600]] - } - }, - params: { - publisher: 'publisher2', - placement: 'placement2' - } - } - ]; - - const result = spec.buildRequests(bidRequests); - expect(result.length).to.equal(2); - - expect(result[0].url).to.equal(ENDPOINT_URL.replace(PUBLISHER_PLACEHOLDER, bidRequests[0].params.publisher)); - expect(result[0].method).to.equal(ENDPOINT_METHOD); - expect(result[0].data).to.deep.equal({ - bidId: bidRequests[0].bidId, - auctionId: bidRequests[0].auctionId, - transactionId: bidRequests[0].transactionId, - adUnitCode: bidRequests[0].adUnitCode, - pageUrl: extractTopWindowUrlFromBidRequest(bidRequests[0]), - referrer: extractTopWindowReferrerFromBidRequest(bidRequests[0]), - sizes: extractSizesFromBidRequest(bidRequests[0]), - params: extractParamsFromBidRequest(bidRequests[0]), - gdpr: null - }); - - expect(result[1].url).to.equal(ENDPOINT_URL.replace(PUBLISHER_PLACEHOLDER, bidRequests[1].params.publisher)); - expect(result[1].method).to.equal(ENDPOINT_METHOD); - expect(result[1].data).to.deep.equal({ - bidId: bidRequests[1].bidId, - auctionId: bidRequests[1].auctionId, - transactionId: bidRequests[1].transactionId, - adUnitCode: bidRequests[1].adUnitCode, - pageUrl: extractTopWindowUrlFromBidRequest(bidRequests[1]), - referrer: extractTopWindowReferrerFromBidRequest(bidRequests[1]), - sizes: extractSizesFromBidRequest(bidRequests[1]), - params: extractParamsFromBidRequest(bidRequests[1]), - gdpr: null - }); - }); - - it('should pass gdpr informations', () => { - const bidderRequest = { - gdprConsent: { - consentString: 'consentString', - gdprApplies: true - } - }; - - const bidRequests = [ - { - bidder: BIDDER_CODE, - bidId: 'bidId3', - adUnitCode: 'adUnitCode3', - transactionId: 'transactionId3', - auctionId: 'auctionId3', - mediaTypes: { - banner: { - sizes: [[100, 200], [300, 400]] - } - }, - params: { - publisher: 'publisher3', - placement: 'placement3' - } - } - ]; - - const result = spec.buildRequests(bidRequests, bidderRequest); - expect(result.length).to.equal(1); - expect(result[0].data.gdpr).to.deep.equal(extractGdprFromBidderRequest(bidderRequest)); - }); - - it('should encode publisher param in endpoint url', () => { - const bidRequests = [ - { - bidder: BIDDER_CODE, - bidId: 'bidId1', - adUnitCode: 'adUnitCode1', - transactionId: 'transactionId1', - auctionId: 'auctionId1', - mediaTypes: { - banner: { - sizes: [[100, 200]] - } - }, - params: { - publisher: 'crazy publisher key äÖÜ', - placement: 'placement1' - } - }, - ]; - - const result = spec.buildRequests(bidRequests); - expect(result[0].url).to.equal(ENDPOINT_URL.replace(PUBLISHER_PLACEHOLDER, encodeURIComponent(bidRequests[0].params.publisher))); - }); - - it('should handle empty bidRequests', () => { - expect(spec.buildRequests([])).to.deep.equal([]); - }); - }); - - describe('interpretResponse', () => { - it('should correctly interpret the server response', () => { - const serverResponse = { - body: { - bid: { - bidId: 'bidId1', - price: 0.12, - net: true, - currency: 'EUR', - ttl: 123 - }, - creative: { - id: 'creativeId1', - width: 100, - height: 200, - html: '
Hello World
' - } - } - }; - - const result = spec.interpretResponse(serverResponse); - expect(result).to.deep.equal([ - { - requestId: serverResponse.body.bid.bidId, - cpm: serverResponse.body.bid.price, - netRevenue: serverResponse.body.bid.net, - currency: serverResponse.body.bid.currency, - ttl: serverResponse.body.bid.ttl, - creativeId: serverResponse.body.creative.id, - width: serverResponse.body.creative.width, - height: serverResponse.body.creative.height, - ad: serverResponse.body.creative.html - } - ]); - }); - - it('should handle empty serverResponse', () => { - expect(spec.interpretResponse({})).to.deep.equal([]); - }); - - it('should handle missing bid', () => { - expect(spec.interpretResponse({ - body: { - creative: {} - } - })).to.deep.equal([]); - }); - - it('should handle missing creative', () => { - expect(spec.interpretResponse({ - body: { - bid: {} - } - })).to.deep.equal([]); - }); - }); - }); -}); diff --git a/test/spec/modules/advangelistsBidAdapter_spec.js b/test/spec/modules/advangelistsBidAdapter_spec.js deleted file mode 100755 index 2b9615fb572..00000000000 --- a/test/spec/modules/advangelistsBidAdapter_spec.js +++ /dev/null @@ -1,137 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/advangelistsBidAdapter.js'; -import { BANNER, VIDEO } from 'src/mediaTypes.js'; - -describe('advangelistsBidAdapter', function () { - let bidRequests; - 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'}]; - - bidRequestsVid = [{'bidder': 'advangelists', 'params': {'pubid': '8537f00948fc37cc03c5f0f88e198a76', 'placement': 1234, 'video': {'id': 123, 'skip': 1, 'mimes': ['video/mp4', 'application/javascript'], 'playbackmethod': [2, 6], 'maxduration': 30}}, 'crumbs': {'pubcid': '979fde13-c71e-4ac2-98b7-28c90f99b449'}, 'mediaTypes': {'video': {'playerSize': [[320, 480]], 'context': 'instream'}}, '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 () { - it('should return true when the required params are passed for banner', function () { - const bidRequest = bidRequests[0]; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }); - - it('should return true when the required params are passed for video', function () { - const bidRequests = bidRequestsVid[0]; - expect(spec.isBidRequestValid(bidRequests)).to.equal(true); - }); - - it('should return false when no pub id params are passed', function () { - const bidRequest = bidRequests[0]; - bidRequest.params.pubid = ''; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when no placement params are passed', function () { - const bidRequest = bidRequests[0]; - bidRequest.params.placement = ''; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when a bid request is not passed', function () { - expect(spec.isBidRequestValid()).to.equal(false); - expect(spec.isBidRequestValid({})).to.equal(false); - }); - }); - - describe('spec.buildRequests', function () { - it('should create a POST request for each bid', function () { - const bidRequest = bidRequests[0]; - const requests = spec.buildRequests([ bidRequest ]); - 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 ]); - expect(requests[0].method).to.equal('POST'); - }); - - it('should have domain in request', function () { - const bidRequest = bidRequests[0]; - const requests = spec.buildRequests([ bidRequest ]); - expect(requests[0].data.site.domain).length !== 0; - }); - }); - - describe('spec.interpretResponse', function () { - describe('for banner bids', function () { - it('should return no bids if the response is not valid', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { banner: {} }; - const bidResponse = spec.interpretResponse({ body: null }, { bidRequest }); - - if (typeof bidResponse !== 'undefined') { - expect(bidResponse.length).to.equal(0); - } else { - expect(true).to.equal(true); - } - }); - - it('should return no bids if the response is empty', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { banner: {} }; - const bidResponse = spec.interpretResponse({ body: [] }, { bidRequest }); - if (typeof bidResponse !== 'undefined') { - expect(bidResponse.length).to.equal(0); - } else { expect(true).to.equal(true); } - }); - - it('should return valid video bid responses', function () { - let _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.ar'], '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']; - expect(bidResponseVid).to.deep.equal({ - requestId: bidRequestsVid[0].bidId, - bidderCode: 'advangelists', - creativeId: serverResponseVid.seatbid[0].bid[0].crid, - cpm: serverResponseVid.seatbid[0].bid[0].price, - width: serverResponseVid.seatbid[0].bid[0].w, - height: serverResponseVid.seatbid[0].bid[0].h, - mediaType: 'video', - currency: 'USD', - netRevenue: true, - ttl: 60 - }); - }); - - it('should return valid banner bid responses', function () { - const advangelistsbidreq = {bids: {}}; - bidRequests.forEach(bid => { - let _mediaTypes = (bid.mediaTypes && bid.mediaTypes.video ? VIDEO : BANNER); - 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': '
', 'adomain': ['advertiserdomain.com'], 'iurl': '', 'cid': 'campaign1', 'crid': 'abcde-12345', '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({ - requestId: bidRequests[0].bidId, - ad: serverResponse.seatbid[0].bid[0].adm, - bidderCode: 'advangelists', - creativeId: serverResponse.seatbid[0].bid[0].crid, - cpm: serverResponse.seatbid[0].bid[0].price, - width: serverResponse.seatbid[0].bid[0].w, - height: serverResponse.seatbid[0].bid[0].h, - mediaType: 'banner', - currency: 'USD', - netRevenue: true, - ttl: 60 - }); - }); - }); - }); -}); diff --git a/test/spec/modules/advenueBidAdapter_spec.js b/test/spec/modules/advenueBidAdapter_spec.js deleted file mode 100644 index 2d7739361b4..00000000000 --- a/test/spec/modules/advenueBidAdapter_spec.js +++ /dev/null @@ -1,107 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/advenueBidAdapter.js'; - -describe('AdvenueAdapter', function () { - let bid = { - bidId: '2dd581a2b6281d', - bidder: 'advenue', - bidderRequestId: '145e1d6a7837c9', - params: { - placementId: 123, - traffic: 'banner' - }, - placementCode: 'placement_0', - auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', - sizes: [[300, 250]], - transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e62' - }; - - describe('isBidRequestValid', function () { - it('Should return true when placementId can be cast to a number', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false when placementId is not a number', function () { - bid.params.placementId = 'aaa'; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid]); - 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://ssp.advenuemedia.co.uk/?c=o&m=multi'); - }); - it('Returns valid data if array of bids is valid', function () { - let data = serverRequest.data; - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'secure', 'host', 'page', 'placements'); - expect(data.deviceWidth).to.be.a('number'); - expect(data.deviceHeight).to.be.a('number'); - expect(data.secure).to.be.within(0, 1); - expect(data.host).to.be.a('string'); - expect(data.page).to.be.a('string'); - let placements = data['placements']; - for (let i = 0; i < placements.length; i++) { - let placement = placements[i]; - expect(placement).to.have.all.keys('placementId', 'bidId', 'traffic', 'sizes'); - expect(placement.placementId).to.be.a('number'); - expect(placement.bidId).to.be.a('string'); - expect(placement.traffic).to.be.a('string'); - expect(placement.sizes).to.be.an('array'); - } - }); - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); - }); - describe('interpretResponse', function () { - let resObject = { - body: [ { - requestId: '123', - mediaType: 'banner', - cpm: 0.3, - width: 320, - height: 50, - ad: '

Hello ad

', - ttl: 1000, - creativeId: '123asd', - netRevenue: true, - currency: 'USD' - } ] - }; - 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++) { - let dataItem = serverResponses[i]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'mediaType'); - 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.mediaType).to.be.a('string'); - } - 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; - }); - }); - }); -}); diff --git a/test/spec/modules/advertlyBidAdapter_spec.js b/test/spec/modules/advertlyBidAdapter_spec.js deleted file mode 100755 index 7825f11948a..00000000000 --- a/test/spec/modules/advertlyBidAdapter_spec.js +++ /dev/null @@ -1,159 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/advertlyBidAdapter.js'; - -const ENDPOINT = 'https://api.advertly.com/www/admin/plugins/Prebid/getAd.php'; - -describe('The Advertly bidding adapter', function () { - describe('isBidRequestValid', function () { - it('should return false when given an invalid bid', function () { - const bid = { - bidder: 'advertly', - }; - const isValid = spec.isBidRequestValid(bid); - expect(isValid).to.equal(false); - }); - - it('should return true when given a publisherId in bid', function () { - const bid = { - bidder: 'advertly', - params: { - publisherId: 2 - }, - }; - const isValid = spec.isBidRequestValid(bid); - expect(isValid).to.equal(true); - }); - }); - - describe('buildRequests', function () { - const bidRequests = [{ - 'bidder': 'advertly', - 'params': { - 'publisherId': 2 - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ] - }]; - - const request = spec.buildRequests(bidRequests); - - it('sends bid request to our endpoint via POST', function () { - expect(request.method).to.equal('POST'); - }); - - it('check endpoint url', function () { - expect(request.url).to.equal(ENDPOINT) - }); - - it('sets the proper banner object', function () { - expect(bidRequests[0].params.publisherId).to.equal(2); - }) - }); - const response = { - body: [ - { - 'requestId': '2ee937f15015c6', - 'cpm': '0.2000', - 'width': 300, - 'height': 600, - 'creativeId': '4', - 'currency': 'USD', - 'netRevenue': true, - 'ad': 'ads.html', - 'mediaType': 'banner' - }, - { - 'requestId': '3e1af92622bdc', - 'cpm': '0.2000', - 'creativeId': '4', - 'context': 'outstream', - 'currency': 'USD', - 'netRevenue': true, - 'vastUrl': 'tezt.xml', - 'width': 640, - 'height': 480, - 'mediaType': 'video' - }] - }; - - const request = [ - { - 'bidder': 'advertly', - 'params': { - 'publisherId': 2 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [300, 600] - ] - } - }, - 'bidId': '2ee937f15015c6', - 'src': 'client', - }, - { - 'bidder': 'advertly', - 'params': { - 'publisherId': 2 - }, - 'mediaTypes': { - 'video': { - 'context': 'outstream', - 'playerSize': [ - [640, 480] - ] - } - }, - 'bidId': '3e1af92622bdc', - 'src': 'client', - } - ]; - - describe('interpretResponse', function () { - it('return empty array when no ad found', function () { - const response = {}; - const request = { bidRequests: [] }; - const bids = spec.interpretResponse(response, request); - expect(bids).to.have.lengthOf(0); - }); - - it('check response for banner and video', function () { - const bids = spec.interpretResponse(response, request); - expect(bids).to.have.lengthOf(2); - expect(bids[0].requestId).to.equal('2ee937f15015c6'); - expect(bids[0].cpm).to.equal('0.2000'); - expect(bids[1].cpm).to.equal('0.2000'); - expect(bids[0].width).to.equal(300); - expect(bids[0].height).to.equal(600); - expect(bids[1].vastUrl).to.not.equal(''); - expect(bids[0].ad).to.not.equal(''); - expect(bids[1].adResponse).to.not.equal(''); - expect(bids[1].renderer).not.to.be.an('undefined'); - }); - }); - - describe('On winning bid', function () { - const bids = spec.interpretResponse(response, request); - spec.onBidWon(bids); - }); - - describe('On bid Time out', function () { - const bids = spec.interpretResponse(response, request); - spec.onTimeout(bids); - }); - - describe('user sync', function () { - it('to check the user sync iframe', function () { - let syncs = spec.getUserSyncs({ - iframeEnabled: true - }); - expect(syncs).to.not.be.an('undefined'); - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('iframe'); - }); - }); -}); diff --git a/test/spec/modules/adxcgAnalyticsAdapter_spec.js b/test/spec/modules/adxcgAnalyticsAdapter_spec.js deleted file mode 100644 index a796e7e966d..00000000000 --- a/test/spec/modules/adxcgAnalyticsAdapter_spec.js +++ /dev/null @@ -1,207 +0,0 @@ -import adxcgAnalyticsAdapter from 'modules/adxcgAnalyticsAdapter.js'; -import { expect } from 'chai'; -import adapterManager from 'src/adapterManager.js'; -import { server } from 'test/mocks/xhr.js'; - -let events = require('src/events'); -let constants = require('src/constants.json'); - -describe('adxcg analytics adapter', function () { - beforeEach(function () { - sinon.stub(events, 'getEvents').returns([]); - }); - - afterEach(function () { - events.getEvents.restore(); - }); - - describe('track', function () { - let initOptions = { - publisherId: '42' - }; - - let auctionTimestamp = 1496510254313; - - // prepare general auction - request and response - let bidRequest = { - 'bidderCode': 'appnexus', - 'bids': [{ - 'params': { - 'placementId': '10433394' - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'transactionId': '2f481ff1-8d20-4c28-8e36-e384e9e3eec6', - 'sizes': '300x250,300x600', - 'bidId': '2eddfdc0c791dc', - 'auctionId': 'a5b849e5-87d7-4205-8300-d063084fcfb7' - } - ] - }; - - let bidResponse = { - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '2eddfdc0c791dc', - 'mediaType': 'banner', - 'source': 'client', - 'requestId': '2eddfdc0c791dc', - 'cpm': 0.5, - 'creativeId': 29681110, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'auctionId': 'a5b849e5-87d7-4205-8300-d063084fcfb7', - 'responseTimestamp': 1522265866110, - 'requestTimestamp': 1522265863600, - 'bidder': 'appnexus', - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'timeToRespond': 2510, - 'size': '300x250' - }; - - // what we expect after general auction - let expectedAfterBid = { - 'bidRequests': [ - { - 'bidderCode': 'appnexus', - 'bids': [ - { - 'transactionId': '2f481ff1-8d20-4c28-8e36-e384e9e3eec6', - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'bidId': '2eddfdc0c791dc', - 'sizes': '300x250,300x600', - 'params': { - 'placementId': '10433394' - } - } - ] - } - ], - 'bidResponses': [ - { - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'bidderCode': 'appnexus', - 'statusMessage': 'Bid available', - 'mediaType': 'banner', - 'renderedSize': '300x250', - 'cpm': 0.5, - 'currency': 'USD', - 'netRevenue': true, - 'timeToRespond': 2510, - 'bidId': '2eddfdc0c791dc', - 'creativeId': '29681110' - } - ], - 'auctionInit': {}, - 'bidTimeout': [ - 'bidderOne', - 'bidderTwo' - ] - }; - - // lets simulate that some bidders timeout - let bidTimeoutArgsV1 = [ - { - bidId: '2baa51527bd015', - bidder: 'bidderOne', - adUnitCode: '/19968336/header-bid-tag-0', - auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f' - }, - { - bidId: '6fe3b4c2c23092', - bidder: 'bidderTwo', - adUnitCode: '/19968336/header-bid-tag-0', - auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f' - } - ]; - - // now simulate some WIN and RENDERING - let wonRequest = { - 'adId': '4587fec4900b81', - 'mediaType': 'banner', - 'requestId': '4587fec4900b81', - 'cpm': 1.962, - 'creativeId': 2126, - 'currency': 'EUR', - 'netRevenue': true, - 'ttl': 302, - 'auctionId': '914bedad-b145-4e46-ba58-51365faea6cb', - 'statusMessage': 'Bid available', - 'responseTimestamp': 1530628534437, - 'requestTimestamp': 1530628534219, - 'bidder': 'testbidder4', - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'timeToRespond': 218, - 'size': '300x250', - 'status': 'rendered' - }; - - let wonExpect = { - 'bidWons': [{ - 'bidderCode': 'testbidder4', - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'mediaType': 'banner', - 'renderedSize': '300x250', - 'cpm': 1.962, - 'currency': 'EUR', - 'netRevenue': true, - 'timeToRespond': 218, - 'bidId': '4587fec4900b81', - 'statusMessage': 'Bid available', - 'status': 'rendered', - 'creativeId': '2126' - }] - }; - - adapterManager.registerAnalyticsAdapter({ - code: 'adxcg', - adapter: adxcgAnalyticsAdapter - }); - - beforeEach(function () { - adapterManager.enableAnalytics({ - provider: 'adxcg', - options: initOptions - }); - }); - - afterEach(function () { - adxcgAnalyticsAdapter.disableAnalytics(); - }); - - it('builds and sends auction data', function () { - // Step 1: Send auction init event - events.emit(constants.EVENTS.AUCTION_INIT, { - timestamp: auctionTimestamp - }); - - // Step 2: Send bid requested event - events.emit(constants.EVENTS.BID_REQUESTED, bidRequest); - - // Step 3: Send bid response event - events.emit(constants.EVENTS.BID_RESPONSE, bidResponse); - - // Step 4: Send bid time out event - events.emit(constants.EVENTS.BID_TIMEOUT, bidTimeoutArgsV1); - - // Step 5: Send auction end event - events.emit(constants.EVENTS.AUCTION_END, {}); - - expect(server.requests.length).to.equal(1); - - let realAfterBid = JSON.parse(server.requests[0].requestBody); - - expect(realAfterBid).to.deep.equal(expectedAfterBid); - - expect(realAfterBid.bidTimeout).to.deep.equal(['bidderOne', 'bidderTwo']); - - // Step 6: Send auction bid won event - events.emit(constants.EVENTS.BID_WON, wonRequest); - - expect(server.requests.length).to.equal(2); - let winEventData = JSON.parse(server.requests[1].requestBody); - - expect(winEventData).to.deep.equal(wonExpect); - }); - }); -}); diff --git a/test/spec/modules/adxcgBidAdapter_spec.js b/test/spec/modules/adxcgBidAdapter_spec.js deleted file mode 100644 index 551d50b60e7..00000000000 --- a/test/spec/modules/adxcgBidAdapter_spec.js +++ /dev/null @@ -1,653 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/adxcgBidAdapter.js'; -import {deepClone, parseUrl} from 'src/utils.js'; -import * as utils from '../../../src/utils.js'; - -describe('AdxcgAdapter', function () { - let bidBanner = { - bidder: 'adxcg', - params: { - adzoneid: '1' - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [640, 360], - [1, 1] - ] - } - }, - bidId: '84ab500420319d', - bidderRequestId: '7101db09af0db2', - auctionId: '1d1a030790a475' - }; - - let bidVideo = { - bidder: 'adxcg', - params: { - adzoneid: '20', - video: { - api: [2], - maxduration: 30 - } - }, - mediaTypes: { - video: { - context: 'instream', - playerSize: [[640, 480]], - protocols: [1, 2], - mimes: ['video/mp4'], - } - }, - adUnitCode: 'adunit-code', - bidId: '84ab500420319d', - bidderRequestId: '7101db09af0db2', - auctionId: '1d1a030790a475' - }; - - let bidNative = { - bidder: 'adxcg', - params: { - adzoneid: '2379' - }, - mediaTypes: { - native: { - image: { - sendId: false, - required: true, - sizes: [80, 80] - }, - title: { - required: true, - len: 75 - }, - body: { - required: true, - len: 200 - }, - sponsoredBy: { - required: false, - len: 20 - } - } - }, - adUnitCode: 'adunit-code', - bidId: '84ab500420319d', - bidderRequestId: '7101db09af0db2', - auctionId: '1d1a030790a475' - }; - - describe('isBidRequestValid', function () { - it('should return true when required params found bidNative', function () { - expect(spec.isBidRequestValid(bidNative)).to.equal(true); - }); - - it('should return true when required params found bidVideo', function () { - expect(spec.isBidRequestValid(bidVideo)).to.equal(true); - }); - - it('should return true when required params found bidBanner', function () { - expect(spec.isBidRequestValid(bidBanner)).to.equal(true); - }); - - it('should return false when required params not found', function () { - expect(spec.isBidRequestValid({})).to.be.false; - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bidBanner); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return true when required video params not found', function () { - const simpleVideo = JSON.parse(JSON.stringify(bidVideo)); - simpleVideo.params.adzoneid = 123; - expect(spec.isBidRequestValid(simpleVideo)).to.be.false; - }); - }); - - describe('request function http', function () { - it('creates a valid adxcg request url bidBanner', function () { - let request = spec.buildRequests([bidBanner]); - expect(request).to.exist; - expect(request.method).to.equal('GET'); - let parsedRequestUrl = parseUrl(request.url); - expect(parsedRequestUrl.hostname).to.equal('hbps.adxcg.net'); - expect(parsedRequestUrl.pathname).to.equal('/get/adi'); - - let query = parsedRequestUrl.search; - expect(query.renderformat).to.equal('javascript'); - expect(query.ver).to.equal('r20210330PB40'); - expect(query.source).to.equal('pbjs10'); - expect(query.pbjs).to.equal('$prebid.version$'); - expect(query.adzoneid).to.equal('1'); - expect(query.format).to.equal('300x250|640x360|1x1'); - expect(query.jsonp).to.be.undefined; - expect(query.prebidBidIds).to.equal('84ab500420319d'); - expect(query.bidfloors).to.equal('0'); - - expect(query).to.have.property('secure'); - expect(query).to.have.property('uw'); - expect(query).to.have.property('uh'); - expect(query).to.have.property('dpr'); - expect(query).to.have.property('bt'); - expect(query).to.have.property('cookies'); - expect(query).to.have.property('tz'); - expect(query).to.have.property('dt'); - expect(query).to.have.property('iob'); - expect(query).to.have.property('rndid'); - expect(query).to.have.property('ref'); - expect(query).to.have.property('url'); - }); - - it('creates a valid adxcg request url bidVideo', function () { - let request = spec.buildRequests([bidVideo]); - expect(request).to.exist; - expect(request.method).to.equal('GET'); - let parsedRequestUrl = parseUrl(request.url); - expect(parsedRequestUrl.hostname).to.equal('hbps.adxcg.net'); - expect(parsedRequestUrl.pathname).to.equal('/get/adi'); - - let query = parsedRequestUrl.search; - // general part - expect(query.renderformat).to.equal('javascript'); - expect(query.ver).to.equal('r20210330PB40'); - expect(query.source).to.equal('pbjs10'); - expect(query.pbjs).to.equal('$prebid.version$'); - expect(query.adzoneid).to.equal('20'); - expect(query.format).to.equal('640x480'); - expect(query.jsonp).to.be.undefined; - expect(query.prebidBidIds).to.equal('84ab500420319d'); - expect(query.bidfloors).to.equal('0'); - - expect(query).to.have.property('secure'); - expect(query).to.have.property('uw'); - expect(query).to.have.property('uh'); - expect(query).to.have.property('dpr'); - expect(query).to.have.property('bt'); - expect(query).to.have.property('cookies'); - expect(query).to.have.property('tz'); - expect(query).to.have.property('dt'); - expect(query).to.have.property('iob'); - expect(query).to.have.property('rndid'); - expect(query).to.have.property('ref'); - expect(query).to.have.property('url'); - - // video specific part - expect(query['video.maxduration.0']).to.equal('30'); - expect(query['video.mimes.0']).to.equal('video/mp4'); - expect(query['video.context.0']).to.equal('instream'); - }); - - it('creates a valid adxcg request url bidNative', function () { - let request = spec.buildRequests([bidNative]); - expect(request).to.exist; - expect(request.method).to.equal('GET'); - let parsedRequestUrl = parseUrl(request.url); - expect(parsedRequestUrl.hostname).to.equal('hbps.adxcg.net'); - expect(parsedRequestUrl.pathname).to.equal('/get/adi'); - - let query = parsedRequestUrl.search; - expect(query.renderformat).to.equal('javascript'); - expect(query.ver).to.equal('r20210330PB40'); - expect(query.source).to.equal('pbjs10'); - expect(query.pbjs).to.equal('$prebid.version$'); - expect(query.adzoneid).to.equal('2379'); - expect(query.format).to.equal('0x0'); - expect(query.jsonp).to.be.undefined; - expect(query.prebidBidIds).to.equal('84ab500420319d'); - expect(query.bidfloors).to.equal('0'); - - expect(query).to.have.property('secure'); - expect(query).to.have.property('uw'); - expect(query).to.have.property('uh'); - expect(query).to.have.property('dpr'); - expect(query).to.have.property('bt'); - expect(query).to.have.property('cookies'); - expect(query).to.have.property('tz'); - expect(query).to.have.property('dt'); - expect(query).to.have.property('iob'); - expect(query).to.have.property('rndid'); - expect(query).to.have.property('ref'); - expect(query).to.have.property('url'); - }); - }); - - describe('gdpr compliance', function () { - it('should send GDPR Consent data if gdprApplies', function () { - let request = spec.buildRequests([bidBanner], { - gdprConsent: { - gdprApplies: true, - consentString: 'consentDataString' - } - }); - let parsedRequestUrl = parseUrl(request.url); - let query = parsedRequestUrl.search; - - expect(query.gdpr).to.equal('1'); - expect(query.gdpr_consent).to.equal('consentDataString'); - }); - - it('should not send GDPR Consent data if gdprApplies is false or undefined', function () { - let request = spec.buildRequests([bidBanner], { - gdprConsent: { - gdprApplies: false, - consentString: 'consentDataString' - } - }); - let parsedRequestUrl = parseUrl(request.url); - let query = parsedRequestUrl.search; - - expect(query.gdpr).to.be.undefined; - expect(query.gdpr_consent).to.be.undefined; - }); - }); - - describe('userid pubcid should be passed to querystring', function () { - let bidderRequests = {}; - let bid = deepClone([bidBanner]); - bid[0].userId = {pubcid: 'pubcidabcd'}; - - it('should send pubcid if available', function () { - let request = spec.buildRequests(bid, bidderRequests); - let parsedRequestUrl = parseUrl(request.url); - let query = parsedRequestUrl.search; - expect(query.pubcid).to.equal('pubcidabcd'); - }); - }); - - describe('userid tdid should be passed to querystring', function () { - let bid = deepClone([bidBanner]); - let bidderRequests = {}; - - bid[0].userId = {tdid: 'tdidabcd'}; - - it('should send pubcid if available', function () { - let request = spec.buildRequests(bid, bidderRequests); - let parsedRequestUrl = parseUrl(request.url); - let query = parsedRequestUrl.search; - expect(query.tdid).to.equal('tdidabcd'); - }); - }); - - describe('userid id5id should be passed to querystring', function () { - let bid = deepClone([bidBanner]); - let bidderRequests = {}; - - bid[0].userId = {id5id: {uid: 'id5idsample'}}; - - it('should send pubcid if available', function () { - let request = spec.buildRequests(bid, bidderRequests); - let parsedRequestUrl = parseUrl(request.url); - let query = parsedRequestUrl.search; - expect(query.id5id).to.equal('id5idsample'); - }); - }); - - describe('userid idl_env should be passed to querystring', function () { - let bid = deepClone([bidBanner]); - let bidderRequests = {}; - - bid[0].userId = {idl_env: 'idl_envsample'}; - - it('should send pubcid if available', function () { - let request = spec.buildRequests(bid, bidderRequests); - let parsedRequestUrl = parseUrl(request.url); - let query = parsedRequestUrl.search; - expect(query.idl_env).to.equal('idl_envsample'); - }); - }); - - describe('response handler', function () { - let BIDDER_REQUEST = { - bidder: 'adxcg', - params: { - adzoneid: '1' - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [640, 360], - [1, 1] - ] - } - }, - bidId: '84ab500420319d', - bidderRequestId: '7101db09af0db2', - auctionId: '1d1a030790a475' - }; - - let BANNER_RESPONSE = { - body: { - id: 'auctionid', - bidid: '84ab500420319d', - seatbid: [{ - bid: [ - { - impid: '84ab500420319d', - price: 0.45, - crid: '42', - adm: '', - w: 300, - h: 250, - adomain: ['adomain.com'], - cat: ['IAB1-4', 'IAB8-16', 'IAB25-5'], - ext: { - crType: 'banner', - advertiser_id: '777', - advertiser_name: 'advertiser', - agency_name: 'agency' - } - } - ] - }], - cur: 'USD' - }, - headers: {someheader: 'fakedata'} - }; - - let BANNER_RESPONSE_WITHDEALID = { - body: { - id: 'auctionid', - bidid: '84ab500420319d', - seatbid: [{ - bid: [ - { - impid: '84ab500420319d', - price: 0.45, - crid: '42', - dealid: '7722', - adm: '', - w: 300, - h: 250, - adomain: ['adomain.com'], - ext: { - crType: 'banner' - } - } - ] - }], - cur: 'USD' - } - }; - - let VIDEO_RESPONSE = { - body: { - id: 'auctionid', - bidid: '84ab500420319d', - seatbid: [{ - bid: [ - { - impid: '84ab500420319d', - price: 0.45, - crid: '42', - nurl: 'vastContentUrl', - adomain: ['adomain.com'], - w: 640, - h: 360, - ext: { - crType: 'video' - } - } - ] - }], - cur: 'USD' - }, - headers: {someheader: 'fakedata'} - }; - - let NATIVE_RESPONSEob = { - assets: [ - { - id: 1, - required: 0, - title: { - text: 'titleContent' - } - }, - { - id: 2, - required: 0, - img: { - url: 'imageContent', - w: 600, - h: 600 - } - }, - { - id: 3, - required: 0, - data: { - label: 'DESC', - value: 'descriptionContent' - } - }, - { - id: 0, - required: 0, - data: { - label: 'SPONSORED', - value: 'sponsoredByContent' - } - }, - { - id: 5, - required: 0, - icon: { - url: 'iconContent', - w: 400, - h: 400 - } - } - ], - link: { - url: 'linkContent' - }, - imptrackers: ['impressionTracker1', 'impressionTracker2'] - } - - let NATIVE_RESPONSE = { - body: { - id: 'auctionid', - bidid: '84ab500420319d', - seatbid: [{ - bid: [ - { - impid: '84ab500420319d', - price: 0.45, - crid: '42', - w: 0, - h: 0, - adm: JSON.stringify(NATIVE_RESPONSEob), - adomain: ['adomain.com'], - ext: { - crType: 'native' - } - } - ] - }], - cur: 'USD' - }, - headers: {someheader: 'fakedata'} - }; - - it('handles regular responses', function () { - expect(BANNER_RESPONSE).to.exist; - expect(BANNER_RESPONSE.body).to.exist; - expect(BANNER_RESPONSE.body.id).to.exist; - expect(BANNER_RESPONSE.body.seatbid[0]).to.exist; - let result = spec.interpretResponse(BANNER_RESPONSE, BIDDER_REQUEST); - - expect(result).to.have.lengthOf(1); - - expect(result[0]).to.exist; - expect(result[0].width).to.equal(300); - expect(result[0].height).to.equal(250); - expect(result[0].creativeId).to.equal(42); - expect(result[0].cpm).to.be.within(0.45, 0.46); - expect(result[0].ad).to.equal(''); - expect(result[0].currency).to.equal('USD'); - expect(result[0].netRevenue).to.equal(true); - expect(result[0].ttl).to.equal(300); - expect(result[0].dealId).to.not.exist; - expect(result[0].meta.advertiserDomains[0]).to.equal('adomain.com'); - expect(result[0].meta.advertiserId).to.be.eql('777'); - expect(result[0].meta.advertiserName).to.be.eql('advertiser'); - expect(result[0].meta.agencyName).to.be.eql('agency'); - expect(result[0].meta.advertiserDomains).to.be.eql(['adomain.com']); - expect(result[0].meta.secondaryCatIds).to.be.eql(['IAB1-4', 'IAB8-16', 'IAB25-5']); - }); - - it('handles regular responses with dealid', function () { - let result = spec.interpretResponse(BANNER_RESPONSE_WITHDEALID); - - expect(result).to.have.lengthOf(1); - - expect(result[0].width).to.equal(300); - expect(result[0].height).to.equal(250); - expect(result[0].creativeId).to.equal(42); - // expect(result[0].cpm).to.equal(0.45); - expect(result[0].cpm).to.be.within(0.45, 0.46); - expect(result[0].ad).to.equal(''); - expect(result[0].currency).to.equal('USD'); - expect(result[0].netRevenue).to.equal(true); - expect(result[0].ttl).to.equal(300); - }); - - it('handles video responses', function () { - let result = spec.interpretResponse(VIDEO_RESPONSE); - expect(result).to.have.lengthOf(1); - - expect(result[0].width).to.equal(640); - expect(result[0].height).to.equal(360); - expect(result[0].mediaType).to.equal('video'); - expect(result[0].creativeId).to.equal(42); - expect(result[0].cpm).to.equal(0.45); - expect(result[0].vastUrl).to.equal('vastContentUrl'); - expect(result[0].currency).to.equal('USD'); - expect(result[0].netRevenue).to.equal(true); - expect(result[0].ttl).to.equal(300); - }); - - it('handles native responses', function () { - let result = spec.interpretResponse(NATIVE_RESPONSE); - - expect(result[0].width).to.equal(0); - expect(result[0].height).to.equal(0); - - expect(result[0].creativeId).to.equal(42); - expect(result[0].cpm).to.equal(0.45); - expect(result[0].currency).to.equal('USD'); - expect(result[0].netRevenue).to.equal(true); - expect(result[0].ttl).to.equal(300); - - expect(result[0].mediaType).to.equal('native'); - - expect(result[0].native.clickUrl).to.equal('linkContent'); - expect(result[0].native.impressionTrackers).to.deep.equal([ - 'impressionTracker1', - 'impressionTracker2' - ]); - expect(result[0].native.title).to.equal('titleContent'); - - expect(result[0].native.image.url).to.equal('imageContent'); - expect(result[0].native.image.height).to.equal(600); - expect(result[0].native.image.width).to.equal(600); - - expect(result[0].native.icon.url).to.equal('iconContent'); - expect(result[0].native.icon.height).to.equal(400); - expect(result[0].native.icon.width).to.equal(400); - - expect(result[0].native.body).to.equal('descriptionContent'); - expect(result[0].native.sponsoredBy).to.equal('sponsoredByContent'); - }); - - it('handles nobid responses', function () { - let response = []; - let bidderRequest = BIDDER_REQUEST; - - let result = spec.interpretResponse(response, bidderRequest); - expect(result.length).to.equal(0); - }); - }); - - describe('getUserSyncs', function () { - let syncoptionsIframe = { - iframeEnabled: 'true' - }; - - it('should return iframe sync option', function () { - expect(spec.getUserSyncs(syncoptionsIframe)[0].type).to.equal('iframe'); - expect(spec.getUserSyncs(syncoptionsIframe)[0].url).to.equal( - 'https://cdn.adxcg.net/pb-sync.html' - ); - }); - }); - - describe('on bidWon', function () { - beforeEach(function () { - sinon.stub(utils, 'triggerPixel'); - }); - afterEach(function () { - utils.triggerPixel.restore(); - }); - it('should replace burl for banner', function () { - const burl = 'burl=${' + 'AUCTION_PRICE}'; - const bid = { - 'bidderCode': 'adxcg', - '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': 'adxcg', - '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': [{'adzoneid': '20'}] - }; - spec.onBidWon(bid); - expect(bid.burl).to.deep.equal(burl); - }); - }); -}); diff --git a/test/spec/modules/adxpremiumAnalyticsAdapter_spec.js b/test/spec/modules/adxpremiumAnalyticsAdapter_spec.js deleted file mode 100644 index e4a8fa9dccd..00000000000 --- a/test/spec/modules/adxpremiumAnalyticsAdapter_spec.js +++ /dev/null @@ -1,415 +0,0 @@ -import adxpremiumAnalyticsAdapter from 'modules/adxpremiumAnalyticsAdapter.js'; -import { testSend } from 'modules/adxpremiumAnalyticsAdapter.js'; -import { expect } from 'chai'; -import adapterManager from 'src/adapterManager.js'; -import { server } from 'test/mocks/xhr.js'; - -let events = require('src/events'); -let constants = require('src/constants.json'); - -describe('AdxPremium analytics adapter', function () { - beforeEach(function () { - sinon.stub(events, 'getEvents').returns([]); - }); - - afterEach(function () { - events.getEvents.restore(); - }); - - describe('track', function () { - let initOptions = { - pubId: 123, - sid: 's2' - }; - - let auctionInit = { - 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b', - 'timestamp': 1589707613899, - 'auctionStatus': 'inProgress', - 'adUnits': [ - { - 'code': 'div-gpt-ad-1533155193780-2', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } - }, - 'bids': [ - { - 'bidder': 'luponmedia', - 'params': { - 'siteId': 303522, - 'keyId': '4o2c4' - }, - 'crumbs': { - 'pubcid': 'aebbdfa9-3e0f-49b6-ad87-437aaa88db2d' - } - } - ], - 'sizes': [ - [ - 300, - 250 - ] - ], - 'transactionId': 'f68c54c2-0814-4ae5-95f5-09f6dd9dc1ef' - } - ], - 'adUnitCodes': [ - 'div-gpt-ad-1533155193780-2' - ], - 'labels': [ - 'BA' - ], - 'bidderRequests': [ - { - 'bidderCode': 'luponmedia', - 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b', - 'bidderRequestId': '18c49b05a23645', - 'bids': [ - { - 'bidder': 'luponmedia', - 'params': { - 'siteId': 303522, - 'keyId': '4o2c4' - }, - 'crumbs': { - 'pubcid': 'aebbdfa9-3e0f-49b6-ad87-437aaa88db2d' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } - }, - 'adUnitCode': 'div-gpt-ad-1533155193780-2', - 'transactionId': 'f68c54c2-0814-4ae5-95f5-09f6dd9dc1ef', - 'sizes': [ - [ - 300, - 250 - ] - ], - 'bidId': '284f8e1469246a', - 'bidderRequestId': '18c49b05a23645', - 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0, - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'novi.ba', - 'sid': '199424', - 'hp': 1 - } - ] - } - } - ], - 'auctionStart': 1589707613899, - 'timeout': 2000, - 'refererInfo': { - 'referer': 'https://test.com/article/176067', - 'reachedTop': true, - 'numIframes': 0, - 'stack': [ - 'https://test.com/article/176067' - ] - }, - 'gdprConsent': {} - } - ], - 'noBids': [], - 'bidsReceived': [], - 'winningBids': [], - 'timeout': 2000, - 'config': { - 'pubId': 4444, - 'sid': 's2' - } - }; - - // requests & responses - let bidRequest = { - 'bidderCode': 'luponmedia', - 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b', - 'bidderRequestId': '18c49b05a23645', - 'bids': [ - { - 'bidder': 'luponmedia', - 'params': { - 'siteId': 303522, - 'keyId': '4o2c4' - }, - 'crumbs': { - 'pubcid': 'aebbdfa9-3e0f-49b6-ad87-437aaa88db2d' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } - }, - 'adUnitCode': 'div-gpt-ad-1533155193780-2', - 'transactionId': 'f68c54c2-0814-4ae5-95f5-09f6dd9dc1ef', - 'sizes': [ - [ - 300, - 250 - ] - ], - 'bidId': '284f8e1469246a', - 'bidderRequestId': '18c49b05a23645', - 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0, - }, - { - 'bidder': 'luponmedia', - 'params': { - 'siteId': 303522, - 'keyId': '4o2c5' - }, - 'crumbs': { - 'pubcid': 'aebbdfa9-3e0f-49b6-ad87-437aaa88db2d' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } - }, - 'adUnitCode': 'div-gpt-ad-1533155193780-3', - 'transactionId': 'f68c54c2-0814-4ae5-95f5-09f6dd9dc1ef', - 'sizes': [ - [ - 300, - 250 - ] - ], - 'bidId': '284f8e1469246b', - 'bidderRequestId': '18c49b05a23645', - 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0, - } - ], - 'auctionStart': 1589707613899, - 'timeout': 2000, - 'refererInfo': { - 'referer': 'https://test.com/article/176067', - 'reachedTop': true, - 'numIframes': 0, - 'stack': [ - 'https://test.com/article/176067' - ] - }, - 'start': 1589707613908 - }; - - let bidResponse = { - 'bidderCode': 'luponmedia', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '3b40e0da8968f5', - 'requestId': '284f8e1469246a', - 'mediaType': 'banner', - 'source': 'client', - 'cpm': 0.43, - 'creativeId': '443801010', - 'currency': 'USD', - 'netRevenue': false, - 'ttl': 300, - 'referrer': '', - 'ad': " ", - 'originalCpm': '0.43', - 'originalCurrency': 'USD', - 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b', - 'responseTimestamp': 1589707615188, - 'requestTimestamp': 1589707613908, - 'bidder': 'luponmedia', - 'adUnitCode': 'div-gpt-ad-1533155193780-2', - 'timeToRespond': 1280, - 'pbLg': '0.00', - 'pbMg': '0.40', - 'pbHg': '0.43', - 'pbAg': '0.40', - 'pbDg': '0.43', - 'pbCg': '0.43', - 'size': '300x250', - 'adserverTargeting': { - 'hb_bidder': 'luponmedia', - 'hb_adid': '3b40e0da8968f5', - 'hb_pb': '0.43', - 'hb_size': '300x250', - 'hb_source': 'client', - 'hb_format': 'banner' - } - }; - - // what we expect after general auction - - let expectedAfterBidData = JSON.parse(atob('eyJwdWJsaXNoZXJfaWQiOjEyMywiYXVjdGlvbl9pZCI6ImM0ZjBjY2UwLTI2NGMtNDgzYS1iMmY0LThhYzIyNDhhODk2YiIsInJlZmVyZXIiOiJodHRwczovL3Rlc3QuY29tL2FydGljbGUvMTc2MDY3Iiwic2NyZWVuX3Jlc29sdXRpb24iOiIxNDQweDkwMCIsImRldmljZV90eXBlIjoiZGVza3RvcCIsImdlbyI6bnVsbCwiZXZlbnRzIjpbeyJ0eXBlIjoiVElNRU9VVCIsImJpZGRlcl9jb2RlIjoibHVwb25tZWRpYSIsImV2ZW50X3RpbWVzdGFtcCI6MTU4OTcwNzYxMzkwOCwiYmlkX2dwdF9jb2RlcyI6eyJkaXYtZ3B0LWFkLTE1MzMxNTUxOTM3ODAtMiI6W1szMDAsMjUwXV0sImRpdi1ncHQtYWQtMTUzMzE1NTE5Mzc4MC0zIjpbWzMwMCwyNTBdXX19XX0=')); - expectedAfterBidData['screen_resolution'] = window.screen.width + 'x' + window.screen.height; - expectedAfterBidData = btoa(JSON.stringify(expectedAfterBidData)); - - let expectedAfterBid = { - 'query': 'mutation {createEvent(input: {event: {eventData: "' + expectedAfterBidData + '"}}) {event {createTime } } }' - }; - - // what we expect after timeout - - let expectedAfterTimeoutData = JSON.parse(atob('eyJwdWJsaXNoZXJfaWQiOjEyMywiYXVjdGlvbl9pZCI6ImM0ZjBjY2UwLTI2NGMtNDgzYS1iMmY0LThhYzIyNDhhODk2YiIsInJlZmVyZXIiOiJodHRwczovL3Rlc3QuY29tL2FydGljbGUvMTc2MDY3Iiwic2NyZWVuX3Jlc29sdXRpb24iOiIxNDQweDkwMCIsImRldmljZV90eXBlIjoiZGVza3RvcCIsImdlbyI6bnVsbCwiZXZlbnRzIjpbeyJ0eXBlIjoiVElNRU9VVCIsImJpZGRlcl9jb2RlIjoibHVwb25tZWRpYSIsImV2ZW50X3RpbWVzdGFtcCI6MTU4OTcwNzYxMzkwOCwiYmlkX2dwdF9jb2RlcyI6eyJkaXYtZ3B0LWFkLTE1MzMxNTUxOTM3ODAtMiI6W1szMDAsMjUwXV0sImRpdi1ncHQtYWQtMTUzMzE1NTE5Mzc4MC0zIjpbWzMwMCwyNTBdXX19XX0=')); - expectedAfterTimeoutData['screen_resolution'] = window.screen.width + 'x' + window.screen.height; - expectedAfterTimeoutData = btoa(JSON.stringify(expectedAfterTimeoutData)); - - let expectedAfterTimeout = { - 'query': 'mutation {createEvent(input: {event: {eventData: "' + expectedAfterTimeoutData + '"}}) {event {createTime } } }' - }; - - // lets simulate that some bidders timeout - let bidTimeoutArgsV1 = [ - { - 'bidId': '284f8e1469246b', - 'bidder': 'luponmedia', - 'adUnitCode': 'div-gpt-ad-1533155193780-3', - 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b' - } - ]; - - // now simulate some WIN and RENDERING - let wonRequest = { - 'bidderCode': 'luponmedia', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '3b40e0da8968f5', - 'requestId': '284f8e1469246a', - 'mediaType': 'banner', - 'source': 'client', - 'cpm': 0.43, - 'creativeId': '443801010', - 'currency': 'USD', - 'netRevenue': false, - 'ttl': 300, - 'referrer': '', - 'ad': " ", - 'originalCpm': '0.43', - 'originalCurrency': 'USD', - 'auctionId': 'c4f0cce0-264c-483a-b2f4-8ac2248a896b', - 'responseTimestamp': 1589707615188, - 'requestTimestamp': 1589707613908, - 'bidder': 'luponmedia', - 'adUnitCode': 'div-gpt-ad-1533155193780-2', - 'timeToRespond': 1280, - 'pbLg': '0.00', - 'pbMg': '0.40', - 'pbHg': '0.43', - 'pbAg': '0.40', - 'pbDg': '0.43', - 'pbCg': '0.43', - 'size': '300x250', - 'adserverTargeting': { - 'hb_bidder': 'luponmedia', - 'hb_adid': '3b40e0da8968f5', - 'hb_pb': '0.43', - 'hb_size': '300x250', - 'hb_source': 'client', - 'hb_format': 'banner' - }, - 'status': 'rendered', - 'params': [ - { - 'siteId': 303522, - 'keyId': '4o2c4' - } - ] - }; - - let wonExpectData = JSON.parse(atob('eyJwdWJsaXNoZXJfaWQiOjEyMywiYXVjdGlvbl9pZCI6ImM0ZjBjY2UwLTI2NGMtNDgzYS1iMmY0LThhYzIyNDhhODk2YiIsInJlZmVyZXIiOiJodHRwczovL3Rlc3QuY29tL2FydGljbGUvMTc2MDY3Iiwic2NyZWVuX3Jlc29sdXRpb24iOiIxNDQweDkwMCIsImRldmljZV90eXBlIjoiZGVza3RvcCIsImdlbyI6bnVsbCwiZXZlbnRzIjpbeyJ0eXBlIjoiVElNRU9VVCIsImJpZGRlcl9jb2RlIjoibHVwb25tZWRpYSIsImV2ZW50X3RpbWVzdGFtcCI6MTU4OTcwNzYxMzkwOCwiYmlkX2dwdF9jb2RlcyI6eyJkaXYtZ3B0LWFkLTE1MzMxNTUxOTM3ODAtMiI6W1szMDAsMjUwXV0sImRpdi1ncHQtYWQtMTUzMzE1NTE5Mzc4MC0zIjpbWzMwMCwyNTBdXX19LHsidHlwZSI6IlJFU1BPTlNFIiwiYmlkZGVyX2NvZGUiOiJsdXBvbm1lZGlhIiwiZXZlbnRfdGltZXN0YW1wIjoxNTg5NzA3NjE1MTg4LCJzaXplIjoiMzAweDI1MCIsImdwdF9jb2RlIjoiZGl2LWdwdC1hZC0xNTMzMTU1MTkzNzgwLTIiLCJjdXJyZW5jeSI6IlVTRCIsImNyZWF0aXZlX2lkIjoiNDQzODAxMDEwIiwidGltZV90b19yZXNwb25kIjoxMjgwLCJjcG0iOjAuNDMsImlzX3dpbm5pbmciOmZhbHNlfV19')); - wonExpectData['screen_resolution'] = window.screen.width + 'x' + window.screen.height; - wonExpectData = btoa(JSON.stringify(wonExpectData)); - - let wonExpect = { - 'query': 'mutation {createEvent(input: {event: {eventData: "' + wonExpectData + '"}}) {event {createTime } } }' - }; - - adapterManager.registerAnalyticsAdapter({ - code: 'adxpremium', - adapter: adxpremiumAnalyticsAdapter - }); - - beforeEach(function () { - adapterManager.enableAnalytics({ - provider: 'adxpremium', - options: initOptions - }); - }); - - afterEach(function () { - adxpremiumAnalyticsAdapter.disableAnalytics(); - }); - - it('builds and sends auction data', function () { - // Step 1: Send auction init event - events.emit(constants.EVENTS.AUCTION_INIT, auctionInit); - - // Step 2: Send bid requested event - events.emit(constants.EVENTS.BID_REQUESTED, bidRequest); - - // Step 3: Send bid response event - events.emit(constants.EVENTS.BID_RESPONSE, bidResponse); - - // Step 4: Send bid time out event - events.emit(constants.EVENTS.BID_TIMEOUT, bidTimeoutArgsV1); - - // Step 5: Send auction end event - events.emit(constants.EVENTS.AUCTION_END, {}); - - testSend(); - - expect(server.requests.length).to.equal(2); - - let realAfterBid = JSON.parse(server.requests[0].requestBody); - - expect(realAfterBid).to.deep.equal(expectedAfterBid); - - // expect after timeout - expect(realAfterBid).to.deep.equal(expectedAfterTimeout); - - // Step 6: Send auction bid won event - events.emit(constants.EVENTS.BID_WON, wonRequest); - - expect(server.requests.length).to.equal(3); - let winEventData = JSON.parse(server.requests[1].requestBody); - - expect(winEventData).to.deep.equal(wonExpect); - }); - }); -}); diff --git a/test/spec/modules/adyoulikeBidAdapter_spec.js b/test/spec/modules/adyoulikeBidAdapter_spec.js deleted file mode 100644 index c432ad1b32d..00000000000 --- a/test/spec/modules/adyoulikeBidAdapter_spec.js +++ /dev/null @@ -1,614 +0,0 @@ -import { expect } from 'chai'; - -import { spec } from 'modules/adyoulikeBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('Adyoulike Adapter', function () { - const canonicalUrl = 'https://canonical.url/?t=%26'; - const referrerUrl = 'http://referrer.url/?param=value'; - const defaultDC = 'hb-api'; - const consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - const bidderRequest = { - 'auctionId': '1d1a030790a475', - 'bidderRequestId': '22edbae2733bf6', - 'timeout': 3000, - 'gdprConsent': { - consentString: consentString, - gdprApplies: true - }, - refererInfo: {referer: referrerUrl} - }; - const bidRequestWithEmptyPlacement = [ - { - 'bidId': 'bid_id_0', - 'bidder': 'adyoulike', - 'placementCode': 'adunit/hb-0', - 'params': {}, - 'sizes': '300x250', - 'mediaTypes': - { 'banner': - {'sizes': ['300x250', '300x600'] - } - } - } - ]; - const bidRequestWithEmptySizes = { - 'bids': [ - { - 'bidId': 'bid_id_0', - 'bidder': 'adyoulike', - 'placementCode': 'adunit/hb-0', - 'params': { - 'placement': 'placement_0' - }, - 'transactionId': 'bid_id_0_transaction_id' - } - ], - }; - - const bidRequestWithSinglePlacement = [ - { - 'bidId': 'bid_id_0', - 'bidder': 'adyoulike', - 'placementCode': 'adunit/hb-0', - 'params': { - 'placement': 'placement_0' - }, - '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': [] - } - }, - }, - 'transactionId': 'bid_id_0_transaction_id' - } - ]; - - const bidRequestWithNativeImageType = [ - { - 'bidId': 'bid_id_0', - 'bidder': 'adyoulike', - 'placementCode': 'adunit/hb-0', - 'params': { - 'placement': 'placement_0' - }, - 'sizes': '300x250', - 'mediaTypes': - { - 'native': { - 'type': 'image', - 'additional': { - 'will': 'be', - 'sent': ['300x250'] - } - }, - }, - 'transactionId': 'bid_id_0_transaction_id' - } - ]; - - const sentBidNative = { - 'bid_id_0': { - 'PlacementID': 'e622af275681965d3095808561a1e510', - 'TransactionID': 'e8355240-d976-4cd5-a493-640656fe08e8', - 'AvailableSizes': '', - 'Native': { - 'image': { - 'required': true, - 'sizes': [] - }, - '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': [] - } - } - } - }; - - const sentNativeImageType = { - 'additional': { - 'sent': [ - '300x250' - ], - 'will': 'be' - }, - 'body': { - 'required': false - }, - 'clickUrl': { - 'required': true - }, - 'cta': { - 'required': false - }, - 'icon': { - 'required': false - }, - 'image': { - 'required': true - }, - 'sponsoredBy': { - 'required': true - }, - 'title': { - 'required': true - }, - 'type': 'image' - }; - - const bidRequestWithDCPlacement = [ - { - 'bidId': 'bid_id_0', - 'bidder': 'adyoulike', - 'placementCode': 'adunit/hb-0', - 'params': { - 'placement': 'placement_0', - 'DC': 'fra01' - }, - 'sizes': '300x250', - 'mediaTypes': - { 'banner': - {'sizes': ['300x250'] - } - }, - 'transactionId': 'bid_id_0_transaction_id' - } - ]; - - const bidRequestMultiPlacements = [ - { - 'bidId': 'bid_id_0', - 'bidder': 'adyoulike', - 'placementCode': 'adunit/hb-0', - 'params': { - 'placement': 'placement_0' - }, - 'sizes': '300x250', - 'mediaTypes': - { 'banner': - {'sizes': ['300x250'] - } - }, - 'transactionId': 'bid_id_0_transaction_id' - }, - { - 'bidId': 'bid_id_1', - 'bidder': 'adyoulike', - 'placementCode': 'adunit/hb-1', - 'params': { - 'placement': 'placement_1' - }, - 'sizes': [[300, 600]], - 'mediaTypes': - { 'banner': - {'sizes': ['300x600'] - } - }, - 'transactionId': 'bid_id_1_transaction_id' - }, - { - 'bidId': 'bid_id_2', - 'bidder': 'adyoulike', - 'placementCode': 'adunit/hb-2', - 'params': {}, - 'sizes': '300x400', - 'transactionId': 'bid_id_2_transaction_id' - }, - { - 'bidId': 'bid_id_3', - 'bidder': 'adyoulike', - 'placementCode': 'adunit/hb-3', - 'params': { - 'placement': 'placement_3' - }, - 'transactionId': 'bid_id_3_transaction_id' - } - ]; - - const requestDataOnePlacement = { - 'bid_id_0': - { 'PlacementID': 'e622af275681965d3095808561a1e510', - 'TransactionID': '1bca18cc-c0fe-439b-88c2-8247d3448f22', - 'Width': 300, - 'Height': 600, - 'AvailableSizes': '300x600' - } - } - - const requestDataMultiPlacement = { - 'bid_id_0': - { 'PlacementID': 'e622af275681965d3095808561a1e510', - 'TransactionID': '1bca18cc-c0fe-439b-88c2-8247d3448f22', - 'Width': 300, - 'Height': 600, - 'AvailableSizes': '300x600' - }, - 'bid_id_1': - { 'PlacementID': 'e622af275681965d3095808561a1e510', - 'TransactionID': 'e63b2d86-ca60-4167-9cf1-497607079634', - 'Width': 400, - 'Height': 250, - 'AvailableSizes': '300x250' - } - } - - const responseWithEmptyPlacement = [ - { - 'Placement': 'placement_0' - } - ]; - const admSample = "\u003cscript id=\"ayl-prebid-a11a121205932e75e622af275681965d\"\u003e\n(function(){\n\twindow.isPrebid = true\n\tvar prebidResults = /*PREBID*/{\"OnEvents\":{\"CLICK\":[{\"Kind\":\"PIXEL_URL\",\"Url\":\"https://testPixelCLICK.com/fake\"}],\"IMPRESSION\":[{\"Kind\":\"PIXEL_URL\",\"Url\":\"https://testPixelIMP.com/fake\"},{\"Kind\":\"JAVASCRIPT_URL\",\"Url\":\"https://testJsIMP.com/fake.js\"}]},\"Disabled\":false,\"Attempt\":\"a11a121205932e75e622af275681965d\",\"ApiPrefix\":\"https://fo-api.omnitagjs.com/fo-api\",\"TrackingPrefix\":\"https://tracking.omnitagjs.com/tracking\",\"DynamicPrefix\":\"https://tag-dyn.omnitagjs.com/fo-dyn\",\"StaticPrefix\":\"https://fo-static.omnitagjs.com/fo-static\",\"BlobPrefix\":\"https://fo-api.omnitagjs.com/fo-api/blobs\",\"SspPrefix\":\"https://fo-ssp.omnitagjs.com/fo-ssp\",\"VisitorPrefix\":\"https://visitor.omnitagjs.com/visitor\",\"Trusted\":true,\"Placement\":\"e622af275681965d3095808561a1e510\",\"PlacementAccess\":\"ALL\",\"Site\":\"6e2df7a92203c3c7a25561ed63f25a27\",\"Lang\":\"EN\",\"SiteLogo\":null,\"HasSponsorImage\":false,\"ResizeIframe\":true,\"IntegrationConfig\":{\"Kind\":\"WIDGET\",\"Widget\":{\"ExtraStyleSheet\":\"\",\"Placeholders\":{\"Body\":{\"Color\":{\"R\":77,\"G\":21,\"B\":82,\"A\":100},\"BackgroundColor\":{\"R\":255,\"G\":255,\"B\":255,\"A\":100},\"FontFamily\":\"Lato\",\"Width\":\"100%\",\"Align\":\"\",\"BoxShadow\":true},\"CallToAction\":{\"Color\":{\"R\":26,\"G\":157,\"B\":212,\"A\":100}},\"Description\":{\"Length\":130},\"Image\":{\"Width\":600,\"Height\":600,\"Lowres\":false,\"Raw\":false},\"Size\":{\"Height\":\"250px\",\"Width\":\"300px\"},\"Sponsor\":{\"Color\":{\"R\":35,\"G\":35,\"B\":35,\"A\":100},\"Label\":true,\"WithoutLogo\":false},\"Title\":{\"Color\":{\"R\":219,\"G\":181,\"B\":255,\"A\":100}}},\"Selector\":{\"Kind\":\"CSS\",\"Css\":\"#ayl-prebid-a11a121205932e75e622af275681965d\"},\"Insertion\":\"AFTER\",\"ClickFormat\":true,\"Creative20\":true,\"WidgetKind\":\"CREATIVE_TEMPLATE_4\"}},\"Legal\":\"Sponsored\",\"ForcedCampaign\":\"f1c80d4bb5643c222ae8de75e9b2f991\",\"ForcedTrack\":\"\",\"ForcedCreative\":\"\",\"ForcedSource\":\"\",\"DisplayMode\":\"DEFAULT\",\"Campaign\":\"f1c80d4bb5643c222ae8de75e9b2f991\",\"CampaignAccess\":\"ALL\",\"CampaignKind\":\"AD_TRAFFIC\",\"DataSource\":\"LOCAL\",\"DataSourceUrl\":\"\",\"DataSourceOnEventsIsolated\":false,\"DataSourceWithoutCookie\":false,\"Content\":{\"Preview\":{\"Thumbnail\":{\"Image\":{\"Kind\":\"EXTERNAL\",\"Data\":{\"External\":{\"Url\":\"https://tag-dyn.omnitagjs.com/fo-dyn/native/preview/image?key=fd4362d35bb174d6f1c80d4bb5643c22\\u0026kind=INTERNAL\\u0026ztop=0.000000\\u0026zleft=0.000000\\u0026zwidth=0.333333\\u0026zheight=1.000000\\u0026width=[width]\\u0026height=[height]\"}},\"ZoneTop\":0,\"ZoneLeft\":0,\"ZoneWidth\":1,\"ZoneHeight\":1,\"Smart\":false,\"NoTransform\":false,\"Quality\":\"NORMAL\"}},\"Text\":{\"CALLTOACTION\":\"Click here to learn more\",\"DESCRIPTION\":\"Considérant l'extrémité conjoncturelle, il serait bon d'anticiper toutes les voies de bon sens.\",\"SPONSOR\":\"Tested by\",\"TITLE\":\"Adserver Traffic Redirect Internal\"},\"Sponsor\":{\"Name\":\"QA Team\"},\"Credit\":{\"Logo\":{\"Resource\":{\"Kind\":\"EXTERNAL\",\"Data\":{\"External\":{\"Url\":\"https://fo-static.omnitagjs.com/fo-static/native/images/info-ayl.png\"}},\"ZoneTop\":0,\"ZoneLeft\":0,\"ZoneWidth\":1,\"ZoneHeight\":1,\"Smart\":false,\"NoTransform\":false,\"Quality\":\"NORMAL\"}},\"Url\":\"https://blobs.omnitagjs.com/adchoice/\"}},\"Landing\":{\"Url\":\"https://www.w3.org/People/mimasa/test/xhtml/entities/entities-11.xhtml#lat1\",\"LegacyTracking\":false},\"ViewButtons\":{\"Close\":{\"Skip\":6000}},\"InternalContentFields\":{\"AnimatedImage\":false}},\"AdDomain\":\"adyoulike.com\",\"Opener\":\"REDIRECT\",\"PerformUITriggers\":[\"CLICK\"],\"RedirectionTarget\":\"TAB\"}/*PREBID*/;\n\tvar insertAds = function insertAds() {\insertAds();\n\t}\n})();\n\u003c/script\u003e"; - const responseWithSinglePlacement = [ - { - 'BidID': 'bid_id_0', - 'Placement': 'placement_0', - 'Ad': admSample, - 'Price': 0.5, - 'Height': 600, - } - ]; - const responseWithMultiplePlacements = [ - { - 'BidID': 'bid_id_0', - 'Placement': 'placement_0', - 'Ad': 'placement_0', - 'Price': 0.5, - 'Height': 0, // test with wrong value - 'Width': 300 - }, - { - 'BidID': 'bid_id_1', - 'Placement': 'placement_1', - 'Ad': 'placement_1', - 'Price': 0.6, - 'Height': 250 - // 'Width' test with missing value - } - ]; - const adapter = newBidder(spec); - - let getEndpoint = (dc = defaultDC) => `https://${dc}.omnitagjs.com/hb-api/prebid`; - - describe('inherited functions', function () { - it('exists and is a function', function () { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - let bid = { - 'bidId': 'bid_id_1', - 'bidder': 'adyoulike', - 'placementCode': 'adunit/hb-1', - 'params': { - 'placement': 'placement_1' - }, - 'sizes': [[300, 600]], - 'transactionId': 'bid_id_1_transaction_id' - }; - - let nativeBid = { - 'bidId': 'bid_id_1', - 'bidder': 'adyoulike', - 'placementCode': 'adunit/hb-1', - 'params': { - 'placement': 'placement_1' - }, - mediaTypes: { - native: { - - } - }, - 'transactionId': 'bid_id_1_transaction_id' - }; - - it('should return true when required params found', function () { - expect(!!spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return true when required params found for native ad', function () { - expect(!!spec.isBidRequestValid(nativeBid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.size; - - expect(!!spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'placement': 0 - }; - expect(!!spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let canonicalQuery; - - beforeEach(function () { - let canonical = document.createElement('link'); - canonical.rel = 'canonical'; - canonical.href = canonicalUrl; - canonicalQuery = sinon.stub(window.top.document.head, 'querySelector'); - canonicalQuery.withArgs('link[rel="canonical"][href]').returns(canonical); - }); - - afterEach(function () { - canonicalQuery.restore(); - }); - - it('Should expand short native image config type', function() { - const request = spec.buildRequests(bidRequestWithNativeImageType, bidderRequest); - const payload = JSON.parse(request.data); - - expect(request.url).to.contain(getEndpoint()); - expect(request.method).to.equal('POST'); - expect(request.url).to.contains('CanonicalUrl=' + encodeURIComponent(canonicalUrl)); - expect(request.url).to.contains('RefererUrl=' + encodeURIComponent(referrerUrl)); - expect(request.url).to.contains('PublisherDomain=http%3A%2F%2Flocalhost%3A9876'); - - expect(payload.Version).to.equal('1.0'); - 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.Bids['bid_id_0'].Native).deep.equal(sentNativeImageType); - }); - - it('should add gdpr/usp consent information to the request', function () { - let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - let uspConsentData = '1YCC'; - let bidderRequest = { - 'auctionId': '1d1a030790a475', - 'bidderRequestId': '22edbae2733bf6', - 'timeout': 3000, - 'gdprConsent': { - consentString: consentString, - gdprApplies: true - }, - 'uspConsent': uspConsentData - }; - - bidderRequest.bids = bidRequestWithSinglePlacement; - - const request = spec.buildRequests(bidRequestWithSinglePlacement, bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.gdprConsent).to.exist; - expect(payload.gdprConsent.consentString).to.exist.and.to.equal(consentString); - expect(payload.gdprConsent.consentRequired).to.exist.and.to.be.true; - expect(payload.uspConsent).to.exist.and.to.equal(uspConsentData); - }); - - it('should not set a default value for gdpr consentRequired', function () { - let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - let uspConsentData = '1YCC'; - let bidderRequest = { - 'auctionId': '1d1a030790a475', - 'bidderRequestId': '22edbae2733bf6', - 'timeout': 3000, - 'gdprConsent': { - consentString: consentString - }, - 'uspConsent': uspConsentData - }; - - bidderRequest.bids = bidRequestWithSinglePlacement; - - const request = spec.buildRequests(bidRequestWithSinglePlacement, bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.gdprConsent).to.exist; - expect(payload.gdprConsent.consentString).to.exist.and.to.equal(consentString); - expect(payload.gdprConsent.consentRequired).to.be.null; - }); - - it('sends bid request to endpoint with single placement', function () { - const request = spec.buildRequests(bidRequestWithSinglePlacement, bidderRequest); - const payload = JSON.parse(request.data); - - expect(request.url).to.contain(getEndpoint()); - expect(request.method).to.equal('POST'); - expect(request.url).to.contains('CanonicalUrl=' + encodeURIComponent(canonicalUrl)); - expect(request.url).to.contains('RefererUrl=' + encodeURIComponent(referrerUrl)); - expect(request.url).to.contains('PublisherDomain=http%3A%2F%2Flocalhost%3A9876'); - - expect(payload.Version).to.equal('1.0'); - 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'); - }); - - it('sends bid request to endpoint with single placement without canonical', function () { - canonicalQuery.restore(); - const request = spec.buildRequests(bidRequestWithSinglePlacement, bidderRequest); - const payload = JSON.parse(request.data); - - expect(request.url).to.contain(getEndpoint()); - expect(request.method).to.equal('POST'); - - expect(request.url).to.not.contains('CanonicalUrl=' + encodeURIComponent(canonicalUrl)); - expect(payload.Version).to.equal('1.0'); - 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'); - }); - - it('sends bid request to endpoint with multiple placements', function () { - const request = spec.buildRequests(bidRequestMultiPlacements, bidderRequest); - const payload = JSON.parse(request.data); - expect(request.url).to.contain(getEndpoint()); - expect(request.method).to.equal('POST'); - - expect(request.url).to.contains('CanonicalUrl=' + encodeURIComponent(canonicalUrl)); - expect(request.url).to.contains('RefererUrl=' + encodeURIComponent(referrerUrl)); - - expect(payload.Version).to.equal('1.0'); - - expect(payload.Bids['bid_id_0'].PlacementID).to.be.equal('placement_0'); - expect(payload.Bids['bid_id_1'].PlacementID).to.be.equal('placement_1'); - expect(payload.Bids['bid_id_3'].PlacementID).to.be.equal('placement_3'); - - expect(payload.Bids['bid_id_0'].TransactionID).to.be.equal('bid_id_0_transaction_id'); - expect(payload.Bids['bid_id_1'].TransactionID).to.be.equal('bid_id_1_transaction_id'); - expect(payload.Bids['bid_id_3'].TransactionID).to.be.equal('bid_id_3_transaction_id'); - expect(payload.PageRefreshed).to.equal(false); - }); - - it('sends bid request to endpoint setted by parameters', function () { - const request = spec.buildRequests(bidRequestWithDCPlacement, bidderRequest); - const payload = JSON.parse(request.data); - - expect(request.url).to.contain(getEndpoint(`${defaultDC}-fra01`)); - }); - }); - // - describe('interpretResponse', function () { - let serverResponse; - - beforeEach(function () { - serverResponse = { - body: {} - } - }); - - it('handles nobid responses', function () { - let response = [{ - BidID: '123dfsdf', - Attempt: '32344fdse1', - Placement: '12df1' - }]; - serverResponse.body = response; - let result = spec.interpretResponse(serverResponse, []); - expect(result).deep.equal([]); - }); - - it('receive reponse with single placement', function () { - serverResponse.body = responseWithSinglePlacement; - let result = spec.interpretResponse(serverResponse, {data: '{"Bids":' + JSON.stringify(requestDataOnePlacement) + '}'}); - - expect(result.length).to.equal(1); - expect(result[0].cpm).to.equal(0.5); - expect(result[0].ad).to.equal(admSample); - expect(result[0].width).to.equal(300); - expect(result[0].height).to.equal(600); - }); - - it('receive reponse with multiple placement', function () { - serverResponse.body = responseWithMultiplePlacements; - let result = spec.interpretResponse(serverResponse, {data: '{"Bids":' + JSON.stringify(requestDataMultiPlacement) + '}'}); - - expect(result.length).to.equal(2); - - expect(result[0].cpm).to.equal(0.5); - expect(result[0].ad).to.equal('placement_0'); - expect(result[0].width).to.equal(300); - expect(result[0].height).to.equal(600); - - expect(result[1].cpm).to.equal(0.6); - expect(result[1].ad).to.equal('placement_1'); - expect(result[1].width).to.equal(400); - expect(result[1].height).to.equal(250); - }); - - it('receive reponse with Native ad', function () { - serverResponse.body = responseWithSinglePlacement; - let result = spec.interpretResponse(serverResponse, {data: '{"Bids":' + JSON.stringify(sentBidNative) + '}'}); - - expect(result.length).to.equal(1); - - expect(result).to.deep.equal([{ - cpm: 0.5, - creativeId: undefined, - currency: 'USD', - netRevenue: true, - requestId: 'bid_id_0', - ttl: 3600, - mediaType: 'native', - native: { - body: 'Considérant l\'extrémité conjoncturelle, il serait bon d\'anticiper toutes les voies de bon sens.', - clickTrackers: [ - 'https://testPixelCLICK.com/fake' - ], - clickUrl: 'https://tracking.omnitagjs.com/tracking/ar?event_kind=CLICK&attempt=a11a121205932e75e622af275681965d&campaign=f1c80d4bb5643c222ae8de75e9b2f991&url=https%3A%2F%2Fwww.w3.org%2FPeople%2Fmimasa%2Ftest%2Fxhtml%2Fentities%2Fentities-11.xhtml%23lat1', - cta: 'Click here to learn more', - image: { - height: 600, - url: 'https://blobs.omnitagjs.com/blobs/f1/f1c80d4bb5643c22/fd4362d35bb174d6f1c80d4bb5643c22', - width: 300, - }, - impressionTrackers: [ - 'https://testPixelIMP.com/fake', - 'https://tracking.omnitagjs.com/tracking/pixel?event_kind=IMPRESSION&attempt=a11a121205932e75e622af275681965d&campaign=f1c80d4bb5643c222ae8de75e9b2f991', - 'https://tracking.omnitagjs.com/tracking/pixel?event_kind=INSERTION&attempt=a11a121205932e75e622af275681965d&campaign=f1c80d4bb5643c222ae8de75e9b2f991' - ], - javascriptTrackers: [ - 'https://testJsIMP.com/fake.js' - ], - privacyIcon: 'https://fo-static.omnitagjs.com/fo-static/native/images/info-ayl.png', - privacyLink: 'https://blobs.omnitagjs.com/adchoice/', - sponsoredBy: 'QA Team', - title: 'Adserver Traffic Redirect Internal', - } - - }]); - }); - }); -}); diff --git a/test/spec/modules/ajaBidAdapter_spec.js b/test/spec/modules/ajaBidAdapter_spec.js deleted file mode 100644 index 80ecab764e8..00000000000 --- a/test/spec/modules/ajaBidAdapter_spec.js +++ /dev/null @@ -1,311 +0,0 @@ -import { spec } from 'modules/ajaBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -const ENDPOINT = 'https://ad.as.amanad.adtdp.com/v2/prebid'; - -describe('AjaAdapter', function () { - const adapter = newBidder(spec); - - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'aja', - 'params': { - 'asi': '123456' - }, - 'adUnitCode': 'adunit', - 'sizes': [[300, 250]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'asi': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [ - { - 'bidder': 'aja', - 'params': { - 'asi': '123456' - }, - 'adUnitCode': 'adunit', - 'sizes': [[300, 250]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - let bidderRequest = { - refererInfo: { - referer: 'https://hoge.com' - } - }; - - it('sends bid request to ENDPOINT via GET', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests[0].url).to.equal(ENDPOINT); - expect(requests[0].method).to.equal('GET'); - expect(requests[0].data).to.equal('asi=123456&skt=5&prebid_id=30b31c1838de1e&prebid_ver=$prebid.version$&page_url=https%3A%2F%2Fhoge.com&'); - }); - }); - - describe('interpretResponse', function () { - it('should get correct banner bid response', function () { - let response = { - 'is_ad_return': true, - 'ad': { - 'ad_type': 1, - 'prebid_id': '51ef8751f9aead', - 'price': 12.34, - 'currency': 'USD', - 'creative_id': '123abc', - 'banner': { - 'w': 300, - 'h': 250, - 'tag': '
', - 'imps': [ - 'https://as.amanad.adtdp.com/v1/imp' - ] - } - }, - 'syncs': [ - 'https://example.com' - ] - }; - - let expectedResponse = [ - { - 'requestId': '51ef8751f9aead', - 'cpm': 12.34, - 'creativeId': '123abc', - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
', - 'mediaType': 'banner', - 'currency': 'USD', - 'ttl': 300, - 'netRevenue': true - } - ]; - - let bidderRequest; - let result = spec.interpretResponse({ body: response }, {bidderRequest}); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('handles video responses', function () { - let response = { - 'is_ad_return': true, - 'ad': { - 'ad_type': 3, - 'prebid_id': '51ef8751f9aead', - 'price': 12.34, - 'currency': 'JPY', - 'creative_id': '123abc', - 'video': { - 'w': 300, - 'h': 250, - 'vtag': '', - 'purl': 'https://cdn/player', - 'progress': true, - 'loop': false, - 'inread': false - } - }, - 'syncs': [ - 'https://example.com' - ] - }; - - let bidderRequest; - let result = spec.interpretResponse({ body: response }, {bidderRequest}); - expect(result[0]).to.have.property('vastXml'); - expect(result[0]).to.have.property('renderer'); - expect(result[0]).to.have.property('mediaType', 'video'); - }); - - it('handles native response', function () { - let response = { - 'is_ad_return': true, - 'ad': { - 'ad_type': 2, - 'prebid_id': '51ef8751f9aead', - 'price': 12.34, - 'currency': 'JPY', - 'creative_id': '123abc', - 'native': { - 'template_and_ads': { - 'head': '', - 'body_wrapper': '', - 'body': '', - 'ads': [ - { - 'ad_format_id': 10, - 'assets': { - 'ad_spot_id': '123abc', - 'index': 0, - 'adchoice_url': 'https://aja-kk.co.jp/optout', - 'cta_text': 'cta', - 'img_icon': 'https://example.com/img_icon', - 'img_icon_width': '50', - 'img_icon_height': '50', - 'img_main': 'https://example.com/img_main', - 'img_main_width': '200', - 'img_main_height': '100', - 'lp_link': 'https://example.com/lp?k=v', - 'sponsor': 'sponsor', - 'title': 'ad_title', - 'description': 'ad_desc' - }, - 'imps': [ - 'https://example.com/imp' - ], - 'inviews': [ - 'https://example.com/inview' - ], - 'jstracker': '', - 'disable_trimming': false - } - ] - } - } - }, - 'syncs': [ - 'https://example.com' - ] - }; - - let expectedResponse = [ - { - 'requestId': '51ef8751f9aead', - 'cpm': 12.34, - 'creativeId': '123abc', - 'dealId': undefined, - 'mediaType': 'native', - 'currency': 'JPY', - 'ttl': 300, - 'netRevenue': true, - 'native': { - 'title': 'ad_title', - 'body': 'ad_desc', - 'cta': 'cta', - 'sponsoredBy': 'sponsor', - 'image': { - 'url': 'https://example.com/img_main', - 'width': 200, - 'height': 100 - }, - 'icon': { - 'url': 'https://example.com/img_icon', - 'width': 50, - 'height': 50 - }, - 'clickUrl': 'https://example.com/lp?k=v', - 'impressionTrackers': [ - 'https://example.com/imp' - ], - 'privacyLink': 'https://aja-kk.co.jp/optout', - } - } - ]; - - let bidderRequest; - let result = spec.interpretResponse({ body: response }, {bidderRequest}) - expect(result).to.deep.equal(expectedResponse) - }); - - it('handles nobid responses', function () { - let response = { - 'is_ad_return': false, - 'ad': {} - }; - - let bidderRequest; - let result = spec.interpretResponse({ body: response }, {bidderRequest}); - expect(result.length).to.equal(0); - }); - }); - - describe('getUserSyncs', function () { - const bidResponse1 = { - body: { - 'is_ad_return': true, - 'ad': { /* ad body */ }, - 'syncs': [ - 'https://example.test/pixel/1' - ], - 'sync_htmls': [ - 'https://example.test/iframe/1' - ] - } - }; - - const bidResponse2 = { - body: { - 'is_ad_return': true, - 'ad': { /* ad body */ }, - 'syncs': [ - 'https://example.test/pixel/2' - ] - } - }; - - it('should use a sync url from first response (pixel and iframe)', function () { - const syncs = spec.getUserSyncs({ pixelEnabled: true, iframeEnabled: true }, [bidResponse1, bidResponse2]); - expect(syncs).to.deep.equal([ - { - type: 'image', - url: 'https://example.test/pixel/1' - }, - { - type: 'iframe', - url: 'https://example.test/iframe/1' - } - ]); - }); - - it('handle empty response (e.g. timeout)', function () { - const syncs = spec.getUserSyncs({ pixelEnabled: true, iframeEnabled: true }, []); - expect(syncs).to.deep.equal([]); - }); - - it('returns empty syncs when not pixel enabled and not iframe enabled', function () { - const syncs = spec.getUserSyncs({ pixelEnabled: false, iframeEnabled: false }, [bidResponse1]); - expect(syncs).to.deep.equal([]); - }); - - it('returns pixel syncs when pixel enabled and not iframe enabled', function() { - const syncs = spec.getUserSyncs({ pixelEnabled: true, iframeEnabled: false }, [bidResponse1]); - expect(syncs).to.deep.equal([ - { - type: 'image', - url: 'https://example.test/pixel/1' - } - ]); - }); - - it('returns iframe syncs when not pixel enabled and iframe enabled', function() { - const syncs = spec.getUserSyncs({ pixelEnabled: false, iframeEnabled: true }, [bidResponse1]); - expect(syncs).to.deep.equal([ - { - type: 'iframe', - url: 'https://example.test/iframe/1' - } - ]); - }); - }); -}); diff --git a/test/spec/modules/amxBidAdapter_spec.js b/test/spec/modules/amxBidAdapter_spec.js deleted file mode 100644 index f502d631c17..00000000000 --- a/test/spec/modules/amxBidAdapter_spec.js +++ /dev/null @@ -1,563 +0,0 @@ -import * as utils from 'src/utils.js'; -import { createEidsArray } from 'modules/userId/eids.js'; -import { expect } from 'chai'; -import { spec } from 'modules/amxBidAdapter.js'; -import { BANNER, VIDEO } from 'src/mediaTypes.js'; -import { config } from 'src/config.js'; - -const sampleRequestId = '82c91e127a9b93e'; -const sampleDisplayAd = (additionalImpressions) => `${additionalImpressions}`; -const sampleDisplayCRID = '78827819'; -// minimal example vast -const sampleVideoAd = (addlImpression) => ` -00:00:15${addlImpression} -`.replace(/\n+/g, '') - -const embeddedTrackingPixel = `https://1x1.a-mo.net/hbx/g_impression?A=sample&B=20903`; -const sampleNurl = 'https://example.exchange/nurl'; - -const sampleFPD = { - site: { - keywords: 'sample keywords', - ext: { - data: { - pageType: 'article' - } - } - }, - user: { - gender: 'O', - yob: 1982, - } -}; - -const stubConfig = (withStub) => { - const stub = sinon.stub(config, 'getConfig').callsFake( - (arg) => arg === 'ortb2' ? sampleFPD : null - ) - - withStub(); - stub.restore(); -}; - -const sampleBidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString: utils.getUniqueIdentifierStr(), - vendorData: {} - }, - auctionId: utils.getUniqueIdentifierStr(), - uspConsent: '1YYY', - refererInfo: { - referer: 'https://www.prebid.org', - canonicalUrl: 'https://www.prebid.org/the/link/to/the/page' - } -}; - -const sampleBidRequestBase = { - bidder: spec.code, - params: { - endpoint: 'https://httpbin.org/post', - }, - sizes: [[320, 50]], - getFloor(params) { - if (params.size == null || params.currency == null || params.mediaType == null) { - throw new Error(`getFloor called with incomplete params: ${JSON.stringify(params)}`) - } - return { - floor: 0.5, - currency: 'USD' - } - }, - mediaTypes: { - [BANNER]: { - sizes: [[300, 250]] - } - }, - adUnitCode: 'div-gpt-ad-example', - transactionId: utils.getUniqueIdentifierStr(), - bidId: sampleRequestId, - auctionId: utils.getUniqueIdentifierStr(), -}; - -const schainConfig = { - ver: '1.0', - nodes: [{ - asi: 'greatnetwork.exchange', - sid: '000001', - hp: 1, - rid: 'bid_request_1', - domain: 'publisher.com' - }] -}; - -const sampleBidRequestVideo = { - ...sampleBidRequestBase, - bidId: sampleRequestId + '_video', - sizes: [[300, 150]], - schain: schainConfig, - mediaTypes: { - [VIDEO]: { - sizes: [[360, 250]], - context: 'adpod', - adPodDurationSec: 90, - contentMode: 'live' - } - } -}; - -const sampleServerResponse = { - 'p': { - 'hreq': ['https://1x1.a-mo.net/hbx/g_sync?partner=test', 'https://1x1.a-mo.net/hbx/g_syncf?__st=iframe'] - }, - 'r': { - [sampleRequestId]: [ - { - 'b': [ - { - 'adid': '78827819', - 'adm': sampleDisplayAd(''), - 'adomain': [ - 'example.com' - ], - 'crid': sampleDisplayCRID, - 'ext': { - 'himp': [ - embeddedTrackingPixel - ], - }, - 'nurl': sampleNurl, - 'h': 600, - 'id': '2014691335735134254', - 'impid': '1', - 'exp': 90, - 'price': 0.25, - 'w': 300 - }, - { - 'adid': '222976952', - 'adm': sampleVideoAd(''), - 'adomain': [ - 'example.com' - ], - 'crid': sampleDisplayCRID, - 'ext': { - 'himp': [ - embeddedTrackingPixel - ], - }, - 'nurl': sampleNurl, - 'h': 1, - 'id': '7735706981389902829', - 'impid': '1', - 'exp': 90, - 'price': 0.25, - 'w': 1 - }, - ], - } - ] - }, -} - -describe('AmxBidAdapter', () => { - describe('isBidRequestValid', () => { - it('endpoint must be an optional string', () => { - expect(spec.isBidRequestValid({params: { endpoint: 1 }})).to.equal(false) - expect(spec.isBidRequestValid({params: { endpoint: 'test' }})).to.equal(true) - }); - - it('tagId is an optional string', () => { - expect(spec.isBidRequestValid({params: { tagId: 1 }})).to.equal(false) - expect(spec.isBidRequestValid({params: { tagId: 'test' }})).to.equal(true) - }); - - it('testMode is an optional truthy value', () => { - expect(spec.isBidRequestValid({params: { testMode: 1 }})).to.equal(true) - expect(spec.isBidRequestValid({params: { testMode: 'true' }})).to.equal(true) - // ignore invalid values (falsy) - expect(spec.isBidRequestValid({params: { testMode: 'non-truthy-invalid-value' }})).to.equal(true) - expect(spec.isBidRequestValid({params: { testMode: false }})).to.equal(true) - }); - - it('none of the params are required', () => { - expect(spec.isBidRequestValid({})).to.equal(true) - }); - }) - describe('getUserSync', () => { - it('will only sync from valid server responses', () => { - const syncs = spec.getUserSyncs({ iframeEnabled: true }); - expect(syncs).to.eql([]); - }); - - it('will return valid syncs from a server response', () => { - const syncs = spec.getUserSyncs({ iframeEnabled: true }, [{body: sampleServerResponse}]); - expect(syncs.length).to.equal(2); - expect(syncs[0].type).to.equal('image'); - expect(syncs[1].type).to.equal('iframe'); - }); - - it('will filter out iframe syncs based on options', () => { - const syncs = spec.getUserSyncs({ iframeEnabled: false }, [{body: sampleServerResponse}, {body: sampleServerResponse}]); - expect(syncs.length).to.equal(2); - expect(syncs).to.satisfy((allSyncs) => allSyncs.every((sync) => sync.type === 'image')) - }); - }); - - describe('buildRequests', () => { - it('will default to prebid.a-mo.net endpoint', () => { - const { url } = spec.buildRequests([], sampleBidderRequest); - expect(url).to.equal('https://prebid.a-mo.net/a/c') - }); - - it('will read the prebid version & global', () => { - const { data: { V: prebidVersion, vg: prebidGlobal } } = spec.buildRequests([{ - ...sampleBidRequestBase, - params: { - testMode: true - } - }], sampleBidderRequest); - expect(prebidVersion).to.equal('$prebid.version$') - expect(prebidGlobal).to.equal('$$PREBID_GLOBAL$$') - }); - - it('reads test mode from the first bid request', () => { - const { data } = spec.buildRequests([{ - ...sampleBidRequestBase, - params: { - testMode: true - } - }], sampleBidderRequest); - expect(data.tm).to.equal(true); - }); - - it('if prebid is in an iframe, will use the frame url as domain, if the topmost is not avialable', () => { - const { data } = spec.buildRequests([sampleBidRequestBase], { - ...sampleBidderRequest, - refererInfo: { - numIframes: 1, - referer: 'http://search-traffic-source.com', - stack: [] - } - }); - expect(data.do).to.equal('localhost') - expect(data.re).to.equal('http://search-traffic-source.com'); - }); - - it('if we are in AMP, make sure we use the canonical URL or the referrer (which is sourceUrl)', () => { - const { data } = spec.buildRequests([sampleBidRequestBase], { - ...sampleBidderRequest, - refererInfo: { - isAmp: true, - referer: 'http://real-publisher-site.com/content', - stack: [] - } - }); - expect(data.do).to.equal('real-publisher-site.com') - expect(data.re).to.equal('http://real-publisher-site.com/content'); - }) - - it('if prebid is in an iframe, will use the topmost url as domain', () => { - const { data } = spec.buildRequests([sampleBidRequestBase], { - ...sampleBidderRequest, - refererInfo: { - numIframes: 1, - referer: 'http://search-traffic-source.com', - stack: ['http://top-site.com', 'http://iframe.com'] - } - }); - expect(data.do).to.equal('top-site.com'); - expect(data.re).to.equal('http://search-traffic-source.com'); - }); - - it('handles referer data and GDPR, USP Consent, COPPA', () => { - const { data } = spec.buildRequests([sampleBidRequestBase], sampleBidderRequest); - delete data.m; // don't deal with "m" in this test - expect(data.gs).to.equal(sampleBidderRequest.gdprConsent.gdprApplies) - expect(data.gc).to.equal(sampleBidderRequest.gdprConsent.consentString) - expect(data.usp).to.equal(sampleBidderRequest.uspConsent) - expect(data.cpp).to.equal(0) - }); - - it('will forward bid request count & wins count data', () => { - const bidderRequestsCount = Math.floor(Math.random() * 100) - const bidderWinsCount = Math.floor(Math.random() * 100) - const { data } = spec.buildRequests([{ - ...sampleBidRequestBase, - bidderRequestsCount, - bidderWinsCount - }], sampleBidderRequest); - - expect(data.brc).to.equal(bidderRequestsCount) - expect(data.bwc).to.equal(bidderWinsCount) - expect(data.trc).to.equal(0) - }); - it('will forward first-party data', () => { - stubConfig(() => { - const { data } = spec.buildRequests([sampleBidRequestBase], sampleBidderRequest); - expect(data.fpd2).to.deep.equal(sampleFPD) - }); - }); - - it('will collect & forward RTI user IDs', () => { - const randomRTI = `greatRTI${Math.floor(Math.random() * 100)}` - const userId = { - britepoolid: 'sample-britepool', - criteoId: 'sample-criteo', - digitrustid: {data: {id: 'sample-digitrust'}}, - id5id: {uid: 'sample-id5'}, - idl_env: 'sample-liveramp', - lipb: {lipbid: 'sample-liveintent'}, - netId: 'sample-netid', - parrableId: { eid: 'sample-parrable' }, - pubcid: 'sample-pubcid', - [randomRTI]: 'sample-unknown', - tdid: 'sample-ttd', - }; - - const eids = createEidsArray(userId); - const bid = { - ...sampleBidRequestBase, - userIdAsEids: eids - }; - - const { data } = spec.buildRequests([bid, bid], sampleBidderRequest); - expect(data.eids).to.deep.equal(eids) - }); - - it('can build a banner request', () => { - const { method, url, data } = spec.buildRequests([sampleBidRequestBase, { - ...sampleBidRequestBase, - bidId: sampleRequestId + '_2', - params: { - ...sampleBidRequestBase.params, - tagId: 'example' - } - }], sampleBidderRequest) - - expect(url).to.equal(sampleBidRequestBase.params.endpoint) - expect(method).to.equal('POST'); - expect(Object.keys(data.m).length).to.equal(2); - expect(data.m[sampleRequestId]).to.deep.equal({ - av: true, - au: 'div-gpt-ad-example', - vd: {}, - ms: [ - [[320, 50]], - [[300, 250]], - [] - ], - aw: 300, - sc: {}, - ah: 250, - tf: 0, - f: 0.5, - vr: false - }); - expect(data.m[sampleRequestId + '_2']).to.deep.equal({ - av: true, - aw: 300, - au: 'div-gpt-ad-example', - sc: {}, - ms: [ - [[320, 50]], - [[300, 250]], - [] - ], - i: 'example', - ah: 250, - vd: {}, - tf: 0, - f: 0.5, - vr: false, - }); - }); - - it('can build a video request', () => { - const { data } = spec.buildRequests([sampleBidRequestVideo], sampleBidderRequest); - expect(Object.keys(data.m).length).to.equal(1); - expect(data.m[sampleRequestId + '_video']).to.deep.equal({ - au: 'div-gpt-ad-example', - ms: [ - [[300, 150]], - [], - [[360, 250]] - ], - av: true, - aw: 360, - ah: 250, - sc: schainConfig, - vd: { - sizes: [[360, 250]], - context: 'adpod', - adPodDurationSec: 90, - contentMode: 'live' - }, - tf: 0, - f: 0.5, - vr: true - }); - }); - }); - - describe('interpretResponse', () => { - const baseBidResponse = { - requestId: sampleRequestId, - cpm: 0.25, - creativeId: sampleDisplayCRID, - currency: 'USD', - netRevenue: true, - meta: { - advertiserDomains: ['example.com'], - }, - }; - - const baseRequest = { - data: { - m: { - [sampleRequestId]: { - aw: 300, - ah: 250, - }, - } - } - }; - - it('will handle a nobid response', () => { - const parsed = spec.interpretResponse({ body: '' }, baseRequest) - expect(parsed).to.eql([]) - }); - - it('can parse a display ad', () => { - const parsed = spec.interpretResponse({ body: sampleServerResponse }, baseRequest) - expect(parsed.length).to.equal(2) - - // we should have display, video, display - expect(parsed[0]).to.deep.equal({ - ...baseBidResponse, - meta: { - ...baseBidResponse.meta, - mediaType: BANNER, - }, - mediaType: BANNER, - width: 300, - height: 600, // from the bid itself - ttl: 90, - ad: sampleDisplayAd( - `` + - `` - ), - }); - }); - - it('can parse a video ad', () => { - const parsed = spec.interpretResponse({ body: sampleServerResponse }, baseRequest) - expect(parsed.length).to.equal(2) - expect(parsed[1]).to.deep.equal({ - ...baseBidResponse, - meta: { - ...baseBidResponse.meta, - mediaType: VIDEO, - }, - mediaType: VIDEO, - vastXml: sampleVideoAd(''), - width: 300, - height: 250, - ttl: 90, - }); - }); - }); - - describe('analytics methods', () => { - let firedPixels = []; - let _Image = window.Image; - before(() => { - _Image = window.Image; - window.Image = class FakeImage { - set src(value) { - firedPixels.push(value) - } - } - }); - - beforeEach(() => { - firedPixels = []; - }); - - after(() => { - window.Image = _Image; - }); - - it('will fire an event for onSetTargeting', () => { - spec.onSetTargeting({ - bidder: 'example', - width: 300, - height: 250, - adId: 'ad-id', - mediaType: BANNER, - cpm: 1.23, - requestId: utils.getUniqueIdentifierStr(), - adUnitCode: 'div-gpt-ad', - adserverTargeting: { - hb_pb: '1.23', - hb_adid: 'ad-id', - hb_bidder: 'example' - } - }); - expect(firedPixels.length).to.equal(1) - expect(firedPixels[0]).to.match(/\/hbx\/g_pbst/) - try { - const parsed = new URL(firedPixels[0]); - const nestedData = parsed.searchParams.get('c2'); - expect(nestedData).to.equal(utils.formatQS({ - hb_pb: '1.23', - hb_adid: 'ad-id', - hb_bidder: 'example' - })); - } catch (e) { - // unsupported browser; try testing for string - const pixel = firedPixels[0]; - expect(pixel).to.have.string(encodeURIComponent('hb_pb=1.23')) - expect(pixel).to.have.string(encodeURIComponent('hb_adid=ad-id')) - } - }); - - it('will log an event for timeout', () => { - spec.onTimeout({ - bidder: 'example', - bidId: 'test-bid-id', - adUnitCode: 'div-gpt-ad', - timeout: 300, - auctionId: utils.getUniqueIdentifierStr() - }); - expect(firedPixels.length).to.equal(1) - expect(firedPixels[0]).to.match(/\/hbx\/g_pbto/) - }); - - it('will log an event for prebid win', () => { - spec.onBidWon({ - bidder: 'example', - adId: 'test-ad-id', - width: 300, - height: 250, - mediaType: VIDEO, - cpm: 1.34, - adUnitCode: 'div-gpt-ad', - timeout: 300, - auctionId: utils.getUniqueIdentifierStr() - }); - expect(firedPixels.length).to.equal(1) - expect(firedPixels[0]).to.match(/\/hbx\/g_pbwin/) - - const pixel = firedPixels[0]; - try { - const url = new URL(pixel); - expect(url.searchParams.get('C')).to.equal('1') - expect(url.searchParams.get('np')).to.equal('1.34') - } catch (e) { - expect(pixel).to.have.string('C=1') - expect(pixel).to.have.string('np=1.34') - } - }); - }); -}); diff --git a/test/spec/modules/aniviewBidAdapter_spec.js b/test/spec/modules/aniviewBidAdapter_spec.js deleted file mode 100644 index 2e1fdb56201..00000000000 --- a/test/spec/modules/aniviewBidAdapter_spec.js +++ /dev/null @@ -1,226 +0,0 @@ -import { spec } from 'modules/aniviewBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -const { expect } = require('chai'); - -describe('ANIVIEW Bid Adapter Test', 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 () { - let bid = { - 'bidder': 'aniview', - 'params': { - 'AV_PUBLISHERID': '123456', - 'AV_CHANNELID': '123456' - }, - 'adUnitCode': 'video1', - 'sizes': [[300, 250], [640, 480]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'requestId': 'a09c66c3-53e3-4428-b296-38fc08e7cd2a', - 'transactionId': 'd6f6b392-54a9-454c-85fb-a2fd882c4a2d', - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - something: 'is wrong' - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bid2Requests = [ - { - 'bidder': 'aniview', - 'params': { - 'AV_PUBLISHERID': '123456', - 'AV_CHANNELID': '123456' - }, - 'adUnitCode': 'test1', - 'sizes': [[300, 250], [640, 480]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'requestId': 'a09c66c3-53e3-4428-b296-38fc08e7cd2a', - 'transactionId': 'd6f6b392-54a9-454c-85fb-a2fd882c4a2d', - } - ]; - let bid1Request = [ - { - 'bidder': 'aniview', - 'params': { - 'AV_PUBLISHERID': '123456', - 'AV_CHANNELID': '123456' - }, - 'adUnitCode': 'test1', - 'sizes': [640, 480], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'requestId': 'a09c66c3-53e3-4428-b296-38fc08e7cd2a', - 'transactionId': 'd6f6b392-54a9-454c-85fb-a2fd882c4a2d', - } - ]; - - it('Test 2 requests', function () { - const requests = spec.buildRequests(bid2Requests); - expect(requests.length).to.equal(2); - const r1 = requests[0]; - const d1 = requests[0].data; - expect(d1).to.have.property('AV_PUBLISHERID'); - expect(d1.AV_PUBLISHERID).to.equal('123456'); - expect(d1).to.have.property('AV_CHANNELID'); - expect(d1.AV_CHANNELID).to.equal('123456'); - expect(d1).to.have.property('AV_WIDTH'); - expect(d1.AV_WIDTH).to.equal(300); - expect(d1).to.have.property('AV_HEIGHT'); - expect(d1.AV_HEIGHT).to.equal(250); - expect(d1).to.have.property('AV_URL'); - expect(d1).to.have.property('cb'); - expect(d1).to.have.property('s2s'); - expect(d1.s2s).to.equal('1'); - expect(d1).to.have.property('pbjs'); - expect(d1.pbjs).to.equal(1); - expect(r1).to.have.property('url'); - expect(r1.url).to.contain('https://gov.aniview.com/api/adserver/vast3/'); - const r2 = requests[1]; - const d2 = requests[1].data; - expect(d2).to.have.property('AV_PUBLISHERID'); - expect(d2.AV_PUBLISHERID).to.equal('123456'); - expect(d2).to.have.property('AV_CHANNELID'); - expect(d2.AV_CHANNELID).to.equal('123456'); - expect(d2).to.have.property('AV_WIDTH'); - expect(d2.AV_WIDTH).to.equal(640); - expect(d2).to.have.property('AV_HEIGHT'); - expect(d2.AV_HEIGHT).to.equal(480); - expect(d2).to.have.property('AV_URL'); - expect(d2).to.have.property('cb'); - expect(d2).to.have.property('s2s'); - expect(d2.s2s).to.equal('1'); - expect(d2).to.have.property('pbjs'); - expect(d2.pbjs).to.equal(1); - expect(r2).to.have.property('url'); - expect(r2.url).to.contain('https://gov.aniview.com/api/adserver/vast3/'); - }); - - it('Test 1 request', function () { - const requests = spec.buildRequests(bid1Request); - expect(requests.length).to.equal(1); - const r = requests[0]; - const d = requests[0].data; - expect(d).to.have.property('AV_PUBLISHERID'); - expect(d.AV_PUBLISHERID).to.equal('123456'); - expect(d).to.have.property('AV_CHANNELID'); - expect(d.AV_CHANNELID).to.equal('123456'); - expect(d).to.have.property('AV_WIDTH'); - expect(d.AV_WIDTH).to.equal(640); - expect(d).to.have.property('AV_HEIGHT'); - expect(d.AV_HEIGHT).to.equal(480); - expect(d).to.have.property('AV_URL'); - expect(d).to.have.property('cb'); - expect(d).to.have.property('s2s'); - expect(d.s2s).to.equal('1'); - expect(d).to.have.property('pbjs'); - expect(d.pbjs).to.equal(1); - expect(r).to.have.property('url'); - expect(r.url).to.contain('https://gov.aniview.com/api/adserver/vast3/'); - }); - }); - - describe('interpretResponse', function () { - let bidRequest = { - 'url': 'https://gov.aniview.com/api/adserver/vast3/', - 'data': { - 'bidId': '253dcb69fb2577', - AV_PUBLISHERID: '55b78633181f4603178b4568', - AV_CHANNELID: '55b7904d181f46410f8b4568', - } - }; - let serverResponse = {}; - serverResponse.body = 'FORDFORD00:00:15'; - - it('Check bid interpretResponse', function () { - const BIDDER_CODE = 'aniview'; - let bidResponses = spec.interpretResponse(serverResponse, bidRequest); - expect(bidResponses.length).to.equal(1); - let bidResponse = bidResponses[0]; - expect(bidResponse.requestId).to.equal(bidRequest.data.bidId); - expect(bidResponse.cpm).to.equal('2'); - expect(bidResponse.ttl).to.equal(600); - expect(bidResponse.currency).to.equal('USD'); - expect(bidResponse.netRevenue).to.equal(true); - expect(bidResponse.mediaType).to.equal('video'); - }); - - it('safely handles XML parsing failure from invalid bid response', function () { - let invalidServerResponse = {}; - invalidServerResponse.body = ''; - - let result = spec.interpretResponse(invalidServerResponse, bidRequest); - expect(result.length).to.equal(0); - }); - - it('handles nobid responses', function () { - let nobidResponse = {}; - nobidResponse.body = ''; - - let result = spec.interpretResponse(nobidResponse, bidRequest); - expect(result.length).to.equal(0); - }); - - it('should add renderer if outstream context', function () { - const bidRequest = spec.buildRequests([ - { - bidId: '253dcb69fb2577', - params: { - playerDomain: 'example.com', - AV_PUBLISHERID: '55b78633181f4603178b4568', - AV_CHANNELID: '55b7904d181f46410f8b4568' - }, - mediaTypes: { - video: { - playerSize: [[640, 480]], - context: 'outstream' - } - } - } - ])[0] - const bidResponse = spec.interpretResponse(serverResponse, bidRequest)[0] - - expect(bidResponse.renderer.url).to.equal('https://example.com/script/6.1/prebidRenderer.js') - expect(bidResponse.renderer.config.AV_PUBLISHERID).to.equal('55b78633181f4603178b4568') - expect(bidResponse.renderer.config.AV_CHANNELID).to.equal('55b7904d181f46410f8b4568') - expect(bidResponse.renderer.loaded).to.equal(false) - expect(bidResponse.width).to.equal(640) - expect(bidResponse.height).to.equal(480) - }) - }); - - describe('getUserSyncs', function () { - it('Check get sync pixels from response', function () { - let pixelUrl = 'https://sync.pixel.url/sync'; - let pixelEvent = 'inventory'; - let pixelType = '3'; - let pixelStr = '{"url":"' + pixelUrl + '", "e":"' + pixelEvent + '", "t":' + pixelType + '}'; - let bidResponse = 'FORDFORD00:00:15'; - let serverResponse = [ - {body: bidResponse} - ]; - let syncPixels = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, serverResponse); - expect(syncPixels.length).to.equal(1); - let pixel = syncPixels[0]; - expect(pixel.url).to.equal(pixelUrl); - expect(pixel.type).to.equal('iframe'); - }); - }); -}); diff --git a/test/spec/modules/aolBidAdapter_spec.js b/test/spec/modules/aolBidAdapter_spec.js deleted file mode 100644 index 50622180ad0..00000000000 --- a/test/spec/modules/aolBidAdapter_spec.js +++ /dev/null @@ -1,835 +0,0 @@ -import {expect} from 'chai'; -import * as utils from 'src/utils.js'; -import {spec} from 'modules/aolBidAdapter.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; - -const DEFAULT_AD_CONTENT = ''; - -let getDefaultBidResponse = () => { - return { - id: '245730051428950632', - cur: 'USD', - seatbid: [{ - bid: [{ - id: 1, - impid: '245730051428950632', - price: 0.09, - adm: DEFAULT_AD_CONTENT, - crid: 'creative-id', - h: 90, - w: 728, - dealid: 'deal-id', - ext: {sizeid: 225} - }] - }] - }; -}; - -let getMarketplaceBidParams = () => { - return { - placement: 1234567, - network: '9599.1' - }; -}; - -let getNexageGetBidParams = () => { - return { - dcn: '2c9d2b50015c5ce9db6aeeed8b9500d6', - pos: 'header' - }; -}; - -let getNexagePostBidParams = () => { - return { - id: 'id-1', - imp: [{ - id: 'id-2', - banner: { - w: '100', - h: '100' - }, - tagid: 'header1' - }] - }; -}; - -let getDefaultBidRequest = () => { - return { - bidderCode: 'aol', - auctionId: 'd3e07445-ab06-44c8-a9dd-5ef9af06d2a6', - bidderRequestId: '7101db09af0db2', - start: new Date().getTime(), - bids: [{ - bidder: 'aol', - bidId: '84ab500420319d', - bidderRequestId: '7101db09af0db2', - auctionId: 'd3e07445-ab06-44c8-a9dd-5ef9af06d2a6', - placementCode: 'foo', - params: getMarketplaceBidParams() - }] - }; -}; - -let getPixels = () => { - return ''; -}; - -describe('AolAdapter', function () { - const MARKETPLACE_URL = 'https://adserver-us.adtech.advertising.com/pubapi/3.0/'; - const NEXAGE_URL = 'https://c2shb.ssp.yahoo.com/bidRequest?'; - const ONE_DISPLAY_TTL = 60; - const ONE_MOBILE_TTL = 3600; - const SUPPORTED_USER_ID_SOURCES = { - 'adserver.org': '100', - 'criteo.com': '200', - 'id5-sync.com': '300', - 'intentiq.com': '400', - 'liveintent.com': '500', - 'quantcast.com': '600', - 'verizonmedia.com': '700', - 'liveramp.com': '800' - }; - - const USER_ID_DATA = { - criteoId: SUPPORTED_USER_ID_SOURCES['criteo.com'], - connectid: SUPPORTED_USER_ID_SOURCES['verizonmedia.com'], - idl_env: SUPPORTED_USER_ID_SOURCES['liveramp.com'], - lipb: { - lipbid: SUPPORTED_USER_ID_SOURCES['liveintent.com'], - segments: ['100', '200'] - }, - tdid: SUPPORTED_USER_ID_SOURCES['adserver.org'], - id5id: { - uid: SUPPORTED_USER_ID_SOURCES['id5-sync.com'], - ext: {foo: 'bar'} - }, - intentIqId: SUPPORTED_USER_ID_SOURCES['intentiq.com'], - quantcastId: SUPPORTED_USER_ID_SOURCES['quantcast.com'] - }; - - function createCustomBidRequest({bids, params} = {}) { - var bidderRequest = getDefaultBidRequest(); - if (bids && Array.isArray(bids)) { - bidderRequest.bids = bids; - } - if (params) { - bidderRequest.bids.forEach(bid => bid.params = params); - } - return bidderRequest; - } - - describe('interpretResponse()', function () { - let bidderSettingsBackup; - let bidResponse; - let bidRequest; - let logWarnSpy; - let isOneMobileBidderStub; - - beforeEach(function () { - bidderSettingsBackup = $$PREBID_GLOBAL$$.bidderSettings; - bidRequest = { - bidderCode: 'test-bidder-code', - bidId: 'bid-id', - ttl: 1234 - }; - bidResponse = { - body: getDefaultBidResponse() - }; - logWarnSpy = sinon.spy(utils, 'logWarn'); - isOneMobileBidderStub = sinon.stub(spec, 'isOneMobileBidder'); - }); - - afterEach(function () { - $$PREBID_GLOBAL$$.bidderSettings = bidderSettingsBackup; - logWarnSpy.restore(); - isOneMobileBidderStub.restore(); - }); - - it('should return formatted bid response with required properties', function () { - let formattedBidResponse = spec.interpretResponse(bidResponse, bidRequest); - expect(formattedBidResponse).to.deep.equal({ - bidderCode: bidRequest.bidderCode, - requestId: 'bid-id', - ad: DEFAULT_AD_CONTENT, - cpm: 0.09, - width: 728, - height: 90, - creativeId: 'creative-id', - pubapiId: '245730051428950632', - currency: 'USD', - dealId: 'deal-id', - netRevenue: true, - meta: { - advertiserDomains: [] - }, - ttl: bidRequest.ttl - }); - }); - }); - - describe('buildRequests()', function () { - it('method exists and is a function', function () { - expect(spec.buildRequests).to.exist.and.to.be.a('function'); - }); - - describe('Marketplace', function () { - it('should not return request when no bids are present', function () { - let [request] = spec.buildRequests([]); - expect(request).to.be.undefined; - }); - - it('should return request for Marketplace endpoint', function () { - let bidRequest = getDefaultBidRequest(); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url.indexOf(MARKETPLACE_URL)).to.equal(0); - }); - - it('should return request for Marketplace via onedisplay bidder code', function () { - let bidRequest = createCustomBidRequest({ - bids: [{ - bidder: 'onedisplay' - }], - params: getMarketplaceBidParams() - }); - - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url.indexOf(MARKETPLACE_URL)).to.equal(0); - }); - - it('should return Marketplace request via onedisplay bidder code when' + - 'Marketplace and One Mobile GET params are present', () => { - let bidParams = Object.assign(getMarketplaceBidParams(), getNexageGetBidParams()); - let bidRequest = createCustomBidRequest({ - bids: [{ - bidder: 'onedisplay' - }], - params: bidParams - }); - - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url.indexOf(MARKETPLACE_URL)).to.equal(0); - }); - - it('should return Marketplace request via onedisplay bidder code when' + - 'Marketplace and One Mobile GET + POST params are present', () => { - let bidParams = Object.assign(getMarketplaceBidParams(), getNexageGetBidParams(), getNexagePostBidParams()); - let bidRequest = createCustomBidRequest({ - bids: [{ - bidder: 'onedisplay' - }], - params: bidParams - }); - - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url.indexOf(MARKETPLACE_URL)).to.equal(0); - }); - - it('should not resolve endpoint for onedisplay bidder code ' + - 'when only One Mobile params are present', () => { - let bidParams = Object.assign(getNexageGetBidParams(), getNexagePostBidParams()); - let bidRequest = createCustomBidRequest({ - bids: [{ - bidder: 'onedisplay' - }], - params: bidParams - }); - - let [request] = spec.buildRequests(bidRequest.bids); - expect(request).to.be.undefined; - }); - - it('should return Marketplace URL for eu region', function () { - let bidRequest = createCustomBidRequest({ - params: { - placement: 1234567, - network: '9599.1', - region: 'eu' - } - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url.indexOf('https://adserver-eu.adtech.advertising.com/pubapi/3.0/')) - .to.equal(0); - }); - - it('should return insecure MP URL if insecure server option is present', function () { - let bidRequest = createCustomBidRequest({ - params: { - placement: 1234567, - network: '9599.1', - server: 'https://adserver-eu.adtech.advertising.com' - } - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url.indexOf('https://adserver-eu.adtech.advertising.com/pubapi/3.0/')) - .to.equal(0); - }); - - it('should return a secure MP URL if relative proto server option is present', function () { - let bidRequest = createCustomBidRequest({ - params: { - placement: 1234567, - network: '9599.1', - server: 'https://adserver-eu.adtech.advertising.com' - } - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url.indexOf('https://adserver-eu.adtech.advertising.com/pubapi/3.0/')) - .to.equal(0); - }); - - it('should return a secure MP URL when server option without protocol is present', function () { - let bidRequest = createCustomBidRequest({ - params: { - placement: 1234567, - network: '9599.1', - server: 'adserver-eu.adtech.advertising.com' - } - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url.indexOf('https://adserver-eu.adtech.advertising.com/pubapi/3.0/')) - .to.equal(0); - }); - - it('should return default Marketplace URL in case of unknown region config option', function () { - let bidRequest = createCustomBidRequest({ - params: { - placement: 1234567, - network: '9599.1', - region: 'an' - } - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url.indexOf(MARKETPLACE_URL)).to.equal(0); - }); - - it('should return url with pubapi bid option', function () { - let bidRequest = getDefaultBidRequest(); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).to.contain('cmd=bid;'); - }); - - it('should return url with version 2 of pubapi', function () { - let bidRequest = getDefaultBidRequest(); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).to.contain('v=2;'); - }); - - it('should return url with cache busting option', function () { - let bidRequest = getDefaultBidRequest(); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).to.match(/misc=\d+/); - }); - - it('should return url with default pageId and sizeId', function () { - let bidRequest = createCustomBidRequest({ - params: { - placement: 1234567, - network: '9599.1' - } - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).to.contain('/pubapi/3.0/9599.1/1234567/0/0/ADTECH;'); - }); - - it('should return url with custom pageId and sizeId when options are present', function () { - let bidRequest = createCustomBidRequest({ - params: { - placement: 1234567, - network: '9599.1', - pageId: 1111, - sizeId: 2222 - } - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).to.contain('/pubapi/3.0/9599.1/1234567/1111/2222/ADTECH;'); - }); - - it('should return url with default alias if alias param is missing', function () { - let bidRequest = getDefaultBidRequest(); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).to.match(/alias=\w+?;/); - }); - - it('should return url with custom alias if it is present', function () { - let bidRequest = createCustomBidRequest({ - params: { - placement: 1234567, - network: '9599.1', - alias: 'desktop_articlepage_something_box_300_250' - } - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).to.contain('alias=desktop_articlepage_something_box_300_250'); - }); - - it('should return url without bidfloor option if is is missing', function () { - let bidRequest = getDefaultBidRequest(); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).not.to.contain('bidfloor='); - }); - - it('should return url with key values if keyValues param is present', function () { - let bidRequest = createCustomBidRequest({ - params: { - placement: 1234567, - network: '9599.1', - keyValues: { - age: 25, - height: 3.42, - test: 'key' - } - } - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).to.contain('kvage=25;kvheight=3.42;kvtest=key'); - }); - - it('should return request object for One Display when configuration is present', function () { - let bidRequest = getDefaultBidRequest(); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.method).to.equal('GET'); - expect(request.ttl).to.equal(ONE_DISPLAY_TTL); - }); - }); - - describe('One Mobile', function () { - it('should return One Mobile url when One Mobile get params are present', function () { - let bidRequest = createCustomBidRequest({ - params: getNexageGetBidParams() - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).to.contain(NEXAGE_URL); - }); - - it('should return One Mobile url with different host when host option is present', function () { - let bidParams = Object.assign({ - host: 'https://qa-hb.nexage.com' - }, getNexageGetBidParams()); - let bidRequest = createCustomBidRequest({ - params: bidParams - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).to.contain('https://qa-hb.nexage.com/bidRequest?'); - }); - - it('should return One Mobile url when One Mobile and Marketplace params are present', function () { - let bidParams = Object.assign(getNexageGetBidParams(), getMarketplaceBidParams()); - let bidRequest = createCustomBidRequest({ - params: bidParams - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).to.contain(NEXAGE_URL); - }); - - it('should return One Mobile url for onemobile bidder code ' + - 'when One Mobile GET and Marketplace params are present', () => { - let bidParams = Object.assign(getNexageGetBidParams(), getMarketplaceBidParams()); - let bidRequest = createCustomBidRequest({ - bids: [{ - bidder: 'onemobile' - }], - params: bidParams - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).to.contain(NEXAGE_URL); - }); - - it('should not return any url for onemobile bidder code' + - 'when only Marketplace params are present', () => { - let bidRequest = createCustomBidRequest({ - bids: [{ - bidder: 'onemobile' - }], - params: getMarketplaceBidParams() - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request).to.be.undefined; - }); - - it('should return One Mobile url with required params - dcn & pos', function () { - let bidRequest = createCustomBidRequest({ - params: getNexageGetBidParams() - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).to.contain(NEXAGE_URL + 'dcn=2c9d2b50015c5ce9db6aeeed8b9500d6&pos=header'); - }); - - it('should return One Mobile url with cmd=bid option', function () { - let bidRequest = createCustomBidRequest({ - params: getNexageGetBidParams() - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).to.contain('cmd=bid'); - }); - - it('should return One Mobile url with generic params if ext option is present', function () { - let bidRequest = createCustomBidRequest({ - params: { - dcn: '54321123', - pos: 'footer-2324', - ext: { - param1: 'val1', - param2: 'val2', - param3: 'val3', - param4: 'val4' - } - } - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).to.equal('https://c2shb.ssp.yahoo.com/bidRequest?dcn=54321123&pos=footer-2324&cmd=bid' + - '¶m1=val1¶m2=val2¶m3=val3¶m4=val4'); - }); - - Object.keys(SUPPORTED_USER_ID_SOURCES).forEach(source => { - it(`should set the user ID query param for ${source}`, function () { - let bidRequest = createCustomBidRequest({ - params: getNexageGetBidParams() - }); - bidRequest.bids[0].userId = {}; - bidRequest.bids[0].userIdAsEids = createEidsArray(USER_ID_DATA); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).to.contain(`&eid${source}=${encodeURIComponent(SUPPORTED_USER_ID_SOURCES[source])}`); - }); - }); - - it('should return request object for One Mobile POST endpoint when POST configuration is present', function () { - let bidConfig = getNexagePostBidParams(); - let bidRequest = createCustomBidRequest({ - params: bidConfig - }); - - let [request] = spec.buildRequests(bidRequest.bids); - expect(request.url).to.contain(NEXAGE_URL); - expect(request.method).to.equal('POST'); - expect(request.ttl).to.equal(ONE_MOBILE_TTL); - expect(request.data).to.deep.equal(bidConfig); - expect(request.options).to.deep.equal({ - contentType: 'application/json', - customHeaders: { - 'x-openrtb-version': '2.2' - } - }); - }); - - it('should not return request object for One Mobile POST endpoint' + - 'if required parameters are missed', () => { - let bidRequest = createCustomBidRequest({ - params: { - imp: [] - } - }); - let [request] = spec.buildRequests(bidRequest.bids); - expect(request).to.be.undefined; - }); - }); - }); - - describe('buildOpenRtbRequestData', () => { - const bid = { - params: { - id: 'bid-id', - imp: [] - } - }; - let euConsentRequiredStub; - - beforeEach(function () { - euConsentRequiredStub = sinon.stub(spec, 'isEUConsentRequired'); - }); - - afterEach(function () { - euConsentRequiredStub.restore(); - }); - - it('returns the basic bid info when regulation data is omitted', () => { - expect(spec.buildOpenRtbRequestData(bid)).to.deep.equal({ - id: 'bid-id', - imp: [] - }); - }); - - it('returns the basic bid info with gdpr data when gdpr consent data is included', () => { - let consentData = { - gdpr: { - consentString: 'someEUConsent' - } - }; - euConsentRequiredStub.returns(true); - expect(spec.buildOpenRtbRequestData(bid, consentData)).to.deep.equal({ - id: 'bid-id', - imp: [], - regs: { - ext: { - gdpr: 1 - } - }, - user: { - ext: { - consent: 'someEUConsent' - } - } - }); - }); - - it('returns the basic bid info with CCPA data when CCPA consent data is included', () => { - let consentData = { - uspConsent: 'someUSPConsent' - }; - expect(spec.buildOpenRtbRequestData(bid, consentData)).to.deep.equal({ - id: 'bid-id', - imp: [], - regs: { - ext: { - us_privacy: 'someUSPConsent' - } - } - }); - }); - - it('returns the basic bid info with GDPR and CCPA data when GDPR and CCPA consent data is included', () => { - let consentData = { - gdpr: { - consentString: 'someEUConsent' - }, - uspConsent: 'someUSPConsent' - }; - euConsentRequiredStub.returns(true); - expect(spec.buildOpenRtbRequestData(bid, consentData)).to.deep.equal({ - id: 'bid-id', - imp: [], - regs: { - ext: { - gdpr: 1, - us_privacy: 'someUSPConsent' - } - }, - user: { - ext: { - consent: 'someEUConsent' - } - } - }); - }); - - it('returns the bid object with eid array populated with PB set eids', () => { - let userIdBid = Object.assign({ - userId: {} - }, bid); - userIdBid.userIdAsEids = createEidsArray(USER_ID_DATA); - expect(spec.buildOpenRtbRequestData(userIdBid)).to.deep.equal({ - id: 'bid-id', - imp: [], - user: { - ext: { - eids: userIdBid.userIdAsEids - } - } - }); - }); - }); - - describe('getUserSyncs()', function () { - let serverResponses; - let bidResponse; - - beforeEach(function () { - bidResponse = getDefaultBidResponse(); - bidResponse.ext = { - pixels: getPixels() - }; - - serverResponses = [ - {body: bidResponse} - ]; - }); - - it('should return user syncs if pixels are present in the response', function () { - let userSyncs = spec.getUserSyncs({}, serverResponses); - - expect(userSyncs).to.deep.equal([ - {type: 'image', url: 'img.org'}, - {type: 'iframe', url: 'pixels1.org'} - ]); - }); - - it('should not return user syncs if pixels are not present', function () { - bidResponse.ext.pixels = null; - let userSyncs = spec.getUserSyncs({}, serverResponses); - - expect(userSyncs).to.deep.equal([]); - }); - }); - - describe('isOneMobileBidder()', function () { - it('should return false when when bidderCode is not present', () => { - expect(spec.isOneMobileBidder(null)).to.be.false; - }); - - it('should return false for unknown bidder code', function () { - expect(spec.isOneMobileBidder('unknownBidder')).to.be.false; - }); - - it('should return true for aol bidder code', function () { - expect(spec.isOneMobileBidder('aol')).to.be.true; - }); - - it('should return true for one mobile bidder code', function () { - expect(spec.isOneMobileBidder('onemobile')).to.be.true; - }); - }); - - describe('isEUConsentRequired()', function () { - it('should return false when consentData object is not present', function () { - expect(spec.isEUConsentRequired(null)).to.be.false; - }); - - it('should return true when gdprApplies equals true and consentString is not present', function () { - let consentData = { - gdpr: { - consentString: null, - gdprApplies: true - } - }; - - expect(spec.isEUConsentRequired(consentData)).to.be.true; - }); - - it('should return false when consentString is present and gdprApplies equals false', function () { - let consentData = { - gdpr: { - consentString: 'consent-string', - gdprApplies: false - } - }; - - expect(spec.isEUConsentRequired(consentData)).to.be.false; - }); - - it('should return true when consentString is present and gdprApplies equals true', function () { - let consentData = { - gdpr: { - consentString: 'consent-string', - gdprApplies: true - } - }; - - expect(spec.isEUConsentRequired(consentData)).to.be.true; - }); - }); - - describe('formatMarketplaceDynamicParams()', function () { - let formatConsentDataStub; - let formatKeyValuesStub; - - beforeEach(function () { - formatConsentDataStub = sinon.stub(spec, 'formatConsentData'); - formatKeyValuesStub = sinon.stub(spec, 'formatKeyValues'); - }); - - afterEach(function () { - formatConsentDataStub.restore(); - formatKeyValuesStub.restore(); - }); - - it('should return empty string when params are not present', function () { - expect(spec.formatMarketplaceDynamicParams()).to.be.equal(''); - }); - - it('should return formatted EU consent params when formatConsentData returns GDPR data', function () { - formatConsentDataStub.returns({ - euconsent: 'test-consent', - gdpr: 1 - }); - expect(spec.formatMarketplaceDynamicParams()).to.be.equal('euconsent=test-consent;gdpr=1;'); - }); - - it('should return formatted US privacy params when formatConsentData returns USP data', function () { - formatConsentDataStub.returns({ - us_privacy: 'test-usp-consent' - }); - expect(spec.formatMarketplaceDynamicParams()).to.be.equal('us_privacy=test-usp-consent;'); - }); - - it('should return formatted EU and USP consent params when formatConsentData returns all data', function () { - formatConsentDataStub.returns({ - euconsent: 'test-consent', - gdpr: 1, - us_privacy: 'test-usp-consent' - }); - expect(spec.formatMarketplaceDynamicParams()).to.be.equal( - 'euconsent=test-consent;gdpr=1;us_privacy=test-usp-consent;'); - }); - - it('should return formatted params when formatKeyValues returns data', function () { - formatKeyValuesStub.returns({ - param1: 'val1', - param2: 'val2', - param3: 'val3' - }); - expect(spec.formatMarketplaceDynamicParams()).to.be.equal('param1=val1;param2=val2;param3=val3;'); - }); - }); - - describe('formatOneMobileDynamicParams()', function () { - let euConsentRequiredStub; - let secureProtocolStub; - - beforeEach(function () { - euConsentRequiredStub = sinon.stub(spec, 'isEUConsentRequired'); - secureProtocolStub = sinon.stub(spec, 'isSecureProtocol'); - }); - - afterEach(function () { - euConsentRequiredStub.restore(); - secureProtocolStub.restore(); - }); - - it('should return empty string when params are not present', function () { - expect(spec.formatOneMobileDynamicParams()).to.be.equal(''); - }); - - it('should return formatted params when params are present', function () { - let params = { - param1: 'val1', - param2: 'val2', - param3: 'val3' - }; - expect(spec.formatOneMobileDynamicParams(params)).to.contain('¶m1=val1¶m2=val2¶m3=val3'); - }); - - it('should return formatted gdpr params when isEUConsentRequired returns true', function () { - let consentData = { - gdpr: { - consentString: 'test-consent' - } - }; - euConsentRequiredStub.returns(true); - expect(spec.formatOneMobileDynamicParams({}, consentData)).to.be.equal('&gdpr=1&euconsent=test-consent'); - }); - - it('should return formatted US privacy params when consentData contains USP data', function () { - let consentData = { - uspConsent: 'test-usp-consent' - }; - expect(spec.formatMarketplaceDynamicParams({}, consentData)).to.be.equal('us_privacy=test-usp-consent;'); - }); - - it('should return formatted EU and USP consent params when consentData contains gdpr and usp values', function () { - euConsentRequiredStub.returns(true); - let consentData = { - gdpr: { - consentString: 'test-consent' - }, - uspConsent: 'test-usp-consent' - }; - expect(spec.formatMarketplaceDynamicParams({}, consentData)).to.be.equal( - 'gdpr=1;euconsent=test-consent;us_privacy=test-usp-consent;'); - }); - - it('should return formatted secure param when isSecureProtocol returns true', function () { - secureProtocolStub.returns(true); - expect(spec.formatOneMobileDynamicParams()).to.be.equal('&secure=1'); - }); - }); -}); diff --git a/test/spec/modules/apacdexBidAdapter_spec.js b/test/spec/modules/apacdexBidAdapter_spec.js deleted file mode 100644 index 3a71833bc3e..00000000000 --- a/test/spec/modules/apacdexBidAdapter_spec.js +++ /dev/null @@ -1,710 +0,0 @@ -import { expect } from 'chai' -import { spec, validateGeoObject, getDomain } from '../../../modules/apacdexBidAdapter.js' -import { newBidder } from 'src/adapters/bidderFactory.js' -import { userSync } from '../../../src/userSync.js'; -import { config } from 'src/config.js'; - -describe('ApacdexBidAdapter', function () { - const adapter = newBidder(spec) - - describe('.code', function () { - it('should return a bidder code of apacdex', function () { - expect(spec.code).to.equal('apacdex') - }) - }) - - describe('inherited functions', function () { - it('should exist and be a function', function () { - expect(adapter.callBids).to.exist.and.to.be.a('function') - }) - }) - - describe('.isBidRequestValid', function () { - it('should return false if there are no params', () => { - const bid = { - 'bidder': 'apacdex', - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false if there is no siteId param', () => { - const bid = { - 'bidder': 'apacdex', - 'adUnitCode': 'adunit-code', - params: { - site_id: '1a2b3c4d5e6f1a2b3c4d', - }, - 'mediaTypes': { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false if there is no mediaTypes', () => { - const bid = { - 'bidder': 'apacdex', - 'adUnitCode': 'adunit-code', - params: { - siteId: '1a2b3c4d5e6f1a2b3c4d' - }, - 'mediaTypes': { - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return true if the bid is valid', () => { - const bid = { - 'bidder': 'apacdex', - 'adUnitCode': 'adunit-code', - params: { - siteId: '1a2b3c4d5e6f1a2b3c4d' - }, - 'mediaTypes': { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - describe('banner', () => { - it('should return false if there are no banner sizes', () => { - const bid = { - 'bidder': 'apacdex', - 'adUnitCode': 'adunit-code', - params: { - siteId: '1a2b3c4d5e6f1a2b3c4d' - }, - 'mediaTypes': { - banner: { - - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return true if there is banner sizes', () => { - const bid = { - 'bidder': 'apacdex', - 'adUnitCode': 'adunit-code', - params: { - siteId: '1a2b3c4d5e6f1a2b3c4d' - }, - 'mediaTypes': { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - }); - - describe('video', () => { - it('should return false if there is no playerSize defined in the video mediaType', () => { - const bid = { - 'bidder': 'apacdex', - 'adUnitCode': 'adunit-code', - params: { - siteId: '1a2b3c4d5e6f1a2b3c4d', - sizes: [[300, 250], [300, 600]] - }, - 'mediaTypes': { - video: { - context: 'instream' - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return true if there is playerSize defined on the video mediaType', () => { - const bid = { - 'bidder': 'apacdex', - 'adUnitCode': 'adunit-code', - params: { - siteId: '1a2b3c4d5e6f1a2b3c4d', - }, - 'mediaTypes': { - video: { - context: 'instream', - playerSize: [[640, 480]] - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - }); - }); - - describe('.buildRequests', function () { - beforeEach(function () { - sinon.stub(userSync, 'canBidderRegisterSync'); - }); - afterEach(function () { - userSync.canBidderRegisterSync.restore(); - }); - let bidRequest = [{ - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'indirectseller.com', - 'sid': '00001', - 'hp': 1 - }, - { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 0 - }, - ] - }, - 'bidder': 'apacdex', - 'params': { - 'siteId': '1a2b3c4d5e6f1a2b3c4d', - 'geo': {'lat': 123.13123456, 'lon': 54.23467311, 'accuracy': 60} - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'targetKey': 0, - 'bidId': '30b31c1838de1f', - 'userIdAsEids': [{ - 'source': 'criteo.com', - 'uids': [{ - 'id': 'p0cCLF9JazY1ZUFjazJRb3NKbEprVTcwZ0IwRUlGalBjOG9laUZNbFJ0ZGpOSnVFbE9VMjBNMzNBTzladGt4cUVGQzBybDY2Y1FqT1dkUkFsMmJIWDRHNjlvNXJjbiUyQlZDd1dOTmt6VlV2TDhRd0F0RTlBcmpyZU5WRHBPU25GQXpyMnlT', - 'atype': 1 - }] - }, { - 'source': 'pubcid.org', - 'uids': [{ - 'id': '2ae366c2-2576-45e5-bd21-72ed10598f17', - 'atype': 1 - }] - }, { - 'source': 'sharedid.org', - 'uids': [{ - 'id': '01EZXQDVAPER4KE1VBS29XKV4Z', - 'atype': 1, - 'ext': { - 'third': '01EZXQDVAPER4KE1VBS29XKV4Z' - } - }] - }], - }, - { - 'bidder': 'apacdex', - 'params': { - 'ad_unit': '/7780971/sparks_prebid_LB', - 'sizes': [[300, 250], [300, 600]], - 'referrer': 'overrides_top_window_location' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[120, 600], [300, 600], [160, 600]], - 'targetKey': 1, - 'bidId': '30b31c1838de1e', - }]; - - let bidderRequests = { - 'gdprConsent': { - 'consentString': 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', - 'vendorData': {}, - 'gdprApplies': true - }, - 'refererInfo': { - 'numIframes': 0, - 'reachedTop': true, - 'referer': 'https://example.com', - 'stack': ['https://example.com'] - }, - uspConsent: 'someCCPAString' - }; - - it('should return a properly formatted request', function () { - const bidRequests = spec.buildRequests(bidRequest, bidderRequests) - expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/apacdex') - expect(bidRequests.method).to.equal('POST') - expect(bidRequests.bidderRequests).to.eql(bidRequest); - }) - - it('should return a properly formatted request with GDPR applies set to true', function () { - const bidRequests = spec.buildRequests(bidRequest, bidderRequests) - expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/apacdex') - expect(bidRequests.method).to.equal('POST') - expect(bidRequests.data.gdpr.gdprApplies).to.equal(true) - expect(bidRequests.data.gdpr.consentString).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A==') - }) - - it('should return a properly formatted request with GDPR applies set to false', function () { - bidderRequests.gdprConsent.gdprApplies = false; - const bidRequests = spec.buildRequests(bidRequest, bidderRequests) - expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/apacdex') - expect(bidRequests.method).to.equal('POST') - expect(bidRequests.data.gdpr.gdprApplies).to.equal(false) - expect(bidRequests.data.gdpr.consentString).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A==') - }) - it('should return a properly formatted request with GDPR applies set to false with no consent_string param', function () { - let bidderRequests = { - 'gdprConsent': { - 'consentString': undefined, - 'vendorData': {}, - 'gdprApplies': false - }, - 'refererInfo': { - 'numIframes': 0, - 'reachedTop': true, - 'referer': 'https://example.com', - 'stack': ['https://example.com'] - } - }; - const bidRequests = spec.buildRequests(bidRequest, bidderRequests) - expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/apacdex') - expect(bidRequests.method).to.equal('POST') - expect(bidRequests.data.gdpr.gdprApplies).to.equal(false) - expect(bidRequests.data.gdpr).to.not.include.keys('consentString') - }) - it('should return a properly formatted request with GDPR applies set to true with no consentString param', function () { - let bidderRequests = { - 'gdprConsent': { - 'consentString': undefined, - 'vendorData': {}, - 'gdprApplies': true - }, - 'refererInfo': { - 'numIframes': 0, - 'reachedTop': true, - 'referer': 'https://example.com', - 'stack': ['https://example.com'] - } - }; - const bidRequests = spec.buildRequests(bidRequest, bidderRequests) - expect(bidRequests.url).to.equal('https://useast.quantumdex.io/auction/apacdex') - expect(bidRequests.method).to.equal('POST') - expect(bidRequests.data.gdpr.gdprApplies).to.equal(true) - expect(bidRequests.data.gdpr).to.not.include.keys('consentString') - }) - it('should return a properly formatted request with schain defined', function () { - const bidRequests = spec.buildRequests(bidRequest, bidderRequests); - expect(bidRequests.data.schain).to.deep.equal(bidRequest[0].schain) - }); - it('should return a properly formatted request with eids defined', function () { - const bidRequests = spec.buildRequests(bidRequest, bidderRequests); - expect(bidRequests.data.eids).to.deep.equal(bidRequest[0].userIdAsEids) - }); - it('should return a properly formatted request with geo defined', function () { - const bidRequests = spec.buildRequests(bidRequest, bidderRequests); - expect(bidRequests.data.geo).to.deep.equal(bidRequest[0].params.geo) - }); - it('should return a properly formatted request with us_privacy included', function () { - const bidRequests = spec.buildRequests(bidRequest, bidderRequests); - expect(bidRequests.data.us_privacy).to.equal('someCCPAString'); - }); - describe('debug test', function() { - beforeEach(function() { - config.setConfig({debug: true}); - }); - afterEach(function() { - config.setConfig({debug: false}); - }); - it('should return a properly formatted request with pbjs_debug is true', function () { - const bidRequests = spec.buildRequests(bidRequest, bidderRequests); - expect(bidRequests.data.test).to.equal(1); - }); - }); - }); - - describe('.interpretResponse', function () { - const bidRequests = { - 'method': 'POST', - 'url': 'https://useast.quantumdex.io/auction/apacdex', - 'withCredentials': true, - 'data': { - 'device': { - 'ua': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36', - 'height': 937, - 'width': 1920, - 'dnt': 0, - 'language': 'vi' - }, - 'site': { - 'id': '343', - 'page': 'https://www.example.com/page', - 'referrer': '', - 'hostname': 'www.example.com' - } - }, - 'bidderRequests': [ - { - 'bidder': 'apacdex', - 'params': { - 'siteId': '343' - }, - 'crumbs': { - 'pubcid': 'c2b2ba08-9954-4850-8ee5-2bf4a2b35eff' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[160, 600], [120, 600]] - } - }, - 'adUnitCode': 'vi_3431035_1', - 'transactionId': '994d8404-4a28-4c43-98d8-a38dbb061910', - 'sizes': [[160, 600], [120, 600]], - 'bidId': '3000aa31c41a29c21', - 'bidderRequestId': '299926b3d3628cdd7', - 'auctionId': '22445943-a0aa-4c63-a413-4deb64fcff1c', - 'src': 'client', - 'bidRequestsCount': 41, - 'bidderRequestsCount': 41, - 'bidderWinsCount': 0, - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'freegames66.com', - 'sid': '343', - 'hp': 1 - } - ] - } - }, - { - 'bidder': 'apacdex', - 'params': { - 'siteId': '343' - }, - 'crumbs': { - 'pubcid': 'c2b2ba08-9954-4850-8ee5-2bf4a2b35eff' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [250, 250], [200, 200], [180, 150]] - } - }, - 'adUnitCode': 'vi_3431033_1', - 'transactionId': '800fe87e-bfec-43a5-ace0-c4e2373ff4b5', - 'sizes': [[300, 250], [250, 250], [200, 200], [180, 150]], - 'bidId': '30024615be22ef66a', - 'bidderRequestId': '299926b3d3628cdd7', - 'auctionId': '22445943-a0aa-4c63-a413-4deb64fcff1c', - 'src': 'client', - 'bidRequestsCount': 41, - 'bidderRequestsCount': 41, - 'bidderWinsCount': 0, - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'freegames66.com', - 'sid': '343', - 'hp': 1 - } - ] - } - }, - { - 'bidder': 'apacdex', - 'params': { - 'siteId': '343' - }, - 'crumbs': { - 'pubcid': 'c2b2ba08-9954-4850-8ee5-2bf4a2b35eff' - }, - 'mediaTypes': { - 'video': { - 'playerSize': [[640, 480]], - 'context': 'instream', - 'mimes': [ - 'video/mp4', - 'video/x-flv', - 'video/x-ms-wmv', - 'application/vnd.apple.mpegurl', - 'application/x-mpegurl', - 'video/3gpp', - 'video/mpeg', - 'video/ogg', - 'video/quicktime', - 'video/webm', - 'video/x-m4v', - 'video/ms-asf', - 'video/x-msvideo' - ], - 'protocols': [1, 2, 3, 4, 5, 6], - 'playbackmethod': [6], - 'maxduration': 120, - 'linearity': 1, - 'api': [2] - } - }, - 'adUnitCode': 'vi_3431909', - 'transactionId': '33d83d87-43cc-499b-aabe-5c22eb6acfbb', - 'sizes': [[640, 480]], - 'bidId': '1854b40107d6745c', - 'bidderRequestId': '1840763b6bda185d', - 'auctionId': 'df495de0-5d42-471f-a501-73bcd7254b80', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0, - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'freegames66.com', - 'sid': '343', - 'hp': 1 - } - ] - } - } - ] - }; - - let serverResponse = { - 'body': { - 'bids': [ - { - 'requestId': '3000aa31c41a29c21', - 'cpm': 1.07, - 'width': 160, - 'height': 600, - 'ad': `
Apacdex AD
`, - 'ttl': 500, - 'creativeId': '1234abcd', - 'netRevenue': true, - 'currency': 'USD', - 'dealId': 'apacdex', - 'mediaType': 'banner' - }, - { - 'requestId': '30024615be22ef66a', - 'cpm': 1, - 'width': 300, - 'height': 250, - 'ad': `
Apacdex AD
`, - 'ttl': 500, - 'creativeId': '1234abcd', - 'netRevenue': true, - 'currency': 'USD', - 'dealId': 'apacdex', - 'mediaType': 'banner' - }, - { - 'requestId': '1854b40107d6745c', - 'cpm': 1.25, - 'width': 300, - 'height': 250, - 'vastXml': 'apacdex', - 'ttl': 500, - 'creativeId': '30292e432662bd5f86d90774b944b038', - 'netRevenue': true, - 'currency': 'USD', - 'dealId': 'apacdex', - 'mediaType': 'video' - } - ], - 'pixel': [{ - 'url': 'https://example.com/pixel.png', - 'type': 'image' - }] - } - }; - - let prebidResponse = [ - { - 'requestId': '3000aa31c41a29c21', - 'cpm': 1.07, - 'width': 160, - 'height': 600, - 'ad': `
Apacdex AD
`, - 'ttl': 500, - 'creativeId': '1234abcd', - 'netRevenue': true, - 'currency': 'USD', - 'dealId': 'apacdex', - 'mediaType': 'banner' - }, - { - 'requestId': '30024615be22ef66a', - 'cpm': 1, - 'width': 300, - 'height': 250, - 'ad': `
Apacdex AD
`, - 'ttl': 500, - 'creativeId': '1234abcd', - 'netRevenue': true, - 'currency': 'USD', - 'dealId': 'apacdex', - 'mediaType': 'banner' - }, - { - 'requestId': '1854b40107d6745c', - 'cpm': 1.25, - 'width': 300, - 'height': 250, - 'vastXml': 'apacdex', - 'ttl': 500, - 'creativeId': '30292e432662bd5f86d90774b944b038', - 'netRevenue': true, - 'currency': 'USD', - 'dealId': 'apacdex', - 'mediaType': 'video' - } - ]; - - it('should map bidResponse to prebidResponse', function () { - const response = spec.interpretResponse(serverResponse, bidRequests); - response.forEach((resp, i) => { - expect(resp.requestId).to.equal(prebidResponse[i].requestId); - expect(resp.cpm).to.equal(prebidResponse[i].cpm); - expect(resp.width).to.equal(prebidResponse[i].width); - expect(resp.height).to.equal(prebidResponse[i].height); - expect(resp.ttl).to.equal(prebidResponse[i].ttl); - expect(resp.creativeId).to.equal(prebidResponse[i].creativeId); - expect(resp.netRevenue).to.equal(prebidResponse[i].netRevenue); - expect(resp.currency).to.equal(prebidResponse[i].currency); - expect(resp.dealId).to.equal(prebidResponse[i].dealId); - if (resp.mediaType === 'video') { - expect(resp.vastXml.indexOf('apacdex')).to.be.greaterThan(0); - } - if (resp.mediaType === 'banner') { - expect(resp.ad.indexOf('Apacdex AD')).to.be.greaterThan(0); - } - }); - }); - }); - - describe('.getUserSyncs', function () { - let bidResponse = [{ - 'body': { - 'pixel': [{ - 'url': 'https://pixel-test', - 'type': 'image' - }] - } - }]; - - it('should return one sync pixel', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, bidResponse)).to.deep.equal([{ - type: 'image', - url: 'https://pixel-test' - }]); - }); - it('should return an empty array when sync is enabled but there are no bidResponses', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, [])).to.have.length(0); - }); - - it('should return an empty array when sync is enabled but no sync pixel returned', function () { - const pixel = Object.assign({}, bidResponse); - delete pixel[0].body.pixel; - expect(spec.getUserSyncs({ pixelEnabled: true }, bidResponse)).to.have.length(0); - }); - - it('should return an empty array', function () { - expect(spec.getUserSyncs({ pixelEnabled: false }, bidResponse)).to.have.length(0); - expect(spec.getUserSyncs({ pixelEnabled: true }, [])).to.have.length(0); - }); - }); - - describe('validateGeoObject', function () { - it('should return true if the geo object is valid', () => { - let geoObject = { - lat: 123.5624234, - lon: 23.6712341, - accuracy: 20 - }; - expect(validateGeoObject(geoObject)).to.equal(true); - }); - - it('should return false if the geo object is not plain object', () => { - let geoObject = [{ - lat: 123.5624234, - lon: 23.6712341, - accuracy: 20 - }]; - expect(validateGeoObject(geoObject)).to.equal(false); - }); - - it('should return false if the geo object is missing lat attribute', () => { - let geoObject = { - lon: 23.6712341, - accuracy: 20 - }; - expect(validateGeoObject(geoObject)).to.equal(false); - }); - - it('should return false if the geo object is missing lon attribute', () => { - let geoObject = { - lat: 123.5624234, - accuracy: 20 - }; - expect(validateGeoObject(geoObject)).to.equal(false); - }); - - it('should return false if the geo object is missing accuracy attribute', () => { - let geoObject = { - lat: 123.5624234, - lon: 23.6712341 - }; - expect(validateGeoObject(geoObject)).to.equal(false); - }); - }); - - describe('getDomain', function () { - it('should return valid domain from publisherDomain config', () => { - let pageUrl = 'https://www.example.com/page/prebid/exam.html'; - config.setConfig({publisherDomain: pageUrl}); - expect(getDomain(pageUrl)).to.equal('example.com'); - }); - it('should return valid domain from pageUrl argument', () => { - let pageUrl = 'https://www.example.com/page/prebid/exam.html'; - config.setConfig({publisherDomain: ''}); - expect(getDomain(pageUrl)).to.equal('example.com'); - }); - it('should return undefined if pageUrl and publisherDomain not config', () => { - let pageUrl; - config.setConfig({publisherDomain: ''}); - expect(getDomain(pageUrl)).to.equal(pageUrl); - }); - }); -}); diff --git a/test/spec/modules/appierAnalyticsAdapter_spec.js b/test/spec/modules/appierAnalyticsAdapter_spec.js deleted file mode 100644 index cd026f64d49..00000000000 --- a/test/spec/modules/appierAnalyticsAdapter_spec.js +++ /dev/null @@ -1,705 +0,0 @@ -import { - appierAnalyticsAdapter, getCpmInUsd, parseBidderCode, parseAdUnitCode, - ANALYTICS_VERSION, BIDDER_STATUS -} from 'modules/appierAnalyticsAdapter.js'; -import {expect} from 'chai'; -const events = require('src/events'); -const constants = require('src/constants.json'); - -const affiliateId = 'WhctHaViHtI'; -const configId = 'd9cc9a9be9b240eda17cf1c9a8a4b29c'; -const serverUrl = 'https://analytics.server.url/v1'; -const autoPick = 'none'; -const predictionId = '2a91ca5de54a4a2e89950af439f7a27f'; -const auctionId = 'b0b39610-b941-4659-a87c-de9f62d3e13e'; - -describe('Appier Prebid AnalyticsAdapter Testing', function () { - describe('event tracking and message cache manager', function () { - beforeEach(function () { - const configOptions = { - affiliateId: affiliateId, - configId: configId, - server: serverUrl, - autoPick: autoPick, - predictionId: predictionId, - sampling: 0, - adSampling: 1, - }; - - appierAnalyticsAdapter.enableAnalytics({ - provider: 'appierAnalytics', - options: configOptions - }); - }); - - afterEach(function () { - appierAnalyticsAdapter.disableAnalytics(); - }); - - describe('#getCpmInUsd()', function() { - it('should get bid cpm as currency is USD', function() { - const receivedBids = [ - { - auctionId: auctionId, - adUnitCode: 'adunit_1', - bidder: 'appier', - bidderCode: 'APPIER', - requestId: 'a1b2c3d4', - timeToRespond: 72, - cpm: 0.1, - currency: 'USD', - originalCpm: 0.1, - originalCurrency: 'USD', - ad: 'fake ad1' - }, - ] - const result = getCpmInUsd(receivedBids[0]); - expect(result).to.equal(0.1); - }); - }); - - describe('#parseBidderCode()', function() { - it('should get lower case bidder code from bidderCode field value', function() { - const receivedBids = [ - { - auctionId: auctionId, - adUnitCode: 'adunit_1', - bidder: 'appier', - bidderCode: 'APPIER', - requestId: 'a1b2c3d4', - timeToRespond: 72, - cpm: 0.1, - currency: 'USD', - originalCpm: 0.1, - originalCurrency: 'USD', - ad: 'fake ad1' - }, - ]; - const result = parseBidderCode(receivedBids[0]); - expect(result).to.equal('appier'); - }); - it('should get lower case bidder code from bidder field value as bidderCode field is missing', function() { - const receivedBids = [ - { - auctionId: auctionId, - adUnitCode: 'adunit_1', - bidder: 'APPIER', - bidderCode: '', - requestId: 'a1b2c3d4', - timeToRespond: 72, - cpm: 0.1, - currency: 'USD', - originalCpm: 0.1, - originalCurrency: 'USD', - ad: 'fake ad1' - }, - ]; - const result = parseBidderCode(receivedBids[0]); - expect(result).to.equal('appier'); - }); - }); - - describe('#parseAdUnitCode()', function() { - it('should get lower case adUnit code from adUnitCode field value', function() { - const receivedBids = [ - { - auctionId: auctionId, - adUnitCode: 'ADUNIT', - bidder: 'appier', - bidderCode: 'APPIER', - requestId: 'a1b2c3d4', - timeToRespond: 72, - cpm: 0.1, - currency: 'USD', - originalCpm: 0.1, - originalCurrency: 'USD', - ad: 'fake ad1' - }, - ]; - const result = parseAdUnitCode(receivedBids[0]); - expect(result).to.equal('adunit'); - }); - }); - - describe('#getCachedAuction()', function() { - const existing = {timeoutBids: [{}]}; - appierAnalyticsAdapter.cachedAuctions['test_auction_id'] = existing; - - it('should get the existing cached object if it exists', function() { - const result = appierAnalyticsAdapter.getCachedAuction('test_auction_id'); - - expect(result).to.equal(existing); - }); - - it('should create a new object and store it in the cache on cache miss', function() { - const result = appierAnalyticsAdapter.getCachedAuction('no_such_id'); - - expect(result).to.deep.include({ - timeoutBids: [], - }); - }); - }); - - describe('when formatting JSON payload sent to backend', function() { - const receivedBids = [ - { - auctionId: auctionId, - adUnitCode: 'adunit_1', - bidder: 'appier', - bidderCode: 'appier', - requestId: 'a1b2c3d4', - timeToRespond: 72, - cpm: 0.1, - currency: 'USD', - originalCpm: 0.1, - originalCurrency: 'USD', - ad: 'fake ad1' - }, - { - auctionId: auctionId, - adUnitCode: 'adunit_1', - bidder: 'reippa', - bidderCode: 'reippa', - requestId: 'b2c3d4e5', - timeToRespond: 100, - cpm: 0.08, - currency: 'USD', - originalCpm: 0.08, - originalCurrency: 'USD', - ad: 'fake ad2' - }, - { - auctionId: auctionId, - adUnitCode: 'adunit_2', - bidder: 'appier', - bidderCode: 'appier', - requestId: 'c3d4e5f6', - timeToRespond: 120, - cpm: 0.09, - currency: 'USD', - originalCpm: 0.09, - originalCurrency: 'USD', - ad: 'fake ad3' - }, - ]; - const highestCpmBids = [ - { - auctionId: auctionId, - adUnitCode: 'adunit_1', - bidder: 'appier', - bidderCode: 'appier', - // No requestId - timeToRespond: 72, - cpm: 0.1, - currency: 'USD', - originalCpm: 0.1, - originalCurrency: 'USD', - ad: 'fake ad1' - } - ]; - const noBids = [ - { - auctionId: auctionId, - adUnitCode: 'adunit_2', - bidder: 'appier', - bidderCode: 'appier', - bidId: 'a1b2c3d4', - } - ]; - const timeoutBids = [ - { - auctionId: auctionId, - adUnitCode: 'adunit_2', - bidder: 'reippa', - bidderCode: 'reippa', - bidId: '00123d4c', - } - ]; - const withoutOriginalCpmBids = [ - { - auctionId: auctionId, - adUnitCode: 'adunit_2', - bidder: 'appier', - bidderCode: 'appier', - requestId: 'c3d4e5f6', - timeToRespond: 120, - cpm: 0.29, - currency: 'USD', - originalCpm: '', - originalCurrency: 'USD', - ad: 'fake ad3' - }, - ]; - const withoutOriginalCurrencyBids = [ - { - auctionId: auctionId, - adUnitCode: 'adunit_2', - bidder: 'appier', - bidderCode: 'appier', - requestId: 'c3d4e5f6', - timeToRespond: 120, - cpm: 0.09, - currency: 'USD', - originalCpm: 0.09, - originalCurrency: '', - ad: 'fake ad3' - }, - ]; - function assertHavingRequiredMessageFields(message) { - expect(message).to.include({ - version: ANALYTICS_VERSION, - auctionId: auctionId, - affiliateId: affiliateId, - configId: configId, - // referrer: window.location.href, - sampling: 0, - adSampling: 1, - prebid: '$prebid.version$', - // autoPick: 'manual', - }); - } - - describe('#createCommonMessage', function() { - it('should correctly serialize some common fields', function() { - const message = appierAnalyticsAdapter.createCommonMessage(auctionId); - - assertHavingRequiredMessageFields(message); - }); - }); - - describe('#serializeBidResponse', function() { - it('should handle BID properly and serialize bid price related fields', function() { - const result = appierAnalyticsAdapter.serializeBidResponse(receivedBids[0], BIDDER_STATUS.BID); - - expect(result).to.include({ - prebidWon: false, - isTimeout: false, - status: BIDDER_STATUS.BID, - time: 72, - cpm: 0.1, - currency: 'USD', - originalCpm: 0.1, - originalCurrency: 'USD', - cpmUsd: 0.1, - }); - }); - - it('should handle NO_BID properly and set status to noBid', function() { - const result = appierAnalyticsAdapter.serializeBidResponse(noBids[0], BIDDER_STATUS.NO_BID); - - expect(result).to.include({ - prebidWon: false, - isTimeout: false, - status: BIDDER_STATUS.NO_BID, - }); - }); - - it('should handle BID_WON properly and serialize bid price related fields', function() { - const result = appierAnalyticsAdapter.serializeBidResponse(receivedBids[0], BIDDER_STATUS.BID_WON); - - expect(result).to.include({ - prebidWon: true, - isTimeout: false, - status: BIDDER_STATUS.BID_WON, - time: 72, - cpm: 0.1, - currency: 'USD', - originalCpm: 0.1, - originalCurrency: 'USD', - cpmUsd: 0.1, - }); - }); - - it('should handle TIMEOUT properly and set status to timeout and isTimeout to true', function() { - const result = appierAnalyticsAdapter.serializeBidResponse(noBids[0], BIDDER_STATUS.TIMEOUT); - - expect(result).to.include({ - prebidWon: false, - isTimeout: true, - status: BIDDER_STATUS.TIMEOUT, - }); - }); - - it('should handle BID_WON properly and fill originalCpm field with cpm in missing originalCpm case', function() { - const result = appierAnalyticsAdapter.serializeBidResponse(withoutOriginalCpmBids[0], BIDDER_STATUS.BID_WON); - - expect(result).to.include({ - prebidWon: true, - isTimeout: false, - status: BIDDER_STATUS.BID_WON, - time: 120, - cpm: 0.29, - currency: 'USD', - originalCpm: 0.29, - originalCurrency: 'USD', - cpmUsd: 0.29, - }); - }); - - it('should handle BID_WON properly and fill originalCurrency field with currency in missing originalCurrency case', function() { - const result = appierAnalyticsAdapter.serializeBidResponse(withoutOriginalCurrencyBids[0], BIDDER_STATUS.BID_WON); - expect(result).to.include({ - prebidWon: true, - isTimeout: false, - status: BIDDER_STATUS.BID_WON, - time: 120, - cpm: 0.09, - currency: 'USD', - originalCpm: 0.09, - originalCurrency: 'USD', - cpmUsd: 0.09, - }); - }); - }); - - describe('#addBidResponseToMessage()', function() { - it('should add a bid response in the output message, grouped by adunit_id and bidder', function() { - const message = { - adUnits: {} - }; - appierAnalyticsAdapter.addBidResponseToMessage(message, noBids[0], BIDDER_STATUS.NO_BID); - - expect(message.adUnits).to.deep.include({ - 'adunit_2': { - 'appier': { - prebidWon: false, - isTimeout: false, - status: BIDDER_STATUS.NO_BID, - } - } - }); - }); - }); - - describe('#createBidMessage()', function() { - it('should format auction message sent to the backend', function() { - const args = { - auctionId: auctionId, - timestamp: 1234567890, - timeout: 3000, - auctionEnd: 1234567990, - adUnitCodes: ['adunit_1', 'adunit_2'], - bidsReceived: receivedBids, - noBids: noBids - }; - - const result = appierAnalyticsAdapter.createBidMessage(args, highestCpmBids, timeoutBids); - - assertHavingRequiredMessageFields(result); - expect(result).to.deep.include({ - auctionElapsed: 100, - timeout: 3000, - adUnits: { - 'adunit_1': { - 'appier': { - prebidWon: true, - isTimeout: false, - status: BIDDER_STATUS.BID, - time: 72, - cpm: 0.1, - currency: 'USD', - originalCpm: 0.1, - originalCurrency: 'USD', - cpmUsd: 0.1, - }, - 'reippa': { - prebidWon: false, - isTimeout: false, - status: BIDDER_STATUS.BID, - time: 100, - cpm: 0.08, - currency: 'USD', - originalCpm: 0.08, - originalCurrency: 'USD', - cpmUsd: 0.08, - } - }, - 'adunit_2': { - // this bid result exists in both bid and noBid arrays and should be treated as bid - 'appier': { - prebidWon: false, - isTimeout: false, - time: 120, - cpm: 0.09, - currency: 'USD', - originalCpm: 0.09, - originalCurrency: 'USD', - cpmUsd: 0.09, - status: BIDDER_STATUS.BID, - }, - 'reippa': { - prebidWon: false, - isTimeout: true, - status: BIDDER_STATUS.TIMEOUT, - } - } - } - }); - }); - }); - - describe('#createImpressionMessage()', function() { - it('should format message sent to the backend with the bid result', function() { - const bid = receivedBids[0]; - const result = appierAnalyticsAdapter.createImpressionMessage(bid); - - assertHavingRequiredMessageFields(result); - expect(result.adUnits).to.deep.include({ - 'adunit_1': { - 'appier': { - prebidWon: true, - isTimeout: false, - status: BIDDER_STATUS.BID_WON, - time: 72, - cpm: 0.1, - currency: 'USD', - originalCpm: 0.1, - originalCurrency: 'USD', - cpmUsd: 0.1, - } - } - }); - }); - }); - - describe('#createCreativeMessage()', function() { - it('should generate message sent to the backend with ad html grouped by adunit and bidder', function() { - const result = appierAnalyticsAdapter.createCreativeMessage(auctionId, receivedBids); - - assertHavingRequiredMessageFields(result); - expect(result.adUnits).to.deep.include({ - 'adunit_1': { - 'appier': { - ad: 'fake ad1' - }, - 'reippa': { - ad: 'fake ad2' - }, - }, - 'adunit_2': { - 'appier': { - ad: 'fake ad3' - } - } - }); - }); - }); - describe('#handleBidTimeout()', function() { - it('should cached the timeout bid as BID_TIMEOUT event was triggered', function() { - appierAnalyticsAdapter.cachedAuctions['test_timeout_auction_id'] = { 'timeoutBids': [] }; - const args = [{ - auctionId: 'test_timeout_auction_id', - timestamp: 1234567890, - timeout: 3000, - auctionEnd: 1234567990, - bidsReceived: receivedBids, - noBids: noBids - }]; - - appierAnalyticsAdapter.handleBidTimeout(args); - const result = appierAnalyticsAdapter.getCachedAuction('test_timeout_auction_id'); - expect(result).to.deep.include({ - timeoutBids: [{ - auctionId: 'test_timeout_auction_id', - timestamp: 1234567890, - timeout: 3000, - auctionEnd: 1234567990, - bidsReceived: receivedBids, - noBids: noBids - }] - }); - }); - }); - describe('#handleBidWon()', function() { - it('should call createImpressionMessage once as BID_WON event was triggered', function() { - sinon.spy(appierAnalyticsAdapter, 'createImpressionMessage'); - const receivedBids = [ - { - auctionId: auctionId, - adUnitCode: 'adunit_1', - bidder: 'appier', - bidderCode: 'appier', - requestId: 'a1b2c3d4', - timeToRespond: 72, - cpm: 0.1, - currency: 'USD', - originalCpm: 0.1, - originalCurrency: 'USD', - ad: 'fake ad1' - }, - ] - - appierAnalyticsAdapter.handleBidWon(receivedBids[0]); - sinon.assert.callCount(appierAnalyticsAdapter.createImpressionMessage, 1); - appierAnalyticsAdapter.createImpressionMessage.restore(); - }); - }); - }); - }); - - describe('Appier Analytics Adapter track handler ', function () { - const configOptions = { - affiliateId: affiliateId, - configId: configId, - server: serverUrl, - autoPick: autoPick, - sampling: 1, - adSampling: 1, - }; - - beforeEach(function () { - sinon.stub(events, 'getEvents').returns([]); - appierAnalyticsAdapter.enableAnalytics({ - provider: 'appierAnalytics', - options: configOptions - }); - }); - - afterEach(function () { - appierAnalyticsAdapter.disableAnalytics(); - events.getEvents.restore(); - }); - - it('should call handleBidWon as BID_WON trigger event', function() { - sinon.spy(appierAnalyticsAdapter, 'handleBidWon'); - events.emit(constants.EVENTS.BID_WON, {}); - sinon.assert.callCount(appierAnalyticsAdapter.handleBidWon, 1); - appierAnalyticsAdapter.handleBidWon.restore(); - }); - - it('should call handleBidTimeout as BID_TIMEOUT trigger event', function() { - sinon.spy(appierAnalyticsAdapter, 'handleBidTimeout'); - events.emit(constants.EVENTS.BID_TIMEOUT, {}); - sinon.assert.callCount(appierAnalyticsAdapter.handleBidTimeout, 1); - appierAnalyticsAdapter.handleBidTimeout.restore(); - }); - - it('should call handleAuctionEnd as AUCTION_END trigger event', function() { - sinon.spy(appierAnalyticsAdapter, 'handleAuctionEnd'); - events.emit(constants.EVENTS.AUCTION_END, {}); - sinon.assert.callCount(appierAnalyticsAdapter.handleAuctionEnd, 1); - appierAnalyticsAdapter.handleAuctionEnd.restore(); - }); - - it('should call createCreativeMessage as AUCTION_END trigger event in adSampled is true', function() { - const configOptions = { - options: { - affiliateId: affiliateId, - configId: configId, - server: serverUrl, - autoPick: autoPick, - sampling: 1, - adSampling: 1, - adSampled: true, - } - }; - const args = { - auctionId: 'test_timeout_auction_id', - timestamp: 1234567890, - timeout: 3000, - auctionEnd: 1234567990, - }; - appierAnalyticsAdapter.initConfig(configOptions); - sinon.stub(appierAnalyticsAdapter, 'sendEventMessage').returns({}); - sinon.stub(appierAnalyticsAdapter, 'createBidMessage').returns({}); - sinon.spy(appierAnalyticsAdapter, 'createCreativeMessage'); - events.emit(constants.EVENTS.AUCTION_END, args); - sinon.assert.callCount(appierAnalyticsAdapter.createCreativeMessage, 1); - appierAnalyticsAdapter.sendEventMessage.restore(); - appierAnalyticsAdapter.createBidMessage.restore(); - appierAnalyticsAdapter.createCreativeMessage.restore(); - }); - }); - - describe('enableAnalytics and config parser', function () { - const configOptions = { - affiliateId: affiliateId, - configId: configId, - server: serverUrl, - autoPick: autoPick, - sampling: 0, - adSampling: 1, - }; - - beforeEach(function () { - appierAnalyticsAdapter.enableAnalytics({ - provider: 'appierAnalytics', - options: configOptions - }); - }); - - afterEach(function () { - appierAnalyticsAdapter.disableAnalytics(); - }); - - it('should parse config correctly with optional values', function () { - expect(appierAnalyticsAdapter.getAnalyticsOptions().options).to.deep.equal(configOptions); - expect(appierAnalyticsAdapter.getAnalyticsOptions().affiliateId).to.equal(configOptions.affiliateId); - expect(appierAnalyticsAdapter.getAnalyticsOptions().configId).to.equal(configOptions.configId); - expect(appierAnalyticsAdapter.getAnalyticsOptions().server).to.equal(configOptions.server); - expect(appierAnalyticsAdapter.getAnalyticsOptions().autoPick).to.equal(configOptions.autoPick); - expect(appierAnalyticsAdapter.getAnalyticsOptions().sampled).to.equal(false); - expect(appierAnalyticsAdapter.getAnalyticsOptions().adSampled).to.equal(true); - }); - - it('should not enable Analytics when affiliateId is missing', function () { - const configOptions = { - options: { - configId: configId - } - }; - const validConfig = appierAnalyticsAdapter.initConfig(configOptions); - expect(validConfig).to.equal(false); - }); - - it('should use DEFAULT_SERVER when server is missing', function () { - const configOptions = { - options: { - configId: configId, - affiliateId: affiliateId - } - }; - appierAnalyticsAdapter.initConfig(configOptions); - expect(appierAnalyticsAdapter.getAnalyticsOptions().server).to.equal('https://prebid-analytics.c.appier.net/v1'); - }); - - it('should use null when autoPick is missing', function () { - const configOptions = { - options: { - configId: configId, - affiliateId: affiliateId - } - }; - appierAnalyticsAdapter.initConfig(configOptions); - expect(appierAnalyticsAdapter.getAnalyticsOptions().autoPick).to.equal(null); - }); - - it('should not enable Analytics when configId is missing', function () { - const configOptions = { - options: { - affiliateId: affiliateId - } - }; - const validConfig = appierAnalyticsAdapter.initConfig(configOptions); - expect(validConfig).to.equal(false); - }); - - it('should fall back to default value when sampling factor is not number', function () { - const configOptions = { - options: { - affiliateId: affiliateId, - configId: configId, - sampling: 'string', - adSampling: 'string' - } - }; - appierAnalyticsAdapter.enableAnalytics({ - provider: 'appierAnalytics', - options: configOptions - }); - - expect(appierAnalyticsAdapter.getAnalyticsOptions().sampled).to.equal(false); - expect(appierAnalyticsAdapter.getAnalyticsOptions().adSampled).to.equal(true); - }); - }); -}); diff --git a/test/spec/modules/appierBidAdapter_spec.js b/test/spec/modules/appierBidAdapter_spec.js deleted file mode 100644 index 5b6ccf14162..00000000000 --- a/test/spec/modules/appierBidAdapter_spec.js +++ /dev/null @@ -1,174 +0,0 @@ -import { expect } from 'chai'; -import { spec, API_SERVERS_MAP, ADAPTER_VERSION } from 'modules/appierBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import { config } from 'src/config.js'; - -describe('AppierAdapter', 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 () { - let bid = { - 'bidder': 'appier', - 'params': { - 'hzid': 'abcd' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - - it('should return true when required params zoneId found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required param zoneId is missing', function () { - let bid = Object.assign({}, bid); - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when required param zoneId has wrong type', function () { - let bid = Object.assign({}, bid); - bid.params = { - 'hzid': null - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function() { - it('should return an empty list when there are no bid requests', function() { - const fakeBidRequests = []; - const fakeBidderRequest = {}; - expect(spec.buildRequests(fakeBidRequests, fakeBidderRequest)).to.be.an('array').that.is.empty; - }); - - it('should generate a POST bid request with method, url, and data fields', function() { - const bid = { - 'bidder': 'appier', - 'params': { - 'hzid': 'abcd' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - const fakeBidRequests = [bid]; - const fakeBidderRequest = {refererInfo: { - 'referer': 'fakeReferer', - 'reachedTop': true, - 'numIframes': 1, - 'stack': [] - }}; - - const builtRequests = spec.buildRequests(fakeBidRequests, fakeBidderRequest); - expect(builtRequests.length).to.equal(1); - expect(builtRequests[0].method).to.equal('POST'); - expect(builtRequests[0].url).match(/v1\/prebid\/bid/); - expect(builtRequests[0].data).deep.equal({ - 'bids': fakeBidRequests, - 'refererInfo': fakeBidderRequest.refererInfo, - 'version': ADAPTER_VERSION - }); - }); - }); - - describe('interpretResponse', function() { - const bid = { - 'bidder': 'appier', - 'params': { - 'hzid': 'abcd' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - const fakeBidRequests = [bid]; - - it('should return an empty aray to indicate no valid bids', function() { - const fakeServerResponse = {}; - - const bidResponses = spec.interpretResponse(fakeServerResponse, fakeBidRequests); - - expect(bidResponses).is.an('array').that.is.empty; - }); - - it('should generate correct response array for bidder', function() { - const fakeBidResult = { - 'requestId': '30b31c1838de1e', - 'cpm': 0.0029346001, - 'creativeId': 'Idl0P0d5S3Ca5kVWcia-wQ', - 'width': 300, - 'height': 250, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'ad': '
fake html
', - 'appierParams': { - 'hzid': 'test_hzid' - } - }; - const fakeServerResponse = { - headers: [], - body: [fakeBidResult] - }; - - const bidResponses = spec.interpretResponse(fakeServerResponse, fakeBidRequests); - expect(bidResponses).deep.equal([fakeBidResult]); - }); - }); - - describe('getApiServer', function() { - it('should use the server specified by setConfig(appier.server)', function() { - config.setConfig({ - 'appier': {'server': 'fake_server'} - }); - - const server = spec.getApiServer(); - - expect(server).equals('fake_server'); - }); - - it('should retrieve a farm specific hostname if server is not specpfied', function() { - config.setConfig({ - 'appier': {'farm': 'tw'} - }); - - const server = spec.getApiServer(); - - expect(server).equals(API_SERVERS_MAP['tw']); - }); - - it('if farm is not recognized, use the default farm', function() { - config.setConfig({ - 'appier': {'farm': 'no_this_farm'} - }); - - const server = spec.getApiServer(); - - expect(server).equals(API_SERVERS_MAP['default']); - }); - - it('if farm is not specified, use the default farm', function() { - config.setConfig({ - 'appier': {} - }); - - const server = spec.getApiServer(); - - expect(server).equals(API_SERVERS_MAP['default']); - }); - }); -}); diff --git a/test/spec/modules/appnexusBidAdapter_spec.js b/test/spec/modules/appnexusBidAdapter_spec.js deleted file mode 100644 index c875cba12bc..00000000000 --- a/test/spec/modules/appnexusBidAdapter_spec.js +++ /dev/null @@ -1,1300 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/appnexusBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -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'; - -const ENDPOINT = 'https://ib.adnxs.com/ut/v3/prebid'; - -describe('AppNexusAdapter', 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 () { - let bid = { - 'bidder': 'appnexus', - 'params': { - 'placementId': '10433394' - }, - '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(bid)).to.equal(true); - }); - - it('should return true when required params found', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'member': '1234', - 'invCode': 'ABCD' - }; - - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'placementId': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let getAdUnitsStub; - let bidRequests = [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': '10433394' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'transactionId': '04f2659e-c005-4eb1-a57c-fa93145e3843' - } - ]; - - beforeEach(function() { - getAdUnitsStub = sinon.stub(auctionManager, 'getAdUnits').callsFake(function() { - return []; - }); - }); - - afterEach(function() { - getAdUnitsStub.restore(); - }); - - it('should parse out private sizes', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - privateSizes: [300, 250] - } - } - ); - - const request = spec.buildRequests([bidRequest]); - 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}]); - }); - - it('should add publisher_id in request', function() { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - publisherId: '1231234' - } - }); - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].publisher_id).to.exist; - expect(payload.tags[0].publisher_id).to.deep.equal(1231234); - expect(payload.publisher_id).to.exist; - expect(payload.publisher_id).to.deep.equal(1231234); - }) - - it('should add source and verison to the tag', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.sdk).to.exist; - expect(payload.sdk).to.deep.equal({ - source: 'pbjs', - version: '$prebid.version$' - }); - }); - - it('should populate the ad_types array on all requests', function () { - let adUnits = [{ - code: 'adunit-code', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: '10433394' - } - }], - transactionId: '04f2659e-c005-4eb1-a57c-fa93145e3843' - }]; - - ['banner', 'video', 'native'].forEach(type => { - getAdUnitsStub.callsFake(function(...args) { - return adUnits; - }); - - const bidRequest = Object.assign({}, bidRequests[0]); - bidRequest.mediaTypes = {}; - bidRequest.mediaTypes[type] = {}; - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].ad_types).to.deep.equal([type]); - - if (type === 'banner') { - delete adUnits[0].mediaTypes; - } - }); - }); - - it('should not populate the ad_types array when adUnit.mediaTypes is undefined', function() { - const bidRequest = Object.assign({}, bidRequests[0]); - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].ad_types).to.not.exist; - }); - - it('should populate the ad_types array on outstream requests', function () { - const bidRequest = Object.assign({}, bidRequests[0]); - bidRequest.mediaTypes = {}; - bidRequest.mediaTypes.video = {context: 'outstream'}; - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].ad_types).to.deep.equal(['video']); - expect(payload.tags[0].hb_source).to.deep.equal(1); - }); - - it('sends bid request to ENDPOINT via POST', function () { - const request = spec.buildRequests(bidRequests); - expect(request.url).to.equal(ENDPOINT); - expect(request.method).to.equal('POST'); - }); - - it('should attach valid video params to the tag', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - video: { - id: 123, - minduration: 100, - foobar: 'invalid' - } - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - expect(payload.tags[0].video).to.deep.equal({ - id: 123, - minduration: 100 - }); - expect(payload.tags[0].hb_source).to.deep.equal(1); - }); - - it('should add video property when adUnit includes a renderer', function () { - const videoData = { - mediaTypes: { - video: { - context: 'outstream', - mimes: ['video/mp4'] - } - }, - params: { - placementId: '10433394', - video: { - skippable: true, - playback_method: ['auto_play_sound_off'] - } - } - }; - - let bidRequest1 = deepClone(bidRequests[0]); - bidRequest1 = Object.assign({}, bidRequest1, videoData, { - renderer: { - url: 'https://test.renderer.url', - render: function () {} - } - }); - - let bidRequest2 = deepClone(bidRequests[0]); - bidRequest2.adUnitCode = 'adUnit_code_2'; - bidRequest2 = Object.assign({}, bidRequest2, videoData); - - const request = spec.buildRequests([bidRequest1, bidRequest2]); - const payload = JSON.parse(request.data); - expect(payload.tags[0].video).to.deep.equal({ - skippable: true, - playback_method: 2, - custom_renderer_present: true - }); - expect(payload.tags[1].video).to.deep.equal({ - skippable: true, - playback_method: 2 - }); - }); - - it('should attach valid user params to the tag', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - user: { - externalUid: '123', - segments: [123, { id: 987, value: 876 }], - foobar: 'invalid' - } - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.user).to.exist; - expect(payload.user).to.deep.equal({ - external_uid: '123', - segments: [{id: 123}, {id: 987, value: 876}] - }); - }); - - it('should attach reserve param when either bid param or getFloor function exists', function () { - let getFloorResponse = { currency: 'USD', floor: 3 }; - let request, payload = null; - let bidRequest = deepClone(bidRequests[0]); - - // 1 -> reserve not defined, getFloor not defined > empty - request = spec.buildRequests([bidRequest]); - payload = JSON.parse(request.data); - - expect(payload.tags[0].reserve).to.not.exist; - - // 2 -> reserve is defined, getFloor not defined > reserve is used - bidRequest.params = { - 'placementId': '10433394', - 'reserve': 0.5 - }; - request = spec.buildRequests([bidRequest]); - payload = JSON.parse(request.data); - - expect(payload.tags[0].reserve).to.exist.and.to.equal(0.5); - - // 3 -> reserve is defined, getFloor is defined > getFloor is used - bidRequest.getFloor = () => getFloorResponse; - - request = spec.buildRequests([bidRequest]); - payload = JSON.parse(request.data); - - expect(payload.tags[0].reserve).to.exist.and.to.equal(3); - }); - - it('should duplicate adpod placements into batches and set correct maxduration', function() { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { placementId: '14542875' } - }, - { - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 300, - durationRangeSec: [15, 30], - } - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload1 = JSON.parse(request[0].data); - const payload2 = JSON.parse(request[1].data); - - // 300 / 15 = 20 total - expect(payload1.tags.length).to.equal(15); - expect(payload2.tags.length).to.equal(5); - - expect(payload1.tags[0]).to.deep.equal(payload1.tags[1]); - expect(payload1.tags[0].video.maxduration).to.equal(30); - - expect(payload2.tags[0]).to.deep.equal(payload1.tags[1]); - expect(payload2.tags[0].video.maxduration).to.equal(30); - }); - - it('should round down adpod placements when numbers are uneven', function() { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { placementId: '14542875' } - }, - { - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 123, - durationRangeSec: [45], - } - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - expect(payload.tags.length).to.equal(2); - }); - - it('should duplicate adpod placements when requireExactDuration is set', function() { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { placementId: '14542875' } - }, - { - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 300, - durationRangeSec: [15, 30], - requireExactDuration: true, - } - } - } - ); - - // 20 total placements with 15 max impressions = 2 requests - const request = spec.buildRequests([bidRequest]); - expect(request.length).to.equal(2); - - // 20 spread over 2 requests = 15 in first request, 5 in second - const payload1 = JSON.parse(request[0].data); - const payload2 = JSON.parse(request[1].data); - expect(payload1.tags.length).to.equal(15); - expect(payload2.tags.length).to.equal(5); - - // 10 placements should have max/min at 15 - // 10 placemenst should have max/min at 30 - const payload1tagsWith15 = payload1.tags.filter(tag => tag.video.maxduration === 15); - const payload1tagsWith30 = payload1.tags.filter(tag => tag.video.maxduration === 30); - expect(payload1tagsWith15.length).to.equal(10); - expect(payload1tagsWith30.length).to.equal(5); - - // 5 placemenst with min/max at 30 were in the first request - // so 5 remaining should be in the second - const payload2tagsWith30 = payload2.tags.filter(tag => tag.video.maxduration === 30); - expect(payload2tagsWith30.length).to.equal(5); - }); - - it('should set durations for placements when requireExactDuration is set and numbers are uneven', function() { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { placementId: '14542875' } - }, - { - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 105, - durationRangeSec: [15, 30, 60], - requireExactDuration: true, - } - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - expect(payload.tags.length).to.equal(7); - - const tagsWith15 = payload.tags.filter(tag => tag.video.maxduration === 15); - const tagsWith30 = payload.tags.filter(tag => tag.video.maxduration === 30); - const tagsWith60 = payload.tags.filter(tag => tag.video.maxduration === 60); - expect(tagsWith15.length).to.equal(3); - expect(tagsWith30.length).to.equal(3); - expect(tagsWith60.length).to.equal(1); - }); - - it('should break adpod request into batches', function() { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { placementId: '14542875' } - }, - { - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 225, - durationRangeSec: [5], - } - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload1 = JSON.parse(request[0].data); - const payload2 = JSON.parse(request[1].data); - const payload3 = JSON.parse(request[2].data); - - expect(payload1.tags.length).to.equal(15); - expect(payload2.tags.length).to.equal(15); - expect(payload3.tags.length).to.equal(15); - }); - - it('should contain hb_source value for adpod', function() { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { placementId: '14542875' } - }, - { - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 300, - durationRangeSec: [15, 30], - } - } - } - ); - const request = spec.buildRequests([bidRequest])[0]; - const payload = JSON.parse(request.data); - expect(payload.tags[0].hb_source).to.deep.equal(7); - }); - - it('should contain hb_source value for other media', function() { - let bidRequest = Object.assign({}, - bidRequests[0], - { - mediaType: 'banner', - params: { - sizes: [[300, 250], [300, 600]], - placementId: 13144370 - } - } - ); - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - expect(payload.tags[0].hb_source).to.deep.equal(1); - }); - - it('adds brand_category_exclusion to request when set', function() { - let bidRequest = Object.assign({}, bidRequests[0]); - sinon - .stub(config, 'getConfig') - .withArgs('adpod.brandCategoryExclusion') - .returns(true); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.brand_category_uniqueness).to.equal(true); - - config.getConfig.restore(); - }); - - it('should attach native params to the request', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - 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} - } - } - ); - - const request = spec.buildRequests([bidRequest]); - 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}, - privacy_supported: true - }); - expect(payload.tags[0].hb_source).to.equal(1); - }); - - it('should always populated tags[].sizes with 1,1 for native if otherwise not defined', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - mediaType: 'native', - nativeParams: { - image: { required: true } - } - } - ); - bidRequest.sizes = [[150, 100], [300, 250]]; - - 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}]); - - delete bidRequest.sizes; - - request = spec.buildRequests([bidRequest]); - payload = JSON.parse(request.data); - - 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 () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - keywords: { - single: 'val', - singleArr: ['val'], - singleArrNum: [5], - multiValMixed: ['value1', 2, 'value3'], - singleValNum: 123, - emptyStr: '', - emptyArr: [''], - badValue: {'foo': 'bar'} // should be dropped - } - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].keywords).to.deep.equal([{ - 'key': 'single', - 'value': ['val'] - }, { - 'key': 'singleArr', - 'value': ['val'] - }, { - 'key': 'singleArrNum', - 'value': ['5'] - }, { - 'key': 'multiValMixed', - 'value': ['value1', '2', 'value3'] - }, { - 'key': 'singleValNum', - 'value': ['123'] - }, { - 'key': 'emptyStr' - }, { - 'key': 'emptyArr' - }]); - }); - - it('should add payment rules to the request', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - usePaymentRule: true - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].use_pmt_rule).to.equal(true); - }); - - it('should add gpid to the request', function () { - let testGpid = '/12345/my-gpt-tag-0'; - let bidRequest = deepClone(bidRequests[0]); - bidRequest.ortb2Imp = { ext: { data: { pbadslot: testGpid } } }; - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].gpid).to.exist.and.equal(testGpid) - }); - - it('should add gdpr consent information to the request', function () { - let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - let bidderRequest = { - 'bidderCode': 'appnexus', - 'auctionId': '1d1a030790a475', - 'bidderRequestId': '22edbae2733bf6', - 'timeout': 3000, - 'gdprConsent': { - consentString: consentString, - gdprApplies: true - } - }; - bidderRequest.bids = bidRequests; - - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.options).to.deep.equal({withCredentials: true}); - const payload = JSON.parse(request.data); - - expect(payload.gdpr_consent).to.exist; - expect(payload.gdpr_consent.consent_string).to.exist.and.to.equal(consentString); - expect(payload.gdpr_consent.consent_required).to.exist.and.to.be.true; - }); - - it('should add us privacy string to payload', function() { - let consentString = '1YA-'; - let bidderRequest = { - 'bidderCode': 'appnexus', - 'auctionId': '1d1a030790a475', - 'bidderRequestId': '22edbae2733bf6', - 'timeout': 3000, - 'uspConsent': consentString - }; - bidderRequest.bids = bidRequests; - - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.us_privacy).to.exist; - expect(payload.us_privacy).to.exist.and.to.equal(consentString); - }); - - it('supports sending hybrid mobile app parameters', function () { - let appRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - app: { - id: 'B1O2W3M4AN.com.prebid.webview', - geo: { - lat: 40.0964439, - lng: -75.3009142 - }, - device_id: { - idfa: '4D12078D-3246-4DA4-AD5E-7610481E7AE', // Apple advertising identifier - aaid: '38400000-8cf0-11bd-b23e-10b96e40000d', // Android advertising identifier - md5udid: '5756ae9022b2ea1e47d84fead75220c8', // MD5 hash of the ANDROID_ID - sha1udid: '4DFAA92388699AC6539885AEF1719293879985BF', // SHA1 hash of the ANDROID_ID - windowsadid: '750c6be243f1c4b5c9912b95a5742fc5' // Windows advertising identifier - } - } - } - } - ); - const request = spec.buildRequests([appRequest]); - const payload = JSON.parse(request.data); - expect(payload.app).to.exist; - expect(payload.app).to.deep.equal({ - appid: 'B1O2W3M4AN.com.prebid.webview' - }); - expect(payload.device.device_id).to.exist; - expect(payload.device.device_id).to.deep.equal({ - aaid: '38400000-8cf0-11bd-b23e-10b96e40000d', - idfa: '4D12078D-3246-4DA4-AD5E-7610481E7AE', - md5udid: '5756ae9022b2ea1e47d84fead75220c8', - sha1udid: '4DFAA92388699AC6539885AEF1719293879985BF', - windowsadid: '750c6be243f1c4b5c9912b95a5742fc5' - }); - expect(payload.device.geo).to.exist; - expect(payload.device.geo).to.deep.equal({ - lat: 40.0964439, - lng: -75.3009142 - }); - }); - - it('should add referer info to payload', function () { - const bidRequest = Object.assign({}, bidRequests[0]) - const bidderRequest = { - refererInfo: { - referer: 'https://example.com/page.html', - reachedTop: true, - numIframes: 2, - stack: [ - 'https://example.com/page.html', - 'https://example.com/iframe1.html', - 'https://example.com/iframe2.html' - ] - } - } - const request = spec.buildRequests([bidRequest], bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.referrer_detection).to.exist; - expect(payload.referrer_detection).to.deep.equal({ - rd_ref: 'https%3A%2F%2Fexample.com%2Fpage.html', - rd_top: true, - rd_ifs: 2, - rd_stk: bidderRequest.refererInfo.stack.map((url) => encodeURIComponent(url)).join(',') - }); - }); - - it('should populate schain if available', function () { - const bidRequest = Object.assign({}, bidRequests[0], { - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - 'asi': 'blob.com', - 'sid': '001', - 'hp': 1 - } - ] - } - }); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - expect(payload.schain).to.deep.equal({ - ver: '1.0', - complete: 1, - nodes: [ - { - 'asi': 'blob.com', - 'sid': '001', - 'hp': 1 - } - ] - }); - }); - - it('should populate coppa if set in config', function () { - let bidRequest = Object.assign({}, bidRequests[0]); - sinon.stub(config, 'getConfig') - .withArgs('coppa') - .returns(true); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.user.coppa).to.equal(true); - - config.getConfig.restore(); - }); - - it('should set the X-Is-Test customHeader if test flag is enabled', function () { - let bidRequest = Object.assign({}, bidRequests[0]); - sinon.stub(config, 'getConfig') - .withArgs('apn_test') - .returns(true); - - const request = spec.buildRequests([bidRequest]); - expect(request.options.customHeaders).to.deep.equal({'X-Is-Test': 1}); - - config.getConfig.restore(); - }); - - it('should always set withCredentials: true on the request.options', function () { - let bidRequest = Object.assign({}, bidRequests[0]); - const request = spec.buildRequests([bidRequest]); - expect(request.options.withCredentials).to.equal(true); - }); - - it('should set simple domain variant if purpose 1 consent is not given', function () { - let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - let bidderRequest = { - 'bidderCode': 'appnexus', - 'auctionId': '1d1a030790a475', - 'bidderRequestId': '22edbae2733bf6', - 'timeout': 3000, - 'gdprConsent': { - consentString: consentString, - gdprApplies: true, - apiVersion: 2, - vendorData: { - purpose: { - consents: { - 1: false - } - } - } - } - }; - bidderRequest.bids = bidRequests; - - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.url).to.equal('https://ib.adnxs-simple.com/ut/v3/prebid'); - }); - - it('should populate eids when supported userIds are available', function () { - const bidRequest = Object.assign({}, bidRequests[0], { - userId: { - tdid: 'sample-userid', - criteoId: 'sample-criteo-userid', - netId: 'sample-netId-userid', - idl_env: 'sample-idl-userid' - } - }); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - expect(payload.eids).to.deep.include({ - source: 'adserver.org', - id: 'sample-userid', - rti_partner: 'TDID' - }); - - expect(payload.eids).to.deep.include({ - source: 'criteo.com', - id: 'sample-criteo-userid', - }); - - expect(payload.eids).to.deep.include({ - source: 'netid.de', - id: 'sample-netId-userid', - }); - - expect(payload.eids).to.deep.include({ - source: 'liveramp.com', - id: 'sample-idl-userid' - }) - }); - - it('should populate iab_support object at the root level if omid support is detected', function () { - // with bid.params.frameworks - let bidRequest_A = Object.assign({}, bidRequests[0], { - params: { - frameworks: [1, 2, 5, 6], - video: { - frameworks: [1, 2, 5, 6] - } - } - }); - let request = spec.buildRequests([bidRequest_A]); - let payload = JSON.parse(request.data); - expect(payload.iab_support).to.be.an('object'); - expect(payload.iab_support).to.deep.equal({ - omidpn: 'Appnexus', - omidpv: '$prebid.version$' - }); - expect(payload.tags[0].banner_frameworks).to.be.an('array'); - expect(payload.tags[0].banner_frameworks).to.deep.equal([1, 2, 5, 6]); - expect(payload.tags[0].video_frameworks).to.be.an('array'); - expect(payload.tags[0].video_frameworks).to.deep.equal([1, 2, 5, 6]); - expect(payload.tags[0].video.frameworks).to.not.exist; - - // without bid.params.frameworks - const bidRequest_B = Object.assign({}, bidRequests[0]); - request = spec.buildRequests([bidRequest_B]); - payload = JSON.parse(request.data); - expect(payload.iab_support).to.not.exist; - expect(payload.tags[0].banner_frameworks).to.not.exist; - expect(payload.tags[0].video_frameworks).to.not.exist; - - // with video.frameworks but it is not an array - const bidRequest_C = Object.assign({}, bidRequests[0], { - params: { - video: { - frameworks: "'1', '2', '3', '6'" - } - } - }); - request = spec.buildRequests([bidRequest_C]); - payload = JSON.parse(request.data); - expect(payload.iab_support).to.not.exist; - expect(payload.tags[0].banner_frameworks).to.not.exist; - expect(payload.tags[0].video_frameworks).to.not.exist; - }); - }) - - describe('interpretResponse', function () { - let bfStub; - before(function() { - bfStub = sinon.stub(bidderFactory, 'getIabSubCategory'); - }); - - after(function() { - bfStub.restore(); - }); - - let response = { - 'version': '3.0.0', - 'tags': [ - { - 'uuid': '3db3773286ee59', - 'tag_id': 10433394, - 'auction_id': '4534722592064951574', - 'nobid': false, - 'no_ad_url': 'https://lax1-ib.adnxs.com/no-ad', - 'timeout_ms': 10000, - 'ad_profile_id': 27079, - 'ads': [ - { - 'content_source': 'rtb', - 'ad_type': 'banner', - 'buyer_member_id': 958, - 'creative_id': 29681110, - 'media_type_id': 1, - 'media_subtype_id': 1, - 'cpm': 0.5, - 'cpm_publisher_currency': 0.5, - 'publisher_currency_code': '$', - 'client_initiated_ad_counting': true, - 'viewability': { - 'config': '' - }, - 'rtb': { - 'banner': { - 'content': '', - 'width': 300, - 'height': 250 - }, - 'trackers': [ - { - 'impression_urls': [ - 'https://lax1-ib.adnxs.com/impression' - ], - 'video_events': {} - } - ] - } - } - ] - } - ] - }; - - it('should get correct bid response', function () { - let expectedResponse = [ - { - 'requestId': '3db3773286ee59', - 'cpm': 0.5, - 'creativeId': 29681110, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '', - 'mediaType': 'banner', - 'currency': 'USD', - 'ttl': 300, - 'netRevenue': true, - 'adUnitCode': 'code', - 'appnexus': { - 'buyerMemberId': 958 - } - } - ]; - let bidderRequest = { - bids: [{ - bidId: '3db3773286ee59', - adUnitCode: 'code' - }] - } - let result = spec.interpretResponse({ body: response }, {bidderRequest}); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('handles nobid responses', function () { - let response = { - 'version': '0.0.1', - 'tags': [{ - 'uuid': '84ab500420319d', - 'tag_id': 5976557, - 'auction_id': '297492697822162468', - 'nobid': true - }] - }; - let bidderRequest; - - let result = spec.interpretResponse({ body: response }, {bidderRequest}); - expect(result.length).to.equal(0); - }); - - it('handles outstream video responses', function () { - let response = { - 'tags': [{ - 'uuid': '84ab500420319d', - 'ads': [{ - 'ad_type': 'video', - 'cpm': 0.500000, - 'notify_url': 'imptracker.com', - 'rtb': { - 'video': { - 'content': '' - } - }, - 'javascriptTrackers': '' - }] - }] - }; - let bidderRequest = { - bids: [{ - bidId: '84ab500420319d', - adUnitCode: 'code', - mediaTypes: { - video: { - context: 'outstream' - } - } - }] - } - - let 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'); - }); - - it('handles instream video responses', function () { - let response = { - 'tags': [{ - 'uuid': '84ab500420319d', - 'ads': [{ - 'ad_type': 'video', - 'cpm': 0.500000, - 'notify_url': 'imptracker.com', - 'rtb': { - 'video': { - 'asset_url': 'https://sample.vastURL.com/here/vid' - } - }, - 'javascriptTrackers': '' - }] - }] - }; - let bidderRequest = { - bids: [{ - bidId: '84ab500420319d', - adUnitCode: 'code', - mediaTypes: { - video: { - context: 'instream' - } - } - }] - } - - let 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'); - }); - - it('handles adpod responses', function () { - let response = { - 'tags': [{ - 'uuid': '84ab500420319d', - 'ads': [{ - 'ad_type': 'video', - 'brand_category_id': 10, - 'cpm': 0.500000, - 'notify_url': 'imptracker.com', - 'rtb': { - 'video': { - 'asset_url': 'https://sample.vastURL.com/here/adpod', - 'duration_ms': 30000, - } - }, - 'viewability': { - 'config': '' - } - }] - }] - }; - - let bidderRequest = { - bids: [{ - bidId: '84ab500420319d', - adUnitCode: 'code', - mediaTypes: { - video: { - context: 'adpod' - } - } - }] - }; - bfStub.returns('1'); - - let 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); - }); - - it('handles native responses', function () { - let response1 = deepClone(response); - response1.tags[0].ads[0].ad_type = 'native'; - response1.tags[0].ads[0].rtb.native = { - 'title': 'Native Creative', - 'desc': 'Cool description great stuff', - 'desc2': 'Additional body text', - 'ctatext': 'Do it', - 'sponsored': 'AppNexus', - 'icon': { - 'width': 0, - 'height': 0, - 'url': 'https://cdn.adnxs.com/icon.png' - }, - 'main_img': { - 'width': 2352, - 'height': 1516, - 'url': 'https://cdn.adnxs.com/img.png' - }, - 'link': { - 'url': 'https://www.appnexus.com', - 'fallback_url': '', - 'click_trackers': ['https://nym1-ib.adnxs.com/click'] - }, - 'impression_trackers': ['https://example.com'], - 'rating': '5', - 'displayurl': 'https://AppNexus.com/?url=display_url', - 'likes': '38908320', - 'downloads': '874983', - 'price': '9.99', - 'saleprice': 'FREE', - 'phone': '1234567890', - 'address': '28 W 23rd St, New York, NY 10010', - 'privacy_link': 'https://appnexus.com/?url=privacy_url', - 'javascriptTrackers': '' - }; - let bidderRequest = { - bids: [{ - bidId: '3db3773286ee59', - adUnitCode: 'code' - }] - } - - let 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'); - expect(result[0].native.image.url).to.equal('https://cdn.adnxs.com/img.png'); - }); - - it('supports configuring outstream renderers', function () { - const outstreamResponse = deepClone(response); - outstreamResponse.tags[0].ads[0].rtb.video = {}; - outstreamResponse.tags[0].ads[0].renderer_url = 'renderer.js'; - - const bidderRequest = { - bids: [{ - bidId: '3db3773286ee59', - renderer: { - options: { - adText: 'configured' - } - }, - mediaTypes: { - video: { - context: 'outstream' - } - } - }] - }; - - const result = spec.interpretResponse({ body: outstreamResponse }, {bidderRequest}); - expect(result[0].renderer.config).to.deep.equal( - bidderRequest.bids[0].renderer.options - ); - }); - - it('should add deal_priority and deal_code', function() { - let responseWithDeal = deepClone(response); - responseWithDeal.tags[0].ads[0].ad_type = 'video'; - responseWithDeal.tags[0].ads[0].deal_priority = 5; - responseWithDeal.tags[0].ads[0].deal_code = '123'; - responseWithDeal.tags[0].ads[0].rtb.video = { - duration_ms: 1500, - player_width: 640, - player_height: 340, - }; - - let bidderRequest = { - bids: [{ - bidId: '3db3773286ee59', - adUnitCode: 'code', - mediaTypes: { - video: { - context: 'adpod' - } - } - }] - } - let result = spec.interpretResponse({ body: responseWithDeal }, {bidderRequest}); - expect(Object.keys(result[0].appnexus)).to.include.members(['buyerMemberId', 'dealPriority', 'dealCode']); - expect(result[0].video.dealTier).to.equal(5); - }); - - it('should add advertiser id', function() { - let responseAdvertiserId = deepClone(response); - responseAdvertiserId.tags[0].ads[0].advertiser_id = '123'; - - let bidderRequest = { - bids: [{ - bidId: '3db3773286ee59', - adUnitCode: 'code' - }] - } - let result = spec.interpretResponse({ body: responseAdvertiserId }, {bidderRequest}); - expect(Object.keys(result[0].meta)).to.include.members(['advertiserId']); - }); - - it('should add advertiserDomains', function() { - let responseAdvertiserId = deepClone(response); - responseAdvertiserId.tags[0].ads[0].adomain = ['123']; - - let bidderRequest = { - bids: [{ - bidId: '3db3773286ee59', - adUnitCode: 'code' - }] - } - let 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/apstreamBidAdapter_spec.js b/test/spec/modules/apstreamBidAdapter_spec.js deleted file mode 100644 index e640c009989..00000000000 --- a/test/spec/modules/apstreamBidAdapter_spec.js +++ /dev/null @@ -1,346 +0,0 @@ -// 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 * as utils from 'src/utils.js'; - -const validBidRequests = [{ - bidId: 'bidId', - adUnitCode: '/id/site1/header-ad', - sizes: [[980, 120], [980, 180]], - mediaTypes: { - banner: { - sizes: [[980, 120], [980, 180]] - } - }, - params: { - publisherId: '1234' - } -}]; - -describe('AP Stream adapter', function() { - describe('isBidRequestValid', function() { - const bid = { - bidder: 'apstream', - mediaTypes: { - banner: { - sizes: [300, 250] - } - }, - params: { - } - }; - - let mockConfig; - beforeEach(function () { - mockConfig = { - apstream: { - publisherId: '4321' - } - }; - sinon.stub(config, 'getConfig').callsFake((key) => { - return utils.deepAccess(mockConfig, key); - }); - }); - - afterEach(function () { - config.getConfig.restore(); - }); - - it('should return true when publisherId is configured and one media type', function() { - bid.params.publisherId = '1234'; - assert(spec.isBidRequestValid(bid)) - }); - - it('should return false when publisherId is configured and two media types', function() { - bid.mediaTypes.video = {sizes: [300, 250]}; - assert.isFalse(spec.isBidRequestValid(bid)) - }); - - it('should return true when publisherId is configured via config', function() { - delete bid.mediaTypes.video; - delete bid.params.publisherId; - assert.isTrue(spec.isBidRequestValid(bid)) - }); - }); - - describe('buildRequests', function() { - it('should send request with correct structure', function() { - const request = spec.buildRequests(validBidRequests, { })[0]; - - assert.equal(request.method, 'GET'); - assert.deepEqual(request.options, {withCredentials: false}); - assert.ok(request.data); - }); - - it('should send request with different endpoints', function() { - const validTwoBidRequests = [ - ...validBidRequests, - ...[{ - bidId: 'bidId2', - adUnitCode: '/id/site1/header-ad', - sizes: [[980, 980], [980, 900]], - mediaTypes: { - banner: { - sizes: [[980, 980], [980, 900]] - } - }, - params: { - publisherId: '1234', - endpoint: 'site2.com' - } - }] - ]; - - const request = spec.buildRequests(validTwoBidRequests, {}); - assert.isArray(request); - assert.lengthOf(request, 2); - assert.equal(request[1].data.bids, 'bidId2:t=b,s=980x980_980x900,c=/id/site1/header-ad'); - }); - - it('should send request with adUnit code', function() { - const adunitCodeValidBidRequests = [ - { - ...validBidRequests[0], - ...{ - params: { - code: 'Site1_Leaderboard' - } - } - } - ]; - - const request = spec.buildRequests(adunitCodeValidBidRequests, { })[0]; - assert.equal(request.data.bids, 'bidId:t=b,s=980x120_980x180,c=Site1_Leaderboard'); - }); - - it('should send request with adUnit id', function() { - const adunitIdValidBidRequests = [ - { - ...validBidRequests[0], - ...{ - params: { - adunitId: '12345' - } - } - } - ]; - - const request = spec.buildRequests(adunitIdValidBidRequests, { })[0]; - assert.equal(request.data.bids, 'bidId:t=b,s=980x120_980x180,u=12345'); - }); - - it('should send request with different media type', function() { - const types = { - 'audio': 'a', - 'banner': 'b', - 'native': 'n', - 'video': 'v' - } - Object.keys(types).forEach(key => { - const adunitIdValidBidRequests = [ - { - ...validBidRequests[0], - ...{ - mediaTypes: { - [key]: { - sizes: [300, 250] - } - } - } - } - ]; - - const request = spec.buildRequests(adunitIdValidBidRequests, { })[0]; - assert.equal(request.data.bids, `bidId:t=${types[key]},s=980x120_980x180,c=/id/site1/header-ad`); - }) - }); - - describe('gdpr', function() { - let mockConfig; - - beforeEach(function () { - mockConfig = { - consentManagement: { - cmpApi: 'iab' - } - }; - sinon.stub(config, 'getConfig').callsFake((key) => { - return utils.deepAccess(mockConfig, key); - }); - }); - - afterEach(function () { - config.getConfig.restore(); - }); - - it('should send GDPR Consent data', function() { - const bidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString: 'consentDataString', - vendorData: { - vendorConsents: { - '394': true - } - } - } - }; - - const request = spec.buildRequests(validBidRequests, bidderRequest)[0].data; - assert.equal(request.iab_consent, bidderRequest.gdprConsent.consentString); - }); - }); - - describe('dsu', function() { - it('should pass DSU from local storage if set', function() { - let dsu = 'some_dsu'; - localStorage.setItem('apr_dsu', dsu); - - const bidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString: 'consentDataString', - vendorData: { - vendorConsents: { - '394': true - } - } - } - }; - - const request = spec.buildRequests(validBidRequests, bidderRequest)[0].data; - - assert.equal(request.dsu, dsu); - }); - - it('should generate new DSU if nothing in local storage', function() { - localStorage.removeItem('apr_dsu'); - - const bidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString: 'consentDataString', - vendorData: { - vendorConsents: { - '394': true - } - } - } - }; - - const request = spec.buildRequests(validBidRequests, bidderRequest)[0].data; - let dsu = localStorage.getItem('apr_dsu'); - - assert.isNotEmpty(dsu); - assert.equal(request.dsu, dsu); - }); - }); - }); - - describe('dsu config', function() { - let mockConfig; - beforeEach(function () { - mockConfig = { - apstream: { - noDsu: true - } - }; - sinon.stub(config, 'getConfig').callsFake((key) => { - return utils.deepAccess(mockConfig, key); - }); - }); - - afterEach(function () { - config.getConfig.restore(); - }); - - it('should not send DSU if it is disabled in config', function() { - const request = spec.buildRequests(validBidRequests, { })[0]; - - assert.equal(request.data.dsu, ''); - }); - }); - - describe('interpretResponse', function () { - it('should return empty array if no body in response', function () { - const serverResponse = {}; - const bidRequest = {}; - - assert.isEmpty(spec.interpretResponse(serverResponse, bidRequest)); - }); - - it('should map server response', function () { - const serverResponse = { - body: [ - { - bidId: 123, - bidDetails: { - cpm: 1.23, - width: 980, - height: 300, - currency: 'DKK', - netRevenue: 'true', - creativeId: '1234', - dealId: '99008', - ad: '

Buy our something!

', - ttl: 360 - } - } - ] - }; - const bidRequest = {}; - - const response = spec.interpretResponse(serverResponse, bidRequest); - - const expected = { - requestId: 123, - cpm: 1.23, - width: 980, - height: 300, - currency: 'DKK', - creativeId: '1234', - netRevenue: 'true', - dealId: '99008', - ad: '

Buy our something!

', - ttl: 360 - }; - - assert.deepEqual(response[0], expected); - }); - - it('should add pixels to ad', function () { - const serverResponse = { - body: [ - { - bidId: 123, - bidDetails: { - cpm: 1.23, - width: 980, - height: 300, - currency: 'DKK', - creativeId: '1234', - netRevenue: 'true', - dealId: '99008', - ad: '

Buy our something!

', - ttl: 360, - noticeUrls: [ - 'site1', - 'site2' - ], - impressionScripts: [ - 'url_to_script' - ] - } - } - ] - }; - const bidRequest = {}; - - const response = spec.interpretResponse(serverResponse, bidRequest); - - assert.match(response[0].ad, /site1/); - assert.match(response[0].ad, /site2/); - }); - }); -}); diff --git a/test/spec/modules/astraoneBidAdapter_spec.js b/test/spec/modules/astraoneBidAdapter_spec.js deleted file mode 100644 index 0e545081869..00000000000 --- a/test/spec/modules/astraoneBidAdapter_spec.js +++ /dev/null @@ -1,212 +0,0 @@ -import { expect } from 'chai' -import { spec } from 'modules/astraoneBidAdapter.js' - -function getSlotConfigs(mediaTypes, params) { - return { - params: params, - sizes: [], - bidId: '2df8c0733f284e', - bidder: 'astraone', - mediaTypes: mediaTypes, - transactionId: '31a58515-3634-4e90-9c96-f86196db1459' - } -} - -describe('AstraOne Adapter', function() { - describe('isBidRequestValid method', function() { - const PLACE_ID = '5f477bf94d506ebe2c4240f3'; - const IMAGE_URL = 'https://creative.astraone.io/files/default_image-1-600x400.jpg'; - - describe('returns true', function() { - describe('when banner slot config has all mandatory params', () => { - describe('and placement has the correct value', function() { - const createBannerSlotConfig = placement => { - return getSlotConfigs( - { banner: {} }, - { - placeId: PLACE_ID, - imageUrl: IMAGE_URL, - placement - } - ) - } - const placements = ['inImage']; - placements.forEach(placement => { - it('should be ' + placement, function() { - const isBidRequestValid = spec.isBidRequestValid( - createBannerSlotConfig(placement) - ) - expect(isBidRequestValid).to.equal(true) - }) - }) - }) - }) - }) - describe('returns false', function() { - describe('when params are not correct', function() { - function createSlotconfig(params) { - return getSlotConfigs({ banner: {} }, params) - } - it('does not have the placeId.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createSlotconfig({ - imageUrl: IMAGE_URL, - placement: 'inImage' - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('does not have the imageUrl.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createSlotconfig({ - placeId: PLACE_ID, - placement: 'inImage' - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('does not have the placement.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createSlotconfig({ - placeId: PLACE_ID, - imageUrl: IMAGE_URL, - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('does not have a the correct placement.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createSlotconfig({ - placeId: PLACE_ID, - imageUrl: IMAGE_URL, - placement: 'something' - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - }) - }) - }) - - describe('buildRequests method', function() { - const bidderRequest = { - refererInfo: { referer: 'referer' } - } - const mandatoryParams = { - placeId: '5af45ad34d506ee7acad0c26', - imageUrl: 'https://creative.astraone.io/files/default_image-1-600x400.jpg', - placement: 'inImage' - } - const validBidRequests = [ - getSlotConfigs({ banner: {} }, mandatoryParams) - ] - it('Url params should be correct ', function() { - const request = spec.buildRequests(validBidRequests, bidderRequest) - expect(request.method).to.equal('POST') - expect(request.url).to.equal('https://ssp.astraone.io/auction/prebid') - }) - - it('Common data request should be correct', function() { - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(Array.isArray(data.bidRequests)).to.equal(true) - data.bidRequests.forEach(bid => { - expect(bid.placeId).to.equal('5af45ad34d506ee7acad0c26') - expect(typeof bid.imageUrl).to.equal('string') - }) - }) - - describe('GDPR params', function() { - describe('when there are not consent management platform', function() { - it('cmp should be false', function() { - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(data.cmp).to.equal(false) - }) - }) - describe('when there are consent management platform', function() { - it('cmps should be true and ga should not sended, when gdprApplies is undefined', function() { - bidderRequest['gdprConsent'] = { - gdprApplies: undefined, - consentString: 'consentString' - } - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(data.cmp).to.equal(true) - expect(Object.keys(data).indexOf('data')).to.equal(-1) - expect(data.cs).to.equal('consentString') - }) - it('cmps should be true and all gdpr parameters should be sended, when there are gdprApplies', function() { - bidderRequest['gdprConsent'] = { - gdprApplies: true, - consentString: 'consentString' - } - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(data.cmp).to.equal(true) - expect(data.ga).to.equal(true) - expect(data.cs).to.equal('consentString') - }) - }) - }) - - describe('BidRequests params', function() { - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - const bidRequests = data.bidRequests - it('should request a Banner', function() { - const bannerBid = bidRequests[0] - expect(bannerBid.bidId).to.equal('2df8c0733f284e') - expect(bannerBid.transactionId).to.equal('31a58515-3634-4e90-9c96-f86196db1459') - expect(bannerBid.placeId).to.equal('5af45ad34d506ee7acad0c26') - }) - }) - }) - - describe('interpret response method', function() { - it('should return a void array, when the server response have not got bids.', function() { - const serverResponse = { - body: [] - } - const bids = spec.interpretResponse(serverResponse) - expect(Array.isArray(bids)).to.equal(true) - expect(bids.length).to.equal(0) - }) - describe('when the server response return a bid', function() { - describe('the bid is a banner', function() { - it('should return a banner bid', function() { - const serverResponse = { - body: { - bids: [ - { - bidId: '2df8c0733f284e', - price: 0.5, - currency: 'USD', - content: { - content: 'html', - actionUrls: {}, - seanceId: '123123' - }, - width: 100, - height: 100, - ttl: 360 - } - ] - } - } - const bids = spec.interpretResponse(serverResponse) - expect(bids.length).to.equal(1) - expect(bids[0].requestId).to.equal('2df8c0733f284e') - expect(bids[0].creativeId).to.equal('123123') - expect(bids[0].cpm).to.equal(0.5) - expect(bids[0].width).to.equal(100) - expect(bids[0].height).to.equal(100) - expect(bids[0].currency).to.equal('USD') - expect(bids[0].netRevenue).to.equal(true) - expect(typeof bids[0].ad).to.equal('string') - expect(typeof bids[0].content).to.equal('object') - }) - }) - }) - }) -}) diff --git a/test/spec/modules/atomxBidAdapter_spec.js b/test/spec/modules/atomxBidAdapter_spec.js deleted file mode 100644 index d798bd6308c..00000000000 --- a/test/spec/modules/atomxBidAdapter_spec.js +++ /dev/null @@ -1,119 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/atomxBidAdapter.js'; - -describe('atomxAdapterTest', function () { - describe('bidRequestValidity', function () { - it('bidRequest with id param', function () { - expect(spec.isBidRequestValid({ - bidder: 'atomx', - params: { - id: 1234, - }, - })).to.equal(true); - }); - - it('bidRequest with no id param', function () { - expect(spec.isBidRequestValid({ - bidder: 'atomx', - params: { - }, - })).to.equal(false); - }); - }); - - describe('bidRequest', function () { - const bidRequests = [{ - 'bidder': 'atomx', - 'params': { - 'id': '123' - }, - 'adUnitCode': 'aaa', - 'transactionId': '1b8389fe-615c-482d-9f1a-177fb8f7d5b0', - 'sizes': [300, 250], - 'bidId': '1abgs362e0x48a8', - 'bidderRequestId': '70deaff71c281d', - 'auctionId': '5c66da22-426a-4bac-b153-77360bef5337' - }, - { - 'bidder': 'atomx', - 'params': { - 'id': '456', - }, - 'adUnitCode': 'bbb', - 'transactionId': '193995b4-7122-4739-959b-2463282a138b', - 'sizes': [[800, 600]], - 'bidId': '22aidtbx5eabd9', - 'bidderRequestId': '70deaff71c281d', - 'auctionId': 'e97cafd0-ebfc-4f5c-b7c9-baa0fd335a4a' - }]; - - it('bidRequest HTTP method', function () { - const requests = spec.buildRequests(bidRequests); - requests.forEach(function(requestItem) { - expect(requestItem.method).to.equal('GET'); - }); - }); - - it('bidRequest url', function () { - const requests = spec.buildRequests(bidRequests); - requests.forEach(function(requestItem) { - expect(requestItem.url).to.match(new RegExp('p\\.ato\\.mx/placement')); - }); - }); - - it('bidRequest data', function () { - const requests = spec.buildRequests(bidRequests); - expect(requests[0].data.id).to.equal('123'); - expect(requests[0].data.size).to.equal('300x250'); - expect(requests[0].data.prebid).to.equal('1abgs362e0x48a8'); - expect(requests[1].data.id).to.equal('456'); - expect(requests[1].data.size).to.equal('800x600'); - expect(requests[1].data.prebid).to.equal('22aidtbx5eabd9'); - }); - }); - - describe('interpretResponse', function () { - const bidRequest = { - 'method': 'GET', - 'url': 'https://p.ato.mx/placement', - 'data': { - 'v': 12, - 'id': '123', - 'size': '300x250', - 'prebid': '22aidtbx5eabd9', - 'b': 0, - 'h': '7t3y9', - 'type': 'javascript', - 'screen': '800x600x32', - 'timezone': 0, - 'domain': 'https://example.com', - 'r': '', - } - }; - - const bidResponse = { - body: { - 'cpm': 0.00009, - 'width': 300, - 'height': 250, - 'url': 'https://atomx.com', - 'creative_id': 456, - 'code': '22aidtbx5eabd9', - }, - headers: {} - }; - - it('result is correct', function () { - const result = spec.interpretResponse(bidResponse, bidRequest); - - expect(result[0].requestId).to.equal('22aidtbx5eabd9'); - expect(result[0].cpm).to.equal(0.00009 * 1000); - expect(result[0].width).to.equal(300); - expect(result[0].height).to.equal(250); - expect(result[0].creativeId).to.equal(456); - expect(result[0].currency).to.equal('USD'); - expect(result[0].ttl).to.equal(60); - expect(result[0].adUrl).to.equal('https://atomx.com'); - }); - }); -}); diff --git a/test/spec/modules/atsAnalyticsAdapter_spec.js b/test/spec/modules/atsAnalyticsAdapter_spec.js deleted file mode 100644 index 59b9105925a..00000000000 --- a/test/spec/modules/atsAnalyticsAdapter_spec.js +++ /dev/null @@ -1,181 +0,0 @@ -import atsAnalyticsAdapter from '../../../modules/atsAnalyticsAdapter.js'; -import { expect } from 'chai'; -import adapterManager from 'src/adapterManager.js'; -import {server} from '../../mocks/xhr.js'; -import {parseBrowser} from '../../../modules/atsAnalyticsAdapter.js'; -import {getStorageManager} from '../../../src/storageManager.js'; -import {analyticsUrl} from '../../../modules/atsAnalyticsAdapter.js'; - -let events = require('src/events'); -let constants = require('src/constants.json'); - -export const storage = getStorageManager(); - -describe('ats analytics adapter', function () { - beforeEach(function () { - sinon.stub(events, 'getEvents').returns([]); - storage.setCookie('_lr_env_src_ats', 'true', 'Thu, 01 Jan 1970 00:00:01 GMT'); - }); - - afterEach(function () { - events.getEvents.restore(); - atsAnalyticsAdapter.getUserAgent.restore(); - atsAnalyticsAdapter.disableAnalytics(); - }); - - describe('track', function () { - it('builds and sends request and response data', function () { - sinon.stub(atsAnalyticsAdapter, 'shouldFireRequest').returns(true); - sinon.stub(atsAnalyticsAdapter, 'getUserAgent').returns('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/536.25 (KHTML, like Gecko) Version/6.0 Safari/536.25'); - let now = new Date(); - now.setTime(now.getTime() + 3600000); - storage.setCookie('_lr_env_src_ats', 'true', now.toUTCString()); - storage.setCookie('_lr_sampling_rate', '10', now.toUTCString()); - - let initOptions = { - pid: '10433394' - }; - let auctionTimestamp = 1496510254326; - - // prepare general auction - request - let bidRequest = { - 'bidderCode': 'appnexus', - 'auctionStart': 1580739265161, - 'bids': [{ - 'bidder': 'appnexus', - 'params': { - 'placementId': '10433394' - }, - 'userId': { - 'idl_env': 'AmThEbO1ssIWjrNdU4noT4ZFBILSVBBYHbipOYt_JP40e5nZdXns2g' - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'transactionId': '2f481ff1-8d20-4c28-8e36-e384e9e3eec6', - 'sizes': '300x250,300x600', - 'bidId': '30c77d079cdf17' - }], - 'refererInfo': { - 'referer': 'https://example.com/dev' - }, - 'auctionId': 'a5b849e5-87d7-4205-8300-d063084fcfb7', - }; - // prepare general auction - response - let bidResponse = { - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '2eddfdc0c791dc', - 'mediaType': 'banner', - 'source': 'client', - 'requestId': '30c77d079cdf17', - 'cpm': 0.5, - 'creativeId': 29681110, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'auctionId': 'a5b849e5-87d7-4205-8300-d063084fcfb7', - 'responseTimestamp': 1580739791978, - 'requestTimestamp': 1580739265164, - 'bidder': 'appnexus', - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'timeToRespond': 2510, - 'size': '300x250' - }; - - // what we expect after general auction - let expectedAfterBid = { - 'Data': [{ - 'has_envelope': true, - 'adapter_version': 1, - 'bidder': 'appnexus', - 'bid_id': '30c77d079cdf17', - 'auction_id': 'a5b849e5-87d7-4205-8300-d063084fcfb7', - 'user_browser': parseBrowser(), - 'user_platform': navigator.platform, - 'auction_start': '2020-02-03T14:14:25.161Z', - 'domain': window.location.hostname, - 'envelope_source': true, - 'pid': '10433394', - 'response_time_stamp': '2020-02-03T14:23:11.978Z', - 'currency': 'USD', - 'cpm': 0.5, - 'net_revenue': true - }] - }; - - // lets simulate that some bidders timeout - let bidTimeoutArgsV1 = [ - { - bidId: '2baa51527bd015', - bidder: 'bidderOne', - adUnitCode: '/19968336/header-bid-tag-0', - auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f' - }, - { - bidId: '6fe3b4c2c23092', - bidder: 'bidderTwo', - adUnitCode: '/19968336/header-bid-tag-0', - auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f' - } - ]; - - adapterManager.registerAnalyticsAdapter({ - code: 'atsAnalytics', - adapter: atsAnalyticsAdapter - }); - - adapterManager.enableAnalytics({ - provider: 'atsAnalytics', - options: initOptions - }); - - // Step 1: Send auction init event - events.emit(constants.EVENTS.AUCTION_INIT, { - timestamp: auctionTimestamp - }); - // Step 2: Send bid requested event - events.emit(constants.EVENTS.BID_REQUESTED, bidRequest); - - // Step 3: Send bid response event - events.emit(constants.EVENTS.BID_RESPONSE, bidResponse); - - // Step 4: Send bid time out event - events.emit(constants.EVENTS.BID_TIMEOUT, bidTimeoutArgsV1); - - // Step 5: Send auction end event - events.emit(constants.EVENTS.AUCTION_END, {}); - - let requests = server.requests.filter(req => { - return req.url.indexOf(analyticsUrl) > -1; - }); - - expect(requests.length).to.equal(1); - - let realAfterBid = JSON.parse(requests[0].requestBody); - // Step 6: assert real data after bid and expected data - expect(realAfterBid['Data']).to.deep.equal(expectedAfterBid['Data']); - - // check that the publisher ID is configured via options - expect(atsAnalyticsAdapter.context.pid).to.equal(initOptions.pid); - }) - it('check browser is safari', function () { - sinon.stub(atsAnalyticsAdapter, 'getUserAgent').returns('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/536.25 (KHTML, like Gecko) Version/6.0 Safari/536.25'); - let browser = parseBrowser(); - expect(browser).to.equal('Safari'); - }) - it('check browser is chrome', function () { - sinon.stub(atsAnalyticsAdapter, 'getUserAgent').returns('Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/80.0.3987.95 Mobile/15E148 Safari/604.1'); - let browser = parseBrowser(); - expect(browser).to.equal('Chrome'); - }) - it('check browser is edge', function () { - sinon.stub(atsAnalyticsAdapter, 'getUserAgent').returns('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.74 Safari/537.36 Edg/79.0.309.43'); - let browser = parseBrowser(); - expect(browser).to.equal('Microsoft Edge'); - }) - it('check browser is firefox', function () { - sinon.stub(atsAnalyticsAdapter, 'getUserAgent').returns('Mozilla/5.0 (iPhone; CPU OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/23.0 Mobile/15E148 Safari/605.1.15'); - let browser = parseBrowser(); - expect(browser).to.equal('Firefox'); - }) - }) -}) diff --git a/test/spec/modules/audiencerunBidAdapter_spec.js b/test/spec/modules/audiencerunBidAdapter_spec.js deleted file mode 100644 index 826944abaf5..00000000000 --- a/test/spec/modules/audiencerunBidAdapter_spec.js +++ /dev/null @@ -1,204 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/audiencerunBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -const ENDPOINT = 'https://d.audiencerun.com/prebid'; - -const BID_SERVER_RESPONSE = { - body: { - bid: [ - { - 'bidId': '51ef8751f9aead', - 'zoneId': '12345abcde', - 'adId': '1234', - 'crid': '5678', - 'cpm': 8.021951999999999999, - 'currency': 'USD', - 'w': 728, - 'h': 90, - 'isNet': false, - 'buying_type': 'rtb', - 'syncUrl': 'https://ac.audiencerun.com/f/sync.html', - 'adm': '' - } - ] - } -}; - -describe('AudienceRun bid adapter tests', 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() { - let bid = { - 'bidder': 'audiencerun', - 'params': { - 'zoneId': '12345abcde' - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'creativeId': 'er2ee' - }; - - it('should return true when required params found', function() { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return true when zoneId is valid', function() { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'zoneId': '12345abcde' - }; - - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function() { - let bid = Object.assign({}, bid); - delete bid.params; - - bid.params = {}; - - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function() { - let bidRequests = [ - { - 'bidder': 'audiencerun', - 'bidId': '51ef8751f9aead', - 'params': { - 'zoneId': '12345abcde' - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'mediaTypes': { - 'banner': { - 'sizes': [[320, 50], [300, 250], [300, 600]] - } - }, - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1 - } - ]; - - it('sends a valid bid request to ENDPOINT via POST', function() { - const request = spec.buildRequests(bidRequests, { - gdprConsent: { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }, - refererInfo: { - canonicalUrl: 'https://example.com/canonical', - referer: 'https://example.com' - } - }); - - expect(request.url).to.equal(ENDPOINT); - expect(request.method).to.equal('POST'); - - const payload = JSON.parse(request.data); - expect(payload.gdpr).to.exist; - - expect(payload.bids).to.exist.and.to.be.an('array').and.to.have.lengthOf(1); - expect(payload.referer).to.exist; - - const bid = payload.bids[0]; - expect(bid).to.exist; - expect(bid).to.have.property('bidId'); - expect(bid).to.have.property('zoneId'); - expect(bid).to.have.property('sizes'); - expect(bid.sizes[0].w).to.be.a('number'); - expect(bid.sizes[0].h).to.be.a('number'); - }); - - it('should send GDPR to endpoint and honor gdprApplies value', function() { - let consentString = 'bogusConsent'; - let bidderRequest = { - 'gdprConsent': { - 'consentString': consentString, - 'gdprApplies': true - } - }; - - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.gdpr).to.exist; - expect(payload.gdpr.consent).to.equal(consentString); - expect(payload.gdpr.applies).to.equal(true); - - let bidderRequest2 = { - 'gdprConsent': { - 'consentString': consentString, - 'gdprApplies': false - } - }; - - const request2 = spec.buildRequests(bidRequests, bidderRequest2); - const payload2 = JSON.parse(request2.data); - - expect(payload2.gdpr).to.exist; - expect(payload2.gdpr.consent).to.equal(consentString); - expect(payload2.gdpr.applies).to.equal(false); - }); - }); - - describe('interpretResponse', function () { - const expectedResponse = [{ - 'requestId': '51ef8751f9aead', - 'adId': '12345abcde', - 'cpm': 8.021951999999999999, - 'width': '728', - 'height': '90', - 'creativeId': '5678', - 'currency': 'USD', - 'netRevenue': false, - 'ttl': 300, - 'ad': '', - 'mediaType': 'banner' - }]; - - it('should get the correct bid response by display ad', function () { - let result = spec.interpretResponse(BID_SERVER_RESPONSE); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('handles empty bid response', function () { - const response = { - body: {} - }; - let result = spec.interpretResponse(response); - expect(result.length).to.equal(0); - }); - }); - - describe('getUserSyncs', function () { - const serverResponses = [ BID_SERVER_RESPONSE ]; - const syncOptions = { iframeEnabled: true }; - - it('should return empty if no server responses', function() { - const syncs = spec.getUserSyncs(syncOptions, []); - expect(syncs).to.deep.equal([]) - }); - - it('should return user syncs', function () { - const syncs = spec.getUserSyncs(syncOptions, serverResponses); - expect(syncs).to.deep.equal([{type: 'iframe', url: 'https://ac.audiencerun.com/f/sync.html'}]) - }); - }); -}); diff --git a/test/spec/modules/automatadBidAdapter_spec.js b/test/spec/modules/automatadBidAdapter_spec.js deleted file mode 100644 index 9d828bad4c3..00000000000 --- a/test/spec/modules/automatadBidAdapter_spec.js +++ /dev/null @@ -1,205 +0,0 @@ -import { expect } from 'chai' -import { spec } from 'modules/automatadBidAdapter.js' -import { newBidder } from 'src/adapters/bidderFactory.js' - -describe('automatadBidAdapter', function () { - const adapter = newBidder(spec) - - let bidRequest = { - bidder: 'automatad', - params: {siteId: '123ad', placementId: '123abc345'}, - mediaTypes: { - banner: { - sizes: [[300, 600]], - } - }, - adUnitCode: 'some-ad-unit-code', - transactionId: '1465569e-52cc-4c36-88a1-7174cfef4b44', - sizes: [[300, 600]], - bidId: '123abc', - bidderRequestId: '3213887463c059', - auctionId: 'abc-123', - src: 'client', - bidRequestsCount: 1 - } - - let expectedResponse = [{ - 'body': { - 'id': 'abc-123', - 'seatbid': [ - { - 'bid': [ - { - 'adm': '', - 'adomain': [ - 'someAdDomain' - ], - 'crid': 123, - 'h': 600, - 'id': 'bid1', - 'impid': '1', - 'nurl': 'https://example/win', - 'price': 0.5, - 'w': 300 - } - ] - } - ] - } - }] - - describe('codes', function () { - it('should return a bidder code of automatad', function () { - expect(spec.code).to.equal('automatad') - }) - it('should alias atd', function () { - expect(spec.aliases.length > 0 && spec.aliases[0] === 'atd').to.be.true - }) - }) - - describe('isBidRequestValid', function () { - let inValidBid = Object.assign({}, bidRequest) - delete inValidBid.params - it('should return true if all params present', function () { - expect(spec.isBidRequestValid(bidRequest)).to.equal(true) - }) - - it('should return false if any parameter missing', function () { - expect(spec.isBidRequestValid(inValidBid)).to.be.false - }) - }) - - describe('buildRequests', function () { - let req = spec.buildRequests([ bidRequest ], { refererInfo: { } }) - let rdata - - it('should return request object', function () { - expect(req).to.not.be.null - }) - - it('should build request data', function () { - expect(req.data).to.not.be.null - }) - - it('should include one request', function () { - rdata = JSON.parse(req.data) - expect(rdata.imp.length).to.equal(1) - }) - - it('should include placement', function () { - let r = rdata.imp[0] - expect(r.placement !== null).to.be.true - }) - - it('should include media types', function () { - let r = rdata.imp[0] - expect(r.media_types !== null).to.be.true - }) - - it('should include all publisher params', function () { - let r = rdata.imp[0] - expect(r.siteID !== null && r.placementID !== null).to.be.true - }) - - it('should include adunit code', function () { - let r = rdata.imp[0] - expect(r.adUnitCode !== null).to.be.true - }) - }) - - describe('interpretResponse', function () { - it('should get the correct bid response', function () { - let result = spec.interpretResponse(expectedResponse[0]) - expect(result).to.be.an('array').that.is.not.empty - expect(result[0].meta.advertiserDomains[0]).to.equal('someAdDomain'); - }) - - it('should interpret multiple bids in seatbid', function () { - let multipleBidResponse = [{ - 'body': { - 'id': 'abc-321', - 'seatbid': [ - { - 'bid': [ - { - 'adm': '', - 'adomain': [ - 'someAdDomain' - ], - 'crid': 123, - 'h': 600, - 'id': 'bid1', - 'impid': 'imp1', - 'nurl': 'https://example/win', - 'price': 0.5, - 'w': 300 - } - ] - }, { - 'bid': [ - { - 'adm': '', - 'adomain': [ - 'someAdDomain' - ], - 'crid': 321, - 'h': 600, - 'id': 'bid1', - 'impid': 'imp2', - 'nurl': 'https://example/win', - 'price': 0.5, - 'w': 300 - } - ] - } - ] - } - }] - let result = spec.interpretResponse(multipleBidResponse[0]).map(bid => { - const {requestId} = bid; - return [ requestId ]; - }); - - assert.equal(result.length, 2); - assert.deepEqual(result, [[ 'imp1' ], [ 'imp2' ]]); - }) - - it('handles empty bid response', function () { - let response = { - body: '' - } - let result = spec.interpretResponse(response) - expect(result.length).to.equal(0) - }) - }) - - describe('getUserSyncs', function () { - it('should return iframe sync', function () { - let sync = spec.getUserSyncs() - expect(sync.length).to.equal(1) - expect(sync[0].type === 'iframe') - expect(typeof sync[0].url === 'string') - }) - }) - - describe('onBidWon', function () { - let serverResponses = spec.interpretResponse(expectedResponse[0]) - let wonbid = serverResponses[0] - let ajaxStub - - beforeEach(() => { - ajaxStub = sinon.stub(spec, 'ajaxCall') - }) - - afterEach(() => { - ajaxStub.restore() - }) - - it('Returns true is nurl is good/not blank', function () { - expect(wonbid.nurl).to.not.equal('') - expect(spec.onBidWon(wonbid)).to.be.true - expect(ajaxStub.calledOnce).to.equal(true) - expect(ajaxStub.firstCall.args[0].indexOf('https://')).to.equal(0) - }) - }) -}) diff --git a/test/spec/modules/avocetBidAdapter_spec.js b/test/spec/modules/avocetBidAdapter_spec.js deleted file mode 100644 index 2a2f29e48d2..00000000000 --- a/test/spec/modules/avocetBidAdapter_spec.js +++ /dev/null @@ -1,167 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/avocetBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; -import { config } from 'src/config'; - -describe('Avocet adapter', function () { - beforeEach(function () { - config.setConfig({ - currency: { - adServerCurrency: 'USD', - }, - publisherDomain: 'test.com', - fpd: { - some: 'data', - }, - }); - }); - - afterEach(function () { - config.resetConfig(); - }); - - describe('inherited functions', function () { - it('exists and is a function', function () { - const adapter = newBidder(spec); - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - it('should return false for bid request missing params', () => { - const invalidBidRequest = { - bid: {}, - }; - expect(spec.isBidRequestValid(invalidBidRequest)).to.equal(false); - }); - it('should return false for an invalid type placement param', () => { - const invalidBidRequest = { - params: { - placement: 123, - }, - }; - expect(spec.isBidRequestValid(invalidBidRequest)).to.equal(false); - }); - it('should return false for an invalid length placement param', () => { - const invalidBidRequest = { - params: { - placement: '123', - }, - }; - expect(spec.isBidRequestValid(invalidBidRequest)).to.equal(false); - }); - it('should return true for a valid length placement param', () => { - const validBidRequest = { - params: { - placement: '012345678901234567890123', - }, - }; - expect(spec.isBidRequestValid(validBidRequest)).to.equal(true); - }); - }); - describe('buildRequests', function () { - it('constructs a valid POST request', function () { - const request = spec.buildRequests( - [ - { - bidder: 'avct', - params: { - placement: '012345678901234567890123', - }, - userId: { - id5id: { - uid: 'test' - } - } - }, - { - bidder: 'avct', - params: { - placement: '012345678901234567890123', - }, - }, - ], - exampleBidderRequest - ); - expect(request.method).to.equal('POST'); - expect(request.url).to.equal('https://ads.avct.cloud/prebid'); - - const requestData = JSON.parse(request.data); - expect(requestData.ext).to.be.an('object'); - expect(requestData.ext.currency).to.equal('USD'); - expect(requestData.ext.publisherDomain).to.equal('test.com'); - expect(requestData.ext.fpd).to.deep.equal({ some: 'data' }); - expect(requestData.ext.schain).to.deep.equal({ - validation: 'strict', - config: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - hp: 1, - }, - ], - }, - }); - expect(requestData.ext.id5id).to.equal('test'); - expect(requestData.bids).to.be.an('array'); - expect(requestData.bids.length).to.equal(2); - }); - }); - describe('interpretResponse', function () { - it('no response', function () { - const response = spec.interpretResponse(); - expect(response).to.be.an('array'); - expect(response.length).to.equal(0); - }); - it('no body', function () { - const response = spec.interpretResponse({}); - expect(response).to.be.an('array'); - expect(response.length).to.equal(0); - }); - it('null body', function () { - const response = spec.interpretResponse({ body: null }); - expect(response).to.be.an('array'); - expect(response.length).to.equal(0); - }); - it('empty body', function () { - const response = spec.interpretResponse({ body: {} }); - expect(response).to.be.an('array'); - expect(response.length).to.equal(0); - }); - it('null body.responses', function () { - const response = spec.interpretResponse({ body: { responses: null } }); - expect(response).to.be.an('array'); - expect(response.length).to.equal(0); - }); - it('array body', function () { - const response = spec.interpretResponse({ body: [{}] }); - expect(response).to.be.an('array'); - expect(response.length).to.equal(1); - }); - it('array body.responses', function () { - const response = spec.interpretResponse({ body: { responses: [{}] } }); - expect(response).to.be.an('array'); - expect(response.length).to.equal(1); - }); - }); -}); - -const exampleBidderRequest = { - schain: { - validation: 'strict', - config: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - hp: 1, - }, - ], - }, - }, -}; diff --git a/test/spec/modules/axonixBidAdapter_spec.js b/test/spec/modules/axonixBidAdapter_spec.js deleted file mode 100644 index a952d527600..00000000000 --- a/test/spec/modules/axonixBidAdapter_spec.js +++ /dev/null @@ -1,378 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/axonixBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; -import * as utils from 'src/utils'; - -describe('AxonixBidAdapter', function () { - const adapter = newBidder(spec); - - const SUPPLY_ID_1 = '91fd110a-5685-11eb-8db6-a7e0eeefbbc7'; - const SUPPLY_ID_2 = '22de2092-568b-11eb-bae3-cfa975dc72aa'; - const REGION_1 = 'us-east-1'; - const REGION_2 = 'eu-west-1'; - - const BANNER_REQUEST = { - adUnitCode: 'ad_code', - bidId: 'abcd1234', - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [300, 200] - ] - } - }, - bidder: 'axonix', - params: { - supplyId: SUPPLY_ID_1, - region: REGION_1 - }, - requestId: 'q4owht8ofqi3ulwsd', - transactionId: 'fvpq3oireansdwo' - }; - - const VIDEO_REQUEST = { - adUnitCode: 'ad_code', - bidId: 'abcd1234', - mediaTypes: { - video: { - context: 'outstream', - mimes: ['video/mp4'], - playerSize: [400, 300], - renderer: { - url: 'https://url.com', - backupOnly: true, - render: () => true - }, - } - }, - bidder: 'axonix', - params: { - supplyId: SUPPLY_ID_1, - region: REGION_1 - }, - requestId: 'q4owht8ofqi3ulwsd', - transactionId: 'fvpq3oireansdwo' - }; - - const BIDDER_REQUEST = { - bidderCode: 'axonix', - auctionId: '18fd8b8b0bd757', - bidderRequestId: '418b37f85e772c', - timeout: 3000, - gdprConsent: { - consentString: 'BOKAVy4OKAVy4ABAB8AAAAAZ+A==', - gdprApplies: true - }, - refererInfo: { - referer: 'https://www.prebid.org', - canonicalUrl: 'https://www.prebid.org/the/link/to/the/page' - } - }; - - const BANNER_RESPONSE = { - body: [{ - requestId: 'f08b3a8dcff747eabada295dcf94eee0', - cpm: 6, - currency: 'USD', - width: 300, - height: 250, - ad: '', - creativeId: 'abc', - netRevenue: false, - meta: { - networkId: 'nid', - advertiserDomains: [ - 'https://the.url' - ], - secondaryCatIds: [ - 'IAB1' - ], - mediaType: 'banner' - }, - nurl: 'https://win.url' - }] - }; - - const VIDEO_RESPONSE = { - body: [{ - requestId: 'f08b3a8dcff747eabada295dcf94eee0', - cpm: 6, - currency: 'USD', - width: 300, - height: 250, - ad: '', - creativeId: 'abc', - netRevenue: false, - meta: { - networkId: 'nid', - advertiserDomains: [ - 'https://the.url' - ], - secondaryCatIds: [ - 'IAB1' - ], - mediaType: 'video' - }, - nurl: 'https://win.url' - }] - }; - - describe('inherited functions', function () { - it('exists and is a function', function () { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - let validBids = [ - { - bidder: 'axonix', - params: { - supplyId: SUPPLY_ID_1, - region: REGION_1 - }, - }, - { - bidder: 'axonix', - params: { - supplyId: SUPPLY_ID_2, - region: REGION_2 - }, - future_parameter: { - future: 'ididid' - } - }, - ]; - - let invalidBids = [ - { - bidder: 'axonix', - params: {}, - }, - { - bidder: 'axonix', - }, - ]; - - it('should accept valid bids', function () { - for (let bid of validBids) { - expect(spec.isBidRequestValid(bid)).to.equal(true); - } - }); - - it('should reject invalid bids', function () { - for (let bid of invalidBids) { - expect(spec.isBidRequestValid(bid)).to.equal(false); - } - }); - }); - - describe('buildRequests: can handle banner ad requests', function () { - it('creates ServerRequests with the correct data', function () { - const [request] = spec.buildRequests([BANNER_REQUEST], BIDDER_REQUEST); - - expect(request).to.have.property('url', `https://openrtb-${REGION_1}.axonix.com/supply/prebid/${SUPPLY_ID_1}`); - expect(request).to.have.property('method', 'POST'); - expect(request).to.have.property('data'); - - const { data } = request; - expect(data.app).to.be.undefined; - - expect(data).to.have.property('site'); - expect(data.site).to.have.property('page', 'https://www.prebid.org'); - - expect(data).to.have.property('validBidRequest', BANNER_REQUEST); - expect(data).to.have.property('connectionType').to.exist; - expect(data).to.have.property('effectiveType').to.exist; - expect(data).to.have.property('devicetype', 2); - expect(data).to.have.property('bidfloor', 0); - expect(data).to.have.property('dnt', 0); - expect(data).to.have.property('language').to.be.a('string'); - expect(data).to.have.property('prebidVersion').to.be.a('string'); - expect(data).to.have.property('screenHeight').to.be.a('number'); - expect(data).to.have.property('screenWidth').to.be.a('number'); - expect(data).to.have.property('tmax').to.be.a('number'); - expect(data).to.have.property('ua').to.be.a('string'); - }); - - it('creates ServerRequests pointing to the correct region and endpoint if it changes', function () { - const bannerRequests = [utils.deepClone(BANNER_REQUEST), utils.deepClone(BANNER_REQUEST)]; - bannerRequests[0].params.endpoint = 'https://the.url'; - bannerRequests[1].params.endpoint = 'https://the.other.url'; - - const requests = spec.buildRequests(bannerRequests, BIDDER_REQUEST); - - requests.forEach((request, index) => { - expect(request).to.have.property('url', bannerRequests[index].params.endpoint); - }); - }); - - it('creates ServerRequests pointing to default endpoint if missing', function () { - const bannerRequests = [utils.deepClone(BANNER_REQUEST), utils.deepClone(BANNER_REQUEST)]; - bannerRequests[1].params.supplyId = SUPPLY_ID_2; - bannerRequests[1].params.region = REGION_2; - - const requests = spec.buildRequests(bannerRequests, BIDDER_REQUEST); - expect(requests[0]).to.have.property('url', `https://openrtb-${REGION_1}.axonix.com/supply/prebid/${SUPPLY_ID_1}`); - expect(requests[1]).to.have.property('url', `https://openrtb-${REGION_2}.axonix.com/supply/prebid/${SUPPLY_ID_2}`); - }); - - it('creates ServerRequests pointing to default region if missing', function () { - const bannerRequest = utils.deepClone(BANNER_REQUEST); - delete bannerRequest.params.region; - - const requests = spec.buildRequests([bannerRequest], BIDDER_REQUEST); - expect(requests[0]).to.have.property('url', `https://openrtb-${REGION_1}.axonix.com/supply/prebid/${SUPPLY_ID_1}`); - }); - }); - - describe('buildRequests: can handle video ad requests', function () { - it('creates ServerRequests with the correct data', function () { - const [request] = spec.buildRequests([VIDEO_REQUEST], BIDDER_REQUEST); - - expect(request).to.have.property('url', `https://openrtb-${REGION_1}.axonix.com/supply/prebid/${SUPPLY_ID_1}`); - expect(request).to.have.property('method', 'POST'); - expect(request).to.have.property('data'); - - const { data } = request; - expect(data.app).to.be.undefined; - - expect(data).to.have.property('site'); - expect(data.site).to.have.property('page', 'https://www.prebid.org'); - - expect(data).to.have.property('validBidRequest', VIDEO_REQUEST); - expect(data).to.have.property('connectionType').to.exist; - expect(data).to.have.property('effectiveType').to.exist; - expect(data).to.have.property('devicetype', 2); - expect(data).to.have.property('bidfloor', 0); - expect(data).to.have.property('dnt', 0); - expect(data).to.have.property('language').to.be.a('string'); - expect(data).to.have.property('prebidVersion').to.be.a('string'); - expect(data).to.have.property('screenHeight').to.be.a('number'); - expect(data).to.have.property('screenWidth').to.be.a('number'); - expect(data).to.have.property('tmax').to.be.a('number'); - expect(data).to.have.property('ua').to.be.a('string'); - }); - - it('creates ServerRequests pointing to the correct region and endpoint if it changes', function () { - const videoRequests = [utils.deepClone(VIDEO_REQUEST), utils.deepClone(VIDEO_REQUEST)]; - videoRequests[0].params.endpoint = 'https://the.url'; - videoRequests[1].params.endpoint = 'https://the.other.url'; - - const requests = spec.buildRequests(videoRequests, BIDDER_REQUEST); - - requests.forEach((request, index) => { - expect(request).to.have.property('url', videoRequests[index].params.endpoint); - }); - }); - - it('creates ServerRequests pointing to default endpoint if missing', function () { - const videoRequests = [utils.deepClone(VIDEO_REQUEST), utils.deepClone(VIDEO_REQUEST)]; - videoRequests[1].params.supplyId = SUPPLY_ID_2; - videoRequests[1].params.region = REGION_2; - - const requests = spec.buildRequests(videoRequests, BIDDER_REQUEST); - expect(requests[0]).to.have.property('url', `https://openrtb-${REGION_1}.axonix.com/supply/prebid/${SUPPLY_ID_1}`); - expect(requests[1]).to.have.property('url', `https://openrtb-${REGION_2}.axonix.com/supply/prebid/${SUPPLY_ID_2}`); - }); - - it('creates ServerRequests pointing to default region if missing', function () { - const videoRequest = utils.deepClone(VIDEO_REQUEST); - delete videoRequest.params.region; - - const requests = spec.buildRequests([videoRequest], BIDDER_REQUEST); - expect(requests[0]).to.have.property('url', `https://openrtb-${REGION_1}.axonix.com/supply/prebid/${SUPPLY_ID_1}`); - }); - }); - - describe.skip('buildRequests: can handle native ad requests', function () { - it('creates ServerRequests pointing to the correct region and endpoint if it changes', function () { - // loop: - // set supply id - // set region/endpoint in ssp config - // call buildRequests, validate request (url, method, supply id) - expect.fail('Not implemented'); - }); - - it('creates ServerRequests pointing to default endpoint if missing', function () { - // no endpoint in config means default value openrtb.axonix.com - expect.fail('Not implemented'); - }); - - it('creates ServerRequests pointing to default region if missing', function () { - // no region in config means default value us-east-1 - expect.fail('Not implemented'); - }); - }); - - describe('interpretResponse', function () { - it('considers corner cases', function() { - expect(spec.interpretResponse(null)).to.be.an('array').that.is.empty; - expect(spec.interpretResponse()).to.be.an('array').that.is.empty; - }); - - it('ignores unparseable responses', function() { - expect(spec.interpretResponse('invalid')).to.be.an('array').that.is.empty; - expect(spec.interpretResponse(['invalid'])).to.be.an('array').that.is.empty; - expect(spec.interpretResponse({ body: [{ invalid: 'object' }] })).to.be.an('array').that.is.empty; - }); - - it('parses banner responses', function () { - const response = spec.interpretResponse(BANNER_RESPONSE); - - expect(response).to.be.an('array').that.is.not.empty; - expect(response[0]).to.equal(BANNER_RESPONSE.body[0]); - }); - - it('parses 1 video responses', function () { - const response = spec.interpretResponse(VIDEO_RESPONSE); - - expect(response).to.be.an('array').that.is.not.empty; - expect(response[0]).to.equal(VIDEO_RESPONSE.body[0]); - }); - - it.skip('parses 1 native responses', function () { - // passing 1 valid native in a response generates an array with 1 correct prebid response - // examine mediaType:native, native element - // check nativeBidIsValid from {@link file://./../../../src/native.js} - expect.fail('Not implemented'); - }); - }); - - describe('onBidWon', function () { - beforeEach(function () { - sinon.stub(utils, 'triggerPixel'); - }); - - afterEach(function () { - utils.triggerPixel.restore(); - }); - - it('called once', function () { - spec.onBidWon(BANNER_RESPONSE.body[0]); - expect(utils.triggerPixel.calledOnce).to.equal(true); - }); - - it('called false', function () { - spec.onBidWon({ cpm: '2.21' }); - expect(utils.triggerPixel.called).to.equal(false); - }); - - it('when there is no notification expected server side, none is called', function () { - var response = spec.onBidWon({}); - expect(utils.triggerPixel.called).to.equal(false); - expect(response).to.be.an('undefined') - }); - }); - - describe('onTimeout', function () { - it('banner response', () => { - spec.onTimeout(spec.interpretResponse(BANNER_RESPONSE)); - }); - - it('video response', () => { - spec.onTimeout(spec.interpretResponse(VIDEO_RESPONSE)); - }); - }); -}); diff --git a/test/spec/modules/beachfrontBidAdapter_spec.js b/test/spec/modules/beachfrontBidAdapter_spec.js deleted file mode 100644 index 605ccc464cb..00000000000 --- a/test/spec/modules/beachfrontBidAdapter_spec.js +++ /dev/null @@ -1,906 +0,0 @@ -import { expect } from 'chai'; -import { spec, VIDEO_ENDPOINT, BANNER_ENDPOINT, OUTSTREAM_SRC, DEFAULT_MIMES } from 'modules/beachfrontBidAdapter.js'; -import { parseUrl } from 'src/utils.js'; - -describe('BeachfrontAdapter', function () { - let bidRequests; - - beforeEach(function () { - bidRequests = [ - { - bidder: 'beachfront', - params: { - bidfloor: 2.00, - appId: '3b16770b-17af-4d22-daff-9606bdf2c9c3' - }, - adUnitCode: 'div-gpt-ad-1460505748561-0', - bidId: '25186806a41eab', - bidderRequestId: '15bdd8d4a0ebaf', - auctionId: 'f17d62d0-e3e3-48d0-9f73-cb4ea358a309' - }, { - bidder: 'beachfront', - params: { - bidfloor: 1.00, - appId: '11bc5dd5-7421-4dd8-c926-40fa653bec76' - }, - adUnitCode: 'div-gpt-ad-1460505748561-1', - bidId: '365088ee6d649d', - bidderRequestId: '15bdd8d4a0ebaf', - auctionId: 'f17d62d0-e3e3-48d0-9f73-cb4ea358a309' - } - ]; - }); - - describe('spec.isBidRequestValid', function () { - it('should return true when the required params are passed', function () { - const bidRequest = bidRequests[0]; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }); - - it('should return false when the "bidfloor" param is missing', function () { - const bidRequest = bidRequests[0]; - bidRequest.params = { - appId: '11bc5dd5-7421-4dd8-c926-40fa653bec76' - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when the "appId" param is missing', function () { - const bidRequest = bidRequests[0]; - bidRequest.params = { - bidfloor: 5.00 - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when no bid params are passed', function () { - const bidRequest = bidRequests[0]; - bidRequest.params = {}; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when a bid request is not passed', function () { - expect(spec.isBidRequestValid()).to.equal(false); - expect(spec.isBidRequestValid({})).to.equal(false); - }); - - describe('for multi-format bids', function () { - it('should return true when the required params are passed for video', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { - video: {} - }; - bidRequest.params = { - video: { - bidfloor: 1.00, - appId: '3b16770b-17af-4d22-daff-9606bdf2c9c3' - } - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }); - - it('should return false when the required params are missing for video', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { - video: {} - }; - bidRequest.params = { - banner: { - bidfloor: 1.00, - appId: '3b16770b-17af-4d22-daff-9606bdf2c9c3' - } - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return true when the required params are passed for banner', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { - banner: {} - }; - bidRequest.params = { - banner: { - bidfloor: 1.00, - appId: '3b16770b-17af-4d22-daff-9606bdf2c9c3' - } - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }); - - it('should return false when the required params are missing for banner', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { - banner: {} - }; - bidRequest.params = { - video: { - bidfloor: 1.00, - appId: '3b16770b-17af-4d22-daff-9606bdf2c9c3' - } - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - }); - }); - - describe('spec.buildRequests', function () { - describe('for video bids', function () { - it('should attach the bid request object', function () { - bidRequests[0].mediaTypes = { video: {} }; - bidRequests[1].mediaTypes = { video: {} }; - const requests = spec.buildRequests(bidRequests); - expect(requests[0].bidRequest).to.equal(bidRequests[0]); - expect(requests[1].bidRequest).to.equal(bidRequests[1]); - }); - - it('should create a POST request for each bid', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { video: {} }; - const requests = spec.buildRequests([ bidRequest ]); - expect(requests[0].method).to.equal('POST'); - expect(requests[0].url).to.equal(VIDEO_ENDPOINT + bidRequest.params.appId); - }); - - it('should attach request data', function () { - const width = 640; - const height = 480; - const bidRequest = bidRequests[0]; - bidRequest.params.tagid = '7cd7a7b4-ef3f-4aeb-9565-3627f255fa10'; - bidRequest.mediaTypes = { - video: { - playerSize: [ width, height ] - } - }; - const topLocation = parseUrl('http://www.example.com?foo=bar', { decodeSearchAsString: true }); - const bidderRequest = { - refererInfo: { - referer: topLocation.href - } - }; - 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); - expect(data.domain).to.equal(document.location.hostname); - expect(data.id).to.be.a('string'); - expect(data.imp[0].video).to.deep.contain({ w: width, h: height, mimes: DEFAULT_MIMES }); - expect(data.imp[0].bidfloor).to.equal(bidRequest.params.bidfloor); - expect(data.imp[0].tagid).to.equal(bidRequest.params.tagid); - expect(data.site).to.deep.equal({ page: topLocation.href, domain: topLocation.hostname }); - expect(data.device).to.deep.contain({ ua: navigator.userAgent, language: navigator.language, js: 1 }); - expect(data.cur).to.deep.equal(['USD']); - }); - - it('must parse bid size from a nested array', function () { - const width = 640; - const height = 480; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { - video: { - playerSize: [[ width, height ]] - } - }; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.imp[0].video).to.deep.contain({ w: width, h: height }); - }); - - it('must parse bid size from a string', function () { - const width = 640; - const height = 480; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { - video: { - playerSize: `${width}x${height}` - } - }; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.imp[0].video).to.deep.contain({ w: width, h: height }); - }); - - it('must handle an empty bid size', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { - video: { - playerSize: [] - } - }; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.imp[0].video).to.deep.contain({ w: undefined, h: undefined }); - }); - - it('must fall back to the size on the bid object', function () { - const width = 640; - const height = 480; - const bidRequest = bidRequests[0]; - bidRequest.sizes = [ width, height ]; - bidRequest.mediaTypes = { video: {} }; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.imp[0].video).to.deep.contain({ w: width, h: height }); - }); - - it('must set video params from the standard object', function () { - const bidRequest = bidRequests[0]; - const mimes = ['video/webm']; - const playbackmethod = 2; - const maxduration = 30; - const placement = 4; - const skip = 1; - bidRequest.mediaTypes = { - video: { mimes, playbackmethod, maxduration, placement, skip } - }; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.imp[0].video).to.deep.contain({ mimes, playbackmethod, maxduration, placement, skip }); - }); - - it('must override video params from the bidder object', function () { - const bidRequest = bidRequests[0]; - const mimes = ['video/webm']; - const playbackmethod = 2; - const maxduration = 30; - const placement = 4; - const skip = 1; - bidRequest.mediaTypes = { video: { placement: 3, skip: 0 } }; - bidRequest.params.video = { mimes, playbackmethod, maxduration, placement, skip }; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.imp[0].video).to.deep.contain({ mimes, playbackmethod, maxduration, placement, skip }); - }); - - it('must add US privacy data to the request', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { video: {} }; - const uspConsent = '2112YYZ'; - const bidderRequest = { uspConsent }; - const requests = spec.buildRequests([ bidRequest ], bidderRequest); - const data = requests[0].data; - expect(data.regs.ext.us_privacy).to.equal(uspConsent); - }); - - it('must add GDPR consent data to the request', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { video: {} }; - const consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - const bidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString - } - }; - 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); - }); - - it('must add schain data to the request', () => { - const schain = { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'directseller.com', - sid: '00001', - rid: 'BidRequest1', - hp: 1 - } - ] - }; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { video: {} }; - bidRequest.schain = schain; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.source.ext.schain).to.deep.equal(schain); - }); - - it('must add the Trade Desk User ID to the request', () => { - const tdid = '4321'; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { video: {} }; - bidRequest.userId = { tdid }; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.user.ext.eids[0]).to.deep.equal({ - source: 'adserver.org', - uids: [{ - id: tdid, - ext: { - rtiPartner: 'TDID' - } - }] - }); - }); - - it('must add the IdentityLink ID to the request', () => { - const idl_env = '4321'; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { video: {} }; - bidRequest.userId = { idl_env }; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.user.ext.eids[0]).to.deep.equal({ - source: 'liveramp.com', - uids: [{ - id: idl_env, - ext: { - rtiPartner: 'idl' - } - }] - }); - }); - - it('must add the Unified ID 2.0 to the request', () => { - const uid2 = { id: '4321' }; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { video: {} }; - bidRequest.userId = { uid2 }; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.user.ext.eids[0]).to.deep.equal({ - source: 'uidapi.com', - uids: [{ - id: uid2.id, - ext: { - rtiPartner: 'UID2' - } - }] - }); - }); - }); - - describe('for banner bids', function () { - it('should attach the bid requests array', function () { - bidRequests[0].mediaTypes = { banner: {} }; - bidRequests[1].mediaTypes = { banner: {} }; - const requests = spec.buildRequests(bidRequests); - expect(requests[0].bidRequest).to.deep.equal(bidRequests); - }); - - it('should create a single POST request for all bids', function () { - bidRequests[0].mediaTypes = { banner: {} }; - bidRequests[1].mediaTypes = { banner: {} }; - const requests = spec.buildRequests(bidRequests); - expect(requests.length).to.equal(1); - expect(requests[0].method).to.equal('POST'); - expect(requests[0].url).to.equal(BANNER_ENDPOINT); - }); - - it('should attach request data', function () { - const width = 300; - const height = 250; - const bidRequest = bidRequests[0]; - bidRequest.params.tagid = '7cd7a7b4-ef3f-4aeb-9565-3627f255fa10'; - bidRequest.mediaTypes = { - banner: { - sizes: [ width, height ] - } - }; - const topLocation = parseUrl('http://www.example.com?foo=bar', { decodeSearchAsString: true }); - const bidderRequest = { - refererInfo: { - referer: topLocation.href - } - }; - const requests = spec.buildRequests([ bidRequest ], bidderRequest); - const data = requests[0].data; - expect(data.slots).to.deep.equal([ - { - slot: bidRequest.adUnitCode, - id: bidRequest.params.appId, - bidfloor: bidRequest.params.bidfloor, - tagid: bidRequest.params.tagid, - sizes: [{ w: width, h: height }] - } - ]); - expect(data.page).to.equal(topLocation.href); - expect(data.domain).to.equal(topLocation.hostname); - expect(data.search).to.equal(topLocation.search); - expect(data.ua).to.equal(navigator.userAgent); - }); - - it('must parse bid size from a nested array', function () { - const width = 300; - const height = 250; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { - banner: { - sizes: [[ width, height ]] - } - }; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.slots[0].sizes).to.deep.equal([ - { w: width, h: height } - ]); - }); - - it('must parse bid size from a string', function () { - const width = 300; - const height = 250; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { - banner: { - sizes: `${width}x${height}` - } - }; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.slots[0].sizes).to.deep.equal([ - { w: width, h: height } - ]); - }); - - it('must handle an empty bid size', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { - banner: { - sizes: [] - } - }; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.slots[0].sizes).to.deep.equal([]); - }); - - it('must fall back to the size on the bid object', function () { - const width = 300; - const height = 250; - const bidRequest = bidRequests[0]; - bidRequest.sizes = [ width, height ]; - bidRequest.mediaTypes = { banner: {} }; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.slots[0].sizes).to.deep.contain({ w: width, h: height }); - }); - - it('must add US privacy data to the request', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { banner: {} }; - const uspConsent = '2112YYZ'; - const bidderRequest = { uspConsent }; - const requests = spec.buildRequests([ bidRequest ], bidderRequest); - const data = requests[0].data; - expect(data.usPrivacy).to.equal(uspConsent); - }); - - it('must add GDPR consent data to the request', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { banner: {} }; - const consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - const bidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString - } - }; - const requests = spec.buildRequests([ bidRequest ], bidderRequest); - const data = requests[0].data; - expect(data.gdpr).to.equal(1); - expect(data.gdprConsent).to.equal(consentString); - }); - - it('must add schain data to the request', () => { - const schain = { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'directseller.com', - sid: '00001', - rid: 'BidRequest1', - hp: 1 - } - ] - }; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { banner: {} }; - bidRequest.schain = schain; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.schain).to.deep.equal(schain); - }); - - it('must add the Trade Desk User ID to the request', () => { - const tdid = '4321'; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { banner: {} }; - bidRequest.userId = { tdid }; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.tdid).to.equal(tdid); - }); - - it('must add the IdentityLink ID to the request', () => { - const idl_env = '4321'; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { banner: {} }; - bidRequest.userId = { idl_env }; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.idl).to.equal(idl_env); - }); - - it('must add the Unified ID 2.0 to the request', () => { - const uid2 = { id: '4321' }; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { banner: {} }; - bidRequest.userId = { uid2 }; - const requests = spec.buildRequests([ bidRequest ]); - const data = requests[0].data; - expect(data.uid2).to.equal(uid2.id); - }); - }); - - describe('for multi-format bids', function () { - it('should create a POST request for each bid format', function () { - const width = 300; - const height = 250; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { - video: { - playerSize: [ width, height ] - }, - banner: { - sizes: [ width, height ] - } - }; - bidRequest.params = { - video: { - bidfloor: 2.00, - appId: '11bc5dd5-7421-4dd8-c926-40fa653bec76' - }, - banner: { - bidfloor: 1.00, - appId: '3b16770b-17af-4d22-daff-9606bdf2c9c3' - } - }; - 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); - }); - - it('must parse bid sizes for each bid format', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { - video: { - playerSize: [ 640, 360 ] - }, - banner: { - sizes: [ 300, 250 ] - } - }; - bidRequest.params = { - video: { - bidfloor: 2.00, - appId: '11bc5dd5-7421-4dd8-c926-40fa653bec76' - }, - banner: { - bidfloor: 1.00, - appId: '3b16770b-17af-4d22-daff-9606bdf2c9c3' - } - }; - 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 }]); - }); - }); - }); - - describe('spec.interpretResponse', function () { - describe('for video bids', function () { - it('should return no bids if the response is not valid', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { video: {} }; - const bidResponse = spec.interpretResponse({ body: null }, { bidRequest }); - expect(bidResponse.length).to.equal(0); - }); - - it('should return no bids if the response "bidPrice" is missing', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { video: {} }; - const serverResponse = { - url: 'http://reachms.bfmio.com/getmu?aid=bid:19c4a196-fb21-4c81-9a1a-ecc5437a39da' - }; - const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest }); - expect(bidResponse.length).to.equal(0); - }); - - it('should return a valid video bid response', function () { - const width = 640; - const height = 480; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { - video: { - playerSize: [ width, height ] - } - }; - const serverResponse = { - bidPrice: 5.00, - url: 'http://reachms.bfmio.com/getmu?aid=bid:19c4a196-fb21-4c81-9a1a-ecc5437a39da', - vast: '', - crid: '123abc' - }; - const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest }); - expect(bidResponse).to.deep.equal({ - requestId: bidRequest.bidId, - bidderCode: spec.code, - cpm: serverResponse.bidPrice, - creativeId: serverResponse.crid, - vastUrl: serverResponse.url, - vastXml: serverResponse.vast, - width: width, - height: height, - renderer: null, - mediaType: 'video', - currency: 'USD', - netRevenue: true, - ttl: 300 - }); - }); - - it('should default to the legacy "cmpId" value for the creative ID', () => { - const width = 640; - const height = 480; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { - video: { - playerSize: [ width, height ] - } - }; - const serverResponse = { - bidPrice: 5.00, - url: 'http://reachms.bfmio.com/getmu?aid=bid:19c4a196-fb21-4c81-9a1a-ecc5437a39da', - cmpId: '123abc' - }; - const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest }); - expect(bidResponse).to.deep.contain({ - creativeId: serverResponse.cmpId - }); - }); - - it('should return only vast url if the response type is "nurl"', () => { - const width = 640; - const height = 480; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { - video: { - playerSize: [ width, height ] - } - }; - bidRequest.params.video = { responseType: 'nurl' }; - const serverResponse = { - bidPrice: 5.00, - url: 'http://reachms.bfmio.com/getmu?aid=bid:19c4a196-fb21-4c81-9a1a-ecc5437a39da', - vast: '', - crid: '123abc' - }; - const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest }); - expect(bidResponse.vastUrl).to.equal(serverResponse.url); - expect(bidResponse.vastXml).to.equal(undefined); - }); - - it('should return only vast xml if the response type is "adm"', () => { - const width = 640; - const height = 480; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { - video: { - playerSize: [ width, height ] - } - }; - bidRequest.params.video = { responseType: 'adm' }; - const serverResponse = { - bidPrice: 5.00, - url: 'http://reachms.bfmio.com/getmu?aid=bid:19c4a196-fb21-4c81-9a1a-ecc5437a39da', - vast: '', - crid: '123abc' - }; - const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest }); - expect(bidResponse.vastUrl).to.equal(undefined); - expect(bidResponse.vastXml).to.equal(serverResponse.vast); - }); - - it('should return a renderer for outstream video bids', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { - video: { - context: 'outstream' - } - }; - const serverResponse = { - bidPrice: 5.00, - url: 'http://reachms.bfmio.com/getmu?aid=bid:19c4a196-fb21-4c81-9a1a-ecc5437a39da', - crid: '123abc' - }; - const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest }); - expect(bidResponse.renderer).to.deep.contain({ - id: bidRequest.bidId, - url: OUTSTREAM_SRC - }); - expect(bidResponse.renderer.render).to.be.a('function'); - }); - }); - - describe('for banner bids', function () { - it('should return no bids if the response is not valid', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { banner: {} }; - const bidResponse = spec.interpretResponse({ body: null }, { bidRequest }); - expect(bidResponse.length).to.equal(0); - }); - - it('should return no bids if the response is empty', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { banner: {} }; - const bidResponse = spec.interpretResponse({ body: [] }, { bidRequest }); - expect(bidResponse.length).to.equal(0); - }); - - it('should return valid banner bid responses', function () { - bidRequests[0].mediaTypes = { - banner: { - sizes: [[ 300, 250 ], [ 728, 90 ]] - } - }; - bidRequests[1].mediaTypes = { - banner: { - sizes: [[ 300, 600 ], [ 200, 200 ]] - } - }; - const serverResponse = [{ - slot: bidRequests[0].adUnitCode, - adm: '
', - crid: 'crid_1', - price: 3.02, - w: 728, - h: 90 - }, { - slot: bidRequests[1].adUnitCode, - adm: '
', - crid: 'crid_2', - price: 3.06, - w: 300, - h: 600 - }]; - 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, - bidderCode: spec.code, - ad: serverResponse[ i ].adm, - creativeId: serverResponse[ i ].crid, - cpm: serverResponse[ i ].price, - width: serverResponse[ i ].w, - height: serverResponse[ i ].h, - mediaType: 'banner', - currency: 'USD', - netRevenue: true, - ttl: 300 - }); - } - }); - }); - }); - - describe('spec.getUserSyncs', function () { - describe('for video bids', function () { - let bidResponse; - - beforeEach(function () { - bidResponse = { - bidPrice: 5.00, - url: 'http://reachms.bfmio.com/getmu?aid=bid:19c4a196-fb21-4c81-9a1a-ecc5437a39da', - crid: '123abc' - }; - }); - - it('should return an iframe user sync if iframes are enabled', function () { - const syncOptions = { - iframeEnabled: true, - pixelEnabled: true - }; - const serverResponses = [{ - body: bidResponse - }]; - const userSyncs = spec.getUserSyncs(syncOptions, serverResponses); - expect(userSyncs.length).to.equal(1); - expect(userSyncs[0].type).to.equal('iframe'); - }); - - it('should return an image user sync if iframes are disabled', function () { - const syncOptions = { - iframeEnabled: false, - pixelEnabled: true - }; - const serverResponses = [{ - body: bidResponse - }]; - const userSyncs = spec.getUserSyncs(syncOptions, serverResponses); - expect(userSyncs.length).to.equal(1); - expect(userSyncs[0].type).to.equal('image'); - }); - - it('should not return user syncs if none are enabled', function () { - const syncOptions = { - iframeEnabled: false, - pixelEnabled: false - }; - const serverResponses = [{ - body: bidResponse - }]; - const userSyncs = spec.getUserSyncs(syncOptions, serverResponses); - expect(userSyncs).to.deep.equal([]); - }); - }); - - describe('for banner bids', function () { - let bidResponse; - - beforeEach(function () { - bidResponse = { - slot: bidRequests[0].adUnitCode, - adm: '
', - crid: 'crid_1', - price: 3.02, - w: 728, - h: 90 - }; - }); - - it('should return user syncs defined the bid response', function () { - const syncUrl = 'https://sync.bfmio.com/sync_iframe?ifpl=5&ifg=1&id=test&gdpr=0&gc=&gce=0'; - const syncOptions = { - iframeEnabled: true, - pixelEnabled: true - }; - const serverResponses = [{ - body: [ - { sync: syncUrl }, - bidResponse - ] - }]; - const userSyncs = spec.getUserSyncs(syncOptions, serverResponses); - expect(userSyncs).to.deep.equal([ - { type: 'iframe', url: syncUrl } - ]); - }); - - it('should not return user syncs if iframes are disabled', function () { - const syncUrl = 'https://sync.bfmio.com/sync_iframe?ifpl=5&ifg=1&id=test&gdpr=0&gc=&gce=0'; - const syncOptions = { - iframeEnabled: false, - pixelEnabled: true - }; - const serverResponses = [{ - body: [ - { sync: syncUrl }, - bidResponse - ] - }]; - const userSyncs = spec.getUserSyncs(syncOptions, serverResponses); - expect(userSyncs).to.deep.equal([]); - }); - - it('should not return user syncs if there are none in the bid response', function () { - const syncOptions = { - iframeEnabled: true, - pixelEnabled: true - }; - const serverResponses = [{ - body: [ - bidResponse - ] - }]; - const userSyncs = spec.getUserSyncs(syncOptions, serverResponses); - expect(userSyncs).to.deep.equal([]); - }); - }); - }); -}); diff --git a/test/spec/modules/betweenBidAdapter_spec.js b/test/spec/modules/betweenBidAdapter_spec.js deleted file mode 100644 index 1b1ccd9efd2..00000000000 --- a/test/spec/modules/betweenBidAdapter_spec.js +++ /dev/null @@ -1,270 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/betweenBidAdapter.js'; - -describe('betweenBidAdapterTests', function () { - it('validate_pub_params', function () { - expect(spec.isBidRequestValid({ - bidder: 'between', - params: { - w: 240, - h: 400, - s: 1112 - } - })).to.equal(true); - }); - it('validate_generated_params', function () { - let bidRequestData = [{ - bidId: 'bid1234', - bidder: 'between', - params: {w: 240, h: 400, s: 1112}, - sizes: [[240, 400]] - }] - let request = spec.buildRequests(bidRequestData); - let req_data = JSON.parse(request.data)[0].data; - expect(req_data.bidid).to.equal('bid1234'); - }); - it('validate itu param', function() { - let bidRequestData = [{ - bidId: 'bid1234', - bidder: 'between', - params: { - w: 240, - h: 400, - s: 1112, - itu: 'https://something.url' - }, - sizes: [[240, 400]] - }]; - - let request = spec.buildRequests(bidRequestData); - let req_data = JSON.parse(request.data)[0].data; - - expect(req_data.itu).to.equal('https://something.url'); - }); - it('validate cur param', function() { - let bidRequestData = [{ - bidId: 'bid1234', - bidder: 'between', - params: { - w: 240, - h: 400, - s: 1112, - cur: 'THX' - }, - sizes: [[240, 400]] - }]; - - let request = spec.buildRequests(bidRequestData); - let req_data = JSON.parse(request.data)[0].data; - - expect(req_data.cur).to.equal('THX'); - }); - it('validate subid param', function() { - let bidRequestData = [{ - bidId: 'bid1234', - bidder: 'between', - params: { - w: 240, - h: 400, - s: 1112, - subid: 1138, - }, - sizes: [[240, 400]] - }]; - - let request = spec.buildRequests(bidRequestData); - let req_data = JSON.parse(request.data)[0].data; - - expect(req_data.subid).to.equal(1138); - }); - it('validate click3rd param', function() { - let bidRequestData = [{ - bidId: 'bid1234', - bidder: 'between', - params: { - w: 240, - h: 400, - s: 1112, - click3rd: 'https://something.url', - }, - sizes: [[240, 400]] - }]; - - let request = spec.buildRequests(bidRequestData); - let req_data = JSON.parse(request.data)[0].data; - - expect(req_data.click3rd).to.equal('https://something.url'); - }); - it('validate pubdata param', function() { - let bidRequestData = [{ - bidId: 'bid1234', - bidder: 'between', - params: { - w: 240, - h: 400, - s: 1112, - pubdata: { - param: '&test=tset' - }, - }, - sizes: [[240, 400]] - }]; - - let request = spec.buildRequests(bidRequestData); - let req_data = JSON.parse(request.data)[0].data; - - expect(req_data['pubside_macro[param]']).to.equal('%26test%3Dtset'); - }); - it('validate gdprConsent', function() { - let bidRequestData = [{ - bidId: 'bid1234', - bidder: 'between', - params: { - w: 240, - h: 400, - s: 1112, - }, - sizes: [[240, 400]] - }]; - let bidderRequest = { - gdprConsent: { - consentString: 'BOtGbjbOtGbjbBQABBENC3-AAAAtR7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4u_1vf99yfm1-7etr3tp_87ues2_Xur__79__3z3_9pxP78k89r7337Ew_v-_v-b7JCON_IA', - gdprApplies: true - } - } - - let request = spec.buildRequests(bidRequestData, bidderRequest); - let req_data = JSON.parse(request.data)[0].data; - - expect(req_data.gdprApplies).to.equal(bidderRequest.gdprConsent.gdprApplies); - expect(req_data.consentString).to.equal(bidderRequest.gdprConsent.consentString); - }); - it('validate_response_params', function () { - let serverResponse = { - body: [{ - bidid: 'bid1234', - cpm: 1.12, - w: 240, - h: 400, - currency: 'USD', - ad: 'Ad html' - }] - }; - let bids = spec.interpretResponse(serverResponse); - expect(bids).to.have.lengthOf(1); - let bid = bids[0]; - expect(bid.cpm).to.equal(1.12); - expect(bid.currency).to.equal('USD'); - expect(bid.width).to.equal(240); - expect(bid.height).to.equal(400); - expect(bid.netRevenue).to.equal(true); - expect(bid.requestId).to.equal('bid1234'); - expect(bid.ad).to.equal('Ad html'); - }); - it('validate_response_params', function () { - let serverResponse = { - body: [{ - bidid: 'bid1234', - w: 240, - h: 400, - currency: 'USD', - ad: 'Ad html' - }] - }; - let bids = spec.interpretResponse(serverResponse); - expect(bids).to.have.lengthOf(1); - let bid = bids[0]; - expect(bid.cpm).to.equal(0); - expect(bid.currency).to.equal('USD'); - expect(bid.width).to.equal(240); - expect(bid.height).to.equal(400); - expect(bid.netRevenue).to.equal(true); - expect(bid.requestId).to.equal('bid1234'); - expect(bid.ad).to.equal('Ad html'); - }); - it('validate response params without currency', function () { - let serverResponse = { - body: [{ - bidid: 'bid1234', - w: 240, - h: 400, - ad: 'Ad html' - }] - }; - let bids = spec.interpretResponse(serverResponse); - expect(bids).to.have.lengthOf(1); - let bid = bids[0]; - expect(bid.currency).to.equal('RUB'); - }); - it('check getUserSyncs', function() { - const syncs = spec.getUserSyncs({}, {}); - expect(syncs).to.be.an('array').that.to.have.lengthOf(1); - expect(syncs[0]).to.deep.equal({type: 'iframe', url: 'https://ads.betweendigital.com/sspmatch-iframe'}); - }); - - it('check sizes', function() { - let bidRequestData = [{ - bidId: 'bid1234', - bidder: 'between', - mediaTypes: { - banner: { - sizes: [[970, 250], [240, 400], [728, 90]] - } - }, - params: { - s: 1112, - }, - }]; - - let request = spec.buildRequests(bidRequestData); - let req_data = JSON.parse(request.data)[0].data; - - expect(req_data.sizes).to.deep.equal(['970x250', '240x400', '728x90']) - }); - - it('check sharedId with id and third', function() { - const bidRequestData = [{ - bidId: 'bid123', - bidder: 'between', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - }, - params: { - s: 1112, - }, - userId: { - sharedid: { - id: '01EXQE7JKNDRDDVATB0S2GX1NT', - third: '01EXQE7JKNDRDDVATB0S2GX1NT' - } - } - }]; - const shid = JSON.parse(spec.buildRequests(bidRequestData).data)[0].data.shid; - const shid3 = JSON.parse(spec.buildRequests(bidRequestData).data)[0].data.shid3; - expect(shid).to.equal('01EXQE7JKNDRDDVATB0S2GX1NT') && expect(shid3).to.equal('01EXQE7JKNDRDDVATB0S2GX1NT'); - }); - it('check sharedId with only id', function() { - const bidRequestData = [{ - bidId: 'bid123', - bidder: 'between', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - }, - params: { - s: 1112, - }, - userId: { - sharedid: { - id: '01EXQE7JKNDRDDVATB0S2GX1NT', - } - } - }]; - const shid = JSON.parse(spec.buildRequests(bidRequestData).data)[0].data.shid; - const shid3 = JSON.parse(spec.buildRequests(bidRequestData).data)[0].data.shid3; - expect(shid).to.equal('01EXQE7JKNDRDDVATB0S2GX1NT') && expect(shid3).to.equal(''); - }); -}); diff --git a/test/spec/modules/bidViewability_spec.js b/test/spec/modules/bidViewability_spec.js deleted file mode 100644 index 211dec090a5..00000000000 --- a/test/spec/modules/bidViewability_spec.js +++ /dev/null @@ -1,297 +0,0 @@ -import * as bidViewability from 'modules/bidViewability.js'; -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 * as prebidGlobal from 'src/prebidGlobal.js'; -import { EVENTS } from 'src/constants.json'; -import adapterManager, { gdprDataHandler, uspDataHandler } from 'src/adapterManager.js'; -import parse from 'url-parse'; - -const GPT_SLOT = { - getAdUnitPath() { - return '/harshad/Jan/2021/'; - }, - - getSlotElementId() { - return 'DIV-1'; - } -}; - -const PBJS_WINNING_BID = { - 'adUnitCode': '/harshad/Jan/2021/', - 'bidderCode': 'pubmatic', - 'bidder': 'pubmatic', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': 'id', - 'requestId': 1024, - 'source': 'client', - 'no_bid': false, - 'cpm': '1.1495', - 'ttl': 180, - 'creativeId': 'id', - 'netRevenue': true, - 'currency': 'USD', - 'vurls': [ - 'https://domain-1.com/end-point?a=1', - 'https://domain-2.com/end-point/', - 'https://domain-3.com/end-point?a=1' - ] -}; - -describe('#bidViewability', function() { - let gptSlot; - let pbjsWinningBid; - - beforeEach(function() { - gptSlot = Object.assign({}, GPT_SLOT); - pbjsWinningBid = Object.assign({}, PBJS_WINNING_BID); - }); - - describe('isBidAdUnitCodeMatchingSlot', function() { - it('match found by GPT Slot getAdUnitPath', function() { - expect(bidViewability.isBidAdUnitCodeMatchingSlot(pbjsWinningBid, gptSlot)).to.equal(true); - }); - - it('match found by GPT Slot getSlotElementId', function() { - pbjsWinningBid.adUnitCode = 'DIV-1'; - expect(bidViewability.isBidAdUnitCodeMatchingSlot(pbjsWinningBid, gptSlot)).to.equal(true); - }); - - it('match not found', function() { - pbjsWinningBid.adUnitCode = 'DIV-10'; - expect(bidViewability.isBidAdUnitCodeMatchingSlot(pbjsWinningBid, gptSlot)).to.equal(false); - }); - }); - - describe('getMatchingWinningBidForGPTSlot', function() { - let winningBidsArray; - let sandbox - beforeEach(function() { - sandbox = sinon.sandbox.create(); - // mocking winningBidsArray - winningBidsArray = []; - sandbox.stub(prebidGlobal, 'getGlobal').returns({ - getAllWinningBids: function (number) { - return winningBidsArray; - } - }); - }); - - afterEach(function() { - sandbox.restore(); - }) - - it('should find a match by using customMatchFunction provided in config', function() { - // Needs config to be passed with customMatchFunction - let bidViewabilityConfig = { - customMatchFunction(bid, slot) { - return ('AD-' + slot.getAdUnitPath()) === bid.adUnitCode; - } - }; - let newWinningBid = Object.assign({}, PBJS_WINNING_BID, {adUnitCode: 'AD-' + PBJS_WINNING_BID.adUnitCode}); - // Needs pbjs.getWinningBids to be implemented with match - winningBidsArray.push(newWinningBid); - let wb = bidViewability.getMatchingWinningBidForGPTSlot(bidViewabilityConfig, gptSlot); - expect(wb).to.deep.equal(newWinningBid); - }); - - it('should NOT find a match by using customMatchFunction provided in config', function() { - // Needs config to be passed with customMatchFunction - let bidViewabilityConfig = { - customMatchFunction(bid, slot) { - return ('AD-' + slot.getAdUnitPath()) === bid.adUnitCode; - } - }; - // Needs pbjs.getWinningBids to be implemented without match; winningBidsArray is set to empty in beforeEach - let wb = bidViewability.getMatchingWinningBidForGPTSlot(bidViewabilityConfig, gptSlot); - expect(wb).to.equal(null); - }); - - it('should find a match by using default matching function', function() { - // Needs config to be passed without customMatchFunction - // Needs pbjs.getWinningBids to be implemented with match - winningBidsArray.push(PBJS_WINNING_BID); - let wb = bidViewability.getMatchingWinningBidForGPTSlot({}, gptSlot); - expect(wb).to.deep.equal(PBJS_WINNING_BID); - }); - - it('should NOT find a match by using default matching function', function() { - // Needs config to be passed without customMatchFunction - // Needs pbjs.getWinningBids to be implemented without match; winningBidsArray is set to empty in beforeEach - let wb = bidViewability.getMatchingWinningBidForGPTSlot({}, gptSlot); - expect(wb).to.equal(null); - }); - }); - - describe('fireViewabilityPixels', function() { - let sandbox; - let triggerPixelSpy; - - beforeEach(function() { - sandbox = sinon.sandbox.create(); - triggerPixelSpy = sandbox.spy(utils, ['triggerPixel']); - }); - - afterEach(function() { - sandbox.restore(); - }); - - it('DO NOT fire pixels if NOT mentioned in module config', function() { - let moduleConfig = {}; - bidViewability.fireViewabilityPixels(moduleConfig, PBJS_WINNING_BID); - expect(triggerPixelSpy.callCount).to.equal(0); - }); - - it('fire pixels if mentioned in module config', function() { - let moduleConfig = {firePixels: true}; - bidViewability.fireViewabilityPixels(moduleConfig, PBJS_WINNING_BID); - PBJS_WINNING_BID.vurls.forEach((url, i) => { - let call = triggerPixelSpy.getCall(i); - expect(call.args[0]).to.equal(url); - }); - }); - - it('USP: should include the us_privacy key when USP Consent is available', function () { - let uspDataHandlerStub = sinon.stub(uspDataHandler, 'getConsentData'); - uspDataHandlerStub.returns('1YYY'); - let moduleConfig = {firePixels: true}; - bidViewability.fireViewabilityPixels(moduleConfig, PBJS_WINNING_BID); - PBJS_WINNING_BID.vurls.forEach((url, i) => { - let call = triggerPixelSpy.getCall(i); - expect(call.args[0].indexOf(url)).to.equal(0); - const testurl = parse(call.args[0]); - const queryObject = utils.parseQS(testurl.query); - expect(queryObject.us_privacy).to.equal('1YYY'); - }); - uspDataHandlerStub.restore(); - }); - - it('USP: should not include the us_privacy key when USP Consent is not available', function () { - let moduleConfig = {firePixels: true}; - bidViewability.fireViewabilityPixels(moduleConfig, PBJS_WINNING_BID); - PBJS_WINNING_BID.vurls.forEach((url, i) => { - let call = triggerPixelSpy.getCall(i); - expect(call.args[0].indexOf(url)).to.equal(0); - const testurl = parse(call.args[0]); - const queryObject = utils.parseQS(testurl.query); - expect(queryObject.us_privacy).to.equal(undefined); - }); - }); - - it('GDPR: should include the GDPR keys when GDPR Consent is available', function() { - let gdprDataHandlerStub = sinon.stub(gdprDataHandler, 'getConsentData'); - gdprDataHandlerStub.returns({ - gdprApplies: true, - consentString: 'consent', - addtlConsent: 'moreConsent' - }); - let moduleConfig = {firePixels: true}; - bidViewability.fireViewabilityPixels(moduleConfig, PBJS_WINNING_BID); - PBJS_WINNING_BID.vurls.forEach((url, i) => { - let call = triggerPixelSpy.getCall(i); - expect(call.args[0].indexOf(url)).to.equal(0); - const testurl = parse(call.args[0]); - const queryObject = utils.parseQS(testurl.query); - expect(queryObject.gdpr).to.equal('1'); - expect(queryObject.gdpr_consent).to.equal('consent'); - expect(queryObject.addtl_consent).to.equal('moreConsent'); - }); - gdprDataHandlerStub.restore(); - }); - - it('GDPR: should not include the GDPR keys when GDPR Consent is not available', function () { - let moduleConfig = {firePixels: true}; - bidViewability.fireViewabilityPixels(moduleConfig, PBJS_WINNING_BID); - PBJS_WINNING_BID.vurls.forEach((url, i) => { - let call = triggerPixelSpy.getCall(i); - expect(call.args[0].indexOf(url)).to.equal(0); - const testurl = parse(call.args[0]); - const queryObject = utils.parseQS(testurl.query); - expect(queryObject.gdpr).to.equal(undefined); - expect(queryObject.gdpr_consent).to.equal(undefined); - expect(queryObject.addtl_consent).to.equal(undefined); - }); - }); - - it('GDPR: should only include the GDPR keys for GDPR Consent fields with values', function () { - let gdprDataHandlerStub = sinon.stub(gdprDataHandler, 'getConsentData'); - gdprDataHandlerStub.returns({ - gdprApplies: true, - consentString: 'consent' - }); - let moduleConfig = {firePixels: true}; - bidViewability.fireViewabilityPixels(moduleConfig, PBJS_WINNING_BID); - PBJS_WINNING_BID.vurls.forEach((url, i) => { - let call = triggerPixelSpy.getCall(i); - expect(call.args[0].indexOf(url)).to.equal(0); - const testurl = parse(call.args[0]); - const queryObject = utils.parseQS(testurl.query); - expect(queryObject.gdpr).to.equal('1'); - expect(queryObject.gdpr_consent).to.equal('consent'); - expect(queryObject.addtl_consent).to.equal(undefined); - }); - gdprDataHandlerStub.restore(); - }) - }); - - describe('impressionViewableHandler', function() { - let sandbox; - let triggerPixelSpy; - let eventsEmitSpy; - let logWinningBidNotFoundSpy; - let callBidViewableBidderSpy; - let winningBidsArray; - - beforeEach(function() { - sandbox = sinon.sandbox.create(); - triggerPixelSpy = sandbox.spy(utils, ['triggerPixel']); - eventsEmitSpy = sandbox.spy(events, ['emit']); - callBidViewableBidderSpy = sandbox.spy(adapterManager, ['callBidViewableBidder']); - // mocking winningBidsArray - winningBidsArray = []; - sandbox.stub(prebidGlobal, 'getGlobal').returns({ - getAllWinningBids: function (number) { - return winningBidsArray; - } - }); - }); - - afterEach(function() { - sandbox.restore(); - }) - - it('matching winning bid is found', function() { - let moduleConfig = { - firePixels: true - }; - winningBidsArray.push(PBJS_WINNING_BID); - bidViewability.impressionViewableHandler(moduleConfig, GPT_SLOT, null); - // fire pixels should be called - PBJS_WINNING_BID.vurls.forEach((url, i) => { - let call = triggerPixelSpy.getCall(i); - expect(call.args[0]).to.equal(url); - }); - // adapterManager.callBidViewableBidder is called with required args - let call = callBidViewableBidderSpy.getCall(0); - expect(call.args[0]).to.equal(PBJS_WINNING_BID.bidder); - expect(call.args[1]).to.deep.equal(PBJS_WINNING_BID); - // EVENTS.BID_VIEWABLE is triggered - call = eventsEmitSpy.getCall(0); - expect(call.args[0]).to.equal(EVENTS.BID_VIEWABLE); - expect(call.args[1]).to.deep.equal(PBJS_WINNING_BID); - }); - - it('matching winning bid is NOT found', function() { - // fire pixels should NOT be called - expect(triggerPixelSpy.callCount).to.equal(0); - // adapterManager.callBidViewableBidder is NOT called - expect(callBidViewableBidderSpy.callCount).to.equal(0); - // EVENTS.BID_VIEWABLE is NOT triggered - expect(eventsEmitSpy.callCount).to.equal(0); - }); - }); -}); diff --git a/test/spec/modules/bidfluenceBidAdapter_spec.js b/test/spec/modules/bidfluenceBidAdapter_spec.js deleted file mode 100644 index 6b3a0c2b044..00000000000 --- a/test/spec/modules/bidfluenceBidAdapter_spec.js +++ /dev/null @@ -1,114 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/bidfluenceBidAdapter.js'; - -const BIDDER_CODE = 'bidfluence'; -const PLACEMENT_ID = '1000'; -const PUB_ID = '1000'; -const CONSENT_STRING = 'DUXDSDFSFWRRR8345F=='; - -const validBidRequests = [{ - 'bidder': BIDDER_CODE, - 'params': { - 'placementId': PLACEMENT_ID, - 'publisherId': PUB_ID, - 'reservePrice': 0 - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250]], - 'bidId': '2b1f23307fb8ef', - 'bidderRequestId': '10edf38ec1a719', - 'auctionId': '1025ba77-5463-4877-b0eb-14b205cb9304' -}]; - -const bidderRequest = { - 'bidderCode': 'bidfluence', - 'auctionId': '1025ba77-5463-4877-b0eb-14b205cb9304', - 'bidderRequestId': '10edf38ec1a719', - 'refererInfo': { - 'numIframes': 0, - 'reachedTop': true, - 'referer': 'test', - 'stack': ['test'] - }, - 'timeout': 1000, - 'gdprConsent': { - 'gdprApplies': true, - 'consentString': CONSENT_STRING, - 'vendorData': '' - } -}; - -bidderRequest.bids = validBidRequests; - -describe('Bidfluence Adapter test', () => { - describe('isBidRequestValid', function () { - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(validBidRequests[0])).to.equal(true); - }); - it('should return the right bidder code', function () { - expect(spec.code).to.eql(BIDDER_CODE); - }); - }); - - describe('buildRequests', function () { - it('sends bid request to our endpoint via POST', function () { - const request = spec.buildRequests(validBidRequests, bidderRequest); - expect(request.method).to.equal('POST'); - const payload = JSON.parse(request.data); - - expect(payload.bids[0].bid).to.equal(validBidRequests[0].bidId); - expect(payload.azr).to.equal(true); - expect(payload.ck).to.not.be.undefined; - expect(payload.bids[0].tid).to.equal(PLACEMENT_ID); - expect(payload.bids[0].pid).to.equal(PUB_ID); - expect(payload.bids[0].rp).to.be.a('number'); - expect(payload.re).to.not.be.undefined; - expect(payload.st).to.not.be.undefined; - expect(payload.tz).to.not.be.undefined; - expect(payload.sr).to.not.be.undefined; - expect(payload.vp).to.not.be.undefined; - expect(payload.sdt).to.not.be.undefined; - expect(payload.bids[0].w).to.equal('300'); - expect(payload.bids[0].h).to.equal('250'); - }); - - it('sends gdpr info if exists', function () { - const request = spec.buildRequests(validBidRequests, bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.gdpr).to.equal(true); - expect(payload.gdprc).to.equal(CONSENT_STRING); - }); - }); - - describe('interpretResponse', function () { - const response = { - body: { - Bids: - [{ - 'CreativeId': '1000', - 'Cpm': 0.50, - 'Ad': '
', - 'Height': 250, - 'Width': 300 - }] - } - }; - - it('should get correct bid response', function () { - const expectedResponse = [{ - requestId: response.body.Bids[0].BidId, - cpm: response.body.Bids[0].Cpm, - width: response.body.Bids[0].Width, - height: response.body.Bids[0].Height, - creativeId: response.body.Bids[0].CreativeId, - ad: response.body.Bids[0].Ad, - currency: 'USD', - netRevenue: true, - ttl: 360 - }]; - - let result = spec.interpretResponse(response, { 'bidderRequest': validBidRequests[0] }); - expect(result).to.deep.equal(expectedResponse); - }); - }); -}); diff --git a/test/spec/modules/bidglassAdapter_spec.js b/test/spec/modules/bidglassAdapter_spec.js deleted file mode 100644 index d153430103d..00000000000 --- a/test/spec/modules/bidglassAdapter_spec.js +++ /dev/null @@ -1,103 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/bidglassBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('Bid Glass Adapter', function () { - const adapter = newBidder(spec); - - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'bidglass', - 'params': { - 'adUnitId': '3' - }, - 'adUnitCode': 'bidglass-testunit', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const bidRequests = [{ - 'bidder': 'bidglass', - 'params': { - 'adUnitId': '3' - }, - 'adUnitCode': 'bidglass-testunit', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }]; - - const request = spec.buildRequests(bidRequests); - - it('sends bid request to our endpoint via POST', function () { - expect(request.method).to.equal('POST'); - }); - - it('sets withCredentials to false', function () { - expect(request.options.withCredentials).to.equal(false); - }); - }); - - describe('interpretResponse', function () { - let response; - beforeEach(function () { - response = { - body: { - 'bidResponses': [{ - 'ad': '', - 'cpm': '0.01', - 'creativeId': '-1', - 'width': '300', - 'height': '250', - 'requestId': '30b31c1838de1e' - }] - } - }; - }); - - it('should get the correct bid response', function () { - let expectedResponse = [{ - 'requestId': '30b31c1838de1e', - 'cpm': 0.01, - 'width': 300, - 'height': 250, - 'creativeId': '-1', - 'dealId': null, - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 10, - 'ad': '' - }]; - - let result = spec.interpretResponse(response); - expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); - }); - - it('handles empty bid response', function () { - let response = { - body: { - 'bidResponses': [] - } - }; - let result = spec.interpretResponse(response); - expect(result.length).to.equal(0); - }); - }); -}); diff --git a/test/spec/modules/bidlabBidAdapter_spec.js b/test/spec/modules/bidlabBidAdapter_spec.js deleted file mode 100644 index cffd43ae6ca..00000000000 --- a/test/spec/modules/bidlabBidAdapter_spec.js +++ /dev/null @@ -1,235 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/bidlabBidAdapter.js'; - -describe('BidlabBidAdapter', function () { - let bid = { - bidId: '23fhj33i987f', - bidder: 'bidlab', - params: { - placementId: 0, - traffic: 'banner' - } - }; - - describe('isBidRequestValid', function () { - it('Should return true if there are bidId, params and placementId parameters present', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false if at least one of parameters is not present', function () { - delete bid.params.placementId; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid]); - 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://service.bidlab.ai/?c=o&m=multi'); - }); - it('Returns valid data if array of bids is valid', function () { - let data = serverRequest.data; - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); - 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'); - let placement = data['placements'][0]; - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes'); - expect(placement.placementId).to.equal(0); - expect(placement.bidId).to.equal('23fhj33i987f'); - expect(placement.traffic).to.equal('banner'); - }); - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); - }); - 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' - }] - }; - let bannerResponses = spec.interpretResponse(banner); - expect(bannerResponses).to.be.an('array').that.is.not.empty; - let dataItem = bannerResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - expect(dataItem.requestId).to.equal('23fhj33i987f'); - expect(dataItem.cpm).to.equal(0.4); - expect(dataItem.width).to.equal(300); - expect(dataItem.height).to.equal(250); - expect(dataItem.ad).to.equal('Test'); - expect(dataItem.ttl).to.equal(120); - expect(dataItem.creativeId).to.equal('2'); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal('USD'); - }); - 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' - }] - }; - let videoResponses = spec.interpretResponse(video); - expect(videoResponses).to.be.an('array').that.is.not.empty; - - let dataItem = videoResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - 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'); - }); - 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', - }] - }; - let nativeResponses = spec.interpretResponse(native); - expect(nativeResponses).to.be.an('array').that.is.not.empty; - - let dataItem = nativeResponses[0]; - expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); - 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'); - }); - 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' - }] - }; - - let 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' - }] - }; - let 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', - }] - }; - let 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' - }] - }; - let serverResponses = spec.interpretResponse(invalid); - expect(serverResponses).to.be.an('array').that.is.empty; - }); - }); - describe('getUserSyncs', function () { - let userSync = spec.getUserSyncs(); - it('Returns valid URL and type', function () { - if (spec.noSync) { - expect(userSync).to.be.equal(false); - } else { - expect(userSync).to.be.an('array').with.lengthOf(1); - expect(userSync[0].type).to.exist; - expect(userSync[0].url).to.exist; - expect(userSync[0].type).to.be.equal('image'); - expect(userSync[0].url).to.be.equal('https://service.bidlab.ai/?c=o&m=sync'); - } - }); - }); -}); diff --git a/test/spec/modules/bidphysicsBidAdapter_spec.js b/test/spec/modules/bidphysicsBidAdapter_spec.js deleted file mode 100644 index fc15c39cf81..00000000000 --- a/test/spec/modules/bidphysicsBidAdapter_spec.js +++ /dev/null @@ -1,261 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/bidphysicsBidAdapter.js'; - -const REQUEST = { - 'bidderCode': 'bidphysics', - 'auctionId': 'auctionId-56a2-4f71-9098-720a68f2f708', - 'bidderRequestId': 'requestId', - 'bidRequest': [{ - 'bidder': 'bidphysics', - 'params': { - 'unitId': 123456, - }, - 'placementCode': 'div-gpt-dummy-placement-code', - 'sizes': [ - [300, 250] - ], - 'bidId': 'bidId1', - 'bidderRequestId': 'bidderRequestId', - 'auctionId': 'auctionId-56a2-4f71-9098-720a68f2f708' - }, - { - 'bidder': 'bidphysics', - 'params': { - 'unitId': 123456, - }, - 'placementCode': 'div-gpt-dummy-placement-code', - 'sizes': [ - [300, 250] - ], - 'bidId': 'bidId2', - 'bidderRequestId': 'bidderRequestId', - 'auctionId': 'auctionId-56a2-4f71-9098-720a68f2f708' - }], - 'start': 1487883186070, - 'auctionStart': 1487883186069, - 'timeout': 3000 -}; - -const RESPONSE = { - 'headers': null, - 'body': { - 'id': 'responseId', - 'seatbid': [ - { - 'bid': [ - { - 'id': 'bidId1', - 'impid': 'bidId1', - 'price': 0.18, - 'adm': '', - 'adid': '144762342', - 'adomain': [ - 'https://dummydomain.com' - ], - 'iurl': 'iurl', - 'cid': '109', - 'crid': 'creativeId', - 'cat': [], - 'w': 300, - 'h': 250, - 'ext': { - 'prebid': { - 'type': 'banner' - }, - 'bidder': { - 'appnexus': { - 'brand_id': 334553, - 'auction_id': 514667951122925701, - 'bidder_id': 2, - 'bid_ad_type': 0 - } - } - } - }, - { - 'id': 'bidId2', - 'impid': 'bidId2', - 'price': 0.1, - 'adm': '', - 'adid': '144762342', - 'adomain': [ - 'https://dummydomain.com' - ], - 'iurl': 'iurl', - 'cid': '109', - 'crid': 'creativeId', - 'cat': [], - 'w': 300, - 'h': 250, - 'ext': { - 'prebid': { - 'type': 'banner' - }, - 'bidder': { - 'appnexus': { - 'brand_id': 386046, - 'auction_id': 517067951122925501, - 'bidder_id': 2, - 'bid_ad_type': 0 - } - } - } - } - ], - 'seat': 'bidphysics' - } - ], - 'ext': { - 'usersync': { - 'sovrn': { - 'status': 'none', - 'syncs': [ - { - 'url': 'urlsovrn', - 'type': 'iframe' - } - ] - }, - 'appnexus': { - 'status': 'none', - 'syncs': [ - { - 'url': 'urlappnexus', - 'type': 'pixel' - } - ] - } - }, - 'responsetimemillis': { - 'appnexus': 127 - } - } - } -}; - -describe('BidPhysics bid adapter', function () { - describe('isBidRequestValid', function () { - it('should accept request if only unitId is passed', function () { - let bid = { - bidder: 'bidphysics', - params: { - unitId: 'unitId', - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - it('should accept request if only networkId is passed', function () { - let bid = { - bidder: 'bidphysics', - params: { - networkId: 'networkId', - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - it('should accept request if only publisherId is passed', function () { - let bid = { - bidder: 'bidphysics', - params: { - publisherId: 'publisherId', - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('reject requests without params', function () { - let bid = { - bidder: 'bidphysics', - params: {} - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - it('creates request data', function () { - let request = spec.buildRequests(REQUEST.bidRequest, REQUEST); - - expect(request).to.exist.and.to.be.a('object'); - const payload = JSON.parse(request.data); - expect(payload.imp[0]).to.have.property('id', REQUEST.bidRequest[0].bidId); - expect(payload.imp[1]).to.have.property('id', REQUEST.bidRequest[1].bidId); - }); - - it('has gdpr data if applicable', function () { - const req = Object.assign({}, REQUEST, { - gdprConsent: { - consentString: 'consentString', - gdprApplies: true, - } - }); - let request = spec.buildRequests(REQUEST.bidRequest, req); - - const payload = JSON.parse(request.data); - expect(payload.user.ext).to.have.property('consent', req.gdprConsent.consentString); - expect(payload.regs.ext).to.have.property('gdpr', 1); - }); - }); - - describe('interpretResponse', function () { - it('have bids', function () { - let bids = spec.interpretResponse(RESPONSE, REQUEST); - expect(bids).to.be.an('array').that.is.not.empty; - validateBidOnIndex(0); - validateBidOnIndex(1); - - function validateBidOnIndex(index) { - expect(bids[index]).to.have.property('currency', 'USD'); - expect(bids[index]).to.have.property('requestId', RESPONSE.body.seatbid[0].bid[index].impid); - expect(bids[index]).to.have.property('cpm', RESPONSE.body.seatbid[0].bid[index].price); - expect(bids[index]).to.have.property('width', RESPONSE.body.seatbid[0].bid[index].w); - expect(bids[index]).to.have.property('height', RESPONSE.body.seatbid[0].bid[index].h); - expect(bids[index]).to.have.property('ad', RESPONSE.body.seatbid[0].bid[index].adm); - expect(bids[index]).to.have.property('creativeId', RESPONSE.body.seatbid[0].bid[index].crid); - expect(bids[index]).to.have.property('ttl', 30); - expect(bids[index]).to.have.property('netRevenue', true); - } - }); - - it('handles empty response', function () { - const EMPTY_RESP = Object.assign({}, RESPONSE, {'body': {}}); - const bids = spec.interpretResponse(EMPTY_RESP, REQUEST); - - expect(bids).to.be.empty; - }); - }); - - describe('getUserSyncs', function () { - it('handles no parameters', function () { - let opts = spec.getUserSyncs({}); - 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}); - - 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}, [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('pixel sync enabled should return results', function () { - let 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('all sync enabled should return all results', function () { - let opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [RESPONSE]); - - expect(opts.length).to.equal(2); - }); - }); -}); diff --git a/test/spec/modules/bizzclickBidAdapter_spec.js b/test/spec/modules/bizzclickBidAdapter_spec.js deleted file mode 100644 index e0698c9eda8..00000000000 --- a/test/spec/modules/bizzclickBidAdapter_spec.js +++ /dev/null @@ -1,396 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/bizzclickBidAdapter.js'; -import {config} from 'src/config.js'; - -const NATIVE_BID_REQUEST = { - code: 'native_example', - mediaTypes: { - native: { - title: { - required: true, - len: 800 - }, - image: { - required: true, - len: 80 - }, - sponsoredBy: { - required: true - }, - clickUrl: { - required: true - }, - privacyLink: { - required: false - }, - body: { - required: true - }, - icon: { - required: true, - sizes: [50, 50] - } - } - }, - bidder: 'bizzclick', - params: { - placementId: 'hash', - accountId: 'accountId' - }, - timeout: 1000 - -}; - -const BANNER_BID_REQUEST = { - code: 'banner_example', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - bidder: 'bizzclick', - params: { - placementId: 'hash', - accountId: 'accountId' - }, - timeout: 1000, - gdprConsent: { - consentString: 'BOEFEAyOEFEAyAHABDENAI4AAAB9vABAASA', - gdprApplies: 1, - }, - uspConsent: 'uspConsent' -} - -const bidRequest = { - refererInfo: { - referer: 'test.com' - } -} - -const VIDEO_BID_REQUEST = { - code: 'video1', - sizes: [640, 480], - mediaTypes: { video: { - minduration: 0, - maxduration: 999, - boxingallowed: 1, - skip: 0, - mimes: [ - 'application/javascript', - 'video/mp4' - ], - w: 1920, - h: 1080, - protocols: [ - 2 - ], - linearity: 1, - api: [ - 1, - 2 - ] - } - }, - - bidder: 'bizzclick', - params: { - placementId: 'hash', - accountId: 'accountId' - }, - timeout: 1000 - -} - -const BANNER_BID_RESPONSE = { - id: 'request_id', - bidid: 'request_imp_id', - seatbid: [{ - bid: [{ - id: 'bid_id', - impid: 'request_imp_id', - price: 5, - adomain: ['example.com'], - adm: 'admcode', - crid: 'crid', - ext: { - mediaType: 'banner' - } - }], - }], -}; - -const VIDEO_BID_RESPONSE = { - id: 'request_id', - bidid: 'request_imp_id', - seatbid: [{ - bid: [{ - id: 'bid_id', - impid: 'request_imp_id', - price: 5, - adomain: ['example.com'], - adm: 'admcode', - crid: 'crid', - ext: { - mediaType: 'video', - vastUrl: 'http://example.vast', - } - }], - }], -}; - -let imgData = { - url: `https://example.com/image`, - w: 1200, - h: 627 -}; - -const NATIVE_BID_RESPONSE = { - id: 'request_id', - bidid: 'request_imp_id', - seatbid: [{ - bid: [{ - id: 'bid_id', - impid: 'request_imp_id', - price: 5, - adomain: ['example.com'], - adm: { native: - { - assets: [ - {id: 0, title: 'dummyText'}, - {id: 3, image: imgData}, - { - id: 5, - data: {value: 'organization.name'} - } - ], - link: {url: 'example.com'}, - imptrackers: ['tracker1.com', 'tracker2.com', 'tracker3.com'], - jstracker: 'tracker1.com' - } - }, - crid: 'crid', - ext: { - mediaType: 'native' - } - }], - }], -}; - -describe('BizzclickAdapter', function() { - describe('with COPPA', function() { - beforeEach(function() { - sinon.stub(config, 'getConfig') - .withArgs('coppa') - .returns(true); - }); - afterEach(function() { - config.getConfig.restore(); - }); - - it('should send the Coppa "required" flag set to "1" in the request', function () { - let serverRequest = spec.buildRequests([BANNER_BID_REQUEST]); - expect(serverRequest.data[0].regs.coppa).to.equal(1); - }); - }); - - describe('isBidRequestValid', function() { - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(NATIVE_BID_REQUEST)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, NATIVE_BID_REQUEST); - delete bid.params; - bid.params = { - 'IncorrectParam': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('build Native Request', function () { - const request = spec.buildRequests([NATIVE_BID_REQUEST], bidRequest); - - it('Creates a ServerRequest object with method, URL and data', function () { - expect(request).to.exist; - expect(request.method).to.exist; - expect(request.url).to.exist; - expect(request.data).to.exist; - }); - - it('sends bid request to our endpoint via POST', function () { - expect(request.method).to.equal('POST'); - }); - - it('Returns valid URL', function () { - expect(request.url).to.equal('https://us-e-node1.bizzclick.com/bid?rtb_seat_id=prebidjs&secret_key=accountId'); - }); - - it('Returns empty data if no valid requests are passed', function () { - let serverRequest = spec.buildRequests([]); - expect(serverRequest).to.be.an('array').that.is.empty; - }); - }); - - describe('build Banner Request', function () { - const request = spec.buildRequests([BANNER_BID_REQUEST]); - - it('Creates a ServerRequest object with method, URL and data', function () { - expect(request).to.exist; - expect(request.method).to.exist; - expect(request.url).to.exist; - expect(request.data).to.exist; - }); - - it('sends bid request to our endpoint via POST', function () { - expect(request.method).to.equal('POST'); - }); - - it('check consent and ccpa string is set properly', function() { - expect(request.data[0].regs.ext.gdpr).to.equal(1); - expect(request.data[0].user.ext.consent).to.equal(BANNER_BID_REQUEST.gdprConsent.consentString); - expect(request.data[0].regs.ext.us_privacy).to.equal(BANNER_BID_REQUEST.uspConsent); - }) - - it('Returns valid URL', function () { - expect(request.url).to.equal('https://us-e-node1.bizzclick.com/bid?rtb_seat_id=prebidjs&secret_key=accountId'); - }); - }); - - describe('build Video Request', function () { - const request = spec.buildRequests([VIDEO_BID_REQUEST]); - - it('Creates a ServerRequest object with method, URL and data', function () { - expect(request).to.exist; - expect(request.method).to.exist; - expect(request.url).to.exist; - expect(request.data).to.exist; - }); - - it('sends bid request to our endpoint via POST', function () { - expect(request.method).to.equal('POST'); - }); - - it('Returns valid URL', function () { - expect(request.url).to.equal('https://us-e-node1.bizzclick.com/bid?rtb_seat_id=prebidjs&secret_key=accountId'); - }); - }); - - describe('interpretResponse', function () { - it('Empty response must return empty array', function() { - const emptyResponse = null; - let response = spec.interpretResponse(emptyResponse); - - expect(response).to.be.an('array').that.is.empty; - }) - - it('Should interpret banner response', function () { - const bannerResponse = { - body: [BANNER_BID_RESPONSE] - } - - const expectedBidResponse = { - requestId: BANNER_BID_RESPONSE.id, - cpm: BANNER_BID_RESPONSE.seatbid[0].bid[0].price, - width: BANNER_BID_RESPONSE.seatbid[0].bid[0].w, - height: BANNER_BID_RESPONSE.seatbid[0].bid[0].h, - ttl: BANNER_BID_RESPONSE.ttl || 1200, - currency: BANNER_BID_RESPONSE.cur || 'USD', - netRevenue: true, - creativeId: BANNER_BID_RESPONSE.seatbid[0].bid[0].crid, - dealId: BANNER_BID_RESPONSE.seatbid[0].bid[0].dealid, - mediaType: 'banner', - ad: BANNER_BID_RESPONSE.seatbid[0].bid[0].adm - } - - let bannerResponses = spec.interpretResponse(bannerResponse); - - expect(bannerResponses).to.be.an('array').that.is.not.empty; - let dataItem = bannerResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - expect(dataItem.requestId).to.equal(expectedBidResponse.requestId); - expect(dataItem.cpm).to.equal(expectedBidResponse.cpm); - expect(dataItem.ad).to.equal(expectedBidResponse.ad); - expect(dataItem.ttl).to.equal(expectedBidResponse.ttl); - expect(dataItem.creativeId).to.equal(expectedBidResponse.creativeId); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal(expectedBidResponse.currency); - expect(dataItem.width).to.equal(expectedBidResponse.width); - expect(dataItem.height).to.equal(expectedBidResponse.height); - }); - - it('Should interpret video response', function () { - const videoResponse = { - body: [VIDEO_BID_RESPONSE] - } - - const expectedBidResponse = { - requestId: VIDEO_BID_RESPONSE.id, - cpm: VIDEO_BID_RESPONSE.seatbid[0].bid[0].price, - width: VIDEO_BID_RESPONSE.seatbid[0].bid[0].w, - height: VIDEO_BID_RESPONSE.seatbid[0].bid[0].h, - ttl: VIDEO_BID_RESPONSE.ttl || 1200, - currency: VIDEO_BID_RESPONSE.cur || 'USD', - netRevenue: true, - creativeId: VIDEO_BID_RESPONSE.seatbid[0].bid[0].crid, - dealId: VIDEO_BID_RESPONSE.seatbid[0].bid[0].dealid, - mediaType: 'video', - vastXml: VIDEO_BID_RESPONSE.seatbid[0].bid[0].adm, - vastUrl: VIDEO_BID_RESPONSE.seatbid[0].bid[0].ext.vastUrl - } - - let videoResponses = spec.interpretResponse(videoResponse); - - expect(videoResponses).to.be.an('array').that.is.not.empty; - let dataItem = videoResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'vastXml', 'vastUrl', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - expect(dataItem.requestId).to.equal(expectedBidResponse.requestId); - expect(dataItem.cpm).to.equal(expectedBidResponse.cpm); - expect(dataItem.vastXml).to.equal(expectedBidResponse.vastXml) - expect(dataItem.ttl).to.equal(expectedBidResponse.ttl); - expect(dataItem.creativeId).to.equal(expectedBidResponse.creativeId); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal(expectedBidResponse.currency); - expect(dataItem.width).to.equal(expectedBidResponse.width); - expect(dataItem.height).to.equal(expectedBidResponse.height); - }); - - it('Should interpret native response', function () { - const nativeResponse = { - body: [NATIVE_BID_RESPONSE] - } - - const expectedBidResponse = { - requestId: NATIVE_BID_RESPONSE.id, - cpm: NATIVE_BID_RESPONSE.seatbid[0].bid[0].price, - width: NATIVE_BID_RESPONSE.seatbid[0].bid[0].w, - height: NATIVE_BID_RESPONSE.seatbid[0].bid[0].h, - ttl: NATIVE_BID_RESPONSE.ttl || 1200, - currency: NATIVE_BID_RESPONSE.cur || 'USD', - netRevenue: true, - creativeId: NATIVE_BID_RESPONSE.seatbid[0].bid[0].crid, - dealId: NATIVE_BID_RESPONSE.seatbid[0].bid[0].dealid, - mediaType: 'native', - native: {clickUrl: NATIVE_BID_RESPONSE.seatbid[0].bid[0].adm.native.link.url} - } - - let nativeResponses = spec.interpretResponse(nativeResponse); - - expect(nativeResponses).to.be.an('array').that.is.not.empty; - let dataItem = nativeResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'native', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - expect(dataItem.requestId).to.equal(expectedBidResponse.requestId); - expect(dataItem.cpm).to.equal(expectedBidResponse.cpm); - expect(dataItem.native.clickUrl).to.equal(expectedBidResponse.native.clickUrl) - expect(dataItem.ttl).to.equal(expectedBidResponse.ttl); - expect(dataItem.creativeId).to.equal(expectedBidResponse.creativeId); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal(expectedBidResponse.currency); - expect(dataItem.width).to.equal(expectedBidResponse.width); - expect(dataItem.height).to.equal(expectedBidResponse.height); - }); - }); -}) diff --git a/test/spec/modules/bluebillywigBidAdapter_spec.js b/test/spec/modules/bluebillywigBidAdapter_spec.js deleted file mode 100644 index 3aee6c69438..00000000000 --- a/test/spec/modules/bluebillywigBidAdapter_spec.js +++ /dev/null @@ -1,1090 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/bluebillywigBidAdapter.js'; -import * as bidderFactory from 'src/adapters/bidderFactory.js'; -import { auctionManager } from 'src/auctionManager.js'; -import { deepClone, deepAccess } from 'src/utils.js'; -import { config } from 'src/config.js'; -import { VIDEO } from 'src/mediaTypes.js'; - -const BB_CONSTANTS = { - BIDDER_CODE: 'bluebillywig', - AUCTION_URL: '$$URL_STARTpbs.bluebillywig.com/openrtb2/auction?pub=$$PUBLICATION', - SYNC_URL: '$$URL_STARTpbs.bluebillywig.com/static/cookie-sync.html?pub=$$PUBLICATION', - RENDERER_URL: 'https://$$PUBLICATION.bbvms.com/r/$$RENDERER.js', - DEFAULT_TIMEOUT: 5000, - DEFAULT_TTL: 300, - DEFAULT_WIDTH: 768, - DEFAULT_HEIGHT: 432, - DEFAULT_NET_REVENUE: true -}; - -describe('BlueBillywigAdapter', () => { - describe('isBidRequestValid', () => { - const baseValidBid = { - bidder: BB_CONSTANTS.BIDDER_CODE, - params: { - accountId: 123, - publicationName: 'bbprebid.dev', - rendererCode: 'glorious_renderer', - connections: [ BB_CONSTANTS.BIDDER_CODE ], - bluebillywig: {} - }, - mediaTypes: { - video: { - context: 'outstream' - } - } - }; - - it('should return true when required params found', () => { - expect(spec.isBidRequestValid(baseValidBid)).to.equal(true); - }); - - it('should return false when params missing', () => { - const bid = deepClone(baseValidBid); - delete bid.params; - - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when publicationName is missing', () => { - const bid = deepClone(baseValidBid); - delete bid.params.publicationName; - - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when publicationName is not a string', () => { - const bid = deepClone(baseValidBid); - - bid.params.publicationName = 123; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.publicationName = false; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.publicationName = void (0); - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.publicationName = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when publicationName is formatted poorly', () => { - const bid = deepClone(baseValidBid); - - bid.params.publicationName = 'bb.'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.publicationName = 'bb-test'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.publicationName = '?'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when renderer is not specified', () => { - const bid = deepClone(baseValidBid); - - delete bid.params.rendererCode; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when renderer is not a string', () => { - const bid = deepClone(baseValidBid); - - bid.params.rendererCode = 123; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.rendererCode = false; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.rendererCode = void (0); - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.rendererCode = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when renderer is formatted poorly', () => { - const bid = deepClone(baseValidBid); - - bid.params.rendererCode = 'bb.'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.rendererCode = 'bb-test'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.rendererCode = '?'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when accountId is not specified', () => { - const bid = deepClone(baseValidBid); - - delete bid.params.accountId; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when connections is not specified', () => { - const bid = deepClone(baseValidBid); - - delete bid.params.connections; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when connections is not an array', () => { - const bid = deepClone(baseValidBid); - - bid.params.connections = 123; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.connections = false; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.connections = void (0); - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.connections = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.connections = 'string'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when a connection is missing', () => { - const bid = deepClone(baseValidBid); - - bid.params.connections.push('potatoes'); - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.connections.pop(); - - delete bid.params[BB_CONSTANTS.BIDDER_CODE]; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should fail if bid has no mediaTypes', () => { - const bid = deepClone(baseValidBid); - - delete bid.mediaTypes; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should fail if bid has no mediaTypes.video', () => { - const bid = deepClone(baseValidBid); - - delete bid.mediaTypes[VIDEO]; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should fail if bid has no mediaTypes.video.context', () => { - const bid = deepClone(baseValidBid); - - delete bid.mediaTypes[VIDEO].context; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should fail if mediaTypes.video.context is not "outstream"', () => { - const bid = deepClone(baseValidBid); - - bid.mediaTypes[VIDEO].context = 'instream'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should fail if video is specified but is not an object', () => { - const bid = deepClone(baseValidBid); - - bid.params.video = null; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.video = 'string'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.video = 123; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.video = false; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.video = void (0); - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should fail if rendererSettings is specified but is not an object', () => { - const bid = deepClone(baseValidBid); - - bid.params.rendererSettings = null; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.rendererSettings = 'string'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.rendererSettings = 123; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.rendererSettings = false; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.rendererSettings = void (0); - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', () => { - const publicationName = 'bbprebid.dev'; - const rendererCode = 'glorious_renderer'; - - const baseValidBid = { - bidder: BB_CONSTANTS.BIDDER_CODE, - params: { - accountId: 123, - publicationName: publicationName, - rendererCode: rendererCode, - connections: [ BB_CONSTANTS.BIDDER_CODE ], - bluebillywig: {} - }, - mediaTypes: { - video: { - context: 'outstream' - } - } - }; - - const baseValidBidRequests = [baseValidBid]; - - const validBidderRequest = { - auctionId: '12abc345-67d8-9012-e345-6f78901a2b34', - auctionStart: 1585918458868, - bidderCode: BB_CONSTANTS.BIDDER_CODE, - bidderRequestId: '1a2345b67c8d9e0', - bids: [{ - adUnitCode: 'ad-unit-test', - auctionId: '12abc345-67d8-9012-e345-6f78901a2b34', - bidId: '1234ab567c89de0', - bidRequestsCount: 1, - bidder: BB_CONSTANTS.BIDDER_CODE, - bidderRequestId: '1a2345b67c8d9e0', - params: baseValidBid.params, - sizes: [[768, 432], [640, 480], [630, 360]], - transactionId: '2b34c5de-f67a-8901-bcd2-34567efabc89' - }], - start: 11585918458869, - timeout: 3000 - }; - - it('sends bid request to AUCTION_URL via POST', () => { - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - expect(request.url).to.equal(`https://pbs.bluebillywig.com/openrtb2/auction?pub=${publicationName}`); - expect(request.method).to.equal('POST'); - }); - - it('sends data as a string', () => { - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - expect(request.data).to.be.a('string'); - }); - - it('sends all bid parameters', () => { - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']); - }); - - it('builds the base request properly', () => { - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.id).to.equal(validBidderRequest.auctionId); - expect(payload.source).to.be.an('object'); - expect(payload.source.tid).to.equal(validBidderRequest.auctionId); - expect(payload.tmax).to.equal(BB_CONSTANTS.DEFAULT_TIMEOUT); - expect(payload.imp).to.be.an('array'); - expect(payload.test).to.be.a('number'); - expect(payload).to.have.nested.property('ext.prebid.targeting'); - expect(payload.ext.prebid.targeting).to.be.an('object'); - expect(payload.ext.prebid.targeting.includewinners).to.equal(true); - expect(payload.ext.prebid.targeting.includebidderkeys).to.equal(false); - }); - - it('adds an impression to the payload', () => { - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.imp.length).to.equal(1); - }); - - it('adds connections to ext', () => { - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.imp[0].ext).to.have.all.keys(['bluebillywig']); - }); - - it('adds gdpr when present', () => { - const newValidBidderRequest = deepClone(validBidderRequest); - newValidBidderRequest.gdprConsent = { - consentString: 'BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA', - gdprApplies: true - }; - - const request = spec.buildRequests(baseValidBidRequests, newValidBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload).to.have.nested.property('regs.ext.gdpr'); - expect(payload.regs.ext.gdpr).to.be.a('number'); - expect(payload.regs.ext.gdpr).to.equal(1); - expect(payload).to.have.nested.property('user.ext.consent'); - expect(payload.user.ext.consent).to.equal(newValidBidderRequest.gdprConsent.consentString); - }); - - it('sets gdpr to 0 when explicitly gdprApplies: false', () => { - const newValidBidderRequest = deepClone(validBidderRequest); - newValidBidderRequest.gdprConsent = { - gdprApplies: false - }; - - const request = spec.buildRequests(baseValidBidRequests, newValidBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload).to.have.nested.property('regs.ext.gdpr'); - expect(payload.regs.ext.gdpr).to.be.a('number'); - expect(payload.regs.ext.gdpr).to.equal(0); - }); - - it('adds usp_consent when present', () => { - const newValidBidderRequest = deepClone(validBidderRequest); - newValidBidderRequest.uspConsent = '1YYY'; - - const request = spec.buildRequests(baseValidBidRequests, newValidBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload).to.have.nested.property('regs.ext.us_privacy'); - expect(payload.regs.ext.us_privacy).to.equal(newValidBidderRequest.uspConsent); - }); - - it('sets coppa to 1 when specified in config', () => { - config.setConfig({'coppa': true}); - - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload).to.have.nested.property('regs.coppa'); - expect(payload.regs.coppa).to.equal(1); - - config.resetConfig(); - }); - - it('does not set coppa when disabled in the config', () => { - config.setConfig({'coppa': false}); - - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(deepAccess(payload, 'regs.coppa')).to.be.undefined; - - config.resetConfig(); - }); - - it('does not set coppa when not specified in config', () => { - config.resetConfig(); - - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(deepAccess(payload, 'regs.coppa')).to.be.undefined; - }); - - it('should add window size to request by default', () => { - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload).to.have.nested.property('device.w'); - expect(payload).to.have.nested.property('device.h'); - expect(payload.device.w).to.be.a('number'); - expect(payload.device.h).to.be.a('number'); - }); - - it('should add site when specified in config', () => { - config.setConfig({ site: { name: 'Blue Billywig', domain: 'bluebillywig.com', page: 'https://bluebillywig.com/', publisher: { id: 'abc', name: 'Blue Billywig', domain: 'bluebillywig.com' } } }); - - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload).to.have.property('site'); - expect(payload).to.have.nested.property('site.name'); - expect(payload).to.have.nested.property('site.domain'); - expect(payload).to.have.nested.property('site.page'); - expect(payload).to.have.nested.property('site.publisher'); - expect(payload).to.have.nested.property('site.publisher.id'); - expect(payload).to.have.nested.property('site.publisher.name'); - expect(payload).to.have.nested.property('site.publisher.domain'); - - config.resetConfig(); - }); - - it('should add app when specified in config', () => { - config.setConfig({ app: { bundle: 'org.prebid.mobile.demoapp', domain: 'prebid.org' } }); - - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload).to.have.property('app'); - expect(payload).to.have.nested.property('app.bundle'); - expect(payload).to.have.nested.property('app.domain'); - expect(payload.app.bundle).to.equal('org.prebid.mobile.demoapp'); - expect(payload.app.domain).to.equal('prebid.org'); - - config.resetConfig(); - }); - - it('should add referrerInfo as site when no app is set', () => { - const newValidBidderRequest = deepClone(validBidderRequest); - - newValidBidderRequest.refererInfo = { referer: 'https://www.bluebillywig.com' }; - - const request = spec.buildRequests(baseValidBidRequests, newValidBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload).to.have.nested.property('site.page'); - expect(payload.site.page).to.equal('https://www.bluebillywig.com'); - }); - - it('should not add referrerInfo as site when app is set', () => { - config.setConfig({ app: { bundle: 'org.prebid.mobile.demoapp', domain: 'prebid.org' } }); - - const newValidBidderRequest = deepClone(validBidderRequest); - newValidBidderRequest.refererInfo = { referer: 'https://www.bluebillywig.com' }; - - const request = spec.buildRequests(baseValidBidRequests, newValidBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.site).to.be.undefined; - config.resetConfig(); - }); - - it('should add device size to request when specified in config', () => { - config.setConfig({ device: { w: 1, h: 1 } }); - - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload).to.have.nested.property('device.w'); - expect(payload).to.have.nested.property('device.h'); - expect(payload.device.w).to.be.a('number'); - expect(payload.device.h).to.be.a('number'); - expect(payload.device.w).to.equal(1); - expect(payload.device.h).to.equal(1); - - config.resetConfig(); - }); - - it('should set schain on the request when set on config', () => { - const schain = { - validation: 'lax', - config: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - hp: 1 - } - ] - } - }; - - const newBaseValidBidRequests = deepClone(baseValidBidRequests); - newBaseValidBidRequests[0].schain = schain; - - const request = spec.buildRequests(newBaseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload).to.have.nested.property('source.ext.schain'); - expect(payload.source.ext.schain).to.deep.equal(schain); - }); - - it('should add currency when specified on the config', () => { - config.setConfig({ currency: { adServerCurrency: 'USD' } }); - - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload).to.have.property('cur'); - expect(payload.cur).to.eql(['USD']); // NB not equal, eql to check for same array because [1] === [1] fails normally - - config.resetConfig(); - }); - - it('should also take in array for currency on the config', () => { - config.setConfig({ currency: { adServerCurrency: ['USD', 'PHP'] } }); - - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload).to.have.property('cur'); - expect(payload.cur).to.eql(['USD']); // NB not equal, eql to check for same array because [1] === [1] fails normally - - config.resetConfig(); - }); - - it('should not set cur when currency is not specified on the config', () => { - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.cur).to.be.undefined; - }); - - it('should set user ids when present', () => { - const userId = { tdid: 123 }; - - const newBaseValidBidRequests = deepClone(baseValidBidRequests); - newBaseValidBidRequests[0].userId = { criteoId: 'sample-userid' }; - - const request = spec.buildRequests(newBaseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(payload).to.have.nested.property('user.ext.eids'); - expect(payload.user.ext.eids).to.be.an('array'); - expect(payload.user.ext.eids.length).to.equal(1); - }); - - it('should not set user ids when none present', () => { - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(deepAccess(payload, 'user.ext.eids')).to.be.undefined; - }); - - it('should set imp.0.video.[w|h|placement] by default', () => { - const newBaseValidBidRequests = deepClone(baseValidBidRequests); - - const request = spec.buildRequests(newBaseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(deepAccess(payload, 'imp.0.video.w')).to.equal(768); - expect(deepAccess(payload, 'imp.0.video.h')).to.equal(432); - expect(deepAccess(payload, 'imp.0.video.placement')).to.equal(3); - }); - - it('should update imp0.video.[w|h] when present in config', () => { - const newBaseValidBidRequests = deepClone(baseValidBidRequests); - newBaseValidBidRequests[0].mediaTypes.video.playerSize = [1, 1]; - - const request = spec.buildRequests(newBaseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(deepAccess(payload, 'imp.0.video.w')).to.equal(1); - expect(deepAccess(payload, 'imp.0.video.h')).to.equal(1); - }); - - it('should allow overriding any imp0.video key through params.video', () => { - const newBaseValidBidRequests = deepClone(baseValidBidRequests); - newBaseValidBidRequests[0].params.video = { - w: 2, - h: 2, - placement: 1, - minduration: 15, - maxduration: 30 - }; - - const request = spec.buildRequests(newBaseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(deepAccess(payload, 'imp.0.video.w')).to.equal(2); - expect(deepAccess(payload, 'imp.0.video.h')).to.equal(2); - expect(deepAccess(payload, 'imp.0.video.placement')).to.equal(1); - expect(deepAccess(payload, 'imp.0.video.minduration')).to.equal(15); - expect(deepAccess(payload, 'imp.0.video.maxduration')).to.equal(30); - }); - - it('should not allow placing any non-OpenRTB 2.5 keys on imp.0.video through params.video', () => { - const newBaseValidBidRequests = deepClone(baseValidBidRequests); - newBaseValidBidRequests[0].params.video = { - 'true': true, - 'testing': 'some', - 123: {}, - '': 'values' - }; - - const request = spec.buildRequests(newBaseValidBidRequests, validBidderRequest); - const payload = JSON.parse(request.data); - - expect(deepAccess(request, 'imp.0.video.true')).to.be.undefined; - expect(deepAccess(payload, 'imp.0.video.testing')).to.be.undefined; - expect(deepAccess(payload, 'imp.0.video.123')).to.be.undefined; - expect(deepAccess(payload, 'imp.0.video.')).to.be.undefined; - }); - }); - describe('interpretResponse', () => { - const publicationName = 'bbprebid.dev'; - const rendererCode = 'glorious_renderer'; - - const baseValidBid = { - bidder: BB_CONSTANTS.BIDDER_CODE, - params: { - accountId: 123, - publicationName: publicationName, - rendererCode: rendererCode, - connections: [ BB_CONSTANTS.BIDDER_CODE ], - bluebillywig: {} - }, - mediaTypes: { - video: { - context: 'outstream' - } - } - }; - - const baseValidBidRequests = [baseValidBid]; - - const validBidderRequest = { - auctionId: '12abc345-67d8-9012-e345-6f78901a2b34', - auctionStart: 1585918458868, - bidderCode: BB_CONSTANTS.BIDDER_CODE, - bidderRequestId: '1a2345b67c8d9e0', - bids: [{ - adUnitCode: 'ad-unit-test', - auctionId: '12abc345-67d8-9012-e345-6f78901a2b34', - bidId: '1234ab567c89de0', - bidRequestsCount: 1, - bidder: BB_CONSTANTS.BIDDER_CODE, - bidderRequestId: '1a2345b67c8d9e0', - params: baseValidBid.params, - sizes: [[640, 480], [630, 360]], - transactionId: '2b34c5de-f67a-8901-bcd2-34567efabc89' - }], - start: 11585918458869, - timeout: 3000 - }; - - const validResponse = { - id: 'a12abc345-67d8-9012-e345-6f78901a2b34', - seatbid: [ - { - bid: [ - { - id: '1', - impid: '1234ab567c89de0', - price: 1, - adm: '\r\nBB Adserver00:00:51', - adid: '67069817', - adomain: [ - 'bluebillywig.com' - ], - cid: '3535', - crid: '67069817', - w: 1, - h: 1, - publicationName: 'bbprebid', - accountId: 123, - ext: { - prebid: { - targeting: { - hb_bidder: 'bluebillywig', - hb_pb: '1.00', - hb_size: '1x1' - }, - type: 'video' - }, - bidder: { - prebid: { - targeting: { - hb_bidder: 'bluebillywig', - hb_pb: '10.00', - hb_size: '1x1' - }, - type: 'video', - video: { - duration: 51, - primary_category: '' - } - }, - bidder: { - bluebillywig: { - brand_id: 1, - auction_id: 1, - bid_ad_type: 1, - creative_info: { - video: { - duration: 51, - mimes: [ - 'video/x-flv', - 'video/mp4', - 'video/webm' - ] - } - } - } - } - } - } - } - ], - seat: 'bluebillywig' - } - ], - cur: 'USD', - ext: { - responsetimemillis: { - bluebillywig: 0 - }, - tmaxrequest: 5000 - } - }; - - const serverResponse = { body: validResponse }; - - it('should build bid array', () => { - const response = deepClone(serverResponse); - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const result = spec.interpretResponse(response, request); - - expect(result.length).to.equal(1); - }); - - it('should have all relevant fields', () => { - const response = deepClone(serverResponse); - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const result = spec.interpretResponse(response, request); - const bid = result[0]; - - // BB_HELPERS.transformRTBToPrebidProps - expect(bid.cpm).to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(bid.bidId).to.equal(serverResponse.body.seatbid[0].bid[0].impid); - expect(bid.requestId).to.equal(serverResponse.body.seatbid[0].bid[0].impid); - expect(bid.width).to.equal(serverResponse.body.seatbid[0].bid[0].w || BB_CONSTANTS.DEFAULT_WIDTH); - expect(bid.height).to.equal(serverResponse.body.seatbid[0].bid[0].h || BB_CONSTANTS.DEFAULT_HEIGHT); - expect(bid.ad).to.equal(serverResponse.body.seatbid[0].bid[0].adm); - expect(bid.netRevenue).to.equal(BB_CONSTANTS.DEFAULT_NET_REVENUE); - expect(bid.creativeId).to.equal(serverResponse.body.seatbid[0].bid[0].crid); - expect(bid.currency).to.equal(serverResponse.body.cur); - expect(bid.ttl).to.equal(BB_CONSTANTS.DEFAULT_TTL); - - expect(bid.publicationName).to.equal(validBidderRequest.bids[0].params.publicationName); - expect(bid.rendererCode).to.equal(validBidderRequest.bids[0].params.rendererCode); - expect(bid.accountId).to.equal(validBidderRequest.bids[0].params.accountId); - }); - - it('should not give anything when seatbid is an empty array', () => { - const seatbidEmptyArray = deepClone(serverResponse); - seatbidEmptyArray.body.seatbid = []; - - const response = seatbidEmptyArray; - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const result = spec.interpretResponse(response, request); - - expect(result.length).to.equal(0); - }); - - it('should not give anything when seatbid is missing', () => { - const seatbidMissing = deepClone(serverResponse); - delete seatbidMissing.body.seatbid; - - const response = seatbidMissing; - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const result = spec.interpretResponse(response, request); - - expect(result.length).to.equal(0); - }); - - const seatbidNotArrayResponse = deepClone(serverResponse); - it('should not give anything when seatbid is not an array', () => { - const invalidValues = [ false, null, {}, void (0), 123, 'string' ]; - - for (const invalidValue of invalidValues) { - seatbidNotArrayResponse.body.seatbid = invalidValue - const response = deepClone(seatbidNotArrayResponse); // interpretResponse is destructive - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const result = spec.interpretResponse(response, request); - - expect(result.length).to.equal(0); - } - }); - - it('should not give anything when seatbid.bid is an empty array', () => { - const seatbidBidEmpty = deepClone(serverResponse); - seatbidBidEmpty.body.seatbid[0].bid = []; - - const response = seatbidBidEmpty; - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const result = spec.interpretResponse(response, request); - - expect(result.length).to.equal(0); - }); - - it('should not give anything when seatbid.bid is missing', () => { - const seatbidBidMissing = deepClone(serverResponse); - delete seatbidBidMissing.body.seatbid[0].bid; - - const response = seatbidBidMissing; - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const result = spec.interpretResponse(response, request); - - expect(result.length).to.equal(0); - }); - - it('should not give anything when seatbid.bid is not an array', () => { - const seatbidBidNotArray = deepClone(serverResponse); - - const invalidValues = [ false, null, {}, void (0), 123, 'string' ]; - - for (const invalidValue of invalidValues) { - seatbidBidNotArray.body.seatbid[0].bid = invalidValue; - - const response = deepClone(seatbidBidNotArray); // interpretResponse is destructive - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const result = spec.interpretResponse(response, request); - - expect(result.length).to.equal(0); - } - }); - - it('should take default width and height when w/h not present', () => { - const bidSizesMissing = deepClone(serverResponse); - - delete bidSizesMissing.body.seatbid[0].bid[0].w; - delete bidSizesMissing.body.seatbid[0].bid[0].h; - - const response = bidSizesMissing; - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const result = spec.interpretResponse(response, request); - - expect(deepAccess(result, '0.width')).to.equal(768); - expect(deepAccess(result, '0.height')).to.equal(432); - }); - - it('should take nurl value when adm not present', () => { - const bidAdmMissing = deepClone(serverResponse); - - delete bidAdmMissing.body.seatbid[0].bid[0].adm; - bidAdmMissing.body.seatbid[0].bid[0].nurl = 'https://bluebillywig.com'; - - const response = bidAdmMissing; - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const result = spec.interpretResponse(response, request); - - expect(deepAccess(result, '0.vastXml')).to.be.undefined; - expect(deepAccess(result, '0.vastUrl')).to.equal('https://bluebillywig.com'); - }); - - it('should not take nurl value when adm present', () => { - const bidAdmNurlPresent = deepClone(serverResponse); - - bidAdmNurlPresent.body.seatbid[0].bid[0].nurl = 'https://bluebillywig.com'; - - const response = bidAdmNurlPresent; - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const result = spec.interpretResponse(response, request); - - expect(deepAccess(result, '0.vastXml')).to.equal(bidAdmNurlPresent.body.seatbid[0].bid[0].adm); - expect(deepAccess(result, '0.vastUrl')).to.be.undefined; - }); - - it('should take ext.prebid.cache data when present, ignore ext.prebid.targeting and nurl', () => { - const bidExtPrebidCache = deepClone(serverResponse); - - delete bidExtPrebidCache.body.seatbid[0].bid[0].adm; - bidExtPrebidCache.body.seatbid[0].bid[0].nurl = 'https://notnurl.com'; - - bidExtPrebidCache.body.seatbid[0].bid[0].ext = { - prebid: { - cache: { - vastXml: { - url: 'https://bluebillywig.com', - cacheId: '12345' - } - }, - targeting: { - hb_uuid: '23456', - hb_cache_host: 'bluebillywig.com', - hb_cache_path: '/cache' - } - } - }; - - const response = bidExtPrebidCache; - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const result = spec.interpretResponse(response, request); - - expect(deepAccess(result, '0.vastUrl')).to.equal('https://bluebillywig.com'); - expect(deepAccess(result, '0.videoCacheKey')).to.equal('12345'); - }); - - it('should take ext.prebid.targeting data when ext.prebid.cache not present, and ignore nurl', () => { - const bidExtPrebidTargeting = deepClone(serverResponse); - - delete bidExtPrebidTargeting.body.seatbid[0].bid[0].adm; - bidExtPrebidTargeting.body.seatbid[0].bid[0].nurl = 'https://notnurl.com'; - - bidExtPrebidTargeting.body.seatbid[0].bid[0].ext = { - prebid: { - targeting: { - hb_uuid: '34567', - hb_cache_host: 'bluebillywig.com', - hb_cache_path: '/cache' - } - } - }; - - const response = bidExtPrebidTargeting; - const request = spec.buildRequests(baseValidBidRequests, validBidderRequest); - const result = spec.interpretResponse(response, request); - - expect(deepAccess(result, '0.vastUrl')).to.equal('https://bluebillywig.com/cache?uuid=34567'); - expect(deepAccess(result, '0.videoCacheKey')).to.equal('34567'); - }); - }); - describe('getUserSyncs', () => { - const publicationName = 'bbprebid.dev'; - const rendererCode = 'glorious_renderer'; - - const baseValidBid = { - bidder: BB_CONSTANTS.BIDDER_CODE, - params: { - accountId: 123, - publicationName: publicationName, - rendererCode: rendererCode, - connections: [ BB_CONSTANTS.BIDDER_CODE ], - bluebillywig: {} - }, - mediaTypes: { - video: { - context: 'outstream' - } - } - }; - - const validBidRequests = [baseValidBid]; - - const validBidderRequest = { - auctionId: '12abc345-67d8-9012-e345-6f78901a2b34', - auctionStart: 1585918458868, - bidderCode: BB_CONSTANTS.BIDDER_CODE, - bidderRequestId: '1a2345b67c8d9e0', - bids: [{ - adUnitCode: 'ad-unit-test', - auctionId: '12abc345-67d8-9012-e345-6f78901a2b34', - bidId: '1234ab567c89de0', - bidRequestsCount: 1, - bidder: BB_CONSTANTS.BIDDER_CODE, - bidderRequestId: '1a2345b67c8d9e0', - params: baseValidBid.params, - sizes: [[768, 432], [640, 480], [630, 360]], - transactionId: '2b34c5de-f67a-8901-bcd2-34567efabc89' - }], - start: 11585918458869, - timeout: 3000 - }; - const validResponse = { - id: 'a12abc345-67d8-9012-e345-6f78901a2b34', - seatbid: [ - { - bid: [ - { - id: '1', - impid: '1234ab567c89de0', - price: 1, - adm: '\r\nBB Adserver00:00:51', - adid: '67069817', - adomain: [ - 'bluebillywig.com' - ], - cid: '3535', - crid: '67069817', - w: 1, - h: 1, - publicationName: 'bbprebid', - accountId: 123, - ext: { - prebid: { - targeting: { - hb_bidder: 'bluebillywig', - hb_pb: '1.00', - hb_size: '1x1' - }, - type: 'video' - }, - bidder: { - prebid: { - targeting: { - hb_bidder: 'bluebillywig', - hb_pb: '10.00', - hb_size: '1x1' - }, - type: 'video', - video: { - duration: 51, - primary_category: '' - } - }, - bidder: { - bluebillywig: { - brand_id: 1, - auction_id: 1, - bid_ad_type: 1, - creative_info: { - video: { - duration: 51, - mimes: [ - 'video/x-flv', - 'video/mp4', - 'video/webm' - ] - } - } - } - } - } - } - } - ], - seat: 'bluebillywig' - } - ], - cur: 'USD', - ext: { - responsetimemillis: { - bluebillywig: 0 - }, - tmaxrequest: 5000 - } - }; - - const serverResponse = { body: validResponse }; - - const gdpr = { - consentString: 'BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAA AAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA', - gdprApplies: true - }; - - it('should return empty if no server response', function () { - const result = spec.getUserSyncs({}, false, gdpr); - expect(result).to.be.empty; - }); - - it('should return empty if server response is empty', function () { - const result = spec.getUserSyncs({}, [], gdpr); - expect(result).to.be.empty; - }); - - it('should return empty if iframeEnabled is not true', () => { - const result = spec.getUserSyncs({iframeEnabled: false}, [serverResponse], gdpr); - expect(result).to.be.empty; - }); - - it('should append the various values if they exist', function() { - // push data to syncStore - spec.buildRequests(validBidRequests, validBidderRequest); - - const result = spec.getUserSyncs({iframeEnabled: true}, [serverResponse], gdpr); - - expect(result).to.not.be.empty; - - expect(result[0].url).to.include('gdpr=1'); - expect(result[0].url).to.include(gdpr.consentString); - expect(result[0].url).to.include('accountId=123'); - expect(result[0].url).to.include(`bidders=${btoa(JSON.stringify(validBidRequests[0].params.connections))}`); - expect(result[0].url).to.include('cb='); - }); - }); -}); diff --git a/test/spec/modules/boldwinBidAdapter_spec.js b/test/spec/modules/boldwinBidAdapter_spec.js deleted file mode 100644 index a353665ec33..00000000000 --- a/test/spec/modules/boldwinBidAdapter_spec.js +++ /dev/null @@ -1,281 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/boldwinBidAdapter.js'; -import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; - -describe('BoldwinBidAdapter', function () { - const bid = { - bidId: '23fhj33i987f', - bidder: 'boldwin', - params: { - placementId: 0, - traffic: BANNER - } - }; - - const bidderRequest = { - refererInfo: { - referer: 'test.com' - } - }; - - describe('isBidRequestValid', function () { - it('Should return true if there are bidId, params and placementId parameters present', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false if at least one of parameters is not present', function () { - delete bid.params.placementId; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid], 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://ssp.videowalldirect.com/?c=o&m=multi'); - }); - it('Returns valid data if array of bids is valid', function () { - let data = serverRequest.data; - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); - 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.gdpr).to.not.exist; - expect(data.ccpa).to.not.exist; - let placement = data['placements'][0]; - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes', 'hPlayer', 'wPlayer', 'schain'); - expect(placement.placementId).to.equal(0); - expect(placement.bidId).to.equal('23fhj33i987f'); - expect(placement.traffic).to.equal(BANNER); - expect(placement.schain).to.be.an('object'); - }); - - it('Returns valid data for mediatype video', function () { - const playerSize = [300, 300]; - bid.mediaTypes = {}; - bid.params.traffic = VIDEO; - bid.mediaTypes[VIDEO] = { - playerSize - }; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data).to.be.an('object'); - let placement = data['placements'][0]; - expect(placement).to.be.an('object'); - expect(placement.traffic).to.equal(VIDEO); - expect(placement.wPlayer).to.equal(playerSize[0]); - expect(placement.hPlayer).to.equal(playerSize[1]); - }); - - it('Returns data with gdprConsent and without uspConsent', function () { - bidderRequest.gdprConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data.gdpr).to.exist; - expect(data.gdpr).to.be.a('string'); - expect(data.gdpr).to.equal(bidderRequest.gdprConsent); - expect(data.ccpa).to.not.exist; - delete bidderRequest.gdprConsent; - }); - - it('Returns data with uspConsent and without gdprConsent', function () { - bidderRequest.uspConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); - let 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; - }); - - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); - }); - 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' - }] - }; - let bannerResponses = spec.interpretResponse(banner); - expect(bannerResponses).to.be.an('array').that.is.not.empty; - let dataItem = bannerResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - expect(dataItem.requestId).to.equal('23fhj33i987f'); - expect(dataItem.cpm).to.equal(0.4); - expect(dataItem.width).to.equal(300); - expect(dataItem.height).to.equal(250); - expect(dataItem.ad).to.equal('Test'); - expect(dataItem.ttl).to.equal(120); - expect(dataItem.creativeId).to.equal('2'); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal('USD'); - }); - 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' - }] - }; - let videoResponses = spec.interpretResponse(video); - expect(videoResponses).to.be.an('array').that.is.not.empty; - - let dataItem = videoResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - 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'); - }); - 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', - }] - }; - let nativeResponses = spec.interpretResponse(native); - expect(nativeResponses).to.be.an('array').that.is.not.empty; - - let dataItem = nativeResponses[0]; - expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); - 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'); - }); - 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' - }] - }; - - let 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' - }] - }; - let 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', - }] - }; - let 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' - }] - }; - let serverResponses = spec.interpretResponse(invalid); - expect(serverResponses).to.be.an('array').that.is.empty; - }); - }); - - describe('getUserSyncs', function () { - let userSync = spec.getUserSyncs(); - it('Returns valid URL and type', function () { - expect(userSync).to.be.an('array').with.lengthOf(1); - expect(userSync[0].type).to.exist; - expect(userSync[0].url).to.exist; - expect(userSync[0].type).to.be.equal('image'); - expect(userSync[0].url).to.be.equal('https://cs.videowalldirect.com/?c=o&m=cookie'); - }); - }); -}); diff --git a/test/spec/modules/bridgewellBidAdapter_spec.js b/test/spec/modules/bridgewellBidAdapter_spec.js deleted file mode 100644 index 0860404355e..00000000000 --- a/test/spec/modules/bridgewellBidAdapter_spec.js +++ /dev/null @@ -1,1302 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/bridgewellBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('bridgewellBidAdapter', 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 () { - it('should return true when required params found', function () { - const validTag = { - 'bidder': 'bridgewell', - 'params': { - 'ChannelID': 'CLJgEAYYvxUiBXBlbm55KgkIrAIQ-gEaATk' - }, - }; - expect(spec.isBidRequestValid(validTag)).to.equal(true); - }); - - it('should return true when required params found', function () { - const validTag = { - 'bidder': 'bridgewell', - 'params': { - 'cid': 1234 - }, - }; - expect(spec.isBidRequestValid(validTag)).to.equal(true); - }); - - it('should return false when required params not found', function () { - const invalidTag = { - 'bidder': 'bridgewell', - 'params': {}, - }; - expect(spec.isBidRequestValid(invalidTag)).to.equal(false); - }); - - it('should return false when required params are empty', function () { - const invalidTag = { - 'bidder': 'bridgewell', - 'params': { - 'ChannelID': '', - }, - }; - expect(spec.isBidRequestValid(invalidTag)).to.equal(false); - }); - - it('should return false when required params are empty', function () { - const invalidTag = { - 'bidder': 'bridgewell', - 'params': { - 'cid': '', - }, - }; - expect(spec.isBidRequestValid(invalidTag)).to.equal(false); - }); - - it('should return false when required param cid is not a number', function () { - const invalidTag = { - 'bidder': 'bridgewell', - 'params': { - 'cid': 'bad_cid', - }, - }; - expect(spec.isBidRequestValid(invalidTag)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const bidRequests = [ - { - 'bidder': 'bridgewell', - 'params': { - 'ChannelID': 'CgUxMjMzOBIBNiIGcGVubnkzKggI2AUQWhoBOQ', - }, - 'adUnitCode': 'adunit-code-2', - 'mediaTypes': { - 'banner': { - 'sizes': [728, 90] - } - }, - 'bidId': '3150ccb55da321', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }, - { - 'bidder': 'bridgewell', - 'params': { - 'ChannelID': 'CgUxMjMzOBIBNiIGcGVubnkzKggI2AUQWhoBOQ', - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [1, 1], - 'mediaTypes': { - 'native': { - 'title': { - 'required': true, - 'len': 15 - }, - 'body': { - 'required': true - }, - 'image': { - 'required': true, - 'sizes': [150, 150] - }, - 'icon': { - 'required': true, - 'sizes': [50, 50] - }, - 'clickUrl': { - 'required': true - }, - 'cta': { - 'required': true - }, - 'sponsoredBy': { - 'required': true - } - } - }, - 'bidId': '3150ccb55da321', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - it('should attach valid params to the tag', function () { - const bidderRequest = { - refererInfo: { - referer: 'https://www.bridgewell.com/' - } - } - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = request.data; - - expect(payload).to.be.an('object'); - expect(payload.adUnits).to.be.an('array'); - expect(payload.url).to.exist.and.to.equal('https://www.bridgewell.com/'); - for (let i = 0, max_i = payload.adUnits.length; i < max_i; i++) { - expect(payload.adUnits[i]).to.have.property('ChannelID').that.is.a('string'); - expect(payload.adUnits[i]).to.not.have.property('cid'); - expect(payload.adUnits[i]).to.have.property('adUnitCode').and.to.equal('adunit-code-2'); - expect(payload.adUnits[i]).to.have.property('requestId').and.to.equal('3150ccb55da321'); - } - }); - - it('should attach valid params to the tag, part2', function() { - const bidderRequest = { - refererInfo: { - referer: 'https://www.bridgewell.com/' - } - } - const bidRequests2 = [ - { - 'bidder': 'bridgewell', - 'params': { - 'cid': 1234, - }, - 'adUnitCode': 'adunit-code-2', - 'mediaTypes': { - 'banner': { - 'sizes': [728, 90] - } - }, - 'bidId': '3150ccb55da321', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }, - ]; - - const request = spec.buildRequests(bidRequests2, bidderRequest); - const payload = request.data; - - expect(payload).to.be.an('object'); - expect(payload.adUnits).to.be.an('array'); - expect(payload.url).to.exist.and.to.equal('https://www.bridgewell.com/'); - for (let i = 0, max_i = payload.adUnits.length; i < max_i; i++) { - expect(payload.adUnits[i]).to.have.property('cid').that.is.a('number'); - expect(payload.adUnits[i]).to.not.have.property('ChannelID'); - expect(payload.adUnits[i]).to.have.property('adUnitCode').and.to.equal('adunit-code-2'); - expect(payload.adUnits[i]).to.have.property('requestId').and.to.equal('3150ccb55da321'); - } - }); - - it('should attach validBidRequests to the tag', function () { - const bidderRequest = { - refererInfo: { - referer: 'https://www.bridgewell.com/' - } - } - - const request = spec.buildRequests(bidRequests, bidderRequest); - const validBidRequests = request.validBidRequests; - expect(validBidRequests).to.deep.equal(bidRequests); - }); - }); - - describe('interpretResponse', function () { - const nativeBidRequests = { - validBidRequests: [ - { - 'bidder': 'bridgewell', - 'params': { - 'ChannelID': 'CgUxMjMzOBIBNiIGcGVubnkzKggI2AUQWhoBOQ', - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [1, 1], - 'mediaTypes': { - 'native': { - 'title': { - 'required': true, - 'len': 15 - }, - 'body': { - 'required': true - }, - 'image': { - 'required': true, - 'sizes': [150, 150] - }, - 'icon': { - 'required': true, - 'sizes': [50, 50] - }, - 'clickUrl': { - 'required': true - }, - 'cta': { - 'required': true - }, - 'sponsoredBy': { - 'required': true - } - } - }, - 'bidId': '3150ccb55da321', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }, - ] - }; - - const nativeServerResponses = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'adomain': ['response.com'], - 'mediaType': 'native', - 'native': { - 'image': { - 'url': 'https://img.scupio.com/test/test-image.jpg', - 'width': 150, - 'height': 150 - }, - 'title': 'test-title', - 'sponsoredBy': 'test-sponsoredBy', - 'body': 'test-body', - 'icon': { - 'url': 'https://img.scupio.com/test/test-icon.jpg', - 'width': 50, - 'height': 50 - }, - 'clickUrl': 'https://img.scupio.com/test-clickUrl', - 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], - 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] - }, - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const bannerBidRequests = { - validBidRequests: [ - { - 'mediaTypes': { - 'banner': { - 'sizes': [300, 250] - } - }, - 'bidId': '3150ccb55da321', - }, - ] - }; - - const bannerServerResponses = [ - { - 'id': 'e5b10774-32bf-4931-85ee-05095e8cff21', - 'bidder_code': 'bridgewell', - 'cpm': 5.0, - 'width': 300, - 'height': 250, - 'adomain': ['response.com'], - 'mediaType': 'banner', - 'ad': '
test 300x250
', - 'ttl': 360, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - it('should return all required parameters', function () { - const result = spec.interpretResponse({ 'body': nativeServerResponses }, nativeBidRequests); - - expect(result[0].requestId).to.equal('3150ccb55da321'); - expect(result[0].cpm).to.equal(7.0); - expect(result[0].width).to.equal(1); - expect(result[0].height).to.equal(1); - expect(result[0].ttl).to.equal(400); - expect(result[0].creativeId).to.equal('0e4048d3-5c74-4380-a21a-00ba35629f7d'); - expect(result[0].netRevenue).to.equal(true); - expect(result[0].currency).to.equal('NTD'); - expect(result[0].mediaType).to.equal('native'); - expect(result[0].native.image.url).to.equal('https://img.scupio.com/test/test-image.jpg'); - expect(String(result[0].meta.advertiserDomains)).to.equal('response.com'); - }); - - it('should return all required parameters banner', function () { - const result = spec.interpretResponse({ 'body': bannerServerResponses }, bannerBidRequests); - - expect(result[0].requestId).to.equal('3150ccb55da321'); - expect(result[0].cpm).to.equal(5.0); - expect(result[0].width).to.equal(300); - expect(result[0].height).to.equal(250); - expect(result[0].ttl).to.equal(360); - expect(result[0].creativeId).to.equal('e5b10774-32bf-4931-85ee-05095e8cff21'); - expect(result[0].netRevenue).to.equal(true); - expect(result[0].currency).to.equal('NTD'); - expect(result[0].mediaType).to.equal('banner'); - expect(result[0].ad).to.equal('
test 300x250
'); - expect(String(result[0].meta.advertiserDomains)).to.equal('response.com'); - }); - - it('should give up bid if server response is undefiend', function () { - let result = spec.interpretResponse({ 'body': undefined }, bannerBidRequests); - - expect(result).to.deep.equal([]); - }); - - it('should give up bid if request sizes is missing', function () { - const request = { - validBidRequests: [ - { - 'mediaTypes': { - 'banner': {} - }, - 'bidId': '3150ccb55da321', - }, - ] - }; - const result = spec.interpretResponse({ 'body': bannerServerResponses }, request); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if response sizes is invalid', function () { - const request = { - validBidRequests: [ - { - 'mediaTypes': { - 'banner': { - 'sizes': [728, 90] - } - }, - 'bidId': '3150ccb55da321', - }, - ] - }; - const result = spec.interpretResponse({ 'body': bannerServerResponses }, request); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if cpm is missing', function () { - const response = [ - { - 'id': 'e5b10774-32bf-4931-85ee-05095e8cff21', - 'bidder_code': 'bridgewell', - 'width': 300, - 'height': 250, - 'mediaType': 'banner', - 'ad': '
test 300x250
', - 'ttl': 360, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, bannerBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if width or height is missing', function () { - const response = [ - { - 'id': 'e5b10774-32bf-4931-85ee-05095e8cff21', - 'bidder_code': 'bridgewell', - 'cpm': 5.0, - 'mediaType': 'banner', - 'ad': '
test 300x250
', - 'ttl': 360, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, bannerBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if ad is missing', function () { - const response = [ - { - 'id': 'e5b10774-32bf-4931-85ee-05095e8cff21', - 'bidder_code': 'bridgewell', - 'cpm': 5.0, - 'width': 300, - 'height': 250, - 'mediaType': 'banner', - 'ttl': 360, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, bannerBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if revenue mode is missing', function () { - const response = [ - { - 'id': 'e5b10774-32bf-4931-85ee-05095e8cff21', - 'bidder_code': 'bridgewell', - 'cpm': 5.0, - 'width': 300, - 'height': 250, - 'mediaType': 'banner', - 'ad': '
test 300x250
', - 'ttl': 360, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, bannerBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if currency is missing', function () { - const response = [ - { - 'id': 'e5b10774-32bf-4931-85ee-05095e8cff21', - 'bidder_code': 'bridgewell', - 'cpm': 5.0, - 'width': 300, - 'height': 250, - 'mediaType': 'banner', - 'ad': '
test 300x250
', - 'ttl': 360, - 'netRevenue': true, - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, bannerBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if mediaType is missing', function () { - const response = [ - { - 'id': 'e5b10774-32bf-4931-85ee-05095e8cff21', - 'bidder_code': 'bridgewell', - 'cpm': 5.0, - 'width': 300, - 'height': 250, - 'ad': '
test 300x250
', - 'ttl': 360, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, bannerBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if mediaType is not support', function () { - const responses = [ - { - 'id': 'e5b10774-32bf-4931-85ee-05095e8cff21', - 'bidder_code': 'bridgewell', - 'cpm': 5.0, - 'width': 300, - 'height': 250, - 'mediaType': 'superNiceAd', - 'ad': '
test 300x250
', - 'ttl': 360, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': responses }, bannerBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if property native of mediaType native is missing', function () { - const response = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'mediaType': 'native', - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if native title is missing', function () { - const response = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'mediaType': 'native', - 'native': { - 'image': { - 'url': 'https://img.scupio.com/test/test-image.jpg', - 'width': 150, - 'height': 150 - }, - 'sponsoredBy': 'test-sponsoredBy', - 'body': 'test-body', - 'icon': { - 'url': 'https://img.scupio.com/test/test-icon.jpg', - 'width': 50, - 'height': 50 - }, - 'clickUrl': 'https://img.scupio.com/test-clickUrl', - 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], - 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] - }, - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if native title is too long', function () { - const response = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'mediaType': 'native', - 'native': { - 'image': { - 'url': 'https://img.scupio.com/test/test-image.jpg', - 'width': 150, - 'height': 150 - }, - 'title': 'test-titletest-title', - 'sponsoredBy': 'test-sponsoredBy', - 'body': 'test-body', - 'icon': { - 'url': 'https://img.scupio.com/test/test-icon.jpg', - 'width': 50, - 'height': 50 - }, - 'clickUrl': 'https://img.scupio.com/test-clickUrl', - 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], - 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] - }, - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if native body is missing', function () { - const response = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'mediaType': 'native', - 'native': { - 'image': { - 'url': 'https://img.scupio.com/test/test-image.jpg', - 'width': 150, - 'height': 150 - }, - 'title': 'test-title', - 'sponsoredBy': 'test-sponsoredBy', - 'icon': { - 'url': 'https://img.scupio.com/test/test-icon.jpg', - 'width': 50, - 'height': 50 - }, - 'clickUrl': 'https://img.scupio.com/test-clickUrl', - 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], - 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] - }, - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if native image url is missing', function () { - const response = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'mediaType': 'native', - 'native': { - 'image': { - 'width': 150, - 'height': 150 - }, - 'title': 'test-title', - 'sponsoredBy': 'test-sponsoredBy', - 'body': 'test-body', - 'icon': { - 'url': 'https://img.scupio.com/test/test-icon.jpg', - 'width': 50, - 'height': 50 - }, - 'clickUrl': 'https://img.scupio.com/test-clickUrl', - 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], - 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] - }, - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if native image is missing', function () { - const response = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'mediaType': 'native', - 'native': { - 'title': 'test-title', - 'sponsoredBy': 'test-sponsoredBy', - 'body': 'test-body', - 'icon': { - 'url': 'https://img.scupio.com/test/test-icon.jpg', - 'width': 50, - 'height': 50 - }, - 'clickUrl': 'https://img.scupio.com/test-clickUrl', - 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], - 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] - }, - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if native image is empty', function () { - const response = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'mediaType': 'native', - 'native': { - 'image': {}, - 'title': 'test-title', - 'sponsoredBy': 'test-sponsoredBy', - 'body': 'test-body', - 'icon': { - 'url': 'https://img.scupio.com/test/test-icon.jpg', - 'width': 50, - 'height': 50 - }, - 'clickUrl': 'https://img.scupio.com/test-clickUrl', - 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], - 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] - }, - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if native image sizes is missing', function () { - const response = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'mediaType': 'native', - 'native': { - 'image': { - 'url': 'https://img.scupio.com/test/test-image.jpg' - }, - 'title': 'test-title', - 'sponsoredBy': 'test-sponsoredBy', - 'body': 'test-body', - 'icon': { - 'url': 'https://img.scupio.com/test/test-icon.jpg', - 'width': 50, - 'height': 50 - }, - 'clickUrl': 'https://img.scupio.com/test-clickUrl', - 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], - 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] - }, - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if native sponsoredBy is missing', function () { - const response = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'mediaType': 'native', - 'native': { - 'image': { - 'url': 'https://img.scupio.com/test/test-image.jpg', - 'width': 150, - 'height': 150 - }, - 'title': 'test-title', - 'body': 'test-body', - 'icon': { - 'url': 'https://img.scupio.com/test/test-icon.jpg', - 'width': 50, - 'height': 50 - }, - 'clickUrl': 'https://img.scupio.com/test-clickUrl', - 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], - 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] - }, - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if native icon is missing', function () { - const response = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'mediaType': 'native', - 'native': { - 'image': { - 'url': 'https://img.scupio.com/test/test-image.jpg', - 'width': 150, - 'height': 150 - }, - 'title': 'test-title', - 'sponsoredBy': 'test-sponsoredBy', - 'body': 'test-body', - 'clickUrl': 'https://img.scupio.com/test-clickUrl', - 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], - 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] - }, - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if native icon url is missing', function () { - const response = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'mediaType': 'native', - 'native': { - 'image': { - 'url': 'https://img.scupio.com/test/test-image.jpg', - 'width': 150, - 'height': 150 - }, - 'title': 'test-title', - 'sponsoredBy': 'test-sponsoredBy', - 'body': 'test-body', - 'icon': { - 'width': 50, - 'height': 50 - }, - 'clickUrl': 'https://img.scupio.com/test-clickUrl', - 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], - 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] - }, - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if native icon sizes is missing', function () { - const response = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'mediaType': 'native', - 'native': { - 'image': { - 'url': 'https://img.scupio.com/test/test-image.jpg', - 'width': 150, - 'height': 150 - }, - 'title': 'test-title', - 'sponsoredBy': 'test-sponsoredBy', - 'body': 'test-body', - 'icon': { - 'url': 'https://img.scupio.com/test/test-icon.jpg', - }, - 'clickUrl': 'https://img.scupio.com/test-clickUrl', - 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], - 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] - }, - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if native clickUrl is missing', function () { - const response = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'mediaType': 'native', - 'native': { - 'image': { - 'url': 'https://img.scupio.com/test/test-image.jpg', - 'width': 150, - 'height': 150 - }, - 'title': 'test-title', - 'sponsoredBy': 'test-sponsoredBy', - 'body': 'test-body', - 'icon': { - 'url': 'https://img.scupio.com/test/test-icon.jpg', - 'width': 50, - 'height': 50 - }, - 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], - 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] - }, - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if native clickTrackers is missing', function () { - const response = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'mediaType': 'native', - 'native': { - 'image': { - 'url': 'https://img.scupio.com/test/test-image.jpg', - 'width': 150, - 'height': 150 - }, - 'title': 'test-title', - 'sponsoredBy': 'test-sponsoredBy', - 'body': 'test-body', - 'icon': { - 'url': 'https://img.scupio.com/test/test-icon.jpg', - 'width': 50, - 'height': 50 - }, - 'clickUrl': 'https://img.scupio.com/test-clickUrl', - 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] - }, - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if native clickTrackers is empty', function () { - const response = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'mediaType': 'native', - 'native': { - 'image': { - 'url': 'https://img.scupio.com/test/test-image.jpg', - 'width': 150, - 'height': 150 - }, - 'title': 'test-title', - 'sponsoredBy': 'test-sponsoredBy', - 'body': 'test-body', - 'icon': { - 'url': 'https://img.scupio.com/test/test-icon.jpg', - 'width': 50, - 'height': 50 - }, - 'clickUrl': 'https://img.scupio.com/test-clickUrl', - 'clickTrackers': [], - 'impressionTrackers': ['https://img.scupio.com/test-impressionTracker'] - }, - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if native impressionTrackers is missing', function () { - const response = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'mediaType': 'native', - 'native': { - 'image': { - 'url': 'https://img.scupio.com/test/test-image.jpg', - 'width': 150, - 'height': 150 - }, - 'title': 'test-title', - 'sponsoredBy': 'test-sponsoredBy', - 'body': 'test-body', - 'icon': { - 'url': 'https://img.scupio.com/test/test-icon.jpg', - 'width': 50, - 'height': 50 - }, - 'clickUrl': 'https://img.scupio.com/test-clickUrl', - 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], - }, - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should give up bid if native impressionTrackers is empty', function () { - const response = [ - { - 'id': '0e4048d3-5c74-4380-a21a-00ba35629f7d', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 1, - 'height': 1, - 'mediaType': 'native', - 'native': { - 'image': { - 'url': 'https://img.scupio.com/test/test-image.jpg', - 'width': 150, - 'height': 150 - }, - 'title': 'test-title', - 'sponsoredBy': 'test-sponsoredBy', - 'body': 'test-body', - 'icon': { - 'url': 'https://img.scupio.com/test/test-icon.jpg', - 'width': 50, - 'height': 50 - }, - 'clickUrl': 'https://img.scupio.com/test-clickUrl', - 'clickTrackers': ['https://img.scupio.com/test-clickTracker'], - 'impressionTrackers': [] - }, - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, - ]; - - const result = spec.interpretResponse({ 'body': response }, nativeBidRequests); - expect(result).to.deep.equal([]); - }); - - it('should contain every request bid id in responses', function () { - const request = { - validBidRequests: [ - { - 'mediaTypes': { - 'banner': { - 'sizes': [300, 250] - } - }, - 'bidId': '3150ccb55da321', - }, - { - 'mediaTypes': { - 'banner': { - 'sizes': [300, 250] - } - }, - 'bidId': '3150ccb55da322', - } - ], - }; - const response = [{ - 'id': '0cd250f4-f40e-4a78-90f5-5168eb0a97e9', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 300, - 'height': 250, - 'mediaType': 'banner', - 'ad': '
test 300x250
', - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, { - 'id': '8a740063-6820-45e4-b01f-34ce9b38e858', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 300, - 'height': 250, - 'mediaType': 'banner', - 'ad': '
test 300x250
', - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }]; - const result = spec.interpretResponse({ 'body': response }, request); - let actualBidId = result.map(obj => obj.requestId); - let expectedBidId = ['3150ccb55da321', '3150ccb55da322']; - - expect(actualBidId).to.include(expectedBidId[0]).and.to.include(expectedBidId[1]); - }); - - it('should have 2 consumed responses when two requests with same sizes are given', function () { - const request = { - validBidRequests: [ - { - 'mediaTypes': { - 'banner': { - 'sizes': [300, 250] - } - }, - 'bidId': '3150ccb55da321', - }, - { - 'mediaTypes': { - 'banner': { - 'sizes': [300, 250] - } - }, - 'bidId': '3150ccb55da322', - } - ], - }; - const response = [{ - 'id': '0cd250f4-f40e-4a78-90f5-5168eb0a97e9', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 300, - 'height': 250, - 'mediaType': 'banner', - 'ad': '
test 300x250
', - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, { - 'id': '8a740063-6820-45e4-b01f-34ce9b38e858', - 'bidder_code': 'bridgewell', - 'cpm': 7.0, - 'width': 300, - 'height': 250, - 'mediaType': 'banner', - 'ad': '
test 300x250
', - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }]; - const reducer = function(accumulator, currentValue) { - if (currentValue.consumed) accumulator++; - return accumulator; - }; - - spec.interpretResponse({ 'body': response }, request); - expect(response.reduce(reducer, 0)).to.equal(2); - }); - - it('should use adUnitCode to build bidResponses', function () { - const request = { - validBidRequests: [ - { - 'adUnitCode': 'div-gpt-ad-1564632520056-0', - 'bidId': '3150ccb55da321', - }, - { - 'adUnitCode': 'div-gpt-ad-1564632520056-1', - 'bidId': '3150ccb55da322', - } - ], - }; - const response = [{ - 'id': '0cd250f4-f40e-4a78-90f5-5168eb0a97e9', - 'bidder_code': 'bridgewell', - 'adUnitCode': 'div-gpt-ad-1564632520056-0', - 'cpm': 7.0, - 'width': 300, - 'height': 250, - 'mediaType': 'banner', - 'ad': '
test 300x250
', - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, { - 'id': '8a740063-6820-45e4-b01f-34ce9b38e858', - 'bidder_code': 'bridgewell', - 'adUnitCode': 'div-gpt-ad-1564632520056-1', - 'cpm': 7.0, - 'width': 300, - 'height': 250, - 'mediaType': 'banner', - 'ad': '
test 300x250
', - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }]; - const result = spec.interpretResponse({ 'body': response }, request); - let actualBidId = result.map(obj => obj.requestId); - let expectedBidId = ['3150ccb55da321', '3150ccb55da322']; - - expect(actualBidId).to.include(expectedBidId[0]).and.to.include(expectedBidId[1]); - }); - - it('should use size to match when adUnitCode is empty string in server response', function () { - const request = { - validBidRequests: [ - { - 'mediaTypes': { - 'banner': { - 'sizes': [300, 250] - } - }, - 'adUnitCode': 'div-gpt-ad-1564632520056-0', - 'bidId': '3150ccb55da321', - }, - { - 'mediaTypes': { - 'banner': { - 'sizes': [300, 250] - } - }, - 'adUnitCode': 'div-gpt-ad-1564632520056-1', - 'bidId': '3150ccb55da322', - } - ], - }; - const response = [{ - 'id': '0cd250f4-f40e-4a78-90f5-5168eb0a97e9', - 'bidder_code': 'bridgewell', - 'adUnitCode': '', - 'cpm': 7.0, - 'width': 300, - 'height': 250, - 'mediaType': 'banner', - 'ad': '
test 300x250
', - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }, { - 'id': '8a740063-6820-45e4-b01f-34ce9b38e858', - 'bidder_code': 'bridgewell', - 'adUnitCode': '', - 'cpm': 7.0, - 'width': 300, - 'height': 250, - 'mediaType': 'banner', - 'ad': '
test 300x250
', - 'ttl': 400, - 'netRevenue': true, - 'currency': 'NTD' - }]; - const result = spec.interpretResponse({ 'body': response }, request); - let actualBidId = result.map(obj => obj.requestId); - let expectedBidId = ['3150ccb55da321', '3150ccb55da322']; - - expect(actualBidId).to.include(expectedBidId[0]).and.to.include(expectedBidId[1]); - }); - }); -}); diff --git a/test/spec/modules/brightMountainMediaBidAdapter_spec.js b/test/spec/modules/brightMountainMediaBidAdapter_spec.js deleted file mode 100644 index 6c7ef816f4f..00000000000 --- a/test/spec/modules/brightMountainMediaBidAdapter_spec.js +++ /dev/null @@ -1,190 +0,0 @@ -import { expect } from 'chai'; -import { spec } from '../../../modules/brightMountainMediaBidAdapter.js'; - -const BIDDER_CODE = 'bmtm'; -const ENDPOINT_URL = 'https://one.elitebidder.com/api/hb'; -const ENDPOINT_URL_SYNC = 'https://console.brightmountainmedia.com:8443/cookieSync'; -const PLACEMENT_ID = 329; - -describe('brightMountainMediaBidAdapter_spec', function () { - let bidBanner = { - bidId: '2dd581a2b6281d', - bidder: BIDDER_CODE, - bidderRequestId: '145e1d6a7837c9', - params: { - placement_id: PLACEMENT_ID - }, - placementCode: 'placementid_0', - auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e62', - }; - - let bidVideo = { - bidId: '2dd581a2b6281d', - bidder: BIDDER_CODE, - bidderRequestId: '145e1d6a7837c9', - params: { - placement_id: PLACEMENT_ID - }, - placementCode: 'placementid_0', - auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', - mediaTypes: { - video: { - playerSizes: [[300, 250]], - context: 'outstream', - skip: 0, - playbackmethod: [1, 2], - mimes: ['video/mp4'] - } - }, - transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e62', - }; - - let bidderRequest = { - bidderCode: BIDDER_CODE, - auctionId: 'fffffff-ffff-ffff-ffff-ffffffffffff', - bidderRequestId: 'ffffffffffffff', - start: 1472239426002, - auctionStart: 1472239426000, - timeout: 5000, - uspConsent: '1YN-', - refererInfo: { - referer: 'http://www.example.com', - reachedTop: true, - } - }; - - describe('isBidRequestValid', function () { - it('Should return true when when required params found', function () { - expect(spec.isBidRequestValid(bidBanner)).to.be.true; - }); - it('Should return false when required params are not passed', function () { - bidBanner.params = {} - expect(spec.isBidRequestValid(bidBanner)).to.be.false; - }); - }); - - function testServerRequestBody(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 URL', function () { - expect(serverRequest.url).to.equal(ENDPOINT_URL); - }); - - it('Returns valid data if array of bids is valid', function () { - let data = serverRequest.data; - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); - 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'); - let placements = data['placements']; - expect(placements).to.be.an('array'); - }); - } - - describe('buildRequests', function () { - bidderRequest['bids'] = [bidBanner]; - let serverRequest = spec.buildRequests([bidBanner], bidderRequest); - testServerRequestBody(serverRequest); - - bidderRequest['bids'] = [bidVideo]; - serverRequest = spec.buildRequests([bidVideo], bidderRequest); - testServerRequestBody(serverRequest); - - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); - }); - - function testServerResponse(serverResponses) { - 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++) { - let dataItem = serverResponses[i]; - 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.mediaType).to.be.a('string'); - } - }); - } - - describe('interpretResponse', function () { - let resObjectBanner = { - body: [{ - requestId: '123', - mediaType: 'banner', - cpm: 0.3, - width: 320, - height: 50, - ad: '

Hello ad

', - ttl: 1000, - creativeId: '123asd', - netRevenue: true, - currency: 'USD' - }] - }; - - let resObjectVideo = { - body: [{ - requestId: '123', - mediaType: 'video', - cpm: 1.5, - width: 320, - height: 50, - ad: '

Hello ad

', - ttl: 1000, - creativeId: '123asd', - netRevenue: true, - currency: 'USD' - }] - }; - let serverResponses = spec.interpretResponse(resObjectBanner); - testServerResponse(serverResponses); - - serverResponses = spec.interpretResponse(resObjectVideo); - testServerResponse(serverResponses); - - 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; - }); - }); - - describe('getUserSyncs', function () { - let syncoptionsIframe = { - 'iframeEnabled': 'true' - } - it('should return iframe sync option', function () { - expect(spec.getUserSyncs(syncoptionsIframe)).to.be.an('array').with.lengthOf(1); - expect(spec.getUserSyncs(syncoptionsIframe)[0].type).to.exist; - expect(spec.getUserSyncs(syncoptionsIframe)[0].url).to.exist; - expect(spec.getUserSyncs(syncoptionsIframe)[0].type).to.equal('iframe') - expect(spec.getUserSyncs(syncoptionsIframe)[0].url).to.equal(ENDPOINT_URL_SYNC) - }); - }); -}); diff --git a/test/spec/modules/brightcomBidAdapter_spec.js b/test/spec/modules/brightcomBidAdapter_spec.js deleted file mode 100644 index a89391d681e..00000000000 --- a/test/spec/modules/brightcomBidAdapter_spec.js +++ /dev/null @@ -1,310 +0,0 @@ -import { expect } from 'chai'; -import * as utils from 'src/utils.js'; -import { spec } from 'modules/brightcomBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -const URL = 'https://brightcombid.marphezis.com/hb'; - -describe('brightcomBidAdapter', function() { - const adapter = newBidder(spec); - let element, win; - let bidRequests; - let sandbox; - - beforeEach(function() { - element = { - x: 0, - y: 0, - - width: 0, - height: 0, - - getBoundingClientRect: () => { - return { - width: element.width, - height: element.height, - - left: element.x, - top: element.y, - right: element.x + element.width, - bottom: element.y + element.height - }; - } - }; - win = { - document: { - visibilityState: 'visible' - }, - - innerWidth: 800, - innerHeight: 600 - }; - bidRequests = [{ - 'bidder': 'brightcom', - 'params': { - 'publisherId': 1234567 - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'bidId': '5fb26ac22bde4', - 'bidderRequestId': '4bf93aeb730cb9', - 'auctionId': 'ffe9a1f7-7b67-4bda-a8e0-9ee5dc9f442e' - }]; - - sandbox = sinon.sandbox.create(); - sandbox.stub(document, 'getElementById').withArgs('adunit-code').returns(element); - sandbox.stub(utils, 'getWindowTop').returns(win); - sandbox.stub(utils, 'getWindowSelf').returns(win); - }); - - afterEach(function() { - sandbox.restore(); - }); - - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'brightcom', - 'params': { - 'publisherId': 1234567 - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'bidId': '5fb26ac22bde4', - 'bidderRequestId': '4bf93aeb730cb9', - 'auctionId': 'ffe9a1f7-7b67-4bda-a8e0-9ee5dc9f442e', - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when publisherId not passed correctly', function () { - bid.params.publisherId = undefined; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when require params are not passed', function () { - let bid = Object.assign({}, bid); - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - it('sends bid request to our endpoint via POST', function () { - const request = spec.buildRequests(bidRequests); - expect(request.method).to.equal('POST'); - }); - - it('request url should match our endpoint url', function () { - const request = spec.buildRequests(bidRequests); - expect(request.url).to.equal(URL); - }); - - 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}]); - }); - - 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}]); - }); - - it('sends bidfloor param if present', function () { - bidRequests[0].params.bidFloor = 0.05; - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.imp[0].bidfloor).to.equal(0.05); - }); - - it('sends tagid', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.imp[0].tagid).to.equal('adunit-code'); - }); - - it('sends publisher id', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.site.publisher.id).to.equal(1234567); - }); - - it('sends gdpr info if exists', function () { - const consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - const bidderRequest = { - 'bidderCode': 'brightcom', - 'auctionId': '1d1a030790a437', - 'bidderRequestId': '22edbae2744bf5', - 'timeout': 3000, - gdprConsent: { - consentString: consentString, - gdprApplies: true - }, - refererInfo: { - referer: 'http://example.com/page.html', - } - }; - bidderRequest.bids = bidRequests; - - const data = JSON.parse(spec.buildRequests(bidRequests, bidderRequest).data); - - expect(data.regs.ext.gdpr).to.exist.and.to.be.a('number'); - expect(data.regs.ext.gdpr).to.equal(1); - expect(data.user.ext.consent).to.exist.and.to.be.a('string'); - expect(data.user.ext.consent).to.equal(consentString); - }); - - context('when element is fully in view', function() { - it('returns 100', function() { - 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); - }); - }); - - context('when element is out of view', function() { - it('returns 0', function() { - 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); - }); - }); - - context('when element is partially in view', function() { - it('returns percentage', function() { - 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); - }); - }); - - context('when width or height of the element is zero', function() { - it('try to use alternative values', function() { - 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); - expect(payload.imp[0].banner.ext.viewability).to.equal(25); - }); - }); - - context('when nested iframes', function() { - it('returns \'na\'', function() { - Object.assign(element, { width: 600, height: 400 }); - - utils.getWindowTop.restore(); - utils.getWindowSelf.restore(); - sandbox.stub(utils, 'getWindowTop').returns(win); - sandbox.stub(utils, 'getWindowSelf').returns({}); - - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.imp[0].banner.ext.viewability).to.equal('na'); - }); - }); - - context('when tab is inactive', function() { - it('returns 0', function() { - Object.assign(element, { width: 600, height: 400 }); - - utils.getWindowTop.restore(); - win.document.visibilityState = 'hidden'; - sandbox.stub(utils, 'getWindowTop').returns(win); - - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.imp[0].banner.ext.viewability).to.equal(0); - }); - }); - }); - - describe('interpretResponse', function () { - let response; - beforeEach(function () { - response = { - body: { - 'id': '37386aade21a71', - 'seatbid': [{ - 'bid': [{ - 'id': '376874781', - 'impid': '283a9f4cd2415d', - 'price': 0.35743275, - 'nurl': '', - 'adm': '', - 'w': 300, - 'h': 250 - }] - }] - } - }; - }); - - it('should get the correct bid response', function () { - let expectedResponse = [{ - 'requestId': '283a9f4cd2415d', - 'cpm': 0.35743275, - 'width': 300, - 'height': 250, - 'creativeId': '376874781', - 'currency': 'USD', - 'netRevenue': true, - 'mediaType': 'banner', - 'ad': `
`, - 'ttl': 60 - }]; - - let result = spec.interpretResponse(response); - expect(result[0]).to.deep.equal(expectedResponse[0]); - }); - - it('crid should default to the bid id if not on the response', function () { - let expectedResponse = [{ - 'requestId': '283a9f4cd2415d', - 'cpm': 0.35743275, - 'width': 300, - 'height': 250, - 'creativeId': response.body.seatbid[0].bid[0].id, - 'currency': 'USD', - 'netRevenue': true, - 'mediaType': 'banner', - 'ad': `
`, - 'ttl': 60 - }]; - - let result = spec.interpretResponse(response); - expect(result[0]).to.deep.equal(expectedResponse[0]); - }); - - it('handles empty bid response', function () { - let response = { - body: '' - }; - let result = spec.interpretResponse(response); - expect(result.length).to.equal(0); - }); - }); - - describe('getUserSyncs ', () => { - let syncOptions = {iframeEnabled: true, pixelEnabled: true}; - - it('should not return', () => { - let returnStatement = spec.getUserSyncs(syncOptions, []); - expect(returnStatement).to.be.empty; - }); - }); -}); diff --git a/test/spec/modules/britepoolIdSystem_spec.js b/test/spec/modules/britepoolIdSystem_spec.js deleted file mode 100644 index ddb61806006..00000000000 --- a/test/spec/modules/britepoolIdSystem_spec.js +++ /dev/null @@ -1,129 +0,0 @@ -import {britepoolIdSubmodule} from 'modules/britepoolIdSystem.js'; -import * as utils from '../../../src/utils.js'; - -describe('BritePool Submodule', () => { - const api_key = '1111'; - const aaid = '4421ea96-34a9-45df-a4ea-3c41a48a18b1'; - const idfa = '2d1c4fac-5507-4e28-991c-ca544e992dba'; - const bpid = '279c0161-5152-487f-809e-05d7f7e653fd'; - const url_override = 'https://override'; - const getter_override = function(params) { - return JSON.stringify({ 'primaryBPID': bpid }); - }; - const getter_callback_override = function(params) { - return callback => { - callback(JSON.stringify({ 'primaryBPID': bpid })); - }; - }; - - let triggerPixelStub; - - beforeEach(function (done) { - triggerPixelStub = sinon.stub(utils, 'triggerPixel'); - done(); - }); - - afterEach(function () { - triggerPixelStub.restore(); - }); - - it('trigger id resolution pixel when no identifiers set', () => { - britepoolIdSubmodule.getId({ params: {} }); - expect(triggerPixelStub.called).to.be.true; - }); - - it('trigger id resolution pixel when no identifiers set with api_key param', () => { - britepoolIdSubmodule.getId({ params: { api_key } }); - expect(triggerPixelStub.called).to.be.true; - }); - - it('does not trigger id resolution pixel when identifiers set', () => { - britepoolIdSubmodule.getId({ params: { api_key, aaid } }); - expect(triggerPixelStub.called).to.be.false; - }); - - it('sends x-api-key in header and one identifier', () => { - const { params, headers, url, errors } = britepoolIdSubmodule.createParams({ api_key, aaid }); - assert(errors.length === 0, errors); - expect(headers['x-api-key']).to.equal(api_key); - expect(params).to.eql({ aaid }); - }); - - it('sends x-api-key in header and two identifiers', () => { - const { params, headers, url, errors } = britepoolIdSubmodule.createParams({ api_key, aaid, idfa }); - assert(errors.length === 0, errors); - expect(headers['x-api-key']).to.equal(api_key); - expect(params).to.eql({ aaid, idfa }); - }); - - it('allows call without api_key', () => { - const { params, headers, url, errors } = britepoolIdSubmodule.createParams({ aaid, idfa }); - expect(params).to.eql({ aaid, idfa }); - expect(errors.length).to.equal(0); - }); - - it('test url override', () => { - const { params, headers, url, errors } = britepoolIdSubmodule.createParams({ api_key, aaid, url: url_override }); - expect(url).to.equal(url_override); - // Making sure it did not become part of params - expect(params.url).to.be.undefined; - }); - - it('test gdpr consent string in url', () => { - const { params, headers, url, errors } = britepoolIdSubmodule.createParams({ api_key, aaid }, { gdprApplies: true, consentString: 'expectedConsentString' }); - expect(url).to.equal('https://api.britepool.com/v1/britepool/id?gdprString=expectedConsentString'); - }); - - it('test gdpr consent string not in url if gdprApplies false', () => { - const { params, headers, url, errors } = britepoolIdSubmodule.createParams({ api_key, aaid }, { gdprApplies: false, consentString: 'expectedConsentString' }); - expect(url).to.equal('https://api.britepool.com/v1/britepool/id'); - }); - - it('test gdpr consent string not in url if consent string undefined', () => { - const { params, headers, url, errors } = britepoolIdSubmodule.createParams({ api_key, aaid }, { gdprApplies: true, consentString: undefined }); - expect(url).to.equal('https://api.britepool.com/v1/britepool/id'); - }); - - it('dynamic pub params should be added to params', () => { - window.britepool_pubparams = { ppid: '12345' }; - const { params, headers, url, errors } = britepoolIdSubmodule.createParams({ api_key, aaid }); - expect(params).to.eql({ aaid, ppid: '12345' }); - window.britepool_pubparams = undefined; - }); - - it('dynamic pub params should override submodule params', () => { - window.britepool_pubparams = { ppid: '67890' }; - const { params, headers, url, errors } = britepoolIdSubmodule.createParams({ api_key, ppid: '12345' }); - expect(params).to.eql({ ppid: '67890' }); - window.britepool_pubparams = undefined; - }); - - it('if dynamic pub params undefined do nothing', () => { - window.britepool_pubparams = undefined; - const { params, headers, url, errors } = britepoolIdSubmodule.createParams({ api_key, aaid }); - expect(params).to.eql({ aaid }); - window.britepool_pubparams = undefined; - }); - - it('test getter override with value', () => { - const { params, headers, url, getter, errors } = britepoolIdSubmodule.createParams({ api_key, aaid, url: url_override, getter: getter_override }); - expect(getter).to.equal(getter_override); - // Making sure it did not become part of params - expect(params.getter).to.be.undefined; - const response = britepoolIdSubmodule.getId({ params: { api_key, aaid, url: url_override, getter: getter_override } }); - assert.deepEqual(response, { id: { 'primaryBPID': bpid } }); - }); - - it('test getter override with callback', done => { - const { params, headers, url, getter, errors } = britepoolIdSubmodule.createParams({ api_key, aaid, url: url_override, getter: getter_callback_override }); - expect(getter).to.equal(getter_callback_override); - // Making sure it did not become part of params - expect(params.getter).to.be.undefined; - const response = britepoolIdSubmodule.getId({ params: { api_key, aaid, url: url_override, getter: getter_callback_override } }); - expect(response.callback).to.not.be.undefined; - response.callback(result => { - assert.deepEqual(result, { 'primaryBPID': bpid }); - done(); - }); - }); -}); diff --git a/test/spec/modules/browsiRtdProvider_spec.js b/test/spec/modules/browsiRtdProvider_spec.js deleted file mode 100644 index ee37d16905b..00000000000 --- a/test/spec/modules/browsiRtdProvider_spec.js +++ /dev/null @@ -1,83 +0,0 @@ -import * as browsiRTD from '../../../modules/browsiRtdProvider.js'; -import {makeSlot} from '../integration/faker/googletag.js'; - -describe('browsi Real time data sub module', function () { - const conf = { - 'auctionDelay': 250, - dataProviders: [{ - 'name': 'browsi', - 'params': { - 'url': 'testUrl.com', - 'siteKey': 'testKey', - 'pubKey': 'testPub', - 'keyName': 'bv' - } - }] - }; - - it('should init and return true', function () { - browsiRTD.collectData(); - expect(browsiRTD.browsiSubmodule.init(conf.dataProviders[0])).to.equal(true) - }); - - it('should create browsi script', function () { - const script = browsiRTD.addBrowsiTag('scriptUrl.com'); - expect(script.getAttribute('data-sitekey')).to.equal('testKey'); - expect(script.getAttribute('data-pubkey')).to.equal('testPub'); - expect(script.async).to.equal(true); - expect(script.prebidData.kn).to.equal(conf.dataProviders[0].params.keyName); - }); - - it('should match placement with ad unit', function () { - const slot = makeSlot({code: '/57778053/Browsi_Demo_300x250', divId: 'browsiAd_1'}); - - const test1 = browsiRTD.isIdMatchingAdUnit(slot, ['/57778053/Browsi_Demo_300x250']); // true - const test2 = browsiRTD.isIdMatchingAdUnit(slot, ['/57778053/Browsi_Demo_300x250', '/57778053/Browsi']); // true - const test3 = browsiRTD.isIdMatchingAdUnit(slot, ['/57778053/Browsi_Demo_Low']); // false - const test4 = browsiRTD.isIdMatchingAdUnit(slot, []); // true - - expect(test1).to.equal(true); - expect(test2).to.equal(true); - expect(test3).to.equal(false); - expect(test4).to.equal(true); - }); - - it('should return correct macro values', function () { - const slot = makeSlot({code: '/57778053/Browsi_Demo_300x250', divId: 'browsiAd_1'}); - - slot.setTargeting('test', ['test', 'value']); - // slot getTargeting doesn't act like GPT so we can't expect real value - const macroResult = browsiRTD.getMacroId({p: '/'}, slot); - expect(macroResult).to.equal('/57778053/Browsi_Demo_300x250/NA'); - - const macroResultB = browsiRTD.getMacroId({}, slot); - expect(macroResultB).to.equal('browsiAd_1'); - - const macroResultC = browsiRTD.getMacroId({p: '', s: {s: 0, e: 1}}, slot); - expect(macroResultC).to.equal('/'); - }); - - describe('should return data to RTD module', function () { - it('should return empty if no ad units defined', function () { - browsiRTD.setData({}); - expect(browsiRTD.browsiSubmodule.getTargetingData([])).to.eql({}); - }); - - it('should return NA if no prediction for ad unit', function () { - makeSlot({code: 'adMock', divId: 'browsiAd_2'}); - browsiRTD.setData({}); - expect(browsiRTD.browsiSubmodule.getTargetingData(['adMock'])).to.eql({adMock: {bv: 'NA'}}); - }); - - it('should return prediction from server', function () { - makeSlot({code: 'hasPrediction', divId: 'hasPrediction'}); - const data = { - p: {'hasPrediction': {p: 0.234}}, - kn: 'bv', - pmd: undefined - }; - browsiRTD.setData(data); - expect(browsiRTD.browsiSubmodule.getTargetingData(['hasPrediction'])).to.eql({hasPrediction: {bv: '0.20'}}); - }) - }) -}); diff --git a/test/spec/modules/bucksenseBidAdapter_spec.js b/test/spec/modules/bucksenseBidAdapter_spec.js deleted file mode 100644 index b977c3a9dd1..00000000000 --- a/test/spec/modules/bucksenseBidAdapter_spec.js +++ /dev/null @@ -1,150 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/bucksenseBidAdapter.js'; - -describe('Bucksense Adapter', function() { - const BIDDER_CODE = 'bucksense'; - const BID_ID = '12345'; - const PLACE_ID = '1000'; - - function getValidBidObject() { - return { - bidder: BIDDER_CODE, - params: { - placementId: PLACE_ID, - } - } - }; - - describe('isBidRequestValid', function() { - var bid; - - beforeEach(function() { - bid = getValidBidObject(); - }); - - it('returns true when valid bid request is sent', function() { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - - it('returns true when valid test bid request is sent', function() { - bid.params['test'] = 1; - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - - it('returns false when bidder not set to "bucksense"', function() { - bid.bidder = 'dummy'; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - - it('returns false when params not set', function() { - delete bid.params; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function() { - var bid, bidRequestObj; - - beforeEach(function() { - bid = getValidBidObject(); - bidRequestObj = { - 'bidderCode': 'bucksense', - 'auctionId': '73540558-86cb-4eef-895f-bf99c5353bd7', - 'bidderRequestId': '1feebcb5938c7e', - 'bids': [ - { - 'bidder': 'bucksense', - 'params': { - 'placementId': 1000 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ [ 300, 250 ], [ 300, 600 ] ] - } - }, - 'adUnitCode': 'test-div', - 'transactionId': '52b3ed07-2a09-4f58-a426-75acc7602c96', - 'sizes': [ [ 300, 250 ], [ 300, 600 ] ], - 'bidId': '22aecdacdcd773', - 'bidderRequestId': '1feebcb5938c7e', - 'auctionId': '73540558-86cb-4eef-895f-bf99c5353bd7', - 'src': 'client', - 'bidRequestsCount': 1 - } - ], - 'auctionStart': 1557176022728, - 'timeout': 1000, - 'refererInfo': { - 'referer': 'https://stefanod.hera.pe/prebid/?pbjs_debug=true', - 'reachedTop': true, - 'numIframes': 0, - 'stack': [ - 'https://stefanod.hera.pe/prebid/?pbjs_debug=true' - ] - }, - 'start': 1557176022731 - }; - }); - - it('should build a very basic request', function() { - var request = spec.buildRequests([bid], bidRequestObj); - expect(request[0].method).to.equal('POST'); - }); - - it('bidRequest data', function () { - var request = spec.buildRequests([bid], bidRequestObj); - expect(request[0].data).to.exist; - }); - }); - - describe('interpretResponse', function() { - var serverResponse; - var serverRequest; - - beforeEach(function() { - serverRequest = { - 'method': 'POST', - 'url': 'https://prebid.bksn.se/prebidjs/', - 'data': { - 'pub_id': 'prebid.org', - 'pl_id': '1000', - 'secure': 0, - 'href': 'https://prebid.org/developers.html', - 'bid_id': '27aaf8e96d9fd5', - 'params': { - 'placementId': '1000' - }, - 'sizes': [ [ 300, 250 ], [ 300, 600 ] ] - } - }; - - serverResponse = { - body: { - 'requestId': '', - 'cpm': 0.3, - 'width': 300, - 'height': 250, - 'ttl': 360, - 'creativeId': 'creative002', - 'currency': 'USD', - 'netRevenue': false, - 'ad': '
', - 'meta': { - 'advertiserDomains': ['http://www.bucksense.com/'] - } - } - }; - }); - - it('should return an array of bid responses', function() { - var responses = spec.interpretResponse(serverResponse, serverRequest); - expect(responses).to.be.an('array').with.length(1); - }); - - it('should return an array of bid responses', function() { - serverResponse = {}; - var responses = spec.interpretResponse(serverResponse, serverRequest); - expect(responses).to.be.an('array').with.length(0); - }); - }); -}); diff --git a/test/spec/modules/buzzoolaBidAdapter_spec.js b/test/spec/modules/buzzoolaBidAdapter_spec.js deleted file mode 100644 index 8a04999219d..00000000000 --- a/test/spec/modules/buzzoolaBidAdapter_spec.js +++ /dev/null @@ -1,279 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/buzzoolaBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.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]]}}, - 'sizes': [[240, 400], [300, 600]] -}, { - 'bidder': 'buzzoola', - 'params': {'placementId': 417846}, - 'sizes': [[240, 400], [300, 600]] -}, { - 'bidder': 'buzzoola', - 'mediaTypes': { - 'video': { - 'playerSize': [[640, 380]], - 'mimes': ['video/mp4'], - 'minduration': 1, - 'maxduration': 2 - } - } -}, { - 'bidder': 'buzzoola', - 'params': {'placementId': 417845} -}]; - -const BANNER_BID = { - 'bidder': 'buzzoola', - 'params': {'placementId': 417846}, - 'mediaTypes': {'banner': {'sizes': [[240, 400], [300, 600]]}}, - 'sizes': [[240, 400], [300, 600]], - 'bidId': '2a11641ada3c6a' -}; - -const BANNER_BID_REQUEST = { - bidderCode: 'buzzoola', - bids: [BANNER_BID] -}; - -const BANNER_RESPONSE = [{ - 'requestId': '2a11641ada3c6a', - 'cpm': 5.583115, - 'width': 240, - 'height': 400, - 'creativeId': '11773', - 'dealId': '', - 'currency': 'RUB', - 'netRevenue': true, - 'ttl': 10800, - 'ad': '
', - 'mediaType': 'banner' -}]; - -const REQUIRED_BANNER_FIELDS = [ - 'requestId', - 'cpm', - 'width', - 'height', - 'ad', - 'ttl', - 'creativeId', - 'netRevenue', - 'currency', - 'mediaType' -]; - -const VIDEO_BID = { - 'bidder': 'buzzoola', - 'params': {'placementId': 417845}, - 'mediaTypes': { - 'video': { - 'context': 'instream', - 'playerSize': [[640, 380]], - 'mimes': ['video/mp4'], - 'minduration': 1, - 'maxduration': 2 - } - }, - 'bidId': '325a54271dc40a' -}; - -const VIDEO_BID_REQUEST = { - bidderCode: 'buzzoola', - bids: [VIDEO_BID] -}; - -const VIDEO_RESPONSE = [{ - 'requestId': '325a54271dc40a', - 'cpm': 4.6158956756756755, - 'width': 640, - 'height': 380, - 'creativeId': '11774', - 'dealId': '', - 'currency': 'RUB', - 'netRevenue': true, - 'ttl': 10800, - 'ad': '{"crs":[{"advertiser_id":165,"title":"qa//PrebidJStestVideoURL","description":"qa//PrebidJStest","duration":0,"ya_id":"55038886","raw_content":"{\\"main_content\\": \\"https://tube.buzzoola.com/xstatic/o42/mcaug/2.mp4\\"}","content":{"main_content":"https://tube.buzzoola.com/xstatic/o42/mcaug/2.mp4"},"content_type":"video_url","sponsor_link":"","sponsor_name":"","overlay":"","overlay_start_after":0,"overlay_close_after":0,"action_button_title":"","tracking_url":{},"iframe_domains":[],"soc_share_url":"https://tube.buzzoola.com/share.html","player_show_skip_button_before_play":false,"player_show_skip_button_seconds":5,"player_show_title":true,"player_data_attributes":{"expandable":"default","overroll":"default"},"click_event_view":"default","share_panel_position":"left","auto_play":true,"logo_url":{},"share_buttons":["vkontakte","facebook","twitter","moimir","odnoklassniki","embed"],"player_show_panels":false,"thumbnail":"","tracking_js":{},"click_event_url":"https://exchange.buzzoola.com/event/f9382ceb-49c2-4683-50d8-5c516c53cd69/14795a96-6261-49dc-7241-207333ab1490/m7JVQI9Y7J35_gEDugNO2bIiP2qTqPKfuLrqqh_LoJu0tD6PoLEglMXUBzVpSg75c-unsaijXpIERGosa1adogXgqjDml4Pm/click/0/","vpaid_js_url":"https://tube.buzzoola.com/new/js/lib/vpaid_js_proxy.js","skip_clickthru":false,"landing_link_text":"","sound_enabled_by_default":false,"landing_link_position":"right","displayed_price":"","js_wrapper_url":"","enable_moat":false,"branding_template":"","event_url":"https://exchange.buzzoola.com/event/f9382ceb-49c2-4683-50d8-5c516c53cd69/14795a96-6261-49dc-7241-207333ab1490/m7JVQI9Y7J35_gEDugNO2bIiP2qTqPKfuLrqqh_LoJu0tD6PoLEglMXUBzVpSg75c-unsaijXpIERGosa1adogXgqjDml4Pm/","resend_event_url":"https://exchange.buzzoola.com/resend_event/f9382ceb-49c2-4683-50d8-5c516c53cd69/14795a96-6261-49dc-7241-207333ab1490/m7JVQI9Y7J35_gEDugNO2bIiP2qTqPKfuLrqqh_LoJu0tD6PoLEglMXUBzVpSg75c-unsaijXpIERGosa1adogXgqjDml4Pm/","creative_hash":"m7JVQI9Y7J35_gEDugNO2bIiP2qTqPKfuLrqqh_LoJu0tD6PoLEglMXUBzVpSg75c-unsaijXpIERGosa1adogXgqjDml4Pm","custom_html":"","custom_js":"","height":0,"width":0,"campaign_id":5758,"line_item_id":17319,"creative_id":11774,"extra":{"imp_id":"14795a96-6261-49dc-7241-207333ab1490","rtime":"2019-08-27 13:58:36"},"subcontent":"vast","auction_settings":{"price":"4.6158956756756755","currency":"RUB","event_name":"player_seen","time_slice":0},"hash_to_embed":"kbDH64c7yFYkSu0KCwSkoUD2bNHAnUTHBERqLGtWnaIF4Kow5peD5g","need_ad":false}],"tracking_urls":{"ctor":["https://www.tns-counter.ru/V13a****buzzola_com/ru/CP1251/tmsec=buzzola_total/1322650417245790778","https://www.tns-counter.ru/V13a****buzzoola_kz/ru/UTF-8/tmsec=buzzoola_video/5395765100939533275","https://buzzoolaru.solution.weborama.fr/fcgi-bin/dispatch.fcgi?a.A=ev&a.si=3071&a.te=37&a.aap=1&a.agi=862&a.evn=PrebidJS.test&g.ra=4581478478720298652","https://x01.aidata.io/0.gif?pid=BUZZOOLA&id=dbdb5b13-e719-4987-7f6a-a882322bbfce","https://top-fwz1.mail.ru/counter?id=3026769","https://www.tns-counter.ru/V13a****buzzola_com/ru/UTF-8/tmsec=buzzola_inread/542059452789128996","https://dm.hybrid.ai/match?id=111&vid=dbdb5b13-e719-4987-7f6a-a882322bbfce","https://px.adhigh.net/p/cm/buzzoola?u=dbdb5b13-e719-4987-7f6a-a882322bbfce","https://ssp1.rtb.beeline.ru/userbind?src=buz&ssp_user_id=dbdb5b13-e719-4987-7f6a-a882322bbfce","https://sync.upravel.com/image?source=buzzoola&id=dbdb5b13-e719-4987-7f6a-a882322bbfce","https://relap.io/api/partners/bzcs.gif?uid=dbdb5b13-e719-4987-7f6a-a882322bbfce","https://x.bidswitch.net/sync?ssp=sspicyads","https://inv-nets.admixer.net/adxcm.aspx?ssp=3C5173FC-CA30-4692-9116-009C19CB1BF9&rurl=%2F%2Fexchange.buzzoola.com%2Fcookiesync%2Fdsp%2Fadmixer-video%2F%24%24visitor_cookie%24%24","https://sync.datamind.ru/cookie/accepter?source=buzzoola&id=dbdb5b13-e719-4987-7f6a-a882322bbfce","https://dmp.vihub.ru/match?sysid=buz&redir=no&uid=dbdb5b13-e719-4987-7f6a-a882322bbfce","https://ad.adriver.ru/cgi-bin/rle.cgi?sid=1&ad=608223&bt=21&pid=2551979&bid=6150299&bn=6150299&rnd=1279444531737367663","https://reichelcormier.bid/point/?method=match&type=ssp&key=4677290772f9000878093d69c199bfba&id=3509&extUid=dbdb5b13-e719-4987-7f6a-a882322bbfce","https://sync.republer.com/match?src=buzzoola&id=dbdb5b13-e719-4987-7f6a-a882322bbfce","https://sm.rtb.mts.ru/p?id=dbdb5b13-e719-4987-7f6a-a882322bbfce&ssp=buzzoola","https://cm.mgid.com/m?cdsp=371151&adu=https%3A%2F%2Fexchange.buzzoola.com%2Fcookiesync%2Fdsp%2Fmarketgid-native%2F%7Bmuidn%7D","https://dmp.gotechnology.io/dmp/syncsspdmp?sspid=122258"]},"tracking_js":{"ctor":["https://buzzoola.fraudscore.mobi/dooJ9sheeeDaZ3fe.js?s=268671&l=417845"]},"placement":{"placement_id":417845,"unit_type":"inread","unit_settings":{"align":"left","autoplay_enable_sound":false,"creatives_amount":1,"debug_mode":false,"expandable":"never","sound_control":"default","target":"","width":"100%"},"unit_settings_list":["width","sound_control","debug_mode","target","creatives_amount","expandable","container_height","align","height"]},"uuid":"dbdb5b13-e719-4987-7f6a-a882322bbfce","auction_id":"f9382ceb-49c2-4683-50d8-5c516c53cd69","env":"prod"}', - 'vastXml': '\n00:00:30', - 'mediaType': 'video' -}]; - -const RENDERER_DATA = { - data: JSON.parse(VIDEO_RESPONSE[0].ad) -}; -RENDERER_DATA.data.placement.unit_settings.width = '' + VIDEO_RESPONSE[0].width; -RENDERER_DATA.data.placement.unit_settings.height = RENDERER_DATA.data.placement.unit_settings.container_height = '' + VIDEO_RESPONSE[0].height; - -const REQUIRED_VIDEO_FIELDS = [ - 'requestId', - 'cpm', - 'width', - 'height', - 'ad', - 'ttl', - 'creativeId', - 'netRevenue', - 'currency', - 'vastXml', - 'mediaType' -]; - -describe('buzzoolaBidAdapter', () => { - const adapter = newBidder(spec); - - describe('inherited functions', () => { - it('exists and is a function', () => { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', () => { - it('should return true when required params found', () => { - expect(spec.isBidRequestValid(VIDEO_BID)).to.be.true; - }); - - it('should return false when required params are not passed', () => { - INVALID_BIDS.forEach(bid => { - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - }); - - describe('buildRequests', () => { - let videoBidRequests = [VIDEO_BID]; - let bannerBidRequests = [BANNER_BID]; - - const bannerRequest = spec.buildRequests(bannerBidRequests, BANNER_BID_REQUEST); - const videoRequest = spec.buildRequests(videoBidRequests, VIDEO_BID_REQUEST); - - it('sends bid request to ENDPOINT via POST', () => { - expect(videoRequest.method).to.equal('POST'); - expect(bannerRequest.method).to.equal('POST'); - }); - - it('sends bid request to correct ENDPOINT', () => { - expect(videoRequest.url).to.equal(ENDPOINT); - expect(bannerRequest.url).to.equal(ENDPOINT); - }); - - it('sends correct video bid parameters', () => { - expect(videoRequest.data).to.deep.equal(VIDEO_BID_REQUEST); - }); - - it('sends correct banner bid parameters', () => { - expect(bannerRequest.data).to.deep.equal(BANNER_BID_REQUEST); - }); - }); - - describe('interpretResponse', () => { - const noBidServerResponse = []; - const emptyResponse = ''; - - function nobidServerResponseCheck(request, response = noBidServerResponse) { - 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}); - - expect(result).to.deep.equal(response); - result.forEach(bid => { - fields.forEach(field => { - expect(bid).to.have.own.property(field); - }) - }); - } - - it('handles video nobid responses', () => { - nobidServerResponseCheck(VIDEO_BID_REQUEST); - }); - - it('handles banner nobid responses', () => { - nobidServerResponseCheck(BANNER_BID_REQUEST); - }); - - it('handles video empty responses', () => { - nobidServerResponseCheck(VIDEO_BID_REQUEST, emptyResponse); - }); - - it('handles banner empty responses', () => { - nobidServerResponseCheck(BANNER_BID_REQUEST, emptyResponse); - }); - - it('should get correct video bid response', () => { - bidServerResponseCheck(VIDEO_RESPONSE, VIDEO_BID_REQUEST, REQUIRED_VIDEO_FIELDS); - }); - - it('should get correct banner bid response', () => { - bidServerResponseCheck(BANNER_RESPONSE, BANNER_BID_REQUEST, REQUIRED_BANNER_FIELDS); - }); - }); - - describe('outstream renderer', () => { - let result; - let renderer; - - before(() => { - const adContainer = document.createElement('div'); - adContainer.id = 'adUnitCode'; - document.body.appendChild(adContainer); - - const outstreamVideoBid = deepClone(VIDEO_BID); - outstreamVideoBid.mediaTypes.video.context = 'outstream'; - - const outstreamVideoRequest = deepClone(VIDEO_BID_REQUEST); - outstreamVideoRequest.bids = [outstreamVideoBid]; - - const scriptElement = document.createElement('div'); - - const scriptStub = sinon.stub(document, 'createElement'); - scriptStub.withArgs('script').returns(scriptElement); - - result = spec.interpretResponse({body: VIDEO_RESPONSE}, {data: outstreamVideoRequest})[0]; - renderer = result.renderer; - - result.adUnitCode = 'adUnitCode'; - - scriptElement.onload && scriptElement.onload(); - - scriptStub.restore(); - }); - - it('should add renderer for outstream video', () => { - expect(result).to.have.own.property('renderer'); - }); - - it('should be instance of Renderer', () => { - expect(renderer).to.be.instanceof(Renderer); - }); - - it('should have valid src', () => { - expect(renderer.url).to.equal(RENDERER_SRC); - }); - - it('should create player instance', () => { - window.Buzzoola = { - Core: { - install: () => {} - } - }; - const spy = sinon.spy(window.Buzzoola.Core, 'install'); - executeRenderer(renderer, result); - expect(spy.called).to.be.true; - - const spyCall = spy.getCall(0); - - expect(spyCall.args[0]).to.be.instanceof(Element); - expect(spyCall.args[1]).to.deep.equal(RENDERER_DATA); - }); - }); -}); diff --git a/test/spec/modules/byplayBidAdapter_spec.js b/test/spec/modules/byplayBidAdapter_spec.js deleted file mode 100644 index 57aad403c4e..00000000000 --- a/test/spec/modules/byplayBidAdapter_spec.js +++ /dev/null @@ -1,93 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/byplayBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import * as bidderFactory from 'src/adapters/bidderFactory.js'; - -describe('byplayBidAdapter', () => { - describe('isBidRequestValid', () => { - describe('exist sectionId', () => { - const bid = { - 'bidder': 'byplay', - 'params': { - 'sectionId': '11111' - }, - }; - - it('should equal true', () => { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - }); - - describe('not exist sectionId', () => { - const bid = { - 'bidder': 'byplay', - 'params': { - }, - }; - - it('should equal false', () => { - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - }); - - describe('buildRequests', () => { - const bids = [ - { - 'bidder': 'byplay', - 'bidId': '1234', - 'params': { - 'sectionId': '1111' - }, - } - ]; - - const request = spec.buildRequests(bids); - - it('should return POST', () => { - expect(request[0].method).to.equal('POST'); - }); - - it('should return data', () => { - expect(request[0].data).to.equal('{"requestId":"1234","sectionId":"1111"}'); - }); - }); - - describe('interpretResponse', () => { - const serverResponse = { - body: { - 'cpm': 1500, - 'width': 320, - 'height': 180, - 'netRevenue': true, - 'creativeId': '1', - 'requestId': '209c1fb5ad88f5', - 'vastXml': '' - } - }; - - const bidderRequest = { - 'method': 'GET', - 'url': 'https://tasp0g98f2.execute-api.ap-northeast-1.amazonaws.com/v1/bidder', - 'data': '{"requestId":"209c1fb5ad88f5","sectionId":7986}' - }; - - const result = spec.interpretResponse(serverResponse, bidderRequest); - - it('should return Array', () => { - expect(Array.isArray(result)).to.equal(true); - }); - - it('should get the correct bid response', () => { - expect(result[0].cpm).to.equal(1500); - expect(result[0].creativeId).to.equal('1'); - expect(result[0].width).to.equal(320); - expect(result[0].height).to.equal(180); - expect(result[0].mediaType).to.equal('video'); - expect(result[0].netRevenue).to.equal(true); - expect(result[0].requestId).to.equal('209c1fb5ad88f5'); - expect(result[0].ttl).to.equal(3000); - expect(result[0].vastXml).to.equal(''); - }); - }); -}); diff --git a/test/spec/modules/c1xBidAdapter_spec.js b/test/spec/modules/c1xBidAdapter_spec.js deleted file mode 100644 index 00741abda7a..00000000000 --- a/test/spec/modules/c1xBidAdapter_spec.js +++ /dev/null @@ -1,182 +0,0 @@ -import { expect } from 'chai'; -import { c1xAdapter } from 'modules/c1xBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -const ENDPOINT = 'https://ht.c1exchange.com/ht'; -const BIDDER_CODE = 'c1x'; - -describe('C1XAdapter', function () { - const adapter = newBidder(c1xAdapter); - - describe('inherited functions', function () { - it('exists and is a function', function () { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - let bid = { - 'bidder': BIDDER_CODE, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'params': { - 'siteId': '9999' - } - }; - - it('should return true when required params are passed', function () { - expect(c1xAdapter.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not found', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'siteId': null - }; - expect(c1xAdapter.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [ - { - 'bidder': BIDDER_CODE, - 'params': { - 'siteId': '9999' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - const parseRequest = (data) => { - const parsedData = '{"' + data.replace(/=|&/g, (foundChar) => { - if (foundChar == '=') return '":"'; - else if (foundChar == '&') return '","'; - }) + '"}' - return parsedData; - }; - - it('sends bid request to ENDPOINT via GET', function () { - const request = c1xAdapter.buildRequests(bidRequests); - expect(request.url).to.equal(ENDPOINT); - expect(request.method).to.equal('GET'); - }); - - it('should generate correct bid Id tag', function () { - const request = c1xAdapter.buildRequests(bidRequests); - expect(request.bids[0].adUnitCode).to.equal('adunit-code'); - expect(request.bids[0].bidId).to.equal('30b31c1838de1e'); - }); - - it('should convert params to proper form and attach to request', function () { - const request = c1xAdapter.buildRequests(bidRequests); - const originalPayload = parseRequest(request.data); - const payloadObj = JSON.parse(originalPayload); - expect(payloadObj.adunits).to.equal('1'); - expect(payloadObj.a1s).to.equal('300x250,300x600'); - expect(payloadObj.a1).to.equal('adunit-code'); - expect(payloadObj.site).to.equal('9999'); - }); - - it('should convert floor price to proper form and attach to request', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - 'params': { - 'siteId': '9999', - 'floorPriceMap': { - '300x250': 4.35 - } - } - }); - const request = c1xAdapter.buildRequests([bidRequest]); - const originalPayload = parseRequest(request.data); - const payloadObj = JSON.parse(originalPayload); - expect(payloadObj.a1p).to.equal('4.35'); - }); - - it('should convert pageurl to proper form and attach to request', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - 'params': { - 'siteId': '9999', - 'pageurl': 'https://c1exchange.com/' - } - }); - const request = c1xAdapter.buildRequests([bidRequest]); - const originalPayload = parseRequest(request.data); - const payloadObj = JSON.parse(originalPayload); - expect(payloadObj.pageurl).to.equal('https://c1exchange.com/'); - }); - - it('should convert GDPR Consent to proper form and attach to request', function () { - let consentString = 'BOP2gFWOQIFovABABAENBGAAAAAAMw'; - let bidderRequest = { - 'bidderCode': 'c1x', - 'gdprConsent': { - 'consentString': consentString, - 'gdprApplies': true - } - } - bidderRequest.bids = bidRequests; - - const request = c1xAdapter.buildRequests(bidRequests, bidderRequest); - const originalPayload = parseRequest(request.data); - const payloadObj = JSON.parse(originalPayload); - expect(payloadObj['consent_string']).to.equal('BOP2gFWOQIFovABABAENBGAAAAAAMw'); - expect(payloadObj['consent_required']).to.equal('true'); - }); - }); - - describe('interpretResponse', function () { - let response = { - 'bid': true, - 'cpm': 1.5, - 'ad': '', - 'width': 300, - 'height': 250, - 'crid': '8888', - 'adId': 'c1x-test', - 'bidType': 'GROSS_BID' - }; - - it('should get correct bid response', function () { - let expectedResponse = [ - { - width: 300, - height: 250, - cpm: 1.5, - ad: '', - creativeId: '8888', - currency: 'USD', - ttl: 300, - netRevenue: false, - requestId: 'yyyy' - } - ]; - let bidderRequest = {}; - bidderRequest.bids = [ - { adUnitCode: 'c1x-test', - bidId: 'yyyy' } - ]; - let result = c1xAdapter.interpretResponse({ body: [response] }, bidderRequest); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('handles nobid responses', function () { - let response = { - bid: false, - adId: 'c1x-test' - }; - let bidderRequest = {}; - let result = c1xAdapter.interpretResponse({ body: [response] }, bidderRequest); - expect(result.length).to.equal(0); - }); - }); -}); diff --git a/test/spec/modules/categoryTranslation_spec.js b/test/spec/modules/categoryTranslation_spec.js deleted file mode 100644 index 2301d6aab1b..00000000000 --- a/test/spec/modules/categoryTranslation_spec.js +++ /dev/null @@ -1,111 +0,0 @@ -import { getAdserverCategoryHook, initTranslation, storage } from 'modules/categoryTranslation.js'; -import { config } from 'src/config.js'; -import * as utils from 'src/utils.js'; -import { expect } from 'chai'; - -describe('category translation', function () { - let fakeTranslationServer; - let getLocalStorageStub; - - beforeEach(function () { - fakeTranslationServer = sinon.fakeServer.create(); - getLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage'); - }); - - afterEach(function() { - fakeTranslationServer.reset(); - getLocalStorageStub.restore(); - config.resetConfig(); - }); - - it('should translate iab category to adserver category', function () { - config.setConfig({ - 'adpod': { - 'brandCategoryExclusion': true - } - }); - getLocalStorageStub.returns(JSON.stringify({ - 'mapping': { - 'iab-1': { - 'id': 1, - 'name': 'sample' - } - } - })); - let bid = { - meta: { - primaryCatId: 'iab-1' - } - } - getAdserverCategoryHook(sinon.spy(), 'code', bid); - expect(bid.meta.adServerCatId).to.equal(1); - }); - - it('should set adserverCatId to undefined if not found in mapping file', function() { - config.setConfig({ - 'adpod': { - 'brandCategoryExclusion': true - } - }); - getLocalStorageStub.returns(JSON.stringify({ - 'mapping': { - 'iab-1': { - 'id': 1, - 'name': 'sample' - } - } - })); - let bid = { - meta: { - primaryCatId: 'iab-2' - } - } - getAdserverCategoryHook(sinon.spy(), 'code', bid); - expect(bid.meta.adServerCatId).to.equal(undefined); - }); - - it('should not make ajax call to update mapping file if data found in localstorage and is not expired', function () { - let clock = sinon.useFakeTimers(utils.timestamp()); - getLocalStorageStub.returns(JSON.stringify({ - lastUpdated: utils.timestamp(), - mapping: { - 'iab-1': '1' - } - })); - initTranslation(); - expect(fakeTranslationServer.requests.length).to.equal(0); - clock.restore(); - }); - - it('should make ajax call to update mapping file if data found in localstorage is expired', function () { - let clock = sinon.useFakeTimers(utils.timestamp()); - getLocalStorageStub.returns(JSON.stringify({ - lastUpdated: utils.timestamp() - 2 * 24 * 60 * 60 * 1000, - mapping: { - 'iab-1': '1' - } - })); - initTranslation(); - expect(fakeTranslationServer.requests.length).to.equal(1); - clock.restore(); - }); - - it('should use default mapping file if publisher has not defined in config', function () { - getLocalStorageStub.returns(null); - initTranslation('http://sample.com', 'somekey'); - expect(fakeTranslationServer.requests.length).to.equal(1); - expect(fakeTranslationServer.requests[0].url).to.equal('http://sample.com'); - }); - - it('should use publisher defined mapping file', function () { - config.setConfig({ - 'brandCategoryTranslation': { - 'translationFile': 'http://sample.com' - } - }); - getLocalStorageStub.returns(null); - initTranslation('http://sample.com', 'somekey'); - expect(fakeTranslationServer.requests.length).to.equal(2); - expect(fakeTranslationServer.requests[0].url).to.equal('http://sample.com'); - }); -}); diff --git a/test/spec/modules/ccxBidAdapter_spec.js b/test/spec/modules/ccxBidAdapter_spec.js deleted file mode 100644 index ef86b391e39..00000000000 --- a/test/spec/modules/ccxBidAdapter_spec.js +++ /dev/null @@ -1,437 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/ccxBidAdapter.js'; -import * as utils from 'src/utils.js'; - -describe('ccxAdapter', function () { - let bids = [ - { - adUnitCode: 'banner', - auctionId: '0b9de793-8eda-481e-a548-c187d58b28d9', - bidId: '2e56e1af51a5d7', - bidder: 'ccx', - bidderRequestId: '17e7b9f58a607e', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - params: { - placementId: 607 - }, - sizes: [[300, 250]], - transactionId: 'aefddd38-cfa0-48ab-8bdd-325de4bab5f9' - }, - { - adUnitCode: 'video', - auctionId: '0b9de793-8eda-481e-a548-c187d58b28d9', - bidId: '3u94t90ut39tt3t', - bidder: 'ccx', - bidderRequestId: '23ur20r239r2r', - mediaTypes: { - video: { - playerSize: [[640, 480]] - } - }, - params: { - placementId: 608 - }, - sizes: [[640, 480]], - transactionId: 'aefddd38-cfa0-48ab-8bdd-325de4bab5f9' - } - ]; - describe('isBidRequestValid', function () { - it('Valid bid requests', function () { - expect(spec.isBidRequestValid(bids[0])).to.be.true; - expect(spec.isBidRequestValid(bids[1])).to.be.true; - }); - it('Invalid bid reqeusts - no placementId', function () { - let bidsClone = utils.deepClone(bids); - bidsClone[0].params = undefined; - expect(spec.isBidRequestValid(bidsClone[0])).to.be.false; - }); - it('Invalid bid reqeusts - invalid banner sizes', function () { - let bidsClone = utils.deepClone(bids); - bidsClone[0].mediaTypes.banner.sizes = [300, 250]; - expect(spec.isBidRequestValid(bidsClone[0])).to.be.false; - bidsClone[0].mediaTypes.banner.sizes = [[300, 250], [750]]; - expect(spec.isBidRequestValid(bidsClone[0])).to.be.false; - bidsClone[0].mediaTypes.banner.sizes = []; - expect(spec.isBidRequestValid(bidsClone[0])).to.be.false; - }); - it('Invalid bid reqeusts - invalid video sizes', function () { - let bidsClone = utils.deepClone(bids); - bidsClone[1].mediaTypes.video.playerSize = []; - expect(spec.isBidRequestValid(bidsClone[1])).to.be.false; - bidsClone[1].mediaTypes.video.sizes = [640, 480]; - expect(spec.isBidRequestValid(bidsClone[1])).to.be.false; - }); - it('Valid bid reqeust - old style sizes', function () { - let bidsClone = utils.deepClone(bids); - delete (bidsClone[0].mediaTypes); - delete (bidsClone[1].mediaTypes); - expect(spec.isBidRequestValid(bidsClone[0])).to.be.true; - expect(spec.isBidRequestValid(bidsClone[1])).to.be.true; - bidsClone[0].sizes = [300, 250]; - expect(spec.isBidRequestValid(bidsClone[0])).to.be.true; - }); - }); - describe('buildRequests', function () { - it('No valid bids', function () { - expect(spec.buildRequests([])).to.be.undefined; - }); - - it('Valid bid request - default', function () { - let response = spec.buildRequests(bids, {bids}); - expect(response).to.be.not.empty; - expect(response.data).to.be.not.empty; - - let data = JSON.parse(response.data); - - expect(data).to.be.an('object'); - expect(data).to.have.keys('site', 'imp', 'id', 'ext', 'device'); - - let imps = [ - { - banner: { - format: [ - { - w: 300, - h: 250 - } - ] - }, - ext: { - pid: 607 - }, - id: '2e56e1af51a5d7', - secure: 1 - }, - { - video: { - w: 640, - h: 480, - protocols: [2, 3, 5, 6], - mimes: ['video/mp4', 'video/x-flv'], - playbackmethod: [1, 2, 3, 4], - skip: 0 - }, - id: '3u94t90ut39tt3t', - secure: 1, - ext: { - pid: 608 - } - } - ]; - expect(data.imp).to.deep.have.same.members(imps); - }); - - it('Valid bid request - custom', function () { - let bidsClone = utils.deepClone(bids); - let imps = [ - { - banner: { - format: [ - { - w: 300, - h: 250 - } - ] - }, - ext: { - pid: 607 - }, - id: '2e56e1af51a5d7', - secure: 1 - }, - { - video: { - w: 640, - h: 480, - protocols: [5, 6], - mimes: ['video/mp4'], - playbackmethod: [3], - skip: 1, - skipafter: 5 - }, - id: '3u94t90ut39tt3t', - secure: 1, - ext: { - pid: 608 - } - } - ]; - - bidsClone[1].params.video = {}; - bidsClone[1].params.video.protocols = [5, 6]; - bidsClone[1].params.video.mimes = ['video/mp4']; - bidsClone[1].params.video.playbackmethod = [3]; - bidsClone[1].params.video.skip = 1; - bidsClone[1].params.video.skipafter = 5; - - let response = spec.buildRequests(bidsClone, {'bids': bidsClone}); - let data = JSON.parse(response.data); - - expect(data.imp).to.deep.have.same.members(imps); - }); - it('Valid bid request - sizes old style', function () { - let bidsClone = utils.deepClone(bids); - delete (bidsClone[0].mediaTypes); - delete (bidsClone[1].mediaTypes); - bidsClone[0].mediaType = 'banner'; - bidsClone[1].mediaType = 'video'; - - let imps = [ - { - banner: { - format: [ - { - w: 300, - h: 250 - } - ] - }, - ext: { - pid: 607 - }, - id: '2e56e1af51a5d7', - secure: 1 - }, - { - video: { - w: 640, - h: 480, - protocols: [2, 3, 5, 6], - mimes: ['video/mp4', 'video/x-flv'], - playbackmethod: [1, 2, 3, 4], - skip: 0 - }, - id: '3u94t90ut39tt3t', - secure: 1, - ext: { - pid: 608 - } - } - ]; - - let response = spec.buildRequests(bidsClone, {'bids': bidsClone}); - let data = JSON.parse(response.data); - - expect(data.imp).to.deep.have.same.members(imps); - }); - it('Valid bid request - sizes old style - no media type', function () { - let bidsClone = utils.deepClone(bids); - delete (bidsClone[0].mediaTypes); - delete (bidsClone[1]); - - let imps = [ - { - banner: { - format: [ - { - w: 300, - h: 250 - } - ] - }, - ext: { - pid: 607 - }, - id: '2e56e1af51a5d7', - secure: 1 - } - ]; - - let response = spec.buildRequests(bidsClone, {'bids': bidsClone}); - let data = JSON.parse(response.data); - - expect(data.imp).to.deep.have.same.members(imps); - }); - }); - - describe('GDPR conformity', function () { - it('should transmit correct data', function () { - let bidsClone = utils.deepClone(bids); - let gdprConsent = { - consentString: 'awefasdfwefasdfasd', - gdprApplies: true - }; - let response = spec.buildRequests(bidsClone, {'bids': bidsClone, 'gdprConsent': gdprConsent}); - let data = JSON.parse(response.data); - - expect(data.regs.ext.gdpr).to.equal(1); - expect(data.user.ext.consent).to.equal('awefasdfwefasdfasd'); - }); - }); - - describe('GDPR absence conformity', function () { - it('should transmit correct data', function () { - let response = spec.buildRequests(bids, {bids}); - let data = JSON.parse(response.data); - - expect(data.regs).to.be.undefined; - expect(data.user).to.be.undefined; - }); - }); - - let response = { - id: '0b9de793-8eda-481e-a548-c187d58b28d9', - seatbid: [ - { - bid: [ - { - id: '2e56e1af51a5d7_221', - impid: '2e56e1af51a5d7', - price: 8.1, - adid: '221', - adm: '', - adomain: ['clickonometrics.com'], - crid: '221', - w: 300, - h: 250, - ext: { - type: 'standard' - } - }, - { - id: '2e56e1af51a5d8_222', - impid: '2e56e1af51a5d8', - price: 5.68, - adid: '222', - adm: '', - adomain: ['clickonometrics.com'], - crid: '222', - w: 640, - h: 480, - ext: { - type: 'video' - } - } - ] - } - ], - cur: 'PLN', - ext: { - ttl: 5, - usersync: [ - { - type: 'image', - url: 'http://foo.sync?param=1' - }, - { - type: 'iframe', - url: 'http://foo.sync?param=2' - } - ] - } - }; - - describe('interpretResponse', function () { - it('Valid bid response - multi', function () { - let bidResponses = [ - { - requestId: '2e56e1af51a5d7', - cpm: 8.1, - width: 300, - height: 250, - creativeId: '221', - netRevenue: false, - ttl: 5, - currency: 'PLN', - ad: '', - meta: { - advertiserDomains: ['clickonometrics.com'] - } - }, - { - requestId: '2e56e1af51a5d8', - cpm: 5.68, - width: 640, - height: 480, - creativeId: '222', - netRevenue: false, - ttl: 5, - currency: 'PLN', - vastXml: '', - meta: { - advertiserDomains: ['clickonometrics.com'] - } - } - ]; - expect(spec.interpretResponse({body: response})).to.deep.have.same.members(bidResponses); - }); - - it('Valid bid response - single', function () { - delete response.seatbid[0].bid[1]; - let bidResponses = [ - { - requestId: '2e56e1af51a5d7', - cpm: 8.1, - width: 300, - height: 250, - creativeId: '221', - netRevenue: false, - ttl: 5, - currency: 'PLN', - ad: '', - meta: { - advertiserDomains: ['clickonometrics.com'] - } - } - ]; - expect(spec.interpretResponse({body: response})).to.deep.have.same.members(bidResponses); - }); - - it('Empty bid response', function () { - expect(spec.interpretResponse({})).to.be.empty; - }); - }); - describe('getUserSyncs', function () { - it('Valid syncs - all', function () { - let syncOptions = { - iframeEnabled: true, - pixelEnabled: true - }; - - let expectedSyncs = [ - { - type: 'image', - url: 'http://foo.sync?param=1' - }, - { - type: 'iframe', - url: 'http://foo.sync?param=2' - } - ]; - expect(spec.getUserSyncs(syncOptions, [{body: response}])).to.deep.have.same.members(expectedSyncs); - }); - - it('Valid syncs - only image', function () { - let syncOptions = { - iframeEnabled: false, - pixelEnabled: true - }; - let expectedSyncs = [ - { - type: 'image', url: 'http://foo.sync?param=1' - } - ]; - expect(spec.getUserSyncs(syncOptions, [{body: response}])).to.deep.have.same.members(expectedSyncs); - }); - - it('Valid syncs - only iframe', function () { - let syncOptions = {iframeEnabled: true, pixelEnabled: false}; - let expectedSyncs = [ - { - type: 'iframe', url: 'http://foo.sync?param=2' - } - ]; - expect(spec.getUserSyncs(syncOptions, [{body: response}])).to.deep.have.same.members(expectedSyncs); - }); - - it('Valid syncs - empty', function () { - let syncOptions = {iframeEnabled: true, pixelEnabled: true}; - response.ext.usersync = {}; - expect(spec.getUserSyncs(syncOptions, [{body: response}])).to.be.empty; - }); - }); -}); diff --git a/test/spec/modules/cedatoBidAdapter_spec.js b/test/spec/modules/cedatoBidAdapter_spec.js deleted file mode 100644 index a7f4875afff..00000000000 --- a/test/spec/modules/cedatoBidAdapter_spec.js +++ /dev/null @@ -1,133 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/cedatoBidAdapter.js'; - -describe('the cedato adapter', function () { - function getValidBidObject() { - return { - bidId: '2f4a613a702b6c', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - params: { - player_id: 1450133326, - } - }; - }; - - describe('isBidRequestValid', function() { - var bid; - - beforeEach(function() { - bid = getValidBidObject(); - }); - - it('should fail validation if the bid isn\'t defined or not an object', function() { - var result = spec.isBidRequestValid(); - - expect(result).to.equal(false); - - result = spec.isBidRequestValid('not an object'); - - expect(result).to.equal(false); - }); - }); - - describe('buildRequests', function() { - var bid, bidRequestObj; - - beforeEach(function() { - bid = getValidBidObject(); - bidRequestObj = { - refererInfo: {referer: 'prebid.js'}, - gdprConsent: { - consentString: 'test-string', - gdprApplies: true - }, - uspConsent: '1NYN' - }; - }); - - it('should build a very basic request', function() { - var [request] = spec.buildRequests([bid], bidRequestObj); - expect(request.method).to.equal('POST'); - }); - - it('should pass gdpr and usp strings to server', function() { - var [request] = spec.buildRequests([bid], bidRequestObj); - var payload = JSON.parse(request.data); - expect(payload.gdpr_consent).to.not.be.undefined; - expect(payload.gdpr_consent.consent_string).to.equal(bidRequestObj.gdprConsent.consentString); - expect(payload.gdpr_consent.consent_required).to.equal(bidRequestObj.gdprConsent.gdprApplies); - expect(payload.us_privacy).to.equal(bidRequestObj.uspConsent); - }); - }); - - describe('interpretResponse', function() { - var bid, serverResponse, bidderRequest; - - beforeEach(function() { - bid = getValidBidObject(); - serverResponse = { - body: { - bidid: '0.36157306192821', - seatbid: [ - { - seat: '0', - bid: [{ - gp: { - 'negative': 0.496954, - 'positive': 0.503046, - 'class': '0' - }, - id: '0.75549202124378', - adomain: 'cedato.com', - uuid: bid.bidId, - crid: '1450133326', - adm: "
\n\n\n", - h: 250, - w: 300, - price: '0.1' - }] - } - ], - cur: 'USD' - } - }; - bidderRequest = { - bids: [bid] - }; - }); - - it('should return an array of bid responses', function() { - var responses = spec.interpretResponse(serverResponse, {bidderRequest}); - expect(responses).to.be.an('array').with.length(1); - }); - }); - - describe('getUserSyncs', function() { - var bid; - - beforeEach(function() { - bid = getValidBidObject(); - }); - - it('should sync with iframe', function() { - var syncs = spec.getUserSyncs({ iframeEnabled: true }, null, { - consentString: '', - gdprApplies: true - }); - - expect(syncs).to.be.an('array').with.length(1); - expect(syncs[0].type).to.equal('iframe'); - }); - - it('should sync with image', function() { - var syncs = spec.getUserSyncs({ pixelEnabled: true }); - - expect(syncs).to.be.an('array').with.length(1); - expect(syncs[0].type).to.equal('image'); - }); - }); -}); diff --git a/test/spec/modules/cleanmedianetBidAdapter_spec.js b/test/spec/modules/cleanmedianetBidAdapter_spec.js deleted file mode 100644 index 5438f6c8701..00000000000 --- a/test/spec/modules/cleanmedianetBidAdapter_spec.js +++ /dev/null @@ -1,597 +0,0 @@ -import {expect} from 'chai'; -import {spec, helper} from 'modules/cleanmedianetBidAdapter.js'; -import * as utils from 'src/utils.js'; -import {newBidder} from '../../../src/adapters/bidderFactory.js'; - -const supplyPartnerId = '123'; -const adapter = newBidder(spec); -describe('CleanmedianetAdapter', function () { - describe('Is String start with search ', function () { - it('check if a string started with', function () { - expect(helper.startsWith('cleanmediaads.com', 'cleanmediaads')).to.equal( - true - ); - }); - }); - - describe('inherited functions', function() { - it('exists and is a function', function() { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function() { - it('should validate supply-partner ID', function() { - expect(spec.isBidRequestValid({ params: {} })).to.equal(false); - expect( - spec.isBidRequestValid({ params: { supplyPartnerId: 123 } }) - ).to.equal(false); - expect( - spec.isBidRequestValid({ params: { supplyPartnerId: '123' } }) - ).to.equal(true); - }); - - it('should validate bid floor', function() { - expect( - spec.isBidRequestValid({ params: { supplyPartnerId: '123' } }) - ).to.equal(true); // bidfloor has a default - expect( - spec.isBidRequestValid({ - params: { supplyPartnerId: '123', bidfloor: '123' } - }) - ).to.equal(false); - expect( - spec.isBidRequestValid({ - params: { supplyPartnerId: '123', bidfloor: 0.1 } - }) - ).to.equal(true); - }); - - it('should validate adpos', function() { - expect( - spec.isBidRequestValid({ params: { supplyPartnerId: '123' } }) - ).to.equal(true); // adpos has a default - expect( - spec.isBidRequestValid({ - params: { supplyPartnerId: '123', adpos: '123' } - }) - ).to.equal(false); - expect( - spec.isBidRequestValid({ - params: { supplyPartnerId: '123', adpos: 0.1 } - }) - ).to.equal(true); - }); - - it('should validate instl', function() { - expect( - spec.isBidRequestValid({ params: { supplyPartnerId: '123' } }) - ).to.equal(true); // adpos has a default - expect( - spec.isBidRequestValid({ - params: { supplyPartnerId: '123', instl: '123' } - }) - ).to.equal(false); - expect( - spec.isBidRequestValid({ - params: { supplyPartnerId: '123', instl: -1 } - }) - ).to.equal(false); - expect( - spec.isBidRequestValid({ params: { supplyPartnerId: '123', instl: 0 } }) - ).to.equal(true); - expect( - spec.isBidRequestValid({ params: { supplyPartnerId: '123', instl: 1 } }) - ).to.equal(true); - expect( - spec.isBidRequestValid({ params: { supplyPartnerId: '123', instl: 2 } }) - ).to.equal(false); - }); - }); - - describe('buildRequests', function() { - const bidRequest = { - adUnitCode: 'adunit-code', - auctionId: '1d1a030790a475', - mediaTypes: { - banner: {} - }, - params: { - supplyPartnerId: supplyPartnerId - }, - sizes: [[300, 250], [300, 600]], - transactionId: 'a123456789', - refererInfo: { referer: 'https://examplereferer.com' }, - gdprConsent: { - consentString: 'some string', - gdprApplies: true - } - }; - it('returns an array', function() { - let response; - response = spec.buildRequests([]); - expect(Array.isArray(response)).to.equal(true); - expect(response.length).to.equal(0); - 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' - }); - response = spec.buildRequests([adUnit1, adUnit2], bidRequest); - expect(Array.isArray(response)).to.equal(true); - expect(response.length).to.equal(2); - }); - - it('builds request correctly', function() { - let bidRequest2 = utils.deepClone(bidRequest); - bidRequest2.refererInfo.referer = 'https://www.test.com/page.html'; - let response = spec.buildRequests([bidRequest], bidRequest2)[0]; - expect(response.data.site.domain).to.equal('www.test.com'); - expect(response.data.site.page).to.equal('https://www.test.com/page.html'); - expect(response.data.site.ref).to.equal('https://www.test.com/page.html'); - expect(response.data.imp.length).to.equal(1); - expect(response.data.imp[0].id).to.equal(bidRequest.transactionId); - expect(response.data.imp[0].instl).to.equal(0); - expect(response.data.imp[0].tagid).to.equal(bidRequest.adUnitCode); - expect(response.data.imp[0].bidfloor).to.equal(0); - expect(response.data.imp[0].bidfloorcur).to.equal('USD'); - const bidRequestWithInstlEquals1 = utils.deepClone(bidRequest); - bidRequestWithInstlEquals1.params.instl = 1; - response = spec.buildRequests( - [bidRequestWithInstlEquals1], - bidRequest2 - )[0]; - expect(response.data.imp[0].instl).to.equal( - bidRequestWithInstlEquals1.params.instl - ); - const bidRequestWithInstlEquals0 = utils.deepClone(bidRequest); - bidRequestWithInstlEquals0.params.instl = 1; - response = spec.buildRequests( - [bidRequestWithInstlEquals0], - bidRequest2 - )[0]; - expect(response.data.imp[0].instl).to.equal( - bidRequestWithInstlEquals0.params.instl - ); - const bidRequestWithBidfloorEquals1 = utils.deepClone(bidRequest); - bidRequestWithBidfloorEquals1.params.bidfloor = 1; - response = spec.buildRequests( - [bidRequestWithBidfloorEquals1], - bidRequest2 - )[0]; - expect(response.data.imp[0].bidfloor).to.equal( - bidRequestWithBidfloorEquals1.params.bidfloor - ); - }); - - it('builds request banner object correctly', function() { - let response; - const bidRequestWithBanner = utils.deepClone(bidRequest); - bidRequestWithBanner.mediaTypes = { - banner: { - sizes: [[300, 250], [120, 600]] - } - }; - response = spec.buildRequests([bidRequestWithBanner], bidRequest)[0]; - expect(response.data.imp[0].banner.w).to.equal( - bidRequestWithBanner.mediaTypes.banner.sizes[0][0] - ); - expect(response.data.imp[0].banner.h).to.equal( - bidRequestWithBanner.mediaTypes.banner.sizes[0][1] - ); - expect(response.data.imp[0].banner.pos).to.equal(0); - const bidRequestWithPosEquals1 = utils.deepClone(bidRequestWithBanner); - bidRequestWithPosEquals1.params.pos = 1; - response = spec.buildRequests([bidRequestWithPosEquals1], bidRequest)[0]; - expect(response.data.imp[0].banner.pos).to.equal( - bidRequestWithPosEquals1.params.pos - ); - }); - - it('builds request video object correctly', function() { - let response; - const bidRequestWithVideo = utils.deepClone(bidRequest); - bidRequestWithVideo.mediaTypes = { - video: { - sizes: [[300, 250], [120, 600]] - } - }; - response = spec.buildRequests([bidRequestWithVideo], bidRequest)[0]; - expect(response.data.imp[0].video.w).to.equal( - bidRequestWithVideo.mediaTypes.video.sizes[0][0] - ); - expect(response.data.imp[0].video.h).to.equal( - bidRequestWithVideo.mediaTypes.video.sizes[0][1] - ); - expect(response.data.imp[0].video.pos).to.equal(0); - const bidRequestWithPosEquals1 = utils.deepClone(bidRequestWithVideo); - bidRequestWithPosEquals1.params.pos = 1; - response = spec.buildRequests([bidRequestWithPosEquals1], bidRequest)[0]; - expect(response.data.imp[0].video.pos).to.equal( - bidRequestWithPosEquals1.params.pos - ); - }); - - it('builds request video object correctly with context', function() { - let response; - const bidRequestWithVideo = utils.deepClone(bidRequest); - bidRequestWithVideo.mediaTypes = { - video: { - context: 'instream' - } - }; - response = spec.buildRequests([bidRequestWithVideo], bidRequest)[0]; - expect(response.data.imp[0].video.ext.context).to.equal('instream'); - bidRequestWithVideo.mediaTypes.video.context = 'outstream'; - - const bidRequestWithPosEquals1 = utils.deepClone(bidRequestWithVideo); - bidRequestWithPosEquals1.mediaTypes.video.context = 'outstream'; - response = spec.buildRequests([bidRequestWithPosEquals1], bidRequest)[0]; - expect(response.data.imp[0].video.ext.context).to.equal('outstream'); - - const bidRequestWithPosEquals2 = utils.deepClone(bidRequestWithVideo); - bidRequestWithPosEquals2.mediaTypes.video.context = null; - response = spec.buildRequests([bidRequestWithPosEquals2], bidRequest)[0]; - expect(response.data.imp[0].video.ext.context).to.equal(null); - }); - it('builds request video object correctly with multi-dimensions size array', function () { - let bidRequestWithVideo = utils.deepClone(bidRequest); - bidRequestWithVideo.mediaTypes.video = { - playerSize: [[304, 254], [305, 255]], - context: 'instream' - }; - - let response = spec.buildRequests([bidRequestWithVideo], bidRequest)[0]; - expect(response.data.imp[1].video.w).to.equal(304); - expect(response.data.imp[1].video.h).to.equal(254); - - bidRequestWithVideo = utils.deepClone(bidRequest); - bidRequestWithVideo.mediaTypes.video = { - playerSize: [304, 254] - }; - - response = spec.buildRequests([bidRequestWithVideo], bidRequest)[0]; - expect(response.data.imp[1].video.w).to.equal(304); - expect(response.data.imp[1].video.h).to.equal(254); - }); - - it('builds request with gdpr consent', function() { - let response = spec.buildRequests([bidRequest], bidRequest)[0]; - expect(response.data.ext).to.have.property('gdpr_consent'); - expect(response.data.ext.gdpr_consent.consent_string).to.equal( - 'some string' - ); - expect(response.data.ext.gdpr_consent.consent_required).to.equal(true); - }); - }); - - describe('interpretResponse', function() { - const bannerBidRequest = { - adUnitCode: 'adunit-code', - auctionId: '1d1a030790a475', - mediaTypes: { - banner: {} - }, - params: { - supplyPartnerId: supplyPartnerId - }, - sizes: [[300, 250], [300, 600]], - transactionId: 'a123456789', - bidId: '111', - refererInfo: { referer: 'https://examplereferer.com' } - }; - - const videoBidRequest = { - adUnitCode: 'adunit-code', - auctionId: '1d1a030790a475', - mediaTypes: { - video: {} - }, - params: { - supplyPartnerId: supplyPartnerId - }, - sizes: [[300, 250], [300, 600]], - transactionId: 'a123456789', - bidId: '111', - refererInfo: { referer: 'https://examplereferer.com' } - }; - - const rtbResponse = { - id: 'imp_5b05b9fde4b09084267a556f', - bidid: 'imp_5b05b9fde4b09084267a556f', - cur: 'USD', - ext: { - utrk: [ - { type: 'iframe', url: '//bidder.cleanmediaads.com/user/sync/1' }, - { type: 'image', url: '//bidder.cleanmediaads.com/user/sync/2' } - ] - }, - seatbid: [ - { - seat: 'seat1', - group: 0, - bid: [ - { - id: '0', - impid: '1', - price: 2.016, - adid: '579ef31bfa788b9d2000d562', - nurl: - 'https://bidder.cleanmediaads.com/pix/monitoring/win_notice/imp_5b05b9fde4b09084267a556f/im.gif?r=imp_5b05b9fde4b09084267a556f&i=1&a=579ef31bfa788b9d2000d562&b=0', - adm: - '', - adomain: ['aaa.com'], - cid: '579ef268fa788b9d2000d55c', - crid: '579ef31bfa788b9d2000d562', - attr: [], - h: 600, - w: 120, - ext: { - vast_url: 'https://my.vast.com', - utrk: [{ type: 'iframe', url: '//p.partner1.io/user/sync/1' }] - } - } - ] - }, - { - seat: 'seat2', - group: 0, - bid: [ - { - id: '1', - impid: '1', - price: 3, - adid: '542jlhdfd2112jnjf3x', - nurl: - 'https://bidder.cleanmediaads.com/pix/monitoring/win_notice/imp_5b05b9fde4b09084267a556f/im.gif?r=imp_5b05b9fde4b09084267a556f&i=1&a=579ef31bfa788b9d2000d562&b=0', - adm: - ' ', - adomain: ['bbb.com'], - cid: 'fgdlwjh2498ydjhg1', - crid: 'kjh34297ydh2133d', - attr: [], - h: 250, - w: 300, - ext: { - utrk: [{ type: 'image', url: '//p.partner2.io/user/sync/1' }] - } - } - ] - } - ] - }; - - it('returns an empty array on missing response', function() { - let response; - - response = spec.interpretResponse(undefined, { - bidRequest: bannerBidRequest - }); - expect(Array.isArray(response)).to.equal(true); - expect(response.length).to.equal(0); - - response = spec.interpretResponse({}, { bidRequest: bannerBidRequest }); - expect(Array.isArray(response)).to.equal(true); - expect(response.length).to.equal(0); - }); - - it('aggregates banner bids from all seat bids', function() { - const response = spec.interpretResponse( - { body: rtbResponse }, - { bidRequest: bannerBidRequest } - ); - expect(Array.isArray(response)).to.equal(true); - expect(response.length).to.equal(1); - - const ad0 = response[0]; - expect(ad0.requestId).to.equal(bannerBidRequest.bidId); - expect(ad0.cpm).to.equal(rtbResponse.seatbid[1].bid[0].price); - expect(ad0.width).to.equal(rtbResponse.seatbid[1].bid[0].w); - expect(ad0.height).to.equal(rtbResponse.seatbid[1].bid[0].h); - expect(ad0.ttl).to.equal(360); - expect(ad0.creativeId).to.equal(rtbResponse.seatbid[1].bid[0].crid); - expect(ad0.netRevenue).to.equal(true); - expect(ad0.currency).to.equal( - rtbResponse.seatbid[1].bid[0].cur || rtbResponse.cur || 'USD' - ); - expect(ad0.ad).to.equal(rtbResponse.seatbid[1].bid[0].adm); - expect(ad0.vastXml).to.be.an('undefined'); - expect(ad0.vastUrl).to.be.an('undefined'); - }); - - it('aggregates video bids from all seat bids', function() { - const response = spec.interpretResponse( - { body: rtbResponse }, - { bidRequest: videoBidRequest } - ); - expect(Array.isArray(response)).to.equal(true); - expect(response.length).to.equal(1); - - const ad0 = response[0]; - expect(ad0.requestId).to.equal(videoBidRequest.bidId); - expect(ad0.cpm).to.equal(rtbResponse.seatbid[0].bid[0].price); - expect(ad0.width).to.equal(rtbResponse.seatbid[0].bid[0].w); - expect(ad0.height).to.equal(rtbResponse.seatbid[0].bid[0].h); - expect(ad0.ttl).to.equal(360); - expect(ad0.creativeId).to.equal(rtbResponse.seatbid[0].bid[0].crid); - expect(ad0.netRevenue).to.equal(true); - expect(ad0.currency).to.equal( - rtbResponse.seatbid[0].bid[0].cur || rtbResponse.cur || 'USD' - ); - expect(ad0.ad).to.be.an('undefined'); - expect(ad0.vastXml).to.equal(rtbResponse.seatbid[0].bid[0].adm); - expect(ad0.vastUrl).to.equal(rtbResponse.seatbid[0].bid[0].ext.vast_url); - }); - - it('aggregates user-sync pixels', function() { - 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); - expect(response[0].url).to.equal( - rtbResponse.ext.utrk[0].url + '?gc=missing' - ); - expect(response[1].type).to.equal(rtbResponse.ext.utrk[1].type); - expect(response[1].url).to.equal( - rtbResponse.ext.utrk[1].url + '?gc=missing' - ); - expect(response[2].type).to.equal( - rtbResponse.seatbid[0].bid[0].ext.utrk[0].type - ); - expect(response[2].url).to.equal( - rtbResponse.seatbid[0].bid[0].ext.utrk[0].url + '?gc=missing' - ); - expect(response[3].type).to.equal( - rtbResponse.seatbid[1].bid[0].ext.utrk[0].type - ); - expect(response[3].url).to.equal( - rtbResponse.seatbid[1].bid[0].ext.utrk[0].url + '?gc=missing' - ); - }); - - it('supports configuring outstream renderers', function() { - const videoResponse = { - id: '64f32497-b2f7-48ec-9205-35fc39894d44', - bidid: 'imp_5c24924de4b0d106447af333', - cur: 'USD', - seatbid: [ - { - seat: '3668', - group: 0, - bid: [ - { - id: 'gb_1', - impid: 'afbb5852-7cea-4a81-aa9a-a41aab505c23', - price: 5.0, - adid: '1274', - nurl: - 'https://bidder.cleanmediaads.com/pix/1275/win_notice/imp_5c24924de4b0d106447af333/im.gif?r=imp_5c24924de4b0d106447af333&i=afbb5852-7cea-4a81-aa9a-a41aab505c23&a=1274&b=gb_1', - adomain: [], - adm: - '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n', - cid: '3668', - crid: '1274', - cat: [], - attr: [], - h: 250, - w: 300, - ext: { - vast_url: - 'https://bidder.cleanmediaads.com/pix/1275/vast_o/imp_5c24924de4b0d106447af333/im.xml?r=imp_5c24924de4b0d106447af333&i=afbb5852-7cea-4a81-aa9a-a41aab505c23&a=1274&b=gb_1&w=300&h=250&vatu=aHR0cHM6Ly9zdGF0aWMuZ2FtYmlkLmlvL2RlbW8vdmFzdC54bWw&vwarv', - imptrackers: [ - 'https://bidder.cleanmediaads.com/pix/1275/imp/imp_5c24924de4b0d106447af333/im.gif?r=imp_5c24924de4b0d106447af333&i=afbb5852-7cea-4a81-aa9a-a41aab505c23&a=1274&b=gb_1' - ] - } - } - ] - } - ], - ext: { - utrk: [ - { - type: 'image', - url: - 'https://bidder.cleanmediaads.com/pix/1275/scm?cb=1545900621675' - } - ] - } - }; - const videoRequest = utils.deepClone(videoBidRequest); - videoRequest.mediaTypes.video.context = 'outstream'; - const result = spec.interpretResponse( - { body: videoResponse }, - { bidRequest: videoRequest } - ); - expect(result[0].renderer).to.not.equal(undefined); - }); - - it('validates in/existing of gdpr consent', function() { - let videoResponse = { - id: '64f32497-b2f7-48ec-9205-35fc39894d44', - bidid: 'imp_5c24924de4b0d106447af333', - cur: 'USD', - seatbid: [ - { - seat: '3668', - group: 0, - bid: [ - { - id: 'gb_1', - impid: 'afbb5852-7cea-4a81-aa9a-a41aab505c23', - price: 5.0, - adid: '1274', - nurl: - 'https://bidder.cleanmediaads.com/pix/1275/win_notice/imp_5c24924de4b0d106447af333/im.gif?r=imp_5c24924de4b0d106447af333&i=afbb5852-7cea-4a81-aa9a-a41aab505c23&a=1274&b=gb_1', - adomain: [], - adm: - '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n', - cid: '3668', - crid: '1274', - cat: [], - attr: [], - h: 250, - w: 300, - ext: { - vast_url: - 'https://bidder.cleanmediaads.com/pix/1275/vast_o/imp_5c24924de4b0d106447af333/im.xml?r=imp_5c24924de4b0d106447af333&i=afbb5852-7cea-4a81-aa9a-a41aab505c23&a=1274&b=gb_1&w=300&h=250&vatu=aHR0cHM6Ly9zdGF0aWMuZ2FtYmlkLmlvL2RlbW8vdmFzdC54bWw&vwarv', - imptrackers: [ - 'https://bidder.cleanmediaads.com/pix/1275/imp/imp_5c24924de4b0d106447af333/im.gif?r=imp_5c24924de4b0d106447af333&i=afbb5852-7cea-4a81-aa9a-a41aab505c23&a=1274&b=gb_1' - ] - } - } - ] - } - ], - ext: { - utrk: [ - { - type: 'image', - url: - 'https://bidder.cleanmediaads.com/pix/1275/scm?cb=1545900621675' - } - ] - } - }; - let gdprConsent = { - gdprApplies: true, - consentString: 'consent string' - }; - let 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://bidder.cleanmediaads.com/pix/1275/scm?cb=1545900621675&gc=consent%20string' - ); - - gdprConsent.gdprApplies = false; - 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://bidder.cleanmediaads.com/pix/1275/scm?cb=1545900621675&gc=missing' - ); - - videoResponse.ext.utrk[0].url = - 'https://bidder.cleanmediaads.com/pix/1275/scm'; - 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://bidder.cleanmediaads.com/pix/1275/scm?gc=missing' - ); - }); - }); -}); diff --git a/test/spec/modules/clickforceBidAdapter_spec.js b/test/spec/modules/clickforceBidAdapter_spec.js deleted file mode 100644 index dad00f94641..00000000000 --- a/test/spec/modules/clickforceBidAdapter_spec.js +++ /dev/null @@ -1,190 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/clickforceBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('ClickforceAdapter', 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 () { - let bid = { - 'bidder': 'clickforce', - 'params': { - 'zone': '6682' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250] - ], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'someIncorrectParam': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [{ - 'bidder': 'clickforce', - 'params': { - 'zone': '6682' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250] - ], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }]; - - const request = spec.buildRequests(bidRequests); - - it('sends bid request to our endpoint via POST', function () { - expect(request.method).to.equal('POST'); - }); - }); - - describe('interpretResponse', function () { - let response = [{ - 'cpm': 0.5, - 'width': '300', - 'height': '250', - 'callback_uid': '220ed41385952a', - 'type': 'Default Ad', - 'tag': '', - 'creativeId': '1f99ac5c3ef10a4097499a5686b30aff-6682', - 'requestId': '220ed41385952a', - 'currency': 'USD', - 'ttl': 60, - 'netRevenue': true, - 'zone': '6682' - }]; - - let response1 = [{ - 'cpm': 0.0625, - 'width': '3', - 'height': '3', - 'callback_uid': '2e27ec595bf1a', - 'type': 'public Bid', - 'tag': { - 'content': { - 'title': 'title', - 'content': 'content', - 'advertiser': 'advertiser', - 'button_text': 'button_text', - 'image': 'image', - 'icon': 'icon' - }, - 'cu': ['cu'], - 'iu': ['iu'], - 'p': '6878:11062:32586:8380573788dad9b9fc17edde444c4dcf:2795' - }, - 'creativeId': '8380573788dad9b9fc17edde444c4dcf-6878', - 'requestId': '2e27ec595bf1a', - 'currency': 'USD', - 'ttl': 60, - 'netRevenue': true, - 'zone': '6878' - }]; - - let expectedResponse = [{ - 'requestId': '220ed41385952a', - 'cpm': 0.5, - 'width': '300', - 'height': '250', - 'creativeId': '1f99ac5c3ef10a4097499a5686b30aff-6682', - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 60, - 'ad': '', - 'mediaType': 'banner', - }]; - - let expectedResponse1 = [{ - 'requestId': '2e27ec595bf1a', - 'cpm': 0.0625, - 'width': '3', - 'height': '3', - 'creativeId': '8380573788dad9b9fc17edde444c4dcf-6878', - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 60, - 'mediaType': 'native', - 'native': { - 'image': { - 'url': 'image', - 'width': 1600, - 'height': 900 - }, - 'title': 'title', - 'sponsoredBy': 'advertiser', - 'body': 'content', - 'icon': { - 'url': 'icon', - 'width': 900, - 'height': 900 - }, - 'clickUrl': 'cu', - 'impressionTrackers': ['iu'] - } - }]; - - it('should get the correct bid response by display ad', function () { - let bidderRequest; - let 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; - let result = spec.interpretResponse({ body: response1 }, {bidderRequest}); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse1[0])); - }); - - it('handles empty bid response', function () { - let response = { - body: {} - }; - let result = spec.interpretResponse(response); - expect(result.length).to.equal(0); - }); - }); - - describe('getUserSyncs function', function () { - it('should register type is iframe', function () { - const syncOptions = { - 'iframeEnabled': 'true' - } - let userSync = spec.getUserSyncs(syncOptions); - expect(userSync[0].type).to.equal('iframe'); - expect(userSync[0].url).to.equal('https://cdn.holmesmind.com/js/capmapping.htm'); - }); - - it('should register type is image', function () { - const syncOptions = { - 'pixelEnabled': 'true' - } - let userSync = spec.getUserSyncs(syncOptions); - expect(userSync[0].type).to.equal('image'); - expect(userSync[0].url).to.equal('https://c.holmesmind.com/cm'); - }); - }); -}); diff --git a/test/spec/modules/clicktripzBidAdapter_spec.js b/test/spec/modules/clicktripzBidAdapter_spec.js deleted file mode 100644 index fed94811c4e..00000000000 --- a/test/spec/modules/clicktripzBidAdapter_spec.js +++ /dev/null @@ -1,152 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/clicktripzBidAdapter.js'; - -const ENDPOINT_URL = 'https://www.clicktripz.com/x/prebid/v1'; - -describe('clicktripzBidAdapter', function () { - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'clicktripz', - 'params': { - placementId: 'testPlacementId', - siteId: 'testSiteId' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250] - ], - 'bidId': '1234asdf1234', - 'bidderRequestId': '1234asdf1234asdf', - 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf120' - }; - - let bid2 = { - 'bidder': 'clicktripz', - 'params': { - placementId: 'testPlacementId' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250] - ], - 'bidId': '1234asdf1234', - 'bidderRequestId': '1234asdf1234asdf', - 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf120' - }; - - let bid3 = { - 'bidder': 'clicktripz', - 'params': { - siteId: 'testSiteId' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250] - ], - 'bidId': '1234asdf1234', - 'bidderRequestId': '1234asdf1234asdf', - 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf120' - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are NOT found', function () { - expect(spec.isBidRequestValid(bid2)).to.equal(false); - expect(spec.isBidRequestValid(bid3)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let validBidRequests = [{ - 'bidder': 'clicktripz', - 'params': { - placementId: 'testPlacementId', - siteId: 'testSiteId' - }, - 'sizes': [ - [300, 250], - [300, 300] - ], - 'bidId': '23beaa6af6cdde', - 'bidderRequestId': '19c0c1efdf37e7', - 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf1', - }, { - 'bidder': 'clicktripz', - 'params': { - placementId: 'testPlacementId2', - siteId: 'testSiteId2' - }, - 'sizes': [ - [300, 250] - ], - 'bidId': '25beaa6af6cdde', - 'bidderRequestId': '19c0c1efdf37e7', - 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf1', - }]; - - const request = spec.buildRequests(validBidRequests); - it('sends bid request to our endpoint via POST', function () { - expect(request.method).to.equal('POST'); - }); - it('sends bid request to our endpoint via POST', function () { - expect(request.method).to.equal('POST'); - }); - - it('sends bid request to our endpoint at the correct URL', function () { - expect(request.url).to.equal(ENDPOINT_URL); - }); - it('sends bid request to our endpoint at the correct URL', function () { - expect(request.url).to.equal(ENDPOINT_URL); - }); - - it('transforms sizes into an array of strings. Pairs of concatenated sizes joined with an x', function () { - expect(request.data[0].sizes.toString()).to.equal('300x250,300x300'); - }); - it('transforms sizes into an array of strings. Pairs of concatenated sizes joined with an x', function () { - expect(request.data[1].sizes.toString()).to.equal('300x250'); - }); - - it('includes bidId, siteId, and placementId in payload', function () { - expect(request.data[0].bidId).to.equal('23beaa6af6cdde'); - expect(request.data[0].siteId).to.equal('testSiteId'); - expect(request.data[0].placementId).to.equal('testPlacementId'); - }); - it('includes bidId, siteId, and placementId in payload', function () { - expect(request.data[1].bidId).to.equal('25beaa6af6cdde'); - expect(request.data[1].siteId).to.equal('testSiteId2'); - expect(request.data[1].placementId).to.equal('testPlacementId2'); - }); - }); - - describe('interpretResponse', function () { - let serverResponse = { - body: [{ - 'bidId': 'bid-request-id', - 'ttl': 120, - 'netRevenue': true, - 'size': '300x200', - 'currency': 'USD', - 'adUrl': 'https://www.clicktripz.com/n3/crane/v0/render?t=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwYXlsb2FkIjoiaHR0cHM6XC9cL3d3dy5jbGlja3RyaXB6LmNvbVwvY2xpY2sucGhwP2NhbXBhaWduSUQ9MTkxNTYmcHJlQ2hlY2tlZD0xJnB1Ymxpc2hlcklEPTM2MCZzZWFyY2hLZXk9N2M5MzQ0NzhlM2M1NTc3Y2EyN2ZmN2Y1NTg5N2NkMzkmc2VhcmNoRGlzcGxheVR5cGU9MSZkaXNwbGF5VHlwZT00JmNyZWF0aXZlVHlwZT1zaW5nbGUmaXNQb3BVbmRlcj0wJnBvc2l0aW9uPTEmdHlwZT0xJmNpdHk9TWFkcmlkJTJDK1NwYWluJmNoZWNrSW5EYXRlPTAzJTJGMDElMkYyMDIwJmNoZWNrT3V0RGF0ZT0wMyUyRjA1JTJGMjAyMCZndWVzdHM9MiZyb29tcz0xIn0.WBDGYr1qfkSvOuK02VpMW3iAua1E02jjDGDViFc2kaE', - 'creativeId': '25ef9876abc5681f153', - 'cpm': 50 - }] - }; - it('should get the correct bid response', function () { - let expectedResponse = [{ - 'requestId': 'bid-request-id', - 'cpm': 50, - 'netRevenue': true, - 'width': '300', - 'height': '200', - 'creativeId': '25ef9876abc5681f153', - 'currency': 'USD', - 'adUrl': 'https://www.clicktripz.com/n3/crane/v0/render?t=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJwYXlsb2FkIjoiaHR0cHM6XC9cL3d3dy5jbGlja3RyaXB6LmNvbVwvY2xpY2sucGhwP2NhbXBhaWduSUQ9MTkxNTYmcHJlQ2hlY2tlZD0xJnB1Ymxpc2hlcklEPTM2MCZzZWFyY2hLZXk9N2M5MzQ0NzhlM2M1NTc3Y2EyN2ZmN2Y1NTg5N2NkMzkmc2VhcmNoRGlzcGxheVR5cGU9MSZkaXNwbGF5VHlwZT00JmNyZWF0aXZlVHlwZT1zaW5nbGUmaXNQb3BVbmRlcj0wJnBvc2l0aW9uPTEmdHlwZT0xJmNpdHk9TWFkcmlkJTJDK1NwYWluJmNoZWNrSW5EYXRlPTAzJTJGMDElMkYyMDIwJmNoZWNrT3V0RGF0ZT0wMyUyRjA1JTJGMjAyMCZndWVzdHM9MiZyb29tcz0xIn0.WBDGYr1qfkSvOuK02VpMW3iAua1E02jjDGDViFc2kaE', - 'ttl': 120 - }]; - let result = spec.interpretResponse(serverResponse); - expect(result).to.deep.equal(expectedResponse); - }); - }); -}); diff --git a/test/spec/modules/cointrafficBidAdapter_spec.js b/test/spec/modules/cointrafficBidAdapter_spec.js deleted file mode 100644 index a2ce4cedea0..00000000000 --- a/test/spec/modules/cointrafficBidAdapter_spec.js +++ /dev/null @@ -1,261 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/cointrafficBidAdapter.js'; -import { config } from 'src/config.js' -import * as utils from 'src/utils.js' - -const ENDPOINT_URL = 'https://appspb.cointraffic.io/pb/tmp'; - -describe('cointrafficBidAdapter', function () { - describe('isBidRequestValid', function () { - let bid = { - bidder: 'cointraffic', - params: { - placementId: 'testPlacementId' - }, - adUnitCode: 'adunit-code', - sizes: [ - [300, 250] - ], - bidId: 'bidId12345', - bidderRequestId: 'bidderRequestId12345', - auctionId: 'auctionId12345' - }; - - it('should return true where required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [ - { - bidder: 'cointraffic', - params: { - placementId: 'testPlacementId' - }, - adUnitCode: 'adunit-code', - sizes: [ - [300, 250] - ], - bidId: 'bidId12345', - bidderRequestId: 'bidderRequestId12345', - auctionId: 'auctionId12345' - }, - { - bidder: 'cointraffic', - params: { - placementId: 'testPlacementId' - }, - adUnitCode: 'adunit-code2', - sizes: [ - [300, 250] - ], - bidId: 'bidId67890"', - bidderRequestId: 'bidderRequestId67890', - auctionId: 'auctionId12345' - } - ]; - - let bidderRequests = { - refererInfo: { - numIframes: 0, - reachedTop: true, - referer: 'https://example.com', - stack: [ - 'https://example.com' - ] - } - }; - - it('replaces currency with EUR if there is no currency provided', function () { - const request = spec.buildRequests(bidRequests, bidderRequests); - - expect(request[0].data.currency).to.equal('EUR'); - expect(request[1].data.currency).to.equal('EUR'); - }); - - it('replaces currency with EUR if there is no currency provided', function () { - const getConfigStub = sinon.stub(config, 'getConfig').callsFake( - arg => arg === 'currency.bidderCurrencyDefault.cointraffic' ? 'USD' : 'EUR' - ); - - const request = spec.buildRequests(bidRequests, bidderRequests); - - expect(request[0].data.currency).to.equal('USD'); - expect(request[1].data.currency).to.equal('USD'); - - getConfigStub.restore(); - }); - - it('throws an error if currency provided in params is not allowed', function () { - const utilsMock = sinon.mock(utils).expects('logError').twice() - const getConfigStub = sinon.stub(config, 'getConfig').callsFake( - arg => arg === 'currency.bidderCurrencyDefault.cointraffic' ? 'BTC' : 'EUR' - ); - - const request = spec.buildRequests(bidRequests, bidderRequests); - - expect(request[0]).to.undefined; - expect(request[1]).to.undefined; - - utilsMock.restore() - getConfigStub.restore(); - }); - - it('sends bid request to our endpoint via POST', function () { - const request = spec.buildRequests(bidRequests, bidderRequests); - - expect(request[0].method).to.equal('POST'); - expect(request[1].method).to.equal('POST'); - }); - - it('attaches source and version to endpoint URL as query params', function () { - const request = spec.buildRequests(bidRequests, bidderRequests); - - expect(request[0].url).to.equal(ENDPOINT_URL); - expect(request[1].url).to.equal(ENDPOINT_URL); - }); - }); - - describe('interpretResponse', function () { - it('should get the correct bid response', function () { - let bidRequest = [{ - method: 'POST', - url: ENDPOINT_URL, - data: { - placementId: 'testPlacementId', - device: 'desktop', - currency: 'EUR', - sizes: ['300x250'], - bidId: 'bidId12345', - referer: 'www.example.com' - } - }]; - - let serverResponse = { - body: { - requestId: 'bidId12345', - cpm: 3.9, - currency: 'EUR', - netRevenue: true, - width: 300, - height: 250, - creativeId: 'creativeId12345', - ttl: 90, - ad: '

I am an ad

' - } - }; - - let expectedResponse = [{ - requestId: 'bidId12345', - cpm: 3.9, - currency: 'EUR', - netRevenue: true, - width: 300, - height: 250, - creativeId: 'creativeId12345', - ttl: 90, - ad: '

I am an ad

' - }]; - - let result = spec.interpretResponse(serverResponse, bidRequest[0]); - expect(Object.keys(result)).to.deep.equal(Object.keys(expectedResponse)); - }); - - it('should get the correct bid response with different currency', function () { - let bidRequest = [{ - method: 'POST', - url: ENDPOINT_URL, - data: { - placementId: 'testPlacementId', - device: 'desktop', - currency: 'USD', - sizes: ['300x250'], - bidId: 'bidId12345', - referer: 'www.example.com' - } - }]; - - let serverResponse = { - body: { - requestId: 'bidId12345', - cpm: 3.9, - currency: 'USD', - netRevenue: true, - width: 300, - height: 250, - creativeId: 'creativeId12345', - ttl: 90, - ad: '

I am an ad

' - } - }; - - let expectedResponse = [{ - requestId: 'bidId12345', - cpm: 3.9, - currency: 'USD', - netRevenue: true, - width: 300, - height: 250, - creativeId: 'creativeId12345', - ttl: 90, - ad: '

I am an ad

' - }]; - - const getConfigStub = sinon.stub(config, 'getConfig').returns('USD'); - - let result = spec.interpretResponse(serverResponse, bidRequest[0]); - expect(Object.keys(result)).to.deep.equal(Object.keys(expectedResponse)); - - getConfigStub.restore(); - }); - - it('should get empty bid response requested currency is not available', function () { - let bidRequest = [{ - method: 'POST', - url: ENDPOINT_URL, - data: { - placementId: 'testPlacementId', - device: 'desktop', - currency: 'BTC', - sizes: ['300x250'], - bidId: 'bidId12345', - referer: 'www.example.com' - } - }]; - - let serverResponse = {}; - - let expectedResponse = []; - - const getConfigStub = sinon.stub(config, 'getConfig').returns('BTC'); - - let result = spec.interpretResponse(serverResponse, bidRequest[0]); - expect(Object.keys(result)).to.deep.equal(Object.keys(expectedResponse)); - - getConfigStub.restore(); - }); - - it('should get empty bid response if no server response', function () { - let bidRequest = [{ - method: 'POST', - url: ENDPOINT_URL, - data: { - placementId: 'testPlacementId', - device: 'desktop', - currency: 'EUR', - sizes: ['300x250'], - bidId: 'bidId12345', - referer: 'www.example.com' - } - }]; - - let serverResponse = {}; - - let expectedResponse = []; - - let result = spec.interpretResponse(serverResponse, bidRequest[0]); - expect(Object.keys(result)).to.deep.equal(Object.keys(expectedResponse)); - }); - }); -}); diff --git a/test/spec/modules/coinzillaBidAdapter_spec.js b/test/spec/modules/coinzillaBidAdapter_spec.js deleted file mode 100644 index a3438b80126..00000000000 --- a/test/spec/modules/coinzillaBidAdapter_spec.js +++ /dev/null @@ -1,120 +0,0 @@ -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'; - -describe('coinzillaBidAdapter', function () { - const adapter = newBidder(spec); - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'coinzilla', - 'params': { - placementId: 'testPlacementId' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250] - ], - 'bidId': '1234asdf1234', - 'bidderRequestId': '1234asdf1234asdf', - 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf120' - }; - it('should return true where required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - }); - describe('buildRequests', function () { - let bidRequests = [ - { - 'bidder': 'coinzilla', - 'params': { - placementId: 'testPlacementId' - }, - 'sizes': [ - [300, 250] - ], - 'bidId': '23beaa6af6cdde', - 'bidderRequestId': '19c0c1efdf37e7', - 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf1', - }, - { - 'bidder': 'coinzilla', - 'params': { - placementId: 'testPlacementId' - }, - 'adUnitCode': 'adunit-code2', - 'sizes': [ - [300, 250] - ], - 'bidId': '382091349b149f"', - 'bidderRequestId': '1f9c98192de251', - 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf1', - } - ]; - - let bidderRequests = { - 'refererInfo': { - 'numIframes': 0, - 'reachedTop': true, - 'referer': 'https://example.com', - 'stack': ['https://example.com'] - } - }; - - const request = spec.buildRequests(bidRequests, bidderRequests); - it('sends bid request to our endpoint via POST', function () { - expect(request[0].method).to.equal('POST'); - expect(request[1].method).to.equal('POST'); - }); - it('attaches source and version to endpoint URL as query params', function () { - expect(request[0].url).to.equal(ENDPOINT_URL); - expect(request[1].url).to.equal(ENDPOINT_URL); - }); - }); - - describe('interpretResponse', function () { - let bidRequest = [ - { - 'method': 'POST', - 'url': ENDPOINT_URL, - 'data': { - 'placementId': 'testPlacementId', - 'width': '300', - 'height': '200', - 'bidId': 'bidId123', - 'referer': 'www.example.com' - } - - } - ]; - let serverResponse = { - body: { - 'ad': '

I am an ad

', - 'cpm': 4.2, - 'creativeId': '12345asdfg', - 'currency': 'EUR', - 'statusMessage': 'Bid available', - 'requestId': 'bidId123', - 'width': 300, - 'height': 250, - 'netRevenue': true - } - }; - it('should get the correct bid response', function () { - let expectedResponse = [{ - 'requestId': 'bidId123', - 'cpm': 4.2, - 'width': 300, - 'height': 250, - 'creativeId': '12345asdfg', - 'currency': 'EUR', - 'netRevenue': true, - 'ttl': 3000, - 'ad': '

I am an ad

' - }]; - let result = spec.interpretResponse(serverResponse, bidRequest[0]); - expect(Object.keys(result)).to.deep.equal(Object.keys(expectedResponse)); - }); - }); -}); diff --git a/test/spec/modules/collectcentBidAdapter_spec.js b/test/spec/modules/collectcentBidAdapter_spec.js deleted file mode 100644 index 0ab83a8024b..00000000000 --- a/test/spec/modules/collectcentBidAdapter_spec.js +++ /dev/null @@ -1,118 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/collectcentBidAdapter.js'; - -describe('Collectcent', function () { - let bid = { - bidId: '2dd581a2b6281d', - bidder: 'collectcent', - bidderRequestId: '145e1d6a7837c9', - params: { - placementId: 123, - traffic: 'banner' - }, - placementCode: 'placement_0', - auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', - sizes: [[300, 250]], - transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e62' - }; - - describe('isBidRequestValid', function () { - it('Should return true when placementId can be cast to a number', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false when placementId is not a number', function () { - bid.params.placementId = 'aaa'; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid]); - 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://publishers.motionspots.com/?c=o&m=multi'); - }); - it('Returns valid data if array of bids is valid', function () { - let data = serverRequest.data; - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'secure', 'host', 'page', 'placements'); - expect(data.deviceWidth).to.be.a('number'); - expect(data.deviceHeight).to.be.a('number'); - expect(data.secure).to.be.within(0, 1); - expect(data.host).to.be.a('string'); - expect(data.page).to.be.a('string'); - let placements = data['placements']; - for (let i = 0; i < placements.length; i++) { - let placement = placements[i]; - expect(placement).to.have.all.keys('placementId', 'bidId', 'traffic', 'sizes'); - expect(placement.placementId).to.be.a('number'); - expect(placement.bidId).to.be.a('string'); - expect(placement.traffic).to.be.a('string'); - expect(placement.sizes).to.be.an('array'); - } - }); - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); - }); - describe('interpretResponse', function () { - let resObject = { - body: [ { - requestId: '123', - mediaType: 'banner', - cpm: 0.3, - width: 320, - height: 50, - ad: '

Hello ad

', - ttl: 1000, - creativeId: '123asd', - netRevenue: true, - currency: 'USD' - } ] - }; - 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++) { - let dataItem = serverResponses[i]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'mediaType'); - 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.mediaType).to.be.a('string'); - } - 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; - }); - }); - }); - - describe('getUserSyncs', function () { - let userSync = spec.getUserSyncs(); - it('Returns valid URL and `', function () { - expect(userSync).to.be.an('array').with.lengthOf(1); - expect(userSync[0].type).to.exist; - expect(userSync[0].url).to.exist; - expect(userSync[0].type).to.be.equal('image'); - expect(userSync[0].url).to.be.equal('https://publishers.motionspots.com/?c=o&m=cookie'); - }); - }); -}); diff --git a/test/spec/modules/colombiaBidAdapter_spec.js b/test/spec/modules/colombiaBidAdapter_spec.js deleted file mode 100644 index 4e80c6b1d9d..00000000000 --- a/test/spec/modules/colombiaBidAdapter_spec.js +++ /dev/null @@ -1,152 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/colombiaBidAdapter'; -import { newBidder } from 'src/adapters/bidderFactory'; - -const HOST_NAME = document.location.protocol + '//' + window.location.host; -const ENDPOINT = 'https://ade.clmbtech.com/cde/prebid.htm'; - -describe('colombiaBidAdapter', function() { - const adapter = newBidder(spec); - - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'colombia', - 'params': { - placementId: '307466' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250] - ], - 'bidId': '23beaa6af6cdde', - 'bidderRequestId': '19c0c1efdf37e7', - 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf1', - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when placementId not passed correctly', function () { - bid.params.placementId = ''; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when require params are not passed', function () { - let bid = Object.assign({}, bid); - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [ - { - 'bidder': 'colombia', - 'params': { - placementId: '307466' - }, - 'adUnitCode': 'adunit-code1', - 'sizes': [ - [300, 250] - ], - 'bidId': '23beaa6af6cdde', - 'bidderRequestId': '19c0c1efdf37e7', - 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf1', - }, - { - 'bidder': 'colombia', - 'params': { - placementId: '307466' - }, - 'adUnitCode': 'adunit-code2', - 'sizes': [ - [300, 250] - ], - 'bidId': '382091349b149f"', - 'bidderRequestId': '"1f9c98192de251"', - 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf1', - } - ]; - - const request = spec.buildRequests(bidRequests); - - it('sends bid request to our endpoint via POST', function () { - expect(request[0].method).to.equal('POST'); - expect(request[1].method).to.equal('POST'); - }); - - it('attaches source and version to endpoint URL as query params', function () { - expect(request[0].url).to.equal(ENDPOINT); - expect(request[1].url).to.equal(ENDPOINT); - }); - }); - - describe('interpretResponse', function () { - let bidRequest = [ - { - 'method': 'POST', - 'url': 'https://ade.clmbtech.com/cde/prebid.htm', - 'data': { - 'v': 'hb1', - 'p': '307466', - 'w': '300', - 'h': '250', - 'cb': 12892917383, - 'r': 'http%3A%2F%2Flocalhost%3A9876%2F%3Fid%3D74552836', - 'uid': '23beaa6af6cdde', - 't': 'i', - } - } - ]; - - let serverResponse = { - body: { - 'ad': '
This is test case for colombia adapter
', - 'cpm': 3.14, - 'creativeId': '6b958110-612c-4b03-b6a9-7436c9f746dc-1sk24', - 'currency': 'USD', - 'uid': '23beaa6af6cdde', - 'width': 728, - 'height': 90, - 'netRevenue': true, - 'ttl': 600, - 'dealid': '', - 'referrer': 'http%3A%2F%2Flocalhost%3A9876%2F%3Fid%3D74552836' - } - }; - - it('should get the correct bid response', function () { - let expectedResponse = [{ - 'requestId': '23beaa6af6cdde', - 'cpm': 3.14, - 'width': 728, - 'height': 90, - 'creativeId': '6b958110-612c-4b03-b6a9-7436c9f746dc-1sk24', - 'dealId': '', - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'referrer': 'http%3A%2F%2Flocalhost%3A9876%2F%3Fid%3D74552836', - 'ad': '
This is test case for colombia adapter
' - }]; - let result = spec.interpretResponse(serverResponse, bidRequest[0]); - expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); - }); - - it('handles empty bid response', function () { - let response = { - body: { - 'uid': '23beaa6af6cdde', - 'height': 0, - 'creativeId': '', - 'statusMessage': 'Bid returned empty or error response', - 'width': 0, - 'cpm': 0 - } - }; - let result = spec.interpretResponse(response, bidRequest[0]); - expect(result.length).to.equal(0); - }); - }); -}); diff --git a/test/spec/modules/colossussspBidAdapter_spec.js b/test/spec/modules/colossussspBidAdapter_spec.js deleted file mode 100644 index f6e24d07c63..00000000000 --- a/test/spec/modules/colossussspBidAdapter_spec.js +++ /dev/null @@ -1,185 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/colossussspBidAdapter.js'; - -describe('ColossussspAdapter', function () { - let bid = { - bidId: '2dd581a2b6281d', - bidder: 'colossusssp', - bidderRequestId: '145e1d6a7837c9', - params: { - placement_id: 0 - }, - placementCode: 'placementid_0', - auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e62', - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '0', - hp: 1, - rid: 'bidrequestid', - // name: 'alladsallthetime', - domain: 'example.com' - } - ] - } - }; - let bidderRequest = { - bidderCode: 'colossus', - auctionId: 'fffffff-ffff-ffff-ffff-ffffffffffff', - bidderRequestId: 'ffffffffffffff', - start: 1472239426002, - auctionStart: 1472239426000, - timeout: 5000, - uspConsent: '1YN-', - refererInfo: { - referer: 'http://www.example.com', - reachedTop: true, - }, - bids: [bid] - } - - describe('isBidRequestValid', function () { - it('Should return true when placement_id can be cast to a number', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false when placement_id is not a number', function () { - bid.params.placement_id = 'aaa'; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid], 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://colossusssp.com/?c=o&m=multi'); - }); - it('Should contain ccpa', function() { - expect(serverRequest.data.ccpa).to.be.an('string') - }) - - it('Returns valid data if array of bids is valid', function () { - let data = serverRequest.data; - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements', 'ccpa'); - 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'); - let placements = data['placements']; - for (let i = 0; i < placements.length; i++) { - let placement = placements[i]; - expect(placement).to.have.all.keys('placementId', 'eids', 'bidId', 'traffic', 'sizes', 'schain', 'floor'); - expect(placement.schain).to.be.an('object') - expect(placement.placementId).to.be.a('number'); - expect(placement.bidId).to.be.a('string'); - expect(placement.traffic).to.be.a('string'); - expect(placement.sizes).to.be.an('array'); - expect(placement.floor).to.be.an('object'); - } - }); - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); - }); - - describe('buildRequests with user ids', function () { - bid.userId = {} - bid.userId.britepoolid = 'britepoolid123'; - bid.userId.idl_env = 'idl_env123'; - bid.userId.tdid = 'tdid123'; - bid.userId.id5id = { uid: 'id5id123' }; - let serverRequest = spec.buildRequests([bid], bidderRequest); - it('Returns valid data if array of bids is valid', function () { - let data = serverRequest.data; - let placements = data['placements']; - expect(data).to.be.an('object'); - for (let i = 0; i < placements.length; i++) { - let placement = placements[i]; - expect(placement).to.have.property('eids') - expect(placement.eids).to.be.an('array') - expect(placement.eids.length).to.be.equal(4) - for (let index in placement.eids) { - let v = placement.eids[index]; - expect(v).to.have.all.keys('source', 'uids') - expect(v.source).to.be.oneOf(['britepool.com', 'identityLink', 'adserver.org', 'id5-sync.com']) - expect(v.uids).to.be.an('array'); - expect(v.uids.length).to.be.equal(1) - expect(v.uids[0]).to.have.property('id') - } - } - }); - }); - - describe('interpretResponse', function () { - let resObject = { - body: [ { - requestId: '123', - mediaType: 'banner', - cpm: 0.3, - width: 320, - height: 50, - ad: '

Hello ad

', - ttl: 1000, - creativeId: '123asd', - netRevenue: true, - currency: 'USD' - } ] - }; - 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++) { - let dataItem = serverResponses[i]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'mediaType'); - 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.mediaType).to.be.a('string'); - } - 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; - }); - }); - }); - - describe('getUserSyncs', function () { - let userSync = spec.getUserSyncs(); - it('Returns valid URL and type', function () { - expect(userSync).to.be.an('array').with.lengthOf(1); - expect(userSync[0].type).to.exist; - expect(userSync[0].url).to.exist; - expect(userSync[0].type).to.be.equal('image'); - expect(userSync[0].url).to.be.equal('https://colossusssp.com/?c=o&m=cookie'); - }); - }); -}); diff --git a/test/spec/modules/concertAnalyticsAdapter_spec.js b/test/spec/modules/concertAnalyticsAdapter_spec.js deleted file mode 100644 index b0aad2f3156..00000000000 --- a/test/spec/modules/concertAnalyticsAdapter_spec.js +++ /dev/null @@ -1,157 +0,0 @@ -import concertAnalytics from 'modules/concertAnalyticsAdapter.js'; -import { expect } from 'chai'; -const sinon = require('sinon'); -let adapterManager = require('src/adapterManager').default; -let events = require('src/events'); -let constants = require('src/constants.json'); - -describe('ConcertAnalyticsAdapter', function() { - let sandbox; - let xhr; - let requests; - let clock; - let timestamp = 1896134400; - let auctionId = '9f894496-10fe-4652-863d-623462bf82b8'; - let timeout = 1000; - - before(function () { - sandbox = sinon.createSandbox(); - xhr = sandbox.useFakeXMLHttpRequest(); - requests = []; - - xhr.onCreate = function (request) { - requests.push(request); - }; - clock = sandbox.useFakeTimers(1896134400); - }); - - after(function () { - sandbox.restore(); - }); - - describe('track', function() { - beforeEach(function () { - sandbox.stub(events, 'getEvents').returns([]); - - adapterManager.enableAnalytics({ - provider: 'concert' - }); - }); - - afterEach(function () { - events.getEvents.restore(); - concertAnalytics.eventsStorage = []; - concertAnalytics.disableAnalytics(); - }); - - it('should catch all events', function() { - sandbox.spy(concertAnalytics, 'track'); - - fireBidEvents(events); - sandbox.assert.callCount(concertAnalytics.track, 5); - }); - - it('should report data for BID_RESPONSE, BID_WON events', function() { - fireBidEvents(events); - clock.tick(3000 + 1000); - - const eventsToReport = ['bidResponse', 'bidWon']; - for (var i = 0; i < concertAnalytics.eventsStorage.length; i++) { - expect(eventsToReport.indexOf(concertAnalytics.eventsStorage[i].event)).to.be.above(-1); - } - - for (var i = 0; i < eventsToReport.length; i++) { - expect(concertAnalytics.eventsStorage.some(function(event) { - return event.event === eventsToReport[i] - })).to.equal(true); - } - }); - - it('should report data in the shape expected by analytics endpoint', function() { - fireBidEvents(events); - clock.tick(3000 + 1000); - - const requiredFields = ['event', 'concert_rid', 'adId', 'auctionId', 'creativeId', 'position', 'url', 'cpm', 'width', 'height', 'timeToRespond']; - - for (var i = 0; i < requiredFields.length; i++) { - expect(concertAnalytics.eventsStorage[0]).to.have.property(requiredFields[i]); - } - }); - }); - - const adUnits = [{ - code: 'desktop_leaderboard_variable', - sizes: [[1030, 590]], - mediaTypes: { - banner: { - sizes: [[1030, 590]] - } - }, - bids: [ - { - bidder: 'concert', - params: { - partnerId: 'test_partner' - } - } - ] - }]; - - const bidResponse = { - 'bidderCode': 'concert', - 'width': 1030, - 'height': 590, - 'statusMessage': 'Bid available', - 'adId': '642f13fe18ab7dc', - 'requestId': '4062fba2e039919', - 'mediaType': 'banner', - 'source': 'client', - 'cpm': 6, - 'ad': '', - 'ttl': 360, - 'creativeId': '138308483085|62bac030-a5d3-11ea-b3be-55590c8153a5', - 'netRevenue': false, - 'currency': 'USD', - 'originalCpm': 6, - 'originalCurrency': 'USD', - 'auctionId': '9f894496-10fe-4652-863d-623462bf82b8', - 'responseTimestamp': 1591213790366, - 'requestTimestamp': 1591213790017, - 'bidder': 'concert', - 'adUnitCode': 'desktop_leaderboard_variable', - 'timeToRespond': 349, - 'status': 'rendered', - 'params': [ - { - 'partnerId': 'cst' - } - ] - } - - const bidWon = { - 'adId': '642f13fe18ab7dc', - 'mediaType': 'banner', - 'requestId': '4062fba2e039919', - 'cpm': 6, - 'creativeId': '138308483085|62bac030-a5d3-11ea-b3be-55590c8153a5', - 'currency': 'USD', - 'netRevenue': false, - 'ttl': 360, - 'auctionId': '9f894496-10fe-4652-863d-623462bf82b8', - 'statusMessage': 'Bid available', - 'responseTimestamp': 1591213790366, - 'requestTimestamp': 1591213790017, - 'bidder': 'concert', - 'adUnitCode': 'desktop_leaderboard_variable', - 'sizes': [[1030, 590]], - 'size': [1030, 590] - } - - function fireBidEvents(events) { - events.emit(constants.EVENTS.AUCTION_INIT, {timestamp, auctionId, timeout, adUnits}); - events.emit(constants.EVENTS.BID_REQUESTED, {bidder: 'concert'}); - events.emit(constants.EVENTS.BID_RESPONSE, bidResponse); - events.emit(constants.EVENTS.AUCTION_END, {}); - events.emit(constants.EVENTS.BID_WON, bidWon); - } -}); diff --git a/test/spec/modules/concertBidAdapter_spec.js b/test/spec/modules/concertBidAdapter_spec.js deleted file mode 100644 index 1b869d51bde..00000000000 --- a/test/spec/modules/concertBidAdapter_spec.js +++ /dev/null @@ -1,219 +0,0 @@ -import { expect } from 'chai'; -import sinon from 'sinon'; -import { spec } from 'modules/concertBidAdapter.js'; -import { getStorageManager } from '../../../src/storageManager.js' - -describe('ConcertAdapter', function () { - let bidRequests; - let bidRequest; - let bidResponse; - - beforeEach(function () { - bidRequests = [ - { - bidder: 'concert', - params: { - partnerId: 'foo', - slotType: 'fizz' - }, - adUnitCode: 'desktop_leaderboard_variable', - bidId: 'foo', - transactionId: '', - sizes: [[1030, 590]] - } - ]; - - bidRequest = { - refererInfo: { - referer: 'https://www.google.com' - }, - uspConsent: '1YYY', - gdprConsent: {} - }; - - bidResponse = { - body: { - bids: [ - { - bidId: '16d2e73faea32d9', - cpm: '6', - width: '1030', - height: '590', - ad: '', - ttl: '360', - creativeId: '123349|a7d62700-a4bf-11ea-829f-ad3b0b7a9383', - netRevenue: false, - currency: 'USD' - } - ] - } - } - }); - - describe('spec.isBidRequestValid', function() { - it('should return when it recieved all the required params', function() { - const bid = bidRequests[0]; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when partner id is missing', function() { - const bid = { - bidder: 'concert', - params: {} - } - - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('spec.buildRequests', function() { - it('should build a payload object with the shape expected by server', function() { - const request = spec.buildRequests(bidRequests, bidRequest); - const payload = JSON.parse(request.data); - expect(payload).to.have.property('meta'); - expect(payload).to.have.property('slots'); - - const metaRequiredFields = ['prebidVersion', 'pageUrl', 'screen', 'debug', 'uid', 'optedOut', 'adapterVersion', 'uspConsent', 'gdprConsent']; - const slotsRequiredFields = ['name', 'bidId', 'transactionId', 'sizes', 'partnerId', 'slotType']; - - metaRequiredFields.forEach(function(field) { - expect(payload.meta).to.have.property(field); - }); - slotsRequiredFields.forEach(function(field) { - expect(payload.slots[0]).to.have.property(field); - }); - }); - - it('should not generate uid if the user has opted out', function() { - const storage = getStorageManager(); - storage.setDataInLocalStorage('c_nap', 'true'); - const request = spec.buildRequests(bidRequests, bidRequest); - const payload = JSON.parse(request.data); - - expect(payload.meta.uid).to.equal(false); - }); - - it('should generate uid if the user has not opted out', function() { - const storage = getStorageManager(); - storage.removeDataFromLocalStorage('c_nap'); - const request = spec.buildRequests(bidRequests, bidRequest); - const payload = JSON.parse(request.data); - - expect(payload.meta.uid).to.not.equal(false); - }); - - it('should grab uid from local storage if it exists', function() { - const storage = getStorageManager(); - storage.setDataInLocalStorage('c_uid', 'foo'); - storage.removeDataFromLocalStorage('c_nap'); - const request = spec.buildRequests(bidRequests, bidRequest); - const payload = JSON.parse(request.data); - - expect(payload.meta.uid).to.equal('foo'); - }); - }); - - describe('spec.interpretResponse', function() { - it('should return bids in the shape expected by prebid', function() { - const bids = spec.interpretResponse(bidResponse, bidRequest); - const requiredFields = ['requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'meta', 'creativeId', 'netRevenue', 'currency']; - - requiredFields.forEach(function(field) { - expect(bids[0]).to.have.property(field); - }); - }); - - it('should return empty bids if there is no response from server', function() { - const bids = spec.interpretResponse({ body: null }, bidRequest); - expect(bids).to.have.lengthOf(0); - }); - - it('should return empty bids if there are no bids from the server', function() { - const bids = spec.interpretResponse({ body: {bids: []} }, bidRequest); - expect(bids).to.have.lengthOf(0); - }); - }); - - describe('spec.getUserSyncs', function() { - it('should not register syncs when iframe is not enabled', function() { - const opts = { - iframeEnabled: false - } - const sync = spec.getUserSyncs(opts, [], bidRequest.gdprConsent, bidRequest.uspConsent); - expect(sync).to.have.lengthOf(0); - }); - - it('should not register syncs when the user has opted out', function() { - const opts = { - iframeEnabled: true - }; - const storage = getStorageManager(); - storage.setDataInLocalStorage('c_nap', 'true'); - - const sync = spec.getUserSyncs(opts, [], bidRequest.gdprConsent, bidRequest.uspConsent); - expect(sync).to.have.lengthOf(0); - }); - - it('should set gdprApplies flag to 1 if the user is in area where GDPR applies', function() { - const opts = { - iframeEnabled: true - }; - const storage = getStorageManager(); - storage.removeDataFromLocalStorage('c_nap'); - - bidRequest.gdprConsent = { - gdprApplies: true - }; - - const sync = spec.getUserSyncs(opts, [], bidRequest.gdprConsent, bidRequest.uspConsent); - expect(sync[0].url).to.have.string('gdpr_applies=1'); - }); - - it('should set gdprApplies flag to 1 if the user is in area where GDPR applies', function() { - const opts = { - iframeEnabled: true - }; - const storage = getStorageManager(); - storage.removeDataFromLocalStorage('c_nap'); - - bidRequest.gdprConsent = { - gdprApplies: false - }; - - const sync = spec.getUserSyncs(opts, [], bidRequest.gdprConsent, bidRequest.uspConsent); - expect(sync[0].url).to.have.string('gdpr_applies=0'); - }); - - it('should set gdpr consent param with the user\'s choices on consent', function() { - const opts = { - iframeEnabled: true - }; - const storage = getStorageManager(); - storage.removeDataFromLocalStorage('c_nap'); - - bidRequest.gdprConsent = { - gdprApplies: false, - consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==' - }; - - const sync = spec.getUserSyncs(opts, [], bidRequest.gdprConsent, bidRequest.uspConsent); - expect(sync[0].url).to.have.string('gdpr_consent=BOJ/P2HOJ/P2HABABMAAAAAZ+A=='); - }); - - it('should set ccpa consent param with the user\'s choices on consent', function() { - const opts = { - iframeEnabled: true - }; - const storage = getStorageManager(); - storage.removeDataFromLocalStorage('c_nap'); - - bidRequest.gdprConsent = { - gdprApplies: false, - uspConsent: '1YYY' - }; - - const sync = spec.getUserSyncs(opts, [], bidRequest.gdprConsent, bidRequest.uspConsent); - expect(sync[0].url).to.have.string('usp_consent=1YY'); - }); - }); -}); diff --git a/test/spec/modules/connectadBidAdapter_spec.js b/test/spec/modules/connectadBidAdapter_spec.js deleted file mode 100644 index dbac3c0dc7c..00000000000 --- a/test/spec/modules/connectadBidAdapter_spec.js +++ /dev/null @@ -1,474 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/connectadBidAdapter.js'; -import { config } from 'src/config.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; - -describe('ConnectAd Adapter', function () { - let bidRequests; - let bidderRequest; - let bidRequestsUserIds; - - beforeEach(function () { - bidRequests = [ - { - bidder: 'conntectad', - params: { - siteId: 123456, - networkId: 123456, - bidfloor: 0.50 - }, - adUnitCode: '/19968336/header-bid-tag-1', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - } - }, - bidId: '2f95c00074b931', - auctionId: 'e76cbb58-f3e1-4ad9-9f4c-718c1919d0df', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: 'e76cbb58-f3e1-4ad9-9f4c-718c1919d0df' - } - ]; - - bidRequestsUserIds = [{ - bidder: 'conntectad', - params: { - siteId: 123456, - networkId: 123456 - }, - adUnitCode: '/19968336/header-bid-tag-1', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - } - }, - bidId: '2f95c00074b931', - auctionId: 'e76cbb58-f3e1-4ad9-9f4c-718c1919d0df', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: 'e76cbb58-f3e1-4ad9-9f4c-718c1919d0df', - userId: { - tdid: '123456' - } - }]; - - bidderRequest = { - timeout: 3000, - gdprConsent: { - gdprApplies: true, - consentString: 'consentDataString', - vendorData: {} - } - } - }); - - describe('inherited functions', function () { - it('should exists and is a function', function () { - const adapter = newBidder(spec); - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('implementation', function () { - describe('for requests', function () { - it('should accept bid', function () { - let validBid = { - bidder: 'connectad', - params: { - siteId: 123456, - networkId: 123456 - }, - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - } - }; - const isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(true); - }); - - it('should reject if missing sizes', function () { - let invalidBid = { - bidder: 'connectad', - params: { - siteId: 123456, - } - }; - const isValid = spec.isBidRequestValid(invalidBid); - expect(isValid).to.equal(false); - }); - - it('should return true when optional bidFloor params found for an ad', function () { - let validBid = { - bidder: 'connectad', - params: { - siteId: 123456, - networkId: 123456, - bidfloor: 0.20 - }, - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - } - }; - const isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(true) - }); - - it('should reject if missing siteId/networkId', function () { - let invalidBid = { - bidder: 'connectad', - params: {}, - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - } - } - }; - const isValid = spec.isBidRequestValid(invalidBid); - expect(isValid).to.equal(false); - }); - - it('should reject if missing networkId', function () { - let invalidBid = { - bidder: 'connectad', - params: { - siteId: 123456 - }, - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - } - } - }; - const isValid = spec.isBidRequestValid(invalidBid); - expect(isValid).to.equal(false); - }); - - it('should contain SiteId and NetworkId', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - const requestparse = JSON.parse(request.data); - expect(requestparse.placements[0].siteId).to.equal(123456); - expect(requestparse.placements[0].networkId).to.equal(123456); - }); - - it('should process floors module if available', function() { - const floorInfo = { - currency: 'USD', - floor: 5.20 - }; - bidRequests[0].getFloor = () => floorInfo; - const request = spec.buildRequests(bidRequests, bidderRequest); - const requestparse = JSON.parse(request.data); - expect(requestparse.placements[0].bidfloor).to.equal(5.20); - }); - - it('should be bidfloor if no floormodule is available', function() { - const request = spec.buildRequests(bidRequests, bidderRequest); - const requestparse = JSON.parse(request.data); - expect(requestparse.placements[0].bidfloor).to.equal(0.50); - }); - - it('should have 0 bidfloor value', function() { - const request = spec.buildRequests(bidRequestsUserIds, bidderRequest); - const requestparse = JSON.parse(request.data); - expect(requestparse.placements[0].bidfloor).to.equal(0); - }); - - it('should contain gdpr info', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - const requestparse = JSON.parse(request.data); - - expect(requestparse.user.ext.gdpr).to.equal(1); - expect(requestparse.user.ext.consent).to.equal('consentDataString'); - }); - - it('should build a request if Consent but no gdprApplies', function () { - let bidderRequest = { - timeout: 3000, - gdprConsent: { - gdprApplies: false, - consentString: 'consentDataString', - }, - } - const request = spec.buildRequests(bidRequests, bidderRequest); - const requestparse = JSON.parse(request.data); - - expect(requestparse.placements[0].adTypes).to.be.an('array'); - expect(requestparse.placements[0].siteId).to.equal(123456); - expect(requestparse.user.ext.consent).to.equal('consentDataString'); - }); - - it('should build a request if gdprConsent empty', function () { - let bidderRequest = { - timeout: 3000, - gdprConsent: {} - } - const request = spec.buildRequests(bidRequests, bidderRequest); - const requestparse = JSON.parse(request.data); - - expect(requestparse.placements[0].adTypes).to.be.an('array'); - expect(requestparse.placements[0].siteId).to.equal(123456); - }); - - it('should have CCPA Consent if defined', function () { - const uspConsent = '1YYN' - bidderRequest.uspConsent = uspConsent - const request = spec.buildRequests(bidRequests, bidderRequest); - const requestparse = JSON.parse(request.data); - - expect(requestparse.user.ext.us_privacy).to.equal(uspConsent); - }); - - it('should not have CCPA Consent if not defined', function () { - bidderRequest.uspConsent = undefined - const request = spec.buildRequests(bidRequests, bidderRequest); - const requestparse = JSON.parse(request.data); - expect(requestparse.user.ext.us_privacy).to.be.undefined; - }); - - it('should not include schain when not provided', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - const requestparse = JSON.parse(request.data); - expect(requestparse.source).to.not.exist; - }); - - it('should submit coppa if set in config', function () { - sinon.stub(config, 'getConfig') - .withArgs('coppa') - .returns(true); - const request = spec.buildRequests(bidRequests, bidderRequest); - const requestparse = JSON.parse(request.data); - expect(requestparse.user.coppa).to.equal(1); - config.getConfig.restore(); - }); - - it('should send all UserData data', function () { - const request = spec.buildRequests(bidRequestsUserIds, bidderRequest); - const requestparse = JSON.parse(request.data); - expect(requestparse.user.ext.eids).to.be.an('array'); - expect(requestparse.user.ext.eids[0].uids[0].id).to.equal('123456'); - }); - - it('should add referer info', function () { - const bidRequest = Object.assign({}, bidRequests[0]) - const bidderRequ = { - refererInfo: { - referer: 'https://connectad.io/page.html', - reachedTop: true, - numIframes: 2, - stack: [ - 'https://connectad.io/page.html', - 'https://connectad.io/iframe1.html', - 'https://connectad.io/iframe2.html' - ] - } - } - const request = spec.buildRequests([bidRequest], bidderRequ); - const requestparse = JSON.parse(request.data); - - expect(requestparse.referrer_info).to.exist; - }); - - it('should populate schain', function () { - const bidRequest = Object.assign({}, bidRequests[0], { - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - 'asi': 'reseller1.com', - 'sid': 'absc1', - 'hp': 1 - } - ] - } - }); - - const request = spec.buildRequests([bidRequest], bidderRequest); - const requestparse = JSON.parse(request.data); - expect(requestparse.source.ext.schain).to.deep.equal({ - ver: '1.0', - complete: 1, - nodes: [ - { - 'asi': 'reseller1.com', - 'sid': 'absc1', - 'hp': 1 - } - ] - }); - }); - }); - - describe('bid responses', function () { - it('should return complete bid response', function () { - let serverResponse = { - body: { - decisions: { - '2f95c00074b931': { - adId: '0', - contents: [ - { - body: '<<<---- Creative --->>>' - } - ], - height: '250', - width: '300', - pricing: { - clearPrice: 11.899999999999999 - } - } - } - } - }; - const request = spec.buildRequests(bidRequests, bidderRequest); - const bids = spec.interpretResponse(serverResponse, request); - - expect(bids).to.be.lengthOf(1); - expect(bids[0].cpm).to.equal(11.899999999999999); - expect(bids[0].width).to.equal('300'); - expect(bids[0].height).to.equal('250'); - expect(bids[0].ad).to.have.length.above(1); - }); - - it('should return empty bid response', function () { - let serverResponse = { - body: { - decisions: [] - } - }; - const request = spec.buildRequests(bidRequests, bidderRequest); - const bids = spec.interpretResponse(serverResponse, request); - expect(bids).to.be.lengthOf(0); - }); - - it('should return empty bid response on incorrect size', function () { - let serverResponse = { - body: { - decisions: { - '2f95c00074b931': { - adId: '0', - contents: [ - { - body: '<<<---- Creative --->>>' - } - ], - height: '160', - width: '600', - pricing: { - clearPrice: 0 - } - } - } - } - }; - const request = spec.buildRequests(bidRequests, bidderRequest); - const bids = spec.interpretResponse(serverResponse, request); - expect(bids).to.be.lengthOf(0); - }); - - it('should return empty bid response on 0 cpm', function () { - let serverResponse = { - body: { - decisions: { - '2f95c00074b931': { - adId: '0', - contents: [ - { - body: '<<<---- Creative --->>>' - } - ], - height: '300', - width: '250', - pricing: { - clearPrice: 0 - } - } - } - } - }; - const request = spec.buildRequests(bidRequests, bidderRequest); - const bids = spec.interpretResponse(serverResponse, request); - expect(bids).to.be.lengthOf(0); - }); - - it('should process a deal id', function () { - let serverResponse = { - body: { - decisions: { - '2f95c00074b931': { - adId: '0', - dealid: 'ABC90210', - contents: [ - { - body: '<<<---- Creative --->>>' - } - ], - height: '300', - width: '250', - pricing: { - clearPrice: 11.899999999999999 - } - } - } - } - }; - const request = spec.buildRequests(bidRequests, bidderRequest); - const bids = spec.interpretResponse(serverResponse, request); - expect(bids).to.be.lengthOf(1); - expect(bids[0].dealid).to.equal('ABC90210'); - }); - }); - }); - - describe('getUserSyncs', () => { - let testParams = [ - { - name: 'iframe/no gdpr or ccpa', - arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, null], - expect: { - type: 'iframe', - pixels: ['https://cdn.connectad.io/connectmyusers.php?'] - } - }, - { - name: 'iframe/gdpr', - arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, {gdprApplies: true, consentString: '234234'}], - expect: { - type: 'iframe', - pixels: ['https://cdn.connectad.io/connectmyusers.php?gdpr=1&gdpr_consent=234234&'] - } - }, - { - name: 'iframe/ccpa', - arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, null, 'YN12'], - expect: { - type: 'iframe', - pixels: ['https://cdn.connectad.io/connectmyusers.php?us_privacy=YN12&'] - } - }, - { - name: 'iframe/ccpa & gdpr', - arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, {gdprApplies: true, consentString: '234234'}, 'YN12'], - expect: { - type: 'iframe', - pixels: ['https://cdn.connectad.io/connectmyusers.php?gdpr=1&gdpr_consent=234234&us_privacy=YN12&'] - } - } - ]; - - for (let i = 0; i < testParams.length; i++) { - let currParams = testParams[i]; - it(currParams.name, function () { - const result = spec.getUserSyncs.apply(this, currParams.arguments); - expect(result).to.have.lengthOf(currParams.expect.pixels.length); - for (let ix = 0; ix < currParams.expect.pixels.length; ix++) { - expect(result[ix].url).to.equal(currParams.expect.pixels[ix]); - expect(result[ix].type).to.equal(currParams.expect.type); - } - }); - } - }); -}); diff --git a/test/spec/modules/consentManagementUsp_spec.js b/test/spec/modules/consentManagementUsp_spec.js deleted file mode 100644 index 7d3cd48a8e4..00000000000 --- a/test/spec/modules/consentManagementUsp_spec.js +++ /dev/null @@ -1,371 +0,0 @@ -import { - setConsentConfig, - requestBidsHook, - resetConsentData, - consentAPI, - consentTimeout, - staticConsentData -} from 'modules/consentManagementUsp.js'; -import * as utils from 'src/utils.js'; -import { config } from 'src/config.js'; -import { uspDataHandler } from 'src/adapterManager.js'; - -let assert = require('chai').assert; -let expect = require('chai').expect; - -function createIFrameMarker() { - var ifr = document.createElement('iframe'); - ifr.width = 0; - ifr.height = 0; - ifr.name = '__uspapiLocator'; - document.body.appendChild(ifr); - return ifr; -} - -describe('consentManagement', function () { - describe('setConsentConfig tests:', function () { - describe('empty setConsentConfig value', function () { - beforeEach(function () { - sinon.stub(utils, 'logInfo'); - sinon.stub(utils, 'logWarn'); - }); - - afterEach(function () { - utils.logInfo.restore(); - utils.logWarn.restore(); - config.resetConfig(); - resetConsentData(); - }); - - it('should not run if no config', function () { - setConsentConfig({}); - expect(consentAPI).to.be.undefined; - expect(consentTimeout).to.be.undefined; - sinon.assert.callCount(utils.logWarn, 1); - }); - - it('should use system default values', function () { - setConsentConfig({usp: {}}); - expect(consentAPI).to.be.equal('iab'); - expect(consentTimeout).to.be.equal(50); - sinon.assert.callCount(utils.logInfo, 3); - }); - - it('should exit the consent manager if config.usp is not an object', function() { - setConsentConfig({}); - expect(consentAPI).to.be.undefined; - sinon.assert.calledOnce(utils.logWarn); - sinon.assert.notCalled(utils.logInfo); - }); - - it('should exit the consent manager if only config.gdpr is an object', function() { - setConsentConfig({ gdpr: { cmpApi: 'iab' } }); - expect(consentAPI).to.be.undefined; - sinon.assert.calledOnce(utils.logWarn); - sinon.assert.notCalled(utils.logInfo); - }); - - it('should exit consentManagementUsp module if config is "undefined"', function() { - setConsentConfig(undefined); - expect(consentAPI).to.be.undefined; - sinon.assert.calledOnce(utils.logWarn); - sinon.assert.notCalled(utils.logInfo); - }); - }); - - describe('valid setConsentConfig value', function () { - afterEach(function () { - config.resetConfig(); - $$PREBID_GLOBAL$$.requestBids.removeAll(); - }); - - it('results in all user settings overriding system defaults', function () { - let allConfig = { - usp: { - cmpApi: 'daa', - timeout: 7500 - } - }; - - setConsentConfig(allConfig); - expect(consentAPI).to.be.equal('daa'); - expect(consentTimeout).to.be.equal(7500); - }); - }); - - describe('static consent string setConsentConfig value', () => { - afterEach(() => { - config.resetConfig(); - $$PREBID_GLOBAL$$.requestBids.removeAll(); - }); - it('results in user settings overriding system defaults', () => { - let staticConfig = { - usp: { - cmpApi: 'static', - timeout: 7500, - consentData: { - getUSPData: { - uspString: '1YYY' - } - } - } - }; - - setConsentConfig(staticConfig); - expect(consentAPI).to.be.equal('static'); - expect(consentTimeout).to.be.equal(0); // should always return without a timeout when config is used - expect(staticConsentData.usPrivacy).to.be.equal(staticConfig.usp.consentData.getUSPData.uspString); - }); - }); - }); - - describe('requestBidsHook tests:', function () { - let goodConfig = { - usp: { - cmpApi: 'iab', - timeout: 7500 - } - }; - - let noConfig = {}; - - let didHookReturn; - - afterEach(function () { - uspDataHandler.consentData = null; - resetConsentData(); - }); - - describe('error checks:', function () { - beforeEach(function () { - didHookReturn = false; - sinon.stub(utils, 'logWarn'); - sinon.stub(utils, 'logError'); - }); - - afterEach(function () { - utils.logWarn.restore(); - utils.logError.restore(); - config.resetConfig(); - $$PREBID_GLOBAL$$.requestBids.removeAll(); - resetConsentData(); - }); - - it('should throw a warning and return to hooked function when an unknown USPAPI framework ID is used', function () { - let badCMPConfig = { usp: { cmpApi: 'bad' } }; - setConsentConfig(badCMPConfig); - expect(consentAPI).to.be.equal(badCMPConfig.usp.cmpApi); - requestBidsHook(() => { didHookReturn = true; }, {}); - let consent = uspDataHandler.getConsentData(); - sinon.assert.calledOnce(utils.logWarn); - expect(didHookReturn).to.be.true; - expect(consent).to.be.null; - }); - - it('should throw proper errors when USP config is not found', function () { - setConsentConfig(noConfig); - requestBidsHook(() => { didHookReturn = true; }, {}); - let consent = uspDataHandler.getConsentData(); - // throw 2 warnings; one for no bidsBackHandler and for CMP not being found (this is an error due to gdpr config) - sinon.assert.calledTwice(utils.logWarn); - expect(didHookReturn).to.be.true; - expect(consent).to.be.null; - }); - }); - - describe('already known consentData:', function () { - let uspStub = sinon.stub(); - let ifr = null; - - beforeEach(function () { - didHookReturn = false; - ifr = createIFrameMarker(); - window.__uspapi = function() {}; - }); - - afterEach(function () { - config.resetConfig(); - $$PREBID_GLOBAL$$.requestBids.removeAll(); - uspStub.restore(); - document.body.removeChild(ifr); - delete window.__uspapi; - resetConsentData(); - }); - - // from prebid 4425 - "the USP (CCPA) api function __uspapi() always responds synchronously, whether or not privacy data is available, while the GDPR CMP may respond asynchronously - // Because the USP API does not wait for a user response, if it was not successfully obtained before the first auction, we should try again to retrieve privacy data before each subsequent auction. - - it('should not bypass CMP and simply use previously stored consentData', function () { - let testConsentData = { - uspString: '1YY' - }; - - uspStub = sinon.stub(window, '__uspapi').callsFake((...args) => { - args[2](testConsentData, true); - }); - - setConsentConfig(goodConfig); - requestBidsHook(() => {}, {}); - uspStub.restore(); - - // reset the stub to ensure it wasn't called during the second round of calls - uspStub = sinon.stub(window, '__uspapi').callsFake((...args) => { - args[2](testConsentData, true); - }); - - requestBidsHook(() => { didHookReturn = true; }, {}); - - let consent = uspDataHandler.getConsentData(); - expect(didHookReturn).to.be.true; - expect(consent).to.equal(testConsentData.uspString); - sinon.assert.called(uspStub); - }); - }); - - describe('USPAPI workflow for iframed page', function () { - let ifr = null; - let stringifyResponse = false; - - beforeEach(function () { - sinon.stub(utils, 'logError'); - sinon.stub(utils, 'logWarn'); - ifr = createIFrameMarker(); - window.addEventListener('message', uspapiMessageHandler, false); - }); - - afterEach(function () { - config.resetConfig(); - $$PREBID_GLOBAL$$.requestBids.removeAll(); - delete window.__uspapi; - utils.logError.restore(); - utils.logWarn.restore(); - resetConsentData(); - document.body.removeChild(ifr); - window.removeEventListener('message', uspapiMessageHandler); - }); - - function uspapiMessageHandler(event) { - if (event && event.data) { - var data = event.data; - if (data.__uspapiCall) { - var callId = data.__uspapiCall.callId; - var response = { - __uspapiReturn: { - callId, - returnValue: { uspString: '1YY' }, - success: true - } - }; - event.source.postMessage(stringifyResponse ? JSON.stringify(response) : response, '*'); - } - } - } - - // Run tests with JSON response and String response - // from CMP window postMessage listener. - testIFramedPage('with/JSON response', false); - // testIFramedPage('with/String response', true); - - function testIFramedPage(testName, messageFormatString) { - it(`should return the consent string from a postmessage + addEventListener response - ${testName}`, (done) => { - stringifyResponse = messageFormatString; - setConsentConfig(goodConfig); - requestBidsHook(() => { - let consent = uspDataHandler.getConsentData(); - sinon.assert.notCalled(utils.logWarn); - sinon.assert.notCalled(utils.logError); - expect(consent).to.equal('1YY'); - done(); - }, {}); - }); - } - }); - - describe('test without iframe locater', function() { - let uspapiStub = sinon.stub(); - - beforeEach(function () { - didHookReturn = false; - sinon.stub(utils, 'logError'); - sinon.stub(utils, 'logWarn'); - window.__uspapi = function() {}; - }); - - afterEach(function () { - config.resetConfig(); - $$PREBID_GLOBAL$$.requestBids.removeAll(); - uspapiStub.restore(); - utils.logError.restore(); - utils.logWarn.restore(); - delete window.__uspapi; - resetConsentData(); - }); - - it('Workflow for normal page withoout iframe locater', function() { - let testConsentData = { - uspString: '1NY' - }; - - uspapiStub = sinon.stub(window, '__uspapi').callsFake((...args) => { - args[2](testConsentData, true); - }); - - setConsentConfig(goodConfig); - requestBidsHook(() => { didHookReturn = true; }, {}); - - let consent = uspDataHandler.getConsentData(); - - sinon.assert.notCalled(utils.logWarn); - sinon.assert.notCalled(utils.logError); - - expect(didHookReturn).to.be.true; - expect(consent).to.equal(testConsentData.uspString); - }); - }); - - describe('USPAPI workflow for normal pages:', function () { - let uspapiStub = sinon.stub(); - let ifr = null; - - beforeEach(function () { - didHookReturn = false; - ifr = createIFrameMarker(); - sinon.stub(utils, 'logError'); - sinon.stub(utils, 'logWarn'); - window.__uspapi = function() {}; - }); - - afterEach(function () { - config.resetConfig(); - $$PREBID_GLOBAL$$.requestBids.removeAll(); - uspapiStub.restore(); - utils.logError.restore(); - utils.logWarn.restore(); - document.body.removeChild(ifr); - delete window.__uspapi; - resetConsentData(); - }); - - it('performs lookup check and stores consentData for a valid existing user', function () { - let testConsentData = { - uspString: '1NY' - }; - - uspapiStub = sinon.stub(window, '__uspapi').callsFake((...args) => { - args[2](testConsentData, true); - }); - - setConsentConfig(goodConfig); - requestBidsHook(() => { didHookReturn = true; }, {}); - - let consent = uspDataHandler.getConsentData(); - - sinon.assert.notCalled(utils.logWarn); - sinon.assert.notCalled(utils.logError); - - expect(didHookReturn).to.be.true; - expect(consent).to.equal(testConsentData.uspString); - }); - }); - }); -}); diff --git a/test/spec/modules/consentManagement_spec.js b/test/spec/modules/consentManagement_spec.js deleted file mode 100644 index 5e9b0f07f46..00000000000 --- a/test/spec/modules/consentManagement_spec.js +++ /dev/null @@ -1,748 +0,0 @@ -import { setConsentConfig, requestBidsHook, resetConsentData, userCMP, consentTimeout, allowAuction, staticConsentData, gdprScope } from 'modules/consentManagement.js'; -import { gdprDataHandler } from 'src/adapterManager.js'; -import * as utils from 'src/utils.js'; -import { config } from 'src/config.js'; - -let expect = require('chai').expect; - -describe('consentManagement', function () { - describe('setConsentConfig tests:', function () { - describe('empty setConsentConfig value', function () { - beforeEach(function () { - sinon.stub(utils, 'logInfo'); - sinon.stub(utils, 'logWarn'); - }); - - afterEach(function () { - utils.logInfo.restore(); - utils.logWarn.restore(); - config.resetConfig(); - resetConsentData(); - }); - - it('should use system default values', function () { - setConsentConfig({}); - expect(userCMP).to.be.equal('iab'); - expect(consentTimeout).to.be.equal(10000); - expect(gdprScope).to.be.equal(false); - sinon.assert.callCount(utils.logInfo, 3); - }); - - it('should exit consent manager if config is not an object', function () { - setConsentConfig(''); - expect(userCMP).to.be.undefined; - sinon.assert.calledOnce(utils.logWarn); - }); - - it('should exit consent manager if gdpr not set with new config structure', function () { - setConsentConfig({ usp: { cmpApi: 'iab', timeout: 50 } }); - expect(userCMP).to.be.undefined; - sinon.assert.calledOnce(utils.logWarn); - }); - - it('should exit consentManagement module if config is "undefined"', function() { - setConsentConfig(undefined); - expect(userCMP).to.be.undefined; - sinon.assert.calledOnce(utils.logWarn); - }); - }); - - describe('valid setConsentConfig value', function () { - afterEach(function () { - config.resetConfig(); - }); - - it('results in all user settings overriding system defaults', function () { - let allConfig = { - cmpApi: 'iab', - timeout: 7500, - allowAuctionWithoutConsent: false, - defaultGdprScope: true - }; - - setConsentConfig(allConfig); - expect(userCMP).to.be.equal('iab'); - expect(consentTimeout).to.be.equal(7500); - expect(allowAuction).to.deep.equal({ - value: false, - definedInConfig: true - }); - expect(gdprScope).to.be.true; - }); - - it('should use new consent manager config structure for gdpr', function () { - setConsentConfig({ - gdpr: { cmpApi: 'daa', timeout: 8700 } - }); - - expect(userCMP).to.be.equal('daa'); - expect(consentTimeout).to.be.equal(8700); - }); - - it('should ignore config.usp and use config.gdpr, with default cmpApi', function () { - setConsentConfig({ - gdpr: { timeout: 5000 }, - usp: { cmpApi: 'daa', timeout: 50 } - }); - - expect(userCMP).to.be.equal('iab'); - expect(consentTimeout).to.be.equal(5000); - }); - - it('should ignore config.usp and use config.gdpr, with default cmpAip and timeout', function () { - setConsentConfig({ - gdpr: {}, - usp: { cmpApi: 'daa', timeout: 50 } - }); - - expect(userCMP).to.be.equal('iab'); - expect(consentTimeout).to.be.equal(10000); - }); - - it('should recognize config.gdpr, with default cmpAip and timeout', function () { - setConsentConfig({ - gdpr: {} - }); - - expect(userCMP).to.be.equal('iab'); - expect(consentTimeout).to.be.equal(10000); - }); - - it('should fallback to old consent manager config object if no config.gdpr', function () { - setConsentConfig({ - cmpApi: 'iab', - timeout: 3333, - allowAuctionWithoutConsent: false, - gdpr: false - }); - - expect(userCMP).to.be.equal('iab'); - expect(consentTimeout).to.be.equal(3333); - expect(allowAuction).to.deep.equal({ - value: false, - definedInConfig: true - }); - expect(gdprScope).to.be.equal(false); - }); - }); - - describe('static consent string setConsentConfig value', () => { - afterEach(() => { - config.resetConfig(); - }); - it('results in user settings overriding system defaults for v1 spec', () => { - let staticConfig = { - cmpApi: 'static', - timeout: 7500, - allowAuctionWithoutConsent: false, - consentData: { - getConsentData: { - 'gdprApplies': true, - 'hasGlobalScope': false, - 'consentData': 'BOOgjO9OOgjO9APABAENAi-AAAAWd7_______9____7_9uz_Gv_r_ff_3nW0739P1A_r_Oz_rm_-zzV44_lpQQRCEA' - }, - getVendorConsents: { - 'metadata': 'BOOgjO9OOgjO9APABAENAi-AAAAWd7_______9____7_9uz_Gv_r_ff_3nW0739P1A_r_Oz_rm_-zzV44_lpQQRCEA', - 'gdprApplies': true, - 'hasGlobalScope': false, - 'isEU': true, - 'cookieVersion': 1, - 'created': '2018-05-29T07:45:48.522Z', - 'lastUpdated': '2018-05-29T07:45:48.522Z', - 'cmpId': 15, - 'cmpVersion': 1, - 'consentLanguage': 'EN', - 'vendorListVersion': 34, - 'maxVendorId': 359, - 'purposeConsents': { - '1': true, - '2': true, - '3': true, - '4': true, - '5': true - }, - 'vendorConsents': { - '1': true, - '2': true, - '3': true, - '4': true, - '5': false - } - } - } - }; - - setConsentConfig(staticConfig); - expect(userCMP).to.be.equal('static'); - expect(consentTimeout).to.be.equal(0); // should always return without a timeout when config is used - expect(allowAuction).to.deep.equal({ - value: false, - definedInConfig: true - }); - expect(staticConsentData).to.be.equal(staticConfig.consentData); - }); - - it('results in user settings overriding system defaults for v2 spec', () => { - let staticConfig = { - cmpApi: 'static', - timeout: 7500, - allowAuctionWithoutConsent: false, - consentData: { - getTCData: { - 'tcString': 'COuqj-POu90rDBcBkBENAZCgAPzAAAPAACiQFwwBAABAA1ADEAbQC4YAYAAgAxAG0A', - 'cmpId': 92, - 'cmpVersion': 100, - 'tcfPolicyVersion': 2, - 'gdprApplies': true, - 'isServiceSpecific': true, - 'useNonStandardStacks': false, - 'purposeOneTreatment': false, - 'publisherCC': 'US', - 'cmpStatus': 'loaded', - 'eventStatus': 'tcloaded', - 'outOfBand': { - 'allowedVendors': {}, - 'discloseVendors': {} - }, - 'purpose': { - 'consents': { - '1': true, - '2': true, - '3': true - }, - 'legitimateInterests': { - '1': false, - '2': false, - '3': false - } - }, - 'vendor': { - 'consents': { - '1': false, - '2': true, - '3': false - }, - 'legitimateInterests': { - '1': false, - '2': true, - '3': false, - '4': false, - '5': false - } - }, - 'specialFeatureOptins': { - '1': false, - '2': false - }, - 'restrictions': {}, - 'publisher': { - 'consents': { - '1': false, - '2': false, - '3': false - }, - 'legitimateInterests': { - '1': false, - '2': false, - '3': false - }, - 'customPurpose': { - 'consents': {}, - 'legitimateInterests': {} - } - } - } - } - }; - - setConsentConfig(staticConfig); - expect(userCMP).to.be.equal('static'); - expect(consentTimeout).to.be.equal(0); // should always return without a timeout when config is used - expect(allowAuction).to.deep.equal({ - value: false, - definedInConfig: true - }); - expect(gdprScope).to.be.equal(false); - expect(staticConsentData).to.be.equal(staticConfig.consentData); - }); - }); - }); - - describe('requestBidsHook tests:', function () { - let goodConfigWithCancelAuction = { - cmpApi: 'iab', - timeout: 7500, - allowAuctionWithoutConsent: false - }; - - let goodConfigWithAllowAuction = { - cmpApi: 'iab', - timeout: 7500, - allowAuctionWithoutConsent: true - }; - - let didHookReturn; - - afterEach(function () { - gdprDataHandler.consentData = null; - resetConsentData(); - }); - - describe('error checks:', function () { - beforeEach(function () { - didHookReturn = false; - sinon.stub(utils, 'logWarn'); - sinon.stub(utils, 'logError'); - }); - - afterEach(function () { - utils.logWarn.restore(); - utils.logError.restore(); - config.resetConfig(); - resetConsentData(); - }); - - it('should throw a warning and return to hooked function when an unknown CMP framework ID is used', function () { - let badCMPConfig = { - cmpApi: 'bad' - }; - setConsentConfig(badCMPConfig); - expect(userCMP).to.be.equal(badCMPConfig.cmpApi); - - requestBidsHook(() => { - didHookReturn = true; - }, {}); - let consent = gdprDataHandler.getConsentData(); - sinon.assert.calledOnce(utils.logWarn); - expect(didHookReturn).to.be.true; - expect(consent).to.be.null; - }); - - it('should throw proper errors when CMP is not found', function () { - setConsentConfig(goodConfigWithCancelAuction); - - requestBidsHook(() => { - didHookReturn = true; - }, {}); - let consent = gdprDataHandler.getConsentData(); - // throw 2 errors; one for no bidsBackHandler and for CMP not being found (this is an error due to gdpr config) - sinon.assert.calledTwice(utils.logError); - expect(didHookReturn).to.be.false; - expect(consent).to.be.null; - }); - }); - - describe('already known consentData:', function () { - let cmpStub = sinon.stub(); - - beforeEach(function () { - didHookReturn = false; - window.__cmp = function () { }; - }); - - afterEach(function () { - config.resetConfig(); - cmpStub.restore(); - delete window.__cmp; - resetConsentData(); - }); - - it('should bypass CMP and simply use previously stored consentData', function () { - let testConsentData = { - gdprApplies: true, - consentData: 'xyz' - }; - - cmpStub = sinon.stub(window, '__cmp').callsFake((...args) => { - args[2](testConsentData); - }); - setConsentConfig(goodConfigWithAllowAuction); - requestBidsHook(() => { }, {}); - cmpStub.restore(); - - // reset the stub to ensure it wasn't called during the second round of calls - cmpStub = sinon.stub(window, '__cmp').callsFake((...args) => { - args[2](testConsentData); - }); - - requestBidsHook(() => { - didHookReturn = true; - }, {}); - let consent = gdprDataHandler.getConsentData(); - - expect(didHookReturn).to.be.true; - expect(consent.consentString).to.equal(testConsentData.consentData); - expect(consent.gdprApplies).to.be.true; - sinon.assert.notCalled(cmpStub); - }); - - it('should not set consent.gdprApplies to true if defaultGdprScope is true', function () { - let testConsentData = { - gdprApplies: false, - consentData: 'xyz' - }; - - cmpStub = sinon.stub(window, '__cmp').callsFake((...args) => { - args[2](testConsentData); - }); - - setConsentConfig({ - cmpApi: 'iab', - timeout: 7500, - defaultGdprScope: true - }); - - requestBidsHook(() => { - didHookReturn = true; - }, {}); - - let consent = gdprDataHandler.getConsentData(); - - expect(consent.gdprApplies).to.be.false; - }); - }); - - describe('iframe tests', function () { - let cmpPostMessageCb = () => { }; - let stringifyResponse; - - function createIFrameMarker(frameName) { - let ifr = document.createElement('iframe'); - ifr.width = 0; - ifr.height = 0; - ifr.name = frameName; - document.body.appendChild(ifr); - return ifr; - } - - function creatCmpMessageHandler(prefix, returnValue) { - return function (event) { - if (event && event.data) { - let data = event.data; - if (data[`${prefix}Call`]) { - let callId = data[`${prefix}Call`].callId; - let response = { - [`${prefix}Return`]: { - callId, - returnValue, - success: true - } - }; - event.source.postMessage(stringifyResponse ? JSON.stringify(response) : response, '*'); - } - } - } - } - - function testIFramedPage(testName, messageFormatString, tarConsentString, ver) { - it(`should return the consent string from a postmessage + addEventListener response - ${testName}`, (done) => { - stringifyResponse = messageFormatString; - setConsentConfig(goodConfigWithAllowAuction); - requestBidsHook(() => { - let consent = gdprDataHandler.getConsentData(); - sinon.assert.notCalled(utils.logError); - expect(consent.consentString).to.equal(tarConsentString); - expect(consent.gdprApplies).to.be.true; - expect(consent.apiVersion).to.equal(ver); - done(); - }, {}); - }); - } - - beforeEach(function () { - sinon.stub(utils, 'logError'); - sinon.stub(utils, 'logWarn'); - }); - - afterEach(function () { - utils.logError.restore(); - utils.logWarn.restore(); - config.resetConfig(); - resetConsentData(); - }); - - describe('v1 CMP workflow for safeframe page', function () { - let registerStub = sinon.stub(); - let ifrSf = null; - beforeEach(function () { - didHookReturn = false; - window.$sf = { - ext: { - register: function () { }, - cmp: function () { } - } - }; - ifrSf = createIFrameMarker('__cmpLocator'); - }); - - afterEach(function () { - delete window.$sf; - registerStub.restore(); - document.body.removeChild(ifrSf); - }); - - it('should return the consent data from a safeframe callback', function () { - let testConsentData = { - data: { - msgName: 'cmpReturn', - vendorConsents: { - metadata: 'abc123def', - gdprApplies: true - }, - vendorConsentData: { - consentData: 'abc123def', - gdprApplies: true - } - } - }; - registerStub = sinon.stub(window.$sf.ext, 'register').callsFake((...args) => { - args[2](testConsentData.data.msgName, testConsentData.data); - }); - - setConsentConfig(goodConfigWithAllowAuction); - requestBidsHook(() => { - didHookReturn = true; - }, { adUnits: [{ sizes: [[300, 250]] }] }); - let consent = gdprDataHandler.getConsentData(); - - sinon.assert.notCalled(utils.logWarn); - sinon.assert.notCalled(utils.logError); - expect(didHookReturn).to.be.true; - expect(consent.consentString).to.equal('abc123def'); - expect(consent.gdprApplies).to.be.true; - expect(consent.apiVersion).to.equal(1); - }); - }); - - describe('v1 CMP workflow for iframe pages', function () { - stringifyResponse = false; - let ifr1 = null; - - beforeEach(function () { - ifr1 = createIFrameMarker('__cmpLocator'); - cmpPostMessageCb = creatCmpMessageHandler('__cmp', { - consentData: 'encoded_consent_data_via_post_message', - gdprApplies: true, - }); - window.addEventListener('message', cmpPostMessageCb, false); - }); - - afterEach(function () { - delete window.__cmp; // deletes the local copy made by the postMessage CMP call function - document.body.removeChild(ifr1); - window.removeEventListener('message', cmpPostMessageCb); - }); - - // Run tests with JSON response and String response - // from CMP window postMessage listener. - testIFramedPage('with/JSON response', false, 'encoded_consent_data_via_post_message', 1); - testIFramedPage('with/String response', true, 'encoded_consent_data_via_post_message', 1); - - it('should contain correct V1 CMP definition', (done) => { - setConsentConfig(goodConfigWithAllowAuction); - requestBidsHook(() => { - const nbArguments = window.__cmp.toString().split('\n')[0].split(', ').length; - expect(nbArguments).to.equal(3); - done(); - }, {}); - }); - }); - - describe('v2 CMP workflow for iframe pages:', function () { - stringifyResponse = false; - let ifr2 = null; - - beforeEach(function () { - ifr2 = createIFrameMarker('__tcfapiLocator'); - cmpPostMessageCb = creatCmpMessageHandler('__tcfapi', { - tcString: 'abc12345234', - gdprApplies: true, - purposeOneTreatment: false, - eventStatus: 'tcloaded' - }); - window.addEventListener('message', cmpPostMessageCb, false); - }); - - afterEach(function () { - delete window.__tcfapi; // deletes the local copy made by the postMessage CMP call function - document.body.removeChild(ifr2); - window.removeEventListener('message', cmpPostMessageCb); - }); - - testIFramedPage('with/JSON response', false, 'abc12345234', 2); - testIFramedPage('with/String response', true, 'abc12345234', 2); - - it('should contain correct v2 CMP definition', (done) => { - setConsentConfig(goodConfigWithAllowAuction); - requestBidsHook(() => { - const nbArguments = window.__tcfapi.toString().split('\n')[0].split(', ').length; - expect(nbArguments).to.equal(4); - done(); - }, {}); - }); - }); - }); - - describe('direct calls to CMP API tests', function () { - let cmpStub = sinon.stub(); - - beforeEach(function () { - didHookReturn = false; - sinon.stub(utils, 'logError'); - sinon.stub(utils, 'logWarn'); - }); - - afterEach(function () { - config.resetConfig(); - cmpStub.restore(); - utils.logError.restore(); - utils.logWarn.restore(); - resetConsentData(); - }); - - describe('v1 CMP workflow for normal pages:', function () { - beforeEach(function () { - window.__cmp = function () { }; - }); - - afterEach(function () { - delete window.__cmp; - }); - - it('performs lookup check and stores consentData for a valid existing user', function () { - let testConsentData = { - gdprApplies: true, - consentData: 'BOJy+UqOJy+UqABAB+AAAAAZ+A==' - }; - cmpStub = sinon.stub(window, '__cmp').callsFake((...args) => { - args[2](testConsentData); - }); - - setConsentConfig(goodConfigWithAllowAuction); - - requestBidsHook(() => { - didHookReturn = true; - }, {}); - let consent = gdprDataHandler.getConsentData(); - - sinon.assert.notCalled(utils.logWarn); - sinon.assert.notCalled(utils.logError); - expect(didHookReturn).to.be.true; - expect(consent.consentString).to.equal(testConsentData.consentData); - expect(consent.gdprApplies).to.be.true; - expect(consent.apiVersion).to.equal(1); - }); - }); - - describe('v2 CMP workflow for normal pages:', function () { - beforeEach(function() { - window.__tcfapi = function () { }; - }); - - afterEach(function () { - delete window.__tcfapi; - }); - - it('performs lookup check and stores consentData for a valid existing user', function () { - let testConsentData = { - tcString: 'abc12345234', - gdprApplies: true, - purposeOneTreatment: false, - eventStatus: 'tcloaded' - }; - cmpStub = sinon.stub(window, '__tcfapi').callsFake((...args) => { - args[2](testConsentData, true); - }); - - setConsentConfig(goodConfigWithAllowAuction); - - requestBidsHook(() => { - didHookReturn = true; - }, {}); - let consent = gdprDataHandler.getConsentData(); - sinon.assert.notCalled(utils.logError); - expect(didHookReturn).to.be.true; - expect(consent.consentString).to.equal(testConsentData.tcString); - expect(consent.gdprApplies).to.be.true; - expect(consent.apiVersion).to.equal(2); - }); - - it('performs lookup check and stores consentData for a valid existing user with additional consent', function () { - let testConsentData = { - tcString: 'abc12345234', - addtlConsent: 'superduperstring', - gdprApplies: true, - purposeOneTreatment: false, - eventStatus: 'tcloaded' - }; - cmpStub = sinon.stub(window, '__tcfapi').callsFake((...args) => { - args[2](testConsentData, true); - }); - - setConsentConfig(goodConfigWithAllowAuction); - - requestBidsHook(() => { - didHookReturn = true; - }, {}); - let consent = gdprDataHandler.getConsentData(); - sinon.assert.notCalled(utils.logError); - expect(didHookReturn).to.be.true; - expect(consent.consentString).to.equal(testConsentData.tcString); - expect(consent.addtlConsent).to.equal(testConsentData.addtlConsent); - expect(consent.gdprApplies).to.be.true; - expect(consent.apiVersion).to.equal(2); - }); - - it('throws an error when processCmpData check fails + does not call requestBids callbcack even when allowAuction is true', function () { - let testConsentData = {}; - let bidsBackHandlerReturn = false; - - cmpStub = sinon.stub(window, '__tcfapi').callsFake((...args) => { - args[2](testConsentData); - }); - - setConsentConfig(goodConfigWithAllowAuction); - - requestBidsHook(() => { - didHookReturn = true; - }, { bidsBackHandler: () => bidsBackHandlerReturn = true }); - let consent = gdprDataHandler.getConsentData(); - - sinon.assert.calledOnce(utils.logError); - sinon.assert.notCalled(utils.logWarn); - expect(didHookReturn).to.be.false; - expect(bidsBackHandlerReturn).to.be.true; - expect(consent).to.be.null; - }); - - it('It still considers it a valid cmp response if gdprApplies is not a boolean', function () { - // gdprApplies is undefined, should just still store consent response but use whatever defaultGdprScope was - let testConsentData = { - tcString: 'abc12345234', - purposeOneTreatment: false, - eventStatus: 'tcloaded' - }; - cmpStub = sinon.stub(window, '__tcfapi').callsFake((...args) => { - args[2](testConsentData, true); - }); - - setConsentConfig({ - cmpApi: 'iab', - timeout: 7500, - defaultGdprScope: true - }); - - requestBidsHook(() => { - didHookReturn = true; - }, {}); - let consent = gdprDataHandler.getConsentData(); - sinon.assert.notCalled(utils.logError); - expect(didHookReturn).to.be.true; - expect(consent.consentString).to.equal(testConsentData.tcString); - expect(consent.gdprApplies).to.be.true; - expect(consent.apiVersion).to.equal(2); - }); - }); - }); - }); -}); diff --git a/test/spec/modules/consumableBidAdapter_spec.js b/test/spec/modules/consumableBidAdapter_spec.js deleted file mode 100644 index 44076194885..00000000000 --- a/test/spec/modules/consumableBidAdapter_spec.js +++ /dev/null @@ -1,342 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/consumableBidAdapter.js'; -import {createBid} from 'src/bidfactory.js'; - -const ENDPOINT = 'https://e.serverbid.com/api/v2'; -const SMARTSYNC_CALLBACK = 'serverbidCallBids'; - -const BIDDER_REQUEST_1 = { - bidderCode: 'consumable', - auctionId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - bidRequest: [ - { - bidder: 'consumable', - params: { - networkId: '9969', - siteId: '730181', - unitId: '123456', - unitName: 'cnsmbl-unit' - }, - placementCode: 'header-bid-tag-1', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - bidId: '23acc48ad47af5', - auctionId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - } - ], - gdprConsent: { - consentString: 'consent-test', - gdprApplies: false - }, - refererInfo: { - referer: 'http://example.com/page.html', - reachedTop: true, - numIframes: 2, - stack: [ - 'http://example.com/page.html', - 'http://example.com/iframe1.html', - 'http://example.com/iframe2.html' - ] - } -}; - -const BIDDER_REQUEST_2 = { - bidderCode: 'consumable', - auctionId: 'a4713c32-3762-4798-b342-4ab810ca770d', - bidderRequestId: '109f2a181342a9', - bidRequest: [ - { - bidder: 'consumable', - params: { - networkId: 9969, - siteId: 730181, - unitId: 123456, - unitName: 'cnsmbl-unit' - }, - placementCode: 'div-gpt-ad-1487778092495-0', - mediaTypes: { - banner: { - sizes: [ - [728, 90], - [970, 90] - ] - } - }, - bidId: '2b0f82502298c9', - bidderRequestId: '109f2a181342a9', - auctionId: 'a4713c32-3762-4798-b342-4ab810ca770d' - }, - { - bidder: 'consumable', - params: { - networkId: 9969, - siteId: 730181, - unitId: 123456, - unitName: 'cnsmbl-unit' - }, - placementCode: 'div-gpt-ad-1487778092495-0', - mediaTypes: { - banner: { - sizes: [ - [728, 90], - [970, 90] - ] - } - }, - bidId: '123', - bidderRequestId: '109f2a181342a9', - auctionId: 'a4713c32-3762-4798-b342-4ab810ca770d' - } - ], - gdprConsent: { - consentString: 'consent-test', - gdprApplies: true - }, - refererInfo: { - referer: 'http://example.com/page.html', - reachedTop: true, - numIframes: 2, - stack: [ - 'http://example.com/page.html', - 'http://example.com/iframe1.html', - 'http://example.com/iframe2.html' - ] - } -}; - -const BIDDER_REQUEST_EMPTY = { - bidderCode: 'consumable', - auctionId: 'b06458ef-4fe5-4a0b-a61b-bccbcedb7b11', - bidderRequestId: '8c8006750b10fd', - bidRequest: [], - gdprConsent: { - consentString: 'consent-test', - gdprApplies: false - } -}; - -const AD_SERVER_RESPONSE = { - 'headers': null, - 'body': { - 'user': { 'key': 'ue1-2d33e91b71e74929b4aeecc23f4376f1' }, - 'pixels': [{ 'type': 'image', 'url': '//sync.serverbid.com/ss/' }], - 'decisions': { - '2b0f82502298c9': { - 'adId': 2364764, - 'creativeId': 1950991, - 'flightId': 2788300, - 'campaignId': 542982, - 'clickUrl': 'https://e.serverbid.com/r', - 'impressionUrl': 'https://e.serverbid.com/i.gif', - 'contents': [{ - 'type': 'html', - 'body': '', - 'data': { - 'height': 90, - 'width': 728, - 'imageUrl': 'https://static.adzerk.net/Advertisers/b0ab77db8a7848c8b78931aed022a5ef.gif', - 'fileName': 'b0ab77db8a7848c8b78931aed022a5ef.gif' - }, - 'template': 'image' - }], - 'height': 90, - 'width': 728, - 'events': [], - 'pricing': {'price': 0.5, 'clearPrice': 0.5, 'revenue': 0.0005, 'rateType': 2, 'eCPM': 0.5} - }, - '123': { - 'adId': 2364764, - 'creativeId': 1950991, - 'flightId': 2788300, - 'campaignId': 542982, - 'clickUrl': 'https://e.serverbid.com/r', - 'impressionUrl': 'https://e.serverbid.com/i.gif', - 'contents': [{ - 'type': 'html', - 'body': '', - 'data': { - 'height': 90, - 'width': 728, - 'imageUrl': 'https://static.adzerk.net/Advertisers/b0ab77db8a7848c8b78931aed022a5ef.gif', - 'fileName': 'b0ab77db8a7848c8b78931aed022a5ef.gif' - }, - 'template': 'image' - }], - 'height': 90, - 'width': 728, - 'events': [], - 'pricing': {'price': 0.5, 'clearPrice': 0.5, 'revenue': 0.0005, 'rateType': 2, 'eCPM': 0.5} - } - } - } -}; - -const BUILD_REQUESTS_OUTPUT = { - method: 'POST', - url: 'https://e.serverbid.com/api/v2', - data: '', - bidRequest: BIDDER_REQUEST_2.bidRequest, - bidderRequest: BIDDER_REQUEST_2 -}; - -describe('Consumable BidAdapter', function () { - let adapter = spec; - - describe('bid request validation', function () { - it('should accept valid bid requests', function () { - let bid = { - bidder: 'consumable', - params: { - networkId: '9969', - siteId: '123', - unitId: '123456', - unitName: 'cnsmbl-unit' - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should accept valid bid requests with extra fields', function () { - let bid = { - bidder: 'consumable', - params: { - networkId: '9969', - siteId: '123', - unitId: '123456', - unitName: 'cnsmbl-unit', - zoneId: '123' - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should reject bid requests without siteId', function () { - let bid = { - bidder: 'consumable', - params: { - networkId: '9969', - unitId: '123456', - unitName: 'cnsmbl-unit' - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should reject bid requests without networkId', function () { - let bid = { - bidder: 'consumable', - params: { - siteId: '9969', - unitId: '123456', - unitName: 'cnsmbl-unit' - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests validation', function () { - it('creates request data', function () { - let request = spec.buildRequests(BIDDER_REQUEST_1.bidRequest, BIDDER_REQUEST_1); - - expect(request).to.exist.and.to.be.a('object'); - }); - - it('request to consumable should contain a url', function () { - let request = spec.buildRequests(BIDDER_REQUEST_1.bidRequest, BIDDER_REQUEST_1); - - expect(request.url).to.have.string('serverbid.com'); - }); - - it('requires valid bids to make request', function () { - let request = spec.buildRequests(BIDDER_REQUEST_EMPTY.bidRequest, BIDDER_REQUEST_EMPTY); - expect(request.bidRequest).to.be.empty; - }); - - it('sends bid request to ENDPOINT via POST', function () { - let request = spec.buildRequests(BIDDER_REQUEST_1.bidRequest, BIDDER_REQUEST_1); - - expect(request.method).to.have.string('POST'); - }); - - it('passes through bidderRequest', function () { - let request = spec.buildRequests(BIDDER_REQUEST_1.bidRequest, BIDDER_REQUEST_1); - - expect(request.bidderRequest).to.equal(BIDDER_REQUEST_1); - }) - }); - describe('interpretResponse validation', function () { - it('response should have valid bidderCode', function () { - let bidRequest = spec.buildRequests(BIDDER_REQUEST_2.bidRequest, BIDDER_REQUEST_2); - let bid = createBid(1, bidRequest.bidRequest[0]); - - expect(bid.bidderCode).to.equal('consumable'); - }); - - it('response should include objects for all bids', function () { - let bids = spec.interpretResponse(AD_SERVER_RESPONSE, BUILD_REQUESTS_OUTPUT); - expect(bids.length).to.equal(2); - }); - - it('registers bids', function () { - let bids = spec.interpretResponse(AD_SERVER_RESPONSE, BUILD_REQUESTS_OUTPUT); - bids.forEach(b => { - expect(b).to.have.property('cpm'); - expect(b.cpm).to.be.above(0); - expect(b).to.have.property('requestId'); - expect(b).to.have.property('unitId'); - expect(b).to.have.property('unitName'); - expect(b).to.have.property('cpm'); - expect(b).to.have.property('width'); - expect(b).to.have.property('height'); - expect(b).to.have.property('ad'); - expect(b).to.have.property('currency', 'USD'); - expect(b).to.have.property('creativeId'); - expect(b).to.have.property('ttl', 30); - expect(b).to.have.property('netRevenue', true); - expect(b).to.have.property('referrer'); - }); - }); - - it('handles nobid responses', function () { - let EMPTY_RESP = Object.assign({}, AD_SERVER_RESPONSE, {'body': {'decisions': null}}) - let bids = spec.interpretResponse(EMPTY_RESP, BUILD_REQUESTS_OUTPUT); - - expect(bids).to.be.empty; - }); - - it('handles no server response', function () { - let bids = spec.interpretResponse(null, BUILD_REQUESTS_OUTPUT); - - expect(bids).to.be.empty; - }); - }); - describe('getUserSyncs', function () { - let syncOptions = {'iframeEnabled': true}; - - it('handles empty sync options', function () { - let opts = spec.getUserSyncs({}); - - expect(opts).to.be.undefined; - }); - - it('should return a sync url if iframe syncs are enabled', function () { - let opts = spec.getUserSyncs(syncOptions); - - expect(opts.length).to.equal(1); - }); - - it('should return a sync url if pixel syncs are enabled and some are returned from the server', function () { - let syncOptions = {'pixelEnabled': true}; - let opts = spec.getUserSyncs(syncOptions, [AD_SERVER_RESPONSE]); - - expect(opts.length).to.equal(1); - }); - }); -}); diff --git a/test/spec/modules/convergeBidAdapter_spec.js b/test/spec/modules/convergeBidAdapter_spec.js deleted file mode 100644 index e92ed475497..00000000000 --- a/test/spec/modules/convergeBidAdapter_spec.js +++ /dev/null @@ -1,899 +0,0 @@ -import { expect } from 'chai'; -import { spec, resetUserSync, getSyncUrl } from 'modules/convergeBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('ConvergeAdapter', 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 () { - let bid = { - 'bidder': 'converge', - 'params': { - 'uid': '1' - }, - '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(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'uid': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - function parseRequest(url) { - const res = {}; - url.split('&').forEach((it) => { - const couple = it.split('='); - res[couple[0]] = decodeURIComponent(couple[1]); - }); - return res; - } - - const bidderRequest = { - refererInfo: { - referer: 'https://example.com' - } - }; - const referrer = bidderRequest.refererInfo.referer; - - let bidRequests = [ - { - 'bidder': 'converge', - 'params': { - 'uid': '59' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }, - { - 'bidder': 'converge', - 'params': { - 'uid': '59' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90], [300, 250]], - 'bidId': '3150ccb55da321', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }, - { - 'bidder': 'converge', - 'params': { - 'uid': '60' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '42dbe3a7168a6a', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - it('should attach valid params to the tag', function () { - const request = spec.buildRequests([bidRequests[0]], bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'net'); - expect(payload).to.have.property('auids', '59'); - expect(payload).to.have.property('sizes', '300x250,300x600'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - expect(payload).to.have.property('wrapperType', 'Prebid_js'); - expect(payload).to.have.property('wrapperVersion', '$prebid.version$'); - }); - - it('sizes must not be duplicated', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'net'); - expect(payload).to.have.property('auids', '59,59,60'); - expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - }); - - it('pt parameter must be "gross" if params.priceType === "gross"', function () { - bidRequests[1].params.priceType = 'gross'; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'gross'); - expect(payload).to.have.property('auids', '59,59,60'); - expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - delete bidRequests[1].params.priceType; - }); - - it('pt parameter must be "net" or "gross"', function () { - bidRequests[1].params.priceType = 'some'; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'net'); - expect(payload).to.have.property('auids', '59,59,60'); - expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - delete bidRequests[1].params.priceType; - }); - - it('if gdprConsent is present payload must have gdpr params', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {consentString: 'AAA', gdprApplies: true}}, bidderRequest); - const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('gdpr_consent', 'AAA'); - expect(payload).to.have.property('gdpr_applies', '1'); - }); - - it('if gdprApplies is false gdpr_applies must be 0', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {consentString: 'AAA', gdprApplies: false}}, bidderRequest); - const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('gdpr_consent', 'AAA'); - expect(payload).to.have.property('gdpr_applies', '0'); - }); - - it('if gdprApplies is undefined gdpr_applies must be 1', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {consentString: 'AAA'}}, bidderRequest); - const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('gdpr_consent', 'AAA'); - expect(payload).to.have.property('gdpr_applies', '1'); - }); - - it('if usPrivacy is present payload must have us_privacy param', function () { - 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); - expect(payload).to.have.property('us_privacy', '1YNN'); - }); - - it('should convert keyword params to proper form and attaches to request', function () { - const bidRequestWithKeywords = [].concat(bidRequests); - bidRequestWithKeywords[1] = Object.assign({}, - bidRequests[1], - { - params: { - uid: '59', - keywords: { - single: 'val', - singleArr: ['val'], - singleArrNum: [5], - multiValMixed: ['value1', 2, 'value3'], - singleValNum: 123, - emptyStr: '', - emptyArr: [''], - badValue: {'foo': 'bar'} // should be dropped - } - } - } - ); - - const request = spec.buildRequests(bidRequestWithKeywords, bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload.keywords).to.be.an('string'); - payload.keywords = JSON.parse(payload.keywords); - - expect(payload.keywords).to.deep.equal([{ - 'key': 'single', - 'value': ['val'] - }, { - 'key': 'singleArr', - 'value': ['val'] - }, { - 'key': 'singleArrNum', - 'value': ['5'] - }, { - 'key': 'multiValMixed', - 'value': ['value1', '2', 'value3'] - }, { - 'key': 'singleValNum', - 'value': ['123'] - }, { - 'key': 'emptyStr' - }, { - 'key': 'emptyArr' - }]); - }); - }); - - describe('interpretResponse', function () { - const responses = [ - {'bid': [{'price': 1.15, 'adm': '
test content 1
', 'auid': 59, 'h': 250, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.5, 'adm': '
test content 2
', 'auid': 60, 'h': 600, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.15, 'adm': '
test content 3
', 'auid': 59, 'h': 90, 'w': 728}], 'seat': '1'}, - {'bid': [{'price': 0, 'auid': 61, 'h': 250, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0, 'adm': '
test content 5
', 'h': 250, 'w': 300}], 'seat': '1'}, - undefined, - {'bid': [], 'seat': '1'}, - {'seat': '1'}, - ]; - - it('should get correct bid response', function () { - const bidRequests = [ - { - 'bidder': 'converge', - 'params': { - 'uid': '59' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '659423fff799cb', - 'bidderRequestId': '5f2009617a7c0a', - 'auctionId': '1cbd2feafe5e8b', - } - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '659423fff799cb', - 'cpm': 1.15, - 'creativeId': 59, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'bidderCode': 'converge', - 'currency': 'EUR', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': [responses[0]]}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('should get correct multi bid response', function () { - const bidRequests = [ - { - 'bidder': 'converge', - 'params': { - 'uid': '59' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '300bfeb0d71a5b', - 'bidderRequestId': '2c2bb1972df9a', - 'auctionId': '1fa09aee5c8c99', - }, - { - 'bidder': 'converge', - 'params': { - 'uid': '60' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '4dff80cc4ee346', - 'bidderRequestId': '2c2bb1972df9a', - 'auctionId': '1fa09aee5c8c99', - }, - { - 'bidder': 'converge', - 'params': { - 'uid': '59' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '5703af74d0472a', - 'bidderRequestId': '2c2bb1972df9a', - 'auctionId': '1fa09aee5c8c99', - } - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '300bfeb0d71a5b', - 'cpm': 1.15, - 'creativeId': 59, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'bidderCode': 'converge', - 'currency': 'EUR', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '4dff80cc4ee346', - 'cpm': 0.5, - 'creativeId': 60, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'ad': '
test content 2
', - 'bidderCode': 'converge', - 'currency': 'EUR', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '5703af74d0472a', - 'cpm': 0.15, - 'creativeId': 59, - 'dealId': undefined, - 'width': 728, - 'height': 90, - 'ad': '
test content 3
', - 'bidderCode': 'converge', - 'currency': 'EUR', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': responses.slice(0, 3)}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('handles wrong and nobid responses', function () { - const bidRequests = [ - { - 'bidder': 'converge', - 'params': { - 'uid': '61' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '300bfeb0d7190gf', - 'bidderRequestId': '2c2bb1972d23af', - 'auctionId': '1fa09aee5c84d34', - }, - { - 'bidder': 'converge', - 'params': { - 'uid': '65' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '300bfeb0d71321', - 'bidderRequestId': '2c2bb1972d23af', - 'auctionId': '1fa09aee5c84d34', - }, - { - 'bidder': 'converge', - 'params': { - 'uid': '70' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '300bfeb0d7183bb', - 'bidderRequestId': '2c2bb1972d23af', - 'auctionId': '1fa09aee5c84d34', - } - ]; - const request = spec.buildRequests(bidRequests); - const result = spec.interpretResponse({'body': {'seatbid': responses.slice(3)}}, request); - expect(result.length).to.equal(0); - }); - - it('complicated case', function () { - const fullResponse = [ - {'bid': [{'price': 1.15, 'adm': '
test content 1
', 'auid': 59, 'h': 250, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.5, 'adm': '
test content 2
', 'auid': 60, 'h': 600, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.15, 'adm': '
test content 3
', 'auid': 59, 'h': 90, 'w': 728}], 'seat': '1'}, - {'bid': [{'price': 0.15, 'adm': '
test content 4
', 'auid': 59, 'h': 600, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.5, 'adm': '
test content 5
', 'auid': 60, 'h': 600, 'w': 350}], 'seat': '1'}, - ]; - const bidRequests = [ - { - 'bidder': 'converge', - 'params': { - 'uid': '59' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '2164be6358b9', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'converge', - 'params': { - 'uid': '59' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '326bde7fbf69', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'converge', - 'params': { - 'uid': '60' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '4e111f1b66e4', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'converge', - 'params': { - 'uid': '59' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '26d6f897b516', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'converge', - 'params': { - 'uid': '60' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '1751cd90161', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - } - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '2164be6358b9', - 'cpm': 1.15, - 'creativeId': 59, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'bidderCode': 'converge', - 'currency': 'EUR', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '4e111f1b66e4', - 'cpm': 0.5, - 'creativeId': 60, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'ad': '
test content 2
', - 'bidderCode': 'converge', - 'currency': 'EUR', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '26d6f897b516', - 'cpm': 0.15, - 'creativeId': 59, - 'dealId': undefined, - 'width': 728, - 'height': 90, - 'ad': '
test content 3
', - 'bidderCode': 'converge', - 'currency': 'EUR', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '326bde7fbf69', - 'cpm': 0.15, - 'creativeId': 59, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'ad': '
test content 4
', - 'bidderCode': 'converge', - 'currency': 'EUR', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': fullResponse}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('dublicate uids and sizes in one slot', function () { - const fullResponse = [ - {'bid': [{'price': 1.15, 'adm': '
test content 1
', 'auid': 59, 'h': 250, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.5, 'adm': '
test content 2
', 'auid': 59, 'h': 250, 'w': 300}], 'seat': '1'}, - ]; - const bidRequests = [ - { - 'bidder': 'converge', - 'params': { - 'uid': '59' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '5126e301f4be', - 'bidderRequestId': '171c5405a390', - 'auctionId': '35bcbc0f7e79c', - }, - { - 'bidder': 'converge', - 'params': { - 'uid': '59' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '57b2ebe70e16', - 'bidderRequestId': '171c5405a390', - 'auctionId': '35bcbc0f7e79c', - }, - { - 'bidder': 'converge', - 'params': { - 'uid': '59' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '225fcd44b18c', - 'bidderRequestId': '171c5405a390', - 'auctionId': '35bcbc0f7e79c', - } - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '5126e301f4be', - 'cpm': 1.15, - 'creativeId': 59, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'bidderCode': 'converge', - 'currency': 'EUR', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '57b2ebe70e16', - 'cpm': 0.5, - 'creativeId': 59, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 2
', - 'bidderCode': 'converge', - 'currency': 'EUR', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': fullResponse}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - }); - - it('should get correct video bid response', function () { - const bidRequests = [ - { - 'bidder': 'converge', - 'params': { - 'uid': '58' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '57dfefb80eca', - 'bidderRequestId': '20394420a762a2', - 'auctionId': '140132d07b031', - 'mediaTypes': { - 'video': { - 'context': 'instream' - } - } - }, - { - 'bidder': 'converge', - 'params': { - 'uid': '60' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': 'e893c787c22dd', - 'bidderRequestId': '20394420a762a2', - 'auctionId': '140132d07b031', - 'mediaTypes': { - 'video': { - 'context': 'instream' - } - } - } - ]; - const response = [ - {'bid': [{'price': 1.15, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 58, content_type: 'video', w: 300, h: 600}], 'seat': '2'}, - {'bid': [{'price': 1.00, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 60, content_type: 'video'}], 'seat': '2'} - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '57dfefb80eca', - 'cpm': 1.15, - 'creativeId': 58, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'bidderCode': 'converge', - 'currency': 'EUR', - 'mediaType': 'video', - 'netRevenue': true, - 'ttl': 360, - 'vastXml': '\n<\/Ad>\n<\/VAST>', - 'adResponse': { - 'content': '\n<\/Ad>\n<\/VAST>' - } - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': response}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('should have right renderer in the bid response', function () { - const spySetRenderer = sinon.spy(); - const stubRenderer = { - setRender: spySetRenderer - }; - const spyRendererInstall = sinon.spy(function() { return stubRenderer; }); - const stubRendererConst = { - install: spyRendererInstall - }; - const bidRequests = [ - { - 'bidder': 'converge', - 'params': { - 'uid': '58' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': 'e6e65553fc8', - 'bidderRequestId': '1380f393215dc7', - 'auctionId': '10b8d2f3c697e3', - 'mediaTypes': { - 'video': { - 'context': 'outstream' - } - } - }, - { - 'bidder': 'converge', - 'params': { - 'uid': '60' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': 'c8fdcb3f269f', - 'bidderRequestId': '1380f393215dc7', - 'auctionId': '10b8d2f3c697e3' - }, - { - 'bidder': 'converge', - 'params': { - 'uid': '61' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '1de036c37685', - 'bidderRequestId': '1380f393215dc7', - 'auctionId': '10b8d2f3c697e3', - 'renderer': {} - } - ]; - const response = [ - {'bid': [{'price': 1.15, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 58, content_type: 'video', w: 300, h: 600}], 'seat': '2'}, - {'bid': [{'price': 1.00, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 60, content_type: 'video', w: 300, h: 250}], 'seat': '2'}, - {'bid': [{'price': 1.20, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 61, content_type: 'video', w: 300, h: 250}], 'seat': '2'} - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': 'e6e65553fc8', - 'cpm': 1.15, - 'creativeId': 58, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'bidderCode': 'converge', - 'currency': 'EUR', - 'mediaType': 'video', - 'netRevenue': true, - 'ttl': 360, - 'vastXml': '\n<\/Ad>\n<\/VAST>', - 'adResponse': { - 'content': '\n<\/Ad>\n<\/VAST>' - }, - 'renderer': stubRenderer - }, - { - 'requestId': 'c8fdcb3f269f', - 'cpm': 1.00, - 'creativeId': 60, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'bidderCode': 'converge', - 'currency': 'EUR', - 'mediaType': 'video', - 'netRevenue': true, - 'ttl': 360, - 'vastXml': '\n<\/Ad>\n<\/VAST>', - 'adResponse': { - 'content': '\n<\/Ad>\n<\/VAST>' - }, - 'renderer': stubRenderer - }, - { - 'requestId': '1de036c37685', - 'cpm': 1.20, - 'creativeId': 61, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'bidderCode': 'converge', - 'currency': 'EUR', - 'mediaType': 'video', - 'netRevenue': true, - 'ttl': 360, - 'vastXml': '\n<\/Ad>\n<\/VAST>', - 'adResponse': { - 'content': '\n<\/Ad>\n<\/VAST>' - } - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': response}}, request, stubRendererConst); - - expect(spySetRenderer.calledTwice).to.equal(true); - expect(spySetRenderer.getCall(0).args[0]).to.be.a('function'); - expect(spySetRenderer.getCall(1).args[0]).to.be.a('function'); - - expect(spyRendererInstall.calledTwice).to.equal(true); - expect(spyRendererInstall.getCall(0).args[0]).to.deep.equal({ - id: 'e6e65553fc8', - url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', - loaded: false - }); - expect(spyRendererInstall.getCall(1).args[0]).to.deep.equal({ - id: 'c8fdcb3f269f', - url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', - loaded: false - }); - - expect(result).to.deep.equal(expectedResponse); - }); - - describe('user sync', function () { - const syncUrl = getSyncUrl(); - - beforeEach(function () { - resetUserSync(); - }); - - it('should register sync image', function () { - let syncs = spec.getUserSyncs({ - pixelEnabled: true - }); - - expect(syncs).to.deep.equal({type: 'image', url: syncUrl}); - }); - - it('should not register sync image more than once', function () { - let syncs = spec.getUserSyncs({ - pixelEnabled: true - }); - expect(syncs).to.deep.equal({type: 'image', url: syncUrl}); - - // when called again, should still have only been called once - syncs = spec.getUserSyncs(); - expect(syncs).to.equal(undefined); - }); - - it('should pass gdpr params if consent is true', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - gdprApplies: true, consentString: 'foo' - })).to.deep.equal({ - type: 'image', url: `${syncUrl}&gdpr=1&gdpr_consent=foo` - }); - }); - - it('should pass gdpr params if consent is false', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - gdprApplies: false, consentString: 'foo' - })).to.deep.equal({ - type: 'image', url: `${syncUrl}&gdpr=0&gdpr_consent=foo` - }); - }); - - it('should pass gdpr param gdpr_consent only when gdprApplies is undefined', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - consentString: 'foo' - })).to.deep.equal({ - type: 'image', url: `${syncUrl}&gdpr_consent=foo` - }); - }); - - it('should pass no params if gdpr consentString is not defined', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {})).to.deep.equal({ - type: 'image', url: syncUrl - }); - }); - - it('should pass no params if gdpr consentString is a number', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - consentString: 0 - })).to.deep.equal({ - type: 'image', url: syncUrl - }); - }); - - it('should pass no params if gdpr consentString is null', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - consentString: null - })).to.deep.equal({ - type: 'image', url: syncUrl - }); - }); - - it('should pass no params if gdpr consentString is a object', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - consentString: {} - })).to.deep.equal({ - type: 'image', url: syncUrl - }); - }); - - it('should pass no params if gdpr is not defined', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, undefined)).to.deep.equal({ - type: 'image', url: syncUrl - }); - }); - - it('should pass usPrivacy param if it is available', function() { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {}, '1YNN')).to.deep.equal({ - type: 'image', url: `${syncUrl}&us_privacy=1YNN` - }); - }); - }); -}); diff --git a/test/spec/modules/conversantBidAdapter_spec.js b/test/spec/modules/conversantBidAdapter_spec.js deleted file mode 100644 index 1c24fb7694a..00000000000 --- a/test/spec/modules/conversantBidAdapter_spec.js +++ /dev/null @@ -1,591 +0,0 @@ -import {expect} from 'chai'; -import {spec, storage} from 'modules/conversantBidAdapter.js'; -import * as utils from 'src/utils.js'; -import { createEidsArray } from 'modules/userId/eids.js'; - -describe('Conversant adapter tests', function() { - const siteId = '108060'; - const versionPattern = /^\d+\.\d+\.\d+(.)*$/; - - const bidRequests = [ - // banner with single size - { - bidder: 'conversant', - params: { - site_id: siteId, - position: 1, - tag_id: 'tagid-1', - bidfloor: 0.5 - }, - placementCode: 'pcode000', - transactionId: 'tx000', - sizes: [[300, 250]], - bidId: 'bid000', - bidderRequestId: '117d765b87bed38', - auctionId: 'req000' - }, - // banner with sizes in mediaTypes.banner.sizes - { - bidder: 'conversant', - params: { - site_id: siteId - }, - mediaTypes: { - banner: { - sizes: [[728, 90], [468, 60]] - } - }, - placementCode: 'pcode001', - transactionId: 'tx001', - bidId: 'bid001', - bidderRequestId: '117d765b87bed38', - auctionId: 'req000' - }, - // banner with tag id and position - { - bidder: 'conversant', - params: { - site_id: siteId, - position: 2, - tag_id: '' - }, - placementCode: 'pcode002', - transactionId: 'tx002', - sizes: [[300, 600], [160, 600]], - bidId: 'bid002', - bidderRequestId: '117d765b87bed38', - auctionId: 'req000' - }, - // video with single size - { - bidder: 'conversant', - params: { - site_id: siteId, - api: [2], - protocols: [1, 2], - mimes: ['video/mp4', 'video/x-flv'], - maxduration: 30 - }, - mediaTypes: { - video: { - context: 'instream', - playerSize: [632, 499], - } - }, - placementCode: 'pcode003', - transactionId: 'tx003', - sizes: [640, 480], - bidId: 'bid003', - bidderRequestId: '117d765b87bed38', - auctionId: 'req000' - }, - // video with playerSize - { - bidder: 'conversant', - params: { - site_id: siteId, - maxduration: 30, - api: [2, 3] - }, - mediaTypes: { - video: { - context: 'instream', - playerSize: [1024, 768], - api: [1, 2], - protocols: [1, 2, 3], - mimes: ['video/mp4', 'video/x-flv'] - } - }, - placementCode: 'pcode004', - transactionId: 'tx004', - bidId: 'bid004', - bidderRequestId: '117d765b87bed38', - auctionId: 'req000' - }, - // video without sizes - { - bidder: 'conversant', - params: { - site_id: siteId - }, - mediaTypes: { - video: { - context: 'instream', - mimes: ['video/mp4', 'video/x-flv'] - } - }, - placementCode: 'pcode005', - transactionId: 'tx005', - bidId: 'bid005', - bidderRequestId: '117d765b87bed38', - auctionId: 'req000' - }]; - - const bidResponses = { - body: { - id: 'req000', - seatbid: [{ - bid: [{ - nurl: 'notify000', - adm: 'markup000', - crid: '1000', - impid: 'bid000', - price: 0.99, - w: 300, - h: 250, - adomain: ['https://example.com'], - id: 'bid000' - }, { - impid: 'bid001', - price: 0.00000, - id: 'bid001' - }, { - nurl: 'notify002', - adm: 'markup002', - crid: '1002', - impid: 'bid002', - price: 2.99, - w: 300, - h: 600, - adomain: ['https://example.com'], - id: 'bid002' - }, { - nurl: 'notify003', - adm: 'markup003', - crid: '1003', - impid: 'bid003', - price: 3.99, - adomain: ['https://example.com'], - id: 'bid003' - }, { - nurl: 'notify004', - adm: '', - crid: '1004', - impid: 'bid004', - price: 4.99, - adomain: ['https://example.com'], - id: 'bid004' - }] - }] - }, - headers: {}}; - - it('Verify basic properties', function() { - expect(spec.code).to.equal('conversant'); - expect(spec.aliases).to.be.an('array').with.lengthOf(1); - expect(spec.aliases[0]).to.equal('cnvr'); - expect(spec.supportedMediaTypes).to.be.an('array').with.lengthOf(2); - expect(spec.supportedMediaTypes[1]).to.equal('video'); - }); - - 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(bidRequests[0])).to.be.true; - expect(spec.isBidRequestValid(bidRequests[1])).to.be.true; - expect(spec.isBidRequestValid(bidRequests[2])).to.be.true; - expect(spec.isBidRequestValid(bidRequests[3])).to.be.true; - expect(spec.isBidRequestValid(bidRequests[4])).to.be.true; - expect(spec.isBidRequestValid(bidRequests[5])).to.be.true; - - const simpleVideo = JSON.parse(JSON.stringify(bidRequests[3])); - simpleVideo.params.site_id = 123; - expect(spec.isBidRequestValid(simpleVideo)).to.be.false; - simpleVideo.params.site_id = siteId; - simpleVideo.params.mimes = [1, 2, 3]; - expect(spec.isBidRequestValid(simpleVideo)).to.be.false; - simpleVideo.params.mimes = 'bad type'; - expect(spec.isBidRequestValid(simpleVideo)).to.be.false; - delete simpleVideo.params.mimes; - expect(spec.isBidRequestValid(simpleVideo)).to.be.true; - }); - - it('Verify buildRequest', function() { - const page = 'http://test.com?a=b&c=123'; - const bidderRequest = { - refererInfo: { - referer: page - } - }; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.method).to.equal('POST'); - expect(request.url).to.equal('https://web.hb.ad.cpe.dotomi.com/cvx/client/hb/ortb/25'); - const payload = request.data; - - expect(payload).to.have.property('id', 'req000'); - expect(payload).to.have.property('at', 1); - expect(payload).to.have.property('imp'); - expect(payload.imp).to.be.an('array').with.lengthOf(6); - - expect(payload.imp[0]).to.have.property('id', 'bid000'); - expect(payload.imp[0]).to.have.property('secure', 1); - expect(payload.imp[0]).to.have.property('bidfloor', 0.5); - expect(payload.imp[0]).to.have.property('displaymanager', 'Prebid.js'); - expect(payload.imp[0]).to.have.property('displaymanagerver').that.matches(versionPattern); - expect(payload.imp[0]).to.have.property('tagid', 'tagid-1'); - 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]).to.not.have.property('video'); - - expect(payload.imp[1]).to.have.property('id', 'bid001'); - expect(payload.imp[1]).to.have.property('secure', 1); - expect(payload.imp[1]).to.have.property('bidfloor', 0); - expect(payload.imp[1]).to.have.property('displaymanager', 'Prebid.js'); - expect(payload.imp[1]).to.have.property('displaymanagerver').that.matches(versionPattern); - expect(payload.imp[1]).to.not.have.property('tagid'); - 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[2]).to.have.property('id', 'bid002'); - expect(payload.imp[2]).to.have.property('secure', 1); - expect(payload.imp[2]).to.have.property('bidfloor', 0); - expect(payload.imp[2]).to.have.property('displaymanager', 'Prebid.js'); - expect(payload.imp[2]).to.have.property('displaymanagerver').that.matches(versionPattern); - 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[3]).to.have.property('id', 'bid003'); - expect(payload.imp[3]).to.have.property('secure', 1); - expect(payload.imp[3]).to.have.property('bidfloor', 0); - expect(payload.imp[3]).to.have.property('displaymanager', 'Prebid.js'); - expect(payload.imp[3]).to.have.property('displaymanagerver').that.matches(versionPattern); - expect(payload.imp[3]).to.not.have.property('tagid'); - expect(payload.imp[3]).to.have.property('video'); - expect(payload.imp[3].video).to.not.have.property('pos'); - expect(payload.imp[3].video).to.have.property('w', 632); - expect(payload.imp[3].video).to.have.property('h', 499); - expect(payload.imp[3].video).to.have.property('mimes'); - expect(payload.imp[3].video.mimes).to.deep.equal(['video/mp4', 'video/x-flv']); - expect(payload.imp[3].video).to.have.property('protocols'); - expect(payload.imp[3].video.protocols).to.deep.equal([1, 2]); - expect(payload.imp[3].video).to.have.property('api'); - expect(payload.imp[3].video.api).to.deep.equal([2]); - expect(payload.imp[3].video).to.have.property('maxduration', 30); - expect(payload.imp[3]).to.not.have.property('banner'); - - expect(payload.imp[4]).to.have.property('id', 'bid004'); - expect(payload.imp[4]).to.have.property('secure', 1); - expect(payload.imp[4]).to.have.property('bidfloor', 0); - expect(payload.imp[4]).to.have.property('displaymanager', 'Prebid.js'); - expect(payload.imp[4]).to.have.property('displaymanagerver').that.matches(versionPattern); - expect(payload.imp[4]).to.not.have.property('tagid'); - expect(payload.imp[4]).to.have.property('video'); - expect(payload.imp[4].video).to.not.have.property('pos'); - expect(payload.imp[4].video).to.have.property('w', 1024); - expect(payload.imp[4].video).to.have.property('h', 768); - expect(payload.imp[4].video).to.have.property('mimes'); - expect(payload.imp[4].video.mimes).to.deep.equal(['video/mp4', 'video/x-flv']); - expect(payload.imp[4].video).to.have.property('protocols'); - expect(payload.imp[4].video.protocols).to.deep.equal([1, 2, 3]); - expect(payload.imp[4].video).to.have.property('api'); - expect(payload.imp[4].video.api).to.deep.equal([2, 3]); - expect(payload.imp[4].video).to.have.property('maxduration', 30); - expect(payload.imp[4]).to.not.have.property('banner'); - - expect(payload.imp[5]).to.have.property('id', 'bid005'); - expect(payload.imp[5]).to.have.property('secure', 1); - expect(payload.imp[5]).to.have.property('bidfloor', 0); - expect(payload.imp[5]).to.have.property('displaymanager', 'Prebid.js'); - expect(payload.imp[5]).to.have.property('displaymanagerver').that.matches(versionPattern); - expect(payload.imp[5]).to.not.have.property('tagid'); - expect(payload.imp[5]).to.have.property('video'); - expect(payload.imp[5].video).to.not.have.property('pos'); - expect(payload.imp[5].video).to.not.have.property('w'); - expect(payload.imp[5].video).to.not.have.property('h'); - expect(payload.imp[5].video).to.have.property('mimes'); - expect(payload.imp[5].video.mimes).to.deep.equal(['video/mp4', 'video/x-flv']); - expect(payload.imp[5].video).to.not.have.property('protocols'); - expect(payload.imp[5].video).to.not.have.property('api'); - expect(payload.imp[5].video).to.not.have.property('maxduration'); - expect(payload.imp[5]).to.not.have.property('banner'); - - expect(payload).to.have.property('site'); - expect(payload.site).to.have.property('id', siteId); - expect(payload.site).to.have.property('mobile').that.is.oneOf([0, 1]); - - expect(payload.site).to.have.property('page', page); - - expect(payload).to.have.property('device'); - expect(payload.device).to.have.property('w', screen.width); - expect(payload.device).to.have.property('h', screen.height); - expect(payload.device).to.have.property('dnt').that.is.oneOf([0, 1]); - expect(payload.device).to.have.property('ua', navigator.userAgent); - - expect(payload).to.not.have.property('user'); // there should be no user by default - }); - - it('Verify override url', function() { - const testUrl = 'https://someurl?name=value'; - const request = spec.buildRequests([{params: {white_label_url: testUrl}}]); - expect(request.url).to.equal(testUrl); - }); - - it('Verify interpretResponse', function() { - const request = spec.buildRequests(bidRequests); - const response = spec.interpretResponse(bidResponses, request); - expect(response).to.be.an('array').with.lengthOf(4); - - let bid = response[0]; - expect(bid).to.have.property('requestId', 'bid000'); - expect(bid).to.have.property('currency', 'USD'); - expect(bid).to.have.property('cpm', 0.99); - expect(bid).to.have.property('creativeId', '1000'); - expect(bid).to.have.property('width', 300); - expect(bid).to.have.property('height', 250); - expect(bid.meta.advertiserDomains).to.deep.equal(['https://example.com']); - expect(bid).to.have.property('ad', 'markup000'); - expect(bid).to.have.property('ttl', 300); - expect(bid).to.have.property('netRevenue', true); - - // There is no bid001 because cpm is $0 - - bid = response[1]; - expect(bid).to.have.property('requestId', 'bid002'); - expect(bid).to.have.property('currency', 'USD'); - expect(bid).to.have.property('cpm', 2.99); - expect(bid).to.have.property('creativeId', '1002'); - expect(bid).to.have.property('width', 300); - expect(bid).to.have.property('height', 600); - expect(bid).to.have.property('ad', 'markup002'); - expect(bid).to.have.property('ttl', 300); - expect(bid).to.have.property('netRevenue', true); - - bid = response[2]; - expect(bid).to.have.property('requestId', 'bid003'); - expect(bid).to.have.property('currency', 'USD'); - expect(bid).to.have.property('cpm', 3.99); - expect(bid).to.have.property('creativeId', '1003'); - expect(bid).to.have.property('width', 632); - expect(bid).to.have.property('height', 499); - expect(bid).to.have.property('vastUrl', 'markup003'); - expect(bid).to.have.property('mediaType', 'video'); - expect(bid).to.have.property('ttl', 300); - expect(bid).to.have.property('netRevenue', true); - - bid = response[3]; - expect(bid).to.have.property('vastXml', ''); - }); - - it('Verify handling of bad responses', function() { - let response = spec.interpretResponse({}, {}); - expect(response).to.be.an('array').with.lengthOf(0); - response = spec.interpretResponse({id: '123'}, {}); - expect(response).to.be.an('array').with.lengthOf(0); - response = spec.interpretResponse({id: '123', seatbid: []}, {}); - expect(response).to.be.an('array').with.lengthOf(0); - }); - - it('Verify publisher commond id support', function() { - // clone bidRequests - let requests = utils.deepClone(bidRequests); - - // add pubcid to every entry - requests.forEach((unit) => { - Object.assign(unit, {crumbs: {pubcid: 12345}}); - }); - // construct http post payload - const payload = spec.buildRequests(requests).data; - expect(payload).to.have.deep.nested.property('user.ext.fpc', 12345); - expect(payload).to.not.have.nested.property('user.ext.eids'); - }); - - it('Verify User ID publisher commond id support', function() { - // clone bidRequests - let requests = utils.deepClone(bidRequests); - - // add pubcid to every entry - requests.forEach((unit) => { - Object.assign(unit, {userId: {pubcid: 67890}}); - Object.assign(unit, {userIdAsEids: createEidsArray(unit.userId)}); - }); - // construct http post payload - const payload = spec.buildRequests(requests).data; - expect(payload).to.have.deep.nested.property('user.ext.fpc', 67890); - expect(payload).to.not.have.nested.property('user.ext.eids'); - }); - - it('Verify GDPR bid request', function() { - // add gdpr info - const bidderRequest = { - gdprConsent: { - consentString: 'BOJObISOJObISAABAAENAA4AAAAAoAAA', - gdprApplies: true - } - }; - - const payload = spec.buildRequests(bidRequests, bidderRequest).data; - expect(payload).to.have.deep.nested.property('user.ext.consent', 'BOJObISOJObISAABAAENAA4AAAAAoAAA'); - expect(payload).to.have.deep.nested.property('regs.ext.gdpr', 1); - }); - - it('Verify GDPR bid request without gdprApplies', function() { - // add gdpr info - const bidderRequest = { - gdprConsent: { - consentString: '' - } - }; - - const payload = spec.buildRequests(bidRequests, bidderRequest).data; - expect(payload).to.have.deep.nested.property('user.ext.consent', ''); - expect(payload).to.not.have.deep.nested.property('regs.ext.gdpr'); - }); - - describe('CCPA', function() { - it('should have us_privacy', function() { - const bidderRequest = { - uspConsent: '1NYN' - }; - - const payload = spec.buildRequests(bidRequests, bidderRequest).data; - expect(payload).to.have.deep.nested.property('regs.ext.us_privacy', '1NYN'); - expect(payload).to.not.have.deep.nested.property('regs.ext.gdpr'); - }); - - it('should have no us_privacy', function() { - const payload = spec.buildRequests(bidRequests, {}).data; - expect(payload).to.not.have.deep.nested.property('regs.ext.us_privacy'); - }); - - it('should have both gdpr and us_privacy', function() { - const bidderRequest = { - gdprConsent: { - consentString: 'BOJObISOJObISAABAAENAA4AAAAAoAAA', - gdprApplies: true - }, - uspConsent: '1NYN' - }; - - const payload = spec.buildRequests(bidRequests, bidderRequest).data; - expect(payload).to.have.deep.nested.property('user.ext.consent', 'BOJObISOJObISAABAAENAA4AAAAAoAAA'); - expect(payload).to.have.deep.nested.property('regs.ext.gdpr', 1); - expect(payload).to.have.deep.nested.property('regs.ext.us_privacy', '1NYN'); - }); - }); - - describe('Extended ID', function() { - it('Verify unifiedid and liveramp', function() { - // clone bidRequests - let requests = utils.deepClone(bidRequests); - - // add pubcid to every entry - requests.forEach((unit) => { - Object.assign(unit, {userId: {pubcid: '112233', tdid: '223344', idl_env: '334455'}}); - Object.assign(unit, {userIdAsEids: createEidsArray(unit.userId)}); - }); - // construct http post payload - const payload = spec.buildRequests(requests).data; - expect(payload).to.have.deep.nested.property('user.ext.eids', [ - {source: 'adserver.org', uids: [{id: '223344', atype: 1, ext: {rtiPartner: 'TDID'}}]}, - {source: 'liveramp.com', uids: [{id: '334455', atype: 3}]} - ]); - }); - }); - - describe('direct reading pubcid', function() { - const ID_NAME = '_pubcid'; - const CUSTOM_ID_NAME = 'myid'; - const EXP = '_exp'; - const TIMEOUT = 2000; - - function cleanUp(key) { - window.document.cookie = key + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;'; - localStorage.removeItem(key); - localStorage.removeItem(key + EXP); - } - - function expStr(timeout) { - return (new Date(Date.now() + timeout * 60 * 60 * 24 * 1000)).toUTCString(); - } - - afterEach(() => { - cleanUp(ID_NAME); - cleanUp(CUSTOM_ID_NAME); - }); - - it('reading cookie', function() { - // clone bidRequests - const requests = utils.deepClone(bidRequests); - - // add a pubcid cookie - storage.setCookie(ID_NAME, '12345', expStr(TIMEOUT)); - - // construct http post payload - const payload = spec.buildRequests(requests).data; - expect(payload).to.have.deep.nested.property('user.ext.fpc', '12345'); - }); - - it('reading custom cookie', function() { - // clone bidRequests - const requests = utils.deepClone(bidRequests); - requests[0].params.pubcid_name = CUSTOM_ID_NAME; - - // add a pubcid cookie - storage.setCookie(CUSTOM_ID_NAME, '12345', expStr(TIMEOUT)); - - // construct http post payload - const payload = spec.buildRequests(requests).data; - expect(payload).to.have.deep.nested.property('user.ext.fpc', '12345'); - }); - - it('reading local storage with empty exp time', function() { - // clone bidRequests - const requests = utils.deepClone(bidRequests); - - // add a pubcid in local storage - storage.setDataInLocalStorage(ID_NAME + EXP, ''); - storage.setDataInLocalStorage(ID_NAME, 'abcde'); - - // construct http post payload - const payload = spec.buildRequests(requests).data; - expect(payload).to.have.deep.nested.property('user.ext.fpc', 'abcde'); - }); - - it('reading local storage with valid exp time', function() { - // clone bidRequests - const requests = utils.deepClone(bidRequests); - - // add a pubcid in local storage - storage.setDataInLocalStorage(ID_NAME + EXP, expStr(TIMEOUT)); - storage.setDataInLocalStorage(ID_NAME, 'fghijk'); - - // construct http post payload - const payload = spec.buildRequests(requests).data; - expect(payload).to.have.deep.nested.property('user.ext.fpc', 'fghijk'); - }); - - it('reading expired local storage', function() { - // clone bidRequests - const requests = utils.deepClone(bidRequests); - - // add a pubcid in local storage - storage.setDataInLocalStorage(ID_NAME + EXP, expStr(-TIMEOUT)); - storage.setDataInLocalStorage(ID_NAME, 'lmnopq'); - - // construct http post payload - const payload = spec.buildRequests(requests).data; - expect(payload).to.not.have.deep.nested.property('user.ext.fpc'); - }); - - it('reading local storage with custom name', function() { - // clone bidRequests - const requests = utils.deepClone(bidRequests); - requests[0].params.pubcid_name = CUSTOM_ID_NAME; - - // add a pubcid in local storage - storage.setDataInLocalStorage(CUSTOM_ID_NAME + EXP, expStr(TIMEOUT)); - storage.setDataInLocalStorage(CUSTOM_ID_NAME, 'fghijk'); - - // construct http post payload - const payload = spec.buildRequests(requests).data; - expect(payload).to.have.deep.nested.property('user.ext.fpc', 'fghijk'); - }); - }); -}); diff --git a/test/spec/modules/cosmosBidAdapter_spec.js b/test/spec/modules/cosmosBidAdapter_spec.js deleted file mode 100644 index b33f53221e2..00000000000 --- a/test/spec/modules/cosmosBidAdapter_spec.js +++ /dev/null @@ -1,355 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/cosmosBidAdapter.js'; -import * as utils from 'src/utils.js'; -const constants = require('src/constants.json'); - -describe('Cosmos adapter', function () { - let bannerBidRequests; - let bannerBidResponse; - let videoBidRequests; - let videoBidResponse; - - beforeEach(function () { - bannerBidRequests = [ - { - bidder: 'cosmos', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - } - }, - params: { - publisherId: '1001', - currency: 'USD', - geo: { - lat: '09.5', - lon: '21.2', - } - }, - bidId: '29f8bd96defe76' - } - ]; - - videoBidRequests = - [ - { - mediaTypes: { - video: { - mimes: ['video/mp4', 'video/x-flv'], - context: 'instream' - } - }, - bidder: 'cosmos', - params: { - publisherId: 1001, - video: { - skippable: true, - minduration: 5, - maxduration: 30 - } - }, - bidId: '39f5cc6eff9b37' - } - ]; - - bannerBidResponse = { - 'body': { - 'id': '93D3BAD6-E2E2-49FB-9D89-920B1761C865', - 'seatbid': [{ - 'bid': [{ - 'id': '82DAAE22-FF66-4FAB-84AB-347B0C5CD02C', - 'impid': '29f8bd96defe76', - 'price': 1.858309, - 'adm': '

COSMOS\"Connecting Advertisers and Publishers directly\"

', - 'adid': 'v55jutrh', - 'adomain': ['febreze.com'], - 'iurl': 'https://thetradedesk-t-general.s3.amazonaws.com/AdvertiserLogos/vgl908z.png', - 'cid': '1234', - 'crid': 'v55jutrh', - 'w': 300, - 'h': 250, - 'ext': { - 'prebid': { - 'type': 'banner' - } - } - }], - 'seat': 'zeta' - }] - } - }; - - videoBidResponse = { - 'body': { - 'id': '93D3BAD6-E2E2-49FB-9D89-920B1761C865', - 'seatbid': [{ - 'bid': [{ - 'id': '82DAAE22-FF66-4FAB-84AB-347B0C5CD02C', - 'impid': '39f5cc6eff9b37', - 'price': 0.858309, - 'adm': 'CosmosHQVAST 2.0 Instream Test 1VAST 2.0 Instream Test 1https://track.cosmoshq.com/event?data=%7B%22id%22%3A%221566011421045%22%2C%22bid%22%3A%2282DAAE22-FF66-4FAB-84AB-347B0C5CD02C%22%2C%22ts%22%3A%2220190817031021%22%2C%22pid%22%3A1001%2C%22plcid%22%3A1%2C%22aid%22%3A1%2C%22did%22%3A1%2C%22cid%22%3A%2222918%22%2C%22af%22%3A3%2C%22at%22%3A1%2C%22w%22%3A300%2C%22h%22%3A250%2C%22crid%22%3A%22v55jutrh%22%2C%22pp%22%3A0.858309%2C%22cp%22%3A0.858309%2C%22mg%22%3A0%7D&type=1https//track.dsp.impression.com/impression00:00:60https//sync.cosmoshq.com/static/video/SampleVideo_1280x720_10mb.mp4', - 'adid': 'v55jutrh', - 'adomain': ['febreze.com'], - 'iurl': 'https://thetradedesk-t-general.s3.amazonaws.com/AdvertiserLogos/vgl908z.png', - 'cid': '1234', - 'crid': 'v55jutrh', - 'w': 300, - 'h': 250, - 'ext': { - 'prebid': { - 'type': 'video' - } - } - }], - 'seat': 'zeta' - }] - } - }; - }); - - describe('isBidRequestValid', function () { - describe('validate the bid object: valid bid', function () { - it('valid bid case', function () { - let validBid = { - bidder: 'cosmos', - params: { - publisherId: 1001, - tagId: 1 - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(true); - }); - - it('validate the bid object: nil/empty bid object', function () { - let validBid = { - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(false); - }); - - it('validate the bid object: publisherId not passed', function () { - let validBid = { - bidder: 'cosmos', - params: { - tagId: 1 - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(false); - }); - - it('validate the bid object: publisherId is not number', function () { - let validBid = { - bidder: 'cosmos', - params: { - publisherId: '301', - tagId: 1 - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(false); - }); - - it('validate the bid object: mimes absent', function () { - let validBid = { - bidder: 'cosmos', - mediaTypes: { - video: {} - }, - params: { - publisherId: 1001 - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(false); - }); - - it('validate the bid object: mimes present', function () { - let validBid = { - bidder: 'cosmos', - mediaTypes: { - video: { - mimes: ['video/mp4', 'application/javascript'] - } - }, - params: { - publisherId: 1001 - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(true); - }); - - it('validate the bid object: tagId is not passed', function () { - let validBid = { - bidder: 'cosmos', - params: { - publisherId: 1001 - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(true); - }); - }); - - describe('buildRequests', function () { - it('build request object: buildRequests function should not modify original bannerBidRequests object', function () { - let originalBidRequests = utils.deepClone(bannerBidRequests); - let request = spec.buildRequests(bannerBidRequests); - expect(bannerBidRequests).to.deep.equal(originalBidRequests); - }); - - it('build request object: endpoint check', function () { - let request = spec.buildRequests(bannerBidRequests); - expect(request[0].url).to.equal('https://bid.cosmoshq.com/openrtb2/bids'); - expect(request[0].method).to.equal('POST'); - }); - - it('build request object: request params check', function () { - let request = spec.buildRequests(bannerBidRequests); - let data = JSON.parse(request[0].data); - expect(data.site.publisher.id).to.equal(bannerBidRequests[0].params.publisherId); // publisher Id - expect(data.imp[0].bidfloorcur).to.equal(bannerBidRequests[0].params.currency); - }); - - it('build request object: request params check without tagId', function () { - delete bannerBidRequests[0].params.tagId; - let request = spec.buildRequests(bannerBidRequests); - let data = JSON.parse(request[0].data); - expect(data.site.publisher.id).to.equal(bannerBidRequests[0].params.publisherId); // publisher Id - expect(data.imp[0].tagid).to.equal(undefined); // tagid - expect(data.imp[0].bidfloorcur).to.equal(bannerBidRequests[0].params.currency); - }); - - it('build request object: request params multi size format object check', function () { - let bidRequest = [ - { - bidder: 'cosmos', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - } - }, - params: { - publisherId: 1001, - currency: 'USD' - } - } - ]; - /* case 1 - size passed in adslot */ - let request = spec.buildRequests(bidRequest); - let data = JSON.parse(request[0].data); - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(250); // height - - /* case 2 - size passed in adslot as well as in sizes array */ - bidRequest[0].sizes = [[300, 600], [300, 250]]; - bidRequest[0].mediaTypes = { - banner: { - sizes: [[300, 600], [300, 250]] - } - }; - request = spec.buildRequests(bidRequest); - data = JSON.parse(request[0].data); - - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(600); // height - - /* case 3 - size passed in sizes but not in adslot */ - bidRequest[0].params.tagId = 1; - bidRequest[0].sizes = [[300, 250], [300, 600]]; - bidRequest[0].mediaTypes = { - banner: { - sizes: [[300, 250], [300, 600]] - } - }; - request = spec.buildRequests(bidRequest); - data = JSON.parse(request[0].data); - - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(250); // height - expect(data.imp[0].banner.format).exist.and.to.be.an('array'); - expect(data.imp[0].banner.format[0]).exist.and.to.be.an('object'); - expect(data.imp[0].banner.format[0].w).to.equal(300); // width - expect(data.imp[0].banner.format[0].h).to.equal(250); // height - }); - - it('build request object: request params currency check', function () { - let bidRequest = [ - { - bidder: 'cosmos', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - } - }, - params: { - publisherId: 1001, - tagId: 1, - currency: 'USD' - }, - sizes: [[300, 250], [300, 600]] - } - ]; - - /* case 1 - - currency specified in adunits - output: imp[0] use currency specified in bannerBidRequests[0].params.currency - - */ - let request = spec.buildRequests(bidRequest); - let data = JSON.parse(request[0].data); - expect(data.imp[0].bidfloorcur).to.equal(bidRequest[0].params.currency); - - /* case 2 - - currency specified in adunit - output: imp[0] use default currency - USD - - */ - delete bidRequest[0].params.currency; - request = spec.buildRequests(bidRequest); - data = JSON.parse(request[0].data); - expect(data.imp[0].bidfloorcur).to.equal('USD'); - }); - - it('build request object: request params check for video ad', function () { - let request = spec.buildRequests(videoBidRequests); - let data = JSON.parse(request[0].data); - expect(data.imp[0].video).to.exist; - expect(data.imp[0]['video']['mimes']).to.exist.and.to.be.an('array'); - expect(data.imp[0]['video']['mimes'][0]).to.equal(videoBidRequests[0].mediaTypes.video['mimes'][0]); - expect(data.imp[0]['video']['mimes'][1]).to.equal(videoBidRequests[0].mediaTypes.video['mimes'][1]); - expect(data.imp[0]['video']['minduration']).to.equal(videoBidRequests[0].params.video['minduration']); - expect(data.imp[0]['video']['maxduration']).to.equal(videoBidRequests[0].params.video['maxduration']); - }); - - describe('interpretResponse', function () { - it('check for banner response', function () { - let request = spec.buildRequests(bannerBidRequests); - let data = JSON.parse(request[0].data); - let response = spec.interpretResponse(bannerBidResponse, request[0]); - expect(response).to.be.an('array').with.length.above(0); - expect(response[0].requestId).to.equal(bannerBidResponse.body.seatbid[0].bid[0].impid); - expect(response[0].cpm).to.equal((bannerBidResponse.body.seatbid[0].bid[0].price).toFixed(2)); - expect(response[0].width).to.equal(bannerBidResponse.body.seatbid[0].bid[0].w); - expect(response[0].height).to.equal(bannerBidResponse.body.seatbid[0].bid[0].h); - if (bannerBidResponse.body.seatbid[0].bid[0].crid) { - expect(response[0].creativeId).to.equal(bannerBidResponse.body.seatbid[0].bid[0].crid); - } else { - expect(response[0].creativeId).to.equal(bannerBidResponse.body.seatbid[0].bid[0].id); - } - expect(response[0].dealId).to.equal(bannerBidResponse.body.seatbid[0].bid[0].dealid); - expect(response[0].currency).to.equal('USD'); - expect(response[0].netRevenue).to.equal(false); - expect(response[0].ttl).to.equal(300); - }); - it('check for video response', function () { - let request = spec.buildRequests(videoBidRequests); - let data = JSON.parse(request[0].data); - let response = spec.interpretResponse(videoBidResponse, request[0]); - }); - }); - }); - }); -}); diff --git a/test/spec/modules/cpmstarBidAdapter_spec.js b/test/spec/modules/cpmstarBidAdapter_spec.js deleted file mode 100644 index 285fca9690a..00000000000 --- a/test/spec/modules/cpmstarBidAdapter_spec.js +++ /dev/null @@ -1,231 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/cpmstarBidAdapter.js'; -import { deepClone } from 'src/utils.js'; -import { config } from 'src/config.js'; - -const valid_bid_requests = [{ - 'bidder': 'cpmstar', - 'params': { - 'placementId': '57' - }, - 'sizes': [[300, 250]], - 'bidId': 'bidId' -}]; - -const bidderRequest = { - refererInfo: { - referer: 'referer', - reachedTop: false, - } -}; - -const serverResponse = { - body: [{ - creatives: [{ - cpm: 1, - width: 0, - height: 0, - currency: 'USD', - netRevenue: true, - ttl: 1, - creativeid: '1234', - requestid: '11123', - code: 'no idea', - media: 'banner', - } - ], - syncs: [{ type: 'image', url: 'https://server.cpmstar.com/pixel.aspx' }] - }] -}; - -describe('Cpmstar Bid Adapter', function () { - describe('isBidRequestValid', function () { - it('should return true since the bid is valid', - function () { - var bid = { params: { placementId: 123456 } }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }) - - it('should return false since the bid is invalid', function () { - var bid = { params: { placementId: '' } }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }) - - it('should return a valid player size', function () { - var bid = { - mediaTypes: { - video: { - playerSize: [[960, 540]] - } - } - } - expect(spec.getPlayerSize(bid)[0]).to.equal(960); - expect(spec.getPlayerSize(bid)[1]).to.equal(540); - }) - - it('should return a default player size', function () { - var bid = { - mediaTypes: { - video: { - playerSize: null - } - } - } - expect(spec.getPlayerSize(bid)[0]).to.equal(640); - expect(spec.getPlayerSize(bid)[1]).to.equal(440); - }) - }); - - describe('buildRequests', function () { - it('should produce a valid production request', function () { - var requests = spec.buildRequests(valid_bid_requests, bidderRequest); - expect(requests[0]).to.have.property('method'); - expect(requests[0]).to.have.property('url'); - expect(requests[0]).to.have.property('bidRequest'); - expect(requests[0].url).to.include('https://server.cpmstar.com/view.aspx'); - }); - it('should produce a valid staging request', function () { - var stgReq = deepClone(valid_bid_requests); - stgReq[0].params.endpoint = 'staging'; - var requests = spec.buildRequests(stgReq, bidderRequest); - expect(requests[0]).to.have.property('method'); - expect(requests[0]).to.have.property('url'); - expect(requests[0]).to.have.property('bidRequest'); - expect(requests[0].url).to.include('https://staging.server.cpmstar.com/view.aspx'); - }); - it('should produce a valid dev request', function () { - var devReq = deepClone(valid_bid_requests); - devReq[0].params.endpoint = 'dev'; - var requests = spec.buildRequests(devReq, bidderRequest); - expect(requests[0]).to.have.property('method'); - expect(requests[0]).to.have.property('url'); - expect(requests[0]).to.have.property('bidRequest'); - expect(requests[0].url).to.include('https://dev.server.cpmstar.com/view.aspx'); - }); - it('should produce a request with support for GDPR', function () { - var gdpr_bidderRequest = deepClone(bidderRequest); - gdpr_bidderRequest.gdprConsent = { - consentString: 'consentString', - gdprApplies: true - }; - var requests = spec.buildRequests(valid_bid_requests, gdpr_bidderRequest); - expect(requests[0]).to.have.property('url'); - expect(requests[0].url).to.include('gdpr_consent=consentString'); - expect(requests[0].url).to.include('gdpr=1'); - }); - it('should produce a request with support for USP', function () { - var usp_bidderRequest = deepClone(bidderRequest); - usp_bidderRequest.uspConsent = '1YYY'; - var requests = spec.buildRequests(valid_bid_requests, usp_bidderRequest); - expect(requests[0]).to.have.property('url'); - expect(requests[0].url).to.include('us_privacy=1YYY'); - }); - it('should produce a request with support for COPPA', function () { - sinon.stub(config, 'getConfig').withArgs('coppa').returns(true); - var requests = spec.buildRequests(valid_bid_requests, bidderRequest); - config.getConfig.restore(); - expect(requests[0]).to.have.property('url'); - expect(requests[0].url).to.include('tfcd=1'); - }); - }); - - it('should produce a request with support for OpenRTB SupplyChain', function () { - var reqs = deepClone(valid_bid_requests); - reqs[0].schain = { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'exchange1.com', - 'sid': '1234', - 'hp': 1 - }, - { - 'asi': 'exchange2.com', - 'sid': 'abcd', - 'hp': 1 - } - ] - }; - var requests = spec.buildRequests(reqs, bidderRequest); - expect(requests[0]).to.have.property('url'); - expect(requests[0].url).to.include('&schain=1.0,1!exchange1.com,1234,1,,,!exchange2.com,abcd,1,,,'); - }); - - describe('interpretResponse', function () { - const request = { - bidRequest: { - mediaType: 'BANNER' - } - }; - - it('should return a valid bidresponse array', function () { - var r = spec.interpretResponse(serverResponse, request) - var c = serverResponse.body[0].creatives[0]; - expect(r[0].length).to.not.equal(0); - expect(r[0].requestId).equal(c.requestid); - expect(r[0].creativeId).equal(c.creativeid); - expect(r[0].cpm).equal(c.cpm); - expect(r[0].width).equal(c.width); - expect(r[0].height).equal(c.height); - expect(r[0].currency).equal(c.currency); - expect(r[0].netRevenue).equal(c.netRevenue); - expect(r[0].ttl).equal(c.ttl); - expect(r[0].ad).equal(c.code); - }); - - it('should return a valid bidresponse array from a non-array-body', function () { - var r = spec.interpretResponse({ body: serverResponse.body[0] }, request) - var c = serverResponse.body[0].creatives[0]; - expect(r[0].length).to.not.equal(0); - expect(r[0].requestId).equal(c.requestid); - expect(r[0].creativeId).equal(c.creativeid); - expect(r[0].cpm).equal(c.cpm); - expect(r[0].width).equal(c.width); - expect(r[0].height).equal(c.height); - expect(r[0].currency).equal(c.currency); - expect(r[0].netRevenue).equal(c.netRevenue); - expect(r[0].ttl).equal(c.ttl); - expect(r[0].ad).equal(c.code); - }); - - it('should return undefined due to an invalid cpm value', function () { - var badServer = deepClone(serverResponse); - badServer.body[0].creatives[0].cpm = 0; - var c = spec.interpretResponse(badServer, request); - expect(c).to.be.undefined; - }); - - it('should return undefined due to a bad response', function () { - var badServer = deepClone(serverResponse); - badServer.body[0].creatives[0].code = null; - var c = spec.interpretResponse(badServer, request); - expect(c).to.be.undefined; - }); - - it('should return a valid response with a dealId', function () { - var dealServer = deepClone(serverResponse); - dealServer.body[0].creatives[0].dealId = 'deal'; - expect(spec.interpretResponse(dealServer, request)[0].dealId).to.equal('deal'); - }); - }); - - describe('getUserSyncs', function () { - var sres = [deepClone(serverResponse)]; - - it('should return a valid pixel sync', function () { - var syncs = spec.getUserSyncs({ pixelEnabled: true }, sres); - expect(syncs.length).equal(1); - expect(syncs[0].type).equal('image'); - expect(syncs[0].url).equal('https://server.cpmstar.com/pixel.aspx'); - }); - - it('should return a valid iframe sync', function () { - sres[0].body[0].syncs[0].type = 'iframe'; - var syncs = spec.getUserSyncs({ iframeEnabled: true }, sres); - expect(syncs.length).equal(1); - expect(syncs[0].type).equal('iframe'); - expect(syncs[0].url).equal('https://server.cpmstar.com/pixel.aspx'); - }); - }); -}); diff --git a/test/spec/modules/craftBidAdapter_spec.js b/test/spec/modules/craftBidAdapter_spec.js deleted file mode 100644 index 3f4bc977016..00000000000 --- a/test/spec/modules/craftBidAdapter_spec.js +++ /dev/null @@ -1,152 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/craftBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {config} from 'src/config.js'; - -describe('craftAdapter', function () { - let 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 () { - before(function() { - this.windowContext = window.context; - window.context = null; - }); - - after(function() { - window.context = this.windowContext; - }); - let bid = { - bidder: 'craft', - params: { - sitekey: 'craft-prebid-example', - placementId: '1234abcd' - }, - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when params.sitekey not found', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - placementId: '1234abcd' - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when params.placementId not found', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - sitekey: 'craft-prebid-example' - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when AMP cotext found', function () { - window.context = { - pageViewId: 'xxx' - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [{ - bidder: 'craft', - params: { - 'sitekey': 'craft-prebid-example', - 'placementId': '1234abcd' - }, - adUnitCode: '/21998384947/prebid-example', - sizes: [[300, 250]], - bidId: '0396fae4eb5f47', - bidderRequestId: '4a859978b5d4bd', - auctionId: '8720f980-4639-4150-923a-e96da2f1de36', - transactionId: 'e0c52da2-c008-491c-a910-c6765d948700', - }]; - let bidderRequest = { - refererInfo: { - referer: 'https://www.gacraft.jp/publish/craft-prebid-example.html' - } - }; - it('sends bid request to ENDPOINT via POST', function () { - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.method).to.equal('POST'); - expect(request.url).to.equal('https://gacraft.jp/prebid-v3/craft-prebid-example'); - let data = JSON.parse(request.data); - expect(data.tags).to.deep.equals([{ - sitekey: 'craft-prebid-example', - placementId: '1234abcd', - uid: null, - sizes: [[300, 250]], - primary_size: [300, 250], - uuid: '0396fae4eb5f47' - }]); - expect(data.referrer_detection).to.deep.equals({ - rd_ref: 'https://www.gacraft.jp/publish/craft-prebid-example.html' - }); - }); - }); - - describe('interpretResponse', function() { - let serverResponse = { - body: { - tags: [{ - uuid: '0396fae4eb5f47', - bid_key: '72038482-c4c3-4055-9e7e-0579585bb421', - won_url: 'https://www.gacraft.jp/publish/won', - ads: [{ - content_source: 'rtb', - ad_type: 'banner', - creative_id: 9999, - cpm: 10.01, - deal_id: '8DEF60EFDFB5', - rtb: { - banner: { - content: '', - width: 300, - height: 250 - }, - } - }] - }], - } - }; - let bidderRequest = { - bids: [{ - bidId: '0396fae4eb5f47', - adUnitCode: 'craft-prebid-example' - }] - }; - it('should get correct bid response', function() { - let bids = spec.interpretResponse(serverResponse, {bidderRequest: bidderRequest}); - expect(bids).to.have.lengthOf(1); - expect(bids[0]).to.deep.equals({ - _adUnitCode: 'craft-prebid-example', - _bidKey: '72038482-c4c3-4055-9e7e-0579585bb421', - _prebidWon: 'https://www.gacraft.jp/publish/won', - ad: '', - cpm: 10.01, - creativeId: 9999, - currency: 'JPY', - dealId: '8DEF60EFDFB5', - height: 250, - mediaType: 'banner', - meta: null, - netRevenue: false, - requestId: '0396fae4eb5f47', - ttl: 360, - width: 300, - }); - }); - }); -}); diff --git a/test/spec/modules/criteoBidAdapter_spec.js b/test/spec/modules/criteoBidAdapter_spec.js deleted file mode 100755 index cad1e3f8114..00000000000 --- a/test/spec/modules/criteoBidAdapter_spec.js +++ /dev/null @@ -1,1501 +0,0 @@ -import { expect } from 'chai'; -import { tryGetCriteoFastBid, spec, PROFILE_ID_PUBLISHERTAG, ADAPTER_VERSION } from 'modules/criteoBidAdapter.js'; -import { createBid } from 'src/bidfactory.js'; -import CONSTANTS from 'src/constants.json'; -import * as utils from 'src/utils.js'; -import { config } from '../../../src/config.js'; -import { NATIVE, VIDEO } from '../../../src/mediaTypes.js'; - -describe('The Criteo bidding adapter', function () { - let utilsMock, sandbox; - - beforeEach(function () { - // Remove FastBid to avoid side effects - localStorage.removeItem('criteo_fast_bid'); - utilsMock = sinon.mock(utils); - - sandbox = sinon.sandbox.create(); - }); - - afterEach(function() { - global.Criteo = undefined; - utilsMock.restore(); - sandbox.restore(); - }); - - describe('isBidRequestValid', function () { - it('should return false when given an invalid bid', function () { - const bid = { - bidder: 'criteo', - }; - const isValid = spec.isBidRequestValid(bid); - expect(isValid).to.equal(false); - }); - - it('should return true when given a zoneId bid', function () { - const bid = { - bidder: 'criteo', - params: { - zoneId: 123, - }, - }; - const isValid = spec.isBidRequestValid(bid); - expect(isValid).to.equal(true); - }); - - it('should return true when given a networkId bid', function () { - const bid = { - bidder: 'criteo', - params: { - networkId: 456, - }, - }; - const isValid = spec.isBidRequestValid(bid); - expect(isValid).to.equal(true); - }); - - it('should return true when given a mixed bid with both a zoneId and a networkId', function () { - const bid = { - bidder: 'criteo', - params: { - zoneId: 123, - networkId: 456, - }, - }; - const isValid = spec.isBidRequestValid(bid); - expect(isValid).to.equal(true); - }); - - it('should return true when given a valid video bid request', function () { - expect(spec.isBidRequestValid({ - bidder: 'criteo', - mediaTypes: { - video: { - context: 'instream', - mimes: ['video/mpeg'], - playerSize: [640, 480], - protocols: [5, 6], - maxduration: 30, - api: [1, 2] - } - }, - params: { - networkId: 456, - video: { - skip: 1, - placement: 1, - playbackmethod: 1 - } - }, - })).to.equal(true); - - expect(spec.isBidRequestValid({ - bidder: 'criteo', - mediaTypes: { - video: { - context: 'outstream', - mimes: ['video/mpeg'], - playerSize: [640, 480], - protocols: [5, 6], - maxduration: 30, - api: [1, 2] - } - }, - params: { - networkId: 456, - video: { - skip: 1, - placement: 2, - playbackmethod: 1 - } - }, - })).to.equal(true); - }); - - it('should return false when given an invalid video bid request', function () { - expect(spec.isBidRequestValid({ - bidder: 'criteo', - mediaTypes: { - video: { - mimes: ['video/mpeg'], - playerSize: [640, 480], - protocols: [5, 6], - maxduration: 30, - api: [1, 2] - } - }, - params: { - networkId: 456, - video: { - skip: 1, - placement: 1, - playbackmethod: 1 - } - }, - })).to.equal(false); - - expect(spec.isBidRequestValid({ - bidder: 'criteo', - mediaTypes: { - video: { - context: 'instream', - mimes: ['video/mpeg'], - playerSize: [640, 480], - protocols: [5, 6], - maxduration: 30, - api: [1, 2] - } - }, - params: { - networkId: 456, - video: { - skip: 1, - placement: 2, - playbackmethod: 1 - } - }, - })).to.equal(false); - - expect(spec.isBidRequestValid({ - bidder: 'criteo', - mediaTypes: { - video: { - context: 'outstream', - mimes: ['video/mpeg'], - playerSize: [640, 480], - protocols: [5, 6], - maxduration: 30, - api: [1, 2] - } - }, - params: { - networkId: 456, - video: { - skip: 1, - placement: 1, - playbackmethod: 1 - } - }, - })).to.equal(false); - - expect(spec.isBidRequestValid({ - bidder: 'criteo', - mediaTypes: { - video: { - context: 'adpod', - mimes: ['video/mpeg'], - playerSize: [640, 480], - protocols: [5, 6], - maxduration: 30, - api: [1, 2] - } - }, - params: { - networkId: 456, - video: { - skip: 1, - placement: 1, - playbackmethod: 1 - } - }, - })).to.equal(false); - - expect(spec.isBidRequestValid({ - bidder: 'criteo', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480], - protocols: [5, 6], - maxduration: 30, - api: [1, 2] - } - }, - params: { - networkId: 456, - video: { - skip: 1, - placement: 1, - playbackmethod: 1 - } - }, - })).to.equal(false); - - expect(spec.isBidRequestValid({ - bidder: 'criteo', - mediaTypes: { - video: { - context: 'instream', - mimes: ['video/mpeg'], - protocols: [5, 6], - maxduration: 30, - api: [1, 2] - } - }, - params: { - networkId: 456, - video: { - skip: 1, - placement: 1, - playbackmethod: 1 - } - }, - })).to.equal(false); - - expect(spec.isBidRequestValid({ - bidder: 'criteo', - mediaTypes: { - video: { - context: 'instream', - mimes: ['video/mpeg'], - playerSize: [640, 480], - maxduration: 30, - api: [1, 2] - } - }, - params: { - networkId: 456, - video: { - skip: 1, - placement: 1, - playbackmethod: 1 - } - }, - })).to.equal(false); - - expect(spec.isBidRequestValid({ - bidder: 'criteo', - mediaTypes: { - video: { - context: 'instream', - mimes: ['video/mpeg'], - playerSize: [640, 480], - protocols: [5, 6], - api: [1, 2] - } - }, - params: { - networkId: 456, - video: { - skip: 1, - placement: 1, - playbackmethod: 1 - } - }, - })).to.equal(false); - - expect(spec.isBidRequestValid({ - bidder: 'criteo', - mediaTypes: { - video: { - context: 'instream', - mimes: ['video/mpeg'], - playerSize: [640, 480], - protocols: [5, 6], - maxduration: 30 - } - }, - params: { - networkId: 456, - video: { - skip: 1, - placement: 1, - playbackmethod: 1 - } - }, - })).to.equal(false); - - expect(spec.isBidRequestValid({ - bidder: 'criteo', - mediaTypes: { - video: { - context: 'instream', - mimes: ['video/mpeg'], - playerSize: [640, 480], - protocols: [5, 6], - maxduration: 30, - api: [1, 2] - } - }, - params: { - networkId: 456, - video: { - placement: 1, - playbackmethod: 1 - } - }, - })).to.equal(false); - - expect(spec.isBidRequestValid({ - bidder: 'criteo', - mediaTypes: { - video: { - context: 'instream', - mimes: ['video/mpeg'], - playerSize: [640, 480], - protocols: [5, 6], - maxduration: 30, - api: [1, 2] - } - }, - params: { - networkId: 456, - video: { - skip: 1, - playbackmethod: 1 - } - }, - })).to.equal(false); - - expect(spec.isBidRequestValid({ - bidder: 'criteo', - mediaTypes: { - video: { - context: 'instream', - mimes: ['video/mpeg'], - playerSize: [640, 480], - protocols: [5, 6], - maxduration: 30, - api: [1, 2] - } - }, - params: { - networkId: 456, - video: { - skip: 1, - placement: 1 - } - }, - })).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const refererUrl = 'https://criteo.com?pbt_debug=1&pbt_nolog=1'; - const bidderRequest = { - refererInfo: { - referer: refererUrl - }, - timeout: 3000, - gdprConsent: { - gdprApplies: 1, - consentString: 'concentDataString', - vendorData: { - vendorConsents: { - '91': 1 - }, - }, - apiVersion: 1, - }, - }; - - afterEach(function () { - config.resetConfig(); - }); - - it('should properly build a request if refererInfo is not provided', function () { - const bidderRequest = {}; - const bidRequests = [ - { - bidder: 'criteo', - adUnitCode: 'bid-123', - transactionId: 'transaction-123', - sizes: [[728, 90]], - params: {} - }, - ]; - const request = spec.buildRequests(bidRequests, bidderRequest); - const ortbRequest = request.data; - expect(ortbRequest.publisher.url).to.equal(''); - }); - - it('should properly build a zoneId request', function () { - const bidRequests = [ - { - bidder: 'criteo', - adUnitCode: 'bid-123', - transactionId: 'transaction-123', - sizes: [[728, 90]], - params: { - zoneId: 123, - publisherSubId: '123', - nativeCallback: function() {}, - integrationMode: 'amp' - }, - }, - ]; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.url).to.match(/^https:\/\/bidder\.criteo\.com\/cdb\?profileId=207&av=\d+&wv=[^&]+&cb=\d+&im=1&debug=1&nolog=1/); - expect(request.method).to.equal('POST'); - const ortbRequest = request.data; - expect(ortbRequest.publisher.url).to.equal(refererUrl); - expect(ortbRequest.slots).to.have.lengthOf(1); - expect(ortbRequest.slots[0].impid).to.equal('bid-123'); - expect(ortbRequest.slots[0].transactionid).to.equal('transaction-123'); - expect(ortbRequest.slots[0].sizes).to.have.lengthOf(1); - expect(ortbRequest.slots[0].sizes[0]).to.equal('728x90'); - expect(ortbRequest.slots[0].zoneid).to.equal(123); - expect(ortbRequest.gdprConsent.consentData).to.equal('concentDataString'); - expect(ortbRequest.gdprConsent.gdprApplies).to.equal(true); - expect(ortbRequest.gdprConsent.version).to.equal(1); - }); - - it('should keep undefined sizes for non native banner', function () { - const bidRequests = [ - { - sizes: [[undefined, undefined]], - params: {}, - }, - ]; - const request = spec.buildRequests(bidRequests, bidderRequest); - const ortbRequest = request.data; - expect(ortbRequest.slots[0].sizes).to.have.lengthOf(1); - expect(ortbRequest.slots[0].sizes[0]).to.equal('undefinedxundefined'); - }); - - it('should keep undefined size for non native banner', function () { - const bidRequests = [ - { - sizes: [undefined, undefined], - params: {}, - }, - ]; - const request = spec.buildRequests(bidRequests, bidderRequest); - const ortbRequest = request.data; - expect(ortbRequest.slots[0].sizes).to.have.lengthOf(1); - expect(ortbRequest.slots[0].sizes[0]).to.equal('undefinedxundefined'); - }); - - it('should properly detect and get sizes of native sizeless banner', function () { - const bidRequests = [ - { - sizes: [[undefined, undefined]], - params: { - nativeCallback: function() {} - }, - }, - ]; - const request = spec.buildRequests(bidRequests, bidderRequest); - const ortbRequest = request.data; - expect(ortbRequest.slots[0].sizes).to.have.lengthOf(1); - expect(ortbRequest.slots[0].sizes[0]).to.equal('2x2'); - }); - - it('should properly detect and get size of native sizeless banner', function () { - const bidRequests = [ - { - sizes: [undefined, undefined], - params: { - nativeCallback: function() {} - }, - }, - ]; - const request = spec.buildRequests(bidRequests, bidderRequest); - const ortbRequest = request.data; - expect(ortbRequest.slots[0].sizes).to.have.lengthOf(1); - expect(ortbRequest.slots[0].sizes[0]).to.equal('2x2'); - }); - - it('should properly build a networkId request', function () { - const bidderRequest = { - refererInfo: { - referer: refererUrl - }, - timeout: 3000, - gdprConsent: { - gdprApplies: 0, - consentString: undefined, - vendorData: { - vendorConsents: { - '1': 0 - }, - }, - }, - }; - const bidRequests = [ - { - bidder: 'criteo', - adUnitCode: 'bid-123', - transactionId: 'transaction-123', - mediaTypes: { - banner: { - sizes: [[300, 250], [728, 90]] - } - }, - params: { - networkId: 456, - }, - }, - ]; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.url).to.match(/^https:\/\/bidder\.criteo\.com\/cdb\?profileId=207&av=\d+&wv=[^&]+&cb=\d/); - expect(request.method).to.equal('POST'); - const ortbRequest = request.data; - expect(ortbRequest.publisher.url).to.equal(refererUrl); - expect(ortbRequest.publisher.networkid).to.equal(456); - expect(ortbRequest.slots).to.have.lengthOf(1); - expect(ortbRequest.slots[0].impid).to.equal('bid-123'); - expect(ortbRequest.slots[0].transactionid).to.equal('transaction-123'); - expect(ortbRequest.slots[0].sizes).to.have.lengthOf(2); - expect(ortbRequest.slots[0].sizes[0]).to.equal('300x250'); - expect(ortbRequest.slots[0].sizes[1]).to.equal('728x90'); - expect(ortbRequest.gdprConsent.consentData).to.equal(undefined); - expect(ortbRequest.gdprConsent.gdprApplies).to.equal(false); - }); - - it('should properly build a mixed request', function () { - const bidderRequest = { - refererInfo: { - referer: refererUrl - }, - timeout: 3000 - }; - const bidRequests = [ - { - bidder: 'criteo', - adUnitCode: 'bid-123', - transactionId: 'transaction-123', - sizes: [[728, 90]], - params: { - zoneId: 123, - }, - }, - { - bidder: 'criteo', - adUnitCode: 'bid-234', - transactionId: 'transaction-234', - sizes: [[300, 250], [728, 90]], - params: { - networkId: 456, - }, - }, - ]; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.url).to.match(/^https:\/\/bidder\.criteo\.com\/cdb\?profileId=207&av=\d+&wv=[^&]+&cb=\d/); - expect(request.method).to.equal('POST'); - const ortbRequest = request.data; - expect(ortbRequest.publisher.url).to.equal(refererUrl); - expect(ortbRequest.publisher.networkid).to.equal(456); - expect(ortbRequest.slots).to.have.lengthOf(2); - expect(ortbRequest.slots[0].impid).to.equal('bid-123'); - expect(ortbRequest.slots[0].transactionid).to.equal('transaction-123'); - expect(ortbRequest.slots[0].sizes).to.have.lengthOf(1); - expect(ortbRequest.slots[0].sizes[0]).to.equal('728x90'); - expect(ortbRequest.slots[1].impid).to.equal('bid-234'); - expect(ortbRequest.slots[1].transactionid).to.equal('transaction-234'); - expect(ortbRequest.slots[1].sizes).to.have.lengthOf(2); - expect(ortbRequest.slots[1].sizes[0]).to.equal('300x250'); - expect(ortbRequest.slots[1].sizes[1]).to.equal('728x90'); - expect(ortbRequest.gdprConsent).to.equal(undefined); - }); - - it('should properly build a request with undefined gdpr consent fields when they are not provided', function () { - const bidRequests = [ - { - bidder: 'criteo', - adUnitCode: 'bid-123', - transactionId: 'transaction-123', - sizes: [[728, 90]], - params: { - zoneId: 123, - }, - }, - ]; - const bidderRequest = { - timeout: 3000, - gdprConsent: {}, - }; - - const ortbRequest = spec.buildRequests(bidRequests, bidderRequest).data; - expect(ortbRequest.gdprConsent.consentData).to.equal(undefined); - expect(ortbRequest.gdprConsent.gdprApplies).to.equal(undefined); - }); - - it('should properly build a request with ccpa consent field', function () { - const bidRequests = [ - { - bidder: 'criteo', - adUnitCode: 'bid-123', - transactionId: 'transaction-123', - sizes: [[728, 90]], - params: { - zoneId: 123, - }, - }, - ]; - const bidderRequest = { - timeout: 3000, - uspConsent: '1YNY', - }; - - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.user).to.not.be.null; - expect(request.data.user.uspIab).to.equal('1YNY'); - }); - - it('should properly build a request with if ccpa consent field is not provided', function () { - const bidRequests = [ - { - bidder: 'criteo', - adUnitCode: 'bid-123', - transactionId: 'transaction-123', - sizes: [[728, 90]], - params: { - zoneId: 123, - }, - }, - ]; - const bidderRequest = { - timeout: 3000 - }; - - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.user).to.not.be.null; - expect(request.data.user.uspIab).to.equal(undefined); - }); - - it('should properly build a video request', function () { - const bidRequests = [ - { - bidder: 'criteo', - adUnitCode: 'bid-123', - transactionId: 'transaction-123', - sizes: [[728, 90]], - mediaTypes: { - video: { - playerSize: [640, 480], - mimes: ['video/mp4', 'video/x-flv'], - maxduration: 30, - api: [1, 2], - protocols: [2, 3] - } - }, - params: { - zoneId: 123, - video: { - skip: 1, - minduration: 5, - startdelay: 5, - playbackmethod: [1, 3], - placement: 2 - } - }, - }, - ]; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.url).to.match(/^https:\/\/bidder\.criteo\.com\/cdb\?profileId=207&av=\d+&wv=[^&]+&cb=\d/); - expect(request.method).to.equal('POST'); - const ortbRequest = request.data; - expect(ortbRequest.slots[0].video.mimes).to.deep.equal(['video/mp4', 'video/x-flv']); - expect(ortbRequest.slots[0].video.playersizes).to.deep.equal(['640x480']); - expect(ortbRequest.slots[0].video.maxduration).to.equal(30); - expect(ortbRequest.slots[0].video.api).to.deep.equal([1, 2]); - expect(ortbRequest.slots[0].video.protocols).to.deep.equal([2, 3]); - expect(ortbRequest.slots[0].video.skip).to.equal(1); - expect(ortbRequest.slots[0].video.minduration).to.equal(5); - expect(ortbRequest.slots[0].video.startdelay).to.equal(5); - expect(ortbRequest.slots[0].video.playbackmethod).to.deep.equal([1, 3]); - expect(ortbRequest.slots[0].video.placement).to.equal(2); - }); - - it('should properly build a video request with more than one player size', function () { - const bidRequests = [ - { - bidder: 'criteo', - adUnitCode: 'bid-123', - transactionId: 'transaction-123', - sizes: [[728, 90]], - mediaTypes: { - video: { - playerSize: [[640, 480], [800, 600]], - mimes: ['video/mp4', 'video/x-flv'], - maxduration: 30, - api: [1, 2], - protocols: [2, 3] - } - }, - params: { - zoneId: 123, - video: { - skip: 1, - minduration: 5, - startdelay: 5, - playbackmethod: [1, 3], - placement: 2 - } - }, - }, - ]; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.url).to.match(/^https:\/\/bidder\.criteo\.com\/cdb\?profileId=207&av=\d+&wv=[^&]+&cb=\d/); - expect(request.method).to.equal('POST'); - const ortbRequest = request.data; - expect(ortbRequest.slots[0].video.mimes).to.deep.equal(['video/mp4', 'video/x-flv']); - expect(ortbRequest.slots[0].video.playersizes).to.deep.equal(['640x480', '800x600']); - expect(ortbRequest.slots[0].video.maxduration).to.equal(30); - expect(ortbRequest.slots[0].video.api).to.deep.equal([1, 2]); - expect(ortbRequest.slots[0].video.protocols).to.deep.equal([2, 3]); - expect(ortbRequest.slots[0].video.skip).to.equal(1); - expect(ortbRequest.slots[0].video.minduration).to.equal(5); - expect(ortbRequest.slots[0].video.startdelay).to.equal(5); - expect(ortbRequest.slots[0].video.playbackmethod).to.deep.equal([1, 3]); - expect(ortbRequest.slots[0].video.placement).to.equal(2); - }); - - it('should properly build a request with ceh', function () { - const bidRequests = [ - { - bidder: 'criteo', - adUnitCode: 'bid-123', - transactionId: 'transaction-123', - sizes: [[728, 90]], - params: { - zoneId: 123, - }, - }, - ]; - config.setConfig({ - criteo: { - ceh: 'hashedemail' - } - }); - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.user).to.not.be.null; - expect(request.data.user.ceh).to.equal('hashedemail'); - }); - - it('should properly build a request without first party data', function () { - const bidRequests = [ - { - bidder: 'criteo', - adUnitCode: 'bid-123', - transactionId: 'transaction-123', - sizes: [[728, 90]], - params: { - zoneId: 123 - } - }, - ]; - - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - }; - return utils.deepAccess(config, key); - }); - - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.publisher.ext).to.equal(undefined); - expect(request.data.user.ext).to.equal(undefined); - expect(request.data.slots[0].ext).to.equal(undefined); - }); - - it('should properly build a request with criteo specific ad unit first party data', function () { - const bidRequests = [ - { - bidder: 'criteo', - adUnitCode: 'bid-123', - transactionId: 'transaction-123', - sizes: [[728, 90]], - params: { - zoneId: 123, - ext: { - bidfloor: 0.75 - } - } - }, - ]; - - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - }; - return utils.deepAccess(config, key); - }); - - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.slots[0].ext).to.deep.equal({ - bidfloor: 0.75, - }); - }); - - it('should properly build a request with first party data', function () { - const contextData = { - keywords: ['power tools'], - ext: { - data: { - pageType: 'article' - } - } - }; - const userData = { - gender: 'M', - ext: { - data: { - registered: true - } - } - }; - const bidRequests = [ - { - bidder: 'criteo', - adUnitCode: 'bid-123', - transactionId: 'transaction-123', - sizes: [[728, 90]], - params: { - zoneId: 123, - ext: { - bidfloor: 0.75 - } - }, - ortb2Imp: { - ext: { - data: { - someContextAttribute: 'abc' - } - } - } - }, - ]; - - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - ortb2: { - site: contextData, - user: userData - } - }; - return utils.deepAccess(config, key); - }); - - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.publisher.ext).to.deep.equal({keywords: ['power tools'], data: {pageType: 'article'}}); - expect(request.data.user.ext).to.deep.equal({gender: 'M', data: {registered: true}}); - expect(request.data.slots[0].ext).to.deep.equal({ - bidfloor: 0.75, - data: { - someContextAttribute: 'abc' - } - }); - }); - }); - - describe('interpretResponse', function () { - it('should return an empty array when parsing a no bid response', function () { - const response = {}; - const request = { bidRequests: [] }; - const bids = spec.interpretResponse(response, request); - expect(bids).to.have.lengthOf(0); - }); - - it('should properly parse a bid response with a networkId', function () { - const response = { - body: { - slots: [{ - impid: 'test-requestId', - cpm: 1.23, - creative: 'test-ad', - width: 728, - height: 90, - dealCode: 'myDealCode', - }], - }, - }; - const request = { - bidRequests: [{ - adUnitCode: 'test-requestId', - bidId: 'test-bidId', - params: { - networkId: 456, - } - }] - }; - const bids = spec.interpretResponse(response, request); - expect(bids).to.have.lengthOf(1); - expect(bids[0].requestId).to.equal('test-bidId'); - expect(bids[0].cpm).to.equal(1.23); - expect(bids[0].ad).to.equal('test-ad'); - expect(bids[0].width).to.equal(728); - expect(bids[0].height).to.equal(90); - expect(bids[0].dealId).to.equal('myDealCode'); - }); - - it('should properly parse a bid response with a zoneId', function () { - const response = { - body: { - slots: [{ - impid: 'test-requestId', - bidId: 'abc123', - cpm: 1.23, - creative: 'test-ad', - width: 728, - height: 90, - zoneid: 123, - }], - }, - }; - const request = { - bidRequests: [{ - adUnitCode: 'test-requestId', - bidId: 'test-bidId', - params: { - zoneId: 123, - }, - }] - }; - const bids = spec.interpretResponse(response, request); - expect(bids).to.have.lengthOf(1); - expect(bids[0].requestId).to.equal('test-bidId'); - expect(bids[0].adId).to.equal('abc123'); - expect(bids[0].cpm).to.equal(1.23); - expect(bids[0].ad).to.equal('test-ad'); - expect(bids[0].width).to.equal(728); - expect(bids[0].height).to.equal(90); - }); - - it('should properly parse a bid response with a video', function () { - const response = { - body: { - slots: [{ - impid: 'test-requestId', - bidId: 'abc123', - cpm: 1.23, - displayurl: 'http://test-ad', - width: 728, - height: 90, - zoneid: 123, - video: true - }], - }, - }; - const request = { - bidRequests: [{ - adUnitCode: 'test-requestId', - bidId: 'test-bidId', - params: { - zoneId: 123, - }, - }] - }; - const bids = spec.interpretResponse(response, request); - expect(bids).to.have.lengthOf(1); - expect(bids[0].requestId).to.equal('test-bidId'); - expect(bids[0].adId).to.equal('abc123'); - expect(bids[0].cpm).to.equal(1.23); - expect(bids[0].vastUrl).to.equal('http://test-ad'); - expect(bids[0].mediaType).to.equal(VIDEO); - }); - - it('should properly parse a bid response with native', function () { - const response = { - body: { - slots: [{ - impid: 'test-requestId', - bidId: 'abc123', - cpm: 1.23, - width: 728, - height: 90, - zoneid: 123, - native: { - 'products': [{ - 'sendTargetingKeys': false, - 'title': 'Product title', - 'description': 'Product desc', - 'price': '100', - 'click_url': 'https://product.click', - 'image': { - 'url': 'https://publisherdirect.criteo.com/publishertag/preprodtest/creative.png', - 'height': 300, - 'width': 300 - }, - 'call_to_action': 'Try it now!' - }], - 'advertiser': { - 'description': 'sponsor', - 'domain': 'criteo.com', - 'logo': {'url': 'https://www.criteo.com/images/criteo-logo.svg', 'height': 300, 'width': 300} - }, - 'privacy': { - 'optout_click_url': 'https://info.criteo.com/privacy/informations', - 'optout_image_url': 'https://static.criteo.net/flash/icon/nai_small.png', - }, - 'impression_pixels': [{'url': 'https://my-impression-pixel/test/impression'}, {'url': 'https://cas.com/lg.com'}] - } - }], - }, - }; - const request = { - bidRequests: [{ - adUnitCode: 'test-requestId', - bidId: 'test-bidId', - params: { - zoneId: 123, - }, - native: true, - }] - }; - const bids = spec.interpretResponse(response, request); - expect(bids).to.have.lengthOf(1); - expect(bids[0].requestId).to.equal('test-bidId'); - expect(bids[0].adId).to.equal('abc123'); - expect(bids[0].cpm).to.equal(1.23); - expect(bids[0].mediaType).to.equal(NATIVE); - }); - - it('should warn only once if sendTargetingKeys set to true on required fields for native bidRequest', () => { - const bidderRequest = { }; - const bidRequests = [ - { - bidder: 'criteo', - adUnitCode: 'bid-123', - transactionId: 'transaction-123', - sizes: [[728, 90]], - params: { - zoneId: 123, - publisherSubId: '123', - nativeCallback: function() {} - }, - }, - { - bidder: 'criteo', - adUnitCode: 'bid-456', - transactionId: 'transaction-456', - sizes: [[728, 90]], - params: { - zoneId: 456, - publisherSubId: '456', - nativeCallback: function() {} - }, - }, - ]; - - const nativeParamsWithSendTargetingKeys = [ - { - nativeParams: { - image: { - sendTargetingKeys: true - }, - } - }, - { - nativeParams: { - icon: { - sendTargetingKeys: true - }, - } - }, - { - nativeParams: { - clickUrl: { - sendTargetingKeys: true - }, - } - }, - { - nativeParams: { - displayUrl: { - sendTargetingKeys: true - }, - } - }, - { - nativeParams: { - privacyLink: { - sendTargetingKeys: true - }, - } - }, - { - nativeParams: { - privacyIcon: { - sendTargetingKeys: true - }, - } - } - ]; - - utilsMock.expects('logWarn') - .withArgs('Criteo: all native assets containing URL should be sent as placeholders with sendId(icon, image, clickUrl, displayUrl, privacyLink, privacyIcon)') - .exactly(nativeParamsWithSendTargetingKeys.length * bidRequests.length); - nativeParamsWithSendTargetingKeys.forEach(nativeParams => { - let transformedBidRequests = {...bidRequests}; - transformedBidRequests = [Object.assign(transformedBidRequests[0], nativeParams), Object.assign(transformedBidRequests[1], nativeParams)]; - spec.buildRequests(transformedBidRequests, bidderRequest); - }); - utilsMock.verify(); - }); - - it('should properly parse a bid response with a zoneId passed as a string', function () { - const response = { - body: { - slots: [{ - impid: 'test-requestId', - cpm: 1.23, - creative: 'test-ad', - width: 728, - height: 90, - zoneid: 123, - }], - }, - }; - const request = { - bidRequests: [{ - adUnitCode: 'test-requestId', - bidId: 'test-bidId', - params: { - zoneId: '123', - }, - }] - }; - const bids = spec.interpretResponse(response, request); - expect(bids).to.have.lengthOf(1); - expect(bids[0].requestId).to.equal('test-bidId'); - expect(bids[0].cpm).to.equal(1.23); - expect(bids[0].ad).to.equal('test-ad'); - expect(bids[0].width).to.equal(728); - expect(bids[0].height).to.equal(90); - }); - - it('should generate unique adIds if none are returned by the endpoint', function () { - const response = { - body: { - slots: [{ - impid: 'test-requestId', - cpm: 1.23, - creative: 'test-ad', - width: 300, - height: 250, - }, { - impid: 'test-requestId', - cpm: 4.56, - creative: 'test-ad', - width: 728, - height: 90, - }], - }, - }; - const request = { - bidRequests: [{ - adUnitCode: 'test-requestId', - bidId: 'test-bidId', - sizes: [[300, 250], [728, 90]], - params: { - networkId: 456, - } - }] - }; - const bids = spec.interpretResponse(response, request); - expect(bids).to.have.lengthOf(2); - const prebidBids = bids.map(bid => Object.assign(createBid(CONSTANTS.STATUS.GOOD, request.bidRequests[0]), bid)); - expect(prebidBids[0].adId).to.not.equal(prebidBids[1].adId); - }); - }); - - describe('tryGetCriteoFastBid', function () { - const VALID_HASH = 'vBeD8Q7GU6lypFbzB07W8hLGj7NL+p7dI9ro2tCxkrmyv0F6stNuoNd75Us33iNKfEoW+cFWypelr6OJPXxki2MXWatRhJuUJZMcK4VBFnxi3Ro+3a0xEfxE4jJm4eGe98iC898M+/YFHfp+fEPEnS6pEyw124ONIFZFrcejpHU='; - const INVALID_HASH = 'invalid'; - const VALID_PUBLISHER_TAG = 'test'; - const INVALID_PUBLISHER_TAG = 'test invalid'; - - const FASTBID_LOCAL_STORAGE_KEY = 'criteo_fast_bid'; - - it('should verify valid hash with valid publisher tag', function () { - localStorage.setItem(FASTBID_LOCAL_STORAGE_KEY, '// Hash: ' + VALID_HASH + '\n' + VALID_PUBLISHER_TAG); - - utilsMock.expects('logInfo').withExactArgs('Using Criteo FastBid').once(); - utilsMock.expects('logWarn').withExactArgs('No hash found in FastBid').never(); - utilsMock.expects('logWarn').withExactArgs('Invalid Criteo FastBid found').never(); - - tryGetCriteoFastBid(); - - expect(localStorage.getItem(FASTBID_LOCAL_STORAGE_KEY)).to.equals('// Hash: ' + VALID_HASH + '\n' + VALID_PUBLISHER_TAG); - utilsMock.verify(); - }); - - it('should verify valid hash with invalid publisher tag', function () { - localStorage.setItem(FASTBID_LOCAL_STORAGE_KEY, '// Hash: ' + VALID_HASH + '\n' + INVALID_PUBLISHER_TAG); - - utilsMock.expects('logInfo').withExactArgs('Using Criteo FastBid').never(); - utilsMock.expects('logWarn').withExactArgs('No hash found in FastBid').never(); - utilsMock.expects('logWarn').withExactArgs('Invalid Criteo FastBid found').once(); - - tryGetCriteoFastBid(); - - expect(localStorage.getItem(FASTBID_LOCAL_STORAGE_KEY)).to.be.null; - utilsMock.verify(); - }); - - it('should verify invalid hash with valid publisher tag', function () { - localStorage.setItem(FASTBID_LOCAL_STORAGE_KEY, '// Hash: ' + INVALID_HASH + '\n' + VALID_PUBLISHER_TAG); - - utilsMock.expects('logInfo').withExactArgs('Using Criteo FastBid').never(); - utilsMock.expects('logWarn').withExactArgs('No hash found in FastBid').never(); - utilsMock.expects('logWarn').withExactArgs('Invalid Criteo FastBid found').once(); - - tryGetCriteoFastBid(); - - expect(localStorage.getItem(FASTBID_LOCAL_STORAGE_KEY)).to.be.null; - utilsMock.verify(); - }); - - it('should verify missing hash', function () { - localStorage.setItem(FASTBID_LOCAL_STORAGE_KEY, VALID_PUBLISHER_TAG); - - utilsMock.expects('logInfo').withExactArgs('Using Criteo FastBid').never(); - utilsMock.expects('logWarn').withExactArgs('No hash found in FastBid').once(); - utilsMock.expects('logWarn').withExactArgs('Invalid Criteo FastBid found').never(); - - tryGetCriteoFastBid(); - - expect(localStorage.getItem(FASTBID_LOCAL_STORAGE_KEY)).to.be.null; - utilsMock.verify(); - }); - }); - - describe('when pubtag prebid adapter is not available', function () { - it('should not warn if sendId is provided on required fields for native bidRequest', () => { - const bidderRequest = { }; - const bidRequestsWithSendId = [ - { - bidder: 'criteo', - adUnitCode: 'bid-123', - transactionId: 'transaction-123', - sizes: [[728, 90]], - params: { - zoneId: 123, - publisherSubId: '123', - nativeCallback: function() {} - }, - nativeParams: { - image: { - sendId: true - }, - icon: { - sendId: true - }, - clickUrl: { - sendId: true - }, - displayUrl: { - sendId: true - }, - privacyLink: { - sendId: true - }, - privacyIcon: { - sendId: true - } - } - } - ]; - - utilsMock.expects('logWarn').withArgs('Criteo: all native assets containing URL should be sent as placeholders with sendId(icon, image, clickUrl, displayUrl, privacyLink, privacyIcon)').never(); - const request = spec.buildRequests(bidRequestsWithSendId, bidderRequest); - utilsMock.verify(); - }); - - it('should warn only once if sendId is not provided on required fields for native bidRequest', () => { - const bidderRequest = { }; - const bidRequests = [ - { - bidder: 'criteo', - adUnitCode: 'bid-123', - transactionId: 'transaction-123', - sizes: [[728, 90]], - params: { - zoneId: 123, - publisherSubId: '123', - nativeCallback: function() {} - }, - }, - { - bidder: 'criteo', - adUnitCode: 'bid-456', - transactionId: 'transaction-456', - sizes: [[728, 90]], - params: { - zoneId: 456, - publisherSubId: '456', - nativeCallback: function() {} - }, - }, - ]; - - const nativeParamsWithoutSendId = [ - { - nativeParams: { - image: { - sendId: false - }, - } - }, - { - nativeParams: { - icon: { - sendId: false - }, - } - }, - { - nativeParams: { - clickUrl: { - sendId: false - }, - } - }, - { - nativeParams: { - displayUrl: { - sendId: false - }, - } - }, - { - nativeParams: { - privacyLink: { - sendId: false - }, - } - }, - { - nativeParams: { - privacyIcon: { - sendId: false - }, - } - } - ]; - - utilsMock.expects('logWarn') - .withArgs('Criteo: all native assets containing URL should be sent as placeholders with sendId(icon, image, clickUrl, displayUrl, privacyLink, privacyIcon)') - .exactly(nativeParamsWithoutSendId.length * bidRequests.length); - nativeParamsWithoutSendId.forEach(nativeParams => { - let transformedBidRequests = {...bidRequests}; - transformedBidRequests = [Object.assign(transformedBidRequests[0], nativeParams), Object.assign(transformedBidRequests[1], nativeParams)]; - spec.buildRequests(transformedBidRequests, bidderRequest); - }); - utilsMock.verify(); - }); - }); - - describe('when pubtag prebid adapter is available', function () { - it('should forward response to pubtag when calling interpretResponse', () => { - const response = {}; - const request = {}; - - const adapter = { interpretResponse: function() {} }; - const adapterMock = sinon.mock(adapter); - adapterMock.expects('interpretResponse').withExactArgs(response, request).once().returns('ok'); - const prebidAdapter = { GetAdapter: function() {} }; - const prebidAdapterMock = sinon.mock(prebidAdapter); - prebidAdapterMock.expects('GetAdapter').withExactArgs(request).once().returns(adapter); - - global.Criteo = { - PubTag: { - Adapters: { - Prebid: prebidAdapter - } - } - }; - - expect(spec.interpretResponse(response, request)).equal('ok'); - adapterMock.verify(); - prebidAdapterMock.verify(); - }); - - it('should forward bid to pubtag when calling onBidWon', () => { - const bid = { auctionId: 123 }; - - const adapter = { handleBidWon: function() {} }; - const adapterMock = sinon.mock(adapter); - adapterMock.expects('handleBidWon').withExactArgs(bid).once(); - const prebidAdapter = { GetAdapter: function() {} }; - const prebidAdapterMock = sinon.mock(prebidAdapter); - prebidAdapterMock.expects('GetAdapter').withExactArgs(bid.auctionId).once().returns(adapter); - - global.Criteo = { - PubTag: { - Adapters: { - Prebid: prebidAdapter - } - } - }; - - spec.onBidWon(bid); - adapterMock.verify(); - prebidAdapterMock.verify(); - }); - - it('should forward bid to pubtag when calling onSetTargeting', () => { - const bid = { auctionId: 123 }; - - const adapter = { handleSetTargeting: function() {} }; - const adapterMock = sinon.mock(adapter); - adapterMock.expects('handleSetTargeting').withExactArgs(bid).once(); - const prebidAdapter = { GetAdapter: function() {} }; - const prebidAdapterMock = sinon.mock(prebidAdapter); - prebidAdapterMock.expects('GetAdapter').withExactArgs(bid.auctionId).once().returns(adapter); - - global.Criteo = { - PubTag: { - Adapters: { - Prebid: prebidAdapter - } - } - }; - - spec.onSetTargeting(bid); - adapterMock.verify(); - prebidAdapterMock.verify(); - }); - - it('should forward bid to pubtag when calling onTimeout', () => { - const timeoutData = [{ auctionId: 123 }]; - - const adapter = { handleBidTimeout: function() {} }; - const adapterMock = sinon.mock(adapter); - adapterMock.expects('handleBidTimeout').once(); - const prebidAdapter = { GetAdapter: function() {} }; - const prebidAdapterMock = sinon.mock(prebidAdapter); - prebidAdapterMock.expects('GetAdapter').withExactArgs(timeoutData[0].auctionId).once().returns(adapter); - - global.Criteo = { - PubTag: { - Adapters: { - Prebid: prebidAdapter - } - } - }; - - spec.onTimeout(timeoutData); - adapterMock.verify(); - prebidAdapterMock.verify(); - }); - - it('should return a POST method with url & data from pubtag', () => { - const bidRequests = { }; - const bidderRequest = { }; - - const prebidAdapter = { buildCdbUrl: function() {}, buildCdbRequest: function() {} }; - const prebidAdapterMock = sinon.mock(prebidAdapter); - prebidAdapterMock.expects('buildCdbUrl').once().returns('cdbUrl'); - prebidAdapterMock.expects('buildCdbRequest').once().returns('cdbRequest'); - - const adapters = { Prebid: function() {} }; - const adaptersMock = sinon.mock(adapters); - adaptersMock.expects('Prebid').withExactArgs(PROFILE_ID_PUBLISHERTAG, ADAPTER_VERSION, bidRequests, bidderRequest, '$prebid.version$').once().returns(prebidAdapter); - - global.Criteo = { - PubTag: { - Adapters: adapters - } - }; - - const buildRequestsResult = spec.buildRequests(bidRequests, bidderRequest); - expect(buildRequestsResult.method).equal('POST'); - expect(buildRequestsResult.url).equal('cdbUrl'); - expect(buildRequestsResult.data).equal('cdbRequest'); - - adaptersMock.verify(); - prebidAdapterMock.verify(); - }); - }); -}); diff --git a/test/spec/modules/criteoIdSystem_spec.js b/test/spec/modules/criteoIdSystem_spec.js deleted file mode 100644 index 65e5aaf741d..00000000000 --- a/test/spec/modules/criteoIdSystem_spec.js +++ /dev/null @@ -1,155 +0,0 @@ -import { criteoIdSubmodule, storage } from 'modules/criteoIdSystem.js'; -import * as utils from 'src/utils.js'; -import * as ajaxLib from 'src/ajax.js'; - -const pastDateString = new Date(0).toString() - -function mockResponse(responseText, fakeResponse = (url, callback) => callback(responseText)) { - return function() { - return fakeResponse; - } -} - -describe('CriteoId module', function () { - const cookiesMaxAge = 13 * 30 * 24 * 60 * 60 * 1000; - - const nowTimestamp = new Date().getTime(); - - let getCookieStub; - let setCookieStub; - let getLocalStorageStub; - let setLocalStorageStub; - let removeFromLocalStorageStub; - let timeStampStub; - let parseUrlStub; - let ajaxBuilderStub; - let triggerPixelStub; - - beforeEach(function (done) { - getCookieStub = sinon.stub(storage, 'getCookie'); - setCookieStub = sinon.stub(storage, 'setCookie'); - getLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage'); - setLocalStorageStub = sinon.stub(storage, 'setDataInLocalStorage'); - removeFromLocalStorageStub = sinon.stub(storage, 'removeDataFromLocalStorage'); - timeStampStub = sinon.stub(utils, 'timestamp').returns(nowTimestamp); - ajaxBuilderStub = sinon.stub(ajaxLib, 'ajaxBuilder').callsFake(mockResponse('{}')); - parseUrlStub = sinon.stub(utils, 'parseUrl').returns({protocol: 'https', hostname: 'testdev.com'}) - triggerPixelStub = sinon.stub(utils, 'triggerPixel'); - done(); - }); - - afterEach(function () { - getCookieStub.restore(); - setCookieStub.restore(); - getLocalStorageStub.restore(); - setLocalStorageStub.restore(); - removeFromLocalStorageStub.restore(); - timeStampStub.restore(); - ajaxBuilderStub.restore(); - triggerPixelStub.restore(); - parseUrlStub.restore(); - }); - - const storageTestCases = [ - { cookie: 'bidId', localStorage: 'bidId2', expected: 'bidId' }, - { cookie: 'bidId', localStorage: undefined, expected: 'bidId' }, - { cookie: undefined, localStorage: 'bidId', expected: 'bidId' }, - { cookie: undefined, localStorage: undefined, expected: undefined }, - ] - - storageTestCases.forEach(testCase => it('getId() should return the bidId when it exists in local storages', function () { - getCookieStub.withArgs('cto_bidid').returns(testCase.cookie); - getLocalStorageStub.withArgs('cto_bidid').returns(testCase.localStorage); - - const id = criteoIdSubmodule.getId(); - expect(id).to.be.deep.equal({id: testCase.expected ? { criteoId: testCase.expected } : undefined}); - })) - - it('decode() should return the bidId when it exists in local storages', function () { - const id = criteoIdSubmodule.decode('testDecode'); - expect(id).to.equal('testDecode') - }); - - it('should call user sync url with the right params', function () { - getCookieStub.withArgs('cto_bundle').returns('bundle'); - window.criteo_pubtag = {} - - const emptyObj = '{}'; - let ajaxStub = sinon.stub().callsFake((url, callback) => callback(emptyObj)); - ajaxBuilderStub.callsFake(mockResponse(undefined, ajaxStub)) - - criteoIdSubmodule.getId(); - const expectedUrl = `https://gum.criteo.com/sid/json?origin=prebid&topUrl=https%3A%2F%2Ftestdev.com%2F&domain=testdev.com&bundle=bundle&cw=1&pbt=1&lsw=1`; - - expect(ajaxStub.calledWith(expectedUrl)).to.be.true; - - window.criteo_pubtag = undefined; - }); - - const responses = [ - { bundle: 'bundle', bidId: 'bidId', acwsUrl: 'acwsUrl' }, - { bundle: 'bundle', bidId: undefined, acwsUrl: 'acwsUrl' }, - { bundle: 'bundle', bidId: 'bidId', acwsUrl: undefined }, - { bundle: undefined, bidId: 'bidId', acwsUrl: 'acwsUrl' }, - { bundle: 'bundle', bidId: undefined, acwsUrl: undefined }, - { bundle: undefined, bidId: 'bidId', acwsUrl: undefined }, - { bundle: undefined, bidId: undefined, acwsUrl: 'acwsUrl' }, - { bundle: undefined, bidId: undefined, acwsUrl: ['acwsUrl', 'acwsUrl2'] }, - { bundle: undefined, bidId: undefined, acwsUrl: undefined }, - ] - - responses.forEach(response => describe('test user sync response behavior', function () { - const expirationTs = new Date(nowTimestamp + cookiesMaxAge).toString(); - - beforeEach(function (done) { - const fakeResponse = (url, callback) => { - callback(JSON.stringify(response)); - setTimeout(done, 0); - } - ajaxBuilderStub.callsFake(mockResponse(undefined, fakeResponse)); - criteoIdSubmodule.getId(); - }) - - it('should save bidId if it exists', function () { - if (response.acwsUrl) { - expect(triggerPixelStub.called).to.be.true; - expect(setCookieStub.calledWith('cto_bundle')).to.be.false; - expect(setLocalStorageStub.calledWith('cto_bundle')).to.be.false; - } else if (response.bundle) { - expect(setCookieStub.calledWith('cto_bundle', response.bundle, expirationTs)).to.be.true; - expect(setLocalStorageStub.calledWith('cto_bundle', response.bundle)).to.be.true; - expect(triggerPixelStub.called).to.be.false; - } - - if (response.bidId) { - expect(setCookieStub.calledWith('cto_bidid', response.bidId, expirationTs)).to.be.true; - expect(setLocalStorageStub.calledWith('cto_bidid', response.bidId)).to.be.true; - } else { - expect(setCookieStub.calledWith('cto_bidid', '', pastDateString)).to.be.true; - expect(removeFromLocalStorageStub.calledWith('cto_bidid')).to.be.true; - } - }); - })); - - const gdprConsentTestCases = [ - { consentData: { gdprApplies: true, consentString: 'expectedConsentString' }, expected: 'expectedConsentString' }, - { consentData: { gdprApplies: false, consentString: 'expectedConsentString' }, expected: undefined }, - { consentData: { gdprApplies: true, consentString: undefined }, expected: undefined }, - { consentData: { gdprApplies: 'oui', consentString: 'expectedConsentString' }, expected: undefined }, - { consentData: undefined, expected: undefined } - ]; - - gdprConsentTestCases.forEach(testCase => it('should call user sync url with the gdprConsent', function () { - const emptyObj = '{}'; - let ajaxStub = sinon.stub().callsFake((url, callback) => callback(emptyObj)); - ajaxBuilderStub.callsFake(mockResponse(undefined, ajaxStub)) - - criteoIdSubmodule.getId(undefined, testCase.consentData); - - if (testCase.expected) { - expect(ajaxStub.calledWithMatch(`gdprString=${testCase.expected}`)).to.be.true; - } else { - expect(ajaxStub.calledWithMatch('gdprString')).not.to.be.true; - } - })); -}); diff --git a/test/spec/modules/currency_spec.js b/test/spec/modules/currency_spec.js deleted file mode 100644 index ccd205964a9..00000000000 --- a/test/spec/modules/currency_spec.js +++ /dev/null @@ -1,423 +0,0 @@ - -import { - getCurrencyRates -} from 'test/fixtures/fixtures.js'; - -import { getGlobal } from 'src/prebidGlobal.js'; - -import { - setConfig, - addBidResponseHook, - currencySupportEnabled, - currencyRates -} from 'modules/currency.js'; - -var assert = require('chai').assert; -var expect = require('chai').expect; - -describe('currency', function () { - let fakeCurrencyFileServer; - let sandbox; - let clock; - - let fn = sinon.spy(); - - beforeEach(function () { - fakeCurrencyFileServer = sinon.fakeServer.create(); - }); - - afterEach(function () { - fakeCurrencyFileServer.restore(); - setConfig({}); - }); - - describe('setConfig', function () { - beforeEach(function() { - sandbox = sinon.sandbox.create(); - clock = sinon.useFakeTimers(1046952000000); // 2003-03-06T12:00:00Z - }); - - afterEach(function () { - sandbox.restore(); - clock.restore(); - }); - - it('results in currencySupportEnabled = false when currency not configured', function () { - setConfig({}); - expect(currencySupportEnabled).to.equal(false); - expect(getGlobal().convertCurrency).to.be.undefined; - }); - it('adds conversion function onto pbjs global var once initiated', function () { - setConfig({ 'adServerCurrency': 'JPY' }); - expect(getGlobal().convertCurrency).to.be.a('function'); - }); - it('results in currencySupportEnabled = true and currencyRates being loaded when configured', function () { - fakeCurrencyFileServer.respondWith(JSON.stringify(getCurrencyRates())); - setConfig({ 'adServerCurrency': 'JPY' }); - fakeCurrencyFileServer.respond(); - expect(currencyRates.dataAsOf).to.equal('2017-04-25'); - expect(currencySupportEnabled).to.equal(true); - }); - - it('currency file is called even when default rates are specified', function() { - // RESET to request currency file (specifically url value for this test) - setConfig({ 'adServerCurrency': undefined }); - - // DO NOT SET DEFAULT RATES, currency file should be requested - setConfig({ - 'adServerCurrency': 'JPY' - }); - fakeCurrencyFileServer.respond(); - expect(fakeCurrencyFileServer.requests.length).to.equal(1); - expect(fakeCurrencyFileServer.requests[0].url).to.equal('https://cdn.jsdelivr.net/gh/prebid/currency-file@1/latest.json?date=20030306'); - - // RESET to request currency file (specifically url value for this test) - setConfig({ 'adServerCurrency': undefined }); - - // SET DEFAULT RATES, currency file should STILL be requested - setConfig({ - 'adServerCurrency': 'JPY', - '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'); - }); - - it('date macro token $$TODAY$$ is replaced by current date (formatted as yyyymmdd)', function () { - // RESET to request currency file (specifically url value for this test) - setConfig({ 'adServerCurrency': undefined }); - - // date macro should replace $$TODAY$$ with date when DEFAULT_CURRENCY_RATE_URL is used - setConfig({ 'adServerCurrency': 'JPY' }); - fakeCurrencyFileServer.respond(); - expect(fakeCurrencyFileServer.requests[0].url).to.equal('https://cdn.jsdelivr.net/gh/prebid/currency-file@1/latest.json?date=20030306'); - - // RESET to request currency file (specifically url value for this test) - setConfig({ 'adServerCurrency': undefined }); - - // date macro should not modify 'conversionRateFile' if TOKEN is not found - setConfig({ - 'adServerCurrency': 'JPY', - 'conversionRateFile': 'http://test.net/currency.json?date=foobar' - }); - fakeCurrencyFileServer.respond(); - expect(fakeCurrencyFileServer.requests[1].url).to.equal('http://test.net/currency.json?date=foobar'); - - // RESET to request currency file (specifically url value for this test) - setConfig({ 'adServerCurrency': undefined }); - - // date macro should replace $$TODAY$$ with date for 'conversionRateFile' is configured - setConfig({ - 'adServerCurrency': 'JPY', - 'conversionRateFile': 'http://test.net/currency.json?date=$$TODAY$$' - }); - fakeCurrencyFileServer.respond(); - expect(fakeCurrencyFileServer.requests[2].url).to.equal('http://test.net/currency.json?date=20030306'); - - // RESET to request currency file (specifically url value for this test) - setConfig({ 'adServerCurrency': undefined }); - - // MULTIPLE TOKENS used in a url is not supported. Only the TOKEN at left-most position is REPLACED - setConfig({ - 'adServerCurrency': 'JPY', - 'conversionRateFile': 'http://test.net/$$TODAY$$/currency.json?date=$$TODAY$$' - }); - fakeCurrencyFileServer.respond(); - expect(fakeCurrencyFileServer.requests[3].url).to.equal('http://test.net/20030306/currency.json?date=$$TODAY$$'); - }); - }); - - describe('global currency function', function () { - it('still returns conversion if default rates present with fetch not returned yet', function () { - setConfig({ - 'adServerCurrency': 'USD', - 'defaultRates': { - 'USD': { EUR: 2, JPY: 100 } - } - }); - // first conversion should use default rates - expect(getGlobal().convertCurrency(1.0, 'USD', 'EUR')).to.equal(2); - expect(getGlobal().convertCurrency(1.0, 'USD', 'JPY')).to.equal(100); - fakeCurrencyFileServer.respond(); - }); - it('uses fetch rates if returned', function () { - fakeCurrencyFileServer.respondWith(JSON.stringify({ - 'dataAsOf': '2017-04-25', - 'conversions': { - 'USD': { EUR: 4, JPY: 200 } - } - })); - setConfig({ - 'adServerCurrency': 'USD', - 'defaultRates': { - 'USD': { EUR: 2, JPY: 100 } - } - }); - // now respond and should use updates rates - fakeCurrencyFileServer.respond(); - expect(getGlobal().convertCurrency(1.0, 'USD', 'EUR')).to.equal(4); - expect(getGlobal().convertCurrency(1.0, 'USD', 'JPY')).to.equal(200); - }); - }); - describe('bidder override', function () { - it('allows setConfig to set bidder currency', function () { - setConfig({}); - - var bid = { cpm: 1, bidder: 'rubicon' }; - var innerBid; - - setConfig({ - adServerCurrency: 'GBP', - bidderCurrencyDefault: { - rubicon: 'GBP' - } - }); - - addBidResponseHook(function(adCodeId, bid) { - innerBid = bid; - }, 'elementId', bid); - - expect(innerBid.currency).to.equal('GBP'); - expect(typeof innerBid.getCpmInNewCurrency).to.equal('function'); - expect(innerBid.getCpmInNewCurrency('GBP')).to.equal('1.000'); - }); - - it('uses adapter currency over currency override if specified', function () { - setConfig({}); - - var bid = { cpm: 1, currency: 'JPY', bidder: 'rubicon' }; - var innerBid; - - setConfig({ - adServerCurrency: 'JPY', - bidderCurrencyDefault: { - rubicon: 'GBP' - } - }); - - addBidResponseHook(function(adCodeId, bid) { - innerBid = bid; - }, 'elementId', bid); - - expect(innerBid.currency).to.equal('JPY'); - expect(typeof innerBid.getCpmInNewCurrency).to.equal('function'); - expect(innerBid.getCpmInNewCurrency('JPY')).to.equal('1.000'); - }); - - it('uses rates specified in json when provided', function () { - setConfig({ - adServerCurrency: 'USD', - rates: { - USD: { - JPY: 100 - } - } - }); - - var bid = { cpm: 100, currency: 'JPY', bidder: 'rubicon' }; - var innerBid; - - addBidResponseHook(function(adCodeId, bid) { - innerBid = bid; - }, 'elementId', bid); - - expect(innerBid.cpm).to.equal('1.0000'); - expect(typeof innerBid.getCpmInNewCurrency).to.equal('function'); - expect(innerBid.getCpmInNewCurrency('JPY')).to.equal('100.000'); - }); - - it('uses rates specified in json when provided and consider boosted bid', function () { - setConfig({ - adServerCurrency: 'USD', - rates: { - USD: { - JPY: 100 - } - } - }); - - var bid = { cpm: 100, currency: 'JPY', bidder: 'rubicon' }; - var innerBid; - - addBidResponseHook(function(adCodeId, bid) { - innerBid = bid; - }, 'elementId', bid); - - expect(innerBid.cpm).to.equal('1.0000'); - expect(typeof innerBid.getCpmInNewCurrency).to.equal('function'); - expect(innerBid.getCpmInNewCurrency('JPY')).to.equal('100.000'); - - // Boosting the bid now - innerBid.cpm *= 10; - expect(innerBid.cpm).to.equal(10.0000); - expect(typeof innerBid.getCpmInNewCurrency).to.equal('function'); - expect(innerBid.getCpmInNewCurrency('JPY')).to.equal('1000.000'); - }); - - it('uses default rates when currency file fails to load', function () { - setConfig({}); - - setConfig({ - adServerCurrency: 'USD', - defaultRates: { - USD: { - JPY: 100 - } - } - }); - - // default response is 404 - fakeCurrencyFileServer.respond(); - - var bid = { cpm: 100, currency: 'JPY', bidder: 'rubicon' }; - var innerBid; - - addBidResponseHook(function(adCodeId, bid) { - innerBid = bid; - }, 'elementId', bid); - - expect(innerBid.cpm).to.equal('1.0000'); - expect(typeof innerBid.getCpmInNewCurrency).to.equal('function'); - expect(innerBid.getCpmInNewCurrency('JPY')).to.equal('100.000'); - }); - }); - - describe('currency.addBidResponseDecorator bidResponseQueue', function () { - it('not run until currency rates file is loaded', function () { - setConfig({}); - - fakeCurrencyFileServer.respondWith(JSON.stringify(getCurrencyRates())); - - var bid = { 'cpm': 1, 'currency': 'USD' }; - - setConfig({ 'adServerCurrency': 'JPY' }); - - var marker = false; - addBidResponseHook(function() { - marker = true; - }, 'elementId', bid); - - expect(marker).to.equal(false); - - fakeCurrencyFileServer.respond(); - expect(marker).to.equal(true); - }); - }); - - describe('currency.addBidResponseDecorator', function () { - it('should leave bid at 1 when currency support is not enabled and fromCurrency is USD', function () { - setConfig({}); - var bid = { 'cpm': 1, 'currency': 'USD' }; - var innerBid; - addBidResponseHook(function(adCodeId, bid) { - innerBid = bid; - }, 'elementId', bid); - expect(innerBid.cpm).to.equal(1); - }); - - it('should result in NO_BID when currency support is not enabled and fromCurrency is not USD', function () { - setConfig({}); - - var bid = { 'cpm': 1, 'currency': 'GBP' }; - var innerBid; - addBidResponseHook(function(adCodeId, bid) { - innerBid = bid; - }, 'elementId', bid); - expect(innerBid.statusMessage).to.equal('Bid returned empty or error response'); - }); - - it('should not buffer bid when currency is already in desired currency', function () { - setConfig({ - 'adServerCurrency': 'USD' - }); - var bid = { 'cpm': 1, 'currency': 'USD' }; - var innerBid; - addBidResponseHook(function(adCodeId, bid) { - innerBid = bid; - }, 'elementId', bid); - expect(bid).to.equal(innerBid); - }); - - it('should result in NO_BID when fromCurrency is not supported in file', function () { - // RESET to request currency file - setConfig({ 'adServerCurrency': undefined }); - - fakeCurrencyFileServer.respondWith(JSON.stringify(getCurrencyRates())); - setConfig({ 'adServerCurrency': 'JPY' }); - fakeCurrencyFileServer.respond(); - var bid = { 'cpm': 1, 'currency': 'ABC' }; - var innerBid; - addBidResponseHook(function(adCodeId, bid) { - innerBid = bid; - }, 'elementId', bid); - expect(innerBid.statusMessage).to.equal('Bid returned empty or error response'); - }); - - it('should result in NO_BID when adServerCurrency is not supported in file', function () { - fakeCurrencyFileServer.respondWith(JSON.stringify(getCurrencyRates())); - setConfig({ 'adServerCurrency': 'ABC' }); - fakeCurrencyFileServer.respond(); - var bid = { 'cpm': 1, 'currency': 'GBP' }; - var innerBid; - addBidResponseHook(function(adCodeId, bid) { - innerBid = bid; - }, 'elementId', bid); - expect(innerBid.statusMessage).to.equal('Bid returned empty or error response'); - }); - - it('should return 1 when currency support is enabled and same currency code is requested as is set to adServerCurrency', function () { - fakeCurrencyFileServer.respondWith(JSON.stringify(getCurrencyRates())); - setConfig({ 'adServerCurrency': 'JPY' }); - fakeCurrencyFileServer.respond(); - var bid = { 'cpm': 1, 'currency': 'JPY' }; - var innerBid; - addBidResponseHook(function(adCodeId, bid) { - innerBid = bid; - }, 'elementId', bid); - expect(innerBid.cpm).to.equal(1); - expect(innerBid.currency).to.equal('JPY'); - }); - - it('should return direct conversion rate when fromCurrency is one of the configured bases', function () { - fakeCurrencyFileServer.respondWith(JSON.stringify(getCurrencyRates())); - setConfig({ 'adServerCurrency': 'GBP' }); - fakeCurrencyFileServer.respond(); - var bid = { 'cpm': 1, 'currency': 'USD' }; - var innerBid; - addBidResponseHook(function(adCodeId, bid) { - innerBid = bid; - }, 'elementId', bid); - expect(innerBid.cpm).to.equal('0.7798'); - expect(innerBid.currency).to.equal('GBP'); - }); - - it('should return reciprocal conversion rate when adServerCurrency is one of the configured bases, but fromCurrency is not', function () { - fakeCurrencyFileServer.respondWith(JSON.stringify(getCurrencyRates())); - setConfig({ 'adServerCurrency': 'GBP' }); - fakeCurrencyFileServer.respond(); - var bid = { 'cpm': 1, 'currency': 'CNY' }; - var innerBid; - addBidResponseHook(function(adCodeId, bid) { - innerBid = bid; - }, 'elementId', bid); - expect(innerBid.cpm).to.equal('0.1133'); - expect(innerBid.currency).to.equal('GBP'); - }); - - it('should return intermediate conversion rate when neither fromCurrency nor adServerCurrency is one of the configured bases', function () { - fakeCurrencyFileServer.respondWith(JSON.stringify(getCurrencyRates())); - setConfig({ 'adServerCurrency': 'CNY' }); - fakeCurrencyFileServer.respond(); - var bid = { 'cpm': 1, 'currency': 'JPY' }; - var innerBid; - addBidResponseHook(function(adCodeId, bid) { - innerBid = bid; - }, 'elementId', bid); - expect(innerBid.cpm).to.equal('0.0623'); - expect(innerBid.currency).to.equal('CNY'); - }); - }); -}); diff --git a/test/spec/modules/dailyhuntBidAdapter_spec.js b/test/spec/modules/dailyhuntBidAdapter_spec.js deleted file mode 100644 index d571150dbee..00000000000 --- a/test/spec/modules/dailyhuntBidAdapter_spec.js +++ /dev/null @@ -1,400 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/dailyhuntBidAdapter.js'; - -const PROD_PREBID_ENDPOINT_URL = 'https://pbs.dailyhunt.in/openrtb2/auction?partner=dailyhunt'; -const PROD_PREBID_TEST_ENDPOINT_URL = 'https://qa-pbs-van.dailyhunt.in/openrtb2/auction?partner=dailyhunt'; - -const _encodeURIComponent = function (a) { - if (!a) { return } - let b = window.encodeURIComponent(a); - b = b.replace(/'/g, '%27'); - return b; -} - -describe('DailyhuntAdapter', function () { - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'dailyhunt', - 'params': { - placement_id: 1, - publisher_id: 1, - partner_name: 'dailyhunt' - } - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - describe('buildRequests', function() { - let bidRequests = [ - { - bidder: 'dailyhunt', - params: { - placement_id: 1, - publisher_id: 1, - partner_name: 'dailyhunt', - bidfloor: 0.1, - device: { - ip: '47.9.247.217' - }, - site: { - cat: ['1', '2', '3'] - } - }, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - adUnitCode: 'adunit-code', - sizes: [[300, 50]], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - transactionId: '04f2659e-c005-4eb1-a57c-fa93145e3843' - } - ]; - let nativeBidRequests = [ - { - bidder: 'dailyhunt', - params: { - placement_id: 1, - publisher_id: 1, - partner_name: 'dailyhunt', - }, - nativeParams: { - title: { - required: true, - len: 80 - }, - image: { - required: true, - sizes: [150, 50] - }, - }, - mediaTypes: { - native: { - title: { - required: true - }, - } - }, - adUnitCode: 'adunit-code', - sizes: [[300, 250], [300, 50]], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - transactionId: '04f2659e-c005-4eb1-a57c-fa93145e3843' - } - ]; - let videoBidRequests = [ - { - bidder: 'dailyhunt', - params: { - placement_id: 1, - publisher_id: 1, - partner_name: 'dailyhunt' - }, - nativeParams: { - video: { - context: 'instream' - } - }, - mediaTypes: { - video: { - context: 'instream' - } - }, - adUnitCode: 'adunit-code', - sizes: [[300, 250], [300, 50]], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - transactionId: '04f2659e-c005-4eb1-a57c-fa93145e3843' - } - ]; - let bidderRequest = { - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'bidderCode': 'dailyhunt', - 'bids': [ - { - ...bidRequests[0] - } - ], - 'refererInfo': { - 'referer': 'http://m.dailyhunt.in/' - } - }; - let nativeBidderRequest = { - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'bidderCode': 'dailyhunt', - 'bids': [ - { - ...nativeBidRequests[0] - } - ], - 'refererInfo': { - 'referer': 'http://m.dailyhunt.in/' - } - }; - let videoBidderRequest = { - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'bidderCode': 'dailyhunt', - 'bids': [ - { - ...videoBidRequests[0] - } - ], - 'refererInfo': { - 'referer': 'http://m.dailyhunt.in/' - } - }; - - it('sends display bid request to ENDPOINT via POST', function () { - const request = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(request.url).to.equal(PROD_PREBID_ENDPOINT_URL); - expect(request.method).to.equal('POST'); - }); - - it('sends native bid request to ENDPOINT via POST', function () { - const request = spec.buildRequests(nativeBidRequests, nativeBidderRequest)[0]; - expect(request.url).to.equal(PROD_PREBID_ENDPOINT_URL); - expect(request.method).to.equal('POST'); - }); - - it('sends video bid request to ENDPOINT via POST', function () { - const request = spec.buildRequests(videoBidRequests, videoBidderRequest)[0]; - expect(request.url).to.equal(PROD_PREBID_ENDPOINT_URL); - expect(request.method).to.equal('POST'); - }); - }); - describe('interpretResponse', function () { - let bidResponses = { - id: 'da32def7-6779-403c-ada7-0b201dbc9744', - seatbid: [ - { - bid: [ - { - id: 'id1', - impid: 'banner-impid', - price: 1.4, - adm: 'adm', - adid: '66658', - crid: 'asd5ddbf014cac993.66466212', - dealid: 'asd5ddbf014cac993.66466212', - w: 300, - h: 250, - nurl: 'winUrl', - ext: { - prebid: { - type: 'banner' - } - } - }, - { - id: '5caccc1f-94a6-4230-a1f9-6186ee65da99', - impid: 'video-impid', - price: 1.4, - nurl: 'winUrl', - adm: 'adm', - adid: '980', - crid: '2394', - w: 300, - h: 250, - ext: { - prebid: { - 'type': 'video' - }, - bidder: { - cacheKey: 'cache_key', - vastUrl: 'vastUrl' - } - } - }, - { - id: '74973faf-cce7-4eff-abd0-b59b8e91ca87', - impid: 'native-impid', - price: 50, - nurl: 'winUrl', - adm: '{"native":{"link":{"url":"url","clicktrackers":[]},"assets":[{"id":1,"required":1,"img":{},"video":{},"data":{},"title":{"text":"TITLE"},"link":{}},{"id":1,"required":1,"img":{},"video":{},"data":{"type":2,"value":"Lorem Ipsum Lorem Ipsum Lorem Ipsum."},"title":{},"link":{}},{"id":1,"required":1,"img":{},"video":{},"data":{"type":12,"value":"Install Here"},"title":{},"link":{}},{"id":1,"required":1,"img":{"type":3,"url":"urk","w":990,"h":505},"video":{},"data":{},"title":{},"link":{}}],"imptrackers":[]}}', - adid: '968', - crid: '2370', - w: 300, - h: 250, - ext: { - prebid: { - type: 'native' - }, - bidder: null - } - }, - { - id: '5caccc1f-94a6-4230-a1f9-6186ee65da99', - impid: 'video-outstream-impid', - price: 1.4, - nurl: 'winUrl', - adm: 'adm', - adid: '980', - crid: '2394', - w: 300, - h: 250, - ext: { - prebid: { - 'type': 'video' - }, - bidder: { - cacheKey: 'cache_key', - vastUrl: 'vastUrl' - } - } - }, - ], - seat: 'dailyhunt' - } - ], - ext: { - responsetimemillis: { - dailyhunt: 119 - } - } - }; - - it('should get correct bid response', function () { - let expectedResponse = [ - { - requestId: '1', - cpm: 1.4, - creativeId: 'asd5ddbf014cac993.66466212', - width: 300, - height: 250, - ttl: 360, - netRevenue: true, - currency: 'USD', - ad: 'adm', - mediaType: 'banner', - winUrl: 'winUrl' - }, - { - requestId: '2', - cpm: 1.4, - creativeId: '2394', - width: 300, - height: 250, - ttl: 360, - netRevenue: true, - currency: 'USD', - mediaType: 'video', - winUrl: 'winUrl', - videoCacheKey: 'cache_key', - vastUrl: 'vastUrl', - }, - { - requestId: '3', - cpm: 1.4, - creativeId: '2370', - width: 300, - height: 250, - ttl: 360, - netRevenue: true, - currency: 'USD', - mediaType: 'native', - winUrl: 'winUrl', - native: { - clickUrl: 'https%3A%2F%2Fmontu1996.github.io%2F', - clickTrackers: [], - impressionTrackers: [], - javascriptTrackers: [], - title: 'TITLE', - body: 'Lorem Ipsum Lorem Ipsum Lorem Ipsum.', - cta: 'Install Here', - image: { - url: 'url', - height: 505, - width: 990 - } - } - }, - { - requestId: '4', - cpm: 1.4, - creativeId: '2394', - width: 300, - height: 250, - ttl: 360, - netRevenue: true, - currency: 'USD', - mediaType: 'video', - winUrl: 'winUrl', - vastXml: 'adm', - }, - ]; - let bidderRequest = { - bids: [ - { - bidId: 'banner-impid', - adUnitCode: 'code1', - requestId: '1' - }, - { - bidId: 'video-impid', - adUnitCode: 'code2', - requestId: '2', - mediaTypes: { - video: { - context: 'instream' - } - } - }, - { - bidId: 'native-impid', - adUnitCode: 'code3', - requestId: '3' - }, - { - bidId: 'video-outstream-impid', - adUnitCode: 'code4', - requestId: '4', - mediaTypes: { - video: { - context: 'outstream' - } - } - }, - ] - } - let result = spec.interpretResponse({ body: bidResponses }, bidderRequest); - result.forEach((r, i) => { - expect(Object.keys(r)).to.have.members(Object.keys(expectedResponse[i])); - }); - }); - }) - describe('onBidWon', function () { - it('should hit win url when bid won', function () { - let bid = { - requestId: '1', - cpm: 1.4, - creativeId: 'asd5ddbf014cac993.66466212', - width: 300, - height: 250, - ttl: 360, - netRevenue: true, - currency: 'USD', - ad: 'adm', - mediaType: 'banner', - winUrl: 'winUrl' - }; - expect(spec.onBidWon(bid)).to.equal(undefined); - }); - }) -}) diff --git a/test/spec/modules/datablocksBidAdapter_spec.js b/test/spec/modules/datablocksBidAdapter_spec.js deleted file mode 100644 index 18b8aac7371..00000000000 --- a/test/spec/modules/datablocksBidAdapter_spec.js +++ /dev/null @@ -1,334 +0,0 @@ -import { expect } from 'chai'; -import { spec } from '../../../modules/datablocksBidAdapter.js'; - -let bid = { - bidId: '2dd581a2b6281d', - bidder: 'datablocks', - bidderRequestId: '145e1d6a7837c9', - params: { - sourceId: 7560, - host: 'v5demo.datablocks.net' - }, - adUnitCode: '/19968336/header-bid-tag-0', - auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', - mediaTypes: { - banner: { - sizes: [ - [300, 250] - ] - } - }, - sizes: [ - [300, 250] - ], - transactionId: '1ccbee15-f6f6-46ce-8998-58fe5542e8e1' -}; - -let bid2 = { - bidId: '2dd581a2b624324g', - bidder: 'datablocks', - bidderRequestId: '145e1d6a7837543', - params: { - sourceId: 7560, - host: 'v5demo.datablocks.net' - }, - adUnitCode: '/19968336/header-bid-tag-0', - auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', - mediaTypes: { - banner: { - sizes: - [728, 90] - } - }, - transactionId: '1ccbee15-f6f6-46ce-8998-58fe55425432' -}; - -let nativeBid = { - adUnitCode: '/19968336/header-bid-tag-0', - auctionId: '160c78a4-f808-410f-b682-d8728f3a79ee', - bidId: '332045ee374a99', - bidder: 'datablocks', - bidderRequestId: '15d9012765e36c', - mediaTypes: { - native: { - title: { - required: true - }, - body: { - required: true - }, - image: { - required: true - } - } - }, - nativeParams: { - title: { - required: true - }, - body: { - required: true, - data: { - len: 250 - } - }, - image: { - required: true, - sizes: [728, 90] - } - }, - params: { - sourceId: 7560, - host: 'v5demo.datablocks.net' - }, - transactionId: '0a4e9788-4def-4b94-bc25-564d7cac99f6' -} - -let videoBid = { - adUnitCode: '/19968336/header-bid-tag-0', - auctionId: '160c78a4-f808-410f-b682-d8728f3a79e1', - bidId: '332045ee374b99', - bidder: 'datablocks', - bidderRequestId: '15d9012765e36d', - mediaTypes: { - video: { - context: 'instream', - playerSize: [501, 400], - durationRangeSec: [15, 60] - } - }, - params: { - sourceId: 7560, - host: 'v5demo.datablocks.net', - video: { - minduration: 14 - } - }, - transactionId: '0a4e9788-4def-4b94-bc25-564d7cac99f7' -} - -const bidderRequest = { - auctionId: '8bfef1be-d3ac-4d18-8859-754c7b4cf017', - auctionStart: Date.now(), - biddeCode: 'datablocks', - bidderRequestId: '10c47a5fc3c41', - bids: [bid, bid2, nativeBid, videoBid], - refererInfo: { - numIframes: 0, - reachedTop: true, - referer: 'https://v5demo.datablocks.net/test', - stack: ['https://v5demo.datablocks.net/test'] - }, - start: Date.now(), - timeout: 10000 -}; - -let resObject = { - body: { - id: '10c47a5fc3c41', - bidid: '166895245-28-11347-1', - seatbid: [{ - seat: '7560', - bid: [{ - id: '1090738570', - impid: '2966b257c81d27', - price: 24.000000, - adm: 'RON', - cid: '55', - adid: '177654', - crid: '177656', - cat: [], - api: [], - w: 300, - h: 250 - }, { - id: '1090738571', - impid: '2966b257c81d28', - price: 24.000000, - adm: 'RON', - cid: '55', - adid: '177654', - crid: '177656', - cat: [], - api: [], - w: 728, - h: 90 - }, { - id: '1090738570', - impid: '15d9012765e36c', - price: 24.000000, - adm: '{"native":{"ver":"1.2","assets":[{"id":1,"required":1,"title":{"text":"Example Title"}},{"id":2,"required":1,"data":{"value":"Example Body"}},{"id":3,"required":1,"img":{"url":"https://example.image.com/"}}],"link":{"url":"https://click.example.com/c/264597/?fcid=29699699045816"},"imptrackers":["https://impression.example.com/i/264597/?fcid=29699699045816"]}}', - cid: '132145', - adid: '154321', - crid: '177432', - cat: [], - api: [] - }, { - id: '1090738575', - impid: '15d9012765e36f', - price: 25.000000, - cid: '12345', - adid: '12345', - crid: '123456', - nurl: 'https://click.v5demo.datablocks.net/m//?fcid=435235435432', - cat: [], - api: [], - w: 500, - h: 400 - }] - }], - cur: 'USD', - ext: {} - } -}; -let bidRequest = { - method: 'POST', - url: 'https://v5demo.datablocks.net/search/?sid=7560', - options: { - withCredentials: false - }, - data: { - device: { - ip: 'peer', - ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) Ap…ML, like Gecko) Chrome/73.0.3683.86 Safari/537.36', - js: 1, - language: 'en' - }, - id: '10c47a5fc3c41', - imp: [{ - banner: { w: 300, h: 250 }, - id: '2966b257c81d27', - secure: false, - tagid: '/19968336/header-bid-tag-0' - }, { - banner: { w: 728, h: 90 }, - id: '2966b257c81d28', - secure: false, - tagid: '/19968336/header-bid-tag-0' - }, { - id: '15d9012765e36c', - native: {request: '{"native":{"assets":[{"id":"1","required":true,"title":{"len":140}},{"id":"2","required":true,"data":{"type":2}},{"id":"3","img":{"w":728,"h":90,"type":3}}]}}'}, - secure: false, - tagid: '/19968336/header-bid-tag-0' - }, { - id: '15d9012765e36f', - video: {w: 500, h: 400, minduration: 15, maxduration: 60}, - secure: false, - tagid: '/19968336/header-bid-tag-0' - }], - site: { - domain: '', - id: 'blank', - page: 'https://v5demo.datablocks.net/test' - } - } -} - -describe('DatablocksAdapter', function() { - describe('isBidRequestValid', function() { - it('Should return true when sourceId and Host are set', function() { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false when host/sourceId is not set', function() { - let moddedBid = Object.assign({}, bid); - delete moddedBid.params.sourceId; - delete moddedBid.params.host; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function() { - let requests = spec.buildRequests([bid, bid2, nativeBid, videoBid], bidderRequest); - it('Creates an array of request objects', function() { - expect(requests).to.be.an('array').that.is.not.empty; - }); - - requests.forEach(request => { - expect(request).to.exist; - it('Returns POST method', function() { - expect(request.method).to.exist; - expect(request.method).to.equal('POST'); - }); - it('Returns valid URL', function() { - expect(request.url).to.exist; - expect(request.url).to.equal('https://v5demo.datablocks.net/search/?sid=7560'); - }); - - it('Should be a valid openRTB request', function() { - let data = request.data; - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('device', 'imp', 'site', 'id'); - expect(data.id).to.be.a('string'); - - let imps = data['imp']; - imps.forEach((imp, index) => { - let curBid = bidderRequest.bids[index]; - if (imp.banner) { - expect(imp).to.have.all.keys('banner', 'id', 'secure', 'tagid'); - expect(imp.banner).to.be.a('object'); - } else if (imp.native) { - expect(imp).to.have.all.keys('native', 'id', 'secure', 'tagid'); - expect(imp.native).to.have.all.keys('request'); - expect(imp.native.request).to.be.a('string'); - let native = JSON.parse(imp.native.request); - expect(native).to.be.a('object'); - } else if (imp.video) { - expect(imp).to.have.all.keys('video', 'id', 'secure', 'tagid'); - expect(imp.video).to.have.all.keys('w', 'h', 'minduration', 'maxduration') - } else { - expect(true).to.equal(false); - } - - expect(imp.id).to.be.a('string'); - expect(imp.id).to.equal(curBid.bidId); - expect(imp.tagid).to.be.a('string'); - expect(imp.tagid).to.equal(curBid.adUnitCode); - expect(imp.secure).to.equal(false); - }) - - expect(data.device.ip).to.equal('peer'); - }); - }) - - it('Returns empty data if no valid requests are passed', function() { - let request = spec.buildRequests([]); - expect(request).to.be.an('array').that.is.empty; - }); - }); - describe('interpretResponse', function() { - let serverResponses = spec.interpretResponse(resObject, bidRequest); - 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++) { - let dataItem = serverResponses[i]; - expect(Object.keys(dataItem)).to.include('cpm', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'mediaType', 'requestId'); - expect(dataItem.requestId).to.be.a('string'); - expect(dataItem.cpm).to.be.a('number'); - 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.mediaType).to.be.a('string'); - - if (dataItem.mediaType == 'banner') { - expect(dataItem.ad).to.be.a('string'); - expect(dataItem.width).to.be.a('number'); - expect(dataItem.height).to.be.a('number'); - } else if (dataItem.mediaType == 'native') { - expect(dataItem.native.title).to.be.a('string'); - expect(dataItem.native.body).to.be.a('string'); - expect(dataItem.native.clickUrl).to.be.a('string'); - } else if (dataItem.mediaType == 'video') { - expect(dataItem.vastUrl).to.be.a('string'); - expect(dataItem.width).to.be.a('number'); - expect(dataItem.height).to.be.a('number'); - } - } - 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; - }); - }); - }); -}); diff --git a/test/spec/modules/decenteradsBidAdapter_spec.js b/test/spec/modules/decenteradsBidAdapter_spec.js deleted file mode 100644 index 257094cae3a..00000000000 --- a/test/spec/modules/decenteradsBidAdapter_spec.js +++ /dev/null @@ -1,207 +0,0 @@ -import { expect } from 'chai' -import { spec } from '../../../modules/decenteradsBidAdapter.js' -import { deepStrictEqual, notEqual, ok, strictEqual } from 'assert' - -describe('DecenteradsAdapter', () => { - const bid = { - bidId: '9ec5b177515ee2e5', - bidder: 'decenterads', - params: { - placementId: 0, - traffic: 'banner' - } - } - - describe('isBidRequestValid', () => { - it('Should return true if there are bidId, params and placementId parameters present', () => { - strictEqual(true, spec.isBidRequestValid(bid)) - }) - - it('Should return false if at least one of parameters is not present', () => { - const b = { ...bid } - delete b.params.placementId - strictEqual(false, spec.isBidRequestValid(b)) - }) - }) - - describe('buildRequests', () => { - const serverRequest = spec.buildRequests([bid]) - - it('Creates a ServerRequest object with method, URL and data', () => { - ok(serverRequest) - ok(serverRequest.method) - ok(serverRequest.url) - ok(serverRequest.data) - }) - - it('Returns POST method', () => { - strictEqual('POST', serverRequest.method) - }) - - it('Returns valid URL', () => { - strictEqual('https://supply.decenterads.com/?c=o&m=multi', serverRequest.url) - }) - - it('Returns valid data if array of bids is valid', () => { - const { data } = serverRequest - strictEqual('object', typeof data) - deepStrictEqual(['deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'], Object.keys(data)) - strictEqual('number', typeof data.deviceWidth) - strictEqual('number', typeof data.deviceHeight) - strictEqual('string', typeof data.language) - strictEqual('string', typeof data.host) - strictEqual('string', typeof data.page) - notEqual(-1, [0, 1].indexOf(data.secure)) - - const placement = data.placements[0] - deepStrictEqual(['placementId', 'bidId', 'traffic'], Object.keys(placement)) - strictEqual(0, placement.placementId) - strictEqual('9ec5b177515ee2e5', placement.bidId) - strictEqual('banner', placement.traffic) - }) - - it('Returns empty data if no valid requests are passed', () => { - const { placements } = spec.buildRequests([]).data - - expect(spec.buildRequests([]).data.placements).to.be.an('array') - strictEqual(0, placements.length) - }) - }) - - describe('interpretResponse', () => { - const validData = [ - { - body: [{ - mediaType: 'banner', - width: 300, - height: 250, - cpm: 0.4, - ad: 'Test', - requestId: '9ec5b177515ee2e5', - ttl: 120, - creativeId: '2', - netRevenue: true, - currency: 'USD', - dealId: '1' - }] - }, - { - body: [{ - vastUrl: 'decenterads.com', - mediaType: 'video', - cpm: 0.5, - requestId: '9ec5b177515ee2e5', - ttl: 120, - creativeId: '2', - netRevenue: true, - currency: 'USD', - dealId: '1' - }] - }, - { - body: [{ - mediaType: 'native', - clickUrl: 'decenterads.com', - title: 'Test', - image: 'decenterads.com', - creativeId: '2', - impressionTrackers: ['decenterads.com'], - ttl: 120, - cpm: 0.4, - requestId: '9ec5b177515ee2e5', - netRevenue: true, - currency: 'USD', - }] - } - ] - - for (const obj of validData) { - const { mediaType } = obj.body[0] - - it(`Should interpret ${mediaType} response`, () => { - const response = spec.interpretResponse(obj) - - expect(response).to.be.an('array') - strictEqual(1, response.length) - - const copy = { ...obj.body[0] } - delete copy.mediaType - deepStrictEqual(copy, response[0]) - }) - } - - const invalidData = [ - { - body: [{ - width: 300, - cpm: 0.4, - ad: 'Test', - requestId: '9ec5b177515ee2e5', - ttl: 120, - creativeId: '2', - netRevenue: true, - currency: 'USD', - dealId: '1' - }] - }, - { - body: [{ - mediaType: 'video', - cpm: 0.5, - requestId: '9ec5b177515ee2e5', - ttl: 120, - creativeId: '2', - netRevenue: true, - currency: 'USD', - dealId: '1' - }] - }, - { - body: [{ - mediaType: 'native', - clickUrl: 'decenterads.com', - title: 'Test', - impressionTrackers: ['decenterads.com'], - ttl: 120, - requestId: '9ec5b177515ee2e5', - creativeId: '2', - netRevenue: true, - currency: 'USD', - }] - } - ] - - for (const obj of invalidData) { - const { mediaType } = obj.body[0] - - it(`Should return an empty array if invalid ${mediaType} response is passed `, () => { - const response = spec.interpretResponse(obj) - - expect(response).to.be.an('array') - strictEqual(0, response.length) - }) - } - - it('Should return an empty array if invalid response is passed', () => { - const response = spec.interpretResponse({ - body: [{ - ttl: 120, - creativeId: '2', - netRevenue: true, - currency: 'USD', - dealId: '1' - }] - }) - - expect(response).to.be.an('array') - strictEqual(0, response.length) - }) - }) - - describe('getUserSyncs', () => { - it('Returns valid URL and type', () => { - const expectedResult = [{ type: 'image', url: 'https://supply.decenterads.com/?c=o&m=cookie' }] - deepStrictEqual(expectedResult, spec.getUserSyncs()) - }) - }) -}) diff --git a/test/spec/modules/deepintentBidAdapter_spec.js b/test/spec/modules/deepintentBidAdapter_spec.js deleted file mode 100644 index fcf7056fb3f..00000000000 --- a/test/spec/modules/deepintentBidAdapter_spec.js +++ /dev/null @@ -1,211 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/deepintentBidAdapter.js'; -import * as utils from '../../../src/utils.js'; - -describe('Deepintent adapter', function () { - let request; - let bannerResponse; - - beforeEach(function () { - request = [ - { - bidder: 'deepintent', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - params: { - tagId: '100013', - w: 728, - h: 90, - pos: 1, - user: { - id: 'di_testuid', - buyeruid: 'di_testbuyeruid', - yob: 2002, - gender: 'F' - }, - custom: { - 'position': 'right-box' - } - } - } - ]; - bannerResponse = { - 'body': { - 'id': '303e1fae-9677-41e2-9a92-15a23445363f', - 'seatbid': [{ - 'bid': [{ - 'id': '11447bb1-a266-470d-b0d7-8810f5b1b75f', - 'impid': 'a7e92b9b-d9db-4de8-9c3f-f90737335445', - 'price': 0.6, - 'adid': '10001', - 'adm': "\r\n", - 'adomain': ['deepintent.com'], - 'cid': '103389', - 'crid': '13665', - 'w': 300, - 'h': 250, - 'dealId': 'dee_12312stdszzsx' - }], - 'seat': '10000' - }], - 'bidid': '0b08b09f-aaa1-4c14-b1c8-7debb1a7c1cd' - } - } - }); - - describe('validations', function () { - it('validBid : tagId is passed', function () { - let bid = { - bidder: 'deepintent', - params: { - tagId: '1232' - } - }, - isValid = spec.isBidRequestValid(bid); - expect(isValid).to.equals(true); - }); - it('invalidBid : tagId is not passed', function () { - let bid = { - bidder: 'deepintent', - params: { - h: 200, - w: 300 - } - }, - isValid = spec.isBidRequestValid(bid); - expect(isValid).to.equals(false); - }); - it('invalidBid : tagId is not a string', function () { - let bid = { - bidder: 'deepintent', - params: { - tagId: 12345 - } - }, - isValid = spec.isBidRequestValid(bid); - expect(isValid).to.equals(false); - }); - }); - describe('request check', function () { - it('unmutaable bid request check', function () { - let oRequest = utils.deepClone(request), - bidRequest = spec.buildRequests(request); - expect(request).to.deep.equal(oRequest); - }); - it('bidder connection check', function () { - let bRequest = spec.buildRequests(request); - expect(bRequest.url).to.equal('https://prebid.deepintent.com/prebid'); - expect(bRequest.method).to.equal('POST'); - expect(bRequest.options.contentType).to.equal('application/json'); - }); - it('bid request check : Device', function () { - let bRequest = spec.buildRequests(request); - let data = JSON.parse(bRequest.data); - expect(data.device.ua).to.be.a('string'); - expect(data.device.js).to.equal(1); - expect(data.device.dnt).to.be.a('number'); - expect(data.device.h).to.be.a('number'); - expect(data.device.w).to.be.a('number'); - }); - it('bid request check : Impression', function () { - let bRequest = spec.buildRequests(request); - let data = JSON.parse(bRequest.data); - expect(data.at).to.equal(1); // auction type - expect(data.imp[0].id).to.equal(request[0].bidId); - expect(data.imp[0].tagid).to.equal('100013'); - }); - it('bid request check : ad size', function () { - let bRequest = spec.buildRequests(request); - let data = JSON.parse(bRequest.data); - expect(data.imp[0].banner).to.be.a('object'); - expect(data.imp[0].banner.w).to.equal(300); - expect(data.imp[0].banner.h).to.equal(250); - }); - it('bid request check : custom params', function () { - let bRequest = spec.buildRequests(request); - let data = JSON.parse(bRequest.data); - expect(data.imp[0].ext).to.be.a('object'); - expect(data.imp[0].ext.deepintent.position).to.equal('right-box'); - }); - it('bid request check: position check', function () { - let bRequest = spec.buildRequests(request); - let data = JSON.parse(bRequest.data); - expect(data.imp[0].banner.pos).to.equal(1); - }); - it('bid request check: displaymanager check', function() { - let bRequest = spec.buildRequests(request); - let data = JSON.parse(bRequest.data); - expect(data.imp[0].displaymanager).to.equal('di_prebid'); - expect(data.imp[0].displaymanagerver).to.equal('1.0.0'); - }); - it('bid request check: user object check', function () { - let bRequest = spec.buildRequests(request); - let data = JSON.parse(bRequest.data); - expect(data.user).to.be.a('object'); - expect(data.user.id).to.equal('di_testuid'); - expect(data.user.buyeruid).to.equal('di_testbuyeruid'); - expect(data.user.yob).to.equal(2002); - expect(data.user.gender).to.equal('F'); - }); - it('bid request check: CCPA Check', function () { - let bidRequest = { - uspConsent: '1NYN' - }; - let bRequest = spec.buildRequests(request, bidRequest); - let data = JSON.parse(bRequest.data); - expect(data.regs.ext.us_privacy).to.equal('1NYN'); - let bidRequest2 = {}; - let bRequest2 = spec.buildRequests(request, bidRequest2); - let data2 = JSON.parse(bRequest2.data); - expect(data2.regs).to.equal(undefined); - }); - it('bid Request check: GDPR Check', function () { - let bidRequest = { - gdprConsent: { - consentString: 'kjfdnidasd123sadsd', - gdprApplies: true - } - }; - let bRequest = spec.buildRequests(request, bidRequest); - let data = JSON.parse(bRequest.data); - expect(data.user.ext.consent).to.equal('kjfdnidasd123sadsd'); - expect(data.regs.ext.gdpr).to.equal(1); - let bidRequest2 = {}; - let bRequest2 = spec.buildRequests(request, bidRequest2); - let data2 = JSON.parse(bRequest2.data); - expect(data2.regs).to.equal(undefined); - expect(data2.user.ext).to.equal(undefined); - }); - }); - describe('user sync check', function () { - it('user sync url check', function () { - let syncOptions = { - iframeEnabled: true - }; - let userSync = spec.getUserSyncs(syncOptions); - expect(userSync).to.be.an('array').with.length.above(0); - expect(userSync[0].type).to.equal('iframe'); - expect(userSync[0].url).to.equal('https://cdn.deepintent.com/syncpixel.html'); - }); - }); - describe('response check', function () { - it('bid response check: valid bid response', function () { - let bRequest = spec.buildRequests(request); - let data = JSON.parse(bRequest.data); - let bResponse = spec.interpretResponse(bannerResponse, request); - expect(bResponse).to.be.an('array').with.length.above(0); - expect(bResponse[0].requestId).to.equal(bannerResponse.body.seatbid[0].bid[0].impid); - expect(bResponse[0].width).to.equal(bannerResponse.body.seatbid[0].bid[0].w); - expect(bResponse[0].height).to.equal(bannerResponse.body.seatbid[0].bid[0].h); - expect(bResponse[0].currency).to.equal('USD'); - expect(bResponse[0].netRevenue).to.equal(false); - expect(bResponse[0].meta.advertiserDomains).to.deep.equal(['deepintent.com']); - expect(bResponse[0].ttl).to.equal(300); - expect(bResponse[0].creativeId).to.equal(bannerResponse.body.seatbid[0].bid[0].crid); - expect(bResponse[0].dealId).to.equal(bannerResponse.body.seatbid[0].bid[0].dealId); - }); - }) -}); diff --git a/test/spec/modules/deepintentDpesIdsystem_spec.js b/test/spec/modules/deepintentDpesIdsystem_spec.js deleted file mode 100644 index 7ea5553393c..00000000000 --- a/test/spec/modules/deepintentDpesIdsystem_spec.js +++ /dev/null @@ -1,76 +0,0 @@ -import { expect } from 'chai'; -import find from 'core-js-pure/features/array/find.js'; -import { storage, deepintentDpesSubmodule } from 'modules/deepintentDpesIdSystem.js'; -import { init, requestBidsHook, setSubmoduleRegistry } from 'modules/userId/index.js'; -import { config } from 'src/config.js'; - -const DI_COOKIE_NAME = '_dpes_id'; -const DI_COOKIE_STORED = '{"id":"2cf40748c4f7f60d343336e08f80dc99"}'; -const DI_COOKIE_OBJECT = {id: '2cf40748c4f7f60d343336e08f80dc99'}; - -const cookieConfig = { - name: 'deepintentId', - storage: { - type: 'cookie', - name: '_dpes_id', - expires: 28 - } -}; - -const html5Config = { - name: 'deepintentId', - storage: { - type: 'html5', - name: '_dpes_id', - expires: 28 - } -} - -describe('Deepintent DPES System', () => { - let getDataFromLocalStorageStub, localStorageIsEnabledStub; - let getCookieStub, cookiesAreEnabledStub; - - beforeEach(() => { - getDataFromLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage'); - localStorageIsEnabledStub = sinon.stub(storage, 'localStorageIsEnabled'); - getCookieStub = sinon.stub(storage, 'getCookie'); - cookiesAreEnabledStub = sinon.stub(storage, 'cookiesAreEnabled'); - }); - - afterEach(() => { - getDataFromLocalStorageStub.restore(); - localStorageIsEnabledStub.restore(); - getCookieStub.restore(); - cookiesAreEnabledStub.restore(); - }); - - describe('Deepintent Dpes Sytsem: test "getId" method', () => { - it('Wrong config should fail the tests', () => { - // no config - expect(deepintentDpesSubmodule.getId()).to.be.eq(undefined); - expect(deepintentDpesSubmodule.getId({ })).to.be.eq(undefined); - - expect(deepintentDpesSubmodule.getId({params: {}, storage: {}})).to.be.eq(undefined); - expect(deepintentDpesSubmodule.getId({params: {}, storage: {type: 'cookie'}})).to.be.eq(undefined); - expect(deepintentDpesSubmodule.getId({params: {}, storage: {name: '_dpes_id'}})).to.be.eq(undefined); - }); - - it('Get value stored in cookie for getId', () => { - getCookieStub.withArgs(DI_COOKIE_NAME).returns(DI_COOKIE_STORED); - let diId = deepintentDpesSubmodule.getId(cookieConfig, undefined, DI_COOKIE_OBJECT); - expect(diId).to.deep.equal(DI_COOKIE_OBJECT); - }); - - it('provides the stored deepintentId if cookie is absent but present in local storage', () => { - getDataFromLocalStorageStub.withArgs(DI_COOKIE_NAME).returns(DI_COOKIE_STORED); - let idx = deepintentDpesSubmodule.getId(html5Config, undefined, DI_COOKIE_OBJECT); - expect(idx).to.deep.equal(DI_COOKIE_OBJECT); - }); - }); - - describe('Deepintent Dpes System : test "decode" method', () => { - it('Get the correct decoded value for dpes id', () => { - expect(deepintentDpesSubmodule.decode(DI_COOKIE_OBJECT, cookieConfig)).to.deep.equal({'deepintentId': {'id': '2cf40748c4f7f60d343336e08f80dc99'}}); - }); - }); -}); diff --git a/test/spec/modules/dfpAdServerVideo_spec.js b/test/spec/modules/dfpAdServerVideo_spec.js deleted file mode 100644 index eaffca01e06..00000000000 --- a/test/spec/modules/dfpAdServerVideo_spec.js +++ /dev/null @@ -1,661 +0,0 @@ -import { expect } from 'chai'; - -import parse from 'url-parse'; -import { buildDfpVideoUrl, buildAdpodVideoUrl } from 'modules/dfpAdServerVideo.js'; -import adUnit from 'test/fixtures/video/adUnit.json'; -import * as utils from 'src/utils.js'; -import { config } from 'src/config.js'; -import { targeting } from 'src/targeting.js'; -import { auctionManager } from 'src/auctionManager.js'; -import { gdprDataHandler, uspDataHandler } from 'src/adapterManager.js'; -import * as adpod from 'modules/adpod.js'; -import { server } from 'test/mocks/xhr.js'; - -const bid = { - videoCacheKey: 'abc', - adserverTargeting: { - hb_uuid: 'abc', - hb_cache_id: 'abc', - }, -}; - -describe('The DFP video support module', function () { - it('should make a legal request URL when given the required params', function () { - const url = parse(buildDfpVideoUrl({ - adUnit: adUnit, - bid: bid, - params: { - 'iu': 'my/adUnit', - 'description_url': 'someUrl.com', - } - })); - - expect(url.protocol).to.equal('https:'); - expect(url.host).to.equal('securepubads.g.doubleclick.net'); - - const queryParams = utils.parseQS(url.query); - expect(queryParams).to.have.property('correlator'); - expect(queryParams).to.have.property('description_url', 'someUrl.com'); - expect(queryParams).to.have.property('env', 'vp'); - expect(queryParams).to.have.property('gdfp_req', '1'); - expect(queryParams).to.have.property('iu', 'my/adUnit'); - expect(queryParams).to.have.property('output', 'vast'); - expect(queryParams).to.have.property('sz', '640x480'); - expect(queryParams).to.have.property('unviewed_position_start', '1'); - expect(queryParams).to.have.property('url'); - }); - - it('can take an adserver url as a parameter', function () { - const bidCopy = utils.deepClone(bid); - bidCopy.vastUrl = 'vastUrl.example'; - - const url = parse(buildDfpVideoUrl({ - adUnit: adUnit, - bid: bidCopy, - url: 'https://video.adserver.example/', - })); - - expect(url.host).to.equal('video.adserver.example'); - - const queryObject = utils.parseQS(url.query); - expect(queryObject.description_url).to.equal('vastUrl.example'); - }); - - it('requires a params object or url', function () { - const url = buildDfpVideoUrl({ - adUnit: adUnit, - bid: bid, - }); - - expect(url).to.be.undefined; - }); - - it('overwrites url params when both url and params object are given', function () { - const url = parse(buildDfpVideoUrl({ - adUnit: adUnit, - bid: bid, - url: 'https://video.adserver.example/ads?sz=640x480&iu=/123/aduniturl&impl=s', - params: { iu: 'my/adUnit' } - })); - - const queryObject = utils.parseQS(url.query); - expect(queryObject.iu).to.equal('my/adUnit'); - }); - - it('should override param defaults with user-provided ones', function () { - const url = parse(buildDfpVideoUrl({ - adUnit: adUnit, - bid: bid, - params: { - 'iu': 'my/adUnit', - 'output': 'vast', - } - })); - - expect(utils.parseQS(url.query)).to.have.property('output', 'vast'); - }); - - it('should include the cache key and adserver targeting in cust_params', function () { - const bidCopy = utils.deepClone(bid); - bidCopy.adserverTargeting = Object.assign(bidCopy.adserverTargeting, { - hb_adid: 'ad_id', - }); - - const url = parse(buildDfpVideoUrl({ - adUnit: adUnit, - bid: bidCopy, - params: { - 'iu': 'my/adUnit' - } - })); - const queryObject = utils.parseQS(url.query); - const customParams = utils.parseQS('?' + decodeURIComponent(queryObject.cust_params)); - - expect(customParams).to.have.property('hb_adid', 'ad_id'); - expect(customParams).to.have.property('hb_uuid', bid.videoCacheKey); - expect(customParams).to.have.property('hb_cache_id', bid.videoCacheKey); - }); - - it('should include the us_privacy key when USP Consent is available', function () { - let uspDataHandlerStub = sinon.stub(uspDataHandler, 'getConsentData'); - uspDataHandlerStub.returns('1YYY'); - - const bidCopy = utils.deepClone(bid); - bidCopy.adserverTargeting = Object.assign(bidCopy.adserverTargeting, { - hb_adid: 'ad_id', - }); - - const url = parse(buildDfpVideoUrl({ - adUnit: adUnit, - bid: bidCopy, - params: { - 'iu': 'my/adUnit' - } - })); - const queryObject = utils.parseQS(url.query); - expect(queryObject.us_privacy).to.equal('1YYY'); - uspDataHandlerStub.restore(); - }); - - it('should not include the us_privacy key when USP Consent is not available', function () { - const bidCopy = utils.deepClone(bid); - bidCopy.adserverTargeting = Object.assign(bidCopy.adserverTargeting, { - hb_adid: 'ad_id', - }); - - const url = parse(buildDfpVideoUrl({ - adUnit: adUnit, - bid: bidCopy, - params: { - 'iu': 'my/adUnit' - } - })); - const queryObject = utils.parseQS(url.query); - expect(queryObject.us_privacy).to.equal(undefined); - }); - - it('should include the GDPR keys when GDPR Consent is available', function () { - let gdprDataHandlerStub = sinon.stub(gdprDataHandler, 'getConsentData'); - gdprDataHandlerStub.returns({ - gdprApplies: true, - consentString: 'consent', - addtlConsent: 'moreConsent' - }); - - const bidCopy = utils.deepClone(bid); - bidCopy.adserverTargeting = Object.assign(bidCopy.adserverTargeting, { - hb_adid: 'ad_id', - }); - - const url = parse(buildDfpVideoUrl({ - adUnit: adUnit, - bid: bidCopy, - params: { - 'iu': 'my/adUnit' - } - })); - const queryObject = utils.parseQS(url.query); - expect(queryObject.gdpr).to.equal('1'); - expect(queryObject.gdpr_consent).to.equal('consent'); - expect(queryObject.addtl_consent).to.equal('moreConsent'); - gdprDataHandlerStub.restore(); - }); - - it('should not include the GDPR keys when GDPR Consent is not available', function () { - const bidCopy = utils.deepClone(bid); - bidCopy.adserverTargeting = Object.assign(bidCopy.adserverTargeting, { - hb_adid: 'ad_id', - }); - - const url = parse(buildDfpVideoUrl({ - adUnit: adUnit, - bid: bidCopy, - params: { - 'iu': 'my/adUnit' - } - })); - const queryObject = utils.parseQS(url.query); - expect(queryObject.gdpr).to.equal(undefined); - expect(queryObject.gdpr_consent).to.equal(undefined); - expect(queryObject.addtl_consent).to.equal(undefined); - }); - - it('should only include the GDPR keys for GDPR Consent fields with values', function () { - let gdprDataHandlerStub = sinon.stub(gdprDataHandler, 'getConsentData'); - gdprDataHandlerStub.returns({ - gdprApplies: true, - consentString: 'consent', - }); - - const bidCopy = utils.deepClone(bid); - bidCopy.adserverTargeting = Object.assign(bidCopy.adserverTargeting, { - hb_adid: 'ad_id', - }); - - const url = parse(buildDfpVideoUrl({ - adUnit: adUnit, - bid: bidCopy, - params: { - 'iu': 'my/adUnit' - } - })); - const queryObject = utils.parseQS(url.query); - expect(queryObject.gdpr).to.equal('1'); - expect(queryObject.gdpr_consent).to.equal('consent'); - expect(queryObject.addtl_consent).to.equal(undefined); - gdprDataHandlerStub.restore(); - }); - - describe('special targeting unit test', function () { - const allTargetingData = { - 'hb_format': 'video', - 'hb_source': 'client', - 'hb_size': '640x480', - 'hb_pb': '5.00', - 'hb_adid': '2c4f6cc3ba128a', - 'hb_bidder': 'testBidder2', - 'hb_format_testBidder2': 'video', - 'hb_source_testBidder2': 'client', - 'hb_size_testBidder2': '640x480', - 'hb_pb_testBidder2': '5.00', - 'hb_adid_testBidder2': '2c4f6cc3ba128a', - 'hb_bidder_testBidder2': 'testBidder2', - 'hb_format_appnexus': 'video', - 'hb_source_appnexus': 'client', - 'hb_size_appnexus': '640x480', - 'hb_pb_appnexus': '5.00', - 'hb_adid_appnexus': '44e0b5f2e5cace', - 'hb_bidder_appnexus': 'appnexus' - }; - let targetingStub; - - before(function () { - targetingStub = sinon.stub(targeting, 'getAllTargeting'); - targetingStub.returns({'video1': allTargetingData}); - - config.setConfig({ - enableSendAllBids: true - }); - }); - - after(function () { - config.resetConfig(); - targetingStub.restore(); - }); - - it('should include all adserver targeting in cust_params if pbjs.enableSendAllBids is true', function () { - const adUnitsCopy = utils.deepClone(adUnit); - adUnitsCopy.bids.push({ - 'bidder': 'testBidder2', - 'params': { - 'placementId': '9333431', - 'video': { - 'skipppable': false, - 'playback_methods': ['auto_play_sound_off'] - } - } - }); - - const bidCopy = utils.deepClone(bid); - bidCopy.adserverTargeting = Object.assign(bidCopy.adserverTargeting, { - hb_adid: 'ad_id', - }); - - const url = parse(buildDfpVideoUrl({ - adUnit: adUnitsCopy, - bid: bidCopy, - params: { - 'iu': 'my/adUnit' - } - })); - const queryObject = utils.parseQS(url.query); - const customParams = utils.parseQS('?' + decodeURIComponent(queryObject.cust_params)); - - expect(customParams).to.have.property('hb_adid', 'ad_id'); - expect(customParams).to.have.property('hb_uuid', bid.videoCacheKey); - expect(customParams).to.have.property('hb_cache_id', bid.videoCacheKey); - expect(customParams).to.have.property('hb_bidder_appnexus', 'appnexus'); - expect(customParams).to.have.property('hb_bidder_testBidder2', 'testBidder2'); - }); - }); - - it('should merge the user-provided cust_params with the default ones', function () { - const bidCopy = utils.deepClone(bid); - bidCopy.adserverTargeting = Object.assign(bidCopy.adserverTargeting, { - hb_adid: 'ad_id', - }); - - const url = parse(buildDfpVideoUrl({ - adUnit: adUnit, - bid: bidCopy, - params: { - 'iu': 'my/adUnit', - cust_params: { - 'my_targeting': 'foo', - }, - }, - })); - const queryObject = utils.parseQS(url.query); - const customParams = utils.parseQS('?' + decodeURIComponent(queryObject.cust_params)); - - expect(customParams).to.have.property('hb_adid', 'ad_id'); - expect(customParams).to.have.property('my_targeting', 'foo'); - }); - - it('should merge the user-provided cust-params with the default ones when using url object', function () { - const bidCopy = utils.deepClone(bid); - bidCopy.adserverTargeting = Object.assign(bidCopy.adserverTargeting, { - hb_adid: 'ad_id', - }); - - const url = parse(buildDfpVideoUrl({ - adUnit: adUnit, - bid: bidCopy, - url: 'https://video.adserver.example/ads?sz=640x480&iu=/123/aduniturl&impl=s&cust_params=section%3dblog%26mykey%3dmyvalue' - })); - - const queryObject = utils.parseQS(url.query); - const customParams = utils.parseQS('?' + decodeURIComponent(queryObject.cust_params)); - - expect(customParams).to.have.property('hb_adid', 'ad_id'); - expect(customParams).to.have.property('section', 'blog'); - expect(customParams).to.have.property('mykey', 'myvalue'); - expect(customParams).to.have.property('hb_uuid', 'abc'); - expect(customParams).to.have.property('hb_cache_id', 'abc'); - }); - - it('should not overwrite an existing description_url for object input and cache disabled', function () { - const bidCopy = utils.deepClone(bid); - bidCopy.vastUrl = 'vastUrl.example'; - - const url = parse(buildDfpVideoUrl({ - adUnit: adUnit, - bid: bidCopy, - params: { - iu: 'my/adUnit', - description_url: 'descriptionurl.example' - } - })); - - const queryObject = utils.parseQS(url.query); - expect(queryObject.description_url).to.equal('descriptionurl.example'); - }); - - it('should work with nobid responses', function () { - const url = buildDfpVideoUrl({ - adUnit: adUnit, - params: { 'iu': 'my/adUnit' } - }); - - expect(url).to.be.a('string'); - }); - - it('should include hb_uuid and hb_cache_id in cust_params when both keys are exluded from overwritten bidderSettings', function () { - const bidCopy = utils.deepClone(bid); - delete bidCopy.adserverTargeting.hb_uuid; - delete bidCopy.adserverTargeting.hb_cache_id; - - const url = parse(buildDfpVideoUrl({ - adUnit: adUnit, - bid: bidCopy, - params: { - 'iu': 'my/adUnit' - } - })); - const queryObject = utils.parseQS(url.query); - const customParams = utils.parseQS('?' + decodeURIComponent(queryObject.cust_params)); - - expect(customParams).to.have.property('hb_uuid', bid.videoCacheKey); - expect(customParams).to.have.property('hb_cache_id', bid.videoCacheKey); - }); - - it('should include hb_uuid and hb_cache_id in cust params from overwritten standard bidderSettings', function () { - const bidCopy = utils.deepClone(bid); - bidCopy.adserverTargeting = Object.assign(bidCopy.adserverTargeting, { - hb_uuid: 'def', - hb_cache_id: 'def' - }); - - const url = parse(buildDfpVideoUrl({ - adUnit: adUnit, - bid: bidCopy, - params: { - 'iu': 'my/adUnit' - } - })); - const queryObject = utils.parseQS(url.query); - const customParams = utils.parseQS('?' + decodeURIComponent(queryObject.cust_params)); - - expect(customParams).to.have.property('hb_uuid', 'def'); - expect(customParams).to.have.property('hb_cache_id', 'def'); - }); - - describe('adpod unit tests', function () { - let amStub; - let amGetAdUnitsStub; - - before(function () { - let adUnits = [{ - code: 'adUnitCode-1', - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 60, - durationRangeSec: [15, 30], - requireExactDuration: true - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 14542875, - } - } - ] - }]; - - amGetAdUnitsStub = sinon.stub(auctionManager, 'getAdUnits'); - amGetAdUnitsStub.returns(adUnits); - amStub = sinon.stub(auctionManager, 'getBidsReceived'); - }); - - beforeEach(function () { - config.setConfig({ - adpod: { - brandCategoryExclusion: true, - deferCaching: false - } - }); - }) - - afterEach(function() { - config.resetConfig(); - }); - - after(function () { - amGetAdUnitsStub.restore(); - amStub.restore(); - }); - - it('should return masterTag url', function() { - amStub.returns(getBidsReceived()); - let uspDataHandlerStub = sinon.stub(uspDataHandler, 'getConsentData'); - uspDataHandlerStub.returns('1YYY'); - let gdprDataHandlerStub = sinon.stub(gdprDataHandler, 'getConsentData'); - gdprDataHandlerStub.returns({ - gdprApplies: true, - consentString: 'consent', - addtlConsent: 'moreConsent' - }); - let url; - parse(buildAdpodVideoUrl({ - code: 'adUnitCode-1', - callback: handleResponse, - params: { - 'iu': 'my/adUnit', - 'description_url': 'someUrl.com', - } - })); - - function handleResponse(err, masterTag) { - if (err) { - return; - } - url = parse(masterTag); - - expect(url.protocol).to.equal('https:'); - expect(url.host).to.equal('securepubads.g.doubleclick.net'); - - const queryParams = utils.parseQS(url.query); - expect(queryParams).to.have.property('correlator'); - expect(queryParams).to.have.property('description_url', 'someUrl.com'); - expect(queryParams).to.have.property('env', 'vp'); - expect(queryParams).to.have.property('gdfp_req', '1'); - expect(queryParams).to.have.property('iu', 'my/adUnit'); - expect(queryParams).to.have.property('output', 'vast'); - expect(queryParams).to.have.property('sz', '640x480'); - expect(queryParams).to.have.property('unviewed_position_start', '1'); - expect(queryParams).to.have.property('url'); - expect(queryParams).to.have.property('cust_params'); - expect(queryParams).to.have.property('us_privacy', '1YYY'); - expect(queryParams).to.have.property('gdpr', '1'); - expect(queryParams).to.have.property('gdpr_consent', 'consent'); - expect(queryParams).to.have.property('addtl_consent', 'moreConsent'); - - const custParams = utils.parseQS(decodeURIComponent(queryParams.cust_params)); - expect(custParams).to.have.property('hb_cache_id', '123'); - expect(custParams).to.have.property('hb_pb_cat_dur', '15.00_395_15s,15.00_406_30s,10.00_395_15s'); - uspDataHandlerStub.restore(); - gdprDataHandlerStub.restore(); - } - }); - - it('should return masterTag url with correct custom params when brandCategoryExclusion is false', function() { - config.setConfig({ - adpod: { - brandCategoryExclusion: false, - } - }); - function getBids() { - let bids = [ - createBid(10, 'adUnitCode-1', 15, '10.00_15s', '123', '395', '10.00'), - createBid(15, 'adUnitCode-1', 15, '15.00_15s', '123', '395', '15.00'), - createBid(25, 'adUnitCode-1', 30, '15.00_30s', '123', '406', '25.00'), - ]; - bids.forEach((bid) => { - delete bid.meta; - }); - return bids; - } - amStub.returns(getBids()); - let url; - parse(buildAdpodVideoUrl({ - code: 'adUnitCode-1', - callback: handleResponse, - params: { - 'iu': 'my/adUnit', - 'description_url': 'someUrl.com', - } - })); - - function handleResponse(err, masterTag) { - if (err) { - return; - } - url = parse(masterTag); - expect(url.protocol).to.equal('https:'); - expect(url.host).to.equal('securepubads.g.doubleclick.net'); - - const queryParams = utils.parseQS(url.query); - expect(queryParams).to.have.property('correlator'); - expect(queryParams).to.have.property('description_url', 'someUrl.com'); - expect(queryParams).to.have.property('env', 'vp'); - expect(queryParams).to.have.property('gdfp_req', '1'); - expect(queryParams).to.have.property('iu', 'my/adUnit'); - expect(queryParams).to.have.property('output', 'xml_vast3'); - expect(queryParams).to.have.property('sz', '640x480'); - expect(queryParams).to.have.property('unviewed_position_start', '1'); - expect(queryParams).to.have.property('url'); - expect(queryParams).to.have.property('cust_params'); - - const custParams = utils.parseQS(decodeURIComponent(queryParams.cust_params)); - expect(custParams).to.have.property('hb_cache_id', '123'); - expect(custParams).to.have.property('hb_pb_cat_dur', '10.00_15s,15.00_15s,15.00_30s'); - } - }); - - it('should handle error when cache fails', function() { - config.setConfig({ - adpod: { - brandCategoryExclusion: true, - deferCaching: true - } - }); - amStub.returns(getBidsReceived()); - - parse(buildAdpodVideoUrl({ - code: 'adUnitCode-1', - callback: handleResponse, - params: { - 'iu': 'my/adUnit', - 'description_url': 'someUrl.com', - } - })); - - server.requests[0].respond(503, { - 'Content-Type': 'plain/text', - }, 'The server could not save anything at the moment.'); - - function handleResponse(err, masterTag) { - expect(masterTag).to.be.null; - expect(err).to.be.an('error'); - } - }); - }) -}); - -function getBidsReceived() { - return [ - createBid(10, 'adUnitCode-1', 15, '10.00_395_15s', '123', '395', '10.00'), - createBid(15, 'adUnitCode-1', 15, '15.00_395_15s', '123', '395', '15.00'), - createBid(25, 'adUnitCode-1', 30, '15.00_406_30s', '123', '406', '25.00'), - ] -} - -function createBid(cpm, adUnitCode, durationBucket, priceIndustryDuration, uuid, label, hbpb) { - return { - 'bidderCode': 'appnexus', - 'width': 640, - 'height': 360, - 'statusMessage': 'Bid available', - 'adId': '28f24ced14586c', - 'mediaType': 'video', - 'source': 'client', - 'requestId': '28f24ced14586c', - 'cpm': cpm, - 'creativeId': 97517771, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 3600, - 'adUnitCode': adUnitCode, - 'video': { - 'context': 'adpod', - 'durationBucket': durationBucket - }, - 'appnexus': { - 'buyerMemberId': 9325 - }, - 'vastUrl': 'http://some-vast-url.com', - 'vastImpUrl': 'http://some-vast-imp-url.com', - 'auctionId': 'ec266b31-d652-49c5-8295-e83fafe5532b', - 'responseTimestamp': 1548442460888, - 'requestTimestamp': 1548442460827, - 'bidder': 'appnexus', - 'timeToRespond': 61, - 'pbLg': '5.00', - 'pbMg': '5.00', - 'pbHg': '5.00', - 'pbAg': '5.00', - 'pbDg': '5.00', - 'pbCg': '', - 'size': '640x360', - 'adserverTargeting': { - 'hb_bidder': 'appnexus', - 'hb_adid': '28f24ced14586c', - 'hb_pb': hbpb, - 'hb_size': '640x360', - 'hb_source': 'client', - 'hb_format': 'video', - 'hb_pb_cat_dur': priceIndustryDuration, - 'hb_cache_id': uuid - }, - 'customCacheKey': `${priceIndustryDuration}_${uuid}`, - 'meta': { - 'primaryCatId': 'iab-1', - 'adServerCatId': label - }, - 'videoCacheKey': '4cf395af-8fee-4960-af0e-88d44e399f14' - } -} diff --git a/test/spec/modules/districtmDmxBidAdapter_spec.js b/test/spec/modules/districtmDmxBidAdapter_spec.js deleted file mode 100644 index 90c18c6a84f..00000000000 --- a/test/spec/modules/districtmDmxBidAdapter_spec.js +++ /dev/null @@ -1,816 +0,0 @@ -import { expect } from 'chai'; -import * as _ from 'lodash'; -import { spec, matchRequest, checkDeepArray, defaultSize, upto5, cleanSizes, shuffle, getApi, bindUserId, getPlaybackmethod, getProtocols, cleanVast } from '../../../modules/districtmDMXBidAdapter.js'; - -const sample_vast = ` - - - - - - - - - 00:00:15 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -` - -const supportedSize = [ - { - size: [300, 250], - s: 100 - }, - { - size: [728, 90], - s: 95 - }, - { - size: [300, 600], - s: 90 - }, - { - size: [160, 600], - s: 88 - }, - { - size: [320, 50], - s: 85 - }, - { - size: [300, 50], - s: 80 - }, - { - size: [970, 250], - s: 75 - }, - { - size: [970, 90], - s: 60 - }, -]; -const bidRequest = [{ - 'bidder': 'districtmDMX', - 'params': { - 'dmxid': 100001, - 'memberid': 100003, - }, - 'userId': { - idl_env: {}, - digitrustid: { - data: { - id: {} - } - }, - id5id: { - uid: '' - }, - pubcid: {}, - tdid: {}, - criteoId: {}, - britepoolid: {}, - intentiqid: {}, - lotamePanoramaId: {}, - parrableId: {}, - netId: {}, - sharedid: {}, - lipb: { - lipbid: {} - }, - - }, - 'adUnitCode': 'div-gpt-ad-12345678-1', - 'transactionId': 'f6d13fa6-ebc1-41ac-9afa-d8171d22d2c2', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '29a28a1bbc8a8d', - 'bidderRequestId': '124b579a136515', - 'auctionId': '3d62f2d3-56a2-4991-888e-f7754619ddcf' -}]; - -const bidRequestVideo = [{ - 'bidder': 'districtmDMX', - 'params': { - 'dmxid': 100001, - 'memberid': 100003, - 'video': { - id: 123, - skipppable: true, - playback_method: ['auto_play_sound_off', 'viewport_sound_off'], - mimes: ['application/javascript', - 'video/mp4'], - } - }, - 'mediaTypes': { - video: { - context: 'instream', // or 'outstream' - playerSize: [[640, 480]] - } - }, - 'adUnitCode': 'div-gpt-ad-12345678-1', - 'transactionId': 'f6d13fa6-ebc1-41ac-9afa-d8171d22d2c2', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '29a28a1bbc8a8d', - 'bidderRequestId': '124b579a136515', - 'auctionId': '3d62f2d3-56a2-4991-888e-f7754619ddcf' -}]; -const bidRequestNoCoppa = [{ - 'bidder': 'districtmDMX', - 'params': { - 'dmxid': 100001, - 'memberid': 100003 - }, - 'adUnitCode': 'div-gpt-ad-12345678-1', - 'transactionId': 'f6d13fa6-ebc1-41ac-9afa-d8171d22d2c2', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '29a28a1bbc8a8d', - 'bidderRequestId': '124b579a136515', - 'auctionId': '3d62f2d3-56a2-4991-888e-f7754619ddcf' -}]; -const bidderRequest = { - 'bidderCode': 'districtmDMX', - 'auctionId': '3d62f2d3-56a2-4991-888e-f7754619ddcf', - 'bidderRequestId': '124b579a136515', - 'bids': [{ - 'bidder': 'districtmDMX', - 'params': { - 'dmxid': 100001, - 'memberid': 100003, - }, - 'adUnitCode': 'div-gpt-ad-12345678-1', - 'transactionId': 'f6d13fa6-ebc1-41ac-9afa-d8171d22d2c2', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '29a28a1bbc8a8d', - 'bidderRequestId': '124b579a136515', - 'auctionId': '3d62f2d3-56a2-4991-888e-f7754619ddcf' - }], - 'auctionStart': 1529511035677, - 'timeout': 700, - 'uspConsent': '1NY', - 'gdprConsent': { - 'consentString': 'BOPqNzUOPqNzUAHABBAAA5AAAAAAAA', - 'vendorData': { - 'metadata': 'BOPqNzUOPqNzUAHABBAAA5AAAAAAAA', - 'hasGlobalScope': false, - 'gdprApplies': true, - 'purposeConsents': { - '1': false, - '2': false, - '3': false, - '4': false, - '5': false - }, - 'vendorConsents': { - '1': false, - '2': false, - '3': false, - '4': false, - '6': false, - '7': false, - '8': false, - '9': false, - '10': false, - '11': false, - '12': false, - '13': false, - '14': false, - '15': false, - '16': false, - '17': false, - '18': false, - '19': false, - '20': false, - '21': false, - '22': false, - '23': false, - '24': false, - '25': false, - '26': false, - '27': false, - '28': false, - '29': false, - '30': false, - '31': false, - '32': false, - '33': false, - '34': false, - '35': false, - '36': false, - '37': false, - '38': false, - '39': false, - '40': false, - '41': false, - '42': false, - '43': false, - '44': false, - '45': false, - '46': false, - '47': false, - '48': false, - '49': false, - '50': false, - '51': false, - '52': false, - '53': false, - '55': false, - '56': false, - '57': false, - '58': false, - '59': false, - '60': false, - '61': false, - '62': false, - '63': false, - '64': false, - '65': false, - '66': false, - '67': false, - '68': false, - '69': false, - '70': false, - '71': false, - '72': false, - '73': false, - '74': false, - '75': false, - '76': false, - '77': false, - '78': false, - '79': false, - '80': false, - '81': false, - '82': false, - '83': false, - '84': false, - '85': false, - '86': false, - '87': false, - '88': false, - '89': false, - '90': false, - '91': false, - '92': false, - '93': false, - '94': false, - '95': false, - '97': false, - '98': false, - '100': false, - '101': false, - '102': false, - '104': false, - '105': false, - '108': false, - '109': false, - '110': false, - '111': false, - '112': false, - '113': false, - '114': false, - '115': false, - '119': false, - '120': false, - '122': false, - '124': false, - '125': false, - '126': false, - '127': false, - '128': false, - '129': false, - '130': false, - '131': false, - '132': false, - '133': false, - '134': false, - '136': false, - '138': false, - '139': false, - '140': false, - '141': false, - '142': false, - '143': false, - '144': false, - '145': false, - '147': false, - '148': false, - '149': false, - '150': false, - '151': false, - '152': false, - '153': false, - '154': false, - '155': false, - '156': false, - '157': false, - '158': false, - '159': false, - '160': false, - '161': false, - '162': false, - '163': false, - '164': false, - '165': false, - '167': false, - '168': false, - '169': false, - '170': false, - '171': false, - '173': false, - '174': false, - '175': false, - '177': false, - '178': false, - '179': false, - '180': false, - '182': false, - '183': false, - '184': false, - '185': false, - '188': false, - '189': false, - '190': false, - '191': false, - '192': false, - '193': false, - '194': false, - '195': false, - '197': false, - '198': false, - '199': false, - '200': false, - '201': false, - '202': false, - '203': false, - '205': false, - '206': false, - '208': false, - '209': false, - '210': false, - '211': false, - '212': false, - '213': false, - '214': false, - '215': false, - '216': false, - '217': false, - '218': false, - '223': false, - '224': false, - '225': false, - '226': false, - '227': false, - '228': false, - '229': false, - '230': false, - '231': false, - '232': false, - '234': false, - '235': false, - '236': false, - '237': false, - '238': false, - '239': false, - '240': false, - '241': false, - '242': false, - '244': false, - '245': false, - '246': false, - '248': false, - '249': false, - '250': false, - '251': false, - '252': false, - '253': false, - '254': false, - '255': false, - '256': false, - '257': false, - '258': false, - '259': false, - '260': false, - '261': false, - '262': false, - '263': false, - '264': false, - '265': false, - '266': false, - '269': false, - '270': false, - '272': false, - '273': false, - '274': false, - '275': false, - '276': false, - '277': false, - '278': false, - '279': false, - '280': false, - '281': false, - '282': false, - '284': false, - '285': false, - '288': false, - '289': false, - '290': false, - '291': false, - '294': false, - '295': false, - '297': false, - '299': false, - '301': false, - '302': false, - '303': false, - '304': false, - '308': false, - '309': false, - '310': false, - '311': false, - '312': false, - '314': false, - '315': false, - '316': false, - '317': false, - '318': false, - '319': false, - '320': false, - '323': false, - '325': false, - '326': false, - '328': false, - '329': false, - '330': false, - '331': false, - '333': false, - '337': false, - '339': false, - '341': false, - '343': false, - '344': false, - '345': false, - '347': false, - '349': false, - '350': false, - '351': false, - '354': false, - '358': false, - '359': false, - '360': false, - '361': false, - '368': false, - '369': false, - '371': false, - '373': false, - '376': false, - '377': false, - '378': false, - '380': false, - '382': false, - '384': false, - '385': false, - '387': false, - '388': false, - '389': false, - '390': false, - '391': false, - '398': false, - '400': false, - '402': false, - '403': false, - '404': false, - '413': false, - '415': false, - '421': false, - '422': false - } - }, - 'gdprApplies': true - }, - 'start': 1529511035686, - 'doneCbCallCount': 0 -}; - -const bidderRequestNoCoppa = { - 'bidderCode': 'districtmDMX', - 'auctionId': '3d62f2d3-56a2-4991-888e-f7754619ddcf', - 'bidderRequestId': '124b579a136515', - 'bids': [{ - 'bidder': 'districtmDMX', - 'params': { - 'dmxid': 100001, - 'memberid': 100003, - }, - 'adUnitCode': 'div-gpt-ad-12345678-1', - 'transactionId': 'f6d13fa6-ebc1-41ac-9afa-d8171d22d2c2', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '29a28a1bbc8a8d', - 'bidderRequestId': '124b579a136515', - 'auctionId': '3d62f2d3-56a2-4991-888e-f7754619ddcf' - }], - 'auctionStart': 1529511035677, - 'timeout': 700, - 'start': 1529511035686, - 'doneCbCallCount': 0 -}; - -const responses = { - 'body': { - 'id': '1f45b37c-5298-4934-b517-4d911aadabfd', - 'cur': 'USD', - 'seatbid': [{ - 'bid': [{ - 'id': '29a28a1bbc8a8d', - 'impid': '29a28a1bbc8a8d', - 'price': '6.42', - 'adm': '
' - }] - }] - }, - 'headers': {} -}; - -const responsesNegative = { - 'body': { - 'id': '1f45b37c-5298-4934-b517-4d911aadabfd', - 'cur': 'USD', - 'seatbid': [{ - 'bid': [{ - 'id': '29a28a1bbc8a8d', - 'impid': '29a28a1bbc8a8d', - 'price': '-0.10', - 'adm': '
' - }] - }] - }, - 'headers': {} -}; - -const emptyResponse = { body: {} }; -const emptyResponseSeatBid = { body: { seatbid: [] } }; - -describe('DistrictM Adaptor', function () { - const districtm = spec; - describe('verification of upto5', function () { - it('upto5 function should always break 12 imps into 3 request same for 15', function () { - expect(upto5([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], bidRequest, bidderRequest, 'https://google').length).to.be.equal(3) - expect(upto5([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], bidRequest, bidderRequest, 'https://google').length).to.be.equal(3) - }) - }) - - describe('test vast tag', function () { - it('img tag should not be present', function () { - expect(cleanVast(sample_vast).indexOf('img') !== -1).to.be.equal(false) - }) - }) - describe('Test getApi function', function () { - const data = { - api: [1] - } - it('Will return 1 for vpaid version 1', function () { - expect(getApi(data)[0]).to.be.equal(1) - }) - it('Will return 2 for vpaid default', function () { - expect(getApi({})[0]).to.be.equal(2) - }) - }) - - describe('Test cleanSizes function', function () { - it('sequence will be respected', function () { - expect(cleanSizes(bidderRequest.bids[0].sizes).toString()).to.be.equal('300,250,300,600') - }) - it('sequence will be respected', function () { - expect(cleanSizes([[728, 90], [970, 90], [300, 600], [320, 50]]).toString()).to.be.equal('728,90,320,50,300,600,970,90') - }) - }) - - describe('Test getPlaybackmethod function', function () { - it('getPlaybackmethod will return 2', function () { - expect(getPlaybackmethod([])[0]).to.be.equal(2) - }) - it('getPlaybackmethod will return 6', function () { - expect(getPlaybackmethod(['viewport_sound_off'])[0]).to.be.equal(6) - }) - }) - - describe('Test getProtocols function', function () { - it('getProtocols will return 3', function () { - expect(getProtocols({ protocols: [3] })[0]).to.be.equal(3) - }) - it('getProtocols will return 6', function () { - expect(_.isEqual(getProtocols({}), [2, 3, 5, 6, 7, 8])).to.be.equal(true) - }) - }) - - describe('All needed functions are available', function () { - it(`isBidRequestValid is present and type function`, function () { - expect(districtm.isBidRequestValid).to.exist.and.to.be.a('function') - }); - - it(`BuildRequests is present and type function`, function () { - expect(districtm.buildRequests).to.exist.and.to.be.a('function') - }); - - it(`interpretResponse is present and type function`, function () { - expect(districtm.interpretResponse).to.exist.and.to.be.a('function') - }); - - it(`getUserSyncs is present and type function`, function () { - expect(districtm.getUserSyncs).to.exist.and.to.be.a('function') - }); - }); - - describe(`these properties are available or not`, function () { - it(`code should have a value of districtmDMX`, function () { - expect(districtm.code).to.be.equal('districtmDMX'); - }); - - it(`timeout should not be defined`, function () { - expect(districtm.onTimeout).to.be.an('undefined'); - }); - }); - - describe(`isBidRequestValid test response`, function () { - let params = { - dmxid: 10001, // optional - memberid: 10003, - }; - it(`function should return true`, function () { - expect(districtm.isBidRequestValid({ params })).to.be.equal(true); - }); - it(`function should return false`, function () { - expect(districtm.isBidRequestValid({ params: {} })).to.be.equal(false); - }); - it(`expect to have memberid`, function () { - expect(params).to.have.property('memberid'); - }); - }); - - describe(`getUserSyncs test usage`, function () { - it(`return value should be an array`, function () { - expect(districtm.getUserSyncs({ iframeEnabled: true })).to.be.an('array'); - }); - it(`array should have only one object and it should have a property type = 'iframe'`, function () { - expect(districtm.getUserSyncs({ iframeEnabled: true }).length).to.be.equal(1); - let [userSync] = districtm.getUserSyncs({ iframeEnabled: true }); - expect(userSync).to.have.property('type'); - expect(userSync.type).to.be.equal('iframe'); - }); - }); - - describe(`buildRequests test usage`, function () { - const buildRequestResults = districtm.buildRequests(bidRequest, bidderRequest); - const buildRequestResultsNoCoppa = districtm.buildRequests(bidRequestNoCoppa, bidderRequestNoCoppa); - it(`the function should return an array`, function () { - expect(buildRequestResults).to.be.an('object'); - }); - it(`contain gdpr consent & ccpa`, function () { - const bidr = JSON.parse(buildRequestResults.data) - expect(bidr.regs.ext.gdpr).to.be.equal(1); - expect(bidr.regs.ext.us_privacy).to.be.equal('1NY'); - expect(bidr.user.ext.consent).to.be.an('string'); - }); - it(`test contain COPPA`, function () { - const bidr = JSON.parse(buildRequestResults.data) - bidr.regs = bidr.regs || {}; - bidr.regs.coppa = 1; - expect(bidr.regs.coppa).to.be.equal(1) - }) - it(`test should not contain COPPA`, function () { - const bidr = JSON.parse(buildRequestResultsNoCoppa.data) - expect(bidr.regs.coppa).to.be.equal(0) - }) - it(`the function should return array length of 1`, function () { - expect(buildRequestResults.data).to.be.a('string'); - }); - }); - - describe('bidRequest Video testing', function () { - const request = districtm.buildRequests(bidRequestVideo, bidRequestVideo); - const data = JSON.parse(request.data) - expect(data instanceof Object).to.be.equal(true) - }) - - describe(`interpretResponse test usage`, function () { - const responseResults = districtm.interpretResponse(responses, { bidderRequest }); - const emptyResponseResults = districtm.interpretResponse(emptyResponse, { bidderRequest }); - const emptyResponseResultsNegation = districtm.interpretResponse(responsesNegative, { bidderRequest }); - const emptyResponseResultsEmptySeat = districtm.interpretResponse(emptyResponseSeatBid, { bidderRequest }); - it(`the function should return an array`, function () { - expect(responseResults).to.be.an('array'); - }); - it(`the function should return array length of 1`, function () { - expect(responseResults.length).to.be.equal(1); - }); - it(`the response return nothing`, function () { - expect(emptyResponseResults.length).to.be.equal(0); - }); - it(`the response seatbid return nothing`, function () { - expect(emptyResponseResultsEmptySeat.length).to.be.equal(0); - }); - - it(`on invalid CPM`, function () { - expect(emptyResponseResultsNegation.length).to.be.equal(0); - }); - }); - - describe(`check validation for id sync gdpr ccpa`, () => { - let allin = spec.getUserSyncs({ iframeEnabled: true }, {}, bidderRequest.gdprConsent, bidderRequest.uspConsent)[0] - let noCCPA = spec.getUserSyncs({ iframeEnabled: true }, {}, bidderRequest.gdprConsent, null)[0] - let noGDPR = spec.getUserSyncs({ iframeEnabled: true }, {}, null, bidderRequest.uspConsent)[0] - let nothing = spec.getUserSyncs({ iframeEnabled: true }, {}, null, null)[0] - - /* - - 'uspConsent': '1NY', - 'gdprConsent': { - 'consentString': 'BOPqNzUOPqNzUAHABBAAA5AAAAAAAA', - */ - it(`gdpr & ccpa should be present`, () => { - expect(allin.url).to.be.equal('https://cdn.districtm.io/ids/index.html?gdpr=BOPqNzUOPqNzUAHABBAAA5AAAAAAAA&ccpa=1NY') - }) - it(`ccpa should be present`, () => { - expect(noGDPR.url).to.be.equal('https://cdn.districtm.io/ids/index.html?ccpa=1NY') - }) - it(`gdpr should be present`, () => { - expect(noCCPA.url).to.be.equal('https://cdn.districtm.io/ids/index.html?gdpr=BOPqNzUOPqNzUAHABBAAA5AAAAAAAA') - }) - it(`gdpr & ccpa shouldn't be present`, () => { - expect(nothing.url).to.be.equal('https://cdn.districtm.io/ids/index.html') - }) - }) - - describe(`Helper function testing`, function () { - const bid = matchRequest('29a28a1bbc8a8d', { bidderRequest }); - const { width, height } = defaultSize(bid); - it(`test matchRequest`, function () { - expect(matchRequest('29a28a1bbc8a8d', { bidderRequest })).to.be.an('object'); - }); - it(`test checkDeepArray`, function () { - expect(_.isEqual(checkDeepArray([728, 90]), [728, 90])).to.be.equal(true); - expect(_.isEqual(checkDeepArray([[728, 90]]), [728, 90])).to.be.equal(true); - expect(_.isEqual(checkDeepArray([[728, 90], [300, 250]]), [728, 90])).to.be.equal(true); - expect(_.isEqual(checkDeepArray([[300, 250], [300, 250]]), [728, 90])).to.be.equal(false); - expect(_.isEqual(checkDeepArray([300, 250]), [300, 250])).to.be.equal(true); - }); - it(`test defaultSize`, function () { - expect(width).to.be.equal(300); - expect(height).to.be.equal(250); - }); - }); -}); diff --git a/test/spec/modules/djaxBidAdapter_spec.js b/test/spec/modules/djaxBidAdapter_spec.js deleted file mode 100644 index bef2b1fddc5..00000000000 --- a/test/spec/modules/djaxBidAdapter_spec.js +++ /dev/null @@ -1,159 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/djaxBidAdapter.js'; - -const ENDPOINT = 'https://demo.reviveadservermod.com/headerbidding_adminshare/www/admin/plugins/Prebid/getAd.php'; - -describe('The Djax bidding adapter', function () { - describe('isBidRequestValid', function () { - it('should return false when given an invalid bid', function () { - const bid = { - bidder: 'djax', - }; - const isValid = spec.isBidRequestValid(bid); - expect(isValid).to.equal(false); - }); - - it('should return true when given a publisherId in bid', function () { - const bid = { - bidder: 'djax', - params: { - publisherId: 2 - }, - }; - const isValid = spec.isBidRequestValid(bid); - expect(isValid).to.equal(true); - }); - }); - - describe('buildRequests', function () { - const bidRequests = [{ - 'bidder': 'djax', - 'params': { - 'publisherId': 2 - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ] - }]; - - const request = spec.buildRequests(bidRequests); - - it('sends bid request to our endpoint via POST', function () { - expect(request.method).to.equal('POST'); - }); - - it('check endpoint url', function () { - expect(request.url).to.equal(ENDPOINT) - }); - - it('sets the proper banner object', function () { - expect(bidRequests[0].params.publisherId).to.equal(2); - }) - }); - const response = { - body: [ - { - 'requestId': '2ee937f15015c6', - 'cpm': '0.2000', - 'width': 300, - 'height': 600, - 'creativeId': '4', - 'currency': 'USD', - 'netRevenue': true, - 'ad': 'ads.html', - 'mediaType': 'banner' - }, - { - 'requestId': '3e1af92622bdc', - 'cpm': '0.2000', - 'creativeId': '4', - 'context': 'outstream', - 'currency': 'USD', - 'netRevenue': true, - 'vastUrl': 'tezt.xml', - 'width': 640, - 'height': 480, - 'mediaType': 'video' - }] - }; - - const request = [ - { - 'bidder': 'djax', - 'params': { - 'publisherId': 2 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [300, 600] - ] - } - }, - 'bidId': '2ee937f15015c6', - 'src': 'client', - }, - { - 'bidder': 'djax', - 'params': { - 'publisherId': 2 - }, - 'mediaTypes': { - 'video': { - 'context': 'outstream', - 'playerSize': [ - [640, 480] - ] - } - }, - 'bidId': '3e1af92622bdc', - 'src': 'client', - } - ]; - - describe('interpretResponse', function () { - it('return empty array when no ad found', function () { - const response = {}; - const request = { bidRequests: [] }; - const bids = spec.interpretResponse(response, request); - expect(bids).to.have.lengthOf(0); - }); - - it('check response for banner and video', function () { - const bids = spec.interpretResponse(response, request); - expect(bids).to.have.lengthOf(2); - expect(bids[0].requestId).to.equal('2ee937f15015c6'); - expect(bids[0].cpm).to.equal('0.2000'); - expect(bids[1].cpm).to.equal('0.2000'); - expect(bids[0].width).to.equal(300); - expect(bids[0].height).to.equal(600); - expect(bids[1].vastUrl).to.not.equal(''); - expect(bids[0].ad).to.not.equal(''); - expect(bids[1].adResponse).to.not.equal(''); - expect(bids[1].renderer).not.to.be.an('undefined'); - }); - }); - - describe('On winning bid', function () { - const bids = spec.interpretResponse(response, request); - spec.onBidWon(bids); - }); - - describe('On bid Time out', function () { - const bids = spec.interpretResponse(response, request); - spec.onTimeout(bids); - }); - - describe('user sync', function () { - it('to check the user sync iframe', function () { - let syncs = spec.getUserSyncs({ - iframeEnabled: true - }); - expect(syncs).to.not.be.an('undefined'); - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('iframe'); - }); - }); -}); diff --git a/test/spec/modules/dmdIdSystem_spec.js b/test/spec/modules/dmdIdSystem_spec.js deleted file mode 100644 index 9c603eebbd5..00000000000 --- a/test/spec/modules/dmdIdSystem_spec.js +++ /dev/null @@ -1,48 +0,0 @@ -import * as utils from '../../../src/utils.js'; - -import {dmdIdSubmodule} from 'modules/dmdIdSystem.js'; - -describe('Dmd ID System', function() { - let logErrorStub; - - beforeEach(function () { - logErrorStub = sinon.stub(utils, 'logError'); - }); - - afterEach(function () { - logErrorStub.restore(); - }); - - it('should log an error if no configParams were passed into getId', function () { - dmdIdSubmodule.getId(); - expect(logErrorStub.calledOnce).to.be.true; - }); - - it('should log an error if configParams doesnot have api_key passed to getId', function () { - 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}}); - 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'}}); - expect(logErrorStub.calledOnce).to.be.false; - }); - - it('should return undefined if empty value passed into decode', function () { - expect(dmdIdSubmodule.decode()).to.be.undefined; - }); - - it('should return undefined if invalid dmd-dgid passed into decode', function () { - expect(dmdIdSubmodule.decode(123)).to.be.undefined; - }); - - it('should return dmdId if valid dmd-dgid passed into decode', function () { - let data = { 'dmdId': 'U12345' }; - expect(dmdIdSubmodule.decode('U12345')).to.deep.equal(data); - }); -}); diff --git a/test/spec/modules/docereeBidAdapter_spec.js b/test/spec/modules/docereeBidAdapter_spec.js deleted file mode 100644 index efff2efa319..00000000000 --- a/test/spec/modules/docereeBidAdapter_spec.js +++ /dev/null @@ -1,97 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/docereeBidAdapter.js'; -import { config } from '../../../src/config.js'; - -describe('BidlabBidAdapter', function () { - config.setConfig({ - doceree: { - context: { - data: { - token: 'testing-token', // required - } - }, - user: { - data: { - gender: '', - email: '', - hashedEmail: '', - firstName: '', - lastName: '', - npi: '', - hashedNPI: '', - city: '', - zipCode: '', - specialization: '', - } - } - } - }); - let bid = { - bidId: 'testing', - bidder: 'doceree', - params: { - placementId: 'DOC_7jm9j5eqkl0xvc5w', - } - }; - - describe('isBidRequestValid', function () { - it('Should return true if placementId is present', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false if placementId is not present', function () { - delete bid.params.placementId; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid]); - serverRequest = serverRequest[0] - 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; - }); - it('Returns GET method', function () { - expect(serverRequest.method).to.equal('GET'); - }); - it('Returns valid URL', function () { - expect(serverRequest.url).to.equal('https://bidder.doceree.com/v1/adrequest?id=DOC_7jm9j5eqkl0xvc5w&pubRequestedURL=undefined&loggedInUser=JTdCJTIyZ2VuZGVyJTIyJTNBJTIyJTIyJTJDJTIyZW1haWwlMjIlM0ElMjIlMjIlMkMlMjJoYXNoZWRFbWFpbCUyMiUzQSUyMiUyMiUyQyUyMmZpcnN0TmFtZSUyMiUzQSUyMiUyMiUyQyUyMmxhc3ROYW1lJTIyJTNBJTIyJTIyJTJDJTIybnBpJTIyJTNBJTIyJTIyJTJDJTIyaGFzaGVkTlBJJTIyJTNBJTIyJTIyJTJDJTIyY2l0eSUyMiUzQSUyMiUyMiUyQyUyMnppcENvZGUlMjIlM0ElMjIlMjIlMkMlMjJzcGVjaWFsaXphdGlvbiUyMiUzQSUyMiUyMiU3RA%3D%3D&prebidjs=true&requestId=testing&'); - }); - }); - describe('interpretResponse', function () { - it('Should interpret banner response', function () { - const banner = { - body: { - DIVID: 'DOC_7jm9j5eqkl0xvc5w', - creativeType: 'banner', - guid: 'G125fzC5NKl3FHeOT8yvL98ILfQS9TVUgk6Q', - currency: 'USD', - cpmBid: 2, - height: '250', - width: '300', - ctaLink: 'https://doceree.com/', - sourceURL: '', - sourceHTML: '
test
', - advertiserDomain: 'doceree.com', - } - }; - let bannerResponses = spec.interpretResponse(banner); - expect(bannerResponses).to.be.an('array').that.is.not.empty; - let dataItem = bannerResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', - 'netRevenue', 'currency', 'mediaType', 'creativeId', 'meta'); - expect(dataItem.requestId).to.equal('G125fzC5NKl3FHeOT8yvL98ILfQS9TVUgk6Q'); - expect(dataItem.cpm).to.equal(2); - expect(dataItem.width).to.equal(300); - expect(dataItem.height).to.equal(250); - expect(dataItem.ad).to.equal('
test
'); - expect(dataItem.ttl).to.equal(30); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal('USD'); - expect(dataItem.creativeId).to.equal('DOC_7jm9j5eqkl0xvc5w'); - expect(dataItem.meta.advertiserDomains).to.be.an('array').that.is.not.empty; - expect(dataItem.meta.advertiserDomains[0]).to.equal('doceree.com') - }); - }) -}); diff --git a/test/spec/modules/dspxBidAdapter_spec.js b/test/spec/modules/dspxBidAdapter_spec.js deleted file mode 100644 index 87752f7747a..00000000000 --- a/test/spec/modules/dspxBidAdapter_spec.js +++ /dev/null @@ -1,342 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/dspxBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -const ENDPOINT_URL = 'https://buyer.dspx.tv/request/'; -const ENDPOINT_URL_DEV = 'https://dcbuyer.dspx.tv/request/'; - -describe('dspxAdapter', function () { - const adapter = newBidder(spec); - - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'dspx', - 'params': { - 'placement': '6682', - 'pfilter': { - 'floorprice': 1000000 - }, - 'bcat': 'IAB2,IAB4', - 'dvt': 'desktop' - }, - 'sizes': [ - [300, 250] - ], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'someIncorrectParam': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [{ - 'bidder': 'dspx', - 'params': { - 'placement': '6682', - 'pfilter': { - 'floorprice': 1000000, - 'private_auction': 0, - 'geo': { - 'country': 'DE' - } - }, - 'bcat': 'IAB2,IAB4', - 'dvt': 'desktop' - }, - 'sizes': [ - [300, 250] - ], - 'bidId': '30b31c1838de1e1', - 'bidderRequestId': '22edbae2733bf61', - 'auctionId': '1d1a030790a475' - }, - { - 'bidder': 'dspx', - 'params': { - 'placement': '101', - 'devMode': true - }, - 'sizes': [ - [300, 250] - ], - 'bidId': '30b31c1838de1e2', - 'bidderRequestId': '22edbae2733bf62', - 'auctionId': '1d1a030790a476' - }, { - 'bidder': 'dspx', - 'params': { - 'placement': '6682', - 'pfilter': { - 'floorprice': 1000000, - 'private_auction': 0, - 'geo': { - 'country': 'DE' - } - }, - 'bcat': 'IAB2,IAB4', - 'dvt': 'desktop' - }, - 'sizes': [ - [300, 250] - ], - 'bidId': '30b31c1838de1e3', - 'bidderRequestId': '22edbae2733bf69', - 'auctionId': '1d1a030790a477' - }, - { - 'bidder': 'dspx', - 'params': { - 'placement': '101', - 'devMode': true - }, - 'sizes': [ - [300, 250] - ], - 'bidId': '30b31c1838de1e4', - 'bidderRequestId': '22edbae2733bf67', - 'auctionId': '1d1a030790a478' - }, - { - 'bidder': 'dspx', - 'params': { - 'placement': '101', - 'devMode': true - }, - 'mediaTypes': { - 'video': { - 'playerSize': [640, 480], - 'context': 'instream' - } - }, - 'bidId': '30b31c1838de1e41', - 'bidderRequestId': '22edbae2733bf67', - 'auctionId': '1d1a030790a478' - } - - ]; - - // With gdprConsent - var bidderRequest = { - refererInfo: { - referer: 'some_referrer.net' - }, - gdprConsent: { - consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', - vendorData: {someData: 'value'}, - gdprApplies: true - } - }; - - var request1 = spec.buildRequests([bidRequests[0]], bidderRequest)[0]; - it('sends bid request to our endpoint via GET', function () { - expect(request1.method).to.equal('GET'); - expect(request1.url).to.equal(ENDPOINT_URL); - let data = request1.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('_f=html&alternative=prebid_js&inventory_item_id=6682&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e1&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bprivate_auction%5D=0&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&bcat=IAB2%2CIAB4&dvt=desktop'); - }); - - var request2 = spec.buildRequests([bidRequests[1]], bidderRequest)[0]; - it('sends bid request to our DEV endpoint via GET', function () { - expect(request2.method).to.equal('GET'); - expect(request2.url).to.equal(ENDPOINT_URL_DEV); - let data = request2.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('_f=html&alternative=prebid_js&inventory_item_id=101&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e2&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&prebidDevMode=1'); - }); - - // Without gdprConsent - var bidderRequestWithoutGdpr = { - refererInfo: { - referer: 'some_referrer.net' - } - }; - var request3 = spec.buildRequests([bidRequests[2]], bidderRequestWithoutGdpr)[0]; - it('sends bid request without gdprConsent to our endpoint via GET', function () { - expect(request3.method).to.equal('GET'); - expect(request3.url).to.equal(ENDPOINT_URL); - let data = request3.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('_f=html&alternative=prebid_js&inventory_item_id=6682&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e3&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bprivate_auction%5D=0&pfilter%5Bgeo%5D%5Bcountry%5D=DE&bcat=IAB2%2CIAB4&dvt=desktop'); - }); - - var request4 = spec.buildRequests([bidRequests[3]], bidderRequestWithoutGdpr)[0]; - it('sends bid request without gdprConsent to our DEV endpoint via GET', function () { - expect(request4.method).to.equal('GET'); - expect(request4.url).to.equal(ENDPOINT_URL_DEV); - let data = request4.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('_f=html&alternative=prebid_js&inventory_item_id=101&srw=300&srh=250&idt=100&bid_id=30b31c1838de1e4&prebidDevMode=1'); - }); - - var request5 = spec.buildRequests([bidRequests[4]], bidderRequestWithoutGdpr)[0]; - it('sends bid video request to our rads endpoint via GET', function () { - expect(request5.method).to.equal('GET'); - let data = request5.data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('_f=vast2&alternative=prebid_js&inventory_item_id=101&srw=640&srh=480&idt=100&bid_id=30b31c1838de1e41&prebidDevMode=1'); - }); - }); - - describe('interpretResponse', function () { - let serverResponse = { - 'body': { - 'cpm': 5000000, - 'crid': 100500, - 'width': '300', - 'height': '250', - 'type': 'sspHTML', - 'tag': '', - 'requestId': '220ed41385952a', - 'currency': 'EUR', - 'ttl': 60, - 'netRevenue': true, - 'zone': '6682' - } - }; - let serverVideoResponse = { - 'body': { - 'cpm': 5000000, - 'crid': 100500, - 'width': '300', - 'height': '250', - 'vastXml': '{"reason":7001,"status":"accepted"}', - 'requestId': '220ed41385952a', - 'type': 'vast2', - 'currency': 'EUR', - 'ttl': 60, - 'netRevenue': true, - 'zone': '6682' - } - }; - - let expectedResponse = [{ - requestId: '23beaa6af6cdde', - cpm: 0.5, - width: 0, - height: 0, - creativeId: 100500, - dealId: '', - currency: 'EUR', - netRevenue: true, - ttl: 300, - type: 'sspHTML', - ad: '' - }, { - requestId: '23beaa6af6cdde', - cpm: 0.5, - width: 0, - height: 0, - creativeId: 100500, - dealId: '', - currency: 'EUR', - netRevenue: true, - ttl: 300, - type: 'vast2', - vastXml: '{"reason":7001,"status":"accepted"}', - mediaType: 'video' - }]; - - it('should get the correct bid response by display ad', function () { - let bidRequest = [{ - 'method': 'GET', - 'url': ENDPOINT_URL, - 'data': { - 'bid_id': '30b31c1838de1e' - } - }]; - let result = spec.interpretResponse(serverResponse, bidRequest[0]); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('should get the correct dspx video bid response by display ad', function () { - let bidRequest = [{ - 'method': 'GET', - 'url': ENDPOINT_URL, - 'mediaTypes': { - 'video': { - 'playerSize': [640, 480], - 'context': 'instream' - } - }, - 'data': { - 'bid_id': '30b31c1838de1e' - } - }]; - let result = spec.interpretResponse(serverVideoResponse, bidRequest[0]); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[1])); - }); - - it('handles empty bid response', function () { - let response = { - body: {} - }; - let result = spec.interpretResponse(response); - expect(result.length).to.equal(0); - }); - }); - - describe(`getUserSyncs test usage`, function () { - let serverResponses; - - beforeEach(function () { - serverResponses = [{ - body: { - requestId: '23beaa6af6cdde', - cpm: 0.5, - width: 0, - height: 0, - creativeId: 100500, - dealId: '', - currency: 'EUR', - netRevenue: true, - ttl: 300, - type: 'sspHTML', - ad: '', - userSync: { - iframeUrl: ['anyIframeUrl?a=1'], - imageUrl: ['anyImageUrl', 'anyImageUrl2'] - } - } - }]; - }); - - it(`return value should be an array`, function () { - expect(spec.getUserSyncs({ iframeEnabled: true })).to.be.an('array'); - }); - it(`array should have only one object and it should have a property type = 'iframe'`, function () { - expect(spec.getUserSyncs({ iframeEnabled: true }, serverResponses).length).to.be.equal(1); - let [userSync] = spec.getUserSyncs({ iframeEnabled: true }, serverResponses); - expect(userSync).to.have.property('type'); - expect(userSync.type).to.be.equal('iframe'); - }); - it(`we have valid sync url for iframe`, function () { - let [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 () { - let [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 () { - let 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'); - expect(userSync[1].url).to.be.equal('anyImageUrl?gdpr=1&gdpr_consent=anyString') - expect(userSync[1].type).to.be.equal('image'); - expect(userSync[2].url).to.be.equal('anyImageUrl2?gdpr=1&gdpr_consent=anyString') - expect(userSync[2].type).to.be.equal('image'); - }); - }); -}); diff --git a/test/spec/modules/e_volutionBidAdapter_spec.js b/test/spec/modules/e_volutionBidAdapter_spec.js deleted file mode 100644 index 447420616d1..00000000000 --- a/test/spec/modules/e_volutionBidAdapter_spec.js +++ /dev/null @@ -1,235 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/e_volutionBidAdapter.js'; - -describe('EvolutionTechBidAdapter', function () { - let bid = { - bidId: '23fhj33i987f', - bidder: 'e_volution', - params: { - placementId: 0, - traffic: 'banner' - } - }; - - describe('isBidRequestValid', function () { - it('Should return true if there are bidId, params and placementId parameters present', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false if at least one of parameters is not present', function () { - delete bid.params.placementId; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid]); - 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://service.e-volution.ai/?c=o&m=multi'); - }); - it('Returns valid data if array of bids is valid', function () { - let data = serverRequest.data; - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); - 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'); - let placement = data['placements'][0]; - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes'); - expect(placement.placementId).to.equal(0); - expect(placement.bidId).to.equal('23fhj33i987f'); - expect(placement.traffic).to.equal('banner'); - }); - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); - }); - 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' - }] - }; - let bannerResponses = spec.interpretResponse(banner); - expect(bannerResponses).to.be.an('array').that.is.not.empty; - let dataItem = bannerResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - expect(dataItem.requestId).to.equal('23fhj33i987f'); - expect(dataItem.cpm).to.equal(0.4); - expect(dataItem.width).to.equal(300); - expect(dataItem.height).to.equal(250); - expect(dataItem.ad).to.equal('Test'); - expect(dataItem.ttl).to.equal(120); - expect(dataItem.creativeId).to.equal('2'); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal('USD'); - }); - 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' - }] - }; - let videoResponses = spec.interpretResponse(video); - expect(videoResponses).to.be.an('array').that.is.not.empty; - - let dataItem = videoResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - 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'); - }); - 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', - }] - }; - let nativeResponses = spec.interpretResponse(native); - expect(nativeResponses).to.be.an('array').that.is.not.empty; - - let dataItem = nativeResponses[0]; - expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); - 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'); - }); - 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' - }] - }; - - let 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' - }] - }; - let 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', - }] - }; - let 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' - }] - }; - let serverResponses = spec.interpretResponse(invalid); - expect(serverResponses).to.be.an('array').that.is.empty; - }); - }); - describe('getUserSyncs', function () { - let userSync = spec.getUserSyncs(); - it('Returns valid URL and type', function () { - if (spec.noSync) { - expect(userSync).to.be.equal(false); - } else { - expect(userSync).to.be.an('array').with.lengthOf(1); - expect(userSync[0].type).to.exist; - expect(userSync[0].url).to.exist; - expect(userSync[0].type).to.be.equal('image'); - expect(userSync[0].url).to.be.equal('https://service.e-volution.ai/?c=o&m=sync'); - } - }); - }); -}); diff --git a/test/spec/modules/ebdrBidAdapter_spec.js b/test/spec/modules/ebdrBidAdapter_spec.js deleted file mode 100644 index ba1cad475da..00000000000 --- a/test/spec/modules/ebdrBidAdapter_spec.js +++ /dev/null @@ -1,235 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/ebdrBidAdapter.js'; -import { VIDEO, BANNER } from 'src/mediaTypes.js'; -import * as utils from 'src/utils.js'; - -describe('ebdrBidAdapter', function () { - let bidRequests; - - beforeEach(function () { - bidRequests = [ - { - code: 'div-gpt-ad-1460505748561-0', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - } - }, - bidder: 'ebdr', - params: { - zoneid: '99999', - bidfloor: '1.00', - IDFA: 'xxx-xxx', - ADID: 'xxx-xxx', - latitude: '34.089811', - longitude: '-118.392805' - }, - bidId: '2c5e8a1a84522d', - bidderRequestId: '1d0c4017f02458', - auctionId: '9adc85ed-43ee-4a78-816b-52b7e578f314' - }, { - adUnitCode: 'div-gpt-ad-1460505748561-1', - mediaTypes: { - video: { - context: 'instream', - playerSize: [300, 250] - } - }, - bidder: 'ebdr', - params: { - zoneid: '99998', - bidfloor: '1.00', - IDFA: 'xxx-xxx', - ADID: 'xxx-xxx', - latitude: '34.089811', - longitude: '-118.392805' - }, - bidId: '23a01e95856577', - bidderRequestId: '1d0c4017f02458', - auctionId: '9adc85ed-43ee-4a78-816b-52b7e578f314' - } - ]; - }); - - describe('spec.isBidRequestValid', function () { - it('should return true when the required params are passed', function () { - const bidRequest = bidRequests[0]; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }); - - it('should return true when the only required param is missing', function () { - const bidRequest = bidRequests[0]; - bidRequest.params = { - zoneid: '99998', - bidfloor: '1.00', - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }); - - it('should return true when the "bidfloor" param is missing', function () { - const bidRequest = bidRequests[0]; - bidRequest.params = { - zoneid: '99998', - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }); - - it('should return false when no bid params are passed', function () { - const bidRequest = bidRequests[0]; - bidRequest.params = {}; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when a bid request is not passed', function () { - expect(spec.isBidRequestValid()).to.equal(false); - expect(spec.isBidRequestValid({})).to.equal(false); - }); - }); - - describe('spec.buildRequests', function () { - describe('for banner bids', function () { - it('must handle an empty bid size', function () { - bidRequests[0].mediaTypes = { banner: {} }; - const requests = spec.buildRequests(bidRequests); - const bidRequest = {}; - bidRequest['2c5e8a1a84522d'] = { mediaTypes: BANNER, w: null, h: null }; - expect(requests.bids['2c5e8a1a84522d']).to.deep.equals(bidRequest['2c5e8a1a84522d']); - }); - it('should create a single GET', function () { - bidRequests[0].mediaTypes = { banner: {} }; - bidRequests[1].mediaTypes = { banner: {} }; - const requests = spec.buildRequests(bidRequests); - expect(requests.method).to.equal('GET'); - }); - it('must parse bid size from a nested array', function () { - const width = 640; - const height = 480; - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { banner: {sizes: [[ width, height ]]} }; - const requests = spec.buildRequests([ bidRequest ]); - const data = {}; - data['2c5e8a1a84522d'] = { mediaTypes: BANNER, w: width, h: height }; - expect(requests.bids['2c5e8a1a84522d']).to.deep.equal(data['2c5e8a1a84522d']); - }); - }); - describe('for video bids', function () { - it('must handle an empty bid size', function () { - bidRequests[1].mediaTypes = { video: {} }; - const requests = spec.buildRequests(bidRequests); - const bidRequest = {}; - bidRequest['23a01e95856577'] = { mediaTypes: VIDEO, w: null, h: null }; - expect(requests.bids['23a01e95856577']).to.deep.equals(bidRequest['23a01e95856577']); - }); - - it('should create a GET request for each bid', function () { - const bidRequest = bidRequests[1]; - const requests = spec.buildRequests([ bidRequest ]); - expect(requests.method).to.equal('GET'); - }); - }); - }); - - describe('spec.interpretResponse', function () { - describe('for video bids', function () { - it('should return no bids if the response is not valid', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { video: {} }; - const bidResponse = spec.interpretResponse({ body: null }, { bidRequest }); - expect(bidResponse.length).to.equal(0); - }); - - it('should return a valid video bid response', function () { - const ebdrReq = {bids: {}}; - bidRequests.forEach(bid => { - let _mediaTypes = (bid.mediaTypes && bid.mediaTypes.video ? VIDEO : BANNER); - ebdrReq.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: '1d0c4017f02458', seatbid: [{bid: [{id: '23a01e95856577', impid: '23a01e95856577', price: 0.81, adid: 'abcde-12345', nurl: 'https://cdn0.bnmla.com/vtest.xml', adm: '\nStatic VASTStatic VAST Tag00:00:15https//www.engagebdr.com/c', adomain: ['advertiserdomain.com'], iurl: '', cid: 'campaign1', crid: 'abcde-12345', w: 300, h: 250}], seat: '19513bcfca8006'}], bidid: '19513bcfca8006', cur: 'USD'}; - const bidResponse = spec.interpretResponse({ body: serverResponse }, ebdrReq); - expect(bidResponse[0]).to.deep.equal({ - requestId: bidRequests[1].bidId, - vastXml: serverResponse.seatbid[0].bid[0].adm, - mediaType: 'video', - creativeId: serverResponse.seatbid[0].bid[0].crid, - cpm: serverResponse.seatbid[0].bid[0].price, - width: serverResponse.seatbid[0].bid[0].w, - height: serverResponse.seatbid[0].bid[0].h, - currency: 'USD', - netRevenue: true, - ttl: 3600, - vastUrl: serverResponse.seatbid[0].bid[0].nurl - }); - }); - }); - - describe('for banner bids', function () { - it('should return no bids if the response is not valid', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { banner: {} }; - const bidResponse = spec.interpretResponse({ body: null }, { bidRequest }); - expect(bidResponse.length).to.equal(0); - }); - - it('should return no bids if the response is empty', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { banner: {} }; - const bidResponse = spec.interpretResponse({ body: [] }, { bidRequest }); - expect(bidResponse.length).to.equal(0); - }); - - it('should return valid banner bid responses', function () { - const ebdrReq = {bids: {}}; - bidRequests.forEach(bid => { - let _mediaTypes = (bid.mediaTypes && bid.mediaTypes.video ? VIDEO : BANNER); - ebdrReq.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: '1d0c4017f02458', seatbid: [{bid: [{id: '2c5e8a1a84522d', impid: '2c5e8a1a84522d', price: 0.81, adid: 'abcde-12345', nurl: '', adm: '
', adomain: ['advertiserdomain.com'], iurl: '', cid: 'campaign1', crid: 'abcde-12345', w: 300, h: 250}], seat: '19513bcfca8006'}], bidid: '19513bcfca8006', cur: 'USD', w: 300, h: 250}; - const bidResponse = spec.interpretResponse({ body: serverResponse }, ebdrReq); - expect(bidResponse[0]).to.deep.equal({ - requestId: bidRequests[ 0 ].bidId, - ad: serverResponse.seatbid[0].bid[0].adm, - mediaType: 'banner', - creativeId: serverResponse.seatbid[0].bid[0].crid, - cpm: serverResponse.seatbid[0].bid[0].price, - width: serverResponse.seatbid[0].bid[0].w, - height: serverResponse.seatbid[0].bid[0].h, - currency: 'USD', - netRevenue: true, - ttl: 3600 - }); - }); - }); - }); - describe('spec.getUserSyncs', function () { - let syncOptions - beforeEach(function () { - syncOptions = { - enabledBidders: ['ebdr'], // only these bidders are allowed to sync - pixelEnabled: true - } - }); - it('sucess with usersync url', function () { - const serverResponse = {id: '1d0c4017f02458', seatbid: [{bid: [{id: '2c5e8a1a84522d', impid: '2c5e8a1a84522d', price: 0.81, adid: 'abcde-12345', nurl: '', adm: '
', adomain: ['advertiserdomain.com'], iurl: 'https://match.bnmla.com/usersync?sspid=59&redir=', cid: 'campaign1', crid: 'abcde-12345', w: 300, h: 250}], seat: '19513bcfca8006'}], bidid: '19513bcfca8006', cur: 'USD', w: 300, h: 250}; - const result = []; - result.push({type: 'image', url: 'https://match.bnmla.com/usersync?sspid=59&redir='}); - expect(spec.getUserSyncs(syncOptions, { body: serverResponse })).to.deep.equal(result); - }); - - it('sucess without usersync url', function () { - const serverResponse = {id: '1d0c4017f02458', seatbid: [{bid: [{id: '2c5e8a1a84522d', impid: '2c5e8a1a84522d', price: 0.81, adid: 'abcde-12345', nurl: '', adm: '
', adomain: ['advertiserdomain.com'], iurl: '', cid: 'campaign1', crid: 'abcde-12345', w: 300, h: 250}], seat: '19513bcfca8006'}], bidid: '19513bcfca8006', cur: 'USD', w: 300, h: 250}; - const result = []; - expect(spec.getUserSyncs(syncOptions, { body: serverResponse })).to.deep.equal(result); - }); - it('empty response', function () { - const serverResponse = {}; - const result = []; - expect(spec.getUserSyncs(syncOptions, { body: serverResponse })).to.deep.equal(result); - }); - }); -}); diff --git a/test/spec/modules/edgequeryxBidAdapter_spec.js b/test/spec/modules/edgequeryxBidAdapter_spec.js deleted file mode 100644 index a66c546bd7c..00000000000 --- a/test/spec/modules/edgequeryxBidAdapter_spec.js +++ /dev/null @@ -1,116 +0,0 @@ -import { - expect -} from 'chai'; -import { - spec -} from 'modules/edgequeryxBidAdapter.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/consentManagement.js'; - -// Default params with optional ones -describe('Edge Query X bid adapter tests', function () { - var DEFAULT_PARAMS = [{ - bidId: 'abcd1234', - mediaTypes: { - banner: { - sizes: [ - [1, 1] - ] - } - }, - bidder: 'edgequeryx', - params: { - accountId: 'test', - widgetId: 'test' - }, - requestId: 'efgh5678', - transactionId: 'zsfgzzg' - }]; - var BID_RESPONSE = { - body: { - requestId: 'abcd1234', - cpm: 22, - width: 1, - height: 1, - creativeId: 'EQXTest', - currency: 'EUR', - netRevenue: true, - ttl: 360, - ad: '< --- awesome script --- >' - } - }; - - it('Verify build request', function () { - config.setConfig({ - 'currency': { - 'adServerCurrency': 'EUR' - } - }); - const request = spec.buildRequests(DEFAULT_PARAMS); - expect(request[0]).to.have.property('url').and.to.equal('https://deep.edgequery.io/prebid/x'); - expect(request[0]).to.have.property('method').and.to.equal('POST'); - const requestContent = JSON.parse(request[0].data); - - expect(requestContent).to.have.property('accountId').and.to.equal('test'); - expect(requestContent).to.have.property('widgetId').and.to.equal('test'); - expect(requestContent).to.have.property('sizes'); - expect(requestContent.sizes[0]).to.have.property('w').and.to.equal(1); - expect(requestContent.sizes[0]).to.have.property('h').and.to.equal(1); - }); - - it('Verify parse response', function () { - const request = spec.buildRequests(DEFAULT_PARAMS); - const bids = spec.interpretResponse(BID_RESPONSE, request[0]); - expect(bids).to.have.lengthOf(1); - const bid = bids[0]; - expect(bid.cpm).to.equal(22); - expect(bid.ad).to.equal('< --- awesome script --- >'); - expect(bid.width).to.equal(1); - expect(bid.height).to.equal(1); - expect(bid.creativeId).to.equal('EQXTest'); - expect(bid.currency).to.equal('EUR'); - expect(bid.netRevenue).to.equal(true); - expect(bid.ttl).to.equal(360); - expect(bid.requestId).to.equal(DEFAULT_PARAMS[0].bidId); - - expect(function () { - spec.interpretResponse(BID_RESPONSE, { - data: 'invalid Json' - }) - }).to.not.throw(); - }); - - it('Verifies bidder code', function () { - expect(spec.code).to.equal('edgequeryx'); - }); - - it('Verifies bidder aliases', function () { - expect(spec.aliases).to.have.lengthOf(1); - expect(spec.aliases[0]).to.equal('eqx'); - }); - - it('Verifies if bid request valid', function () { - expect(spec.isBidRequestValid(DEFAULT_PARAMS[0])).to.equal(true); - expect(spec.isBidRequestValid({})).to.equal(false); - expect(spec.isBidRequestValid({ - params: {} - })).to.equal(false); - expect(spec.isBidRequestValid({ - params: { - widgetyId: 'abcdef' - } - })).to.equal(false); - expect(spec.isBidRequestValid({ - params: { - widgetId: 'test', - accountId: 'test' - } - })).to.equal(true); - }); -}); diff --git a/test/spec/modules/eids_spec.js b/test/spec/modules/eids_spec.js deleted file mode 100644 index 1ccaab2b302..00000000000 --- a/test/spec/modules/eids_spec.js +++ /dev/null @@ -1,388 +0,0 @@ -import {createEidsArray} from 'modules/userId/eids.js'; -import {expect} from 'chai'; - -// Note: In unit tets cases for bidders, call the createEidsArray function over userId object that is used for calling fetchBids -// this way the request will stay consistent and unit test cases will not need lots of changes. - -describe('eids array generation for known sub-modules', function() { - it('pubCommonId', function() { - const userId = { - pubcid: 'some-random-id-value' - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'pubcid.org', - uids: [{id: 'some-random-id-value', atype: 1}] - }); - }); - - it('unifiedId: ext generation', function() { - const userId = { - tdid: 'some-random-id-value' - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'adserver.org', - uids: [{id: 'some-random-id-value', atype: 1, ext: { rtiPartner: 'TDID' }}] - }); - }); - - describe('id5Id', function() { - it('does not include an ext if not provided', function() { - const userId = { - id5id: { - uid: 'some-random-id-value' - } - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'id5-sync.com', - uids: [{ id: 'some-random-id-value', atype: 1 }] - }); - }); - - it('includes ext if provided', function() { - const userId = { - id5id: { - uid: 'some-random-id-value', - ext: { - linkType: 0 - } - } - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'id5-sync.com', - uids: [{ - id: 'some-random-id-value', - atype: 1, - ext: { - linkType: 0 - } - }] - }); - }); - }); - - it('parrableId', function() { - const userId = { - parrableId: { - eid: 'some-random-id-value' - } - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'parrable.com', - uids: [{id: 'some-random-id-value', atype: 1}] - }); - }); - - it('merkleId', function() { - const userId = { - merkleId: { - id: 'some-random-id-value', keyID: 1 - } - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'merkleinc.com', - uids: [{id: 'some-random-id-value', - atype: 3, - ext: { keyID: 1 - }}] - }); - }); - - it('identityLink', function() { - const userId = { - idl_env: 'some-random-id-value' - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'liveramp.com', - uids: [{id: 'some-random-id-value', atype: 3}] - }); - }); - - it('liveIntentId; getValue call and ext', function() { - const userId = { - lipb: { - lipbid: 'some-random-id-value', - segments: ['s1', 's2'] - } - }; - const newEids = createEidsArray(userId); - 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']} - }); - }); - - it('liveIntentId; getValue call and NO ext', function() { - const userId = { - lipb: { - lipbid: 'some-random-id-value' - } - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'liveintent.com', - uids: [{id: 'some-random-id-value', atype: 3}] - }); - }); - - it('britepoolId', function() { - const userId = { - britepoolid: 'some-random-id-value' - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'britepool.com', - uids: [{id: 'some-random-id-value', atype: 3}] - }); - }); - - it('lotamePanoramaId', function () { - const userId = { - lotamePanoramaId: 'some-random-id-value', - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'crwdcntrl.net', - uids: [{ id: 'some-random-id-value', atype: 1 }], - }); - }); - - it('criteo', function() { - const userId = { - criteoId: 'some-random-id-value' - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'criteo.com', - uids: [{id: 'some-random-id-value', atype: 1}] - }); - }); - - it('tapadId', function() { - const userId = { - tapadId: 'some-random-id-value' - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'tapad.com', - uids: [{id: 'some-random-id-value', atype: 1}] - }); - }); - - it('deepintentId', function() { - const userId = { - deepintentId: 'some-random-id-value' - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'deepintent.com', - uids: [{id: 'some-random-id-value', atype: 3}] - }); - }); - - it('NetId', function() { - const userId = { - netId: 'some-random-id-value' - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'netid.de', - uids: [{id: 'some-random-id-value', atype: 1}] - }); - }); - - it('NextRollId', function() { - const userId = { - nextrollId: 'some-random-id-value' - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'nextroll.com', - uids: [{id: 'some-random-id-value', atype: 1}] - }); - }); - it('Sharedid', function() { - const userId = { - sharedid: { - id: 'test_sharedId', - third: 'test_sharedId' - } - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'sharedid.org', - uids: [{ - id: 'test_sharedId', - atype: 1, - ext: { - third: 'test_sharedId' - } - }] - }); - }); - it('Sharedid: Not Synched', function() { - const userId = { - sharedid: { - id: 'test_sharedId' - } - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'sharedid.org', - uids: [{ - id: 'test_sharedId', - atype: 1 - }] - }); - }); - - it('zeotapIdPlus', function() { - const userId = { - IDP: 'some-random-id-value' - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'zeotap.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }); - }); - - it('haloId', function() { - const userId = { - haloId: 'some-random-id-value' - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'audigent.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }); - }); - - it('quantcastId', function() { - const userId = { - quantcastId: 'some-random-id-value' - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'quantcast.com', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }); - }); - it('uid2', function() { - const userId = { - uid2: {'id': 'Sample_AD_Token'} - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(1); - expect(newEids[0]).to.deep.equal({ - source: 'uidapi.com', - uids: [{ - id: 'Sample_AD_Token', - atype: 3 - }] - }); - }); - it('pubProvidedId', function() { - const userId = { - pubProvidedId: [{ - source: 'example.com', - uids: [{ - id: 'value read from cookie or local storage', - ext: { - stype: 'ppuid' - } - }] - }, { - source: 'id-partner.com', - uids: [{ - id: 'value read from cookie or local storage' - }] - }] - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(2); - expect(newEids[0]).to.deep.equal({ - source: 'example.com', - uids: [{ - id: 'value read from cookie or local storage', - ext: { - stype: 'ppuid' - } - }] - }); - expect(newEids[1]).to.deep.equal({ - source: 'id-partner.com', - uids: [{ - id: 'value read from cookie or local storage' - }] - }); - }); -}); -describe('Negative case', function() { - it('eids array generation for UN-known sub-module', function() { - // UnknownCommonId - const userId = { - unknowncid: 'some-random-id-value' - }; - const newEids = createEidsArray(userId); - expect(newEids.length).to.equal(0); - }); - - it('eids array generation for known sub-module with non-string value', function() { - // pubCommonId - let userId = { - pubcid: undefined - }; - let newEids = createEidsArray(userId); - expect(newEids.length).to.equal(0); - userId.pubcid = 123; - newEids = createEidsArray(userId); - expect(newEids.length).to.equal(0); - userId.pubcid = []; - newEids = createEidsArray(userId); - expect(newEids.length).to.equal(0); - userId.pubcid = {}; - newEids = createEidsArray(userId); - expect(newEids.length).to.equal(0); - userId.pubcid = null; - newEids = createEidsArray(userId); - expect(newEids.length).to.equal(0); - }); -}); diff --git a/test/spec/modules/emoteevBidAdapter_spec.js b/test/spec/modules/emoteevBidAdapter_spec.js deleted file mode 100644 index 43ae62f1eb9..00000000000 --- a/test/spec/modules/emoteevBidAdapter_spec.js +++ /dev/null @@ -1,876 +0,0 @@ -import { - assert, expect -} from 'chai'; -import { - ADAPTER_VERSION, - DOMAIN, - DOMAIN_DEVELOPMENT, - DOMAIN_STAGING, - domain, - BIDDER_PATH, - bidderUrl, - buildRequests, - conformBidRequest, - DEFAULT_ENV, - DEVELOPMENT, - EVENTS_PATH, - eventsUrl, - FOOTER, - gdprConsent, - getDeviceDimensions, - getDeviceInfo, - getDocumentDimensions, - getUserSyncs, - getViewDimensions, - IN_CONTENT, - interpretResponse, - isBidRequestValid, - ON_ADAPTER_CALLED, - ON_BID_WON, - ON_BIDDER_TIMEOUT, - onBidWon, - onAdapterCalled, - onTimeout, - OVERLAY, - PRODUCTION, - requestsPayload, - resolveDebug, - resolveEnv, - spec, - STAGING, - USER_SYNC_IFRAME_PATH, - USER_SYNC_IMAGE_PATH, - userSyncIframeUrl, - userSyncImageUrl, - validateSizes, - validateContext, - validateExternalId, - VENDOR_ID, - WALLPAPER, - storage -} from 'modules/emoteevBidAdapter.js'; -import * as utils from '../../../src/utils.js'; -import {config} from '../../../src/config.js'; - -const cannedValidBidRequests = [{ - adUnitCode: '/19968336/header-bid-tag-1', - auctionId: 'fcbf2b27-a951-496f-b5bb-1324ce7c0558', - bidId: '2b8de6572e8193', - bidRequestsCount: 1, - bidder: 'emoteev', - bidderRequestId: '1203b39fecc6a5', - crumbs: {pubcid: 'f3371d16-4e8b-42b5-a770-7e5be1fdf03d'}, - params: { - adSpaceId: 5084, - context: IN_CONTENT, - externalId: 42 - }, - sizes: [[300, 250], [250, 300], [300, 600]], - transactionId: '58dbd732-7a39-45f1-b23e-1c24051a941c', -}]; -const cannedBidderRequest = { - auctionId: 'fcbf2b27-a951-496f-b5bb-1324ce7c0558', - auctionStart: 1544200122837, - bidderCode: 'emoteev', - bidderRequestId: '1203b39fecc6a5', - doneCbCallCount: 0, - refererInfo: { - canonicalUrl: undefined, - numIframes: 0, - reachedTop: true, - referer: 'https://localhost:9999/integrationExamples/gpt/hello_world_emoteev.html', - stack: ['https://localhost:9999/integrationExamples/gpt/hello_world_emoteev.html'] - }, - start: 1544200012839, - timeout: 3000, - gdprConsent: { - gdprApplies: true, - vendorData: {vendorConsents: {[VENDOR_ID]: true}}, - } -}; -const serverResponse = - { - body: [ - { - requestId: cannedValidBidRequests[0].bidId, - cpm: 1, - width: cannedValidBidRequests[0].sizes[0][0], - height: cannedValidBidRequests[0].sizes[0][1], - ad: '
', - ttl: 360, - creativeId: 123, - netRevenue: false, - currency: 'EUR', - } - ] - }; - -describe('emoteevBidAdapter', function () { - describe('isBidRequestValid', function () { - it('should return true when valid', function () { - const validBid = { - bidder: 'emoteev', - bidId: '23a45b4e3', - params: { - adSpaceId: 12345, - context: IN_CONTENT, - externalId: 42 - }, - mediaTypes: { - banner: { - sizes: [[750, 200]] - } - }, - }; - expect(isBidRequestValid(validBid)).to.equal(true); - - expect(spec.isBidRequestValid(validBid)).to.exist.and.to.be.a('boolean'); - expect(spec.isBidRequestValid({})).to.exist.and.to.be.a('boolean'); - }); - - it('should return false when required params are invalid', function () { - expect(isBidRequestValid({ - bidder: '', // invalid bidder - params: { - adSpaceId: 12345, - context: IN_CONTENT, - externalId: 42 - }, - mediaTypes: { - banner: { - sizes: [[750, 200]] - } - }, - })).to.equal(false); - expect(isBidRequestValid({ - bidder: 'emoteev', - params: { - adSpaceId: '', // invalid adSpaceId - context: IN_CONTENT, - externalId: 42 - }, - mediaTypes: { - banner: { - sizes: [[750, 200]] - } - }, - })).to.equal(false); - expect(isBidRequestValid({ - bidder: 'emoteev', - params: { - adSpaceId: 12345, - context: 'something', // invalid context - externalId: 42 - }, - mediaTypes: { - banner: { - sizes: [[750, 200]] - } - }, - })).to.equal(false); - expect(isBidRequestValid({ - bidder: 'emoteev', - params: { - adSpaceId: 12345, - context: IN_CONTENT, - externalId: 'lol' // invalid externalId - }, - mediaTypes: { - banner: { - sizes: [[750, 200]] - } - }, - })).to.equal(false); - expect(isBidRequestValid({ - bidder: 'emoteev', - params: { - adSpaceId: 12345, - context: IN_CONTENT, - externalId: 42 - }, - mediaTypes: { - banner: { - sizes: [[750]] // invalid size - } - }, - })).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const - env = DEFAULT_ENV, - debug = true, - currency = 'EUR', - request = buildRequests(env, debug, currency, cannedValidBidRequests, cannedBidderRequest); - - expect(request).to.exist.and.have.all.keys( - 'method', - 'url', - 'data', - ); - - expect(request.method).to.equal('POST'); - expect(request.url).to.equal(bidderUrl(env)); - - expect(spec.buildRequests(cannedValidBidRequests, cannedBidderRequest)).to.exist.and.to.be.an('object'); - }); - - describe('interpretResponse', function () { - it('bid objects from response', function () { - const bidResponses = interpretResponse(serverResponse); - expect(bidResponses).to.be.an('array').that.is.not.empty; - expect(bidResponses[0]).to.have.property('requestId', cannedValidBidRequests[0].bidId); - expect(bidResponses[0]).to.have.property('cpm', serverResponse.body[0].cpm); - expect(bidResponses[0]).to.have.property('width', serverResponse.body[0].width); - expect(bidResponses[0]).to.have.property('height', serverResponse.body[0].height); - expect(bidResponses[0]).to.have.property('ad', serverResponse.body[0].ad); - expect(bidResponses[0]).to.have.property('ttl', serverResponse.body[0].ttl); - expect(bidResponses[0]).to.have.property('creativeId', serverResponse.body[0].creativeId); - expect(bidResponses[0]).to.have.property('netRevenue', serverResponse.body[0].netRevenue); - expect(bidResponses[0]).to.have.property('currency', serverResponse.body[0].currency); - }); - }); - - describe('onAdapterCalled', function () { - const - bidRequest = cannedValidBidRequests[0], - url = onAdapterCalled(DEFAULT_ENV, bidRequest); - - expect(url).to.have.property('protocol'); - expect(url).to.have.property('hostname'); - expect(url).to.have.property('pathname', EVENTS_PATH); - expect(url).to.have.nested.property('search.eventName', ON_ADAPTER_CALLED); - expect(url).to.have.nested.property('search.pubcId', bidRequest.crumbs.pubcid); - expect(url).to.have.nested.property('search.bidId', bidRequest.bidId); - expect(url).to.have.nested.property('search.adSpaceId', bidRequest.params.adSpaceId); - expect(url).to.have.nested.property('search.cache_buster'); - }); - - describe('onBidWon', function () { - const - pubcId = cannedValidBidRequests[0].crumbs.pubcid, - bidObject = serverResponse.body[0], - url = onBidWon(DEFAULT_ENV, pubcId, bidObject); - - expect(url).to.have.property('protocol'); - expect(url).to.have.property('hostname'); - expect(url).to.have.property('pathname', EVENTS_PATH); - expect(url).to.have.nested.property('search.eventName', ON_BID_WON); - expect(url).to.have.nested.property('search.pubcId', pubcId); - expect(url).to.have.nested.property('search.bidId', bidObject.requestId); - expect(url).to.have.nested.property('search.cache_buster'); - }); - - describe('onTimeout', function () { - const - data = { - ...cannedValidBidRequests[0], - timeout: 123, - }, - url = onTimeout(DEFAULT_ENV, data); - - expect(url).to.have.property('protocol'); - expect(url).to.have.property('hostname'); - expect(url).to.have.property('pathname', EVENTS_PATH); - expect(url).to.have.nested.property('search.eventName', ON_BIDDER_TIMEOUT); - expect(url).to.have.nested.property('search.bidId', data.bidId); - expect(url).to.have.nested.property('search.pubcId', data.crumbs.pubcid); - expect(url).to.have.nested.property('search.adSpaceId', data.params.adSpaceId); - expect(url).to.have.nested.property('search.timeout', data.timeout); - expect(url).to.have.nested.property('search.cache_buster'); - }); - - describe('getUserSyncs', function () { - expect(getUserSyncs( - DEFAULT_ENV, - { - iframeEnabled: false, - pixelEnabled: false - })).to.deep.equal([]); - expect(getUserSyncs( - PRODUCTION, - { - iframeEnabled: false, - pixelEnabled: true - })).to.deep.equal([{ - type: 'image', - url: userSyncImageUrl(PRODUCTION) - }]); - expect(getUserSyncs( - STAGING, - { - iframeEnabled: true, - pixelEnabled: false - })).to.deep.equal([{ - type: 'iframe', - url: userSyncIframeUrl(STAGING) - }]); - expect(getUserSyncs( - DEVELOPMENT, - { - iframeEnabled: true, - pixelEnabled: true - })).to.deep.equal([{ - type: 'image', - url: userSyncImageUrl(DEVELOPMENT) - }, { - type: 'iframe', - url: userSyncIframeUrl(DEVELOPMENT) - }]); - }); - - describe('domain', function () { - expect(domain(null)).to.deep.equal(DOMAIN); - expect(domain('anything')).to.deep.equal(DOMAIN); - expect(domain(PRODUCTION)).to.deep.equal(DOMAIN); - expect(domain(STAGING)).to.deep.equal(DOMAIN_STAGING); - expect(domain(DEVELOPMENT)).to.deep.equal(DOMAIN_DEVELOPMENT); - }); - - describe('eventsUrl', function () { - expect(eventsUrl(null)).to.deep.equal(utils.buildUrl({ - protocol: 'https', - hostname: domain(DEFAULT_ENV), - pathname: EVENTS_PATH - })); - expect(eventsUrl('anything')).to.deep.equal(utils.buildUrl({ - protocol: 'https', - hostname: domain(DEFAULT_ENV), - pathname: EVENTS_PATH - })); - expect(eventsUrl(PRODUCTION)).to.deep.equal(utils.buildUrl({ - protocol: 'https', - hostname: domain(PRODUCTION), - pathname: EVENTS_PATH - })); - expect(eventsUrl(STAGING)).to.deep.equal(utils.buildUrl({ - protocol: 'https', - hostname: domain(STAGING), - pathname: EVENTS_PATH - })); - expect(eventsUrl(DEVELOPMENT)).to.deep.equal(utils.buildUrl({ - hostname: domain(DEVELOPMENT), - pathname: EVENTS_PATH - })); - }); - - describe('bidderUrl', function () { - expect(bidderUrl(null)).to.deep.equal(utils.buildUrl({ - protocol: 'https', - hostname: domain(DEFAULT_ENV), - pathname: BIDDER_PATH - })); - expect(bidderUrl('anything')).to.deep.equal(utils.buildUrl({ - protocol: 'https', - hostname: domain(DEFAULT_ENV), - pathname: BIDDER_PATH - })); - expect(bidderUrl(PRODUCTION)).to.deep.equal(utils.buildUrl({ - protocol: 'https', - hostname: domain(PRODUCTION), - pathname: BIDDER_PATH - })); - expect(bidderUrl(STAGING)).to.deep.equal(utils.buildUrl({ - protocol: 'https', - hostname: domain(STAGING), - pathname: BIDDER_PATH - })); - expect(bidderUrl(DEVELOPMENT)).to.deep.equal(utils.buildUrl({ - hostname: domain(DEVELOPMENT), - pathname: BIDDER_PATH - })); - }); - - describe('userSyncIframeUrl', function () { - expect(userSyncIframeUrl(null)).to.deep.equal(utils.buildUrl({ - protocol: 'https', - hostname: domain(DEFAULT_ENV), - pathname: USER_SYNC_IFRAME_PATH - })); - expect(userSyncIframeUrl('anything')).to.deep.equal(utils.buildUrl({ - protocol: 'https', - hostname: domain(DEFAULT_ENV), - pathname: USER_SYNC_IFRAME_PATH - })); - expect(userSyncIframeUrl(PRODUCTION)).to.deep.equal(utils.buildUrl({ - protocol: 'https', - hostname: domain(PRODUCTION), - pathname: USER_SYNC_IFRAME_PATH - })); - expect(userSyncIframeUrl(STAGING)).to.deep.equal(utils.buildUrl({ - protocol: 'https', - hostname: domain(STAGING), - pathname: USER_SYNC_IFRAME_PATH - })); - expect(userSyncIframeUrl(DEVELOPMENT)).to.deep.equal(utils.buildUrl({ - hostname: domain(DEVELOPMENT), - pathname: USER_SYNC_IFRAME_PATH - })); - }); - - describe('userSyncImageUrl', function () { - expect(userSyncImageUrl(null)).to.deep.equal(utils.buildUrl({ - protocol: 'https', - hostname: domain(DEFAULT_ENV), - pathname: USER_SYNC_IMAGE_PATH - })); - expect(userSyncImageUrl('anything')).to.deep.equal(utils.buildUrl({ - protocol: 'https', - hostname: domain(DEFAULT_ENV), - pathname: USER_SYNC_IMAGE_PATH - })); - expect(userSyncImageUrl(PRODUCTION)).to.deep.equal(utils.buildUrl({ - protocol: 'https', - hostname: domain(PRODUCTION), - pathname: USER_SYNC_IMAGE_PATH - })); - expect(userSyncImageUrl(STAGING)).to.deep.equal(utils.buildUrl({ - protocol: 'https', - hostname: domain(STAGING), - pathname: USER_SYNC_IMAGE_PATH - })); - expect(userSyncImageUrl(DEVELOPMENT)).to.deep.equal(utils.buildUrl({ - hostname: domain(DEVELOPMENT), - pathname: USER_SYNC_IMAGE_PATH - })); - }); - - describe('conformBidRequest', function () { - expect(conformBidRequest(cannedValidBidRequests[0])).to.deep.equal({ - params: cannedValidBidRequests[0].params, - crumbs: cannedValidBidRequests[0].crumbs, - sizes: cannedValidBidRequests[0].sizes, - bidId: cannedValidBidRequests[0].bidId, - bidderRequestId: cannedValidBidRequests[0].bidderRequestId, - }); - }); - - describe('gdprConsent', function () { - describe('gdpr applies, consent given', function () { - const bidderRequest = { - ...cannedBidderRequest, - gdprConsent: { - gdprApplies: true, - vendorData: {vendorConsents: {[VENDOR_ID]: true}}, - } - }; - expect(gdprConsent(bidderRequest)).to.deep.equal(true); - }); - describe('gdpr applies, consent withdrawn', function () { - const bidderRequest = { - ...cannedBidderRequest, - gdprConsent: { - gdprApplies: true, - vendorData: {vendorConsents: {[VENDOR_ID]: false}}, - } - }; - expect(gdprConsent(bidderRequest)).to.deep.equal(false); - }); - describe('gdpr applies, consent unknown', function () { - const bidderRequest = { - ...cannedBidderRequest, - gdprConsent: { - gdprApplies: true, - vendorData: {}, - } - }; - expect(gdprConsent(bidderRequest)).to.deep.equal(undefined); - }); - }); - - describe('requestsPayload', function () { - const - currency = 'EUR', - debug = true; - - const payload = requestsPayload(debug, currency, cannedValidBidRequests, cannedBidderRequest); - - expect(payload).to.exist.and.have.all.keys( - 'akPbjsVersion', - 'bidRequests', - 'currency', - 'debug', - 'language', - 'refererInfo', - 'deviceInfo', - 'userAgent', - 'gdprApplies', - 'gdprConsent', - ); - - expect(payload.bidRequests[0]).to.exist.and.have.all.keys( - 'params', - 'crumbs', - 'sizes', - 'bidId', - 'bidderRequestId', - ); - - expect(payload.akPbjsVersion).to.deep.equal(ADAPTER_VERSION); - expect(payload.bidRequests[0].params).to.deep.equal(cannedValidBidRequests[0].params); - expect(payload.bidRequests[0].crumbs).to.deep.equal(cannedValidBidRequests[0].crumbs); - expect(payload.bidRequests[0].mediaTypes).to.deep.equal(cannedValidBidRequests[0].mediaTypes); - expect(payload.bidRequests[0].bidId).to.deep.equal(cannedValidBidRequests[0].bidId); - expect(payload.bidRequests[0].bidderRequestId).to.deep.equal(cannedValidBidRequests[0].bidderRequestId); - expect(payload.currency).to.deep.equal(currency); - expect(payload.debug).to.deep.equal(debug); - expect(payload.language).to.deep.equal(navigator.language); - expect(payload.deviceInfo).to.exist.and.have.all.keys( - 'browserWidth', - 'browserHeight', - 'deviceWidth', - 'deviceHeight', - 'documentWidth', - 'documentHeight', - 'webGL', - ); - expect(payload.userAgent).to.deep.equal(navigator.userAgent); - expect(payload.gdprApplies).to.deep.equal(cannedBidderRequest.gdprConsent.gdprApplies); - }); - - describe('getViewDimensions', function () { - const window = { - innerWidth: 1024, - innerHeight: 768 - }; - const documentWithElement = { - documentElement: - { - clientWidth: 512, - clientHeight: 384 - } - }; - const documentWithBody = { - body: - { - clientWidth: 512, - clientHeight: 384 - } - }; - expect(getViewDimensions(window, documentWithElement)).to.deep.equal({ - width: 1024, - height: 768 - }); - expect(getViewDimensions(window, documentWithBody)).to.deep.equal({width: 1024, height: 768}); - expect(getViewDimensions(window, documentWithElement)).to.deep.equal({ - width: 1024, - height: 768 - }); - expect(getViewDimensions(window, documentWithBody)).to.deep.equal({width: 1024, height: 768}); - expect(getViewDimensions({}, documentWithElement)).to.deep.equal({width: 512, height: 384}); - expect(getViewDimensions({}, documentWithBody)).to.deep.equal({width: 512, height: 384}); - }); - - describe('getDeviceDimensions', function () { - const window = {screen: {width: 1024, height: 768}}; - expect(getDeviceDimensions(window)).to.deep.equal({width: 1024, height: 768}); - expect(getDeviceDimensions({})).to.deep.equal({width: '', height: ''}); - }); - - describe('getDocumentDimensions', function () { - expect(getDocumentDimensions({ - documentElement: { - clientWidth: 1, - clientHeight: 1, - offsetWidth: 0, - offsetHeight: 0, - scrollWidth: 0, - scrollHeight: 0, - }, - })).to.deep.equal({width: 1, height: 1}); - - expect(getDocumentDimensions({ - documentElement: { - clientWidth: 1, - clientHeight: 1, - offsetWidth: 0, - offsetHeight: 0, - scrollWidth: 0, - scrollHeight: 0, - }, - body: { - scrollHeight: 0, - offsetHeight: 0, - } - })).to.deep.equal({width: 1, height: 1}); - - expect(getDocumentDimensions({ - documentElement: { - clientWidth: 0, - clientHeight: 0, - offsetWidth: 1, - offsetHeight: 1, - scrollWidth: 0, - scrollHeight: 0, - }, - body: { - scrollHeight: 0, - offsetHeight: 0, - } - })).to.deep.equal({width: 1, height: 1}); - - expect(getDocumentDimensions({ - documentElement: { - clientWidth: 0, - clientHeight: 0, - offsetWidth: 0, - offsetHeight: 0, - scrollWidth: 1, - scrollHeight: 1, - }, - body: { - scrollHeight: 0, - offsetHeight: 0, - } - })).to.deep.equal({width: 1, height: 1}); - - expect(getDocumentDimensions({ - documentElement: { - clientWidth: undefined, - clientHeight: undefined, - offsetWidth: undefined, - offsetHeight: undefined, - scrollWidth: undefined, - scrollHeight: undefined, - }, - body: { - scrollHeight: undefined, - offsetHeight: undefined, - } - })).to.deep.equal({width: '', height: ''}); - }); - - // describe('isWebGLEnabled', function () { - // it('handles no webgl', function () { - // const - // document = new Document(), - // canvas = sinon.createStubInstance(HTMLCanvasElement); - // sinon.stub(document, 'createElement').withArgs('canvas').returns(canvas); - // canvas.getContext.withArgs('webgl').returns(undefined); - // canvas.getContext.withArgs('experimental-webgl').returns(undefined); - // expect(isWebGLEnabled(document)).to.equal(false); - // }); - // - // it('handles webgl exception', function () { - // const - // document = new Document(), - // canvas = sinon.createStubInstance(HTMLCanvasElement); - // sinon.stub(document, 'createElement').withArgs('canvas').returns(canvas); - // canvas.getContext.withArgs('webgl').throws(DOMException); - // expect(isWebGLEnabled(document)).to.equal(false); - // }); - // - // it('handles experimental webgl', function () { - // const - // document = new Document(), - // canvas = sinon.createStubInstance(HTMLCanvasElement); - // sinon.stub(document, 'createElement').withArgs('canvas').returns(canvas); - // canvas.getContext.withArgs('webgl').returns(undefined); - // canvas.getContext.withArgs('experimental-webgl').returns(true); - // expect(isWebGLEnabled(document)).to.equal(true); - // }); - // - // it('handles experimental webgl exception', function () { - // const - // document = new Document(), - // canvas = sinon.createStubInstance(HTMLCanvasElement); - // sinon.stub(document, 'createElement').withArgs('canvas').returns(canvas); - // canvas.getContext.withArgs('webgl').returns(undefined); - // canvas.getContext.withArgs('experimental-webgl').throws(DOMException); - // expect(isWebGLEnabled(document)).to.equal(false); - // }); - // - // it('handles webgl', function () { - // const - // document = new Document(), - // canvas = sinon.createStubInstance(HTMLCanvasElement); - // sinon.stub(document, 'createElement').withArgs('canvas').returns(canvas); - // canvas.getContext.withArgs('webgl').returns(true); - // expect(isWebGLEnabled(document)).to.equal(true); - // }); - // }); - - describe('getDeviceInfo', function () { - expect(getDeviceInfo( - {width: 1, height: 2}, - {width: 3, height: 4}, - {width: 5, height: 6}, - true - )).to.deep.equal({ - deviceWidth: 1, - deviceHeight: 2, - browserWidth: 3, - browserHeight: 4, - documentWidth: 5, - documentHeight: 6, - webGL: true - }); - }); - - describe('resolveEnv', function () { - it('defaults to production', function () { - expect(resolveEnv({}, null)).to.deep.equal(DEFAULT_ENV); - }); - expect(resolveEnv({}, PRODUCTION)).to.deep.equal(PRODUCTION); - expect(resolveEnv({}, STAGING)).to.deep.equal(STAGING); - expect(resolveEnv({}, DEVELOPMENT)).to.deep.equal(DEVELOPMENT); - expect(resolveEnv({emoteev: {env: PRODUCTION}}, null)).to.deep.equal(PRODUCTION); - expect(resolveEnv({emoteev: {env: STAGING}}, null)).to.deep.equal(STAGING); - expect(resolveEnv({emoteev: {env: DEVELOPMENT}}, null)).to.deep.equal(DEVELOPMENT); - it('prioritizes parameter over configuration', function () { - expect(resolveEnv({emoteev: {env: STAGING}}, DEVELOPMENT)).to.deep.equal(DEVELOPMENT); - }); - }); - - describe('resolveDebug', function () { - it('defaults to production', function () { - expect(resolveDebug({}, null)).to.deep.equal(false); - }); - expect(resolveDebug({}, 'false')).to.deep.equal(false); - expect(resolveDebug({}, 'true')).to.deep.equal(true); - expect(resolveDebug({debug: true}, null)).to.deep.equal(true); - it('prioritizes parameter over configuration', function () { - expect(resolveDebug({debug: true}, 'false')).to.deep.equal(false); - }); - }); - - describe('side effects', function () { - let triggerPixelStub; - let getCookieSpy; - let getConfigSpy; - let getParameterByNameSpy; - - before(function() { - config.resetConfig(); - }); - after(function() { - config.resetConfig(); - }); - beforeEach(function () { - triggerPixelStub = sinon.stub(utils, 'triggerPixel'); - getCookieSpy = sinon.spy(storage, 'getCookie'); - getConfigSpy = sinon.spy(config, 'getConfig'); - getParameterByNameSpy = sinon.spy(utils, 'getParameterByName'); - }); - afterEach(function () { - triggerPixelStub.restore(); - getCookieSpy.restore(); - getConfigSpy.restore(); - getParameterByNameSpy.restore(); - }); - - describe('isBidRequestValid', function () { - it('has intended side-effects', function () { - const validBidRequest = { - bidder: 'emoteev', - bidId: '23a45b4e3', - params: { - adSpaceId: 12345, - }, - mediaTypes: { - banner: { - sizes: [[750, 200]] - } - }, - }; - spec.isBidRequestValid(validBidRequest); - sinon.assert.notCalled(utils.triggerPixel); - sinon.assert.notCalled(storage.getCookie); - // sinon.assert.notCalled(config.getConfig); - sinon.assert.notCalled(utils.getParameterByName); - }); - }); - describe('isBidRequestValid empty request', function() { - it('has intended side-effects empty request', function () { - const invalidBidRequest = {}; - spec.isBidRequestValid(invalidBidRequest); - sinon.assert.notCalled(utils.triggerPixel); - sinon.assert.notCalled(storage.getCookie); - // disabling these getConfig tests as they have been flaky in browserstack testing - // sinon.assert.notCalled(config.getConfig); - sinon.assert.notCalled(utils.getParameterByName); - }); - }); - describe('buildRequests', function () { - it('has intended side-effects', function () { - spec.buildRequests(cannedValidBidRequests, cannedBidderRequest); - sinon.assert.notCalled(utils.triggerPixel); - sinon.assert.notCalled(storage.getCookie); - // sinon.assert.callCount(config.getConfig, 3); - sinon.assert.callCount(utils.getParameterByName, 2); - }); - }); - describe('interpretResponse', function () { - it('has intended side-effects', function () { - spec.interpretResponse(serverResponse); - sinon.assert.notCalled(utils.triggerPixel); - sinon.assert.notCalled(storage.getCookie); - // sinon.assert.notCalled(config.getConfig); - sinon.assert.notCalled(utils.getParameterByName); - }); - }); - describe('onBidWon', function () { - it('has intended side-effects', function () { - const bidObject = serverResponse.body[0]; - spec.onBidWon(bidObject); - sinon.assert.calledOnce(utils.triggerPixel); - sinon.assert.calledOnce(storage.getCookie); - // sinon.assert.calledOnce(config.getConfig); - sinon.assert.calledOnce(utils.getParameterByName); - }); - }); - describe('onTimeout', function () { - it('has intended side-effects', function () { - spec.onTimeout(cannedValidBidRequests[0]); - sinon.assert.calledOnce(utils.triggerPixel); - sinon.assert.notCalled(storage.getCookie); - // sinon.assert.calledOnce(config.getConfig); - sinon.assert.calledOnce(utils.getParameterByName); - }); - }); - describe('getUserSyncs', function () { - it('has intended side-effects', function () { - spec.getUserSyncs({}); - sinon.assert.notCalled(utils.triggerPixel); - sinon.assert.notCalled(storage.getCookie); - // sinon.assert.calledOnce(config.getConfig); - sinon.assert.calledOnce(utils.getParameterByName); - }); - }); - }); - - describe('validateSizes', function () { - it('only accepts valid array of sizes', function () { - expect(validateSizes([])).to.deep.equal(false); - expect(validateSizes([[]])).to.deep.equal(false); - expect(validateSizes([[450, 450], undefined])).to.deep.equal(false); - expect(validateSizes([[450, 450], 'size'])).to.deep.equal(false); - expect(validateSizes([[1, 1]])).to.deep.equal(true); - expect(validateSizes([[1, 1], [450, 450]])).to.deep.equal(true); - }); - }); - - describe('validateContext', function () { - it('only accepts valid context', function () { - expect(validateContext(IN_CONTENT)).to.deep.equal(true); - expect(validateContext(FOOTER)).to.deep.equal(true); - expect(validateContext(OVERLAY)).to.deep.equal(true); - expect(validateContext(WALLPAPER)).to.deep.equal(true); - expect(validateContext(null)).to.deep.equal(false); - expect(validateContext('anything else')).to.deep.equal(false); - }); - }); - - describe('validateExternalId', function () { - it('only accepts a positive integer or null', function () { - expect(validateExternalId(0)).to.deep.equal(false); - expect(validateExternalId(42)).to.deep.equal(true); - expect(validateExternalId(42.0)).to.deep.equal(true); // edge case: valid externalId - expect(validateExternalId(3.14159)).to.deep.equal(false); - expect(validateExternalId('externalId')).to.deep.equal(false); - expect(validateExternalId(undefined)).to.deep.equal(true); - expect(validateExternalId(null)).to.deep.equal(true); - }); - }); -}); diff --git a/test/spec/modules/emx_digitalBidAdapter_spec.js b/test/spec/modules/emx_digitalBidAdapter_spec.js deleted file mode 100644 index 855ffa0a0b7..00000000000 --- a/test/spec/modules/emx_digitalBidAdapter_spec.js +++ /dev/null @@ -1,655 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/emx_digitalBidAdapter.js'; -import * as utils from 'src/utils.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('emx_digital Adapter', function () { - describe('callBids', function () { - const adapter = newBidder(spec); - it('exists and is a function', function () { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - describe('banner request validity', function () { - let bid = { - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25251' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c2501de1e', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }; - let badBid = { - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25251' - }, - 'mediaTypes': { - 'banner': { - } - }, - 'adUnitCode': 'adunit-code', - 'bidId': '30b31c2501de1e', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }; - let noBid = {}; - let otherBid = { - 'bidder': 'emxdigital', - 'params': { - 'tagid': '25251' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c2501de1e', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }; - let noMediaSizeBid = { - 'bidder': 'emxdigital', - 'params': { - 'tagid': '25251' - }, - 'mediaTypes': { - 'banner': {} - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c2501de1e', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - expect(spec.isBidRequestValid(badBid)).to.equal(false); - expect(spec.isBidRequestValid(noBid)).to.equal(false); - expect(spec.isBidRequestValid(otherBid)).to.equal(false); - expect(spec.isBidRequestValid(noMediaSizeBid)).to.equal(false); - }); - }); - - describe('video request validity', function () { - let bid = { - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25251', - 'video': {} - }, - 'mediaTypes': { - 'video': { - 'context': 'instream', - 'playerSize': [640, 480] - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c2501de1e', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }; - let noInstreamBid = { - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25251', - 'video': { - 'protocols': [1, 7] - } - }, - 'mediaTypes': { - 'video': { - 'context': 'something_random' - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c2501de1e', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }; - - let outstreamBid = { - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25251', - 'video': {} - }, - 'mediaTypes': { - 'video': { - 'context': 'outstream', - 'playerSize': [640, 480] - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c2501de1e', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - expect(spec.isBidRequestValid(noInstreamBid)).to.equal(false); - expect(spec.isBidRequestValid(outstreamBid)).to.equal(true); - }); - - it('should contain tagid param', function () { - expect(spec.isBidRequestValid({ - bidder: 'emx_digital', - params: {}, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - } - })).to.equal(false); - expect(spec.isBidRequestValid({ - bidder: 'emx_digital', - params: { - tagid: '' - }, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - } - })).to.equal(false); - expect(spec.isBidRequestValid({ - bidder: 'emx_digital', - params: { - tagid: '123' - }, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - } - })).to.equal(true); - }); - }); - }); - - describe('buildRequests', function () { - let bidderRequest = { - 'bidderCode': 'emx_digital', - 'auctionId': 'e19f1eff-8b27-42a6-888d-9674e5a6130c', - 'bidderRequestId': '22edbae3120bf6', - 'timeout': 1500, - 'refererInfo': { - 'numIframes': 0, - 'reachedTop': true, - 'referer': 'https://example.com/index.html?pbjs_debug=true' - }, - 'bids': [{ - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25251' - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [300, 250], - [300, 600] - ] - } - }, - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c2501de1e', - 'auctionId': 'e19f1eff-8b27-42a6-888d-9674e5a6130c', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - }] - }; - let request = spec.buildRequests(bidderRequest.bids, bidderRequest); - - it('sends bid request to ENDPOINT via POST', function () { - expect(request.method).to.equal('POST'); - }); - - it('contains the correct options', function () { - expect(request.options.withCredentials).to.equal(true); - }); - - it('contains a properly formatted endpoint url', function () { - const url = request.url.split('?'); - const queryParams = url[1].split('&'); - expect(queryParams[0]).to.match(new RegExp('^t=\d*', 'g')); - expect(queryParams[1]).to.match(new RegExp('^ts=\d*', 'g')); - }); - - it('builds with bid floor', function () { - const bidRequestWithBidFloor = utils.deepClone(bidderRequest.bids); - bidRequestWithBidFloor[0].params.bidfloor = 1; - const requestWithFloor = spec.buildRequests(bidRequestWithBidFloor, bidderRequest); - const data = JSON.parse(requestWithFloor.data); - expect(data.imp[0].bidfloor).to.equal(bidRequestWithBidFloor[0].params.bidfloor); - }); - - it('builds request properly', function () { - const data = JSON.parse(request.data); - expect(Array.isArray(data.imp)).to.equal(true); - expect(data.id).to.equal(bidderRequest.auctionId); - expect(data.imp.length).to.equal(1); - expect(data.imp[0].id).to.equal('30b31c2501de1e'); - expect(data.imp[0].tid).to.equal('d7b773de-ceaa-484d-89ca-d9f51b8d61ec'); - expect(data.imp[0].tagid).to.equal('25251'); - expect(data.imp[0].secure).to.equal(0); - expect(data.imp[0].vastXml).to.equal(undefined); - }); - - it('properly sends site information and protocol', function () { - request = spec.buildRequests(bidderRequest.bids, bidderRequest); - request = JSON.parse(request.data); - expect(request.site).to.have.property('domain', 'example.com'); - expect(request.site).to.have.property('page', 'https://example.com/index.html?pbjs_debug=true'); - expect(request.site).to.have.property('ref', window.top.document.referrer); - }); - - it('builds correctly formatted request banner object', function () { - let bidRequestWithBanner = utils.deepClone(bidderRequest.bids); - let request = spec.buildRequests(bidRequestWithBanner, bidderRequest); - const data = JSON.parse(request.data); - expect(data.imp[0].video).to.equal(undefined); - expect(data.imp[0].banner).to.exist.and.to.be.a('object'); - expect(data.imp[0].banner.w).to.equal(bidRequestWithBanner[0].mediaTypes.banner.sizes[0][0]); - expect(data.imp[0].banner.h).to.equal(bidRequestWithBanner[0].mediaTypes.banner.sizes[0][1]); - expect(data.imp[0].banner.format[0].w).to.equal(bidRequestWithBanner[0].mediaTypes.banner.sizes[0][0]); - expect(data.imp[0].banner.format[0].h).to.equal(bidRequestWithBanner[0].mediaTypes.banner.sizes[0][1]); - expect(data.imp[0].banner.format[1].w).to.equal(bidRequestWithBanner[0].mediaTypes.banner.sizes[1][0]); - expect(data.imp[0].banner.format[1].h).to.equal(bidRequestWithBanner[0].mediaTypes.banner.sizes[1][1]); - }); - - it('builds correctly formatted request video object for instream', function () { - let bidRequestWithVideo = utils.deepClone(bidderRequest.bids); - bidRequestWithVideo[0].mediaTypes = { - video: { - context: 'instream', - playerSize: [[640, 480]] - }, - }; - bidRequestWithVideo[0].params.video = {}; - let request = spec.buildRequests(bidRequestWithVideo, bidderRequest); - const data = JSON.parse(request.data); - expect(data.imp[0].video).to.exist.and.to.be.a('object'); - expect(data.imp[0].video.w).to.equal(bidRequestWithVideo[0].mediaTypes.video.playerSize[0][0]); - expect(data.imp[0].video.h).to.equal(bidRequestWithVideo[0].mediaTypes.video.playerSize[0][1]); - }); - - it('builds correctly formatted request video object for outstream', function () { - let bidRequestWithOutstreamVideo = utils.deepClone(bidderRequest.bids); - bidRequestWithOutstreamVideo[0].mediaTypes = { - video: { - context: 'outstream', - playerSize: [[640, 480]] - }, - }; - bidRequestWithOutstreamVideo[0].params.video = {}; - let request = spec.buildRequests(bidRequestWithOutstreamVideo, bidderRequest); - const data = JSON.parse(request.data); - expect(data.imp[0].video).to.exist.and.to.be.a('object'); - expect(data.imp[0].video.w).to.equal(bidRequestWithOutstreamVideo[0].mediaTypes.video.playerSize[0][0]); - expect(data.imp[0].video.h).to.equal(bidRequestWithOutstreamVideo[0].mediaTypes.video.playerSize[0][1]); - }); - - it('shouldn\'t contain a user obj without GDPR information', function () { - let request = spec.buildRequests(bidderRequest.bids, bidderRequest) - request = JSON.parse(request.data) - expect(request).to.not.have.property('user'); - }); - - it('should have the right gdpr info when enabled', function () { - let consentString = 'OIJSZsOAFsABAB8EMXZZZZZ+A=='; - const gdprBidderRequest = utils.deepClone(bidderRequest); - gdprBidderRequest.gdprConsent = { - 'consentString': consentString, - 'gdprApplies': true - }; - let request = spec.buildRequests(gdprBidderRequest.bids, gdprBidderRequest); - - request = JSON.parse(request.data) - expect(request.regs.ext).to.have.property('gdpr', 1); - expect(request.user.ext).to.have.property('consent', consentString); - }); - - it('should\'t contain consent string if gdpr isn\'t applied', function () { - const nonGdprBidderRequest = utils.deepClone(bidderRequest); - nonGdprBidderRequest.gdprConsent = { - 'gdprApplies': false - }; - let request = spec.buildRequests(nonGdprBidderRequest.bids, nonGdprBidderRequest); - request = JSON.parse(request.data) - expect(request.regs.ext).to.have.property('gdpr', 0); - expect(request).to.not.have.property('user'); - }); - - it('should add us privacy info to request', function() { - const uspBidderRequest = utils.deepClone(bidderRequest); - let consentString = '1YNN'; - uspBidderRequest.uspConsent = consentString; - let request = spec.buildRequests(uspBidderRequest.bids, uspBidderRequest); - request = JSON.parse(request.data); - expect(request.us_privacy).to.exist; - expect(request.us_privacy).to.exist.and.to.equal(consentString); - }); - - it('should add schain object to request', function() { - const schainBidderRequest = utils.deepClone(bidderRequest); - schainBidderRequest.bids[0].schain = { - 'complete': 1, - 'ver': '1.0', - 'nodes': [ - { - 'asi': 'testing.com', - 'sid': 'abc', - 'hp': 1 - } - ] - }; - let request = spec.buildRequests(schainBidderRequest.bids, schainBidderRequest); - request = JSON.parse(request.data); - expect(request.source.ext.schain).to.exist; - expect(request.source.ext.schain).to.have.property('complete', 1); - expect(request.source.ext.schain).to.have.property('ver', '1.0'); - expect(request.source.ext.schain.nodes[0].asi).to.equal(schainBidderRequest.bids[0].schain.nodes[0].asi); - }); - }); - - describe('interpretResponse', function () { - let bid = { - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25251', - 'video': {} - }, - 'mediaTypes': { - 'video': { - 'context': 'instream', - 'playerSize': [640, 480] - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c2501de1e', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }; - - const bid_outstream = { - 'bidderRequest': { - 'bids': [{ - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25251', - 'video': {} - }, - 'mediaTypes': { - 'video': { - 'context': 'outstream', - 'playerSize': [640, 480] - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '987654321cba', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }, { - 'bidder': 'emx_digital', - 'params': { - 'tagid': '25252', - 'video': {} - }, - 'mediaTypes': { - 'video': { - 'context': 'instream', - 'playerSize': [640, 480] - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '987654321dcb', - 'bidderRequestId': '22edbae3120bf6', - 'auctionId': '1d1a01234a475' - }] - } - }; - - const serverResponse = { - 'id': '12819a18-56e1-4256-b836-b69a10202668', - 'seatbid': [{ - 'bid': [{ - 'adid': '123456abcde', - 'adm': '', - 'crid': '3434abab34', - 'h': 250, - 'id': '987654321cba', - 'price': 0.5, - 'ttl': 300, - 'w': 300 - }], - 'seat': '1356' - }, { - 'bid': [{ - 'adid': '123456abcdf', - 'adm': '', - 'crid': '3434abab35', - 'h': 600, - 'id': '987654321dcb', - 'price': 0.5, - 'ttl': 300, - 'w': 300 - }] - }] - }; - - const expectedResponse = [{ - 'requestId': '12819a18-56e1-4256-b836-b69a10202668', - 'cpm': 0.5, - 'width': 300, - 'height': 250, - 'creativeId': '3434abab34', - 'dealId': null, - 'currency': 'USD', - 'netRevneue': true, - 'mediaType': 'banner', - 'ad': '', - 'ttl': 300 - }, { - 'requestId': '12819a18-56e1-4256-b836-b69a10202668', - 'cpm': 0.7, - 'width': 300, - 'height': 600, - 'creativeId': '3434abab35', - 'dealId': null, - 'currency': 'USD', - 'netRevneue': true, - 'mediaType': 'banner', - 'ad': '', - 'ttl': 300 - }]; - - it('should properly format bid response', function () { - let result = spec.interpretResponse({ - body: serverResponse - }); - expect(Object.keys(result[0]).length).to.equal(Object.keys(expectedResponse[0]).length); - expect(Object.keys(result[0]).requestId).to.equal(Object.keys(expectedResponse[0]).requestId); - expect(Object.keys(result[0]).bidderCode).to.equal(Object.keys(expectedResponse[0]).bidderCode); - expect(Object.keys(result[0]).cpm).to.equal(Object.keys(expectedResponse[0]).cpm); - expect(Object.keys(result[0]).creativeId).to.equal(Object.keys(expectedResponse[0]).creativeId); - expect(Object.keys(result[0]).width).to.equal(Object.keys(expectedResponse[0]).width); - expect(Object.keys(result[0]).height).to.equal(Object.keys(expectedResponse[0]).height); - expect(Object.keys(result[0]).ttl).to.equal(Object.keys(expectedResponse[0]).ttl); - expect(Object.keys(result[0]).adId).to.equal(Object.keys(expectedResponse[0]).adId); - expect(Object.keys(result[0]).currency).to.equal(Object.keys(expectedResponse[0]).currency); - expect(Object.keys(result[0]).netRevenue).to.equal(Object.keys(expectedResponse[0]).netRevenue); - expect(Object.keys(result[0]).ad).to.equal(Object.keys(expectedResponse[0]).ad); - }); - - it('should return multiple bids', function () { - let result = spec.interpretResponse({ - body: serverResponse - }); - expect(Array.isArray(result.seatbid)) - - const ad0 = result[0]; - const ad1 = result[1]; - expect(ad0.ad).to.equal(serverResponse.seatbid[0].bid[0].adm); - expect(ad0.cpm).to.equal(serverResponse.seatbid[0].bid[0].price); - expect(ad0.creativeId).to.equal(serverResponse.seatbid[0].bid[0].crid); - expect(ad0.currency).to.equal('USD'); - expect(ad0.netRevenue).to.equal(true); - expect(ad0.requestId).to.equal(serverResponse.seatbid[0].bid[0].id); - expect(ad0.ttl).to.equal(300); - - expect(ad1.ad).to.equal(serverResponse.seatbid[1].bid[0].adm); - expect(ad1.cpm).to.equal(serverResponse.seatbid[1].bid[0].price); - expect(ad1.creativeId).to.equal(serverResponse.seatbid[1].bid[0].crid); - expect(ad1.currency).to.equal('USD'); - expect(ad1.netRevenue).to.equal(true); - expect(ad1.requestId).to.equal(serverResponse.seatbid[1].bid[0].id); - expect(ad1.ttl).to.equal(300); - }); - - it('returns a banner bid for non-xml creatives', function () { - let result = spec.interpretResponse({ - body: serverResponse - }, { bidRequest: bid } - ); - const ad0 = result[0]; - const ad1 = result[1]; - expect(ad0.mediaType).to.equal('banner'); - expect(ad0.ad.indexOf('
'; - vastServerResponse.seatbid[1].bid[0].adm = '
'; - - let result = spec.interpretResponse({ - body: vastServerResponse - }, { bidRequest: bid } - ); - const ad0 = result[0]; - const ad1 = result[1]; - expect(ad0.mediaType).to.equal('video'); - expect(ad0.ad.indexOf(' -1).to.equal(true); - expect(ad0.vastXml).to.equal(vastServerResponse.seatbid[0].bid[0].adm); - expect(ad0.ad).to.exist.and.to.be.a('string'); - expect(ad1.mediaType).to.equal('video'); - expect(ad1.ad.indexOf(' -1).to.equal(true); - expect(ad1.vastXml).to.equal(vastServerResponse.seatbid[1].bid[0].adm); - expect(ad1.ad).to.exist.and.to.be.a('string'); - }); - - it('returns a renderer for outstream video creatives', function () { - const vastServerResponse = utils.deepClone(serverResponse); - vastServerResponse.seatbid[0].bid[0].adm = ''; - vastServerResponse.seatbid[1].bid[0].adm = ''; - let 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'); - expect(ad0.renderer.url).to.equal('https://js.brealtime.com/outstream/1.30.0/bundle.js'); - expect(ad0.renderer.id).to.equal('987654321cba'); - expect(ad1.renderer).to.equal(undefined); - }); - - it('handles nobid responses', function () { - let serverResponse = { - 'bids': [] - }; - - let result = spec.interpretResponse({ - body: serverResponse - }); - expect(result.length).to.equal(0); - }); - - it('should not throw an error when decoding an improperly encoded adm', function () { - const badAdmServerResponse = utils.deepClone(serverResponse); - badAdmServerResponse.seatbid[0].bid[0].adm = '\\<\\/script\\>'; - badAdmServerResponse.seatbid[1].bid[0].adm = '%3F%%3Demx%3C3prebid'; - - assert.doesNotThrow(() => spec.interpretResponse({ - body: badAdmServerResponse - })); - }); - }); - - describe('getUserSyncs', function () { - it('should register the iframe sync url', function () { - let syncs = spec.getUserSyncs({ - iframeEnabled: true - }); - expect(syncs).to.not.be.an('undefined'); - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('iframe'); - }); - - it('should pass gdpr params', function () { - let syncs = spec.getUserSyncs({ iframeEnabled: true }, {}, { - gdprApplies: false, consentString: 'test' - }); - expect(syncs).to.not.be.an('undefined'); - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.contains('gdpr=0'); - }); - }); -}); diff --git a/test/spec/modules/engageyaBidAdapter_spec.js b/test/spec/modules/engageyaBidAdapter_spec.js deleted file mode 100644 index ad411fc9350..00000000000 --- a/test/spec/modules/engageyaBidAdapter_spec.js +++ /dev/null @@ -1,161 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/engageyaBidAdapter.js'; -import * as utils from 'src/utils.js'; - -const ENDPOINT_URL = 'https://recs.engageya.com/rec-api/getrecs.json'; - -export const _getUrlVars = function(url) { - var hash; - var myJson = {}; - var hashes = url.slice(url.indexOf('?') + 1).split('&'); - for (var i = 0; i < hashes.length; i++) { - hash = hashes[i].split('='); - myJson[hash[0]] = hash[1]; - } - return myJson; -} - -describe('engageya adapter', function() { - let bidRequests; - let nativeBidRequests; - - beforeEach(function() { - bidRequests = [ - { - bidder: 'engageya', - params: { - widgetId: 85610, - websiteId: 91140, - pageUrl: '[PAGE_URL]' - } - } - ] - - nativeBidRequests = [ - { - bidder: 'engageya', - params: { - widgetId: 85610, - websiteId: 91140, - pageUrl: '[PAGE_URL]' - }, - nativeParams: { - title: { - required: true, - len: 80 - }, - image: { - required: true, - sizes: [150, 50] - }, - sponsoredBy: { - required: true - } - } - } - ] - }) - describe('isBidRequestValid', function () { - it('valid bid case', function () { - let validBid = { - bidder: 'engageya', - params: { - widgetId: 85610, - websiteId: 91140, - pageUrl: '[PAGE_URL]' - } - } - let isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(true); - }); - - it('invalid bid case: widgetId and websiteId is not passed', function() { - let validBid = { - bidder: 'engageya', - params: { - } - } - let isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(false); - }) - - it('invalid bid case: widget id must be number', function() { - let invalidBid = { - bidder: 'engageya', - params: { - widgetId: '157746a', - websiteId: 91140, - pageUrl: '[PAGE_URL]' - } - } - let isValid = spec.isBidRequestValid(invalidBid); - expect(isValid).to.equal(false); - }) - }) - - describe('buildRequests', function () { - it('sends bid request to ENDPOINT via GET', function () { - const request = spec.buildRequests(bidRequests)[0]; - expect(request.url).to.include(ENDPOINT_URL); - expect(request.method).to.equal('GET'); - }); - - it('buildRequests function should not modify original bidRequests object', function () { - let originalBidRequests = utils.deepClone(bidRequests); - let request = spec.buildRequests(bidRequests); - expect(bidRequests).to.deep.equal(originalBidRequests); - }); - - it('buildRequests function should not modify original nativeBidRequests object', function () { - let originalBidRequests = utils.deepClone(nativeBidRequests); - let request = spec.buildRequests(nativeBidRequests); - expect(nativeBidRequests).to.deep.equal(originalBidRequests); - }); - - it('Request params check', function() { - let request = spec.buildRequests(bidRequests)[0]; - const data = _getUrlVars(request.url) - expect(parseInt(data.wid)).to.exist.and.to.equal(bidRequests[0].params.widgetId); - expect(parseInt(data.webid)).to.exist.and.to.equal(bidRequests[0].params.websiteId); - }) - }) - - describe('interpretResponse', function () { - let response = {recs: [ - { - 'ecpm': 0.0920, - 'postId': '', - 'ad': '', - 'thumbnail_path': 'https://engageya.live/wp-content/uploads/2019/05/images.png' - } - ], - imageWidth: 300, - imageHeight: 250, - ireqId: '1d236f7890b', - pbtypeId: 2}; - - it('should get correct bid response', function () { - let expectedResponse = [ - { - 'requestId': '1d236f7890b', - 'cpm': 0.0920, - 'width': 300, - 'height': 250, - 'netRevenue': false, - 'currency': 'USD', - 'creativeId': '', - 'ttl': 700, - 'ad': '' - } - ]; - let request = spec.buildRequests(bidRequests)[0]; - let 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); - expect(result[0].ad).to.not.equal(null); - expect(result[0].currency).to.equal('USD'); - expect(result[0].netRevenue).to.equal(false); - }); - }) -}) diff --git a/test/spec/modules/enrichmentFpdModule_spec.js b/test/spec/modules/enrichmentFpdModule_spec.js deleted file mode 100644 index e5271143f2c..00000000000 --- a/test/spec/modules/enrichmentFpdModule_spec.js +++ /dev/null @@ -1,97 +0,0 @@ -import { expect } from 'chai'; -import * as utils from 'src/utils.js'; -import { getRefererInfo } from 'src/refererDetection.js'; -import { initSubmodule } from 'modules/enrichmentFpdModule.js'; - -describe('the first party data enrichment module', function() { - let width; - let widthStub; - let height; - let heightStub; - let querySelectorStub; - let canonical; - let keywords; - - before(function() { - canonical = document.createElement('link'); - canonical.rel = 'canonical'; - keywords = document.createElement('meta'); - keywords.name = 'keywords'; - }); - - beforeEach(function() { - querySelectorStub = sinon.stub(window.top.document, 'querySelector'); - querySelectorStub.withArgs("link[rel='canonical']").returns(canonical); - querySelectorStub.withArgs("meta[name='keywords']").returns(keywords); - widthStub = sinon.stub(window.top, 'innerWidth').get(function() { - return width; - }); - heightStub = sinon.stub(window.top, 'innerHeight').get(function() { - return height; - }); - }); - - afterEach(function() { - widthStub.restore(); - heightStub.restore(); - querySelectorStub.restore(); - canonical = document.createElement('link'); - canonical.rel = 'canonical'; - keywords = document.createElement('meta'); - keywords.name = 'keywords'; - }); - - it('adds ref and device values', function() { - width = 800; - height = 500; - - let validated = initSubmodule({}, {}); - - expect(validated.site.ref).to.equal(getRefererInfo().referer); - expect(validated.site.page).to.be.undefined; - expect(validated.site.domain).to.be.undefined; - expect(validated.device).to.deep.equal({ w: 800, h: 500 }); - expect(validated.site.keywords).to.be.undefined; - }); - - it('adds page and domain values if canonical url exists', function() { - width = 800; - height = 500; - canonical.href = 'https://www.domain.com/path?query=12345'; - - let validated = initSubmodule({}, {}); - - expect(validated.site.ref).to.equal(getRefererInfo().referer); - expect(validated.site.page).to.equal('https://www.domain.com/path?query=12345'); - expect(validated.site.domain).to.equal('domain.com'); - expect(validated.device).to.deep.equal({ w: 800, h: 500 }); - expect(validated.site.keywords).to.be.undefined; - }); - - it('adds keyword value if keyword meta content exists', function() { - width = 800; - height = 500; - keywords.content = 'value1,value2,value3'; - - let validated = initSubmodule({}, {}); - - expect(validated.site.ref).to.equal(getRefererInfo().referer); - expect(validated.site.page).to.be.undefined; - expect(validated.site.domain).to.be.undefined; - expect(validated.device).to.deep.equal({ w: 800, h: 500 }); - expect(validated.site.keywords).to.equal('value1,value2,value3'); - }); - - it('does not overwrite existing data from getConfig ortb2', function() { - width = 800; - height = 500; - - let validated = initSubmodule({}, {device: {w: 1200, h: 700}, site: {ref: 'https://someUrl.com', page: 'test.com'}}); - - expect(validated.site.ref).to.equal('https://someUrl.com'); - expect(validated.site.page).to.equal('test.com'); - expect(validated.site.domain).to.be.undefined; - expect(validated.device).to.deep.equal({ w: 1200, h: 700 }); - expect(validated.site.keywords).to.be.undefined; - }); -}); diff --git a/test/spec/modules/envivoBidAdapter_spec.js b/test/spec/modules/envivoBidAdapter_spec.js deleted file mode 100644 index 7bd1dd1ccf1..00000000000 --- a/test/spec/modules/envivoBidAdapter_spec.js +++ /dev/null @@ -1,159 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/envivoBidAdapter.js'; - -const ENDPOINT = 'https://ad.nvivo.tv/ads/www/admin/plugins/Prebid/getAd.php'; - -describe('The Envivo bidding adapter', function () { - describe('isBidRequestValid', function () { - it('should return false when given an invalid bid', function () { - const bid = { - bidder: 'envivo', - }; - const isValid = spec.isBidRequestValid(bid); - expect(isValid).to.equal(false); - }); - - it('should return true when given a publisherId in bid', function () { - const bid = { - bidder: 'envivo', - params: { - publisherId: 14 - }, - }; - const isValid = spec.isBidRequestValid(bid); - expect(isValid).to.equal(true); - }); - }); - - describe('buildRequests', function () { - const bidRequests = [{ - 'bidder': 'envivo', - 'params': { - 'publisherId': 14 - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ] - }]; - - const request = spec.buildRequests(bidRequests); - - it('sends bid request to our endpoint via POST', function () { - expect(request.method).to.equal('POST'); - }); - - it('check endpoint url', function () { - expect(request.url).to.equal(ENDPOINT) - }); - - it('sets the proper banner object', function () { - expect(bidRequests[0].params.publisherId).to.equal(14); - }) - }); - const response = { - body: [ - { - 'requestId': '2ee937f15015c6', - 'cpm': '0.2000', - 'width': 300, - 'height': 600, - 'creativeId': '4', - 'currency': 'USD', - 'netRevenue': true, - 'ad': 'ads.html', - 'mediaType': 'banner' - }, - { - 'requestId': '3e1af92622bdc', - 'cpm': '0.2000', - 'creativeId': '4', - 'context': 'outstream', - 'currency': 'USD', - 'netRevenue': true, - 'vastUrl': 'tezt.xml', - 'width': 640, - 'height': 480, - 'mediaType': 'video' - }] - }; - - const request = [ - { - 'bidder': 'envivo', - 'params': { - 'publisherId': 14 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [300, 600] - ] - } - }, - 'bidId': '2ee937f15015c6', - 'src': 'client', - }, - { - 'bidder': 'envivo', - 'params': { - 'publisherId': 14 - }, - 'mediaTypes': { - 'video': { - 'context': 'outstream', - 'playerSize': [ - [640, 480] - ] - } - }, - 'bidId': '3e1af92622bdc', - 'src': 'client', - } - ]; - - describe('interpretResponse', function () { - it('return empty array when no ad found', function () { - const response = {}; - const request = { bidRequests: [] }; - const bids = spec.interpretResponse(response, request); - expect(bids).to.have.lengthOf(0); - }); - - it('check response for banner and video', function () { - const bids = spec.interpretResponse(response, request); - expect(bids).to.have.lengthOf(2); - expect(bids[0].requestId).to.equal('2ee937f15015c6'); - expect(bids[0].cpm).to.equal('0.2000'); - expect(bids[1].cpm).to.equal('0.2000'); - expect(bids[0].width).to.equal(300); - expect(bids[0].height).to.equal(600); - expect(bids[1].vastUrl).to.not.equal(''); - expect(bids[0].ad).to.not.equal(''); - expect(bids[1].adResponse).to.not.equal(''); - expect(bids[1].renderer).not.to.be.an('undefined'); - }); - }); - - describe('On winning bid', function () { - const bids = spec.interpretResponse(response, request); - spec.onBidWon(bids); - }); - - describe('On bid Time out', function () { - const bids = spec.interpretResponse(response, request); - spec.onTimeout(bids); - }); - - describe('user sync', function () { - it('to check the user sync iframe', function () { - let syncs = spec.getUserSyncs({ - iframeEnabled: true - }); - expect(syncs).to.not.be.an('undefined'); - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('iframe'); - }); - }); -}); diff --git a/test/spec/modules/eplanningAnalyticsAdapter_spec.js b/test/spec/modules/eplanningAnalyticsAdapter_spec.js deleted file mode 100644 index 255d116a0ff..00000000000 --- a/test/spec/modules/eplanningAnalyticsAdapter_spec.js +++ /dev/null @@ -1,160 +0,0 @@ -import eplAnalyticsAdapter from 'modules/eplanningAnalyticsAdapter.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import { expect } from 'chai'; -import { parseUrl } from 'src/utils.js'; -import { server } from 'test/mocks/xhr.js'; -let adapterManager = require('src/adapterManager').default; -let events = require('src/events'); -let constants = require('src/constants.json'); - -describe('eplanning analytics adapter', function () { - beforeEach(function () { - sinon.stub(events, 'getEvents').returns([]); - }); - - afterEach(function () { - events.getEvents.restore(); - eplAnalyticsAdapter.disableAnalytics(); - }); - - describe('track', function () { - it('builds and sends auction data', function () { - sinon.spy(eplAnalyticsAdapter, 'track'); - - let auctionTimestamp = 1496510254313; - let pauctionId = '5018eb39-f900-4370-b71e-3bb5b48d324f'; - let initOptions = { - host: 'https://ads.ar.e-planning.net/hba/1/', - ci: '12345' - }; - let pbidderCode = 'adapter'; - - const bidRequest = { - bidderCode: pbidderCode, - auctionId: pauctionId, - bidderRequestId: '1a6fc81528d0f6', - bids: [{ - bidder: pbidderCode, - placementCode: 'container-1', - bidId: '208750227436c1', - bidderRequestId: '1a6fc81528d0f6', - auctionId: pauctionId, - startTime: 1509369418389, - sizes: [[300, 250]], - }], - auctionStart: 1509369418387, - timeout: 3000, - start: 1509369418389 - }; - - const bidResponse = { - bidderCode: pbidderCode, - adId: '208750227436c1', - cpm: 0.015, - auctionId: pauctionId, - responseTimestamp: 1509369418832, - requestTimestamp: 1509369418389, - bidder: pbidderCode, - timeToRespond: 443, - size: '300x250', - width: 300, - height: 250, - }; - - let bidTimeout = [ - { - bidId: '208750227436c1', - bidder: pbidderCode, - auctionId: pauctionId - } - ]; - - adapterManager.registerAnalyticsAdapter({ - code: 'eplanning', - adapter: eplAnalyticsAdapter - }); - - adapterManager.enableAnalytics({ - provider: 'eplanning', - options: initOptions - }); - - // Emit the events with the "real" arguments - - // Step 1: Send auction init event - events.emit(constants.EVENTS.AUCTION_INIT, { - auctionId: pauctionId, - timestamp: auctionTimestamp - }); - - // Step 2: Send bid requested event - events.emit(constants.EVENTS.BID_REQUESTED, bidRequest); - - // Step 3: Send bid response event - events.emit(constants.EVENTS.BID_RESPONSE, bidResponse); - - // Step 4: Send bid time out event - events.emit(constants.EVENTS.BID_TIMEOUT, bidTimeout); - - // Step 5: Send auction bid won event - events.emit(constants.EVENTS.BID_WON, { - adId: 'adIdData', - ad: 'adContent', - auctionId: pauctionId, - width: 300, - height: 250 - }); - - // Step 6: Send auction end event - events.emit(constants.EVENTS.AUCTION_END, {auctionId: pauctionId}); - - // Step 7: Find the request data sent (filtering other hosts) - let requests = server.requests.filter(req => { - return req.url.indexOf(initOptions.host) > -1; - }); - expect(requests.length).to.equal(1); - - expect(includes([initOptions.host + initOptions.ci], requests[0].url)); - expect(includes(['https://ads.ar.e-planning.net/hba/1/12345?d='], requests[0].url)); - - let info = requests[0].url; - let purl = parseUrl(info); - let eplData = JSON.parse(decodeURIComponent(purl.search.d)); - - // Step 8 check that 6 events were sent - expect(eplData.length).to.equal(6); - - // Step 9 verify that we only receive the parameters we need - let expectedEventValues = [ - // AUCTION INIT - {ec: constants.EVENTS.AUCTION_INIT, - p: {auctionId: pauctionId, time: auctionTimestamp}}, - // BID REQ - {ec: constants.EVENTS.BID_REQUESTED, - p: {auctionId: pauctionId, time: 1509369418389, bidder: pbidderCode, bids: [{time: 1509369418389, sizes: [[300, 250]], bidder: pbidderCode, placementCode: 'container-1', auctionId: pauctionId}]}}, - // BID RESP - {ec: constants.EVENTS.BID_RESPONSE, - p: {auctionId: pauctionId, bidder: pbidderCode, cpm: 0.015, size: '300x250', time: 1509369418832}}, - // BID T.O. - {ec: constants.EVENTS.BID_TIMEOUT, - p: [{auctionId: pauctionId, bidder: pbidderCode}]}, - // BID WON - {ec: constants.EVENTS.BID_WON, - p: {auctionId: pauctionId, size: '300x250'}}, - // AUCTION END - {ec: constants.EVENTS.AUCTION_END, - p: {auctionId: pauctionId}} - ]; - - for (let evid = 0; evid < eplData.length; evid++) { - expect(eplData[evid]).to.deep.equal(expectedEventValues[evid]); - } - - // Step 10 check that the host to send the ajax request is configurable via options - expect(eplAnalyticsAdapter.context.host).to.equal(initOptions.host); - - // Step 11 verify that we received 6 events - sinon.assert.callCount(eplAnalyticsAdapter.track, 6); - }); - }); -}); diff --git a/test/spec/modules/eplanningBidAdapter_spec.js b/test/spec/modules/eplanningBidAdapter_spec.js deleted file mode 100644 index 1d3a8344170..00000000000 --- a/test/spec/modules/eplanningBidAdapter_spec.js +++ /dev/null @@ -1,925 +0,0 @@ -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 } from 'modules/userId/index.js'; -import * as utils from 'src/utils.js'; - -describe('E-Planning Adapter', function () { - const adapter = newBidder('spec'); - const CI = '12345'; - const ADUNIT_CODE = 'adunit-co:de'; - const ADUNIT_CODE2 = 'adunit-code-dos'; - const ADUNIT_CODE_VIEW = 'adunit-code-view'; - const ADUNIT_CODE_VIEW2 = 'adunit-code-view2'; - const ADUNIT_CODE_VIEW3 = 'adunit-code-view3'; - const CLEAN_ADUNIT_CODE2 = '300x250_1'; - const CLEAN_ADUNIT_CODE = '300x250_0'; - const CLEAN_ADUNIT_CODE_ML = 'adunitco_de'; - const BID_ID = '123456789'; - const BID_ID2 = '987654321'; - const BID_ID3 = '998877665'; - const CPM = 1.3; - const W = '300'; - const H = '250'; - const ADM = '
This is an ad
'; - const I_ID = '7854abc56248f873'; - const CRID = '1234567890'; - const TEST_ISV = 'leles.e-planning.net'; - const validBid = { - 'bidder': 'eplanning', - 'bidId': BID_ID, - 'params': { - 'ci': CI, - }, - 'adUnitCode': ADUNIT_CODE, - 'sizes': [[300, 250], [300, 600]], - }; - const validBid2 = { - 'bidder': 'eplanning', - 'bidId': BID_ID2, - 'params': { - 'ci': CI, - }, - 'adUnitCode': ADUNIT_CODE2, - 'sizes': [[300, 250], [300, 600]], - }; - const ML = '1'; - const validBidMappingLinear = { - 'bidder': 'eplanning', - 'bidId': BID_ID, - 'params': { - 'ci': CI, - 'ml': ML, - }, - 'adUnitCode': ADUNIT_CODE, - 'sizes': [[300, 250], [300, 600]], - }; - const SN = 'spaceName'; - const validBidSpaceName = { - 'bidder': 'eplanning', - 'bidId': BID_ID, - 'params': { - 'ci': CI, - 'sn': SN, - }, - 'sizes': [[300, 250], [300, 600]], - }; - const validBidView = { - 'bidder': 'eplanning', - 'bidId': BID_ID, - 'params': { - 'ci': CI, - }, - 'adUnitCode': ADUNIT_CODE_VIEW, - 'sizes': [[300, 250], [300, 600]], - }; - const validBidView2 = { - 'bidder': 'eplanning', - 'bidId': BID_ID2, - 'params': { - 'ci': CI, - }, - 'adUnitCode': ADUNIT_CODE_VIEW2, - 'sizes': [[300, 250], [300, 600]], - }; - const validBidView3 = { - 'bidder': 'eplanning', - 'bidId': BID_ID3, - 'params': { - 'ci': CI, - }, - 'adUnitCode': ADUNIT_CODE_VIEW3, - 'sizes': [[300, 250], [300, 600]], - }; - const testBid = { - 'bidder': 'eplanning', - 'params': { - 't': 1, - 'isv': TEST_ISV - }, - 'adUnitCode': ADUNIT_CODE, - 'sizes': [[300, 250], [300, 600]], - }; - const invalidBid = { - 'bidder': 'eplanning', - 'params': { - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - }; - const validBidExistingSizesInPriorityListForMobile = { - 'bidder': 'eplanning', - 'bidId': BID_ID, - 'params': { - 'ci': CI, - }, - 'adUnitCode': ADUNIT_CODE, - 'sizes': [[970, 250], [320, 50], [300, 50]], - }; - const validBidSizesNotExistingInPriorityListForMobile = { - 'bidder': 'eplanning', - 'bidId': BID_ID, - 'params': { - 'ci': CI, - }, - 'adUnitCode': ADUNIT_CODE, - 'sizes': [[970, 250], [300, 70], [160, 600]], - }; - const validBidExistingSizesInPriorityListForDesktop = { - 'bidder': 'eplanning', - 'bidId': BID_ID, - 'params': { - 'ci': CI, - }, - 'adUnitCode': ADUNIT_CODE, - 'sizes': [[970, 250], [300, 600], [300, 250]], - 'ext': { - 'screen': { - 'w': 1025, - 'h': 1025 - } - } - }; - const response = { - body: { - 'sI': { - 'k': '12345' - }, - 'sec': { - 'k': 'ROS' - }, - 'sp': [{ - 'k': CLEAN_ADUNIT_CODE, - 'a': [{ - 'adm': ADM, - 'id': '7854abc56248f874', - 'i': I_ID, - 'fi': '7854abc56248f872', - 'ip': '45621afd87462104', - 'w': W, - 'h': H, - 'crid': CRID, - 'pr': CPM - }], - }], - 'cs': [ - 'http://a-sync-url.com/', - { - 'u': 'http://another-sync-url.com/test.php?&partner=123456&endpoint=us-east', - 'ifr': true - } - ] - } - }; - const responseWithTwoAdunits = { - body: { - 'sI': { - 'k': '12345' - }, - 'sec': { - 'k': 'ROS' - }, - 'sp': [{ - 'k': CLEAN_ADUNIT_CODE, - 'a': [{ - 'adm': ADM, - 'id': '7854abc56248f874', - 'i': I_ID, - 'fi': '7854abc56248f872', - 'ip': '45621afd87462104', - 'w': W, - 'h': H, - 'crid': CRID, - 'pr': CPM - }] - }, { - 'k': CLEAN_ADUNIT_CODE2, - 'a': [{ - 'adm': ADM, - 'id': '7854abc56248f874', - 'i': I_ID, - 'fi': '7854abc56248f872', - 'ip': '45621afd87462104', - 'w': W, - 'h': H, - 'crid': CRID, - 'pr': CPM - }], - }, - ], - 'cs': [ - 'http://a-sync-url.com/', - { - 'u': 'http://another-sync-url.com/test.php?&partner=123456&endpoint=us-east', - 'ifr': true - } - ] - } - }; - const responseWithNoAd = { - body: { - 'sI': { - 'k': '12345' - }, - 'sec': { - 'k': 'ROS' - }, - 'sp': [{ - 'k': 'spname', - }], - 'cs': [ - 'http://a-sync-url.com/', - { - 'u': 'http://another-sync-url.com/test.php?&partner=123456&endpoint=us-east', - 'ifr': true - } - ] - } - }; - const responseWithNoSpace = { - body: { - 'sI': { - 'k': '12345' - }, - 'sec': { - 'k': 'ROS' - }, - 'cs': [ - 'http://a-sync-url.com/', - { - 'u': 'http://another-sync-url.com/test.php?&partner=123456&endpoint=us-east', - 'ifr': true - } - ] - } - }; - const refererUrl = 'https://localhost'; - const bidderRequest = { - refererInfo: { - referer: refererUrl - }, - gdprConsent: { - gdprApplies: 1, - consentString: 'concentDataString', - vendorData: { - vendorConsents: { - '90': 1 - }, - }, - }, - uspConsent: 'consentCcpa' - }; - - describe('inherited functions', function () { - it('exists and is a function', function () { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - it('should return true when bid has ci parameter', function () { - expect(spec.isBidRequestValid(validBid)).to.equal(true); - }); - - it('should return false when bid does not have ci parameter and is not a test bid', function () { - expect(spec.isBidRequestValid(invalidBid)).to.equal(false); - }); - - it('should return true when bid does not have ci parameter but is a test bid', function () { - expect(spec.isBidRequestValid(testBid)).to.equal(true); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [validBid]; - let sandbox; - beforeEach(() => { - sandbox = sinon.sandbox.create(); - }); - - afterEach(() => { - sandbox.restore(); - }); - - const createWindow = () => { - const win = {}; - win.self = win; - win.innerWidth = 1025; - return win; - }; - - function setupSingleWindow(sandBox) { - const win = createWindow(); - sandBox.stub(utils, 'getWindowSelf').returns(win); - } - - it('should create the url correctly', function () { - const url = spec.buildRequests(bidRequests, bidderRequest).url; - expect(url).to.equal('https://ads.us.e-planning.net/pbjs/1/' + CI + '/1/localhost/ROS'); - }); - - it('should return GET method', function () { - const method = spec.buildRequests(bidRequests, bidderRequest).method; - expect(method).to.equal('GET'); - }); - - it('should return pbv parameter with value prebid version', function () { - const pbv = spec.buildRequests(bidRequests, bidderRequest).data.pbv; - expect(pbv).to.equal('$prebid.version$'); - }); - - it('should return e parameter with value according to the adunit sizes', function () { - const e = spec.buildRequests(bidRequests, bidderRequest).data.e; - expect(e).to.equal('300x250_0:300x250,300x600'); - }); - - it('should return e parameter with linear mapping attribute with value according to the adunit sizes', function () { - let bidRequestsML = [validBidMappingLinear]; - const e = spec.buildRequests(bidRequestsML, bidderRequest).data.e; - expect(e).to.equal(CLEAN_ADUNIT_CODE_ML + ':300x250,300x600'); - }); - - it('should return e parameter with space name attribute with value according to the adunit sizes', function () { - let bidRequestsSN = [validBidSpaceName]; - const e = spec.buildRequests(bidRequestsSN, bidderRequest).data.e; - expect(e).to.equal(SN + ':300x250,300x600'); - }); - - it('should return correct e parameter with more than one adunit', function () { - const NEW_CODE = ADUNIT_CODE + '2'; - const CLEAN_NEW_CODE = CLEAN_ADUNIT_CODE + '2'; - const anotherBid = { - 'bidder': 'eplanning', - 'params': { - 'ci': CI, - }, - 'adUnitCode': NEW_CODE, - 'sizes': [[100, 100]], - }; - bidRequests.push(anotherBid); - - const e = spec.buildRequests(bidRequests, bidderRequest).data.e; - expect(e).to.equal('300x250_0:300x250,300x600+100x100_0:100x100'); - }); - - it('should return correct e parameter with linear mapping attribute with more than one adunit', function () { - let bidRequestsML = [validBidMappingLinear]; - const NEW_CODE = ADUNIT_CODE + '2'; - const CLEAN_NEW_CODE = CLEAN_ADUNIT_CODE_ML + '2'; - const anotherBid = { - 'bidder': 'eplanning', - 'params': { - 'ci': CI, - 'ml': ML, - }, - 'adUnitCode': NEW_CODE, - 'sizes': [[100, 100]], - }; - bidRequestsML.push(anotherBid); - - const e = spec.buildRequests(bidRequestsML, bidderRequest).data.e; - expect(e).to.equal(CLEAN_ADUNIT_CODE_ML + ':300x250,300x600+' + CLEAN_NEW_CODE + ':100x100'); - }); - - it('should return correct e parameter with space name attribute with more than one adunit', function () { - let bidRequestsSN = [validBidSpaceName]; - const NEW_SN = 'anotherNameSpace'; - const anotherBid = { - 'bidder': 'eplanning', - 'params': { - 'ci': CI, - 'sn': NEW_SN, - }, - 'sizes': [[100, 100]], - }; - bidRequestsSN.push(anotherBid); - - const e = spec.buildRequests(bidRequestsSN, bidderRequest).data.e; - expect(e).to.equal(SN + ':300x250,300x600+' + NEW_SN + ':100x100'); - }); - - it('should return correct e parameter when the adunit has no size', function () { - const noSizeBid = { - 'bidder': 'eplanning', - 'params': { - 'ci': CI, - }, - 'adUnitCode': ADUNIT_CODE, - }; - - const e = spec.buildRequests([noSizeBid], bidderRequest).data.e; - expect(e).to.equal('1x1_0:1x1'); - }); - - it('should return correct e parameter with linear mapping attribute when the adunit has no size', function () { - const noSizeBid = { - 'bidder': 'eplanning', - 'params': { - 'ci': CI, - 'ml': ML, - }, - 'adUnitCode': ADUNIT_CODE, - }; - - const e = spec.buildRequests([noSizeBid], bidderRequest).data.e; - expect(e).to.equal(CLEAN_ADUNIT_CODE_ML + ':1x1'); - }); - - it('should return ur parameter with current window url', function () { - const ur = spec.buildRequests(bidRequests, bidderRequest).data.ur; - expect(ur).to.equal(bidderRequest.refererInfo.referer); - }); - - it('should return fr parameter when there is a referrer', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - const dataRequest = request.data; - expect(dataRequest.fr).to.equal(refererUrl); - }); - - it('should return crs parameter with document charset', function () { - let expected; - try { - expected = window.top.document.characterSet; - } catch (e) { - expected = document.characterSet; - } - - const chset = spec.buildRequests(bidRequests, bidderRequest).data.crs; - - expect(chset).to.equal(expected); - }); - - it('should return the testing url when the request has the t parameter', function () { - const url = spec.buildRequests([testBid], bidderRequest).url; - const expectedUrl = 'https://' + TEST_ISV + '/layers/t_pbjs_2.json'; - expect(url).to.equal(expectedUrl); - }); - - it('should return the parameter ncb with value 1', function () { - const ncb = spec.buildRequests(bidRequests, bidderRequest).data.ncb; - expect(ncb).to.equal('1'); - }); - - it('should properly build a gdpr request', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - const dataRequest = request.data; - expect(dataRequest.gdpr).to.equal('1'); - expect(dataRequest.gdprcs).to.equal('concentDataString'); - }); - - it('should properly build a uspConsent request', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - const dataRequest = request.data; - expect(dataRequest.ccpa).to.equal('consentCcpa'); - }); - - it('should return the e parameter with a value according to the sizes in order corresponding to the mobile priority list of the ad units', function () { - let bidRequestsPrioritySizes = [validBidExistingSizesInPriorityListForMobile]; - const e = spec.buildRequests(bidRequestsPrioritySizes, bidderRequest).data.e; - expect(e).to.equal('320x50_0:320x50,300x50,970x250'); - }); - - it('should return the e parameter with a value according to the sizes in order corresponding to the desktop priority list of the ad units', function () { - let bidRequestsPrioritySizes = [validBidExistingSizesInPriorityListForDesktop]; - setupSingleWindow(sandbox); - const e = spec.buildRequests(bidRequestsPrioritySizes, bidderRequest).data.e; - expect(e).to.equal('300x250_0:300x250,300x600,970x250'); - }); - - it('should return the e parameter with a value according to the sizes in order as they are sent from the ad units', function () { - let bidRequestsPrioritySizes2 = [validBidSizesNotExistingInPriorityListForMobile]; - const e = spec.buildRequests(bidRequestsPrioritySizes2, bidderRequest).data.e; - expect(e).to.equal('970x250_0:970x250,300x70,160x600'); - }); - }); - - describe('interpretResponse', function () { - it('should return an empty array when there is no ads in the response', function () { - const bidResponses = spec.interpretResponse(responseWithNoAd); - expect(bidResponses).to.be.empty; - }); - - it('should return an empty array when there is no spaces in the response', function () { - const bidResponses = spec.interpretResponse(responseWithNoSpace); - expect(bidResponses).to.be.empty; - }); - - it('should correctly map the parameters in the response', function () { - const bidResponse = spec.interpretResponse(response, { adUnitToBidId: { [CLEAN_ADUNIT_CODE]: BID_ID } })[0]; - const expectedResponse = { - requestId: BID_ID, - cpm: CPM, - width: W, - height: H, - ad: ADM, - ttl: 120, - creativeId: CRID, - netRevenue: true, - currency: 'USD', - }; - expect(bidResponse).to.deep.equal(expectedResponse); - }); - }); - - describe('getUserSyncs', function () { - const sOptionsAllEnabled = { - pixelEnabled: true, - iframeEnabled: true - }; - const sOptionsAllDisabled = { - pixelEnabled: false, - iframeEnabled: false - }; - const sOptionsOnlyPixel = { - pixelEnabled: true, - iframeEnabled: false - }; - const sOptionsOnlyIframe = { - pixelEnabled: false, - iframeEnabled: true - }; - - it('should return an empty array if the response has no syncs', function () { - const noSyncsResponse = { cs: [] }; - const syncs = spec.getUserSyncs(sOptionsAllEnabled, [noSyncsResponse]); - expect(syncs).to.be.empty; - }); - - it('should return an empty array if there is no sync options enabled', function () { - const syncs = spec.getUserSyncs(sOptionsAllDisabled, [response]); - expect(syncs).to.be.empty; - }); - - it('should only return pixels if iframe is not enabled', function () { - const syncs = spec.getUserSyncs(sOptionsOnlyPixel, [response]); - syncs.forEach(sync => expect(sync.type).to.equal('image')); - }); - - it('should only return iframes if pixel is not enabled', function () { - const syncs = spec.getUserSyncs(sOptionsOnlyIframe, [response]); - syncs.forEach(sync => expect(sync.type).to.equal('iframe')); - }); - }); - - describe('adUnits mapping to bidId', function () { - it('should correctly map the bidId to the adunit', function () { - const requests = spec.buildRequests([validBid, validBid2], bidderRequest); - const responses = spec.interpretResponse(responseWithTwoAdunits, requests); - expect(responses[0].requestId).to.equal(BID_ID); - expect(responses[1].requestId).to.equal(BID_ID2); - }); - }); - describe('viewability', function() { - let storageIdRender = 'pbsr_' + validBidView.adUnitCode; - let storageIdView = 'pbvi_' + validBidView.adUnitCode; - let bidRequests = [validBidView]; - let bidRequestMultiple = [validBidView, validBidView2, validBidView3]; - let getLocalStorageSpy; - let setDataInLocalStorageSpy; - let hasLocalStorageStub; - let clock; - let element; - let getBoundingClientRectStub; - let sandbox = sinon.sandbox.create(); - let focusStub; - function createElement(id) { - element = document.createElement('div'); - element.id = id || ADUNIT_CODE_VIEW; - element.style.width = '50px'; - element.style.height = '50px'; - if (frameElement) { - frameElement.style.width = '100px'; - frameElement.style.height = '100px'; - } - element.style.background = 'black'; - document.body.appendChild(element); - } - function createElementVisible(id) { - createElement(id); - sandbox.stub(element, 'getBoundingClientRect').returns({ - x: 0, - y: 0, - width: 50, - height: 50, - top: 0, - right: 50, - bottom: 50, - left: 0, - }); - } - function createElementOutOfView(id) { - createElement(id); - sandbox.stub(element, 'getBoundingClientRect').returns({ - x: 100, - y: 100, - width: 250, - height: 250, - top: 100, - right: 350, - bottom: 350, - left: 100, - }); - } - - function createPartiallyVisibleElement(id) { - createElement(id); - sandbox.stub(element, 'getBoundingClientRect').returns({ - x: 0, - y: 0, - width: 50, - height: 150, - top: 0, - right: 50, - bottom: 150, - left: 0, - }); - } - function createPartiallyInvisibleElement(id) { - createElement(id); - sandbox.stub(element, 'getBoundingClientRect').returns({ - x: 0, - y: 0, - width: 150, - height: 150, - top: 0, - right: 150, - bottom: 150, - left: 0, - }); - } - function createElementOutOfRange(id) { - createElement(id); - sandbox.stub(element, 'getBoundingClientRect').returns({ - x: 200, - y: 200, - width: 350, - height: 350, - top: 200, - right: 350, - bottom: 350, - left: 200, - }); - } - beforeEach(function () { - getLocalStorageSpy = sandbox.spy(storage, 'getDataFromLocalStorage'); - setDataInLocalStorageSpy = sandbox.spy(storage, 'setDataInLocalStorage'); - - hasLocalStorageStub = sandbox.stub(storage, 'hasLocalStorage'); - hasLocalStorageStub.returns(true); - - clock = sandbox.useFakeTimers(); - - focusStub = sandbox.stub(window.top.document, 'hasFocus'); - focusStub.returns(true); - }); - afterEach(function () { - sandbox.restore(); - if (document.getElementById(ADUNIT_CODE_VIEW)) { - document.body.removeChild(element); - } - window.top.localStorage.removeItem(storageIdRender); - window.top.localStorage.removeItem(storageIdView); - }); - - it('should create the url correctly without LocalStorage', function() { - createElementVisible(); - hasLocalStorageStub.returns(false); - const response = spec.buildRequests(bidRequests, bidderRequest); - - expect(response.url).to.equal('https://ads.us.e-planning.net/pbjs/1/' + CI + '/1/localhost/ROS'); - expect(response.data.vs).to.equal('F'); - - sinon.assert.notCalled(getLocalStorageSpy); - sinon.assert.notCalled(setDataInLocalStorageSpy); - }); - - it('should create the url correctly with LocalStorage', function() { - createElementVisible(); - const response = spec.buildRequests(bidRequests, bidderRequest); - expect(response.url).to.equal('https://ads.us.e-planning.net/pbjs/1/' + CI + '/1/localhost/ROS'); - - expect(response.data.vs).to.equal('F'); - - sinon.assert.called(getLocalStorageSpy); - sinon.assert.called(setDataInLocalStorageSpy); - sinon.assert.calledWith(getLocalStorageSpy, storageIdRender); - sinon.assert.calledWith(setDataInLocalStorageSpy, storageIdRender); - - expect(storage.getDataFromLocalStorage(storageIdRender)).to.equal('1'); - }); - - context('when element is fully in view', function() { - let respuesta; - beforeEach(function () { - createElementVisible(); - }); - it('when you have a render', function() { - respuesta = spec.buildRequests(bidRequests, bidderRequest); - clock.tick(1005); - - expect(respuesta.data.vs).to.equal('F'); - - expect(storage.getDataFromLocalStorage(storageIdRender)).to.equal('1'); - expect(storage.getDataFromLocalStorage(storageIdView)).to.equal('1'); - }); - it('when you have more than four render', function() { - storage.setDataInLocalStorage(storageIdRender, 4); - respuesta = spec.buildRequests(bidRequests, bidderRequest); - clock.tick(1005); - - expect(respuesta.data.vs).to.equal('0'); - - expect(storage.getDataFromLocalStorage(storageIdRender)).to.equal('5'); - expect(storage.getDataFromLocalStorage(storageIdView)).to.equal('1'); - }); - it('when you have more than four render and already record visibility', function() { - storage.setDataInLocalStorage(storageIdRender, 4); - storage.setDataInLocalStorage(storageIdView, 4); - respuesta = spec.buildRequests(bidRequests, bidderRequest); - clock.tick(1005); - - expect(respuesta.data.vs).to.equal('a'); - - expect(storage.getDataFromLocalStorage(storageIdRender)).to.equal('5'); - expect(storage.getDataFromLocalStorage(storageIdView)).to.equal('5'); - }); - }); - - context('when element is out of view', function() { - let respuesta; - beforeEach(function () { - createElementOutOfView(); - }); - - it('when you have a render', function() { - respuesta = spec.buildRequests(bidRequests, bidderRequest); - clock.tick(1005); - expect(respuesta.data.vs).to.equal('F'); - - expect(storage.getDataFromLocalStorage(storageIdRender)).to.equal('1'); - expect(storage.getDataFromLocalStorage(storageIdView)).to.equal(null); - }); - it('when you have more than four render', function() { - storage.setDataInLocalStorage(storageIdRender, 4); - respuesta = spec.buildRequests(bidRequests, bidderRequest); - clock.tick(1005); - expect(respuesta.data.vs).to.equal('0'); - - expect(storage.getDataFromLocalStorage(storageIdRender)).to.equal('5'); - expect(storage.getDataFromLocalStorage(storageIdView)).to.equal(null); - }); - }); - - context('when element is partially in view', function() { - let respuesta; - it('should register visibility with more than 50%', function() { - createPartiallyVisibleElement(); - respuesta = spec.buildRequests(bidRequests, bidderRequest); - clock.tick(1005); - - expect(storage.getDataFromLocalStorage(storageIdRender)).to.equal('1'); - expect(storage.getDataFromLocalStorage(storageIdView)).to.equal('1'); - }); - it('you should not register visibility with less than 50%', function() { - createPartiallyInvisibleElement(); - respuesta = spec.buildRequests(bidRequests, bidderRequest); - clock.tick(1005); - - expect(storage.getDataFromLocalStorage(storageIdRender)).to.equal('1'); - expect(storage.getDataFromLocalStorage(storageIdView)).to.equal(null); - }); - }); - context('when width or height of the element is zero', function() { - beforeEach(function () { - createElementVisible(); - }); - it('if the width is zero but the height is within the range', function() { - element.style.width = '0px'; - spec.buildRequests(bidRequests, bidderRequest) - clock.tick(1005); - - expect(storage.getDataFromLocalStorage(storageIdRender)).to.equal('1'); - expect(storage.getDataFromLocalStorage(storageIdView)).to.equal(null); - }); - it('if the height is zero but the width is within the range', function() { - element.style.height = '0px'; - spec.buildRequests(bidRequests, bidderRequest) - clock.tick(1005); - - expect(storage.getDataFromLocalStorage(storageIdRender)).to.equal('1'); - expect(storage.getDataFromLocalStorage(storageIdView)).to.equal(null); - }); - it('if both are zero', function() { - element.style.height = '0px'; - element.style.width = '0px'; - spec.buildRequests(bidRequests, bidderRequest) - clock.tick(1005); - - expect(storage.getDataFromLocalStorage(storageIdRender)).to.equal('1'); - expect(storage.getDataFromLocalStorage(storageIdView)).to.equal(null); - }); - }); - context('when tab is inactive', function() { - it('I should not register if it is not in focus', function() { - createElementVisible(); - focusStub.returns(false); - spec.buildRequests(bidRequests, bidderRequest); - clock.tick(1005); - expect(storage.getDataFromLocalStorage(storageIdRender)).to.equal('1'); - expect(storage.getDataFromLocalStorage(storageIdView)).to.equal(null); - }); - }); - context('segmentBeginsBeforeTheVisibleRange', function() { - it('segmentBeginsBeforeTheVisibleRange', function() { - createElementOutOfRange(); - spec.buildRequests(bidRequests, bidderRequest); - clock.tick(1005); - expect(storage.getDataFromLocalStorage(storageIdRender)).to.equal('1'); - expect(storage.getDataFromLocalStorage(storageIdView)).to.equal(null); - }); - }); - context('when there are multiple adunit', function() { - let respuesta; - beforeEach(function () { - [ADUNIT_CODE_VIEW, ADUNIT_CODE_VIEW2, ADUNIT_CODE_VIEW3].forEach(ac => { - storage.setDataInLocalStorage('pbsr_' + ac, 5); - storage.setDataInLocalStorage('pbvi_' + ac, 5); - }); - }); - afterEach(function () { - [ADUNIT_CODE_VIEW, ADUNIT_CODE_VIEW2, ADUNIT_CODE_VIEW3].forEach(ac => { - if (document.getElementById(ac)) { - document.body.removeChild(document.getElementById(ac)); - } - window.top.localStorage.removeItem(ac); - window.top.localStorage.removeItem(ac); - }); - }); - it('all visibles', function() { - createElementVisible(ADUNIT_CODE_VIEW); - createElementVisible(ADUNIT_CODE_VIEW2); - createElementVisible(ADUNIT_CODE_VIEW3); - - respuesta = spec.buildRequests(bidRequestMultiple, bidderRequest); - clock.tick(1005); - [ADUNIT_CODE_VIEW, ADUNIT_CODE_VIEW2, ADUNIT_CODE_VIEW3].forEach(ac => { - expect(storage.getDataFromLocalStorage('pbsr_' + ac)).to.equal('6'); - expect(storage.getDataFromLocalStorage('pbvi_' + ac)).to.equal('6'); - }); - expect('aaa').to.equal(respuesta.data.vs); - }); - it('none visible', function() { - createElementOutOfView(ADUNIT_CODE_VIEW); - createElementOutOfView(ADUNIT_CODE_VIEW2); - createElementOutOfView(ADUNIT_CODE_VIEW3); - - respuesta = spec.buildRequests(bidRequestMultiple, bidderRequest); - clock.tick(1005); - [ADUNIT_CODE_VIEW, ADUNIT_CODE_VIEW2, ADUNIT_CODE_VIEW3].forEach(ac => { - expect(storage.getDataFromLocalStorage('pbsr_' + ac)).to.equal('6'); - expect(storage.getDataFromLocalStorage('pbvi_' + ac)).to.equal('5'); - }); - - expect('aaa').to.equal(respuesta.data.vs); - }); - it('some visible and others not visible', function() { - createElementVisible(ADUNIT_CODE_VIEW); - createElementOutOfView(ADUNIT_CODE_VIEW2); - createElementOutOfView(ADUNIT_CODE_VIEW3); - - respuesta = spec.buildRequests(bidRequestMultiple, bidderRequest); - clock.tick(1005); - expect(storage.getDataFromLocalStorage('pbsr_' + ADUNIT_CODE_VIEW)).to.equal('6'); - expect(storage.getDataFromLocalStorage('pbvi_' + ADUNIT_CODE_VIEW)).to.equal('6'); - [ADUNIT_CODE_VIEW2, ADUNIT_CODE_VIEW3].forEach(ac => { - expect(storage.getDataFromLocalStorage('pbsr_' + ac)).to.equal('6'); - expect(storage.getDataFromLocalStorage('pbvi_' + ac)).to.equal('5'); - }); - expect('aaa').to.equal(respuesta.data.vs); - }); - }); - }); - describe('Send eids', function() { - it('should add eids to the request', function() { - init(config); - config.setConfig({ - userSync: { - userIds: [ - { name: 'id5Id', value: { 'id5id': { uid: 'ID5-ZHMOL_IfFSt7_lVYX8rBZc6GH3XMWyPQOBUfr4bm0g!', ext: { linkType: 1 } } } }, - { name: 'pubCommonId', value: {'pubcid': 'c29cb2ae-769d-42f6-891a-f53cadee823d'} }, - { name: 'unifiedId', value: {'tdid': 'D6885E90-2A7A-4E0F-87CB-7734ED1B99A3'} } - ] - } - }); - let bidRequests = [validBidView]; - const expected_id5id = encodeURIComponent(JSON.stringify({ uid: 'ID5-ZHMOL_IfFSt7_lVYX8rBZc6GH3XMWyPQOBUfr4bm0g!', ext: { linkType: 1 } })); - const request = spec.buildRequests(bidRequests, bidderRequest); - const dataRequest = request.data; - - expect('D6885E90-2A7A-4E0F-87CB-7734ED1B99A3').to.equal(dataRequest.e_tdid); - expect('c29cb2ae-769d-42f6-891a-f53cadee823d').to.equal(dataRequest.e_pubcid); - expect(expected_id5id).to.equal(dataRequest.e_id5id); - }); - }); -}); diff --git a/test/spec/modules/etargetBidAdapter_spec.js b/test/spec/modules/etargetBidAdapter_spec.js deleted file mode 100644 index 2dbf6cd68c5..00000000000 --- a/test/spec/modules/etargetBidAdapter_spec.js +++ /dev/null @@ -1,433 +0,0 @@ -import {assert, expect} from 'chai'; -import {spec} from 'modules/etargetBidAdapter.js'; -import { BANNER, VIDEO } from 'src/mediaTypes.js'; - -describe('etarget adapter', function () { - let serverResponse, bidRequest, bidResponses; - let bids = []; - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'etarget', - 'params': { - 'refid': '55410', - 'country': '1' - } - }; - - it('should return true when required params found', function () { - assert(spec.isBidRequestValid(bid)); - }); - }); - - describe('buildRequests', function () { - it('should pass multiple bids via single request', function () { - let request = spec.buildRequests(bids); - let parsedUrl = parseUrl(request.url); - assert.lengthOf(parsedUrl.items, 7); - }); - - it('should handle global request parameters', function () { - let parsedUrl = parseUrl(spec.buildRequests([bids[0]]).url); - assert.equal(parsedUrl.path, 'https://sk.search.etargetnet.com/hb'); - }); - - it('should set correct request method', function () { - let request = spec.buildRequests([bids[0]]); - assert.equal(request.method, 'POST'); - }); - - it('should correctly form bid items', function () { - let bidList = bids; - let request = spec.buildRequests(bidList); - let parsedUrl = parseUrl(request.url); - assert.deepEqual(parsedUrl.items, [ - { - refid: '1', - country: '1', - transactionId: '5f33781f-9552-4ca1', - url: 'some// there' - }, - { - refid: '2', - country: '1', - someVar: 'someValue', - pt: 'gross', - transactionId: '5f33781f-9552-4iuy' - }, - { - refid: '3', - country: '1', - pdom: 'home', - transactionId: '5f33781f-9552-7ev3' - }, - { - refid: '3', - country: '1', - pdom: 'home', - transactionId: '5f33781f-9552-7ev3' - }, - { - refid: '3', - country: '1', - pdom: 'home', - transactionId: '5f33781f-9552-7ev3' - }, - { - refid: '5', - country: '1', - pt: 'net', - transactionId: '5f33781f-9552-7ev3', - }, - { - refid: '6', - country: '1', - pt: 'gross', - transactionId: '5f33781f-9552-7ev3' - } - ]); - }); - - it('should not change original validBidRequests object', function () { - var resultBids = JSON.parse(JSON.stringify(bids[0])); - let request = spec.buildRequests([bids[0]]); - assert.deepEqual(resultBids, bids[0]); - }); - - describe('gdpr', function () { - it('should send GDPR Consent data to etarget if gdprApplies', function () { - let resultBids = JSON.parse(JSON.stringify(bids[0])); - let request = spec.buildRequests([bids[0]], {gdprConsent: {gdprApplies: true, consentString: 'concentDataString'}}); - let parsedUrl = parseUrl(request.url).query; - - assert.equal(parsedUrl.gdpr, 'true'); - assert.equal(parsedUrl.gdpr_consent, 'concentDataString'); - }); - - it('should not send GDPR Consent data to etarget if gdprApplies is false or undefined', function () { - let resultBids = JSON.parse(JSON.stringify(bids[0])); - let request = spec.buildRequests([bids[0]], {gdprConsent: {gdprApplies: false, consentString: 'concentDataString'}}); - let parsedUrl = parseUrl(request.url).query; - - assert.ok(!parsedUrl.gdpr); - assert.ok(!parsedUrl.gdpr_consent); - - 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'}}); - - assert.deepEqual(request.gdpr, { - gdpr: true, - gdpr_consent: 'concentDataString' - }); - - request = spec.buildRequests([bids[0]]); - assert.ok(!request.gdpr); - }); - }); - }); - - describe('interpretResponse', function () { - it('should respond with empty response when there is empty serverResponse', function () { - let result = spec.interpretResponse({ body: {} }, {}); - assert.deepEqual(result, []); - }); - it('should respond with empty response when response from server is not banner', function () { - serverResponse.body[0].response = 'not banner'; - serverResponse.body = [serverResponse.body[0]]; - bidRequest.bids = [bidRequest.bids[0]]; - let result = spec.interpretResponse(serverResponse, bidRequest); - - assert.deepEqual(result, []); - }); - it('should interpret server response correctly with one bid', function () { - serverResponse.body = [serverResponse.body[0]]; - bidRequest.bids = [bidRequest.bids[0]]; - let result = spec.interpretResponse(serverResponse, bidRequest)[0]; - - assert.equal(result.requestId, '2a0cf4e'); - assert.equal(result.cpm, 13.9); - assert.equal(result.width, 300); - assert.equal(result.height, 250); - assert.equal(result.currency, 'EUR'); - assert.equal(result.netRevenue, true); - assert.isNotNull(result.reason); - assert.equal(result.ttl, 360); - assert.equal(result.ad, ''); - assert.equal(result.transactionId, '5f33781f-9552-4ca1'); - }); - - it('should set correct netRevenue', function () { - serverResponse.body = [serverResponse.body[0]]; - bidRequest.bids = [bidRequest.bids[1]]; - bidRequest.netRevenue = 'net'; - let result = spec.interpretResponse(serverResponse, bidRequest)[0]; - - assert.equal(result.netRevenue, true); - }); - - it('should create bid response item for every requested item', function () { - let result = spec.interpretResponse(serverResponse, bidRequest); - assert.lengthOf(result, 5); - }); - - it('should create bid response with vast xml', function () { - const result = spec.interpretResponse(serverResponse, bidRequest)[3]; - assert.equal(result.vastXml, ''); - }); - - it('should create bid response with vast url', function () { - const result = spec.interpretResponse(serverResponse, bidRequest)[4]; - assert.equal(result.vastUrl, 'vast://url'); - }); - - it('should set mediaType on bid response', function () { - 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]); - } - }); - - it('should set default netRevenue as gross', function () { - bidRequest.netRevenue = 'gross'; - const result = spec.interpretResponse(serverResponse, bidRequest); - for (let i = 0; i < result.length; i++) { - assert.equal(result[i].netRevenue, true); - } - }); - - it('should set gdpr if it exist in bidRequest', function () { - bidRequest.gdpr = { - gdpr: true, - gdpr_consent: 'ERW342EIOWT34234KMGds' - }; - let result = spec.interpretResponse(serverResponse, bidRequest); - for (let i = 0; i < result.length; i++) { - assert.equal(result[i].gdpr, true); - assert.equal(result[i].gdpr_consent, 'ERW342EIOWT34234KMGds'); - }; - - bidRequest.gdpr = undefined; - result = spec.interpretResponse(serverResponse, bidRequest); - for (let i = 0; i < result.length; i++) { - assert.ok(!result[i].gdpr); - assert.ok(!result[i].gdpr_consent); - }; - }); - - describe('verifySizes', function () { - it('should respond with empty response when sizes doesn\'t match', function () { - serverResponse.body[0].response = 'banner'; - serverResponse.body[0].width = 100; - serverResponse.body[0].height = 150; - - serverResponse.body = [serverResponse.body[0]]; - bidRequest.bids = [bidRequest.bids[0]]; - let result = spec.interpretResponse(serverResponse, bidRequest); - - assert.equal(serverResponse.body.length, 1); - assert.equal(serverResponse.body[0].response, 'banner'); - assert.deepEqual(result, []); - }); - it('should respond with empty response when sizes as a strings doesn\'t match', function () { - serverResponse.body[0].response = 'banner'; - serverResponse.body[0].width = 100; - serverResponse.body[0].height = 150; - - serverResponse.body = [serverResponse.body[0]]; - bidRequest.bids = [bidRequest.bids[0]]; - - bidRequest.bids[0].sizes = [['101', '150']]; - let result = spec.interpretResponse(serverResponse, bidRequest); - - assert.equal(serverResponse.body.length, 1); - assert.equal(serverResponse.body[0].response, 'banner'); - assert.deepEqual(result, []); - }); - it('should support size dimensions as a strings', function () { - serverResponse.body[0].response = 'banner'; - serverResponse.body[0].width = 300; - serverResponse.body[0].height = 600; - - serverResponse.body = [serverResponse.body[0]]; - bidRequest.bids = [bidRequest.bids[0]]; - - bidRequest.bids[0].sizes = [['300', '250'], ['250', '300'], ['300', '600'], ['600', '300']] - let result = spec.interpretResponse(serverResponse, bidRequest); - - assert.equal(result[0].width, 300); - assert.equal(result[0].height, 600); - }); - }) - }); - - beforeEach(function () { - let sizes = [[250, 300], [300, 250], [300, 600]]; - let placementCode = ['div-01', 'div-02', 'div-03', 'div-04', 'div-05']; - let 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], - auctionId: '7aefb970-2045', - bidId: '2a0cf4e', - bidder: 'etarget', - bidderRequestId: '1ab8d9', - params: params[0], - tid: 45, - placementCode: placementCode[0], - sizes: [[300, 250], [250, 300], [300, 600], [600, 300]], - transactionId: '5f33781f-9552-4ca1' - }, - { - adUnitCode: placementCode[1], - auctionId: '7aefb970-2045', - bidId: '2a0cf5b', - bidder: 'etarget', - bidderRequestId: '1ab8d9', - params: params[1], - placementCode: placementCode[1], - sizes: [[300, 250], [250, 300], [300, 600], [600, 300]], - transactionId: '5f33781f-9552-4iuy' - }, - { - adUnitCode: placementCode[2], - auctionId: '7aefb970-2045', - bidId: '2a0cf6n', - bidder: 'etarget', - bidderRequestId: '1ab8d9', - params: params[2], - placementCode: placementCode[2], - sizes: [[300, 250], [250, 300], [300, 600], [600, 300]], - transactionId: '5f33781f-9552-7ev3' - }, - { - adUnitCode: placementCode[3], - auctionId: '7aefb970-2045', - bidId: '2a0cf6n', - bidder: 'etarget', - bidderRequestId: '1ab8d9', - params: params[2], - placementCode: placementCode[2], - sizes: [], - transactionId: '5f33781f-9552-7ev3' - }, - { - adUnitCode: placementCode[4], - auctionId: '7aefb970-2045', - bidId: '2a0cf6n', - bidder: 'etarget', - bidderRequestId: '1ab8d9', - params: params[2], - placementCode: placementCode[2], - sizes: [], - transactionId: '5f33781f-9552-7ev3' - }, - { - adUnitCode: placementCode[4], - auctionId: '7aefb970-2045', - bidId: '2a0cf6n', - bidder: 'etarget', - bidderRequestId: '1ab8d9', - params: params[3], - placementCode: placementCode[2], - sizes: [], - transactionId: '5f33781f-9552-7ev3' - }, - { - adUnitCode: placementCode[4], - auctionId: '7aefb970-2045', - bidId: '2a0cf6n', - bidder: 'etarget', - bidderRequestId: '1ab8d9', - params: params[4], - placementCode: placementCode[2], - sizes: [], - transactionId: '5f33781f-9552-7ev3' - } - ]; - serverResponse = { - body: [ - { - banner: '', - deal_id: '123abc', - height: 250, - response: 'banner', - width: 300, - win_bid: 13.9, - win_cur: 'EUR' - }, - { - banner: '', - deal_id: '123abc', - height: 300, - response: 'banner', - width: 250, - win_bid: 13.9, - win_cur: 'EUR' - }, - { - banner: '', - deal_id: '123abc', - height: 300, - response: 'banner', - width: 600, - win_bid: 10, - win_cur: 'EUR' - }, - { - deal_id: '123abc', - height: 300, - response: 'video', - width: 600, - win_bid: 10, - win_cur: 'EUR', - vast_content: '' - }, - { - deal_id: '123abc', - height: 300, - response: 'video', - width: 600, - win_bid: 10, - win_cur: 'EUR', - vast_link: 'vast://url' - } - ], - headers: {} - }; - bidRequest = { - bidder: 'etarget', - bids: bids, - method: 'POST', - url: 'url', - netRevenue: 'net' - }; - }); -}); - -function parseUrl(url) { - const parts = url.split('/'); - const query = parts.pop().split('&'); - return { - path: parts.join('/'), - items: query - .filter((i) => !~i.indexOf('=')) - .map((i) => atob(decodeURIComponent(i)) - .split('&') - .reduce(toObject, {})), - query: query - .filter((i) => ~i.indexOf('=')) - .map((i) => i.replace('?', '')) - .reduce(toObject, {}) - }; -} - -function toObject(cache, string) { - const keyValue = string.split('='); - cache[keyValue[0]] = keyValue[1]; - return cache; -} diff --git a/test/spec/modules/fabrickIdSystem_spec.js b/test/spec/modules/fabrickIdSystem_spec.js deleted file mode 100644 index c250c8e5e8b..00000000000 --- a/test/spec/modules/fabrickIdSystem_spec.js +++ /dev/null @@ -1,134 +0,0 @@ -import * as utils from '../../../src/utils.js'; -import {server} from '../../mocks/xhr.js'; - -import {fabrickIdSubmodule, appendUrl} from 'modules/fabrickIdSystem.js'; - -const defaultConfigParams = { - apiKey: '123', - e: 'abc', - p: ['def', 'hij'], - url: 'http://localhost:9999/test/mocks/fabrickId.json?' -}; -const responseHeader = {'Content-Type': 'application/json'} - -describe('Fabrick ID System', function() { - let logErrorStub; - - beforeEach(function () { - }); - - afterEach(function () { - }); - - it('should log an error if no configParams were passed into getId', function () { - logErrorStub = sinon.stub(utils, 'logError'); - fabrickIdSubmodule.getId(); - expect(logErrorStub.calledOnce).to.be.true; - logErrorStub.restore(); - }); - - it('should error on json parsing', function() { - logErrorStub = sinon.stub(utils, 'logError'); - let submoduleCallback = fabrickIdSubmodule.getId({ - name: 'fabrickId', - params: defaultConfigParams - }).callback; - let callBackSpy = sinon.spy(); - submoduleCallback(callBackSpy); - let request = server.requests[0]; - request.respond( - 200, - responseHeader, - '] this is not json {' - ); - expect(callBackSpy.calledOnce).to.be.true; - expect(logErrorStub.calledOnce).to.be.true; - logErrorStub.restore(); - }); - - it('should truncate the params', function() { - let r = ''; - for (let i = 0; i < 1500; i++) { - r += 'r'; - } - let configParams = Object.assign({}, defaultConfigParams, { - refererInfo: { - referer: r, - stack: ['s-0'], - canonicalUrl: 'cu-0' - } - }); - let submoduleCallback = fabrickIdSubmodule.getId({ - name: 'fabrickId', - params: configParams - }).callback; - let callBackSpy = sinon.spy(); - submoduleCallback(callBackSpy); - let request = server.requests[0]; - r = ''; - for (let i = 0; i < 1000 - 3; i++) { - r += 'r'; - } - expect(request.url).to.match(new RegExp(`r=${r}&r=`)); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should complete successfully', function() { - let configParams = Object.assign({}, defaultConfigParams, { - refererInfo: { - referer: 'r-0', - stack: ['s-0'], - canonicalUrl: 'cu-0' - } - }); - let submoduleCallback = fabrickIdSubmodule.getId({ - name: 'fabrickId', - params: configParams - }).callback; - let callBackSpy = sinon.spy(); - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.match(/r=r-0&r=s-0&r=cu-0&r=http/); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should truncate 2', function() { - let configParams = { - maxUrlLen: 10, - maxRefLen: 5, - maxSpaceAvailable: 2 - }; - - let url = appendUrl('', 'r', '123', configParams); - expect(url).to.equal('&r=12'); - - url = appendUrl('12345', 'r', '678', configParams); - expect(url).to.equal('12345&r=67'); - - url = appendUrl('12345678', 'r', '9', configParams); - expect(url).to.equal('12345678'); - - configParams.maxRefLen = 8; - url = appendUrl('', 'r', '1234&', configParams); - expect(url).to.equal('&r=1234'); - - url = appendUrl('', 'r', '123&', configParams); - expect(url).to.equal('&r=123'); - - url = appendUrl('', 'r', '12&', configParams); - expect(url).to.equal('&r=12%26'); - - url = appendUrl('', 'r', '1&&', configParams); - expect(url).to.equal('&r=1%26'); - }); -}); diff --git a/test/spec/modules/feedadBidAdapter_spec.js b/test/spec/modules/feedadBidAdapter_spec.js deleted file mode 100644 index 6b75af0d55d..00000000000 --- a/test/spec/modules/feedadBidAdapter_spec.js +++ /dev/null @@ -1,457 +0,0 @@ -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'; - -describe('FeedAdAdapter', function () { - describe('Public API', function () { - it('should have the FeedAd bidder code', function () { - expect(spec.code).to.equal(CODE); - }); - it('should only support video and banner ads', function () { - expect(spec.supportedMediaTypes).to.be.a('array'); - expect(spec.supportedMediaTypes).to.include(BANNER); - expect(spec.supportedMediaTypes).not.to.include(VIDEO); - expect(spec.supportedMediaTypes).not.to.include(NATIVE); - }); - it('should export the BidderSpec 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.onTimeout).to.be.a('function'); - expect(spec.onBidWon).to.be.a('function'); - }); - it('should export the TCF vendor ID', function () { - expect(spec.gvlid).to.equal(781); - }) - }); - - describe('isBidRequestValid', function () { - it('should detect missing params', function () { - let result = spec.isBidRequestValid({ - bidder: 'feedad', - sizes: [] - }); - expect(result).to.equal(false); - }); - it('should detect missing client token', function () { - let result = spec.isBidRequestValid({ - bidder: 'feedad', - sizes: [], - params: {placementId: 'placement'} - }); - expect(result).to.equal(false); - }); - it('should detect zero length client token', function () { - let result = spec.isBidRequestValid({ - bidder: 'feedad', - sizes: [], - params: {clientToken: '', placementId: 'placement'} - }); - expect(result).to.equal(false); - }); - it('should detect missing placement id', function () { - let result = spec.isBidRequestValid({ - bidder: 'feedad', - sizes: [], - params: {clientToken: 'clientToken'} - }); - expect(result).to.equal(false); - }); - it('should detect zero length placement id', function () { - let result = spec.isBidRequestValid({ - bidder: 'feedad', - sizes: [], - params: {clientToken: 'clientToken', placementId: ''} - }); - expect(result).to.equal(false); - }); - it('should detect too long placement id', function () { - var placementId = ''; - for (var i = 0; i < 300; i++) { - placementId += 'a'; - } - let result = spec.isBidRequestValid({ - bidder: 'feedad', - sizes: [], - params: {clientToken: 'clientToken', placementId} - }); - expect(result).to.equal(false); - }); - it('should detect invalid placement id', function () { - [ - 'placement id with spaces', - 'some|id', - 'PLACEMENTID', - 'placeme:ntId' - ].forEach(id => { - let result = spec.isBidRequestValid({ - bidder: 'feedad', - sizes: [], - params: {clientToken: 'clientToken', placementId: id} - }); - expect(result).to.equal(false); - }); - }); - it('should accept valid parameters', function () { - let result = spec.isBidRequestValid({ - bidder: 'feedad', - sizes: [], - params: {clientToken: 'clientToken', placementId: 'placement-id'} - }); - expect(result).to.equal(true); - }); - }); - - describe('buildRequests', function () { - const bidderRequest = { - refererInfo: { - referer: 'the referer' - }, - some: 'thing' - }; - - it('should accept empty lists', function () { - let result = spec.buildRequests([], bidderRequest); - expect(result).to.be.empty; - }); - it('should filter native media types', function () { - let bid = { - code: 'feedad', - mediaTypes: { - native: { - sizes: [[300, 250], [300, 600]], - } - }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} - }; - let result = spec.buildRequests([bid], bidderRequest); - expect(result).to.be.empty; - }); - it('should filter video media types without outstream context', function () { - let bid = { - code: 'feedad', - mediaTypes: { - video: { - context: 'instream' - } - }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} - }; - let result = spec.buildRequests([bid], bidderRequest); - expect(result).to.be.empty; - }); - it('should pass through outstream video media', function () { - let bid = { - code: 'feedad', - mediaTypes: { - video: { - context: 'outstream' - } - }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} - }; - let result = spec.buildRequests([bid], bidderRequest); - expect(result.data.bids).to.be.lengthOf(1); - expect(result.data.bids[0]).to.deep.equal(bid); - }); - it('should pass through banner media', function () { - let bid = { - code: 'feedad', - mediaTypes: { - banner: { - sizes: [[320, 250]] - } - }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} - }; - let result = spec.buildRequests([bid], bidderRequest); - expect(result.data.bids).to.be.lengthOf(1); - expect(result.data.bids[0]).to.deep.equal(bid); - }); - it('should detect empty media types', function () { - let bid = { - code: 'feedad', - mediaTypes: { - banner: undefined, - video: undefined, - native: undefined - }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} - }; - let result = spec.buildRequests([bid], bidderRequest); - expect(result).to.be.empty; - }); - it('should use POST', function () { - let bid = { - code: 'feedad', - mediaTypes: { - banner: { - sizes: [[320, 250]] - } - }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} - }; - let result = spec.buildRequests([bid], bidderRequest); - expect(result.method).to.equal('POST'); - }); - it('should use the correct URL', function () { - let bid = { - code: 'feedad', - mediaTypes: { - banner: { - sizes: [[320, 250]] - } - }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} - }; - let result = spec.buildRequests([bid], bidderRequest); - expect(result.url).to.equal('https://api.feedad.com/1/prebid/web/bids'); - }); - it('should specify the content type explicitly', function () { - let bid = { - code: 'feedad', - mediaTypes: { - banner: { - sizes: [[320, 250]] - } - }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} - }; - let result = spec.buildRequests([bid], bidderRequest); - expect(result.options).to.deep.equal({ - contentType: 'application/json' - }) - }); - it('should include the bidder request', function () { - let bid = { - code: 'feedad', - mediaTypes: { - banner: { - sizes: [[320, 250]] - } - }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} - }; - let result = spec.buildRequests([bid, bid, bid], bidderRequest); - expect(result.data).to.deep.include(bidderRequest); - }); - it('should detect missing bidder request parameter', function () { - let bid = { - code: 'feedad', - mediaTypes: { - banner: { - sizes: [[320, 250]] - } - }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} - }; - let result = spec.buildRequests([bid, bid, bid]); - expect(result).to.be.empty; - }); - it('should not include GDPR data if the bidder request has none available', function () { - let bid = { - code: 'feedad', - mediaTypes: { - banner: { - sizes: [[320, 250]] - } - }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} - }; - let result = spec.buildRequests([bid], bidderRequest); - expect(result.data.gdprApplies).to.be.undefined; - expect(result.data.consentIabTcf).to.be.undefined; - }); - it('should include GDPR data if the bidder requests contains it', function () { - let bid = { - code: 'feedad', - mediaTypes: { - banner: { - sizes: [[320, 250]] - } - }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} - }; - let request = Object.assign({}, bidderRequest, { - gdprConsent: { - consentString: 'the consent string', - gdprApplies: true - } - }); - let result = spec.buildRequests([bid], request); - expect(result.data.gdprApplies).to.equal(request.gdprConsent.gdprApplies); - expect(result.data.consentIabTcf).to.equal(request.gdprConsent.consentString); - }); - }); - - describe('interpretResponse', function () { - const body = [{ - foo: 'bar', - sub: { - obj: 5 - } - }, { - bar: 'foo' - }]; - - it('should convert string bodies to JSON', function () { - let result = spec.interpretResponse({body: JSON.stringify(body)}); - expect(result).to.deep.equal(body); - }); - - it('should pass through body objects', function () { - let result = spec.interpretResponse({body}); - expect(result).to.deep.equal(body); - }); - }); - - describe('event tracking calls', function () { - const clientToken = 'clientToken'; - const placementId = 'placement id'; - const auctionId = 'the auction id'; - const bidId = 'the bid id'; - const transactionId = 'the transaction id'; - const referer = 'the referer'; - const bidderRequest = { - refererInfo: { - referer: referer - }, - some: 'thing' - }; - const bid = { - 'bidder': 'feedad', - 'params': { - 'clientToken': 'fupp', - 'placementId': 'prebid-test' - }, - 'crumbs': { - 'pubcid': '6254a85f-bded-489a-9736-83c45d45ef1d' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': transactionId, - 'sizes': [ - [ - 300, - 250 - ] - ], - 'bidId': bidId, - 'bidderRequestId': '10739fe6fe2127', - 'auctionId': '5ac67dff-d971-4b56-84a3-345a87a1f786', - 'src': 'client', - 'bidRequestsCount': 1 - }; - const timeoutData = { - 'bidId': bidId, - 'bidder': 'feedad', - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'auctionId': auctionId, - 'params': [ - { - 'clientToken': clientToken, - 'placementId': placementId - } - ], - 'timeout': 3000 - }; - const bidWonData = { - 'bidderCode': 'feedad', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '3a4529aa05114d', - 'requestId': bidId, - 'mediaType': 'banner', - 'source': 'client', - 'cpm': 0.5, - 'ad': 'ad content', - 'ttl': 60, - 'creativeId': 'feedad-21-0', - 'netRevenue': true, - 'currency': 'EUR', - 'auctionId': auctionId, - 'responseTimestamp': 1558365914596, - 'requestTimestamp': 1558365914506, - 'bidder': 'feedad', - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'timeToRespond': 90, - 'pbLg': '0.50', - 'pbMg': '0.50', - 'pbHg': '0.50', - 'pbAg': '0.50', - 'pbDg': '0.50', - 'pbCg': '', - 'size': '300x250', - 'adserverTargeting': { - 'hb_bidder': 'feedad', - 'hb_adid': '3a4529aa05114d', - 'hb_pb': '0.50', - 'hb_size': '300x250', - 'hb_source': 'client', - 'hb_format': 'banner' - }, - 'status': 'rendered', - 'params': [ - { - 'clientToken': clientToken, - 'placementId': placementId - } - ] - }; - const cases = [ - ['onTimeout', timeoutData, 'prebid_bidTimeout'], - ['onBidWon', bidWonData, 'prebid_bidWon'], - ]; - - cases.forEach(([name, data, eventKlass]) => { - let subject = spec[name]; - describe(name + ' handler', function () { - it('should do nothing on empty data', function () { - subject(undefined); - subject(null); - expect(server.requests.length).to.equal(0); - }); - - it('should do nothing when bid metadata is not set', function () { - subject(data); - expect(server.requests.length).to.equal(0); - }); - - it('should send tracking params when correct metadata was set', function () { - spec.buildRequests([bid], bidderRequest); - let expectedData = { - app_hybrid: false, - client_token: clientToken, - placement_id: placementId, - klass: eventKlass, - prebid_auction_id: auctionId, - prebid_bid_id: bidId, - prebid_transaction_id: transactionId, - referer, - sdk_version: '1.0.2' - }; - subject(data); - expect(server.requests.length).to.equal(1); - let call = server.requests[0]; - 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;charset=utf-8'}); - }) - }); - }); - }); -}); diff --git a/test/spec/modules/fidelityBidAdapter_spec.js b/test/spec/modules/fidelityBidAdapter_spec.js deleted file mode 100644 index 304a98675b3..00000000000 --- a/test/spec/modules/fidelityBidAdapter_spec.js +++ /dev/null @@ -1,233 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/fidelityBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('FidelityAdapter', 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 () { - let bid = { - 'bidder': 'fidelity', - 'params': { - 'zoneid': '27248', - 'floor': '0.05', - 'server': 'x.fidelity-media.com', - }, - '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(bid)).to.equal(true); - }); - - it('should return true when required params found', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'zoneid': '27248', - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'zoneid': 0, - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidderRequest = { - bidderCode: 'fidelity', - requestId: 'c45dd708-a418-42ec-b8a7-b70a6c6fab0a', - bidderRequestId: '178e34bad3658f', - bids: [ - { - bidder: 'fidelity', - params: { - zoneid: '27248', - floor: '0.05', - server: 'x.fidelity-media.com', - }, - placementCode: '/19968336/header-bid-tag-0', - sizes: [[300, 250], [320, 50]], - bidId: '2ffb201a808da7', - bidderRequestId: '178e34bad3658f', - requestId: 'c45dd708-a418-42ec-b8a7-b70a6c6fab0a', - transactionId: 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b', - schain: { - ver: '1.0', - complete: 1, - nodes: [{ - asi: 'exchange1.com', - sid: '1234', - hp: 1, - rid: 'bid-request-1', - name: 'publisher', - domain: 'publisher.com' - }] - } - } - ], - start: 1472239426002, - auctionStart: 1472239426000, - timeout: 5000, - refererInfo: { - referer: 'http://test.com/index.html' - } - }; - - it('should add params to the request', function () { - let schainString = '1.0,1!exchange1.com,1234,1,bid-request-1,publisher,publisher.com'; - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - const payload = request.data; - expect(payload.from).to.exist; - expect(payload.v).to.exist; - expect(payload.requestid).to.exist; - expect(payload.impid).to.exist; - expect(payload.zoneid).to.exist; - expect(payload.floor).to.exist; - expect(payload.charset).to.exist; - expect(payload.subid).to.exist; - expect(payload.flashver).to.exist; - expect(payload.tmax).to.exist; - expect(payload.defloc).to.exist; - expect(payload.schain).to.exist.and.to.be.a('string'); - expect(payload.schain).to.equal(schainString); - }); - - it('should add consent information to the request - TCF v1', function () { - let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - let uspConsentString = '1YN-'; - bidderRequest.gdprConsent = { - gdprApplies: true, - allowAuctionWithoutConsent: true, - consentString: consentString, - vendorData: { - vendorConsents: { - '408': true - }, - }, - apiVersion: 1 - }; - bidderRequest.uspConsent = uspConsentString; - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - const payload = request.data; - expect(payload.gdpr).to.exist.and.to.be.a('number'); - expect(payload.gdpr).to.equal(1); - expect(payload.consent_str).to.exist.and.to.be.a('string'); - expect(payload.consent_str).to.equal(consentString); - expect(payload.consent_given).to.exist.and.to.be.a('number'); - expect(payload.consent_given).to.equal(1); - expect(payload.us_privacy).to.exist.and.to.be.a('string'); - expect(payload.us_privacy).to.equal(uspConsentString); - }); - - it('should add consent information to the request - TCF v2', function () { - let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - let uspConsentString = '1YN-'; - bidderRequest.gdprConsent = { - gdprApplies: true, - allowAuctionWithoutConsent: true, - consentString: consentString, - vendorData: { - vendor: { - consents: { - '408': true - } - }, - }, - apiVersion: 2 - }; - bidderRequest.uspConsent = uspConsentString; - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - const payload = request.data; - expect(payload.gdpr).to.exist.and.to.be.a('number'); - expect(payload.gdpr).to.equal(1); - expect(payload.consent_str).to.exist.and.to.be.a('string'); - expect(payload.consent_str).to.equal(consentString); - expect(payload.consent_given).to.exist.and.to.be.a('number'); - expect(payload.consent_given).to.equal(1); - expect(payload.us_privacy).to.exist.and.to.be.a('string'); - expect(payload.us_privacy).to.equal(uspConsentString); - }); - - it('sends bid request to ENDPOINT via GET', function () { - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(request.url).to.equal('https://x.fidelity-media.com/delivery/hb.php'); - expect(request.method).to.equal('GET'); - }); - }) - - describe('interpretResponse', function () { - let response = { - 'id': '543210', - 'seatbid': [ { - 'bid': [ { - 'id': '1111111', - 'impid': 'bidId-123456-1', - 'price': 0.09, - 'adm': '', - 'width': 728, - 'height': 90, - } ] - } ] - }; - - it('should get correct bid response', function () { - let expectedResponse = [ - { - requestId: 'bidId-123456-1', - creativeId: 'bidId-123456-1', - cpm: 0.09, - width: 728, - height: 90, - ad: '', - netRevenue: true, - currency: 'USD', - ttl: 360, - } - ]; - - let result = spec.interpretResponse({ body: response }); - expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); - }); - - it('handles nobid responses', function () { - let response = { - 'id': '543210', - 'seatbid': [ ] - }; - - let result = spec.interpretResponse({ body: response }); - expect(result.length).to.equal(0); - }); - }); - - describe('user sync', function () { - const syncUrl = 'https://x.fidelity-media.com/delivery/matches.php?type=iframe'; - - it('should register the sync iframe', function () { - expect(spec.getUserSyncs({})).to.be.undefined; - expect(spec.getUserSyncs({iframeEnabled: false})).to.be.undefined; - const options = spec.getUserSyncs({iframeEnabled: true}); - expect(options).to.not.be.undefined; - expect(options).to.have.lengthOf(1); - expect(options[0].type).to.equal('iframe'); - expect(options[0].url).to.equal(syncUrl); - }); - }); -}); diff --git a/test/spec/modules/fintezaAnalyticsAdapter_spec.js b/test/spec/modules/fintezaAnalyticsAdapter_spec.js deleted file mode 100644 index 4c76f79f518..00000000000 --- a/test/spec/modules/fintezaAnalyticsAdapter_spec.js +++ /dev/null @@ -1,235 +0,0 @@ -import fntzAnalyticsAdapter from 'modules/fintezaAnalyticsAdapter.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import { expect } from 'chai'; -import { parseUrl } from 'src/utils.js'; -import { server } from 'test/mocks/xhr.js'; - -let adapterManager = require('src/adapterManager').default; -let events = require('src/events'); -let constants = require('src/constants.json'); - -function setCookie(name, value, expires) { - document.cookie = name + '=' + value + - '; path=/' + - (expires ? ('; expires=' + expires.toUTCString()) : '') + - '; SameSite=Lax'; -} - -describe('finteza analytics adapter', function () { - const clientId = 'fntz-client-32145'; - const uniqCookie = '5045380421580287382'; - - beforeEach(function () { - setCookie('_fz_uniq', uniqCookie); - sinon.stub(events, 'getEvents').returns([]); - sinon.spy(fntzAnalyticsAdapter, 'track'); - - adapterManager.registerAnalyticsAdapter({ - code: 'finteza', - adapter: fntzAnalyticsAdapter - }); - - adapterManager.enableAnalytics({ - provider: 'finteza', - options: { - id: clientId, // Client ID (required) - bidRequestTrack: 'Bid Request %BIDDER%', - bidResponseTimeTrack: 'Bid Response Time %bidder%', - bidResponsePriceTrack: 'Bid Response Price %bidder%', - bidTimeoutTrack: 'Bid Timeout %Bidder%', - bidWonTrack: 'Bid Won %BIDDER%', - } - }); - }); - - afterEach(function () { - setCookie('_fz_uniq', '', new Date(0)); - events.getEvents.restore(); - fntzAnalyticsAdapter.track.restore(); - fntzAnalyticsAdapter.disableAnalytics(); - }); - - describe('track', () => { - describe('bid request', () => { - it('builds and sends data', function () { - const bidderCode = 'Bidder789'; - const pauctionId = '5018eb39-f900-4370-b71e-3bb5b48d324f'; - - const bidRequest = { - bidderCode: bidderCode, - auctionId: pauctionId, - bidderRequestId: '1a6fc81528d0f6', - bids: [{ - bidder: bidderCode, - placementCode: 'container-1', - bidId: '208750227436c1', - bidderRequestId: '1a6fc81528d0f6', - auctionId: pauctionId, - startTime: 1509369418389, - sizes: [[300, 250]], - }], - auctionStart: 1509369418387, - timeout: 3000, - start: 1509369418389 - }; - - // Emit the events with the "real" arguments - events.emit(constants.EVENTS.BID_REQUESTED, bidRequest); - - expect(server.requests.length).to.equal(1); - - expect(server.requests[0].method).to.equal('GET'); - expect(server.requests[0].withCredentials).to.equal(true); - - const url = parseUrl(server.requests[0].url); - - expect(url.protocol).to.equal('https'); - expect(url.hostname).to.equal('content.mql5.com'); - expect(url.pathname).to.equal('/tr'); - expect(url.search.id).to.equal(clientId); - expect(url.search.fz_uniq).to.equal(uniqCookie); - expect(decodeURIComponent(url.search.event)).to.equal(`Bid Request ${bidderCode.toUpperCase()}`); - - sinon.assert.callCount(fntzAnalyticsAdapter.track, 1); - }); - }); - - describe('bid response', () => { - it('builds and sends data', function () { - const bidderCode = 'Bidder789'; - const pauctionId = '5018eb39-f900-4370-b71e-3bb5b48d324f'; - - const timeToRespond = 443; - const cpm = 0.015; - - const bidResponse = { - bidderCode: bidderCode, - adId: '208750227436c1', - cpm: cpm, - auctionId: pauctionId, - responseTimestamp: 1509369418832, - requestTimestamp: 1509369418389, - bidder: bidderCode, - timeToRespond: timeToRespond, - size: '300x250', - width: 300, - height: 250, - }; - - // Emit the events with the "real" arguments - events.emit(constants.EVENTS.BID_RESPONSE, bidResponse); - - expect(server.requests.length).to.equal(2); - - expect(server.requests[0].method).to.equal('GET'); - expect(server.requests[0].withCredentials).to.equal(true); - - let url = parseUrl(server.requests[0].url); - - expect(url.protocol).to.equal('https'); - expect(url.hostname).to.equal('content.mql5.com'); - expect(url.pathname).to.equal('/tr'); - expect(url.search.id).to.equal(clientId); - expect(url.search.fz_uniq).to.equal(uniqCookie); - expect(decodeURIComponent(url.search.event)).to.equal(`Bid Response Price ${bidderCode.toLowerCase()}`); - expect(url.search.value).to.equal(String(cpm)); - expect(url.search.unit).to.equal('usd'); - - expect(server.requests[1].method).to.equal('GET'); - expect(server.requests[1].withCredentials).to.equal(true); - - url = parseUrl(server.requests[1].url); - - expect(url.protocol).to.equal('https'); - expect(url.hostname).to.equal('content.mql5.com'); - expect(url.pathname).to.equal('/tr'); - expect(url.search.id).to.equal(clientId); - expect(url.search.fz_uniq).to.equal(uniqCookie); - expect(decodeURIComponent(url.search.event)).to.equal(`Bid Response Time ${bidderCode.toLowerCase()}`); - expect(url.search.value).to.equal(String(timeToRespond)); - expect(url.search.unit).to.equal('ms'); - - sinon.assert.callCount(fntzAnalyticsAdapter.track, 1); - }); - }); - - describe('bid won', () => { - it('builds and sends data', function () { - const bidderCode = 'Bidder789'; - const pauctionId = '5018eb39-f900-4370-b71e-3bb5b48d324f'; - - const cpm = 0.015; - - const bidWon = { - bidderCode: bidderCode, - cpm: cpm, - adId: 'adIdData', - ad: 'adContent', - auctionId: pauctionId, - width: 300, - height: 250 - } - - // Emit the events with the "real" arguments - events.emit(constants.EVENTS.BID_WON, bidWon); - - expect(server.requests.length).to.equal(1); - - expect(server.requests[0].method).to.equal('GET'); - expect(server.requests[0].withCredentials).to.equal(true); - - const url = parseUrl(server.requests[0].url); - - expect(url.protocol).to.equal('https'); - expect(url.hostname).to.equal('content.mql5.com'); - expect(url.pathname).to.equal('/tr'); - expect(url.search.id).to.equal(clientId); - expect(url.search.fz_uniq).to.equal(uniqCookie); - expect(decodeURIComponent(url.search.event)).to.equal(`Bid Won ${bidderCode.toUpperCase()}`); - expect(url.search.value).to.equal(String(cpm)); - expect(url.search.unit).to.equal('usd'); - - sinon.assert.callCount(fntzAnalyticsAdapter.track, 1); - }); - }); - - describe('bid timeout', () => { - it('builds and sends data', function () { - const bidderCode = 'biDDer789'; - const pauctionId = '5018eb39-f900-4370-b71e-3bb5b48d324f'; - - const timeout = 2540; - - const bidTimeout = [ - { - bidId: '208750227436c1', - bidder: bidderCode, - auctionId: pauctionId, - timeout: timeout, - } - ]; - - // Emit the events with the "real" arguments - events.emit(constants.EVENTS.BID_TIMEOUT, bidTimeout); - - expect(server.requests.length).to.equal(1); - - expect(server.requests[0].method).to.equal('GET'); - expect(server.requests[0].withCredentials).to.equal(true); - - const url = parseUrl(server.requests[0].url); - - expect(url.protocol).to.equal('https'); - expect(url.hostname).to.equal('content.mql5.com'); - expect(url.pathname).to.equal('/tr'); - expect(url.search.id).to.equal(clientId); - expect(url.search.fz_uniq).to.equal(uniqCookie); - expect(decodeURIComponent(url.search.event)).to.equal(`Bid Timeout Bidder789`); - expect(url.search.value).to.equal(String(timeout)); - expect(url.search.unit).to.equal('ms'); - - sinon.assert.callCount(fntzAnalyticsAdapter.track, 1); - }); - }); - }); -}); diff --git a/test/spec/modules/fluctBidAdapter_spec.js b/test/spec/modules/fluctBidAdapter_spec.js deleted file mode 100644 index 6530a3c36cf..00000000000 --- a/test/spec/modules/fluctBidAdapter_spec.js +++ /dev/null @@ -1,201 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/fluctBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {config} from 'src/config.js'; - -describe('fluctAdapter', 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 bid = { - bidder: 'fluct', - params: { - dfpUnitCode: '/1000/dfp_unit_code', - tagId: '10000:100000001', - groupId: '1000000002', - } - }; - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return true when dfpUnitCode is not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - tagId: '10000:100000001', - groupId: '1000000002', - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when groupId is not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - dfpUnitCode: '/1000/dfp_unit_code', - tagId: '10000:100000001', - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const bidRequests = [{ - bidder: 'fluct', - params: { - dfpUnitCode: '/100000/unit_code', - tagId: '10000:100000001', - groupId: '1000000002', - }, - adUnitCode: '/10000/unit_code', - sizes: [[300, 250], [336, 280]], - bidId: '237f4d1a293f99', - bidderRequestId: '1a857fa34c1c96', - auctionId: 'a297d1aa-7900-4ce4-a0aa-caa8d46c4af7', - transactionId: '00b2896c-2731-4f01-83e4-7a3ad5da13b6', - }]; - const bidderRequest = { - refererInfo: { - referer: 'http://example.com' - } - }; - - it('sends bid request to ENDPOINT via POST', function () { - const request = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(request.method).to.equal('POST'); - }); - }); - - describe('interpretResponse', function() { - const callBeaconSnippet = ''; - - it('should get correct bid response', function() { - const bidRequest = { - bidder: 'fluct', - params: { - dfpUnitCode: '/10000/unit_code', - tagid: '10000:100000001', - groupId: '1000000002', - }, - adUnitCode: '/10000/unit_code', - sizes: [[300, 250], [336, 280]], - bidId: '237f4d1a293f99', - bidderRequestId: '1a857fa34c1c96', - auctionId: 'a297d1aa-7900-4ce4-a0aa-caa8d46c4af7', - transactionId: '00b2896c-2731-4f01-83e4-7a3ad5da13b6', - }; - - const serverResponse = { - body: { - id: '237f4d1a293f99', - cur: 'JPY', - seatbid: [{ - bid: [{ - price: 100, - w: 300, - h: 250, - adm: '', - burl: 'https://i.adingo.jp/?test=1&et=hb&bidid=237f4d1a293f99', - crid: 'test_creative', - }] - }] - } - }; - - const expectedResponse = [ - { - bidderCode: 'fluct', - requestId: '237f4d1a293f99', - currency: 'JPY', - cpm: 100, - netRevenue: true, - width: 300, - height: 250, - creativeId: 'test_creative', - ttl: 300, - ad: '' + callBeaconSnippet, - } - ]; - - const result = spec.interpretResponse(serverResponse, bidRequest); - expect(result).to.have.lengthOf(1); - expect(result).to.deep.have.same.members(expectedResponse); - }); - - it('should get correct bid response with dealId', function() { - const bidRequest = { - bidder: 'fluct', - params: { - dfpUnitCode: '/10000/unit_code', - tagid: '10000:100000001', - groupId: '1000000002' - }, - adUnitCode: '/10000/unit_code', - sizes: [[300, 250], [336, 280]], - bidId: '237f4d1a293f99', - bidderRequestId: '1a857fa34c1c96', - auctionId: 'a297d1aa-7900-4ce4-a0aa-caa8d46c4af7', - transactionId: '00b2896c-2731-4f01-83e4-7a3ad5da13b6', - }; - - const serverResponse = { - body: { - id: '237f4d1a293f99', - cur: 'JPY', - seatbid: [{ - bid: [{ - price: 100, - w: 300, - h: 250, - adm: '', - burl: 'https://i.adingo.jp/?test=1&et=hb&bidid=237f4d1a293f99', - crid: 'test_creative', - dealid: 'test_deal', - }] - }] - } - }; - - const expectedResponse = [ - { - bidderCode: 'fluct', - requestId: '237f4d1a293f99', - currency: 'JPY', - cpm: 100, - netRevenue: true, - width: 300, - height: 250, - creativeId: 'test_creative', - ttl: 300, - ad: '' + callBeaconSnippet, - dealId: 'test_deal', - } - ]; - - const result = spec.interpretResponse(serverResponse, bidRequest); - expect(result).to.have.lengthOf(1); - expect(result).to.deep.have.same.members(expectedResponse); - }); - - it('should get empty response when bid server returns 204', function() { - expect(spec.interpretResponse({})).to.be.empty; - }); - }); -}); diff --git a/test/spec/modules/fpdModule_spec.js b/test/spec/modules/fpdModule_spec.js deleted file mode 100644 index c2a6c41835e..00000000000 --- a/test/spec/modules/fpdModule_spec.js +++ /dev/null @@ -1,464 +0,0 @@ -import {expect} from 'chai'; -import * as utils from 'src/utils.js'; -import {config} from 'src/config.js'; -import {getRefererInfo} from 'src/refererDetection.js'; -import {init, registerSubmodules} from 'modules/fpdModule/index.js'; -import * as enrichmentModule from 'modules/enrichmentFpdModule.js'; -import * as validationModule from 'modules/validationFpdModule/index.js'; - -let enrichments = { - name: 'enrichments', - queue: 2, - init: enrichmentModule.initSubmodule -}; -let validations = { - name: 'validations', - queue: 1, - init: validationModule.initSubmodule -}; - -describe('the first party data module', function () { - let ortb2 = { - device: { - h: 911, - w: 1733 - }, - user: { - data: [{ - segment: [{ - id: 'foo' - }], - name: 'bar', - ext: 'string' - }] - }, - site: { - content: { - data: [{ - segment: [{ - id: 'test' - }], - name: 'content', - ext: { - foo: 'bar' - } - }] - } - } - }; - - let conf = { - device: { - h: 500, - w: 750 - }, - user: { - keywords: 'test1, test2', - gender: 'f', - data: [{ - segment: [{ - id: 'test' - }], - name: 'alt' - }] - }, - site: { - ref: 'domain.com', - page: 'www.domain.com/test', - ext: { - data: { - inventory: ['first'] - } - } - } - }; - - afterEach(function () { - config.resetConfig(); - }); - - describe('first party data intitializing', function () { - let width; - let widthStub; - let height; - let heightStub; - let querySelectorStub; - let canonical; - let keywords; - - before(function() { - canonical = document.createElement('link'); - canonical.rel = 'canonical'; - keywords = document.createElement('meta'); - keywords.name = 'keywords'; - }); - - beforeEach(function() { - querySelectorStub = sinon.stub(window.top.document, 'querySelector'); - querySelectorStub.withArgs("link[rel='canonical']").returns(canonical); - querySelectorStub.withArgs("meta[name='keywords']").returns(keywords); - widthStub = sinon.stub(window.top, 'innerWidth').get(function () { - return width; - }); - heightStub = sinon.stub(window.top, 'innerHeight').get(function () { - return height; - }); - }); - - afterEach(function() { - widthStub.restore(); - heightStub.restore(); - querySelectorStub.restore(); - canonical = document.createElement('link'); - canonical.rel = 'canonical'; - keywords = document.createElement('meta'); - keywords.name = 'keywords'; - }); - - it('sets default referer and dimension values to ortb2 data', function () { - registerSubmodules(enrichments); - registerSubmodules(validations); - - let validated; - - width = 1120; - height = 750; - - init(); - - validated = config.getConfig('ortb2'); - expect(validated.site.ref).to.equal(getRefererInfo().referer); - expect(validated.site.page).to.be.undefined; - expect(validated.site.domain).to.be.undefined; - expect(validated.device).to.deep.equal({w: 1120, h: 750}); - expect(validated.site.keywords).to.be.undefined; - }); - - it('sets page and domain values to ortb2 data if canonical link exists', function () { - let validated; - - canonical.href = 'https://www.domain.com/path?query=12345'; - - init(); - - validated = config.getConfig('ortb2'); - expect(validated.site.ref).to.equal(getRefererInfo().referer); - expect(validated.site.page).to.equal('https://www.domain.com/path?query=12345'); - expect(validated.site.domain).to.equal('domain.com'); - expect(validated.device).to.deep.to.equal({w: 1120, h: 750}); - expect(validated.site.keywords).to.be.undefined; - }); - - it('sets keyword values to ortb2 data if keywords meta exists', function () { - let validated; - - keywords.content = 'value1,value2,value3'; - - init(); - - validated = config.getConfig('ortb2'); - expect(validated.site.ref).to.equal(getRefererInfo().referer); - expect(validated.site.page).to.be.undefined; - expect(validated.site.domain).to.be.undefined; - expect(validated.device).to.deep.to.equal({w: 1120, h: 750}); - expect(validated.site.keywords).to.equal('value1,value2,value3'); - }); - - it('only sets values that do not exist in ortb2 config', function () { - let validated; - - config.setConfig({ortb2: {site: {ref: 'https://testpage.com', domain: 'newDomain.com'}}}); - - init(); - - validated = config.getConfig('ortb2'); - expect(validated.site.ref).to.equal('https://testpage.com'); - expect(validated.site.page).to.be.undefined; - expect(validated.site.domain).to.equal('newDomain.com'); - expect(validated.device).to.deep.to.equal({w: 1120, h: 750}); - expect(validated.site.keywords).to.be.undefined; - }); - - it('filters ortb2 data that is set', function () { - let validated; - let conf = { - ortb2: { - user: { - data: {}, - gender: 'f', - age: 45 - }, - site: { - content: { - data: [{ - segment: { - test: 1 - }, - name: 'foo' - }, { - segment: [{ - id: 'test' - }, { - id: 3 - }], - name: 'bar' - }] - } - }, - device: { - w: 1, - h: 1 - } - } - }; - - config.setConfig(conf); - canonical.href = 'https://www.domain.com/path?query=12345'; - width = 1120; - height = 750; - - init(); - - validated = config.getConfig('ortb2'); - expect(validated.site.ref).to.equal(getRefererInfo().referer); - expect(validated.site.page).to.equal('https://www.domain.com/path?query=12345'); - expect(validated.site.domain).to.equal('domain.com'); - expect(validated.site.content.data).to.deep.equal([{segment: [{id: 'test'}], name: 'bar'}]); - expect(validated.user.data).to.be.undefined; - expect(validated.device).to.deep.to.equal({w: 1, h: 1}); - expect(validated.site.keywords).to.be.undefined; - }); - - it('should not overwrite existing data with default settings', function () { - let validated; - let conf = { - ortb2: { - site: { - ref: 'https://referer.com' - } - } - }; - - config.setConfig(conf); - - init(); - - validated = config.getConfig('ortb2'); - expect(validated.site.ref).to.equal('https://referer.com'); - }); - - it('should allow overwrite default data with setConfig', function () { - let validated; - let conf = { - ortb2: { - site: { - ref: 'https://referer.com' - } - } - }; - - config.setConfig(conf); - - init(); - - validated = config.getConfig('ortb2'); - expect(validated.site.ref).to.equal('https://referer.com'); - }); - - it('should filter all data', function () { - let validated; - let conf = { - imp: [], - site: { - name: 123, - domain: 456, - page: 789, - ref: 987, - keywords: ['keywords'], - search: 654, - cat: 'cat', - sectioncat: 'sectioncat', - pagecat: 'pagecat', - content: { - data: [{ - name: 1, - segment: [] - }] - } - }, - user: { - yob: 'twenty', - gender: 0, - keywords: ['foobar'], - data: ['test'] - }, - device: [800, 450], - cur: { - adServerCurrency: 'USD' - } - }; - - config.setConfig({'firstPartyData': {skipEnrichments: true}}); - - config.setConfig({ortb2: conf}); - - init(); - - validated = config.getConfig('ortb2'); - expect(validated).to.deep.equal({}); - }); - - it('should add enrichments but not alter any arbitrary ortb2 data', function () { - let validated; - let conf = { - site: { - ext: { - data: { - inventory: ['value1'] - } - } - }, - user: { - ext: { - data: { - visitor: ['value2'] - } - } - }, - cur: ['USD'] - }; - - config.setConfig({ortb2: conf}); - - init(); - - validated = config.getConfig('ortb2'); - expect(validated.site.ref).to.equal(getRefererInfo().referer); - expect(validated.site.ext.data).to.deep.equal({inventory: ['value1']}); - expect(validated.user.ext.data).to.deep.equal({visitor: ['value2']}); - expect(validated.cur).to.deep.equal(['USD']); - }); - - it('should filter bidderConfig data', function () { - let validated; - let conf = { - bidders: ['bidderA', 'bidderB'], - config: { - ortb2: { - site: { - keywords: 'other', - ref: 'https://domain.com' - }, - user: { - keywords: 'test', - data: [{ - segment: [{id: 4}], - name: 't' - }] - } - } - } - }; - - config.setBidderConfig(conf); - - init(); - - validated = config.getBidderConfig(); - expect(validated.bidderA.ortb2).to.not.be.undefined; - expect(validated.bidderA.ortb2.user.data).to.be.undefined; - expect(validated.bidderA.ortb2.user.keywords).to.equal('test'); - expect(validated.bidderA.ortb2.site.keywords).to.equal('other'); - expect(validated.bidderA.ortb2.site.ref).to.equal('https://domain.com'); - }); - - it('should not filter bidderConfig data as it is valid', function () { - let validated; - let conf = { - bidders: ['bidderA', 'bidderB'], - config: { - ortb2: { - site: { - keywords: 'other', - ref: 'https://domain.com' - }, - user: { - keywords: 'test', - data: [{ - segment: [{id: 'data1_id'}], - name: 'data1' - }] - } - } - } - }; - - config.setBidderConfig(conf); - - init(); - - validated = config.getBidderConfig(); - expect(validated.bidderA.ortb2).to.not.be.undefined; - expect(validated.bidderA.ortb2.user.data).to.deep.equal([{segment: [{id: 'data1_id'}], name: 'data1'}]); - expect(validated.bidderA.ortb2.user.keywords).to.equal('test'); - expect(validated.bidderA.ortb2.site.keywords).to.equal('other'); - expect(validated.bidderA.ortb2.site.ref).to.equal('https://domain.com'); - }); - - it('should not set default values if skipEnrichments is turned on', function () { - let validated; - config.setConfig({'firstPartyData': {skipEnrichments: true}}); - - let conf = { - site: { - keywords: 'other' - }, - user: { - keywords: 'test', - data: [{ - segment: [{id: 'data1_id'}], - name: 'data1' - }] - } - } - ; - - config.setConfig({ortb2: conf}); - - init(); - - validated = config.getConfig(); - expect(validated.ortb2).to.not.be.undefined; - expect(validated.ortb2.device).to.be.undefined; - expect(validated.ortb2.site.ref).to.be.undefined; - expect(validated.ortb2.site.page).to.be.undefined; - expect(validated.ortb2.site.domain).to.be.undefined; - }); - - it('should not validate ortb2 data if skipValidations is turned on', function () { - let validated; - config.setConfig({'firstPartyData': {skipValidations: true}}); - - let conf = { - site: { - keywords: 'other' - }, - user: { - keywords: 'test', - data: [{ - segment: [{id: 'nonfiltered'}] - }] - } - } - ; - - config.setConfig({ortb2: conf}); - - init(); - - validated = config.getConfig(); - expect(validated.ortb2).to.not.be.undefined; - expect(validated.ortb2.user.data).to.deep.equal([{segment: [{id: 'nonfiltered'}]}]); - }); - }); -}); diff --git a/test/spec/modules/freeWheelAdserverVideo_spec.js b/test/spec/modules/freeWheelAdserverVideo_spec.js deleted file mode 100644 index 0a215092e18..00000000000 --- a/test/spec/modules/freeWheelAdserverVideo_spec.js +++ /dev/null @@ -1,350 +0,0 @@ -import { expect } from 'chai'; -import { adpodUtils } from 'modules/freeWheelAdserverVideo.js'; -import { auctionManager } from 'src/auctionManager.js'; -import { config } from 'src/config.js'; -import { server } from 'test/mocks/xhr.js'; - -describe('freeWheel adserver module', function() { - let amStub; - let amGetAdUnitsStub; - - before(function () { - let adUnits = [{ - code: 'preroll_1', - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 60, - durationRangeSec: [15, 30], - requireExactDuration: true - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 14542875, - } - } - ] - }, { - code: 'midroll_1', - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 60, - durationRangeSec: [15, 30], - requireExactDuration: true - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 14542875, - } - } - ] - }]; - - amGetAdUnitsStub = sinon.stub(auctionManager, 'getAdUnits'); - amGetAdUnitsStub.returns(adUnits); - amStub = sinon.stub(auctionManager, 'getBidsReceived'); - }); - - beforeEach(function () { - config.setConfig({ - adpod: { - brandCategoryExclusion: false, - deferCaching: false - } - }); - }) - - afterEach(function() { - config.resetConfig(); - }); - - after(function () { - amGetAdUnitsStub.restore(); - amStub.restore(); - }); - - it('should return targeting for all adunits', function() { - amStub.returns(getBidsReceived()); - let targeting; - adpodUtils.getTargeting({ - callback: function(errorMsg, targetingResult) { - targeting = targetingResult; - } - }); - - expect(targeting['preroll_1'].length).to.equal(3); - expect(targeting['midroll_1'].length).to.equal(3); - }); - - it('should return targeting for passed adunit code', function() { - amStub.returns(getBidsReceived()); - let targeting; - adpodUtils.getTargeting({ - codes: ['preroll_1'], - callback: function(errorMsg, targetingResult) { - targeting = targetingResult; - } - }); - - expect(targeting['preroll_1']).to.exist; - expect(targeting['midroll_1']).to.not.exist; - }); - - it('should only use adpod bids', function() { - let bannerBid = [{ - 'ad': 'creative', - 'cpm': '1.99', - 'width': 300, - 'height': 250, - 'requestId': '1', - 'creativeId': 'some-id', - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 360, - 'bidderCode': 'appnexus', - 'statusMessage': 'Bid available', - 'adId': '28f24ced14586c', - 'adUnitCode': 'preroll_1' - }]; - amStub.returns(getBidsReceived().concat(bannerBid)); - let targeting; - adpodUtils.getTargeting({ - callback: function(errorMsg, targetingResult) { - targeting = targetingResult; - } - }); - - expect(targeting['preroll_1'].length).to.equal(3); - expect(targeting['midroll_1'].length).to.equal(3); - }); - - it('should return unique category bids when competitive exclusion is enabled', function() { - config.setConfig({ - adpod: { - brandCategoryExclusion: true, - deferCaching: false - } - }); - amStub.returns([ - createBid(10, 'preroll_1', 30, '10.00_395_30s', '123', '395'), - createBid(15, 'preroll_1', 30, '15.00_395_30s', '123', '395'), - createBid(15, 'midroll_1', 60, '15.00_406_60s', '123', '406'), - createBid(10, 'preroll_1', 30, '10.00_395_30s', '123', '395') - ]); - let targeting; - adpodUtils.getTargeting({ - callback: function(errorMsg, targetingResult) { - targeting = targetingResult; - } - }); - - expect(targeting['preroll_1'].length).to.equal(3); - expect(targeting['midroll_1'].length).to.equal(2); - }); - - it('should only select bids less than adpod duration', function() { - amStub.returns([ - createBid(10, 'preroll_1', 90, '10.00_395_90s', '123', '395'), - createBid(15, 'preroll_1', 90, '15.00_395_90s', '123', '395'), - createBid(15, 'midroll_1', 90, '15.00_406_90s', '123', '406') - ]); - let targeting; - adpodUtils.getTargeting({ - callback: function(errorMsg, targetingResult) { - targeting = targetingResult; - } - }); - - expect(targeting['preroll_1']).to.be.empty; - expect(targeting['midroll_1']).to.be.empty; - }); - - it('should select bids when deferCaching is enabled', function() { - config.setConfig({ - adpod: { - deferCaching: true - } - }); - amStub.returns(getBidsReceived()); - let targeting; - adpodUtils.getTargeting({ - callback: function(errorMsg, targetingResult) { - targeting = targetingResult; - } - }); - - server.requests[0].respond( - 200, - { 'Content-Type': 'text/plain' }, - JSON.stringify({'responses': getBidsReceived().slice(0, 4)}) - ); - - expect(targeting['preroll_1'].length).to.equal(3); - expect(targeting['midroll_1'].length).to.equal(3); - }); - - it('should prioritize bids with deal', function() { - config.setConfig({ - adpod: { - deferCaching: true, - prioritizeDeals: true - } - }); - - let tier6Bid = createBid(10, 'preroll_1', 15, 'tier6_395_15s', '123', '395'); - tier6Bid['video']['dealTier'] = 'tier6' - - let tier7Bid = createBid(11, 'preroll_1', 45, 'tier7_395_15s', '123', '395'); - tier7Bid['video']['dealTier'] = 'tier7' - - let bidsReceived = [ - tier6Bid, - tier7Bid, - createBid(15, 'preroll_1', 90, '15.00_395_90s', '123', '395'), - ] - amStub.returns(bidsReceived); - let targeting; - adpodUtils.getTargeting({ - callback: function(errorMsg, targetingResult) { - targeting = targetingResult; - } - }); - - server.requests[0].respond( - 200, - { 'Content-Type': 'text/plain' }, - 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'}); - }); - - it('should apply minDealTier to bids if configured', function() { - config.setConfig({ - adpod: { - deferCaching: true, - prioritizeDeals: true, - dealTier: { - 'appnexus': { - prefix: 'tier', - minDealTier: 5 - } - } - } - }); - - let tier2Bid = createBid(10, 'preroll_1', 15, 'tier2_395_15s', '123', '395'); - tier2Bid['video']['dealTier'] = 2 - tier2Bid['adserverTargeting']['hb_pb'] = '10.00' - - let tier7Bid = createBid(11, 'preroll_1', 45, 'tier7_395_15s', '123', '395'); - tier7Bid['video']['dealTier'] = 7 - tier7Bid['adserverTargeting']['hb_pb'] = '11.00' - - let bid = createBid(15, 'preroll_1', 15, '15.00_395_90s', '123', '395'); - bid['adserverTargeting']['hb_pb'] = '15.00' - - let bidsReceived = [ - tier2Bid, - tier7Bid, - bid - ] - amStub.returns(bidsReceived); - let targeting; - adpodUtils.getTargeting({ - callback: function(errorMsg, targetingResult) { - targeting = targetingResult; - } - }); - - server.requests[0].respond( - 200, - { 'Content-Type': 'text/plain' }, - 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'}); - }) -}); - -function getBidsReceived() { - return [ - createBid(10, 'preroll_1', 15, '10.00_395_15s', '123', '395'), - createBid(15, 'preroll_1', 15, '15.00_395_15s', '123', '395'), - createBid(15, 'midroll_1', 30, '15.00_406_30s', '123', '406'), - createBid(5, 'midroll_1', 5, '5.00_406_5s', '123', '406'), - createBid(20, 'midroll_1', 60, '20.00_406_60s', '123', '406'), - ] -} - -function createBid(cpm, adUnitCode, durationBucket, priceIndustryDuration, uuid, industry) { - return { - 'bidderCode': 'appnexus', - 'width': 640, - 'height': 360, - 'statusMessage': 'Bid available', - 'adId': '28f24ced14586c', - 'mediaType': 'video', - 'source': 'client', - 'requestId': '28f24ced14586c', - 'cpm': cpm, - 'creativeId': 97517771, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 3600, - 'adUnitCode': adUnitCode, - 'video': { - 'context': 'adpod', - 'durationBucket': durationBucket - }, - 'appnexus': { - 'buyerMemberId': 9325 - }, - 'vastUrl': 'http://some-vast-url.com', - 'vastImpUrl': 'http://some-vast-imp-url.com', - 'auctionId': 'ec266b31-d652-49c5-8295-e83fafe5532b', - 'responseTimestamp': 1548442460888, - 'requestTimestamp': 1548442460827, - 'bidder': 'appnexus', - 'timeToRespond': 61, - 'pbLg': '5.00', - 'pbMg': '5.00', - 'pbHg': '5.00', - 'pbAg': '5.00', - 'pbDg': '5.00', - 'pbCg': '', - 'size': '640x360', - 'adserverTargeting': { - 'hb_bidder': 'appnexus', - 'hb_adid': '28f24ced14586c', - 'hb_pb': '5.00', - 'hb_size': '640x360', - 'hb_source': 'client', - 'hb_format': 'video', - 'hb_pb_cat_dur': priceIndustryDuration, - 'hb_cache_id': uuid - }, - 'customCacheKey': `${priceIndustryDuration}_${uuid}`, - 'meta': { - 'primaryCatId': 'iab-1', - 'adServerCatId': industry - }, - 'videoCacheKey': '4cf395af-8fee-4960-af0e-88d44e399f14' - } -} diff --git a/test/spec/modules/freewheel-sspBidAdapter_spec.js b/test/spec/modules/freewheel-sspBidAdapter_spec.js deleted file mode 100644 index e416bd1c26b..00000000000 --- a/test/spec/modules/freewheel-sspBidAdapter_spec.js +++ /dev/null @@ -1,568 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/freewheel-sspBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -const ENDPOINT = '//ads.stickyadstv.com/www/delivery/swfIndex.php'; - -describe('freewheelSSP BidAdapter Test', () => { - const adapter = newBidder(spec); - - describe('inherited functions', () => { - it('exists and is a function', () => { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValidForBanner', () => { - let bid = { - 'bidder': 'freewheel-ssp', - 'params': { - 'zoneId': '277225' - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [300, 250], [300, 600] - ] - } - }, - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - - it('should return true when required params found', () => { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', () => { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - wrong: 'missing zone id' - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('isBidRequestValidForVideo', () => { - let bid = { - 'bidder': 'freewheel-ssp', - 'params': { - 'zoneId': '277225' - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'video': { - 'playerSize': [300, 250], - } - }, - 'sizes': [[300, 250]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - - it('should return true when required params found', () => { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', () => { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - wrong: 'missing zone id' - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequestsForBanner', () => { - let bidRequests = [ - { - 'bidder': 'freewheel-ssp', - 'params': { - 'zoneId': '277225' - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [300, 250], [300, 600] - ] - } - }, - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - it('should add parameters to the tag', () => { - const request = spec.buildRequests(bidRequests); - const payload = request[0].data; - expect(payload.reqType).to.equal('AdsSetup'); - expect(payload.protocolVersion).to.equal('2.0'); - expect(payload.zoneId).to.equal('277225'); - expect(payload.componentId).to.equal('prebid'); - expect(payload.componentSubId).to.equal('mustang'); - expect(payload.playerSize).to.equal('300x600'); - }); - - it('sends bid request to ENDPOINT via GET', () => { - const request = spec.buildRequests(bidRequests); - expect(request[0].url).to.contain(ENDPOINT); - expect(request[0].method).to.equal('GET'); - }); - - it('should add usp consent to the request', () => { - let uspConsentString = '1FW-SSP-uspConsent-'; - let bidderRequest = {}; - bidderRequest.uspConsent = uspConsentString; - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = request[0].data; - expect(payload.reqType).to.equal('AdsSetup'); - expect(payload.protocolVersion).to.equal('2.0'); - expect(payload.zoneId).to.equal('277225'); - expect(payload.componentId).to.equal('prebid'); - expect(payload.componentSubId).to.equal('mustang'); - expect(payload.playerSize).to.equal('300x600'); - expect(payload._fw_us_privacy).to.exist.and.to.be.a('string'); - expect(payload._fw_us_privacy).to.equal(uspConsentString); - }); - - it('should add gdpr consent to the request', () => { - let gdprConsentString = '1FW-SSP-gdprConsent-'; - let bidderRequest = { - 'gdprConsent': { - 'consentString': gdprConsentString - } - }; - - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = request[0].data; - expect(payload.reqType).to.equal('AdsSetup'); - expect(payload.protocolVersion).to.equal('2.0'); - expect(payload.zoneId).to.equal('277225'); - expect(payload.componentId).to.equal('prebid'); - expect(payload.componentSubId).to.equal('mustang'); - expect(payload.playerSize).to.equal('300x600'); - expect(payload._fw_gdpr_consent).to.exist.and.to.be.a('string'); - expect(payload._fw_gdpr_consent).to.equal(gdprConsentString); - - let gdprConsent = { - 'gdprApplies': true, - 'consentString': gdprConsentString - } - let syncOptions = { - 'pixelEnabled': true - } - const userSyncs = spec.getUserSyncs(syncOptions, null, gdprConsent, null); - expect(userSyncs).to.deep.equal([{ - type: 'image', - url: 'https://ads.stickyadstv.com/auto-user-sync?gdpr=1&gdpr_consent=1FW-SSP-gdprConsent-' - }]); - }); - }) - - describe('buildRequestsForVideo', () => { - let bidRequests = [ - { - 'bidder': 'freewheel-ssp', - 'params': { - 'zoneId': '277225' - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'video': { - 'playerSize': [300, 600], - } - }, - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - it('should add parameters to the tag', () => { - const request = spec.buildRequests(bidRequests); - const payload = request[0].data; - expect(payload.reqType).to.equal('AdsSetup'); - expect(payload.protocolVersion).to.equal('2.0'); - expect(payload.zoneId).to.equal('277225'); - expect(payload.componentId).to.equal('prebid'); - expect(payload.componentSubId).to.equal('mustang'); - expect(payload.playerSize).to.equal('300x600'); - }); - - it('sends bid request to ENDPOINT via GET', () => { - const request = spec.buildRequests(bidRequests); - expect(request[0].url).to.contain(ENDPOINT); - expect(request[0].method).to.equal('GET'); - }); - - it('should add usp consent to the request', () => { - let uspConsentString = '1FW-SSP-uspConsent-'; - let bidderRequest = {}; - bidderRequest.uspConsent = uspConsentString; - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = request[0].data; - expect(payload.reqType).to.equal('AdsSetup'); - expect(payload.protocolVersion).to.equal('2.0'); - expect(payload.zoneId).to.equal('277225'); - expect(payload.componentId).to.equal('prebid'); - expect(payload.componentSubId).to.equal('mustang'); - expect(payload.playerSize).to.equal('300x600'); - expect(payload._fw_us_privacy).to.exist.and.to.be.a('string'); - expect(payload._fw_us_privacy).to.equal(uspConsentString); - }); - - it('should add gdpr consent to the request', () => { - let gdprConsentString = '1FW-SSP-gdprConsent-'; - let bidderRequest = { - 'gdprConsent': { - 'consentString': gdprConsentString - } - }; - - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = request[0].data; - expect(payload.reqType).to.equal('AdsSetup'); - expect(payload.protocolVersion).to.equal('2.0'); - expect(payload.zoneId).to.equal('277225'); - expect(payload.componentId).to.equal('prebid'); - expect(payload.componentSubId).to.equal('mustang'); - expect(payload.playerSize).to.equal('300x600'); - expect(payload._fw_gdpr_consent).to.exist.and.to.be.a('string'); - expect(payload._fw_gdpr_consent).to.equal(gdprConsentString); - - let gdprConsent = { - 'gdprApplies': true, - 'consentString': gdprConsentString - } - let syncOptions = { - 'pixelEnabled': true - } - const userSyncs = spec.getUserSyncs(syncOptions, null, gdprConsent, null); - expect(userSyncs).to.deep.equal([{ - type: 'image', - url: 'https://ads.stickyadstv.com/auto-user-sync?gdpr=1&gdpr_consent=1FW-SSP-gdprConsent-' - }]); - }); - }) - - describe('interpretResponseForBanner', () => { - let bidRequests = [ - { - 'bidder': 'freewheel-ssp', - 'params': { - 'zoneId': '277225' - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [300, 250], [300, 600] - ] - } - }, - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - let formattedBidRequests = [ - { - 'bidder': 'freewheel-ssp', - 'params': { - 'zoneId': '277225', - 'format': 'floorad' - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [300, 250], [300, 600] - ] - } - }, - 'sizes': [[600, 250], [300, 600]], - 'bidId': '30b3other1c1838de1e', - 'bidderRequestId': '22edbae273other3bf6', - 'auctionId': '1d1a03079test0a475', - }, - { - 'bidder': 'stickyadstv', - 'params': { - 'zoneId': '277225', - 'format': 'test' - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [300, 600] - ] - } - }, - 'sizes': [[300, 600]], - 'bidId': '2', - 'bidderRequestId': '3', - 'auctionId': '4', - } - ]; - - let response = '' + - '' + - ' ' + - ' Adswizz' + - ' ' + - ' https://ads.stickyadstv.com/auto-user-sync?dealId=NRJ-PRO-12008' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' 00:00:09' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' 0.2000' + - ' ' + - ' ' + - ' ' + - ''; - - let ad = '
'; - let formattedAd = '
'; - - it('should get correct bid response', () => { - var request = spec.buildRequests(bidRequests); - - let expectedResponse = [ - { - requestId: '30b31c1838de1e', - cpm: '0.2000', - width: 300, - height: 600, - creativeId: '28517153', - currency: 'EUR', - netRevenue: true, - ttl: 360, - dealId: 'NRJ-PRO-00008', - campaignId: 'SMF-WOW-55555', - bannerId: '12345', - ad: ad - } - ]; - - let result = spec.interpretResponse(response, request[0]); - expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); - expect(result[0].dealId).to.equal('NRJ-PRO-00008'); - expect(result[0].campaignId).to.equal('SMF-WOW-55555'); - expect(result[0].bannerId).to.equal('12345'); - }); - - it('should get correct bid response with formated ad', () => { - var request = spec.buildRequests(formattedBidRequests); - - let expectedResponse = [ - { - requestId: '30b31c1838de1e', - cpm: '0.2000', - width: 300, - height: 600, - creativeId: '28517153', - currency: 'EUR', - netRevenue: true, - ttl: 360, - dealId: 'NRJ-PRO-00008', - campaignId: 'SMF-WOW-55555', - bannerId: '12345', - ad: formattedAd - } - ]; - - let result = spec.interpretResponse(response, request[0]); - expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); - expect(result[0].dealId).to.equal('NRJ-PRO-00008'); - expect(result[0].campaignId).to.equal('SMF-WOW-55555'); - expect(result[0].bannerId).to.equal('12345'); - }); - - it('handles nobid responses', () => { - var request = spec.buildRequests(formattedBidRequests); - let response = ''; - - let result = spec.interpretResponse(response, request[0]); - expect(result.length).to.equal(0); - }); - }); - - describe('interpretResponseForVideo', () => { - let bidRequests = [ - { - 'bidder': 'freewheel-ssp', - 'params': { - 'zoneId': '277225' - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'video': { - 'playerSize': [300, 600], - } - }, - 'sizes': [[300, 400]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - let formattedBidRequests = [ - { - 'bidder': 'freewheel-ssp', - 'params': { - 'zoneId': '277225', - 'format': 'floorad' - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'video': { - 'playerSize': [300, 600], - } - }, - 'sizes': [[300, 400]], - 'bidId': '30b3other1c1838de1e', - 'bidderRequestId': '22edbae273other3bf6', - 'auctionId': '1d1a03079test0a475', - }, - { - 'bidder': 'stickyadstv', - 'params': { - 'zoneId': '277225', - 'format': 'test' - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'video': { - 'playerSize': [300, 600], - } - }, - 'sizes': [[300, 400]], - 'bidId': '2', - 'bidderRequestId': '3', - 'auctionId': '4', - } - ]; - - let response = '' + - '' + - ' ' + - ' Adswizz' + - ' ' + - ' https://ads.stickyadstv.com/auto-user-sync?dealId=NRJ-PRO-00008' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' 00:00:09' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' ' + - ' 0.2000' + - ' ' + - ' ' + - ' ' + - ''; - - let ad = '
'; - let formattedAd = '
'; - - it('should get correct bid response', () => { - var request = spec.buildRequests(bidRequests); - - let expectedResponse = [ - { - requestId: '30b31c1838de1e', - cpm: '0.2000', - width: 300, - height: 600, - creativeId: '28517153', - currency: 'EUR', - netRevenue: true, - ttl: 360, - dealId: 'NRJ-PRO-00008', - campaignId: 'SMF-WOW-55555', - bannerId: '12345', - vastXml: response, - mediaType: 'video', - ad: ad - } - ]; - - let result = spec.interpretResponse(response, request[0]); - expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); - expect(result[0].dealId).to.equal('NRJ-PRO-00008'); - expect(result[0].campaignId).to.equal('SMF-WOW-55555'); - expect(result[0].bannerId).to.equal('12345'); - }); - - it('should get correct bid response with formated ad', () => { - var request = spec.buildRequests(formattedBidRequests); - - let expectedResponse = [ - { - requestId: '30b31c1838de1e', - cpm: '0.2000', - width: 300, - height: 600, - creativeId: '28517153', - currency: 'EUR', - netRevenue: true, - ttl: 360, - dealId: 'NRJ-PRO-00008', - campaignId: 'SMF-WOW-55555', - bannerId: '12345', - vastXml: response, - mediaType: 'video', - ad: formattedAd - } - ]; - - let result = spec.interpretResponse(response, request[0]); - expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); - expect(result[0].dealId).to.equal('NRJ-PRO-00008'); - expect(result[0].campaignId).to.equal('SMF-WOW-55555'); - expect(result[0].bannerId).to.equal('12345'); - }); - - it('handles nobid responses', () => { - var request = spec.buildRequests(formattedBidRequests); - let response = ''; - - let result = spec.interpretResponse(response, request[0]); - expect(result.length).to.equal(0); - }); - }); -}); diff --git a/test/spec/modules/gammaBidAdapter_spec.js b/test/spec/modules/gammaBidAdapter_spec.js deleted file mode 100644 index cdaa1b5448a..00000000000 --- a/test/spec/modules/gammaBidAdapter_spec.js +++ /dev/null @@ -1,104 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/gammaBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('gammaBidAdapter', function() { - const adapter = newBidder(spec); - - let bid = { - 'bidder': 'gamma', - 'params': { - siteId: '1465446377', - zoneId: '1515999290' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250] - ], - 'bidId': '23beaa6af6cdde', - 'bidderRequestId': '19c0c1efdf37e7', - 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf1', - }; - let bidArray = [bid]; - - describe('isBidRequestValid', () => { - it('should return true when required params found', () => { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when require params are not passed', () => { - let bid = Object.assign({}, bid); - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when params not passed correctly', () => { - bid.params.siteId = ''; - bid.params.zoneId = ''; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', () => { - it('should attempt to send bid requests to the endpoint via GET', () => { - const requests = spec.buildRequests(bidArray); - requests.forEach(function(requestItem) { - expect(requestItem.method).to.equal('GET'); - expect(requestItem.url).to.match(new RegExp(`hb.gammaplatform.com`)); - }); - }); - }); - - describe('interpretResponse', () => { - let serverResponse; - - beforeEach(() => { - serverResponse = { - body: { - 'id': '23beaa6af6cdde', - 'bid': '5611802021800040585', - 'type': 'banner', - 'cur': 'USD', - 'seatbid': [{ - 'seat': '5611802021800040585', - 'bid': [{ - 'id': '1515999070', - 'impid': '1', - 'price': 0.45, - 'adm': '', - 'adid': '1515999070', - 'dealid': 'gax-paj2qarjf2g', - 'h': 250, - 'w': 300 - }] - }] - } - }; - }) - - it('should get the correct bid response', () => { - let expectedResponse = [{ - 'requestId': '23beaa6af6cdde', - 'cpm': 0.45, - 'width': 300, - 'height': 250, - 'creativeId': '1515999070', - 'dealId': 'gax-paj2qarjf2g', - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'ad': '' - }]; - let result = spec.interpretResponse(serverResponse); - expect(Object.keys(result)).to.deep.equal(Object.keys(expectedResponse)); - }); - - it('handles empty bid response', () => { - let response = { - body: {} - }; - let result = spec.interpretResponse(response); - expect(result.length).to.equal(0); - }); - }); -}); diff --git a/test/spec/modules/gamoshiBidAdapter_spec.js b/test/spec/modules/gamoshiBidAdapter_spec.js deleted file mode 100644 index 2996b853046..00000000000 --- a/test/spec/modules/gamoshiBidAdapter_spec.js +++ /dev/null @@ -1,561 +0,0 @@ -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'; - -const supplyPartnerId = '123'; -const adapter = newBidder(spec); -const TTL = 360; - -describe('GamoshiAdapter', () => { - let schainConfig, - bidRequest, - bannerBidRequest, - videoBidRequest, - rtbResponse, - videoResponse, - gdprConsent; - - beforeEach(() => { - schainConfig = { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'indirectseller.com', - 'sid': '00001', - 'hp': 1 - }, - - { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 2 - } - ] - }; - - bidRequest = { - 'adUnitCode': 'adunit-code', - 'auctionId': '1d1a030790a475', - 'mediaTypes': { - banner: {} - }, - 'params': { - 'supplyPartnerId': supplyPartnerId - }, - 'sizes': [[300, 250], [300, 600]], - 'transactionId': 'a123456789', - refererInfo: {referer: 'http://examplereferer.com'}, - gdprConsent: { - consentString: 'some string', - gdprApplies: true - }, - schain: schainConfig, - uspConsent: 'gamoshiCCPA' - }; - - bannerBidRequest = { - 'adUnitCode': 'adunit-code', - 'auctionId': '1d1a030790a475', - 'mediaTypes': { - banner: {} - }, - 'params': { - 'supplyPartnerId': supplyPartnerId - }, - 'sizes': [[300, 250], [300, 600]], - 'transactionId': 'a123456789', - 'bidId': '111', - refererInfo: {referer: 'http://examplereferer.com'} - }; - - videoBidRequest = { - 'adUnitCode': 'adunit-code', - 'auctionId': '1d1a030790a475', - 'mediaTypes': { - video: {} - }, - 'params': { - 'supplyPartnerId': supplyPartnerId - }, - 'sizes': [[300, 250], [300, 600]], - 'transactionId': 'a123456789', - 'bidId': '111', - refererInfo: {referer: 'http://examplereferer.com'} - }; - - rtbResponse = { - 'id': 'imp_5b05b9fde4b09084267a556f', - 'bidid': 'imp_5b05b9fde4b09084267a556f', - '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'} - ] - }, - 'seatbid': [ - { - 'seat': 'seat1', - 'group': 0, - 'bid': [ - { - 'id': '0', - 'impid': '1', - 'price': 2.016, - 'adid': '579ef31bfa788b9d2000d562', - 'nurl': 'https://rtb.gamoshi.io/pix/monitoring/win_notice/imp_5b05b9fde4b09084267a556f/im.gif?r=imp_5b05b9fde4b09084267a556f&i=1&a=579ef31bfa788b9d2000d562&b=0', - 'adm': '', - 'adomain': ['aaa.com'], - 'cid': '579ef268fa788b9d2000d55c', - 'crid': '579ef31bfa788b9d2000d562', - 'attr': [], - 'h': 600, - 'w': 120, - 'ext': { - 'vast_url': 'http://my.vast.com', - 'utrk': [ - {'type': 'iframe', 'url': '//p.partner1.io/user/sync/1'} - ] - } - } - ] - }, - { - 'seat': 'seat2', - 'group': 0, - 'bid': [ - { - 'id': '1', - 'impid': '1', - 'price': 3, - 'adid': '542jlhdfd2112jnjf3x', - 'nurl': 'https://rtb.gamoshi.io/pix/monitoring/win_notice/imp_5b05b9fde4b09084267a556f/im.gif?r=imp_5b05b9fde4b09084267a556f&i=1&a=579ef31bfa788b9d2000d562&b=0', - 'adm': ' ', - 'adomain': ['bbb.com'], - 'cid': 'fgdlwjh2498ydjhg1', - 'crid': 'kjh34297ydh2133d', - 'attr': [], - 'h': 250, - 'w': 300, - 'ext': { - 'utrk': [ - {'type': 'image', 'url': '//p.partner2.io/user/sync/1'} - ] - } - } - ] - } - ] - }; - - videoResponse = { - 'id': '64f32497-b2f7-48ec-9205-35fc39894d44', - 'bidid': 'imp_5c24924de4b0d106447af333', - 'cur': 'USD', - 'seatbid': [ - { - 'seat': '3668', - 'group': 0, - 'bid': [ - { - 'id': 'gb_1', - 'impid': 'afbb5852-7cea-4a81-aa9a-a41aab505c23', - 'price': 5.0, - 'adid': '1274', - 'nurl': 'https://rtb.gamoshi.io/pix/1275/win_notice/imp_5c24924de4b0d106447af333/im.gif?r=imp_5c24924de4b0d106447af333&i=afbb5852-7cea-4a81-aa9a-a41aab505c23&a=1274&b=gb_1', - 'adomain': [], - 'adm': '\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n', - 'cid': '3668', - 'crid': '1274', - 'cat': [], - 'attr': [], - 'h': 250, - 'w': 300, - 'ext': { - 'vast_url': 'https://rtb.gamoshi.io/pix/1275/vast_o/imp_5c24924de4b0d106447af333/im.xml?r=imp_5c24924de4b0d106447af333&i=afbb5852-7cea-4a81-aa9a-a41aab505c23&a=1274&b=gb_1&w=300&h=250&vatu=aHR0cHM6Ly9zdGF0aWMuZ2FtYmlkLmlvL2RlbW8vdmFzdC54bWw&vwarv', - 'imptrackers': [ - 'https://rtb.gamoshi.io/pix/1275/imp/imp_5c24924de4b0d106447af333/im.gif?r=imp_5c24924de4b0d106447af333&i=afbb5852-7cea-4a81-aa9a-a41aab505c23&a=1274&b=gb_1'] - } - } - ] - } - ], - 'ext': { - 'utrk': [{ - 'type': 'image', - 'url': 'https://rtb.gamoshi.io/pix/1275/scm?cb=1545900621675&gdpr=[GDPR]&consent=[CONSENT]&us_privacy=[US_PRIVACY]' - }] - } - }; - - gdprConsent = { - gdprApplies: true, - consentString: 'consent string' - }; - }); - - describe('Get top Frame', () => { - it('check if you are in the top frame', () => { - expect(helper.getTopFrame()).to.equal(0); - }); - - it('verify domain parsing', () => { - expect(helper.getTopWindowDomain('http://www.domain.com')).to.equal('www.domain.com'); - }); - }); - - describe('Is String start with search', () => { - it('check if a string started with', () => { - expect(helper.startsWith('gamoshi.com', 'gamo')).to.equal(true); - }); - }); - - describe('inherited functions', () => { - it('exists and is a function', () => { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', () => { - it('should validate supply-partner ID', () => { - expect(spec.isBidRequestValid({params: {}})).to.equal(false); - expect(spec.isBidRequestValid({params: {supplyPartnerId: 123}})).to.equal(false); - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123'}})).to.equal(true); - }); - - 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', - rtbEndpoint: 'https://some.url.com' - } - })).to.equal(true); - }); - - it('should validate bid floor', () => { - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123'}})).to.equal(true); // bidfloor has a default - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123', bidfloor: '123'}})).to.equal(false); - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123', bidfloor: 0.1}})).to.equal(true); - }); - - it('should validate adpos', () => { - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123'}})).to.equal(true); // adpos has a default - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123', adpos: '123'}})).to.equal(false); - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123', adpos: 0.1}})).to.equal(true); - }); - - it('should validate instl', () => { - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123'}})).to.equal(true); // adpos has a default - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123', instl: '123'}})).to.equal(false); - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123', instl: -1}})).to.equal(false); - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123', instl: 0}})).to.equal(true); - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123', instl: 1}})).to.equal(true); - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123', instl: 2}})).to.equal(false); - }); - }); - - describe('buildRequests', () => { - it('returns an array', () => { - let response; - response = spec.buildRequests([]); - expect(Array.isArray(response)).to.equal(true); - expect(response.length).to.equal(0); - 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'}); - response = spec.buildRequests([adUnit1, adUnit2], bidRequest); - expect(Array.isArray(response)).to.equal(true); - expect(response.length).to.equal(2); - }); - - it('targets correct endpoint', () => { - let response; - response = spec.buildRequests([bidRequest], bidRequest)[0]; - expect(response.method).to.equal('POST'); - expect(response.url).to.match(new RegExp(`^https://rtb\\.gamoshi\\.io/r/${supplyPartnerId}/bidr\\?rformat=open_rtb&reqformat=rtb_json&bidder=prebid$`, 'g')); - expect(response.data.id).to.equal(bidRequest.auctionId); - const bidRequestWithEndpoint = utils.deepClone(bidRequest); - bidRequestWithEndpoint.params.rtbEndpoint = 'https://rtb2.gamoshi.io/a12'; - response = spec.buildRequests([bidRequestWithEndpoint], bidRequest)[0]; - expect(response.url).to.match(new RegExp(`^https://rtb2\\.gamoshi\\.io/a12/r/${supplyPartnerId}/bidr\\?rformat=open_rtb&reqformat=rtb_json&bidder=prebid$`, 'g')); - }); - - it('builds request correctly', () => { - let bidRequest2 = utils.deepClone(bidRequest); - bidRequest2.refererInfo.referer = 'http://www.test.com/page.html'; - let response = spec.buildRequests([bidRequest], bidRequest2)[0]; - - expect(response.data.site.domain).to.equal('www.test.com'); - expect(response.data.site.page).to.equal('http://www.test.com/page.html'); - expect(response.data.site.ref).to.equal('http://www.test.com/page.html'); - expect(response.data.imp.length).to.equal(1); - expect(response.data.imp[0].id).to.equal(bidRequest.transactionId); - expect(response.data.imp[0].instl).to.equal(0); - expect(response.data.imp[0].tagid).to.equal(bidRequest.adUnitCode); - expect(response.data.imp[0].bidfloor).to.equal(0); - expect(response.data.imp[0].bidfloorcur).to.equal('USD'); - expect(response.data.regs.ext.us_privacy).to.equal('gamoshiCCPA');// USP/CCPAs - expect(response.data.source.ext.schain).to.deep.equal(bidRequest2.schain); - - const bidRequestWithInstlEquals1 = utils.deepClone(bidRequest); - bidRequestWithInstlEquals1.params.instl = 1; - response = spec.buildRequests([bidRequestWithInstlEquals1], bidRequest2)[0]; - expect(response.data.imp[0].instl).to.equal(bidRequestWithInstlEquals1.params.instl); - const bidRequestWithInstlEquals0 = utils.deepClone(bidRequest); - bidRequestWithInstlEquals0.params.instl = 1; - response = spec.buildRequests([bidRequestWithInstlEquals0], bidRequest2)[0]; - expect(response.data.imp[0].instl).to.equal(bidRequestWithInstlEquals0.params.instl); - const bidRequestWithBidfloorEquals1 = utils.deepClone(bidRequest); - bidRequestWithBidfloorEquals1.params.bidfloor = 1; - response = spec.buildRequests([bidRequestWithBidfloorEquals1], bidRequest2)[0]; - expect(response.data.imp[0].bidfloor).to.equal(bidRequestWithBidfloorEquals1.params.bidfloor); - }); - - it('builds request banner object correctly', () => { - let response; - const bidRequestWithBanner = utils.deepClone(bidRequest); - bidRequestWithBanner.mediaTypes = { - banner: { - sizes: [[300, 250], [120, 600]] - } - }; - response = spec.buildRequests([bidRequestWithBanner], bidRequest)[0]; - expect(response.data.imp[0].banner.w).to.equal(bidRequestWithBanner.mediaTypes.banner.sizes[0][0]); - expect(response.data.imp[0].banner.h).to.equal(bidRequestWithBanner.mediaTypes.banner.sizes[0][1]); - expect(response.data.imp[0].banner.pos).to.equal(0); - expect(response.data.imp[0].banner.topframe).to.equal(0); - const bidRequestWithPosEquals1 = utils.deepClone(bidRequestWithBanner); - bidRequestWithPosEquals1.params.pos = 1; - response = spec.buildRequests([bidRequestWithPosEquals1], bidRequest)[0]; - expect(response.data.imp[0].banner.pos).to.equal(bidRequestWithPosEquals1.params.pos); - }); - - it('builds request video object correctly', () => { - let response; - const bidRequestWithVideo = utils.deepClone(bidRequest); - bidRequestWithVideo.mediaTypes = { - video: { - playerSize: [[302, 252]] - } - }; - response = spec.buildRequests([bidRequestWithVideo], bidRequest)[0]; - expect(response.data.imp[0].video.w).to.equal(bidRequestWithVideo.mediaTypes.video.playerSize[0][0]); - expect(response.data.imp[0].video.h).to.equal(bidRequestWithVideo.mediaTypes.video.playerSize[0][1]); - expect(response.data.imp[0].video.pos).to.equal(0); - bidRequestWithVideo.mediaTypes = { - video: { - playerSize: [302, 252] - } - }; - - const bidRequestWithPosEquals1 = utils.deepClone(bidRequestWithVideo); - expect(response.data.imp[0].video.w).to.equal(bidRequestWithVideo.mediaTypes.video.playerSize[0]); - expect(response.data.imp[0].video.h).to.equal(bidRequestWithVideo.mediaTypes.video.playerSize[1]); - - bidRequestWithPosEquals1.params.pos = 1; - response = spec.buildRequests([bidRequestWithPosEquals1], bidRequest)[0]; - expect(response.data.imp[0].video.pos).to.equal(bidRequestWithPosEquals1.params.pos); - }); - - it('builds request video object correctly with context', () => { - const bidRequestWithVideo = utils.deepClone(bidRequest); - bidRequestWithVideo.mediaTypes = { - video: { - context: 'instream' - } - }; - let response = spec.buildRequests([bidRequestWithVideo], bidRequest)[0]; - expect(response.data.imp[0].video.ext.context).to.equal('instream'); - bidRequestWithVideo.mediaTypes.video.context = 'outstream'; - - const bidRequestWithPosEquals1 = utils.deepClone(bidRequestWithVideo); - bidRequestWithPosEquals1.mediaTypes.video.context = 'outstream'; - response = spec.buildRequests([bidRequestWithPosEquals1], bidRequest)[0]; - expect(response.data.imp[0].video.ext.context).to.equal('outstream'); - - const bidRequestWithPosEquals2 = utils.deepClone(bidRequestWithVideo); - bidRequestWithPosEquals2.mediaTypes.video.context = null; - response = spec.buildRequests([bidRequestWithPosEquals2], bidRequest)[0]; - expect(response.data.imp[0].video.ext.context).to.equal(null); - }); - - it('builds request video object correctly with multi-dimensions size array', () => { - let response; - const bidRequestWithVideo = utils.deepClone(bidRequest); - bidRequestWithVideo.mediaTypes.video = { - playerSize: [[304, 254], [305, 255]], - context: 'instream' - }; - - response = spec.buildRequests([bidRequestWithVideo], bidRequest)[0]; - expect(response.data.imp[1].video.ext.context).to.equal('instream'); - bidRequestWithVideo.mediaTypes.video.context = 'outstream'; - - const bidRequestWithPosEquals1 = utils.deepClone(bidRequestWithVideo); - bidRequestWithPosEquals1.mediaTypes.video.context = 'outstream'; - response = spec.buildRequests([bidRequestWithPosEquals1], bidRequest)[0]; - expect(response.data.imp[1].video.ext.context).to.equal('outstream'); - - const bidRequestWithPosEquals2 = utils.deepClone(bidRequestWithVideo); - bidRequestWithPosEquals2.mediaTypes.video.context = null; - response = spec.buildRequests([bidRequestWithPosEquals2], bidRequest)[0]; - expect(response.data.imp[1].video.ext.context).to.equal(null); - }); - - it('builds request with gdpr consent', () => { - let response = spec.buildRequests([bidRequest], bidRequest)[0]; - - expect(response.data.ext.gdpr_consent).to.not.equal(null).and.not.equal(undefined); - expect(response.data.ext).to.have.property('gdpr_consent'); - expect(response.data.ext.gdpr_consent.consent_string).to.equal('some string'); - expect(response.data.ext.gdpr_consent.consent_required).to.equal(true); - - expect(response.data.regs.ext.gdpr).to.not.equal(null).and.not.equal(undefined); - expect(response.data.user.ext.consent).to.equal('some string'); - }); - - it('build request with ID5 Id', () => { - const bidRequestClone = utils.deepClone(bidRequest); - bidRequestClone.userId = {}; - bidRequestClone.userId.id5id = { uid: 'id5-user-id' }; - let request = spec.buildRequests([bidRequestClone], bidRequestClone)[0]; - expect(request.data.user.ext.eids).to.deep.equal([{ - 'source': 'id5-sync.com', - 'uids': [{ - 'id': 'id5-user-id', - 'ext': { - 'rtiPartner': 'ID5ID' - } - }] - }]); - }); - - it('build request with unified Id', () => { - const bidRequestClone = utils.deepClone(bidRequest); - bidRequestClone.userId = {}; - bidRequestClone.userId.tdid = 'tdid-user-id'; - let request = spec.buildRequests([bidRequestClone], bidRequestClone)[0]; - expect(request.data.user.ext.eids).to.deep.equal([{ - 'source': 'adserver.org', - 'uids': [{ - 'id': 'tdid-user-id', - 'ext': { - 'rtiPartner': 'TDID' - } - }] - }]); - }); - }); - - describe('interpretResponse', () => { - it('returns an empty array on missing response', () => { - 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}); - expect(Array.isArray(response)).to.equal(true); - expect(response.length).to.equal(0); - }); - - it('aggregates banner bids from all seat bids', () => { - const response = spec.interpretResponse({body: rtbResponse}, {bidRequest: bannerBidRequest}); - expect(Array.isArray(response)).to.equal(true); - expect(response.length).to.equal(1); - const ad0 = response[0]; - expect(ad0.requestId).to.equal(bannerBidRequest.bidId); - expect(ad0.cpm).to.equal(rtbResponse.seatbid[1].bid[0].price); - expect(ad0.width).to.equal(rtbResponse.seatbid[1].bid[0].w); - expect(ad0.height).to.equal(rtbResponse.seatbid[1].bid[0].h); - expect(ad0.ttl).to.equal(TTL); - expect(ad0.creativeId).to.equal(rtbResponse.seatbid[1].bid[0].crid); - expect(ad0.netRevenue).to.equal(true); - expect(ad0.currency).to.equal(rtbResponse.seatbid[1].bid[0].cur || rtbResponse.cur || 'USD'); - expect(ad0.ad).to.equal(rtbResponse.seatbid[1].bid[0].adm); - expect(ad0.vastXml).to.be.an('undefined'); - expect(ad0.vastUrl).to.be.an('undefined'); - }); - - it('aggregates video bids from all seat bids', () => { - const response = spec.interpretResponse({body: rtbResponse}, {bidRequest: videoBidRequest}); - expect(Array.isArray(response)).to.equal(true); - expect(response.length).to.equal(1); - const ad0 = response[0]; - expect(ad0.requestId).to.equal(videoBidRequest.bidId); - expect(ad0.cpm).to.equal(rtbResponse.seatbid[0].bid[0].price); - expect(ad0.width).to.equal(rtbResponse.seatbid[0].bid[0].w); - expect(ad0.height).to.equal(rtbResponse.seatbid[0].bid[0].h); - expect(ad0.ttl).to.equal(TTL); - expect(ad0.creativeId).to.equal(rtbResponse.seatbid[0].bid[0].crid); - expect(ad0.netRevenue).to.equal(true); - expect(ad0.currency).to.equal(rtbResponse.seatbid[0].bid[0].cur || rtbResponse.cur || 'USD'); - expect(ad0.ad).to.be.an('undefined'); - expect(ad0.vastXml).to.equal(rtbResponse.seatbid[0].bid[0].adm); - expect(ad0.vastUrl).to.equal(rtbResponse.seatbid[0].bid[0].ext.vast_url); - }); - - it('aggregates user-sync pixels', () => { - 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); - expect(response[0].url).to.equal('//rtb.gamoshi.io/user/sync/1?gdpr=0&consent=&usp='); - expect(response[1].type).to.equal(rtbResponse.ext.utrk[1].type); - expect(response[1].url).to.equal('//rtb.gamoshi.io/user/sync/2'); - expect(response[2].type).to.equal(rtbResponse.seatbid[0].bid[0].ext.utrk[0].type); - expect(response[2].url).to.equal('//p.partner1.io/user/sync/1'); - expect(response[3].type).to.equal(rtbResponse.seatbid[1].bid[0].ext.utrk[0].type); - expect(response[3].url).to.equal('//p.partner2.io/user/sync/1'); - }); - - it('supports configuring outstream renderers', () => { - const videoRequest = utils.deepClone(videoBidRequest); - videoRequest.mediaTypes.video.context = 'outstream'; - const result = spec.interpretResponse({body: videoResponse}, {bidRequest: videoRequest}); - expect(result[0].renderer).to.not.equal(undefined); - }); - - it('validates in/existing of gdpr consent', () => { - 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, '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); - 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'); - }); - - it('validates existence of gdpr, gdpr consent and usp consent', () => { - 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, ''); - 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='); - }); - }); -}); diff --git a/test/spec/modules/gdprEnforcement_spec.js b/test/spec/modules/gdprEnforcement_spec.js deleted file mode 100644 index 82cb70f42be..00000000000 --- a/test/spec/modules/gdprEnforcement_spec.js +++ /dev/null @@ -1,1125 +0,0 @@ -import { - deviceAccessHook, - setEnforcementConfig, - userSyncHook, - userIdHook, - makeBidRequestsHook, - validateRules, - enforcementRules, - purpose1Rule, - purpose2Rule, - enableAnalyticsHook, - getGvlid, - internal -} from 'modules/gdprEnforcement.js'; -import { config } from 'src/config.js'; -import adapterManager, { gdprDataHandler } from 'src/adapterManager.js'; -import * as utils from 'src/utils.js'; -import { validateStorageEnforcement } from 'src/storageManager.js'; -import events from 'src/events.js'; - -describe('gdpr enforcement', function () { - let nextFnSpy; - let logWarnSpy; - let gdprDataHandlerStub; - let staticConfig = { - cmpApi: 'static', - timeout: 7500, - allowAuctionWithoutConsent: false, - consentData: { - getTCData: { - 'tcString': 'COuqj-POu90rDBcBkBENAZCgAPzAAAPAACiQFwwBAABAA1ADEAbQC4YAYAAgAxAG0A', - 'cmpId': 92, - 'cmpVersion': 100, - 'tcfPolicyVersion': 2, - 'gdprApplies': true, - 'isServiceSpecific': true, - 'useNonStandardStacks': false, - 'purposeOneTreatment': false, - 'publisherCC': 'US', - 'cmpStatus': 'loaded', - 'eventStatus': 'tcloaded', - 'outOfBand': { - 'allowedVendors': {}, - 'discloseVendors': {} - }, - 'purpose': { - 'consents': { - '1': true, - '2': true, - '3': true, - '7': true - }, - 'legitimateInterests': { - '1': false, - '2': true, - '3': false - } - }, - 'vendor': { - 'consents': { - '1': true, - '2': true, - '3': false, - '4': true, - '5': false - }, - 'legitimateInterests': { - '1': false, - '2': true, - '3': false, - '4': false, - '5': false - } - }, - 'specialFeatureOptins': { - '1': false, - '2': false - }, - 'restrictions': {}, - 'publisher': { - 'consents': { - '1': false, - '2': false, - '3': false - }, - 'legitimateInterests': { - '1': false, - '2': false, - '3': false - }, - 'customPurpose': { - 'consents': {}, - 'legitimateInterests': {} - } - } - } - } - }; - - after(function () { - validateStorageEnforcement.getHooks({ hook: deviceAccessHook }).remove(); - $$PREBID_GLOBAL$$.requestBids.getHooks().remove(); - adapterManager.makeBidRequests.getHooks({ hook: makeBidRequestsHook }).remove(); - }) - - describe('deviceAccessHook', function () { - let adapterManagerStub; - - function getBidderSpec(gvlid) { - return { - getSpec: () => { - return { - gvlid - } - } - } - } - - beforeEach(function () { - nextFnSpy = sinon.spy(); - gdprDataHandlerStub = sinon.stub(gdprDataHandler, 'getConsentData'); - logWarnSpy = sinon.spy(utils, 'logWarn'); - adapterManagerStub = sinon.stub(adapterManager, 'getBidAdapter'); - }); - afterEach(function () { - config.resetConfig(); - gdprDataHandler.getConsentData.restore(); - logWarnSpy.restore(); - adapterManagerStub.restore(); - }); - it('should not allow device access when device access flag is set to false', function () { - config.setConfig({ - deviceAccess: false, - consentManagement: { - gdpr: { - rules: [{ - purpose: 'storage', - enforcePurpose: false, - enforceVendor: false, - vendorExceptions: ['appnexus', 'rubicon'] - }] - } - } - }); - - deviceAccessHook(nextFnSpy); - expect(nextFnSpy.calledOnce).to.equal(true); - let result = { - hasEnforcementHook: true, - valid: false - } - sinon.assert.calledWith(nextFnSpy, undefined, undefined, result); - }); - - it('should only check for consent for vendor exceptions when enforcePurpose and enforceVendor are false', function () { - adapterManagerStub.withArgs('appnexus').returns(getBidderSpec(1)); - adapterManagerStub.withArgs('rubicon').returns(getBidderSpec(5)); - setEnforcementConfig({ - gdpr: { - rules: [{ - purpose: 'storage', - enforcePurpose: false, - enforceVendor: false, - vendorExceptions: ['appnexus'] - }] - } - }); - let consentData = {} - consentData.vendorData = staticConfig.consentData.getTCData; - consentData.gdprApplies = true; - consentData.apiVersion = 2; - gdprDataHandlerStub.returns(consentData); - - deviceAccessHook(nextFnSpy, 1, 'appnexus'); - deviceAccessHook(nextFnSpy, 5, 'rubicon'); - expect(logWarnSpy.callCount).to.equal(0); - }); - - it('should check consent for all vendors when enforcePurpose and enforceVendor are true', function () { - adapterManagerStub.withArgs('appnexus').returns(getBidderSpec(1)); - adapterManagerStub.withArgs('rubicon').returns(getBidderSpec(3)); - setEnforcementConfig({ - gdpr: { - rules: [{ - purpose: 'storage', - enforcePurpose: true, - enforceVendor: true, - }] - } - }); - let consentData = {} - consentData.vendorData = staticConfig.consentData.getTCData; - consentData.gdprApplies = true; - consentData.apiVersion = 2; - gdprDataHandlerStub.returns(consentData); - - deviceAccessHook(nextFnSpy, 1, 'appnexus'); - deviceAccessHook(nextFnSpy, 3, 'rubicon'); - expect(logWarnSpy.callCount).to.equal(1); - }); - - it('should allow device access when gdprApplies is false and hasDeviceAccess flag is true', function () { - adapterManagerStub.withArgs('appnexus').returns(getBidderSpec(1)); - setEnforcementConfig({ - gdpr: { - rules: [{ - purpose: 'storage', - enforcePurpose: true, - enforceVendor: true, - vendorExceptions: [] - }] - } - }); - let consentData = {} - consentData.vendorData = staticConfig.consentData.getTCData; - consentData.gdprApplies = false; - consentData.apiVersion = 2; - gdprDataHandlerStub.returns(consentData); - - deviceAccessHook(nextFnSpy, 1, 'appnexus'); - expect(nextFnSpy.calledOnce).to.equal(true); - let result = { - hasEnforcementHook: true, - valid: true - } - sinon.assert.calledWith(nextFnSpy, 1, 'appnexus', result); - }); - - it('should use gvlMapping set by publisher', function() { - config.setConfig({ - 'gvlMapping': { - 'appnexus': 4 - } - }); - setEnforcementConfig({ - gdpr: { - rules: [{ - purpose: 'storage', - enforcePurpose: true, - enforceVendor: true, - vendorExceptions: [] - }] - } - }); - let consentData = {} - consentData.vendorData = staticConfig.consentData.getTCData; - consentData.gdprApplies = true; - consentData.apiVersion = 2; - gdprDataHandlerStub.returns(consentData); - - deviceAccessHook(nextFnSpy, 1, 'appnexus'); - expect(nextFnSpy.calledOnce).to.equal(true); - let result = { - hasEnforcementHook: true, - valid: true - } - sinon.assert.calledWith(nextFnSpy, 4, 'appnexus', result); - config.resetConfig(); - }); - - it('should use gvl id of alias and not of parent', function() { - let curBidderStub = sinon.stub(config, 'getCurrentBidder'); - curBidderStub.returns('appnexus-alias'); - adapterManager.aliasBidAdapter('appnexus', 'appnexus-alias'); - config.setConfig({ - 'gvlMapping': { - 'appnexus-alias': 4 - } - }); - setEnforcementConfig({ - gdpr: { - rules: [{ - purpose: 'storage', - enforcePurpose: true, - enforceVendor: true, - vendorExceptions: [] - }] - } - }); - let consentData = {} - consentData.vendorData = staticConfig.consentData.getTCData; - consentData.gdprApplies = true; - consentData.apiVersion = 2; - gdprDataHandlerStub.returns(consentData); - - deviceAccessHook(nextFnSpy, 1, 'appnexus'); - expect(nextFnSpy.calledOnce).to.equal(true); - let result = { - hasEnforcementHook: true, - valid: true - } - sinon.assert.calledWith(nextFnSpy, 4, 'appnexus', result); - config.resetConfig(); - curBidderStub.restore(); - }); - }); - - describe('userSyncHook', function () { - let curBidderStub; - let adapterManagerStub; - - beforeEach(function () { - gdprDataHandlerStub = sinon.stub(gdprDataHandler, 'getConsentData'); - logWarnSpy = sinon.spy(utils, 'logWarn'); - curBidderStub = sinon.stub(config, 'getCurrentBidder'); - adapterManagerStub = sinon.stub(adapterManager, 'getBidAdapter'); - nextFnSpy = sinon.spy(); - }); - - afterEach(function () { - config.getCurrentBidder.restore(); - config.resetConfig(); - gdprDataHandler.getConsentData.restore(); - adapterManager.getBidAdapter.restore(); - logWarnSpy.restore(); - }); - - it('should allow bidder to do user sync if consent is true', function () { - setEnforcementConfig({ - gdpr: { - rules: [{ - purpose: 'storage', - enforcePurpose: false, - enforceVendor: true, - vendorExceptions: ['sampleBidder2'] - }] - } - }); - let consentData = {} - consentData.vendorData = staticConfig.consentData.getTCData; - consentData.gdprApplies = true; - consentData.apiVersion = 2; - gdprDataHandlerStub.returns(consentData); - - curBidderStub.returns('sampleBidder1'); - adapterManagerStub.withArgs('sampleBidder1').returns({ - getSpec: function () { - return { - 'gvlid': 1 - } - } - }); - userSyncHook(nextFnSpy); - - curBidderStub.returns('sampleBidder2'); - adapterManagerStub.withArgs('sampleBidder2').returns({ - getSpec: function () { - return { - 'gvlid': 3 - } - } - }); - userSyncHook(nextFnSpy); - expect(nextFnSpy.calledTwice).to.equal(true); - }); - - it('should not allow bidder to do user sync if user has denied consent', function () { - setEnforcementConfig({ - gdpr: { - rules: [{ - purpose: 'storage', - enforcePurpose: false, - enforceVendor: true, - vendorExceptions: [] - }] - } - }); - let consentData = {} - consentData.vendorData = staticConfig.consentData.getTCData; - consentData.apiVersion = 2; - consentData.gdprApplies = true; - gdprDataHandlerStub.returns(consentData); - - curBidderStub.returns('sampleBidder1'); - adapterManagerStub.withArgs('sampleBidder1').returns({ - getSpec: function () { - return { - 'gvlid': 1 - } - } - }); - userSyncHook(nextFnSpy); - - curBidderStub.returns('sampleBidder2'); - adapterManagerStub.withArgs('sampleBidder2').returns({ - getSpec: function () { - return { - 'gvlid': 3 - } - } - }); - userSyncHook(nextFnSpy); - expect(nextFnSpy.calledOnce).to.equal(true); - expect(logWarnSpy.callCount).to.equal(1); - }); - - it('should not check vendor consent when enforceVendor is false', function () { - setEnforcementConfig({ - gdpr: { - rules: [{ - purpose: 'storage', - enforcePurpose: true, - enforceVendor: false, - vendorExceptions: ['sampleBidder1'] - }] - } - }); - let consentData = {} - consentData.vendorData = staticConfig.consentData.getTCData; - consentData.apiVersion = 2; - consentData.gdprApplies = true; - gdprDataHandlerStub.returns(consentData); - - curBidderStub.returns('sampleBidder1'); - adapterManagerStub.withArgs('sampleBidder1').returns({ - getSpec: function () { - return { - 'gvlid': 1 - } - } - }); - userSyncHook(nextFnSpy); - - curBidderStub.returns('sampleBidder2'); - adapterManagerStub.withArgs('sampleBidder2').returns({ - getSpec: function () { - return { - 'gvlid': 3 - } - } - }); - userSyncHook(nextFnSpy); - expect(nextFnSpy.calledTwice).to.equal(true); - expect(logWarnSpy.callCount).to.equal(0); - }); - }); - - describe('userIdHook', function () { - beforeEach(function () { - logWarnSpy = sinon.spy(utils, 'logWarn'); - nextFnSpy = sinon.spy(); - }); - afterEach(function () { - config.resetConfig(); - logWarnSpy.restore(); - }); - it('should allow user id module if consent is given', function () { - setEnforcementConfig({ - gdpr: { - rules: [{ - purpose: 'storage', - enforcePurpose: false, - enforceVendor: true, - vendorExceptions: [] - }] - } - }); - let consentData = {} - consentData.vendorData = staticConfig.consentData.getTCData; - consentData.apiVersion = 2; - consentData.gdprApplies = true; - let submodules = [{ - submodule: { - gvlid: 1, - name: 'sampleUserId' - } - }] - userIdHook(nextFnSpy, submodules, consentData); - // Should pass back hasValidated flag since version 2 - const args = nextFnSpy.getCalls()[0].args; - expect(args[1].hasValidated).to.be.true; - expect(nextFnSpy.calledOnce).to.equal(true); - sinon.assert.calledWith(nextFnSpy, submodules, { ...consentData, hasValidated: true }); - }); - - it('should allow userId module if gdpr not in scope', function () { - let submodules = [{ - submodule: { - gvlid: 1, - name: 'sampleUserId' - } - }]; - let consentData = null; - userIdHook(nextFnSpy, submodules, consentData); - // Should not pass back hasValidated flag since version 2 - const args = nextFnSpy.getCalls()[0].args; - expect(args[1]).to.be.null; - expect(nextFnSpy.calledOnce).to.equal(true); - sinon.assert.calledWith(nextFnSpy, submodules, consentData); - }); - - it('should not allow user id module if user denied consent', function () { - setEnforcementConfig({ - gdpr: { - rules: [{ - purpose: 'storage', - enforcePurpose: false, - enforceVendor: true, - vendorExceptions: [] - }] - } - }); - let consentData = {} - consentData.vendorData = staticConfig.consentData.getTCData; - consentData.apiVersion = 2; - consentData.gdprApplies = true; - - let submodules = [{ - submodule: { - gvlid: 1, - name: 'sampleUserId' - } - }, { - submodule: { - gvlid: 3, - name: 'sampleUserId1' - } - }] - userIdHook(nextFnSpy, submodules, consentData); - expect(logWarnSpy.callCount).to.equal(1); - let expectedSubmodules = [{ - submodule: { - gvlid: 1, - name: 'sampleUserId' - } - }] - sinon.assert.calledWith(nextFnSpy, expectedSubmodules, { ...consentData, hasValidated: true }); - }); - }); - - describe('makeBidRequestsHook', function () { - let sandbox; - let adapterManagerStub; - let emitEventSpy; - - const MOCK_AD_UNITS = [{ - code: 'ad-unit-1', - mediaTypes: {}, - bids: [{ - bidder: 'bidder_1' // has consent - }, { - bidder: 'bidder_2' // doesn't have consent, but liTransparency is true. Bidder remains active. - }] - }, { - code: 'ad-unit-2', - mediaTypes: {}, - bids: [{ - bidder: 'bidder_2' - }, { - bidder: 'bidder_3' - }] - }]; - - beforeEach(function () { - sandbox = sinon.createSandbox(); - gdprDataHandlerStub = sandbox.stub(gdprDataHandler, 'getConsentData'); - adapterManagerStub = sandbox.stub(adapterManager, 'getBidAdapter'); - logWarnSpy = sandbox.spy(utils, 'logWarn'); - nextFnSpy = sandbox.spy(); - emitEventSpy = sandbox.spy(events, 'emit'); - }); - afterEach(function () { - config.resetConfig(); - sandbox.restore(); - }); - - it('should block bidder which does not have consent and allow bidder which has consent (liTransparency is established)', function () { - setEnforcementConfig({ - gdpr: { - rules: [{ - purpose: 'basicAds', - enforcePurpose: true, - enforceVendor: true, - vendorExceptions: [] - }] - } - }); - const consentData = {}; - consentData.vendorData = staticConfig.consentData.getTCData; - consentData.apiVersion = 2; - consentData.gdprApplies = true; - - gdprDataHandlerStub.returns(consentData); - adapterManagerStub.withArgs('bidder_1').returns({ - getSpec: function () { - return { 'gvlid': 4 } - } - }); - adapterManagerStub.withArgs('bidder_2').returns({ - getSpec: function () { - return { 'gvlid': 5 } - } - }); - adapterManagerStub.withArgs('bidder_3').returns({ - getSpec: function () { - return { 'gvlid': undefined } - } - }); - makeBidRequestsHook(nextFnSpy, MOCK_AD_UNITS, []); - - // Assertions - expect(nextFnSpy.calledOnce).to.equal(true); - sinon.assert.calledWith(nextFnSpy, [{ - code: 'ad-unit-1', - mediaTypes: {}, - bids: [ - sinon.match({ bidder: 'bidder_1' }), - sinon.match({ bidder: 'bidder_2' }) - ] - }, { - code: 'ad-unit-2', - mediaTypes: {}, - bids: [ - sinon.match({ bidder: 'bidder_2' }), - sinon.match({ bidder: 'bidder_3' }) // should be allowed even though it's doesn't have a gvlId because liTransparency is established. - ] - }], []); - }); - - it('should block bidder which does not have consent and allow bidder which has consent (liTransparency is NOT established)', function() { - setEnforcementConfig({ - gdpr: { - rules: [{ - purpose: 'basicAds', - enforcePurpose: true, - enforceVendor: true, - vendorExceptions: ['bidder_3'] - }] - } - }); - const consentData = {}; - - // set li for purpose 2 to false - const newConsentData = utils.deepClone(staticConfig); - newConsentData.consentData.getTCData.purpose.legitimateInterests['2'] = false; - - consentData.vendorData = newConsentData.consentData.getTCData; - consentData.apiVersion = 2; - consentData.gdprApplies = true; - - gdprDataHandlerStub.returns(consentData); - adapterManagerStub.withArgs('bidder_1').returns({ - getSpec: function () { - return { 'gvlid': 4 } - } - }); - adapterManagerStub.withArgs('bidder_2').returns({ - getSpec: function () { - return { 'gvlid': 5 } - } - }); - adapterManagerStub.withArgs('bidder_3').returns({ - getSpec: function () { - return { 'gvlid': undefined } - } - }); - - makeBidRequestsHook(nextFnSpy, MOCK_AD_UNITS, []); - - // Assertions - expect(nextFnSpy.calledOnce).to.equal(true); - sinon.assert.calledWith(nextFnSpy, [{ - code: 'ad-unit-1', - mediaTypes: {}, - bids: [ - sinon.match({ bidder: 'bidder_1' }), // 'bidder_2' is not present because it doesn't have vendorConsent - ] - }, { - code: 'ad-unit-2', - mediaTypes: {}, - bids: [ - sinon.match({ bidder: 'bidder_3' }), // 'bidder_3' is allowed despite gvlId being undefined because it's part of vendorExceptions - ] - }], []); - - expect(logWarnSpy.calledOnce).to.equal(true); - }); - - it('should skip validation checks if GDPR version is not equal to "2"', function () { - setEnforcementConfig({ - gdpr: { - rules: [{ - purpose: 'storage', - enforePurpose: false, - enforceVendor: false, - vendorExceptions: [] - }] - } - }); - - const consentData = {}; - consentData.vendorData = staticConfig.consentData.getTCData; - consentData.apiVersion = 1; - consentData.gdprApplies = true; - gdprDataHandlerStub.returns(consentData); - - makeBidRequestsHook(nextFnSpy, MOCK_AD_UNITS, []); - - // Assertions - expect(nextFnSpy.calledOnce).to.equal(true); - sinon.assert.calledWith(nextFnSpy, sinon.match.array.deepEquals(MOCK_AD_UNITS), []); - expect(emitEventSpy.notCalled).to.equal(true); - expect(logWarnSpy.notCalled).to.equal(true); - }); - }); - - describe('enableAnalyticsHook', function () { - let sandbox; - let adapterManagerStub; - - const MOCK_ANALYTICS_ADAPTER_CONFIG = [{ - provider: 'analyticsAdapter_A', - options: {} - }, { - provider: 'analyticsAdapter_B', - options: {} - }, { - provider: 'analyticsAdapter_C', - options: {} - }]; - - beforeEach(function () { - sandbox = sinon.createSandbox(); - gdprDataHandlerStub = sandbox.stub(gdprDataHandler, 'getConsentData'); - adapterManagerStub = sandbox.stub(adapterManager, 'getAnalyticsAdapter'); - logWarnSpy = sandbox.spy(utils, 'logWarn'); - nextFnSpy = sandbox.spy(); - }); - - afterEach(function() { - config.resetConfig(); - sandbox.restore(); - }); - - it('should block analytics adapter which does not have consent and allow the one(s) which have consent', function() { - setEnforcementConfig({ - gdpr: { - rules: [{ - purpose: 'measurement', - enforcePurpose: true, - enforceVendor: true, - vendorExceptions: ['analyticsAdapter_B'] - }] - } - }); - - const consentData = {}; - consentData.vendorData = staticConfig.consentData.getTCData; - consentData.apiVersion = 2; - consentData.gdprApplies = true; - - gdprDataHandlerStub.returns(consentData); - adapterManagerStub.withArgs('analyticsAdapter_A').returns({ gvlid: 3 }); - adapterManagerStub.withArgs('analyticsAdapter_B').returns({ gvlid: 5 }); - adapterManagerStub.withArgs('analyticsAdapter_C').returns({ gvlid: 1 }); - - enableAnalyticsHook(nextFnSpy, MOCK_ANALYTICS_ADAPTER_CONFIG); - - // Assertions - expect(nextFnSpy.calledOnce).to.equal(true); - sinon.assert.calledWith(nextFnSpy, [{ - provider: 'analyticsAdapter_B', - options: {} - }, { - provider: 'analyticsAdapter_C', - options: {} - }]); - expect(logWarnSpy.calledOnce).to.equal(true); - }); - }); - - describe('validateRules', function () { - const createGdprRule = (purposeName = 'storage', enforcePurpose = true, enforceVendor = true, vendorExceptions = []) => ({ - purpose: purposeName, - enforcePurpose: enforcePurpose, - enforceVendor: enforceVendor, - vendorExceptions: vendorExceptions - }); - - const consentData = { - vendorData: staticConfig.consentData.getTCData, - apiVersion: 2, - gdprApplies: true - }; - - // Bidder - 'bidderA' has vendorConsent - const vendorAllowedModule = 'bidderA'; - const vendorAllowedGvlId = 1; - - // Bidder = 'bidderB' doesn't have vendorConsent - const vendorBlockedModule = 'bidderB'; - const vendorBlockedGvlId = 3; - - const consentDataWithPurposeConsentFalse = utils.deepClone(consentData); - consentDataWithPurposeConsentFalse.vendorData.purpose.consents['1'] = false; - - it('should return true when enforcePurpose=true AND purposeConsent[p]==true AND enforceVendor[p,v]==true AND vendorConsent[v]==true', function () { - // 'enforcePurpose' and 'enforceVendor' both are 'true' - const gdprRule = createGdprRule('storage', true, true, []); - - // case 1 - Both purpose consent and vendor consent is 'true'. validateRules must return 'true' - let isAllowed = validateRules(gdprRule, consentData, vendorAllowedModule, vendorAllowedGvlId); - expect(isAllowed).to.equal(true); - - // case 2 - Purpose consent is 'true' but vendor consent is 'false'. validateRules must return 'false' - isAllowed = validateRules(gdprRule, consentData, vendorBlockedModule, vendorBlockedGvlId); - expect(isAllowed).to.equal(false); - - // case 3 - Purpose consent is 'false' but vendor consent is 'true'. validateRules must return 'false' - isAllowed = validateRules(gdprRule, consentDataWithPurposeConsentFalse, vendorAllowedModule, vendorAllowedGvlId); - expect(isAllowed).to.equal(false); - - // case 4 - Both purpose consent and vendor consent is 'false'. validateRules must return 'false' - isAllowed = validateRules(gdprRule, consentDataWithPurposeConsentFalse, vendorBlockedModule, vendorBlockedGvlId); - expect(isAllowed).to.equal(false); - }); - - it('should return true when enforcePurpose=true AND purposeConsent[p]==true AND enforceVendor[p,v]==false', function () { - // 'enforcePurpose' is 'true' and 'enforceVendor' is 'false' - const gdprRule = createGdprRule('storage', true, false, []); - - // case 1 - Both purpose consent and vendor consent is 'true'. validateRules must return 'true' - let isAllowed = validateRules(gdprRule, consentData, vendorAllowedModule, vendorAllowedGvlId); - expect(isAllowed).to.equal(true); - - // case 2 - Purpose consent is 'true' but vendor consent is 'false'. validateRules must return 'true' because vendorConsent doens't matter - isAllowed = validateRules(gdprRule, consentData, vendorBlockedModule, vendorBlockedGvlId); - expect(isAllowed).to.equal(true); - - // case 3 - Purpose consent is 'false' but vendor consent is 'true'. validateRules must return 'false' because vendorConsent doesn't matter - isAllowed = validateRules(gdprRule, consentDataWithPurposeConsentFalse, vendorAllowedModule, vendorAllowedGvlId); - expect(isAllowed).to.equal(false); - - // case 4 - Both purpose consent and vendor consent is 'false'. validateRules must return 'false' and vendorConsent doesn't matter - isAllowed = validateRules(gdprRule, consentDataWithPurposeConsentFalse, vendorBlockedModule, vendorAllowedGvlId); - expect(isAllowed).to.equal(false); - }); - - it('should return true when enforcePurpose=false AND enforceVendor[p,v]==true AND vendorConsent[v]==true', function () { - // 'enforcePurpose' is 'false' and 'enforceVendor' is 'true' - const gdprRule = createGdprRule('storage', false, true, []); - - // case 1 - Both purpose consent and vendor consent is 'true'. validateRules must return 'true' - let isAllowed = validateRules(gdprRule, consentData, vendorAllowedModule, vendorAllowedGvlId); - expect(isAllowed).to.equal(true); - - // case 2 - Purpose consent is 'true' but vendor consent is 'false'. validateRules must return 'false' because purposeConsent doesn't matter - isAllowed = validateRules(gdprRule, consentData, vendorBlockedModule, vendorBlockedGvlId); - expect(isAllowed).to.equal(false); - - // case 3 - urpose consent is 'false' but vendor consent is 'true'. validateRules must return 'true' because purposeConsent doesn't matter - isAllowed = validateRules(gdprRule, consentDataWithPurposeConsentFalse, vendorAllowedModule, vendorAllowedGvlId); - expect(isAllowed).to.equal(true); - - // case 4 - Both purpose consent and vendor consent is 'false'. validateRules must return 'false' and purposeConsent doesn't matter - isAllowed = validateRules(gdprRule, consentDataWithPurposeConsentFalse, vendorBlockedModule, vendorBlockedGvlId); - expect(isAllowed).to.equal(false); - }); - - it('should return true when enforcePurpose=false AND enforceVendor[p,v]==false', function () { - // 'enforcePurpose' is 'false' and 'enforceVendor' is 'false' - const gdprRule = createGdprRule('storage', false, false, []); - - // case 1 - Both purpose consent and vendor consent is 'true'. validateRules must return 'true', both the consents do not matter. - let isAllowed = validateRules(gdprRule, consentData, vendorAllowedModule, vendorAllowedGvlId); - expect(isAllowed).to.equal(true); - - // case 2 - Purpose consent is 'true' but vendor consent is 'false'. validateRules must return 'true', both the consents do not matter. - isAllowed = validateRules(gdprRule, consentData, vendorBlockedModule, vendorBlockedGvlId); - expect(isAllowed).to.equal(true); - - // case 3 - urpose consent is 'false' but vendor consent is 'true'. validateRules must return 'true', both the consents do not matter. - isAllowed = validateRules(gdprRule, consentDataWithPurposeConsentFalse, vendorAllowedModule, vendorAllowedGvlId); - expect(isAllowed).to.equal(true); - - // case 4 - Both purpose consent and vendor consent is 'false'. validateRules must return 'true', both the consents do not matter. - isAllowed = validateRules(gdprRule, consentDataWithPurposeConsentFalse, vendorBlockedModule, vendorBlockedGvlId); - expect(isAllowed).to.equal(true); - }); - - it('should return true when "vendorExceptions" contains the name of the vendor under test', function () { - // 'vendorExceptions' contains 'bidderB' which doesn't have vendor consent. - const gdprRule = createGdprRule('storage', false, true, [vendorBlockedModule]); - - /* 'bidderB' gets a free pass since it's included in the 'vendorExceptions' array. validateRules must disregard - user's choice for purpose and vendor consent and return 'true' for this bidder(s) */ - const isAllowed = validateRules(gdprRule, consentData, vendorBlockedModule, vendorBlockedGvlId); - expect(isAllowed).to.equal(true); - }); - - describe('Purpose 2 special case', function () { - const consentDataWithLIFalse = utils.deepClone(consentData); - consentDataWithLIFalse.vendorData.purpose.legitimateInterests['2'] = false; - - const consentDataWithPurposeConsentFalse = utils.deepClone(consentData); - consentDataWithPurposeConsentFalse.vendorData.purpose.consents['2'] = false; - - const consentDataWithPurposeConsentFalseAndLIFalse = utils.deepClone(consentData); - consentDataWithPurposeConsentFalseAndLIFalse.vendorData.purpose.legitimateInterests['2'] = false; - consentDataWithPurposeConsentFalseAndLIFalse.vendorData.purpose.consents['2'] = false; - - it('should return true when (enforcePurpose=true AND purposeConsent[p]===true AND enforceVendor[p.v]===true AND vendorConsent[v]===true) OR (purposesLITransparency[p]===true)', function () { - // both 'enforcePurpose' and 'enforceVendor' is 'true' - const gdprRule = createGdprRule('basicAds', true, true, []); - - // case 1 - Both purpose consent and vendor consent is 'true', but legitimateInterests for purpose 2 is 'false'. validateRules must return 'true'. - let isAllowed = validateRules(gdprRule, consentDataWithLIFalse, vendorAllowedModule, vendorAllowedGvlId); - expect(isAllowed).to.equal(true); - - // case 2 - Purpose consent is 'true' but vendor consent is 'false', but legitimateInterests for purpose 2 is 'true'. validateRules must return 'true'. - isAllowed = validateRules(gdprRule, consentData, vendorBlockedModule, vendorBlockedGvlId); - expect(isAllowed).to.equal(true); - - // case 3 - Purpose consent is 'true' and vendor consent is 'true', as well as legitimateInterests for purpose 2 is 'true'. validateRules must return 'true'. - isAllowed = validateRules(gdprRule, consentData, vendorAllowedModule, vendorAllowedGvlId); - expect(isAllowed).to.equal(true); - - // case 4 - Purpose consent is 'true' and vendor consent is 'false', and legitimateInterests for purpose 2 is 'false'. validateRules must return 'false'. - isAllowed = validateRules(gdprRule, consentDataWithLIFalse, vendorBlockedModule, vendorBlockedGvlId); - expect(isAllowed).to.equal(false); - }); - - it('should return true when (enforcePurpose=true AND purposeConsent[p]===true AND enforceVendor[p.v]===false) OR (purposesLITransparency[p]===true)', function () { - // 'enforcePurpose' is 'true' and 'enforceVendor' is 'false' - const gdprRule = createGdprRule('basicAds', true, false, []); - - // case 1 - Purpose consent is 'true', vendor consent doesn't matter and legitimateInterests for purpose 2 is 'true'. validateRules must return 'true'. - let isAllowed = validateRules(gdprRule, consentData, vendorBlockedModule, vendorBlockedGvlId); - expect(isAllowed).to.equal(true); - - // case 2 - Purpose consent is 'false', vendor consent doesn't matter and legitimateInterests for purpose 2 is 'true'. validateRules must return 'true'. - isAllowed = validateRules(gdprRule, consentDataWithPurposeConsentFalse, vendorAllowedModule, vendorAllowedGvlId); - expect(isAllowed).to.equal(true); - - // case 3 - Purpose consent is 'false', vendor consent doesn't matter and legitimateInterests for purpose 2 is 'false'. validateRules must return 'false'. - isAllowed = validateRules(gdprRule, consentDataWithPurposeConsentFalseAndLIFalse, vendorAllowedModule, vendorAllowedGvlId); - expect(isAllowed).to.equal(false); - }); - - it('should return true when (enforcePurpose=false AND enforceVendor[p,v]===true AND vendorConsent[v]===true) OR (purposesLITransparency[p]===true)', function () { - // 'enforcePurpose' is 'false' and 'enforceVendor' is 'true' - const gdprRule = createGdprRule('basicAds', false, true, []); - - // case - 1 Vendor consent is 'true', purpose consent doesn't matter and legitimateInterests for purpose 2 is 'true'. validateRules must return 'true'. - let isAllowed = validateRules(gdprRule, consentData, vendorAllowedModule, vendorAllowedGvlId); - expect(isAllowed).to.equal(true); - - // case 2 - Vendor consent is 'false', purpose consent doesn't matter and legitimateInterests for purpose 2 is 'true'. validateRules must return 'true'. - isAllowed = validateRules(gdprRule, consentData, vendorBlockedModule, vendorBlockedGvlId); - expect(isAllowed).to.equal(true); - - // case 3 - Vendor consent is 'false', purpose consent doesn't matter and legitimateInterests for purpose 2 is 'false'. validateRules must return 'false'. - isAllowed = validateRules(gdprRule, consentDataWithLIFalse, vendorBlockedModule, vendorBlockedGvlId); - expect(isAllowed).to.equal(false); - }); - }); - }) - - describe('setEnforcementConfig', function () { - let sandbox; - const DEFAULT_RULES = [{ - purpose: 'storage', - enforcePurpose: true, - enforceVendor: true, - vendorExceptions: [] - }, { - purpose: 'basicAds', - enforcePurpose: true, - enforceVendor: true, - vendorExceptions: [] - }]; - beforeEach(function () { - sandbox = sinon.createSandbox(); - logWarnSpy = sandbox.spy(utils, 'logWarn'); - }); - afterEach(function () { - config.resetConfig(); - sandbox.restore(); - }); - - it('should enforce TCF2 Purpose1 and Purpose 2 if no "rules" found in the config', function () { - setEnforcementConfig({ - gdpr: { - cmpApi: 'iab', - allowAuctionWithoutConsent: true, - timeout: 5000 - } - }); - - expect(logWarnSpy.calledOnce).to.equal(true); - expect(enforcementRules).to.deep.equal(DEFAULT_RULES); - }); - - it('should enforce TCF2 Purpose 2 also if only Purpose 1 is defined in "rules"', function () { - const purpose1RuleDefinedInConfig = { - purpose: 'storage', - enforcePurpose: false, - enforceVendor: true, - vendorExceptions: ['bidderA'] - } - setEnforcementConfig({ - gdpr: { - rules: [purpose1RuleDefinedInConfig] - } - }); - - expect(purpose1Rule).to.deep.equal(purpose1RuleDefinedInConfig); - expect(purpose2Rule).to.deep.equal(DEFAULT_RULES[1]); - }); - - it('should enforce TCF2 Purpose 1 also if only Purpose 2 is defined in "rules"', function () { - const purpose2RuleDefinedInConfig = { - purpose: 'basicAds', - enforcePurpose: false, - enforceVendor: true, - vendorExceptions: ['bidderA'] - } - setEnforcementConfig({ - gdpr: { - rules: [purpose2RuleDefinedInConfig] - } - }); - - expect(purpose1Rule).to.deep.equal(DEFAULT_RULES[0]); - expect(purpose2Rule).to.deep.equal(purpose2RuleDefinedInConfig); - }); - - it('should use the "rules" defined in config if a definition found', function() { - const rules = [{ - purpose: 'storage', - enforcePurpose: false, - enforceVendor: false - }, { - purpose: 'basicAds', - enforcePurpose: false, - enforceVendor: false - }] - setEnforcementConfig({gdpr: { rules }}); - - expect(enforcementRules).to.deep.equal(rules); - }); - }); - - describe('TCF2FinalResults', function() { - let sandbox; - beforeEach(function() { - sandbox = sinon.createSandbox(); - sandbox.spy(events, 'emit'); - }); - afterEach(function() { - config.resetConfig(); - sandbox.restore(); - }); - it('should emit TCF2 enforcement data on auction end', function() { - const rules = [{ - purpose: 'storage', - enforcePurpose: false, - enforceVendor: false - }, { - purpose: 'basicAds', - enforcePurpose: false, - enforceVendor: false - }] - setEnforcementConfig({gdpr: { rules }}); - - events.emit('auctionEnd', {}) - - // Assertions - sinon.assert.calledWith(events.emit.getCall(1), 'tcf2Enforcement', sinon.match.object); - }) - }); - - describe('getGvlid', function() { - let sandbox; - let getGvlidForBidAdapterStub; - let getGvlidForUserIdModuleStub; - let getGvlidForAnalyticsAdapterStub; - beforeEach(function() { - sandbox = sinon.createSandbox(); - getGvlidForBidAdapterStub = sandbox.stub(internal, 'getGvlidForBidAdapter'); - getGvlidForUserIdModuleStub = sandbox.stub(internal, 'getGvlidForUserIdModule'); - getGvlidForAnalyticsAdapterStub = sandbox.stub(internal, 'getGvlidForAnalyticsAdapter'); - }); - afterEach(function() { - sandbox.restore(); - config.resetConfig(); - }); - - it('should return "null" if called without passing any argument', function() { - const gvlid = getGvlid(); - expect(gvlid).to.equal(null); - }); - - it('should return "null" if GVL ID is not defined for any of these modules: Bid adapter, UserId submodule and Analytics adapter', function() { - getGvlidForBidAdapterStub.withArgs('moduleA').returns(null); - getGvlidForUserIdModuleStub.withArgs('moduleA').returns(null); - getGvlidForAnalyticsAdapterStub.withArgs('moduleA').returns(null); - - const gvlid = getGvlid('moduleA'); - expect(gvlid).to.equal(null); - }); - - it('should return the GVL ID from gvlMapping if it is defined in setConfig', function() { - config.setConfig({ - gvlMapping: { - moduleA: 1 - } - }); - - // Actual GVL ID for moduleA is 2, as defined on its the bidAdapter.js file. - getGvlidForBidAdapterStub.withArgs('moduleA').returns(2); - - const gvlid = getGvlid('moduleA'); - expect(gvlid).to.equal(1); - }); - - it('should return the GVL ID by calling getGvlidForBidAdapter -> getGvlidForUserIdModule -> getGvlidForAnalyticsAdapter in sequence', function() { - getGvlidForBidAdapterStub.withArgs('moduleA').returns(null); - getGvlidForUserIdModuleStub.withArgs('moduleA').returns(null); - getGvlidForAnalyticsAdapterStub.withArgs('moduleA').returns(7); - - expect(getGvlid('moduleA')).to.equal(7); - }); - }); -}); diff --git a/test/spec/modules/geoedgeRtdProvider_spec.js b/test/spec/modules/geoedgeRtdProvider_spec.js deleted file mode 100644 index cf4e0b53fde..00000000000 --- a/test/spec/modules/geoedgeRtdProvider_spec.js +++ /dev/null @@ -1,111 +0,0 @@ -import * as utils from '../../../src/utils.js'; -import * as hook from '../../../src/hook.js' -import { beforeInit, geoedgeSubmodule, setWrapper, wrapper, htmlPlaceholder, WRAPPER_URL, getClientUrl } from '../../../modules/geoedgeRtdProvider.js'; -import { server } from '../../../test/mocks/xhr.js'; - -let key = '123123123'; -function makeConfig() { - return { - name: 'geoedge', - params: { - wap: false, - key: key, - bidders: { - bidderA: true, - bidderB: false - } - } - }; -} - -function mockBid(bidderCode) { - return { - 'ad': '', - 'cpm': '1.00', - 'width': 300, - 'height': 250, - 'bidderCode': bidderCode, - 'requestId': utils.getUniqueIdentifierStr(), - 'creativeId': 'id', - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 360 - }; -} - -let mockWrapper = `${htmlPlaceholder}`; - -describe('Geoedge RTD module', function () { - describe('beforeInit', function () { - let submoduleStub; - - before(function () { - submoduleStub = sinon.stub(hook, 'submodule'); - }); - after(function () { - submoduleStub.restore(); - }); - it('should fetch the wrapper', function () { - beforeInit(); - let request = server.requests[0]; - let isWrapperRequest = request && request.url && request.url && request.url === WRAPPER_URL; - expect(isWrapperRequest).to.equal(true); - }); - it('should register RTD submodule provider', function () { - expect(submoduleStub.calledWith('realTimeData', geoedgeSubmodule)).to.equal(true); - }); - }); - describe('setWrapper', function () { - it('should set the wrapper', function () { - setWrapper(mockWrapper); - expect(wrapper).to.equal(mockWrapper); - }); - }); - describe('submodule', function () { - describe('name', function () { - it('should be geoedge', function () { - expect(geoedgeSubmodule.name).to.equal('geoedge'); - }); - }); - describe('init', function () { - let insertElementStub; - - before(function () { - insertElementStub = sinon.stub(utils, 'insertElement'); - }); - after(function () { - utils.insertElement.restore(); - }); - it('should return false when missing params or key', function () { - let missingParams = geoedgeSubmodule.init({}); - let missingKey = geoedgeSubmodule.init({ params: {} }); - expect(missingParams || missingKey).to.equal(false); - }); - it('should return true when params are ok', function () { - expect(geoedgeSubmodule.init(makeConfig())).to.equal(true); - }); - it('should preload the client', function () { - let isLinkPreloadAsScript = arg => arg.tagName === 'LINK' && arg.rel === 'preload' && arg.as === 'script' && arg.href === getClientUrl(key); - expect(insertElementStub.calledWith(sinon.match(isLinkPreloadAsScript))).to.equal(true); - }); - }); - describe('onBidResponseEvent', function () { - let bidFromA = mockBid('bidderA'); - it('should wrap bid html when bidder is configured', function () { - geoedgeSubmodule.onBidResponseEvent(bidFromA, makeConfig()); - expect(bidFromA.ad.indexOf('')).to.equal(0); - }); - it('should not wrap bid html when bidder is not configured', function () { - let bidFromB = mockBid('bidderB'); - geoedgeSubmodule.onBidResponseEvent(bidFromB, makeConfig()); - expect(bidFromB.ad.indexOf('')).to.equal(-1); - }); - it('should only muatate the bid ad porperty', function () { - let copy = Object.assign({}, bidFromA); - delete copy.ad; - let equalsOriginal = Object.keys(copy).every(key => copy[key] === bidFromA[key]); - expect(equalsOriginal).to.equal(true); - }); - }); - }); -}); diff --git a/test/spec/modules/getintentBidAdapter_spec.js b/test/spec/modules/getintentBidAdapter_spec.js deleted file mode 100644 index 1959bda5c39..00000000000 --- a/test/spec/modules/getintentBidAdapter_spec.js +++ /dev/null @@ -1,142 +0,0 @@ -import { expect } from 'chai' -import { spec } from 'modules/getintentBidAdapter.js' - -describe('GetIntent Adapter Tests:', function () { - const bidRequests = [{ - bidId: 'bid12345', - params: { - pid: 'p1000', - tid: 't1000' - }, - sizes: [[300, 250]] - }, - { - bidId: 'bid54321', - params: { - pid: 'p1000', - tid: 't1000' - }, - sizes: [[50, 50], [100, 100]] - }] - const videoBidRequest = { - bidId: 'bid789', - params: { - pid: 'p1001', - tid: 't1001', - video: { - mimes: ['video/mp4', 'application/javascript'], - max_dur: 20, - api: [1, 2], - skippable: true - } - }, - sizes: [300, 250], - mediaType: 'video' - }; - - it('Verify build request', function () { - const serverRequests = spec.buildRequests(bidRequests); - let serverRequest = serverRequests[0]; - expect(serverRequest.url).to.equal('https://px.adhigh.net/rtb/direct_banner'); - expect(serverRequest.method).to.equal('GET'); - expect(serverRequest.data.bid_id).to.equal('bid12345'); - expect(serverRequest.data.pid).to.equal('p1000'); - expect(serverRequest.data.tid).to.equal('t1000'); - expect(serverRequest.data.size).to.equal('300x250'); - expect(serverRequest.data.is_video).to.equal(false); - serverRequest = serverRequests[1]; - expect(serverRequest.data.size).to.equal('50x50,100x100'); - }); - - it('Verify build video request', function () { - const serverRequests = spec.buildRequests([videoBidRequest]); - let serverRequest = serverRequests[0]; - expect(serverRequest.url).to.equal('https://px.adhigh.net/rtb/direct_vast'); - expect(serverRequest.method).to.equal('GET'); - expect(serverRequest.data.bid_id).to.equal('bid789'); - expect(serverRequest.data.pid).to.equal('p1001'); - expect(serverRequest.data.tid).to.equal('t1001'); - expect(serverRequest.data.size).to.equal('300x250'); - expect(serverRequest.data.is_video).to.equal(true); - expect(serverRequest.data.mimes).to.equal('video/mp4,application/javascript'); - expect(serverRequest.data.max_dur).to.equal(20); - expect(serverRequest.data.api).to.equal('1,2'); - expect(serverRequest.data.skippable).to.equal(true); - }); - - it('Verify parse response', function () { - const serverResponse = { - body: { - bid_id: 'bid12345', - cpm: 2.25, - currency: 'USD', - size: '300x250', - creative_id: '1000', - ad: 'Ad markup' - }, - headers: { - } - }; - const bids = spec.interpretResponse(serverResponse); - expect(bids).to.have.lengthOf(1); - const bid = bids[0]; - expect(bid.cpm).to.equal(2.25); - expect(bid.currency).to.equal('USD'); - expect(bid.creativeId).to.equal('1000'); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.requestId).to.equal('bid12345'); - expect(bid.mediaType).to.equal('banner'); - expect(bid.ad).to.equal('Ad markup'); - }); - - it('Verify parse video response', function () { - const serverResponse = { - body: { - bid_id: 'bid789', - cpm: 3.25, - currency: 'USD', - size: '300x250', - creative_id: '2000', - vast_url: 'https://vast.xml/url' - }, - headers: { - } - }; - const bids = spec.interpretResponse(serverResponse); - expect(bids).to.have.lengthOf(1); - const bid = bids[0]; - expect(bid.cpm).to.equal(3.25); - expect(bid.currency).to.equal('USD'); - expect(bid.creativeId).to.equal('2000'); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.requestId).to.equal('bid789'); - expect(bid.mediaType).to.equal('video'); - expect(bid.vastUrl).to.equal('https://vast.xml/url'); - }); - - it('Verify bidder code', function () { - expect(spec.code).to.equal('getintent'); - }); - - it('Verify bidder aliases', function () { - expect(spec.aliases).to.have.lengthOf(1); - expect(spec.aliases[0]).to.equal('getintentAdapter'); - }); - - it('Verify supported media types', function () { - expect(spec.supportedMediaTypes).to.have.lengthOf(2); - expect(spec.supportedMediaTypes[0]).to.equal('video'); - expect(spec.supportedMediaTypes[1]).to.equal('banner'); - }); - - it('Verify if bid request valid', function () { - expect(spec.isBidRequestValid(bidRequests[0])).to.equal(true); - expect(spec.isBidRequestValid(bidRequests[1])).to.equal(true); - expect(spec.isBidRequestValid({})).to.equal(false); - expect(spec.isBidRequestValid({ params: {} })).to.equal(false); - expect(spec.isBidRequestValid({ params: { test: 123 } })).to.equal(false); - expect(spec.isBidRequestValid({ params: { pid: 111, tid: 222 } })).to.equal(true); - }); -}); diff --git a/test/spec/modules/gjirafaBidAdapter_spec.js b/test/spec/modules/gjirafaBidAdapter_spec.js deleted file mode 100644 index f0fb01f4398..00000000000 --- a/test/spec/modules/gjirafaBidAdapter_spec.js +++ /dev/null @@ -1,168 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/gjirafaBidAdapter'; - -describe('gjirafaAdapterTest', () => { - describe('bidRequestValidity', () => { - it('bidRequest with propertyId and placementId', () => { - expect(spec.isBidRequestValid({ - bidder: 'gjirafa', - params: { - propertyId: '{propertyId}', - placementId: '{placementId}' - } - })).to.equal(true); - }); - - it('bidRequest without propertyId', () => { - expect(spec.isBidRequestValid({ - bidder: 'gjirafa', - params: { - placementId: '{placementId}' - } - })).to.equal(false); - }); - - it('bidRequest without placementId', () => { - expect(spec.isBidRequestValid({ - bidder: 'gjirafa', - params: { - propertyId: '{propertyId}', - } - })).to.equal(false); - }); - - it('bidRequest without propertyId or placementId', () => { - expect(spec.isBidRequestValid({ - bidder: 'gjirafa', - params: {} - })).to.equal(false); - }); - }); - - describe('bidRequest', () => { - const bidRequests = [{ - 'bidder': 'gjirafa', - 'params': { - 'propertyId': '{propertyId}', - 'placementId': '{placementId}', - 'data': { - 'catalogs': [{ - 'catalogId': 1, - 'items': ['1', '2', '3'] - }], - 'inventory': { - 'category': ['category1', 'category2'], - 'query': ['query'] - } - } - }, - 'adUnitCode': 'hb-leaderboard', - 'transactionId': 'b6b889bb-776c-48fd-bc7b-d11a1cf0425e', - 'sizes': [[728, 90]], - 'bidId': '10bdc36fe0b48c8', - 'bidderRequestId': '70deaff71c281d', - 'auctionId': 'f9012acc-b6b7-4748-9098-97252914f9dc' - }]; - - it('bidRequest HTTP method', () => { - const requests = spec.buildRequests(bidRequests); - requests.forEach(function (requestItem) { - expect(requestItem.method).to.equal('POST'); - }); - }); - - it('bidRequest url', () => { - const endpointUrl = 'https://central.gjirafa.com/bid'; - const requests = spec.buildRequests(bidRequests); - requests.forEach(function (requestItem) { - expect(requestItem.url).to.match(new RegExp(`${endpointUrl}`)); - }); - }); - - it('bidRequest data', () => { - const requests = spec.buildRequests(bidRequests); - requests.forEach(function (requestItem) { - expect(requestItem.data).to.exist; - }); - }); - - it('bidRequest sizes', () => { - const requests = spec.buildRequests(bidRequests); - requests.forEach(function (requestItem) { - expect(requestItem.data.placements).to.exist; - expect(requestItem.data.placements.length).to.equal(1); - expect(requestItem.data.placements[0].sizes).to.equal('728x90'); - }); - }); - - it('bidRequest data param', () => { - const requests = spec.buildRequests(bidRequests); - requests.forEach((requestItem) => { - expect(requestItem.data.data).to.exist; - expect(requestItem.data.data.catalogs).to.exist; - expect(requestItem.data.data.inventory).to.exist; - expect(requestItem.data.data.catalogs.length).to.equal(1); - expect(requestItem.data.data.catalogs[0].items.length).to.equal(3); - expect(Object.keys(requestItem.data.data.inventory).length).to.equal(2); - expect(requestItem.data.data.inventory.category.length).to.equal(2); - expect(requestItem.data.data.inventory.query.length).to.equal(1); - }); - }); - }); - - describe('interpretResponse', () => { - const bidRequest = { - 'method': 'POST', - 'url': 'https://central.gjirafa.com/bid', - 'data': { - 'sizes': '728x90', - 'adUnitId': 'hb-leaderboard', - 'placementId': '{placementId}', - 'propertyId': '{propertyId}', - 'pageViewGuid': '{pageViewGuid}', - 'url': 'http://localhost:9999/integrationExamples/gpt/hello_world.html?pbjs_debug=true', - 'requestid': '26ee8fe87940da7', - 'bidid': '2962dbedc4768bf' - } - }; - - const bidResponse = { - body: [{ - 'CPM': 1, - 'Width': 728, - 'Height': 90, - 'Referrer': 'http://localhost:9999/integrationExamples/gpt/hello_world.html?pbjs_debug=true', - 'Ad': '
Test ad
', - 'CreativeId': '123abc', - 'NetRevenue': false, - 'Currency': 'EUR', - 'TTL': 360 - }], - headers: {} - }; - - it('all keys present', () => { - const result = spec.interpretResponse(bidResponse, bidRequest); - - let keys = [ - 'requestId', - 'cpm', - 'width', - 'height', - 'creativeId', - 'currency', - 'netRevenue', - 'ttl', - 'referrer', - 'ad', - 'vastUrl', - 'mediaType' - ]; - - let resultKeys = Object.keys(result[0]); - resultKeys.forEach(function (key) { - expect(keys.indexOf(key) !== -1).to.equal(true); - }); - }) - }); -}); diff --git a/test/spec/modules/glimpseBidAdapter_spec.js b/test/spec/modules/glimpseBidAdapter_spec.js deleted file mode 100644 index cc11efcb2af..00000000000 --- a/test/spec/modules/glimpseBidAdapter_spec.js +++ /dev/null @@ -1,179 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/glimpseBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -/** - * Test Helpers - */ - -const API = 'https://api.glimpseprotocol.io/cloud/v1/vault/prebid'; - -const templateBidRequest = { - bidder: 'glimpse', - params: { - placementId: 'glimpse-demo-300x250', - }, - adUnitCode: 'banner-div-a', - sizes: [[300, 250]], - bidId: '26a80b71cfd671', - bidderRequestId: '133baeded6ac94', - auctionId: '96692a73-307b-44b8-8e4f-ddfb40341570', -}; - -const templateBidderRequest = { - bidderCode: 'glimpse', - auctionId: '96692a73-307b-44b8-8e4f-ddfb40341570', - bidderRequestId: '133baeded6ac94', - timeout: 3000, - gdprConsent: { - apiVersion: 2, - consentString: - 'COzP517OzP517AcABBENAlCsAP_AAAAAAAwIF8NX-T5eL2vju2Zdt7JEaYwfZxyigOgThgQIsW8NwIeFbBoGP2EgHBG4JCQAGBAkkgCBAQMsHGBcCQAAgIgRiRKMYE2MjzNKBJJAigkbc0FACDVunsHS2ZCY70-8O__bPAviADAvUC-AAAAA.YAAAAAAAAAAA', - gdprApplies: true, - vendorData: {}, - }, - refererInfo: { - referer: 'https://demo.glimpseprotocol.io/prebid/desktop', - reachedTop: true, - numIframes: 0, - stack: ['https://demo.glimpseprotocol.io/prebid/desktop'], - }, -}; - -const templateBidResponse = { - ad: '
HelloWorld
', - adUnitCode: 'banner-div-a', - bidder: 'glimpse', - cpm: 1.04, - creativeId: 'glimpse-demo-300x250', - currency: 'GBP', - height: 250, - mediaType: 'banner', - netRevenue: true, - pbAg: '1.04', - pbDg: '1.04', - pbHg: '1.04', - pbLg: '1.00', - pbMg: '1.05', - requestId: '133baeded6ac94', - ttl: 60, - width: 300, -}; - -const copyBidResponse = () => ({ ...templateBidResponse }); -const copyBidderRequest = () => ({ ...templateBidderRequest, bids: copyBidRequests() }); -const copyBidRequest = () => ({ ...templateBidRequest }); - -const copyBidRequests = () => [copyBidRequest()]; -const copyBidResponses = () => ({ - body: [copyBidResponse()], -}); - -/** - * Tests - */ - -describe('GlimpseProtocolAdapter', 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'); - expect(adapter.getSpec).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - it('should return true when params.placementId is valid', function () { - expect(spec.isBidRequestValid(templateBidRequest)).to.equal(true); - }); - - it('should return false when params.placementId is invalid', function () { - let bid = copyBidRequest(); - delete bid.params; - bid.params = { - placementId: 0, - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when params is not passed', function () { - let bid = copyBidRequest(); - delete bid.params; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when params.placementId is not passed', function () { - let bid = copyBidRequest(); - delete bid.params.placementId; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const bidRequest = copyBidRequest(); - const bidRequests = [bidRequest]; - - it('should add version and source information', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - - expect(payload.sdk).to.exist; - expect(payload.sdk).to.deep.equal({ - source: 'pbjs', - version: '$prebid.version$', - }); - }); - - it('should send request to API via POST', function () { - const request = spec.buildRequests(bidRequests); - expect(request.url).to.equal(API); - expect(request.method).to.equal('POST'); - }); - - it('should add GDPR consent', function () { - const bidderRequest = copyBidderRequest(); - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.gdprConsent).to.exist; - const { gdprConsent } = payload; - expect(gdprConsent.gdprApplies).to.be.true; - expect(gdprConsent.consentString).to.equal(bidderRequest.gdprConsent.consentString); - }); - - it('should add referer info', function () { - const bidderRequest = copyBidderRequest(); - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.refererInfo.referer).to.equal(templateBidderRequest.refererInfo.referer); - }); - }); - - describe('interpretResponse', function () { - it('should handle valid bid responses', function () { - const response = copyBidResponses(); - - const bids = spec.interpretResponse(response); - expect(bids).to.have.length(1); - expect(bids[0].adUnitCode).to.equal(templateBidRequest.adUnitCode); - }); - - it('should handle no bid responses', function () { - const response = copyBidResponses(); - response.body = []; - - const bids = spec.interpretResponse(response); - expect(bids).to.have.length(0); - }); - - it('should return no bid on an invalid response', function () { - const response = copyBidResponses(); - delete response.body; - - const bids = spec.interpretResponse(response); - expect(bids).to.have.length(0); - }); - }); -}); diff --git a/test/spec/modules/glomexBidAdapter_spec.js b/test/spec/modules/glomexBidAdapter_spec.js deleted file mode 100644 index b43623928f7..00000000000 --- a/test/spec/modules/glomexBidAdapter_spec.js +++ /dev/null @@ -1,133 +0,0 @@ -import { expect } from 'chai' -import { spec } from 'modules/glomexBidAdapter.js' -import { newBidder } from 'src/adapters/bidderFactory.js' - -const REQUEST = { - bidder: 'glomex', - params: { - integrationId: 'abcdefg', - playlistId: 'defghjk' - }, - bidderRequestId: '143346cf0f1732', - auctionId: '2e41f65424c87c', - adUnitCode: 'adunit-code', - bidId: '2d925f27f5079f', - sizes: [640, 360] -} - -const BIDDER_REQUEST = { - auctionId: '2d921234f5079f', - refererInfo: { - isAmp: true, - numIframes: 0, - reachedTop: true, - referer: 'https://glomex.com' - }, - gdprConsent: { - gdprApplies: true, - consentString: 'CO5asbJO5asbJE-AAAENAACAAAAAAAAAAAYgAAAAAAAA.IAAA' - } -} - -const RESPONSE = { - bids: [ - { - id: '2d925f27f5079f', - cpm: 3.5, - width: 640, - height: 360, - creativeId: 'creative-1j75x4ln1kk6m1ius', - dealId: 'deal-1j75x4ln1kk6m1iut', - currency: 'EUR', - netRevenue: true, - ttl: 300, - ad: '' - } - ] -} -describe('glomexBidAdapter', 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 () { - it('should return true when required params found', function () { - const request = { - 'params': { - 'integrationId': 'abcdefg' - } - } - expect(spec.isBidRequestValid(request)).to.equal(true) - }) - - it('should return false when required params are not passed', function () { - expect(spec.isBidRequestValid({})).to.equal(false) - }) - }) - - describe('buildRequests', function () { - const bidRequests = [REQUEST] - const request = spec.buildRequests(bidRequests, BIDDER_REQUEST) - - it('sends bid request to ENDPOINT via POST', function () { - expect(request.method).to.equal('POST') - }) - - it('returns a list of valid requests', function () { - expect(request.validBidRequests).to.eql([REQUEST]) - }) - - it('sends params.integrationId', function () { - expect(request.validBidRequests[0].params.integrationId).to.eql(REQUEST.params.integrationId) - }) - - it('sends params.playlistId', function () { - expect(request.validBidRequests[0].params.playlistId).to.eql(REQUEST.params.playlistId) - }) - - it('sends refererInfo', function () { - expect(request.data.refererInfo).to.eql(BIDDER_REQUEST.refererInfo) - }) - - it('sends gdprConsent', function () { - expect(request.data.gdprConsent).to.eql(BIDDER_REQUEST.gdprConsent) - }) - - it('sends the auctionId', function () { - expect(request.data.auctionId).to.eql(BIDDER_REQUEST.auctionId) - }) - }) - - 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) - }) - - it('handles the server response', function () { - const result = spec.interpretResponse( - { - body: RESPONSE - }, - { - validBidRequests: [REQUEST] - } - ) - - expect(result[0].requestId).to.equal('2d925f27f5079f') - expect(result[0].cpm).to.equal(3.5) - expect(result[0].width).to.equal(640) - expect(result[0].height).to.equal(360) - expect(result[0].creativeId).to.equal('creative-1j75x4ln1kk6m1ius') - expect(result[0].dealId).to.equal('deal-1j75x4ln1kk6m1iut') - expect(result[0].currency).to.equal('EUR') - expect(result[0].netRevenue).to.equal(true) - expect(result[0].ttl).to.equal(300) - expect(result[0].ad).to.equal('') - }) - }) -}) diff --git a/test/spec/modules/gmosspBidAdapter_spec.js b/test/spec/modules/gmosspBidAdapter_spec.js deleted file mode 100644 index 52bb8460caa..00000000000 --- a/test/spec/modules/gmosspBidAdapter_spec.js +++ /dev/null @@ -1,174 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/gmosspBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import * as utils from 'src/utils.js'; - -const ENDPOINT = 'https://sp.gmossp-sp.jp/hb/prebid/query.ad'; - -describe('GmosspAdapter', 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 () { - let bid = { - bidder: 'gmossp', - params: { - sid: '123456' - } - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const bidRequests = [ - { - bidder: 'gmossp', - params: { - sid: '123456' - }, - adUnitCode: 'adunit-code', - sizes: [ - [300, 250], - [320, 50], - [320, 100], - ], - bidId: '2b84475b5b636e', - bidderRequestId: '1f4001782ac16c', - auctionId: 'aba03555-4802-4c45-9f15-05ffa8594cff', - transactionId: '791e9d84-af92-4903-94da-24c7426d9d0c' - } - ]; - - it('sends bid request to ENDPOINT via GET', function () { - const bidderRequest = { - refererInfo: { - referer: 'https://hoge.com' - } - }; - - const requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests[0].url).to.equal(ENDPOINT); - expect(requests[0].method).to.equal('GET'); - expect(requests[0].data).to.equal('tid=791e9d84-af92-4903-94da-24c7426d9d0c&bid=2b84475b5b636e&ver=$prebid.version$&sid=123456&url=https%3A%2F%2Fhoge.com&cur=JPY&dnt=0&'); - }); - - it('should use fallback if refererInfo.referer in bid request is empty', function () { - const bidderRequest = { - refererInfo: { - referer: '' - } - }; - - const requests = spec.buildRequests(bidRequests, bidderRequest); - const result = 'tid=791e9d84-af92-4903-94da-24c7426d9d0c&bid=2b84475b5b636e&ver=$prebid.version$&sid=123456&url=' + encodeURIComponent(window.top.location.href) + '&cur=JPY&dnt=0&'; - expect(requests[0].data).to.equal(result); - }); - }); - - describe('interpretResponse', function () { - const bidderRequests = [ - { - bidder: 'gmossp', - params: { - sid: '123456' - }, - adUnitCode: 'adunit-code', - sizes: [ - [300, 250], - [320, 50], - [320, 100], - ], - bidId: '2b84475b5b636e', - bidderRequestId: '1f4001782ac16c', - auctionId: 'aba03555-4802-4c45-9f15-05ffa8594cff', - transactionId: '791e9d84-af92-4903-94da-24c7426d9d0c' - } - ]; - - it('should get correct banner bid response', function() { - const response = { - bid: '2b84475b5b636e', - price: 20, - w: 300, - h: 250, - ad: '
', - creativeId: '985ec572b32be309.76973017', - cur: 'JPY', - dealId: '', - imps: [ - 'https://sp.gmossp-sp.jp/hb/prebid/imp.ad' - ], - syncs: [ - 'https://sync.dsp.reemo-ad.jp' - ], - ttl: 300 - }; - - const expectedResponse = [ - { - requestId: '2b84475b5b636e', - cpm: 20, - currency: 'JPY', - width: 300, - height: 250, - ad: '
', - creativeId: '985ec572b32be309.76973017', - netRevenue: true, - ttl: 300 - } - ]; - - const result = spec.interpretResponse({ body: response }, bidderRequests); - expect(result).to.have.lengthOf(1); - - response.imps.forEach(impTracker => { - const tracker = utils.createTrackPixelHtml(impTracker); - expectedResponse[0].ad += tracker; - }); - - expect(result).to.deep.have.same.members(expectedResponse); - }); - - it('handles nobid responses', function () { - const response = ''; - - const result = spec.interpretResponse({ body: response }, bidderRequests); - expect(result.length).to.equal(0); - }); - }); - - describe('getUserSyncs', function () { - const bidResponse = { - body: { - ad: {}, - syncs: [ - 'https://hoge.com' - ] - } - }; - it('should return returns pixel syncs', function () { - const syncs = spec.getUserSyncs({ pixelEnabled: true, iframeEnabled: true }, [bidResponse]); - expect(syncs).to.deep.equal([ - { - type: 'image', - url: 'https://hoge.com' - } - ]) - }) - }); -}); diff --git a/test/spec/modules/gnetBidAdapter_spec.js b/test/spec/modules/gnetBidAdapter_spec.js deleted file mode 100644 index 40f8ad50d78..00000000000 --- a/test/spec/modules/gnetBidAdapter_spec.js +++ /dev/null @@ -1,145 +0,0 @@ -import { - expect -} from 'chai'; -import { - spec -} from 'modules/gnetBidAdapter.js'; -import { - newBidder -} from 'src/adapters/bidderFactory.js'; - -const ENDPOINT = 'https://adserver.gnetproject.com/prebid.php'; - -describe('gnetAdapter', 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 () { - let bid = { - bidder: 'gnet', - params: { - websiteId: '4', - externalId: '4d52cccf30309282256012cf30309282' - } - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const bidRequests = [{ - bidder: 'gnet', - params: { - websiteId: '4', - externalId: '4d52cccf30309282256012cf30309282' - }, - adUnitCode: '/150790500/4_ZONA_IAB_300x250_5', - sizes: [ - [300, 250], - ], - bidId: '2a19afd5173318', - bidderRequestId: '1f4001782ac16c', - auctionId: 'aba03555-4802-4c45-9f15-05ffa8594cff', - transactionId: '894bdff6-61ec-4bec-a5a9-f36a5bfccef5' - }]; - - const bidderRequest = { - refererInfo: { - referer: 'https://gnetproject.com/' - } - }; - - it('sends bid request to ENDPOINT via POST', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests[0].url).to.equal(ENDPOINT); - expect(requests[0].method).to.equal('POST'); - expect(requests[0].data).to.equal(JSON.stringify({ - 'referer': 'https://gnetproject.com/', - 'adUnitCode': '/150790500/4_ZONA_IAB_300x250_5', - 'bidId': '2a19afd5173318', - 'transactionId': '894bdff6-61ec-4bec-a5a9-f36a5bfccef5', - 'sizes': ['300x250'], - 'params': { - 'websiteId': '4', - 'externalId': '4d52cccf30309282256012cf30309282' - } - })); - }); - }); - - describe('interpretResponse', function () { - const bidderRequests = [{ - bidder: 'gnet', - params: { - clientId: '123456' - }, - adUnitCode: '/150790500/4_ZONA_IAB_300x250_5', - sizes: [ - [300, 250], - ], - bidId: '2a19afd5173318', - bidderRequestId: '1f4001782ac16c', - auctionId: 'aba03555-4802-4c45-9f15-05ffa8594cff', - transactionId: '894bdff6-61ec-4bec-a5a9-f36a5bfccef5' - }]; - - it('should get correct banner bid response', function () { - const response = { - bids: [ - { - bidId: '2a19afd5173318', - cpm: 0.1, - currency: 'BRL', - width: 300, - height: 250, - ad: '

I am an ad

', - creativeId: '173560700', - } - ] - }; - - const expectedResponse = [ - { - requestId: '2a19afd5173318', - cpm: 0.1, - currency: 'BRL', - width: 300, - height: 250, - ad: '

I am an ad

', - ttl: 300, - creativeId: '173560700', - netRevenue: true - } - ]; - - const result = spec.interpretResponse({ - body: response - }, bidderRequests); - expect(result).to.have.lengthOf(1); - expect(result).to.deep.have.same.members(expectedResponse); - }); - - it('handles nobid responses', function () { - const response = ''; - - const result = spec.interpretResponse({ - body: response - }, bidderRequests); - expect(result.length).to.equal(0); - }); - }); -}); diff --git a/test/spec/modules/googleAnalyticsAdapter_spec.js b/test/spec/modules/googleAnalyticsAdapter_spec.js deleted file mode 100644 index b801b5fe696..00000000000 --- a/test/spec/modules/googleAnalyticsAdapter_spec.js +++ /dev/null @@ -1,27 +0,0 @@ -import ga from 'modules/googleAnalyticsAdapter.js'; - -var assert = require('assert'); - -describe('Ga', function () { - describe('enableAnalytics', function () { - var cpmDistribution = function(cpm) { - return cpm <= 1 ? '<= 1$' : '> 1$'; - } - var config = { options: { trackerName: 'foo', enableDistribution: true, cpmDistribution: cpmDistribution } }; - - // enableAnalytics can only be called once - ga.enableAnalytics(config); - - it('should accept a tracker name option and output prefixed send string', function () { - var output = ga.getTrackerSend(); - assert.equal(output, 'foo.send'); - }); - - it('should use the custom cpm distribution', function() { - assert.equal(ga.getCpmDistribution(0.5), '<= 1$'); - assert.equal(ga.getCpmDistribution(1), '<= 1$'); - assert.equal(ga.getCpmDistribution(2), '> 1$'); - assert.equal(ga.getCpmDistribution(5.23), '> 1$'); - }); - }); -}); diff --git a/test/spec/modules/gothamadsBidAdapter_spec.js b/test/spec/modules/gothamadsBidAdapter_spec.js deleted file mode 100644 index f0a3ea253f3..00000000000 --- a/test/spec/modules/gothamadsBidAdapter_spec.js +++ /dev/null @@ -1,416 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/gothamadsBidAdapter.js'; -import { config } from 'src/config.js'; - -const NATIVE_BID_REQUEST = { - code: 'native_example', - mediaTypes: { - native: { - title: { - required: true, - len: 800 - }, - image: { - required: true, - len: 80 - }, - sponsoredBy: { - required: true - }, - clickUrl: { - required: true - }, - privacyLink: { - required: false - }, - body: { - required: true - }, - icon: { - required: true, - sizes: [50, 50] - } - } - }, - bidder: 'gothamads', - params: { - placementId: 'hash', - accountId: 'accountId' - }, - timeout: 1000 - -}; - -const BANNER_BID_REQUEST = { - code: 'banner_example', - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [300, 600] - ] - } - }, - bidder: 'gothamads', - params: { - placementId: 'hash', - accountId: 'accountId' - }, - timeout: 1000, - gdprConsent: { - consentString: 'BOEFEAyOEFEAyAHABDENAI4AAAB9vABAASA', - gdprApplies: 1, - }, - uspConsent: 'uspConsent' -} - -const bidRequest = { - refererInfo: { - referer: 'test.com' - } -} - -const VIDEO_BID_REQUEST = { - code: 'video1', - sizes: [640, 480], - mediaTypes: { - video: { - minduration: 0, - maxduration: 999, - boxingallowed: 1, - skip: 0, - mimes: [ - 'application/javascript', - 'video/mp4' - ], - w: 1920, - h: 1080, - protocols: [ - 2 - ], - linearity: 1, - api: [ - 1, - 2 - ] - } - }, - - bidder: 'gothamads', - params: { - placementId: 'hash', - accountId: 'accountId' - }, - timeout: 1000 - -} - -const BANNER_BID_RESPONSE = { - id: 'request_id', - bidid: 'request_imp_id', - seatbid: [{ - bid: [{ - id: 'bid_id', - impid: 'request_imp_id', - price: 5, - adomain: ['example.com'], - adm: 'admcode', - crid: 'crid', - ext: { - mediaType: 'banner' - } - }], - }], -}; - -const VIDEO_BID_RESPONSE = { - id: 'request_id', - bidid: 'request_imp_id', - seatbid: [{ - bid: [{ - id: 'bid_id', - impid: 'request_imp_id', - price: 5, - adomain: ['example.com'], - adm: 'admcode', - crid: 'crid', - ext: { - mediaType: 'video', - vastUrl: 'http://example.vast', - } - }], - }], -}; - -let imgData = { - url: `https://example.com/image`, - w: 1200, - h: 627 -}; - -const NATIVE_BID_RESPONSE = { - id: 'request_id', - bidid: 'request_imp_id', - seatbid: [{ - bid: [{ - id: 'bid_id', - impid: 'request_imp_id', - price: 5, - adomain: ['example.com'], - adm: { - native: { - assets: [{ - id: 0, - title: 'dummyText' - }, - { - id: 3, - image: imgData - }, - { - id: 5, - data: { - value: 'organization.name' - } - } - ], - link: { - url: 'example.com' - }, - imptrackers: ['tracker1.com', 'tracker2.com', 'tracker3.com'], - jstracker: 'tracker1.com' - } - }, - crid: 'crid', - ext: { - mediaType: 'native' - } - }], - }], -}; - -describe('GothamAdsAdapter', function () { - describe('with COPPA', function () { - beforeEach(function () { - sinon.stub(config, 'getConfig') - .withArgs('coppa') - .returns(true); - }); - afterEach(function () { - config.getConfig.restore(); - }); - - it('should send the Coppa "required" flag set to "1" in the request', function () { - let serverRequest = spec.buildRequests([BANNER_BID_REQUEST]); - expect(serverRequest.data[0].regs.coppa).to.equal(1); - }); - }); - describe('isBidRequestValid', function () { - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(NATIVE_BID_REQUEST)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, NATIVE_BID_REQUEST); - delete bid.params; - bid.params = { - 'IncorrectParam': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('build Native Request', function () { - const request = spec.buildRequests([NATIVE_BID_REQUEST], bidRequest); - - it('Creates a ServerRequest object with method, URL and data', function () { - expect(request).to.exist; - expect(request.method).to.exist; - expect(request.url).to.exist; - expect(request.data).to.exist; - }); - - it('sends bid request to our endpoint via POST', function () { - expect(request.method).to.equal('POST'); - }); - - it('Returns valid URL', function () { - expect(request.url).to.equal('https://us-e-node1.gothamads.com/bid?pass=accountId&integration=prebidjs'); - }); - - it('Returns empty data if no valid requests are passed', function () { - let serverRequest = spec.buildRequests([]); - expect(serverRequest).to.be.an('array').that.is.empty; - }); - }); - - describe('build Banner Request', function () { - const request = spec.buildRequests([BANNER_BID_REQUEST]); - - it('Creates a ServerRequest object with method, URL and data', function () { - expect(request).to.exist; - expect(request.method).to.exist; - expect(request.url).to.exist; - expect(request.data).to.exist; - }); - - it('check consent and ccpa string is set properly', function () { - expect(request.data[0].regs.ext.gdpr).to.equal(1); - expect(request.data[0].user.ext.consent).to.equal(BANNER_BID_REQUEST.gdprConsent.consentString); - expect(request.data[0].regs.ext.us_privacy).to.equal(BANNER_BID_REQUEST.uspConsent); - }); - - it('sends bid request to our endpoint via POST', function () { - expect(request.method).to.equal('POST'); - }); - - it('Returns valid URL', function () { - expect(request.url).to.equal('https://us-e-node1.gothamads.com/bid?pass=accountId&integration=prebidjs'); - }); - }); - - describe('build Video Request', function () { - const request = spec.buildRequests([VIDEO_BID_REQUEST]); - - it('Creates a ServerRequest object with method, URL and data', function () { - expect(request).to.exist; - expect(request.method).to.exist; - expect(request.url).to.exist; - expect(request.data).to.exist; - }); - - it('sends bid request to our endpoint via POST', function () { - expect(request.method).to.equal('POST'); - }); - - it('Returns valid URL', function () { - expect(request.url).to.equal('https://us-e-node1.gothamads.com/bid?pass=accountId&integration=prebidjs'); - }); - }); - - describe('interpretResponse', function () { - it('Empty response must return empty array', function () { - const emptyResponse = null; - let response = spec.interpretResponse(emptyResponse); - - expect(response).to.be.an('array').that.is.empty; - }) - - it('Should interpret banner response', function () { - const bannerResponse = { - body: [BANNER_BID_RESPONSE] - } - - const expectedBidResponse = { - requestId: BANNER_BID_RESPONSE.id, - cpm: BANNER_BID_RESPONSE.seatbid[0].bid[0].price, - width: BANNER_BID_RESPONSE.seatbid[0].bid[0].w, - height: BANNER_BID_RESPONSE.seatbid[0].bid[0].h, - ttl: BANNER_BID_RESPONSE.ttl || 1200, - currency: BANNER_BID_RESPONSE.cur || 'USD', - netRevenue: true, - creativeId: BANNER_BID_RESPONSE.seatbid[0].bid[0].crid, - dealId: BANNER_BID_RESPONSE.seatbid[0].bid[0].dealid, - mediaType: 'banner', - meta: BANNER_BID_RESPONSE.seatbid[0].bid[0].adomain, - ad: BANNER_BID_RESPONSE.seatbid[0].bid[0].adm - } - - let bannerResponses = spec.interpretResponse(bannerResponse); - - expect(bannerResponses).to.be.an('array').that.is.not.empty; - let 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(expectedBidResponse.requestId); - expect(dataItem.cpm).to.equal(expectedBidResponse.cpm); - expect(dataItem.ad).to.equal(expectedBidResponse.ad); - expect(dataItem.ttl).to.equal(expectedBidResponse.ttl); - expect(dataItem.creativeId).to.equal(expectedBidResponse.creativeId); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.meta).to.have.property('advertiserDomains', expectedBidResponse.meta); - expect(dataItem.currency).to.equal(expectedBidResponse.currency); - expect(dataItem.width).to.equal(expectedBidResponse.width); - expect(dataItem.height).to.equal(expectedBidResponse.height); - }); - - it('Should interpret video response', function () { - const videoResponse = { - body: [VIDEO_BID_RESPONSE] - } - - const expectedBidResponse = { - requestId: VIDEO_BID_RESPONSE.id, - cpm: VIDEO_BID_RESPONSE.seatbid[0].bid[0].price, - width: VIDEO_BID_RESPONSE.seatbid[0].bid[0].w, - height: VIDEO_BID_RESPONSE.seatbid[0].bid[0].h, - ttl: VIDEO_BID_RESPONSE.ttl || 1200, - currency: VIDEO_BID_RESPONSE.cur || 'USD', - netRevenue: true, - creativeId: VIDEO_BID_RESPONSE.seatbid[0].bid[0].crid, - dealId: VIDEO_BID_RESPONSE.seatbid[0].bid[0].dealid, - mediaType: 'video', - meta: VIDEO_BID_RESPONSE.seatbid[0].bid[0].adomain, - vastXml: VIDEO_BID_RESPONSE.seatbid[0].bid[0].adm, - vastUrl: VIDEO_BID_RESPONSE.seatbid[0].bid[0].ext.vastUrl - } - - let videoResponses = spec.interpretResponse(videoResponse); - - expect(videoResponses).to.be.an('array').that.is.not.empty; - let dataItem = videoResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'vastXml', 'vastUrl', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta'); - expect(dataItem.requestId).to.equal(expectedBidResponse.requestId); - expect(dataItem.cpm).to.equal(expectedBidResponse.cpm); - expect(dataItem.vastXml).to.equal(expectedBidResponse.vastXml); - expect(dataItem.ttl).to.equal(expectedBidResponse.ttl); - expect(dataItem.creativeId).to.equal(expectedBidResponse.creativeId); - expect(dataItem.meta).to.have.property('advertiserDomains', expectedBidResponse.meta); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal(expectedBidResponse.currency); - expect(dataItem.width).to.equal(expectedBidResponse.width); - expect(dataItem.height).to.equal(expectedBidResponse.height); - }); - - it('Should interpret native response', function () { - const nativeResponse = { - body: [NATIVE_BID_RESPONSE] - } - - const expectedBidResponse = { - requestId: NATIVE_BID_RESPONSE.id, - cpm: NATIVE_BID_RESPONSE.seatbid[0].bid[0].price, - width: NATIVE_BID_RESPONSE.seatbid[0].bid[0].w, - height: NATIVE_BID_RESPONSE.seatbid[0].bid[0].h, - ttl: NATIVE_BID_RESPONSE.ttl || 1200, - currency: NATIVE_BID_RESPONSE.cur || 'USD', - netRevenue: true, - creativeId: NATIVE_BID_RESPONSE.seatbid[0].bid[0].crid, - dealId: NATIVE_BID_RESPONSE.seatbid[0].bid[0].dealid, - meta: NATIVE_BID_RESPONSE.seatbid[0].bid[0].adomain, - mediaType: 'native', - native: { - clickUrl: NATIVE_BID_RESPONSE.seatbid[0].bid[0].adm.native.link.url - } - } - - let nativeResponses = spec.interpretResponse(nativeResponse); - - expect(nativeResponses).to.be.an('array').that.is.not.empty; - let dataItem = nativeResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'native', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta'); - expect(dataItem.requestId).to.equal(expectedBidResponse.requestId); - expect(dataItem.cpm).to.equal(expectedBidResponse.cpm); - expect(dataItem.native.clickUrl).to.equal(expectedBidResponse.native.clickUrl); - expect(dataItem.ttl).to.equal(expectedBidResponse.ttl); - expect(dataItem.meta).to.have.property('advertiserDomains', expectedBidResponse.meta); - expect(dataItem.creativeId).to.equal(expectedBidResponse.creativeId); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal(expectedBidResponse.currency); - expect(dataItem.width).to.equal(expectedBidResponse.width); - expect(dataItem.height).to.equal(expectedBidResponse.height); - }); - }); -}) diff --git a/test/spec/modules/gptPreAuction_spec.js b/test/spec/modules/gptPreAuction_spec.js deleted file mode 100644 index c4a81c21d5c..00000000000 --- a/test/spec/modules/gptPreAuction_spec.js +++ /dev/null @@ -1,191 +0,0 @@ -import { - appendGptSlots, - appendPbAdSlot, - _currentConfig, - makeBidRequestsHook -} from 'modules/gptPreAuction.js'; -import { config } from 'src/config.js'; -import { makeSlot } from '../integration/faker/googletag.js'; - -describe('GPT pre-auction module', () => { - let sandbox; - beforeEach(() => { - sandbox = sinon.sandbox.create(); - }); - afterEach(() => { - sandbox.restore(); - config.setConfig({ gptPreAuction: { enabled: false } }); - }); - - const testSlots = [ - makeSlot({ code: 'slotCode1', divId: 'div1' }), - makeSlot({ code: 'slotCode2', divId: 'div2' }), - makeSlot({ code: 'slotCode3', divId: 'div3' }) - ]; - - describe('appendPbAdSlot', () => { - // sets up our document body to test the pbAdSlot dom actions against - document.body.innerHTML = '
test1
' + - '
test2
' + - '
test2
'; - - it('should be unchanged if already defined on adUnit', () => { - const adUnit = { ortb2Imp: { ext: { data: { pbadslot: '12345' } } } }; - appendPbAdSlot(adUnit); - expect(adUnit.ortb2Imp.ext.data.pbadslot).to.equal('12345'); - }); - - it('should use adUnit.code if matching id exists', () => { - const adUnit = { code: 'foo1', ortb2Imp: { ext: { data: {} } } }; - appendPbAdSlot(adUnit); - expect(adUnit.ortb2Imp.ext.data.pbadslot).to.equal('bar1'); - }); - - it('should use the gptSlot.adUnitPath if the adUnit.code matches a div id but does not have a data-adslotid', () => { - const adUnit = { code: 'foo3', mediaTypes: { banner: { sizes: [[250, 250]] } }, ortb2Imp: { ext: { data: { adserver: { name: 'gam', adslot: '/baz' } } } } }; - appendPbAdSlot(adUnit); - expect(adUnit.ortb2Imp.ext.data.pbadslot).to.equal('/baz'); - }); - - it('should use the video adUnit.code (which *should* match the configured "adSlotName", but is not being tested) if there is no matching div with "data-adslotid" defined', () => { - const adUnit = { code: 'foo4', mediaTypes: { video: { sizes: [[250, 250]] } }, ortb2Imp: { ext: { data: {} } } }; - adUnit.code = 'foo5'; - appendPbAdSlot(adUnit, undefined); - expect(adUnit.ortb2Imp.ext.data.pbadslot).to.equal('foo5'); - }); - - it('should use the adUnit.code if all other sources failed', () => { - const adUnit = { code: 'foo4', ortb2Imp: { ext: { data: {} } } }; - appendPbAdSlot(adUnit, undefined); - expect(adUnit.ortb2Imp.ext.data.pbadslot).to.equal('foo4'); - }); - - it('should use the customPbAdSlot function if one is given', () => { - config.setConfig({ - gptPreAuction: { - customPbAdSlot: () => 'customPbAdSlotName' - } - }); - - const adUnit = { code: 'foo1', ortb2Imp: { ext: { data: {} } } }; - appendPbAdSlot(adUnit); - expect(adUnit.ortb2Imp.ext.data.pbadslot).to.equal('customPbAdSlotName'); - }); - }); - - describe('appendGptSlots', () => { - it('should not add adServer object to context if no slots defined', () => { - const adUnit = { code: 'adUnitCode', ortb2Imp: { ext: { data: {} } } }; - appendGptSlots([adUnit]); - expect(adUnit.ortb2Imp.ext.data.adserver).to.be.undefined; - }); - - it('should not add adServer object to context if no slot matches', () => { - window.googletag.pubads().setSlots(testSlots); - const adUnit = { code: 'adUnitCode', ortb2Imp: { ext: { data: {} } } }; - appendGptSlots([adUnit]); - expect(adUnit.ortb2Imp.ext.data.adserver).to.be.undefined; - }); - - it('should add adServer object to context if matching slot is found', () => { - window.googletag.pubads().setSlots(testSlots); - const adUnit = { code: 'slotCode2', ortb2Imp: { ext: { data: {} } } }; - appendGptSlots([adUnit]); - expect(adUnit.ortb2Imp.ext.data.adserver).to.be.an('object'); - expect(adUnit.ortb2Imp.ext.data.adserver).to.deep.equal({ name: 'gam', adslot: 'slotCode2' }); - }); - - it('should use the customGptSlotMatching function if one is given', () => { - config.setConfig({ - gptPreAuction: { - customGptSlotMatching: slot => - adUnitCode => adUnitCode.toUpperCase() === slot.getAdUnitPath().toUpperCase() - } - }); - - window.googletag.pubads().setSlots(testSlots); - const adUnit = { code: 'SlOtCoDe1', ortb2Imp: { ext: { data: {} } } }; - appendGptSlots([adUnit]); - expect(adUnit.ortb2Imp.ext.data.adserver).to.be.an('object'); - expect(adUnit.ortb2Imp.ext.data.adserver).to.deep.equal({ name: 'gam', adslot: 'slotCode1' }); - }); - }); - - describe('handleSetGptConfig', () => { - it('should enable the module by default', () => { - config.setConfig({ gptPreAuction: {} }); - expect(_currentConfig.enabled).to.equal(true); - }); - - it('should disable the module if told to in set config', () => { - config.setConfig({ gptPreAuction: { enabled: false } }); - expect(_currentConfig).to.be.an('object').that.is.empty; - }); - - it('should accept custom functions in config', () => { - config.setConfig({ - gptPreAuction: { - customGptSlotMatching: () => 'customGptSlot', - customPbAdSlot: () => 'customPbAdSlot' - } - }); - - expect(_currentConfig.enabled).to.equal(true); - expect(_currentConfig.customGptSlotMatching).to.a('function'); - expect(_currentConfig.customPbAdSlot).to.a('function'); - expect(_currentConfig.customGptSlotMatching()).to.equal('customGptSlot'); - expect(_currentConfig.customPbAdSlot()).to.equal('customPbAdSlot'); - }); - - it('should check that custom functions in config are type function', () => { - config.setConfig({ - gptPreAuction: { - customGptSlotMatching: 12345, - customPbAdSlot: 'test' - } - }); - expect(_currentConfig).to.deep.equal({ - enabled: true, - customGptSlotMatching: false, - customPbAdSlot: false - }); - }); - }); - - describe('makeBidRequestsHook', () => { - let returnedAdUnits; - const runMakeBidRequests = adUnits => { - const next = adUnits => { - returnedAdUnits = adUnits; - }; - makeBidRequestsHook(next, adUnits); - }; - - it('should append PB Ad Slot and GPT Slot info to first-party data in each ad unit', () => { - const testAdUnits = [{ - code: 'adUnit1', - ortb2Imp: { ext: { data: { pbadslot: '12345' } } } - }, { - code: 'slotCode1', - ortb2Imp: { ext: { data: { pbadslot: '67890' } } } - }, { - code: 'slotCode3', - }]; - - const expectedAdUnits = [{ - code: 'adUnit1', - ortb2Imp: { ext: { data: { pbadslot: '12345' } } } - }, { - code: 'slotCode1', - ortb2Imp: { ext: { data: { pbadslot: '67890', adserver: { name: 'gam', adslot: 'slotCode1' } } } } - }, { - code: 'slotCode3', - ortb2Imp: { ext: { data: { pbadslot: 'slotCode3', adserver: { name: 'gam', adslot: 'slotCode3' } } } } - }]; - - window.googletag.pubads().setSlots(testSlots); - runMakeBidRequests(testAdUnits); - expect(returnedAdUnits).to.deep.equal(expectedAdUnits); - }); - }); -}); diff --git a/test/spec/modules/gridBidAdapter_spec.js b/test/spec/modules/gridBidAdapter_spec.js deleted file mode 100644 index e161d82fdd6..00000000000 --- a/test/spec/modules/gridBidAdapter_spec.js +++ /dev/null @@ -1,1018 +0,0 @@ -import { expect } from 'chai'; -import { spec, resetUserSync, getSyncUrl } from 'modules/gridBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import { config } from 'src/config.js'; - -describe('TheMediaGrid Adapter', 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 () { - let bid = { - 'bidder': 'grid', - 'params': { - 'uid': '1' - }, - '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(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'uid': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - function parseRequest(data) { - return JSON.parse(data); - } - const bidderRequest = { - refererInfo: {referer: 'https://example.com'}, - bidderRequestId: '22edbae2733bf6', - auctionId: '9e2dfbfe-00c7-4f5e-9850-4044df3229c7', - timeout: 3000 - }; - const referrer = encodeURIComponent(bidderRequest.refererInfo.referer); - let bidRequests = [ - { - 'bidder': 'grid', - 'params': { - 'uid': '1', - 'bidFloor': 1.25 - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'bidId': '42dbe3a7168a6a', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '9e2dfbfe-00c7-4f5e-9850-4044df3229c7', - }, - { - 'bidder': 'grid', - 'params': { - 'uid': '2' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '9e2dfbfe-00c7-4f5e-9850-4044df3229c7', - }, - { - 'bidder': 'grid', - 'params': { - 'uid': '11' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'mediaTypes': { - 'video': { - 'playerSize': [[400, 600]], - 'mimes': ['video/mp4', 'video/webm', 'application/javascript', 'video/ogg'] - } - }, - 'bidId': '3150ccb55da321', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '9e2dfbfe-00c7-4f5e-9850-4044df3229c7', - }, - { - 'bidder': 'grid', - 'params': { - 'uid': '3' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'mediaTypes': { - 'video': { - 'playerSize': [[400, 600]], - 'protocols': [1, 2, 3] - }, - 'banner': { - 'sizes': [[728, 90]] - } - }, - 'bidId': '3150ccb55da321', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '9e2dfbfe-00c7-4f5e-9850-4044df3229c7', - } - ]; - - it('should attach valid params to the tag', function () { - const request = spec.buildRequests([bidRequests[0]], bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.deep.equal({ - 'id': bidderRequest.bidderRequestId, - 'site': { - 'page': referrer - }, - 'tmax': bidderRequest.timeout, - 'source': { - 'tid': bidderRequest.auctionId, - 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'} - }, - 'imp': [{ - 'id': bidRequests[0].bidId, - 'tagid': bidRequests[0].params.uid, - 'ext': {'divid': bidRequests[0].adUnitCode}, - 'bidfloor': bidRequests[0].params.bidFloor, - 'banner': { - 'w': 300, - 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] - } - }] - }); - }); - - it('make possible to process request without mediaTypes', function () { - const request = spec.buildRequests([bidRequests[0], bidRequests[1]], bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.deep.equal({ - 'id': bidderRequest.bidderRequestId, - 'site': { - 'page': referrer - }, - 'tmax': bidderRequest.timeout, - 'source': { - 'tid': bidderRequest.auctionId, - 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'} - }, - 'imp': [{ - 'id': bidRequests[0].bidId, - 'tagid': bidRequests[0].params.uid, - 'ext': {'divid': bidRequests[0].adUnitCode}, - 'bidfloor': bidRequests[0].params.bidFloor, - 'banner': { - 'w': 300, - 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] - } - }, { - 'id': bidRequests[1].bidId, - 'tagid': bidRequests[1].params.uid, - 'ext': {'divid': bidRequests[1].adUnitCode}, - 'banner': { - 'w': 300, - 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] - } - }] - }); - }); - - it('should attach valid params to the video tag', function () { - const request = spec.buildRequests(bidRequests.slice(0, 3), bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.deep.equal({ - 'id': bidderRequest.bidderRequestId, - 'site': { - 'page': referrer - }, - 'tmax': bidderRequest.timeout, - 'source': { - 'tid': bidderRequest.auctionId, - 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'} - }, - 'imp': [{ - 'id': bidRequests[0].bidId, - 'tagid': bidRequests[0].params.uid, - 'ext': {'divid': bidRequests[0].adUnitCode}, - 'bidfloor': bidRequests[0].params.bidFloor, - 'banner': { - 'w': 300, - 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] - } - }, { - 'id': bidRequests[1].bidId, - 'tagid': bidRequests[1].params.uid, - 'ext': {'divid': bidRequests[1].adUnitCode}, - 'banner': { - 'w': 300, - 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] - } - }, { - 'id': bidRequests[2].bidId, - 'tagid': bidRequests[2].params.uid, - 'ext': {'divid': bidRequests[2].adUnitCode}, - 'video': { - 'w': 400, - 'h': 600, - 'mimes': ['video/mp4', 'video/webm', 'application/javascript', 'video/ogg'] - } - }] - }); - }); - - it('should support mixed mediaTypes', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.deep.equal({ - 'id': bidderRequest.bidderRequestId, - 'site': { - 'page': referrer - }, - 'tmax': bidderRequest.timeout, - 'source': { - 'tid': bidderRequest.auctionId, - 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'} - }, - 'imp': [{ - 'id': bidRequests[0].bidId, - 'tagid': bidRequests[0].params.uid, - 'ext': {'divid': bidRequests[0].adUnitCode}, - 'bidfloor': bidRequests[0].params.bidFloor, - 'banner': { - 'w': 300, - 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] - } - }, { - 'id': bidRequests[1].bidId, - 'tagid': bidRequests[1].params.uid, - 'ext': {'divid': bidRequests[1].adUnitCode}, - 'banner': { - 'w': 300, - 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] - } - }, { - 'id': bidRequests[2].bidId, - 'tagid': bidRequests[2].params.uid, - 'ext': {'divid': bidRequests[2].adUnitCode}, - 'video': { - 'w': 400, - 'h': 600, - 'mimes': ['video/mp4', 'video/webm', 'application/javascript', 'video/ogg'], - } - }, { - 'id': bidRequests[3].bidId, - 'tagid': bidRequests[3].params.uid, - 'ext': {'divid': bidRequests[3].adUnitCode}, - 'banner': { - 'w': 728, - 'h': 90, - 'format': [{'w': 728, 'h': 90}] - }, - 'video': { - 'w': 400, - 'h': 600, - 'protocols': [1, 2, 3] - } - }] - }); - }); - - it('if gdprConsent is present payload must have gdpr params', function () { - 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); - expect(payload).to.have.property('user'); - expect(payload.user).to.have.property('ext'); - expect(payload.user.ext).to.have.property('consent', 'AAA'); - expect(payload).to.have.property('regs'); - expect(payload.regs).to.have.property('ext'); - expect(payload.regs.ext).to.have.property('gdpr', 1); - }); - - it('if usPrivacy is present payload must have us_privacy param', function () { - 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); - expect(payload).to.have.property('regs'); - expect(payload.regs).to.have.property('ext'); - expect(payload.regs.ext).to.have.property('us_privacy', '1YNN'); - }); - - it('if userId is present payload must have user.ext param with right keys', function () { - const eids = [ - { - source: 'pubcid.org', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - { - source: 'adserver.org', - uids: [{ - id: 'some-random-id-value', - atype: 1, - ext: { - rtiPartner: 'TDID' - } - }] - } - ]; - const bidRequestsWithUserIds = bidRequests.map((bid) => { - return Object.assign({ - userIdAsEids: eids - }, bid); - }); - const request = spec.buildRequests(bidRequestsWithUserIds, bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('user'); - expect(payload.user).to.have.property('ext'); - expect(payload.user.ext.eids).to.deep.equal(eids); - }); - - it('if schain is present payload must have source.ext.schain param', function () { - const schain = { - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - hp: 1 - } - ] - }; - const bidRequestsWithSChain = bidRequests.map((bid) => { - return Object.assign({ - schain: schain - }, bid); - }); - const request = spec.buildRequests(bidRequestsWithSChain, bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('source'); - expect(payload.source).to.have.property('ext'); - expect(payload.source.ext).to.have.property('schain'); - expect(payload.source.ext.schain).to.deep.equal(schain); - }); - - it('if content and segment is present in jwTargeting, payload must have right params', function () { - const jsContent = {id: 'test_jw_content_id'}; - const jsSegments = ['test_seg_1', 'test_seg_2']; - const bidRequestsWithJwTargeting = bidRequests.map((bid) => { - return Object.assign({ - rtd: { - jwplayer: { - targeting: { - segments: jsSegments, - content: jsContent - } - } - } - }, bid); - }); - const request = spec.buildRequests(bidRequestsWithJwTargeting, bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('user'); - expect(payload.user.data).to.deep.equal([{ - name: 'iow_labs_pub_data', - segment: [ - {name: 'jwpseg', value: jsSegments[0]}, - {name: 'jwpseg', value: jsSegments[1]} - ] - }]); - expect(payload).to.have.property('site'); - expect(payload.site.content).to.deep.equal(jsContent); - }); - - it('should contain the keyword values if it present in ortb2.(site/user)', function () { - const getConfigStub = sinon.stub(config, 'getConfig').callsFake( - arg => arg === 'ortb2.user' ? {'keywords': 'foo'} : (arg === 'ortb2.site' ? {'keywords': 'bar'} : null)); - const request = spec.buildRequests([bidRequests[0]], bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload.ext.keywords).to.deep.equal([{'key': 'user', 'value': ['foo']}, {'key': 'context', 'value': ['bar']}]); - getConfigStub.restore(); - }); - - it('shold be right tmax when timeout in config is less then timeout in bidderRequest', function() { - const getConfigStub = sinon.stub(config, 'getConfig').callsFake( - arg => arg === 'bidderTimeout' ? 2000 : null); - const request = spec.buildRequests([bidRequests[0]], bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload.tmax).to.equal(2000); - getConfigStub.restore(); - }); - it('shold be right tmax when timeout in bidderRequest is less then timeout in config', function() { - const getConfigStub = sinon.stub(config, 'getConfig').callsFake( - arg => arg === 'bidderTimeout' ? 5000 : null); - const request = spec.buildRequests([bidRequests[0]], bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload.tmax).to.equal(3000); - getConfigStub.restore(); - }); - it('should contain regs.coppa if coppa is true in config', function () { - const getConfigStub = sinon.stub(config, 'getConfig').callsFake( - arg => arg === 'coppa' ? true : null); - const request = spec.buildRequests([bidRequests[0]], bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('regs'); - expect(payload.regs).to.have.property('coppa', 1); - getConfigStub.restore(); - }); - it('should contain imp[].ext.data.adserver if available', function() { - const ortb2Imp = [{ - ext: { - data: { - adserver: { - name: 'ad_server_name', - adslot: '/111111/slot' - }, - pbadslot: '/111111/slot' - } - } - }, { - ext: { - data: { - adserver: { - name: 'ad_server_name', - adslot: '/222222/slot' - }, - pbadslot: '/222222/slot' - } - } - }]; - const bidRequestsWithOrtb2Imp = bidRequests.slice(0, 3).map((bid, ind) => { - return Object.assign(ortb2Imp[ind] ? { ortb2Imp: ortb2Imp[ind] } : {}, bid); - }); - const request = spec.buildRequests(bidRequestsWithOrtb2Imp, bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload.imp[0].ext).to.deep.equal({ - divid: bidRequests[0].adUnitCode, - data: ortb2Imp[0].ext.data, - gpid: ortb2Imp[0].ext.data.adserver.adslot - }); - expect(payload.imp[1].ext).to.deep.equal({ - divid: bidRequests[1].adUnitCode, - data: ortb2Imp[1].ext.data, - gpid: ortb2Imp[1].ext.data.adserver.adslot - }); - expect(payload.imp[2].ext).to.deep.equal({ - divid: bidRequests[2].adUnitCode - }); - }); - describe('floorModule', function () { - const floorTestData = { - 'currency': 'USD', - 'floor': 1.50 - }; - const bidRequest = Object.assign({ - getFloor: (_) => { - return floorTestData; - } - }, bidRequests[1]); - it('should return the value from getFloor if present', function () { - const request = spec.buildRequests([bidRequest], bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload.imp[0].bidfloor).to.equal(floorTestData.floor); - }); - 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); - const request = spec.buildRequests([bidRequestsWithFloor], bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload.imp[0].bidfloor).to.equal(floorTestData.floor); - }); - 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); - const request = spec.buildRequests([bidRequestsWithFloor], bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload.imp[0].bidfloor).to.equal(bidfloor); - }); - }); - }); - - describe('interpretResponse', function () { - const responses = [ - {'bid': [{'impid': '659423fff799cb', 'price': 1.15, 'adm': '
test content 1
', 'auid': 1, 'h': 250, 'w': 300, 'dealid': 11}], 'seat': '1'}, - {'bid': [{'impid': '4dff80cc4ee346', 'price': 0.5, 'adm': '
test content 2
', 'auid': 2, 'h': 600, 'w': 300}], 'seat': '1'}, - {'bid': [{'impid': '5703af74d0472a', 'price': 0.15, 'adm': '
test content 3
', 'auid': 1, 'h': 90, 'w': 728}], 'seat': '1'}, - {'bid': [{'impid': '2344da98f78b42', 'price': 0, 'auid': 3, 'h': 250, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0, 'adm': '
test content 5
', 'h': 250, 'w': 300}], 'seat': '1'}, - undefined, - {'bid': [], 'seat': '1'}, - {'seat': '1'}, - ]; - - it('should get correct bid response', function () { - const bidRequests = [ - { - 'bidder': 'grid', - 'params': { - 'uid': '1' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '659423fff799cb', - 'bidderRequestId': '5f2009617a7c0a', - 'auctionId': '1cbd2feafe5e8b', - } - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '659423fff799cb', - 'cpm': 1.15, - 'creativeId': 1, - 'dealId': 11, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': false, - 'ttl': 360, - 'meta': { - advertiserDomains: [] - }, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': [responses[0]]}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('should get correct multi bid response', function () { - const bidRequests = [ - { - 'bidder': 'grid', - 'params': { - 'uid': '1' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '659423fff799cb', - 'bidderRequestId': '2c2bb1972df9a', - 'auctionId': '1fa09aee5c8c99', - }, - { - 'bidder': 'grid', - 'params': { - 'uid': '2' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '4dff80cc4ee346', - 'bidderRequestId': '2c2bb1972df9a', - 'auctionId': '1fa09aee5c8c99', - }, - { - 'bidder': 'grid', - 'params': { - 'uid': '1' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '5703af74d0472a', - 'bidderRequestId': '2c2bb1972df9a', - 'auctionId': '1fa09aee5c8c99', - } - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '659423fff799cb', - 'cpm': 1.15, - 'creativeId': 1, - 'dealId': 11, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': false, - 'ttl': 360, - 'meta': { - advertiserDomains: [] - }, - }, - { - 'requestId': '4dff80cc4ee346', - 'cpm': 0.5, - 'creativeId': 2, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'ad': '
test content 2
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': false, - 'ttl': 360, - 'meta': { - advertiserDomains: [] - }, - }, - { - 'requestId': '5703af74d0472a', - 'cpm': 0.15, - 'creativeId': 1, - 'dealId': undefined, - 'width': 728, - 'height': 90, - 'ad': '
test content 3
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': false, - 'ttl': 360, - 'meta': { - advertiserDomains: [] - }, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': responses.slice(0, 3)}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('should get correct video bid response', function () { - const bidRequests = [ - { - 'bidder': 'grid', - 'params': { - 'uid': '11' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '659423fff799cb', - 'bidderRequestId': '5f2009617a7c0a', - 'auctionId': '1cbd2feafe5e8b', - 'mediaTypes': { - 'video': { - 'context': 'instream' - } - } - }, - { - 'bidder': 'grid', - 'params': { - 'uid': '12' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '2bc598e42b6a', - 'bidderRequestId': '5f2009617a7c0a', - 'auctionId': '1cbd2feafe5e8b', - 'mediaTypes': { - 'video': { - 'context': 'instream' - } - } - } - ]; - const response = [ - {'bid': [{'impid': '659423fff799cb', 'price': 1.15, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 11, content_type: 'video', w: 300, h: 600}], 'seat': '2'}, - {'bid': [{'impid': '2bc598e42b6a', 'price': 1.00, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 12, content_type: 'video'}], 'seat': '2'} - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '659423fff799cb', - 'cpm': 1.15, - 'creativeId': 11, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'currency': 'USD', - 'mediaType': 'video', - 'netRevenue': false, - 'ttl': 360, - 'meta': { - advertiserDomains: [] - }, - 'vastXml': '\n<\/Ad>\n<\/VAST>', - 'adResponse': { - 'content': '\n<\/Ad>\n<\/VAST>' - } - }, - { - 'requestId': '2bc598e42b6a', - 'cpm': 1.00, - 'creativeId': 12, - 'dealId': undefined, - 'width': undefined, - 'height': undefined, - 'currency': 'USD', - 'mediaType': 'video', - 'netRevenue': false, - 'ttl': 360, - 'meta': { - advertiserDomains: [] - }, - 'vastXml': '\n<\/Ad>\n<\/VAST>', - 'adResponse': { - 'content': '\n<\/Ad>\n<\/VAST>' - } - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': response}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('handles wrong and nobid responses', function () { - const bidRequests = [ - { - 'bidder': 'grid', - 'params': { - 'uid': '3' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '300bfeb0d7190gf', - 'bidderRequestId': '2c2bb1972d23af', - 'auctionId': '1fa09aee5c84d34', - }, - { - 'bidder': 'grid', - 'params': { - 'uid': '4' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '300bfeb0d71321', - 'bidderRequestId': '2c2bb1972d23af', - 'auctionId': '1fa09aee5c84d34', - }, - { - 'bidder': 'grid', - 'params': { - 'uid': '5' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '300bfeb0d7183bb', - 'bidderRequestId': '2c2bb1972d23af', - 'auctionId': '1fa09aee5c84d34', - } - ]; - const request = spec.buildRequests(bidRequests); - 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', 'price': 1.15, 'adm': '
test content 1
', 'auid': 1, 'h': 250, 'w': 300, dealid: 11}], 'seat': '1'}, - {'bid': [{'impid': '4e111f1b66e4', 'price': 0.5, 'adm': '
test content 2
', 'auid': 2, 'h': 600, 'w': 300, dealid: 12}], 'seat': '1'}, - {'bid': [{'impid': '26d6f897b516', 'price': 0.15, 'adm': '
test content 3
', 'auid': 1, 'h': 90, 'w': 728}], 'seat': '1'}, - {'bid': [{'impid': '326bde7fbf69', 'price': 0.15, 'adm': '
test content 4
', 'auid': 1, 'h': 600, 'w': 300}], 'seat': '1'}, - {'bid': [{'impid': '2234f233b22a', 'price': 0.5, 'adm': '
test content 5
', 'auid': 2, 'h': 600, 'w': 350}], 'seat': '1'}, - ]; - const bidRequests = [ - { - 'bidder': 'grid', - 'params': { - 'uid': '1' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '2164be6358b9', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'grid', - 'params': { - 'uid': '1' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '326bde7fbf69', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'grid', - 'params': { - 'uid': '2' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '4e111f1b66e4', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'grid', - 'params': { - 'uid': '1' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '26d6f897b516', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'grid', - 'params': { - 'uid': '2' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '1751cd90161', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - } - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '2164be6358b9', - 'cpm': 1.15, - 'creativeId': 1, - 'dealId': 11, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': false, - 'ttl': 360, - 'meta': { - advertiserDomains: [] - }, - }, - { - 'requestId': '4e111f1b66e4', - 'cpm': 0.5, - 'creativeId': 2, - 'dealId': 12, - 'width': 300, - 'height': 600, - 'ad': '
test content 2
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': false, - 'ttl': 360, - 'meta': { - advertiserDomains: [] - }, - }, - { - 'requestId': '26d6f897b516', - 'cpm': 0.15, - 'creativeId': 1, - 'dealId': undefined, - 'width': 728, - 'height': 90, - 'ad': '
test content 3
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': false, - 'ttl': 360, - 'meta': { - advertiserDomains: [] - }, - }, - { - 'requestId': '326bde7fbf69', - 'cpm': 0.15, - 'creativeId': 1, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'ad': '
test content 4
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': false, - 'ttl': 360, - 'meta': { - advertiserDomains: [] - }, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': fullResponse}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - }); - - describe('user sync', function () { - const syncUrl = getSyncUrl(); - - beforeEach(function () { - resetUserSync(); - }); - - it('should register the Emily iframe', function () { - let syncs = spec.getUserSyncs({ - pixelEnabled: true - }); - - 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}); - - // when called again, should still have only been called once - syncs = spec.getUserSyncs(); - expect(syncs).to.equal(undefined); - }); - - it('should pass gdpr params if consent is true', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - gdprApplies: true, consentString: 'foo' - })).to.deep.equal({ - type: 'image', url: `${syncUrl}&gdpr=1&gdpr_consent=foo` - }); - }); - - it('should pass gdpr params if consent is false', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - gdprApplies: false, consentString: 'foo' - })).to.deep.equal({ - type: 'image', url: `${syncUrl}&gdpr=0&gdpr_consent=foo` - }); - }); - - it('should pass gdpr param gdpr_consent only when gdprApplies is undefined', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - consentString: 'foo' - })).to.deep.equal({ - type: 'image', url: `${syncUrl}&gdpr_consent=foo` - }); - }); - - it('should pass no params if gdpr consentString is not defined', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {})).to.deep.equal({ - type: 'image', url: syncUrl - }); - }); - - it('should pass no params if gdpr consentString is a number', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - consentString: 0 - })).to.deep.equal({ - type: 'image', url: syncUrl - }); - }); - - it('should pass no params if gdpr consentString is null', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - consentString: null - })).to.deep.equal({ - type: 'image', url: syncUrl - }); - }); - - it('should pass no params if gdpr consentString is a object', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - consentString: {} - })).to.deep.equal({ - type: 'image', url: syncUrl - }); - }); - - it('should pass no params if gdpr is not defined', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, undefined)).to.deep.equal({ - type: 'image', url: syncUrl - }); - }); - - it('should pass usPrivacy param if it is available', function() { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {}, '1YNN')).to.deep.equal({ - type: 'image', url: `${syncUrl}&us_privacy=1YNN` - }); - }); - }); -}); diff --git a/test/spec/modules/gridNMBidAdapter_spec.js b/test/spec/modules/gridNMBidAdapter_spec.js deleted file mode 100644 index 2aec9713000..00000000000 --- a/test/spec/modules/gridNMBidAdapter_spec.js +++ /dev/null @@ -1,459 +0,0 @@ -import { expect } from 'chai'; -import { spec, resetUserSync, getSyncUrl } from 'modules/gridNMBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('TheMediaGridNM Adapter', 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 () { - let bid = { - 'bidder': 'gridNM', - 'params': { - 'source': 'jwp', - 'secid': '11', - 'pubid': '22', - 'video': { - 'mimes': ['video/mp4', 'video/x-ms-wmv'], - 'protocols': [1, 2, 3, 4, 5, 6] - } - }, - '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(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - const paramsList = [ - { - 'source': 'jwp', - 'secid': '11', - 'pubid': '22', - 'video': { - 'protocols': [1, 2, 3, 4, 5, 6] - } - }, - { - 'source': 'jwp', - 'secid': '11', - 'pubid': '22', - 'video': { - 'mimes': ['video/mp4', 'video/x-ms-wmv'], - } - }, - { - 'secid': '11', - 'pubid': '22', - 'video': { - 'mimes': ['video/mp4', 'video/x-ms-wmv'], - 'protocols': [1, 2, 3, 4, 5, 6] - } - }, - { - 'source': 'jwp', - 'pubid': '22', - 'video': { - 'mimes': ['video/mp4', 'video/x-ms-wmv'], - 'protocols': [1, 2, 3, 4, 5, 6] - } - }, - { - 'source': 'jwp', - 'secid': '11', - 'video': { - 'mimes': ['video/mp4', 'video/x-ms-wmv'], - 'protocols': [1, 2, 3, 4, 5, 6] - } - } - ]; - paramsList.forEach((params) => { - const invalidBid = Object.assign({}, bid); - delete invalidBid.params; - invalidBid.params = params; - expect(spec.isBidRequestValid(invalidBid)).to.equal(false); - }); - }); - - it('should return false when required params has invalid values', function () { - const paramsList = [ - { - 'source': 'jwp', - 'secid': '11', - 'pubid': '22', - 'video': { - 'mimes': ['video/mp4', 'video/x-ms-wmv'], - 'protocols': '1,2,3,4,5' - } - }, - { - 'source': 'jwp', - 'secid': '11', - 'pubid': '22', - 'video': { - 'mimes': [1, 2], - 'protocols': [1, 2, 3, 4, 5] - } - }, - { - 'source': 'jwp', - 'secid': 11, - 'pubid': '22', - 'video': { - 'mimes': ['video/mp4', 'video/x-ms-wmv'], - 'protocols': [1, 2, 3, 4, 5] - } - }, - { - 'source': 111, - 'secid': '11', - 'pubid': '22', - 'video': { - 'mimes': ['video/mp4', 'video/x-ms-wmv'], - 'protocols': [1, 2, 3, 4, 5] - } - } - ]; - - paramsList.forEach((params) => { - const invalidBid = Object.assign({}, bid); - delete invalidBid.params; - invalidBid.params = params; - expect(spec.isBidRequestValid(invalidBid)).to.equal(false); - }); - }); - }); - - describe('buildRequests', function () { - function parseRequestUrl(url) { - const res = {}; - url.replace(/^[^\?]+\?/, '').split('&').forEach((it) => { - const couple = it.split('='); - res[couple[0]] = decodeURIComponent(couple[1]); - }); - return res; - } - const bidderRequest = {refererInfo: {referer: 'https://example.com'}}; - const referrer = bidderRequest.refererInfo.referer; - let bidRequests = [ - { - 'bidder': 'gridNM', - 'params': { - 'source': 'jwp', - 'secid': '11', - 'pubid': '22', - 'video': { - 'mimes': ['video/mp4', 'video/x-ms-wmv'], - 'protocols': [1, 2, 3, 4, 5, 6] - } - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }, - { - 'bidder': 'gridNM', - 'params': { - 'source': 'jwp', - 'secid': '11', - 'pubid': '22', - 'video': { - 'mimes': ['video/mp4'], - 'protocols': [1, 2, 3], - 'skip': 1 - } - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '3150ccb55da321', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - it('should attach valid params to the tag', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - const requestsSizes = ['300x250,300x600', '728x90']; - requests.forEach((req, i) => { - expect(req.url).to.be.an('string'); - const payload = parseRequestUrl(req.url); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('r', '22edbae2733bf6'); - expect(payload).to.have.property('wrapperType', 'Prebid_js'); - expect(payload).to.have.property('wrapperVersion', '$prebid.version$'); - expect(payload).to.have.property('sizes', requestsSizes[i]); - expect(req.data).to.deep.equal(bidRequests[i].params); - }); - }); - - it('if gdprConsent is present payload must have gdpr params', function () { - const [request] = spec.buildRequests([bidRequests[0]], {gdprConsent: {consentString: 'AAA', gdprApplies: true}, refererInfo: bidderRequest.refererInfo}); - expect(request.url).to.be.an('string'); - const payload = parseRequestUrl(request.url); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('gdpr_consent', 'AAA'); - expect(payload).to.have.property('gdpr_applies', '1'); - }); - - it('if gdprApplies is false gdpr_applies must be 0', function () { - const [request] = spec.buildRequests([bidRequests[0]], {gdprConsent: {consentString: 'AAA', gdprApplies: false}}); - expect(request.url).to.be.an('string'); - const payload = parseRequestUrl(request.url); - expect(payload).to.have.property('gdpr_consent', 'AAA'); - expect(payload).to.have.property('gdpr_applies', '0'); - }); - - it('if gdprApplies is undefined gdpr_applies must be 1', function () { - const [request] = spec.buildRequests([bidRequests[0]], {gdprConsent: {consentString: 'AAA'}}); - expect(request.url).to.be.an('string'); - const payload = parseRequestUrl(request.url); - expect(payload).to.have.property('gdpr_consent', 'AAA'); - expect(payload).to.have.property('gdpr_applies', '1'); - }); - - it('if usPrivacy is present payload must have us_privacy param', function () { - const bidderRequestWithUSP = Object.assign({uspConsent: '1YNN'}, bidderRequest); - const [request] = spec.buildRequests([bidRequests[0]], bidderRequestWithUSP); - expect(request.url).to.be.an('string'); - const payload = parseRequestUrl(request.url); - expect(payload).to.have.property('us_privacy', '1YNN'); - }); - }); - - describe('interpretResponse', function () { - const responses = [ - {'bid': [{'price': 1.15, 'adm': '\n<\/Ad>\n<\/VAST>', 'content_type': 'video', 'h': 250, 'w': 300, 'dealid': 11}], 'seat': '2'}, - {'bid': [{'price': 0.5, 'adm': '\n<\/Ad>\n<\/VAST>', 'content_type': 'video', 'h': 600, 'w': 300}], 'seat': '2'}, - {'bid': [{'price': 0, 'h': 250, 'w': 300}], 'seat': '2'}, - {'bid': [{'price': 0, 'adm': '\n<\/Ad>\n<\/VAST>', 'h': 250, 'w': 300}], 'seat': '2'}, - undefined, - {'bid': [], 'seat': '2'}, - {'seat': '2'}, - ]; - - it('should get correct video bid response', function () { - const bidRequests = [ - { - 'bidder': 'gridNM', - 'params': { - 'source': 'jwp', - 'secid': '11', - 'pubid': '22', - 'video': { - 'mimes': ['video/mp4', 'video/x-ms-wmv'], - 'protocols': [1, 2, 3, 4, 5, 6] - } - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '659423fff799cb', - 'bidderRequestId': '5f2009617a7c0a', - 'auctionId': '1cbd2feafe5e8b', - 'mediaTypes': { - 'video': { - 'context': 'instream' - } - } - }, - { - 'bidder': 'gridNM', - 'params': { - 'source': 'jwp', - 'secid': '11', - 'pubid': '22', - 'video': { - 'mimes': ['video/mp4'], - 'protocols': [1, 2, 3, 4, 5], - 'skip': 1 - } - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '2bc598e42b6a', - 'bidderRequestId': '1e8b5a465f404', - 'auctionId': '1cbd2feafe5e8b', - 'mediaTypes': { - 'video': { - 'context': 'instream' - } - } - } - ]; - const requests = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '659423fff799cb', - 'cpm': 1.15, - 'creativeId': '5f2009617a7c0a', - 'dealId': 11, - 'width': 300, - 'height': 250, - 'currency': 'USD', - 'mediaType': 'video', - 'netRevenue': false, - 'ttl': 360, - 'vastXml': '\n<\/Ad>\n<\/VAST>', - 'adResponse': { - 'content': '\n<\/Ad>\n<\/VAST>' - } - }, - { - 'requestId': '2bc598e42b6a', - 'cpm': 0.5, - 'creativeId': '1e8b5a465f404', - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'currency': 'USD', - 'mediaType': 'video', - 'netRevenue': false, - 'ttl': 360, - 'vastXml': '\n<\/Ad>\n<\/VAST>', - 'adResponse': { - 'content': '\n<\/Ad>\n<\/VAST>' - } - } - ]; - - requests.forEach((req, i) => { - const result = spec.interpretResponse({'body': {'seatbid': [responses[i]]}}, req); - expect(result[0]).to.deep.equal(expectedResponse[i]); - }); - }); - - it('handles wrong and nobid responses', function () { - responses.slice(2).forEach((resp) => { - const request = spec.buildRequests([{ - 'bidder': 'gridNM', - 'params': { - 'source': 'jwp', - 'secid': '11', - 'pubid': '22', - 'video': { - 'mimes': ['video/mp4'], - 'protocols': [1, 2, 3, 4, 5], - 'skip': 1 - } - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '2bc598e42b6a', - 'bidderRequestId': '39d74f5b71464', - 'auctionId': '1cbd2feafe5e8b', - 'mediaTypes': { - 'video': { - 'context': 'instream' - } - } - }]); - const result = spec.interpretResponse({'body': {'seatbid': [resp]}}, request[0]); - expect(result.length).to.equal(0); - }); - }); - }); - - describe('user sync', function () { - const syncUrl = getSyncUrl(); - - beforeEach(function () { - resetUserSync(); - }); - - it('should register the Emily iframe', function () { - let syncs = spec.getUserSyncs({ - pixelEnabled: true - }); - - 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}); - - // when called again, should still have only been called once - syncs = spec.getUserSyncs(); - expect(syncs).to.equal(undefined); - }); - - it('should pass gdpr params if consent is true', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - gdprApplies: true, consentString: 'foo' - })).to.deep.equal({ - type: 'image', url: `${syncUrl}&gdpr=1&gdpr_consent=foo` - }); - }); - - it('should pass gdpr params if consent is false', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - gdprApplies: false, consentString: 'foo' - })).to.deep.equal({ - type: 'image', url: `${syncUrl}&gdpr=0&gdpr_consent=foo` - }); - }); - - it('should pass gdpr param gdpr_consent only when gdprApplies is undefined', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - consentString: 'foo' - })).to.deep.equal({ - type: 'image', url: `${syncUrl}&gdpr_consent=foo` - }); - }); - - it('should pass no params if gdpr consentString is not defined', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {})).to.deep.equal({ - type: 'image', url: syncUrl - }); - }); - - it('should pass no params if gdpr consentString is a number', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - consentString: 0 - })).to.deep.equal({ - type: 'image', url: syncUrl - }); - }); - - it('should pass no params if gdpr consentString is null', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - consentString: null - })).to.deep.equal({ - type: 'image', url: syncUrl - }); - }); - - it('should pass no params if gdpr consentString is a object', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { - consentString: {} - })).to.deep.equal({ - type: 'image', url: syncUrl - }); - }); - - it('should pass no params if gdpr is not defined', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, undefined)).to.deep.equal({ - type: 'image', url: syncUrl - }); - }); - - it('should pass usPrivacy param if it is available', function() { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {}, '1YNN')).to.deep.equal({ - type: 'image', url: `${syncUrl}&us_privacy=1YNN` - }); - }); - }); -}); diff --git a/test/spec/modules/gumgumBidAdapter_spec.js b/test/spec/modules/gumgumBidAdapter_spec.js deleted file mode 100644 index a7b18a16173..00000000000 --- a/test/spec/modules/gumgumBidAdapter_spec.js +++ /dev/null @@ -1,666 +0,0 @@ -import { BANNER, VIDEO } from 'src/mediaTypes.js'; - -import { expect } from 'chai'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import { spec } from 'modules/gumgumBidAdapter.js'; - -const ENDPOINT = 'https://g2.gumgum.com/hbid/imp'; -const JCSI = { t: 0, rq: 8, pbv: '$prebid.version$' } - -describe('gumgumAdapter', 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 () { - let bid = { - 'bidder': 'gumgum', - 'params': { - 'inScreen': '10433394', - 'bidfloor': 0.05 - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - sizes: [[300, 250], [300, 600], [1, 1]] - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - - it('should return true when required params found', function () { - const zoneBid = { ...bid, params: { 'zone': '123' } }; - const pubIdBid = { ...bid, params: { 'pubId': 123 } }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - expect(spec.isBidRequestValid(zoneBid)).to.equal(true); - expect(spec.isBidRequestValid(pubIdBid)).to.equal(true); - }); - - it('should return true when required params found', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'inSlot': '789' - }; - - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return true when inslot sends sizes and trackingid', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'inSlot': '789', - 'sizes': [[0, 1], [2, 3], [4, 5], [6, 7]] - }; - - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when no unit type is specified', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'placementId': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when bidfloor is not a number', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'inSlot': '789', - 'bidfloor': '0.50' - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false if invalid request id is found', function () { - const bidRequest = { - id: 12345, - sizes: [[300, 250], [1, 1]], - url: ENDPOINT, - method: 'GET', - pi: 3, - data: { t: '10433394' } - }; - let body; - spec.interpretResponse({ body }, bidRequest); // empty response - expect(spec.isBidRequestValid(bid)).to.be.equal(false); - }); - }); - - describe('buildRequests', function () { - let sizesArray = [[300, 250], [300, 600]]; - let bidRequests = [ - { - 'bidder': 'gumgum', - 'params': { - 'inSlot': '9' - }, - 'adUnitCode': 'adunit-code', - 'sizes': sizesArray, - 'bidId': '30b31c1838de1e', - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'exchange1.com', - 'sid': '1234', - 'hp': 1, - 'rid': 'bid-request-1', - 'name': 'publisher', - 'domain': 'publisher.com' - }, - { - 'asi': 'exchange2.com', - 'sid': 'abcd', - 'hp': 1, - 'rid': 'bid-request-2', - 'name': 'intermediary', - 'domain': 'intermediary.com' - } - ] - } - } - ]; - const vidMediaTypes = { - video: { - playerSize: [640, 480], - context: 'instream', - minduration: 1, - maxduration: 2, - linearity: 1, - startdelay: 1, - placement: 123456, - protocols: [1, 2] - } - }; - const zoneParam = { 'zone': '123a' }; - const pubIdParam = { 'pubId': 123 }; - - it('should set pubId param if found', function () { - const request = { ...bidRequests[0], params: pubIdParam }; - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.pubId).to.equal(pubIdParam.pubId); - }); - - it('should set t param when zone param is found', function () { - const request = { ...bidRequests[0], params: zoneParam }; - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.t).to.equal(zoneParam.zone); - }); - - it('should set the iriscat param when found', function () { - const request = { ...bidRequests[0], params: { iriscat: 'abc123' } } - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data).to.have.property('iriscat'); - }); - - it('should not set the iriscat param when not found', function () { - const request = { ...bidRequests[0] } - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data).to.not.have.property('iriscat'); - }); - - it('should set the irisid param when found', function () { - const request = { ...bidRequests[0], params: { irisid: 'abc123' } } - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data).to.have.property('irisid'); - }); - - it('should not set the irisid param when not found', function () { - const request = { ...bidRequests[0] } - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data).to.not.have.property('irisid'); - }); - - it('should not set the irisid param when not of type string', function () { - const request = { ...bidRequests[0], params: { irisid: 123456 } } - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data).to.not.have.property('irisid'); - }); - - describe('product id', function () { - it('should set the correct pi param if native param is found', function () { - const request = { ...bidRequests[0], params: { ...zoneParam, native: 2 } }; - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.pi).to.equal(5); - }); - it('should set the correct pi param for video', function () { - const request = { ...bidRequests[0], params: zoneParam, mediaTypes: vidMediaTypes }; - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.pi).to.equal(7); - }); - it('should set the correct pi param for invideo', function () { - const invideo = { video: { ...vidMediaTypes.video, linearity: 2 } }; - const request = { ...bidRequests[0], params: zoneParam, mediaTypes: invideo }; - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.pi).to.equal(6); - }); - it('should set the correct pi param if slot param is found', function () { - const request = { ...bidRequests[0], params: { ...zoneParam, slot: '123s' } }; - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.pi).to.equal(3); - }); - it('should default the pi param to 2 if only zone or pubId param is found', function () { - const zoneRequest = { ...bidRequests[0], params: zoneParam }; - const pubIdRequest = { ...bidRequests[0], params: pubIdParam }; - const zoneBidRequest = spec.buildRequests([zoneRequest])[0]; - const pubIdBidRequest = spec.buildRequests([pubIdRequest])[0]; - expect(zoneBidRequest.data.pi).to.equal(2); - expect(pubIdBidRequest.data.pi).to.equal(2); - }); - }); - - it('should return a defined sizes field for video', function () { - const request = { ...bidRequests[0], mediaTypes: vidMediaTypes, params: { 'videoPubID': 123 } }; - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.sizes).to.equal(vidMediaTypes.video.playerSize); - }); - it('should handle multiple sizes for inslot', function () { - const mediaTypes = { banner: { sizes: [[300, 250], [300, 600]] } } - const request = { ...bidRequests[0], mediaTypes }; - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.bf).to.equal('300x250,300x600'); - }); - describe('floorModule', function () { - const floorTestData = { - 'currency': 'USD', - 'floor': 1.50 - }; - bidRequests[0].getFloor = _ => { - return floorTestData; - }; - it('should return the value from getFloor if present', function () { - const request = spec.buildRequests(bidRequests)[0]; - expect(request.data.fp).to.equal(floorTestData.floor); - }); - it('should return the getFloor.floor value if it is greater than bidfloor', function () { - const bidfloor = 0.80; - const request = { ...bidRequests[0] }; - request.params.bidfloor = bidfloor; - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.fp).to.equal(floorTestData.floor); - }); - it('should return the bidfloor value if it is greater than getFloor.floor', function () { - const bidfloor = 1.80; - const request = { ...bidRequests[0] }; - request.params.bidfloor = bidfloor; - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.fp).to.equal(bidfloor); - }); - it('should return a floor currency', function () { - const request = spec.buildRequests(bidRequests)[0]; - expect(request.data.fpc).to.equal(floorTestData.currency); - }) - }); - - it('sends bid request to ENDPOINT via GET', function () { - const request = spec.buildRequests(bidRequests)[0]; - expect(request.url).to.equal(ENDPOINT); - expect(request.method).to.equal('GET'); - expect(request.id).to.equal('30b31c1838de1e'); - }); - it('should set t and fp parameters in bid request if inScreen request param is found', function () { - const request = Object.assign({}, bidRequests[0]); - delete request.params; - request.params = { - 'inScreen': '10433394', - 'bidfloor': 0.05 - }; - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.pi).to.equal(2); - expect(bidRequest.data).to.include.any.keys('t'); - expect(bidRequest.data).to.include.any.keys('fp'); - }); - it('should set iriscat parameter if iriscat param is found and is of type string', function () { - const iriscat = 'segment'; - const request = { ...bidRequests[0] }; - request.params = { ...request.params, iriscat }; - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.iriscat).to.equal(iriscat); - }); - it('should not send iriscat parameter if iriscat param is not found', function () { - const request = { ...bidRequests[0] }; - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.iriscat).to.be.undefined; - }); - it('should not send iriscat parameter if iriscat param is not of type string', function () { - const iriscat = 123; - const request = { ...bidRequests[0] }; - request.params = { ...request.params, iriscat }; - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.iriscat).to.be.undefined; - }); - it('should send pubId if inScreenPubID param is specified', function () { - const request = Object.assign({}, bidRequests[0]); - delete request.params; - request.params = { - 'inScreenPubID': 123 - }; - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data).to.include.any.keys('pubId'); - expect(bidRequest.data.pubId).to.equal(request.params.inScreenPubID); - expect(bidRequest.data).to.not.include.any.keys('t'); - }); - it('should send pubId if videoPubID param is specified', function () { - const request = { ...bidRequests[0], mediaTypes: vidMediaTypes, params: { 'videoPubID': 123 } }; - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data).to.include.any.keys('pubId'); - expect(bidRequest.data.pubId).to.equal(request.params.videoPubID); - expect(bidRequest.data).to.not.include.any.keys('t'); - }); - it('should set a ni parameter in bid request if ICV request param is found', function () { - const request = Object.assign({}, bidRequests[0]); - delete request.params; - request.params = { - 'ICV': '10433395' - }; - const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.pi).to.equal(5); - expect(bidRequest.data).to.include.any.keys('ni'); - }); - it('should add parameters associated with video if video request param is found', function () { - const videoVals = { - playerSize: [640, 480], - context: 'instream', - minduration: 1, - maxduration: 2, - linearity: 1, - startdelay: 1, - placement: 123456, - protocols: [1, 2] - }; - const request = Object.assign({}, bidRequests[0]); - delete request.params; - request.mediaTypes = { - video: videoVals - }; - request.params = { - 'video': '10433395' - }; - const bidRequest = spec.buildRequests([request])[0]; - // 7 is video product line - expect(bidRequest.data.pi).to.eq(7); - expect(bidRequest.data.mind).to.eq(videoVals.minduration); - expect(bidRequest.data.maxd).to.eq(videoVals.maxduration); - expect(bidRequest.data.li).to.eq(videoVals.linearity); - expect(bidRequest.data.sd).to.eq(videoVals.startdelay); - expect(bidRequest.data.pt).to.eq(videoVals.placement); - expect(bidRequest.data.pr).to.eq(videoVals.protocols.join(',')); - expect(bidRequest.data.viw).to.eq(videoVals.playerSize[0].toString()); - expect(bidRequest.data.vih).to.eq(videoVals.playerSize[1].toString()); - }); - it('should add parameters associated with invideo if invideo request param is found', function () { - const inVideoVals = { - playerSize: [640, 480], - context: 'instream', - minduration: 1, - maxduration: 2, - linearity: 1, - startdelay: 1, - placement: 123456, - protocols: [1, 2] - }; - const request = Object.assign({}, bidRequests[0]); - delete request.params; - request.mediaTypes = { - video: inVideoVals - }; - request.params = { - 'inVideo': '10433395' - }; - const bidRequest = spec.buildRequests([request])[0]; - // 6 is invideo product line - expect(bidRequest.data.pi).to.eq(6); - expect(bidRequest.data.mind).to.eq(inVideoVals.minduration); - expect(bidRequest.data.maxd).to.eq(inVideoVals.maxduration); - expect(bidRequest.data.li).to.eq(inVideoVals.linearity); - expect(bidRequest.data.sd).to.eq(inVideoVals.startdelay); - expect(bidRequest.data.pt).to.eq(inVideoVals.placement); - expect(bidRequest.data.pr).to.eq(inVideoVals.protocols.join(',')); - expect(bidRequest.data.viw).to.eq(inVideoVals.playerSize[0].toString()); - expect(bidRequest.data.vih).to.eq(inVideoVals.playerSize[1].toString()); - }); - it('should not add additional parameters depending on params field', function () { - const request = spec.buildRequests(bidRequests)[0]; - expect(request.data).to.not.include.any.keys('ni'); - expect(request.data).to.not.include.any.keys('t'); - expect(request.data).to.not.include.any.keys('eAdBuyId'); - expect(request.data).to.not.include.any.keys('adBuyId'); - }); - it('should add gdpr consent parameters if gdprConsent is present', function () { - const gdprConsent = { consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', gdprApplies: true }; - const fakeBidRequest = { gdprConsent: gdprConsent }; - const bidRequest = spec.buildRequests(bidRequests, fakeBidRequest)[0]; - expect(bidRequest.data.gdprApplies).to.eq(1); - expect(bidRequest.data.gdprConsent).to.eq('BOJ/P2HOJ/P2HABABMAAAAAZ+A=='); - }); - it('should handle gdprConsent is present but values are undefined case', function () { - const gdprConsent = { consent_string: undefined, gdprApplies: undefined }; - const fakeBidRequest = { gdprConsent: gdprConsent }; - const bidRequest = spec.buildRequests(bidRequests, fakeBidRequest)[0]; - expect(bidRequest.data).to.not.include.any.keys('gdprConsent') - }); - it('should add uspConsent parameter if it is present in the bidderRequest', function () { - const noUspBidRequest = spec.buildRequests(bidRequests)[0]; - const uspConsentObj = { uspConsent: '1YYY' }; - const bidRequest = spec.buildRequests(bidRequests, uspConsentObj)[0]; - expect(noUspBidRequest.data).to.not.include.any.keys('uspConsent'); - expect(bidRequest.data).to.include.any.keys('uspConsent'); - 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 bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.tdid).to.eq(unifiedId.userId.tdid); - }); - it('should not add a tdid parameter if unified id is not found', function () { - const request = spec.buildRequests(bidRequests)[0]; - expect(request.data).to.not.include.any.keys('tdid'); - }); - it('should send schain parameter in serialized form', function () { - const serializedForm = '1.0,1!exchange1.com,1234,1,bid-request-1,publisher,publisher.com!exchange2.com,abcd,1,bid-request-2,intermediary,intermediary.com' - const request = spec.buildRequests(bidRequests)[0]; - expect(request.data).to.include.any.keys('schain'); - expect(request.data.schain).to.eq(serializedForm); - }); - it('should send ns parameter if browser contains navigator.connection property', function () { - const bidRequest = spec.buildRequests(bidRequests)[0]; - const connection = window.navigator && window.navigator.connection; - if (connection) { - const downlink = connection.downlink || connection.bandwidth; - expect(bidRequest.data).to.include.any.keys('ns'); - expect(bidRequest.data.ns).to.eq(Math.round(downlink * 1024)); - } else { - expect(bidRequest.data).to.not.include.any.keys('ns'); - } - }); - it('adds jcsi param with correct keys', function () { - const expectedKeys = Object.keys(JCSI).sort(); - const jcsi = JSON.stringify(JCSI); - const bidRequest = spec.buildRequests(bidRequests)[0]; - const actualKeys = Object.keys(JSON.parse(bidRequest.data.jcsi)).sort(); - expect(actualKeys).to.eq(actualKeys); - expect(bidRequest.data.jcsi).to.eq(jcsi); - }); - }) - - describe('interpretResponse', function () { - const metaData = { adomain: ['advertiser.com'], mediaType: BANNER } - const serverResponse = { - ad: { - id: 29593, - width: 300, - height: 250, - ipd: 2000, - markup: '

I am an ad

', - ii: true, - du: null, - price: 0, - zi: 0, - impurl: 'http://g2.gumgum.com/ad/view', - clsurl: 'http://g2.gumgum.com/ad/close' - }, - pag: { - t: 'ggumtest', - pvid: 'aa8bbb65-427f-4689-8cee-e3eed0b89eec', - css: 'html { overflow-y: auto }', - js: 'console.log("environment", env);' - }, - jcsi: { t: 0, rq: 8 }, - thms: 10000, - meta: metaData - } - const bidRequest = { - id: 12345, - sizes: [[300, 250], [1, 1]], - url: ENDPOINT, - method: 'GET', - pi: 3 - } - const expectedMetaData = { advertiserDomains: ['advertiser.com'], mediaType: BANNER }; - const expectedResponse = { - ad: '

I am an ad

', - cpm: 0, - creativeId: 29593, - currency: 'USD', - height: '250', - netRevenue: true, - requestId: 12345, - width: '300', - mediaType: BANNER, - ttl: 60, - meta: expectedMetaData - }; - - it('should get correct bid response', function () { - expect(spec.interpretResponse({ body: serverResponse }, bidRequest)).to.deep.equal([expectedResponse]); - }); - - it('should set a default value for advertiserDomains if adomain is not found', function () { - const meta = { ...metaData }; - delete meta.adomain; - - const response = { ...serverResponse, meta }; - const expectedMeta = { ...expectedMetaData, advertiserDomains: [] }; - const expected = { ...expectedResponse, meta: expectedMeta }; - - expect(spec.interpretResponse({ body: response }, bidRequest)).to.deep.equal([expected]); - }); - - it('should set a default value for meta.mediaType if mediaType is not found in the response', function () { - const meta = { ...metaData }; - delete meta.mediaType; - const response = { ...serverResponse, meta }; - const expected = { ...expectedResponse }; - - expect(spec.interpretResponse({ body: response }, bidRequest)).to.deep.equal([expected]); - }); - - it('should pass correct currency if found in bid response', function () { - const cur = 'EURO'; - const response = { ...serverResponse }; - response.ad.cur = cur; - - const expected = { ...expectedResponse }; - expected.currency = cur; - - expect(spec.interpretResponse({ body: response }, bidRequest)).to.deep.equal([expected]); - }); - - it('handles nobid responses', function () { - let response = { - 'ad': {}, - 'pag': { - 't': 'ggumtest', - 'pvid': 'aa8bbb65-427f-4689-8cee-e3eed0b89eec', - 'css': 'html { overflow-y: auto }', - 'js': 'console.log("environment", env);' - }, - 'thms': 10000 - } - let result = spec.interpretResponse({ body: response }, bidRequest); - expect(result.length).to.equal(0); - }); - - it('handles empty response', function () { - let body; - let result = spec.interpretResponse({ body }, bidRequest); - expect(result.length).to.equal(0); - }); - - it('uses response width and height', function () { - const result = spec.interpretResponse({ body: serverResponse }, bidRequest)[0]; - expect(result.width).to.equal(serverResponse.ad.width.toString()); - expect(result.height).to.equal(serverResponse.ad.height.toString()); - }); - - it('defaults to use bidRequest sizes when width and height are not found', function () { - const { ad, jcsi, pag, thms, meta } = serverResponse - const noAdSizes = { ...ad } - delete noAdSizes.width - delete noAdSizes.height - const responseWithoutSizes = { jcsi, pag, thms, meta, ad: noAdSizes } - const request = { ...bidRequest, sizes: [[100, 200]] } - const result = spec.interpretResponse({ body: responseWithoutSizes }, request)[0]; - - expect(result.width).to.equal(request.sizes[0][0].toString()) - expect(result.height).to.equal(request.sizes[0][1].toString()) - }); - - it('returns 1x1 when eligible product and size available', function () { - let inscreenBidRequest = { - id: 12346, - sizes: [[300, 250], [1, 1]], - url: ENDPOINT, - method: 'GET', - data: { - pi: 2, - t: 'ggumtest' - } - } - let inscreenServerResponse = { - 'ad': { - 'id': 2065333, - 'height': 90, - 'ipd': 2000, - 'markup': '

I am an inscreen ad

', - 'ii': true, - 'du': null, - 'price': 1, - 'zi': 0, - 'impurl': 'http://g2.gumgum.com/ad/view', - 'clsurl': 'http://g2.gumgum.com/ad/close' - }, - 'pag': { - 't': 'ggumtest', - 'pvid': 'aa8bbb65-427f-4689-8cee-e3eed0b89eec', - 'css': 'html { overflow-y: auto }', - 'js': 'console.log("environment", env);' - }, - 'thms': 10000 - } - let result = spec.interpretResponse({ body: inscreenServerResponse }, inscreenBidRequest); - expect(result[0].width).to.equal('1'); - expect(result[0].height).to.equal('1'); - }); - - it('updates jcsi object when the server response jcsi prop is found', function () { - const response = Object.assign({ cw: 'AD_JSON' }, serverResponse); - const bidResponse = spec.interpretResponse({ body: response }, bidRequest)[0].ad; - const decodedResponse = JSON.parse(atob(bidResponse)); - expect(decodedResponse.jcsi).to.eql(JCSI); - }); - - it('sets the correct mediaType depending on product', function () { - const bannerBidResponse = spec.interpretResponse({ body: serverResponse }, bidRequest)[0]; - const invideoBidResponse = spec.interpretResponse({ body: serverResponse }, { ...bidRequest, data: { pi: 6 } })[0]; - const videoBidResponse = spec.interpretResponse({ body: serverResponse }, { ...bidRequest, data: { pi: 7 } })[0]; - expect(bannerBidResponse.mediaType).to.equal(BANNER); - expect(invideoBidResponse.mediaType).to.equal(VIDEO); - expect(videoBidResponse.mediaType).to.equal(VIDEO); - }); - - it('sets a vastXml property if mediaType is video', function () { - const videoBidResponse = spec.interpretResponse({ body: serverResponse }, { ...bidRequest, data: { pi: 7 } })[0]; - expect(videoBidResponse.vastXml).to.exist; - }); - }) - describe('getUserSyncs', function () { - const syncOptions = { - 'iframeEnabled': 'true' - } - const response = { - 'pxs': { - 'scr': [ - { - 't': 'i', - 'u': 'https://c.gumgum.com/images/pixel.gif' - }, - { - 't': 'f', - 'u': 'https://www.nytimes.com/' - } - ] - } - } - let result = spec.getUserSyncs(syncOptions, [{ body: response }]); - expect(result[0].type).to.equal('image') - expect(result[1].type).to.equal('iframe') - }) -}); diff --git a/test/spec/modules/h12mediaBidAdapter_spec.js b/test/spec/modules/h12mediaBidAdapter_spec.js deleted file mode 100644 index 9861069f260..00000000000 --- a/test/spec/modules/h12mediaBidAdapter_spec.js +++ /dev/null @@ -1,437 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/h12mediaBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; -import * as utils from 'src/utils'; - -describe('H12 Media Adapter', function () { - const DEFAULT_CURRENCY = 'USD'; - const DEFAULT_TTL = 360; - const DEFAULT_NET_REVENUE = false; - const adapter = newBidder('spec'); - - const validBid = { - adUnitCode: 'div-gpt-ad-1460505748561-0', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - } - }, - bidder: 'h12media', - bidId: '1c5e8a1a84522d', - bidderRequestId: '1d0c4017f02458', - auctionId: '9adc85ed-43ee-4a78-816b-52b7e578f313', - params: { - pubid: 123321, - pubsubid: 'pubsubtestid', - }, - }; - - const validBid2 = { - adUnitCode: 'div-gpt-ad-1460505748561-1', - mediaTypes: { - banner: {} - }, - bidder: 'h12media', - bidId: '2c5e8a1a84522d', - bidderRequestId: '2d0c4017f02458', - auctionId: '9adc85ed-43ee-4a78-816b-52b7e578f314', - params: { - pubid: 123321, - size: '100x200' - }, - }; - - const invalidBid = { - adUnitCode: 'div-gpt-ad-1460505748561-2', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - } - }, - bidder: 'h12media', - bidId: '3c5e8a1a84522d', - bidderRequestId: '3d0c4017f02458', - auctionId: '9adc85ed-43ee-4a78-816b-52b7e578f315', - }; - - const bidderRequest = { - refererInfo: { - referer: 'https://localhost' - }, - gdprConsent: { - gdprApplies: 1, - consentString: 'concentDataString', - vendorData: { - vendorConsents: { - '90': 1 - }, - }, - }, - uspConsent: 'consentUspString' - }; - - const serverResponse = { - currency: 'EUR', - netRevenue: true, - ttl: 500, - bid: { - bidId: validBid.bidId, - cpm: 0.33, - width: 300, - height: 600, - creativeId: '335566', - ad: '
my ad
', - meta: { - advertiserId: '54321', - advertiserName: 'My advertiser', - advertiserDomains: ['test.com'] - } - }, - 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'} - ], - }; - - const serverResponse2 = { - bid: { - bidId: validBid2.bidId, - cpm: 0.33, - width: 300, - height: 600, - creativeId: '335566', - ad: '
my ad 2
', - } - }; - - function removeElement(id) { - if (document.getElementById(id)) { - document.body.removeChild(document.getElementById(id)); - } - } - - function createElement(id) { - const div = document.createElement('div'); - div.id = id; - div.style.width = '50px'; - div.style.height = '50px'; - if (frameElement) { - frameElement.style.width = '100px'; - frameElement.style.height = '100px'; - } - div.style.background = 'black'; - document.body.appendChild(div); - return div; - } - function createElementVisible(id) { - const element = createElement(id); - sandbox.stub(element, 'getBoundingClientRect').returns({ - x: 10, - y: 10, - }); - return element; - } - function createElementInvisible(id) { - const element = document.createElement('div'); - element.id = id; - document.body.appendChild(element); - element.style.display = 'none'; - return element; - } - - function createElementHidden(id) { - const element = createElement(id); - document.body.appendChild(element); - element.style.visibility = 'hidden'; - sandbox.stub(element, 'getBoundingClientRect').returns({ - x: 100, - y: 100, - }); - return element; - } - - let sandbox; - - beforeEach(function () { - sandbox = sinon.sandbox.create(); - sandbox.stub(frameElement, 'getBoundingClientRect').returns({ - left: 10, - top: 10, - }); - }); - - afterEach(function () { - removeElement(validBid.adUnitCode); - removeElement(validBid2.adUnitCode); - removeElement(invalidBid.adUnitCode); - sandbox.restore(); - }); - - after(function() { - sandbox.reset(); - }) - - describe('inherited functions', function () { - it('exists and is a function', function () { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - it('should return true when bid is valid', function () { - expect(spec.isBidRequestValid(validBid)).to.equal(true); - }); - - it('should return false when bid does not have pubid parameter', function () { - expect(spec.isBidRequestValid(invalidBid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - it('should return adUnit size', function () { - createElementVisible(validBid.adUnitCode); - createElementVisible(validBid2.adUnitCode); - const requests = spec.buildRequests([validBid, validBid2], bidderRequest); - const requestsData = requests[0].data.bidrequest; - - expect(requestsData).to.include({adunitSize: validBid.mediaTypes.banner.sizes}); - }); - - it('should return empty bid size', function () { - createElementVisible(validBid.adUnitCode); - createElementVisible(validBid2.adUnitCode); - const requests = spec.buildRequests([validBid, validBid2], bidderRequest); - const requestsData2 = requests[1].data.bidrequest; - - expect(requestsData2).to.deep.include({adunitSize: []}); - }); - - it('should return pubsubid from params', function () { - createElementVisible(validBid.adUnitCode); - createElementVisible(validBid2.adUnitCode); - const requests = spec.buildRequests([validBid, validBid2], bidderRequest); - const requestsData = requests[0].data.bidrequest; - const requestsData2 = requests[1].data.bidrequest; - - 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}; - 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: ''}); - }); - - it('should return bid size from params', function () { - createElementVisible(validBid.adUnitCode); - createElementVisible(validBid2.adUnitCode); - const requests = spec.buildRequests([validBid, validBid2], bidderRequest); - 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}); - }); - - it('should return GDPR info', function () { - createElementVisible(validBid.adUnitCode); - createElementVisible(validBid2.adUnitCode); - const requests = spec.buildRequests([validBid, validBid2], bidderRequest); - 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}); - }); - - it('should not have error on empty GDPR', function () { - createElementVisible(validBid.adUnitCode); - createElementVisible(validBid2.adUnitCode); - 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}); - }); - - it('should not have error on empty USP', function () { - createElementVisible(validBid.adUnitCode); - createElementVisible(validBid2.adUnitCode); - 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}); - }); - - it('should create single POST', function () { - createElementVisible(validBid.adUnitCode); - createElementVisible(validBid2.adUnitCode); - const requests = spec.buildRequests([validBid, validBid2], bidderRequest); - - expect(requests[0].method).to.equal('POST'); - expect(requests[1].method).to.equal('POST'); - }); - }); - - describe('creative viewability', function () { - it('should return coords', function () { - createElementVisible(validBid.adUnitCode); - const requests = spec.buildRequests([validBid], bidderRequest); - const requestsData = requests[0].data.bidrequest; - - expect(requestsData).to.deep.include({coords: {x: 10, y: 10}}); - }); - - it('should define iframe', function () { - createElementVisible(validBid.adUnitCode); - createElementVisible(validBid2.adUnitCode); - const requests = spec.buildRequests([validBid, validBid2], bidderRequest); - const requestsData = requests[0].data; - const requestsData2 = requests[1].data; - - expect(requestsData).to.include({isiframe: true}); - expect(requestsData2).to.include({isiframe: true}); - }); - - it('should define visible element', function () { - createElementVisible(validBid.adUnitCode); - const requests = spec.buildRequests([validBid], bidderRequest); - const requestsData = requests[0].data.bidrequest; - - expect(requestsData).to.include({ishidden: false}); - }); - - it('should define invisible element', function () { - createElementInvisible(validBid.adUnitCode); - const requests = spec.buildRequests([validBid], bidderRequest); - const requestsData = requests[0].data.bidrequest; - - expect(requestsData).to.include({ishidden: true}); - }); - - it('should define hidden element', function () { - createElementHidden(validBid.adUnitCode); - const requests = spec.buildRequests([validBid], bidderRequest); - const requestsData = requests[0].data.bidrequest; - - expect(requestsData).to.include({ishidden: true}); - }); - }); - - describe('interpretResponse', function () { - it('should return no bids if the response is not valid', function () { - const bidResponse = spec.interpretResponse({ body: null }, validBid); - - expect(bidResponse.length).to.equal(0); - }); - - it('should return no bids if the response is empty', function () { - const bidResponse = spec.interpretResponse({ body: [] }, { validBid }); - - expect(bidResponse).to.be.empty; - }); - - it('should return valid bid responses', function () { - createElementVisible(validBid.adUnitCode); - createElementVisible(validBid2.adUnitCode); - const request = spec.buildRequests([validBid, validBid2], bidderRequest); - const bidResponse = spec.interpretResponse({body: serverResponse}, request[0]); - - expect(bidResponse[0]).to.deep.include({ - requestId: validBid.bidId, - ad: serverResponse.bid.ad, - mediaType: 'banner', - creativeId: serverResponse.bid.creativeId, - cpm: serverResponse.bid.cpm, - width: serverResponse.bid.width, - height: serverResponse.bid.height, - currency: 'EUR', - netRevenue: true, - ttl: 500, - meta: serverResponse.bid.meta, - pubid: validBid.params.pubid - }); - }); - - it('should return default bid params', function () { - createElementVisible(validBid.adUnitCode); - createElementVisible(validBid2.adUnitCode); - const request = spec.buildRequests([validBid, validBid2], bidderRequest); - const bidResponse = spec.interpretResponse({body: serverResponse2}, request[0]); - - expect(bidResponse[0]).to.deep.include({ - requestId: validBid2.bidId, - ad: serverResponse2.bid.ad, - mediaType: 'banner', - creativeId: serverResponse2.bid.creativeId, - cpm: serverResponse2.bid.cpm, - width: serverResponse2.bid.width, - height: serverResponse2.bid.height, - meta: serverResponse2.bid.meta, - pubid: validBid2.params.pubid, - currency: DEFAULT_CURRENCY, - netRevenue: DEFAULT_NET_REVENUE, - ttl: DEFAULT_TTL, - }); - }); - }); - - describe('getUserSyncs', function () { - let syncOptions - beforeEach(function () { - syncOptions = { - enabledBidders: ['h12media'], - pixelEnabled: true, - iframeEnabled: true - } - }); - - it('should success with usersync pixel url', function () { - const result = { - 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); - - expect(syncs).to.deep.include(result); - }); - - it('should success with usersync iframe url', function () { - const result = { - 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); - - expect(syncs).to.deep.include(result); - }); - - it('should success without GDRP', function () { - const result = { - type: 'iframe', - 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); - }); - - it('should success without usersync url', function () { - 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([]); - }); - }); -}); diff --git a/test/spec/modules/haloIdSystem_spec.js b/test/spec/modules/haloIdSystem_spec.js deleted file mode 100644 index 8b6a67adee1..00000000000 --- a/test/spec/modules/haloIdSystem_spec.js +++ /dev/null @@ -1,42 +0,0 @@ -import { haloIdSubmodule, storage } from 'modules/haloIdSystem.js'; -import { server } from 'test/mocks/xhr.js'; -import * as utils from 'src/utils.js'; - -describe('HaloIdSystem', function () { - describe('getId', function() { - let getDataFromLocalStorageStub; - - beforeEach(function() { - getDataFromLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage'); - }); - - afterEach(function () { - getDataFromLocalStorageStub.restore(); - }); - - it('gets a haloId', function() { - const config = { - params: {} - }; - const callbackSpy = sinon.spy(); - const callback = haloIdSubmodule.getId(config).callback; - callback(callbackSpy); - const request = server.requests[0]; - expect(request.url).to.eq(`https://id.halo.ad.gt/api/v1/pbhid`); - request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify({ haloId: 'testHaloId1' })); - expect(callbackSpy.lastCall.lastArg).to.deep.equal({haloId: 'testHaloId1'}); - }); - - it('gets a cached haloid', function() { - const config = { - params: {} - }; - getDataFromLocalStorageStub.withArgs('auHaloId').returns('tstCachedHaloId1'); - - const callbackSpy = sinon.spy(); - const callback = haloIdSubmodule.getId(config).callback; - callback(callbackSpy); - expect(callbackSpy.lastCall.lastArg).to.deep.equal({haloId: 'tstCachedHaloId1'}); - }); - }); -}); diff --git a/test/spec/modules/haloRtdProvider_spec.js b/test/spec/modules/haloRtdProvider_spec.js deleted file mode 100644 index 3052441a00d..00000000000 --- a/test/spec/modules/haloRtdProvider_spec.js +++ /dev/null @@ -1,374 +0,0 @@ -import {config} from 'src/config.js'; -import {HALOID_LOCAL_NAME, RTD_LOCAL_NAME, addRealTimeData, getRealTimeData, haloSubmodule, storage} from 'modules/haloRtdProvider.js'; -import {server} from 'test/mocks/xhr.js'; - -const responseHeader = {'Content-Type': 'application/json'}; - -describe('haloRtdProvider', function() { - let getDataFromLocalStorageStub; - - beforeEach(function() { - config.resetConfig(); - getDataFromLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage'); - }); - - afterEach(function () { - getDataFromLocalStorageStub.restore(); - }); - - describe('haloSubmodule', function() { - it('successfully instantiates', function () { - expect(haloSubmodule.init()).to.equal(true); - }); - }); - - describe('Add Real-Time Data', function() { - it('merges ortb2 data', function() { - let rtdConfig = {}; - let bidConfig = {}; - - const setConfigUserObj1 = { - name: 'www.dataprovider1.com', - ext: { taxonomyname: 'iab_audience_taxonomy' }, - segment: [{ - id: '1776' - }] - }; - - const setConfigUserObj2 = { - name: 'www.dataprovider2.com', - ext: { taxonomyname: 'iab_audience_taxonomy' }, - segment: [{ - id: '1914' - }] - }; - - const setConfigSiteObj1 = { - name: 'www.dataprovider3.com', - ext: { - taxonomyname: 'iab_audience_taxonomy' - }, - segment: [ - { - id: '1812' - }, - { - id: '1955' - } - ] - } - - config.setConfig({ - ortb2: { - user: { - data: [setConfigUserObj1, setConfigUserObj2] - }, - site: { - content: { - data: [setConfigSiteObj1] - } - } - } - }); - - const rtdUserObj1 = { - name: 'www.dataprovider4.com', - ext: { - taxonomyname: 'iab_audience_taxonomy' - }, - segment: [ - { - id: '1918' - }, - { - id: '1939' - } - ] - }; - - const rtdSiteObj1 = { - name: 'www.dataprovider5.com', - ext: { - taxonomyname: 'iab_audience_taxonomy' - }, - segment: [ - { - id: '1945' - }, - { - id: '2003' - } - ] - }; - - const rtd = { - ortb2: { - user: { - data: [rtdUserObj1] - }, - site: { - content: { - data: [rtdSiteObj1] - } - } - } - }; - - let pbConfig = config.getConfig(); - addRealTimeData(bidConfig, rtd, rtdConfig); - - let ortb2Config = config.getConfig().ortb2; - - expect(ortb2Config.user.data).to.deep.include.members([setConfigUserObj1, setConfigUserObj2, rtdUserObj1]); - expect(ortb2Config.site.content.data).to.deep.include.members([setConfigSiteObj1, rtdSiteObj1]); - }); - - it('allows publisher defined rtd ortb2 logic', function() { - const rtdConfig = { - params: { - handleRtd: function(bidConfig, rtd, rtdConfig, pbConfig) { - if (rtd.ortb2.user.data[0].segment[0].id == '1776') { - pbConfig.setConfig({ortb2: rtd.ortb2}); - } else { - pbConfig.setConfig({ortb2: {}}); - } - } - } - }; - - let bidConfig = {}; - - const rtdUserObj1 = { - name: 'www.dataprovider.com', - ext: { taxonomyname: 'iab_audience_taxonomy' }, - segment: [{ - id: '1776' - }] - }; - - let rtd = { - ortb2: { - user: { - data: [rtdUserObj1] - } - } - }; - - config.resetConfig(); - - let pbConfig = config.getConfig(); - addRealTimeData(bidConfig, rtd, rtdConfig); - expect(config.getConfig().ortb2.user.data).to.deep.include.members([rtdUserObj1]); - - const rtdUserObj2 = { - name: 'www.audigent.com', - ext: { - segtax: '1', - taxprovider: '1' - }, - segment: [{ - id: 'pubseg1' - }] - }; - - rtd = { - ortb2: { - user: { - data: [rtdUserObj2] - } - } - }; - - config.resetConfig(); - - pbConfig = config.getConfig(); - addRealTimeData(bidConfig, rtd, rtdConfig); - expect(config.getConfig().ortb2).to.deep.equal({}); - }); - - it('allows publisher defined adunit logic', function() { - const rtdConfig = { - params: { - handleRtd: function(bidConfig, rtd, rtdConfig, pbConfig) { - var adUnits = bidConfig.adUnits; - for (var i = 0; i < adUnits.length; i++) { - var adUnit = adUnits[i]; - for (var j = 0; j < adUnit.bids.length; j++) { - var bid = adUnit.bids[j]; - if (bid.bidder == 'adBuzz') { - for (var k = 0; k < rtd.adBuzz.length; k++) { - bid.adBuzzData.segments.adBuzz.push(rtd.adBuzz[k]); - } - } else if (bid.bidder == 'trueBid') { - for (var k = 0; k < rtd.trueBid.length; k++) { - bid.trueBidSegments.push(rtd.trueBid[k]); - } - } - } - } - } - } - }; - - let bidConfig = { - adUnits: [ - { - bids: [ - { - bidder: 'adBuzz', - adBuzzData: { - segments: { - adBuzz: [ - { - id: 'adBuzzSeg1' - } - ] - } - } - }, - { - bidder: 'trueBid', - trueBidSegments: [] - } - ] - } - ] - }; - - const rtd = { - adBuzz: [{id: 'adBuzzSeg2'}, {id: 'adBuzzSeg3'}], - trueBid: [{id: 'truebidSeg1'}, {id: 'truebidSeg2'}, {id: 'truebidSeg3'}] - }; - - addRealTimeData(bidConfig, rtd, rtdConfig); - - expect(bidConfig.adUnits[0].bids[0].adBuzzData.segments.adBuzz[0].id).to.equal('adBuzzSeg1'); - expect(bidConfig.adUnits[0].bids[0].adBuzzData.segments.adBuzz[1].id).to.equal('adBuzzSeg2'); - expect(bidConfig.adUnits[0].bids[0].adBuzzData.segments.adBuzz[2].id).to.equal('adBuzzSeg3'); - expect(bidConfig.adUnits[0].bids[1].trueBidSegments[0].id).to.equal('truebidSeg1'); - expect(bidConfig.adUnits[0].bids[1].trueBidSegments[1].id).to.equal('truebidSeg2'); - expect(bidConfig.adUnits[0].bids[1].trueBidSegments[2].id).to.equal('truebidSeg3'); - }); - }); - - describe('Get Real-Time Data', function() { - it('gets rtd from local storage cache', function() { - const rtdConfig = { - params: { - segmentCache: true - } - }; - - const bidConfig = {}; - - const rtdUserObj1 = { - name: 'www.dataprovider3.com', - ext: { - taxonomyname: 'iab_audience_taxonomy' - }, - segment: [ - { - id: '1918' - }, - { - id: '1939' - } - ] - }; - - const cachedRtd = { - rtd: { - ortb2: { - user: { - data: [rtdUserObj1] - } - } - } - }; - - getDataFromLocalStorageStub.withArgs(RTD_LOCAL_NAME).returns(JSON.stringify(cachedRtd)); - - expect(config.getConfig().ortb2).to.be.undefined; - getRealTimeData(bidConfig, () => {}, rtdConfig, {}); - expect(config.getConfig().ortb2.user.data).to.deep.include.members([rtdUserObj1]); - }); - - it('gets real-time data via async request', function() { - const setConfigSiteObj1 = { - name: 'www.audigent.com', - ext: { - segtax: '1', - taxprovider: '1' - }, - segment: [ - { - id: 'pubseg1' - }, - { - id: 'pubseg2' - } - ] - } - - config.setConfig({ - ortb2: { - site: { - content: { - data: [setConfigSiteObj1] - } - } - } - }); - - const rtdConfig = { - params: { - segmentCache: false, - usePubHalo: true, - requestParams: { - publisherId: 'testPub1' - } - } - }; - - let bidConfig = {}; - - const rtdUserObj1 = { - name: 'www.audigent.com', - ext: { - segtax: '1', - taxprovider: '1' - }, - segment: [ - { - id: 'pubseg1' - }, - { - id: 'pubseg2' - } - ] - }; - - const data = { - rtd: { - ortb2: { - user: { - data: [rtdUserObj1] - } - } - } - }; - - getDataFromLocalStorageStub.withArgs(HALOID_LOCAL_NAME).returns('testHaloId1'); - getRealTimeData(bidConfig, () => {}, rtdConfig, {}); - - let request = server.requests[0]; - let postData = JSON.parse(request.requestBody); - expect(postData.config).to.have.deep.property('publisherId', 'testPub1'); - expect(postData.userIds).to.have.deep.property('haloId', 'testHaloId1'); - - request.respond(200, responseHeader, JSON.stringify(data)); - - expect(config.getConfig().ortb2.user.data).to.deep.include.members([rtdUserObj1]); - }); - }); -}); diff --git a/test/spec/modules/haxmediaBidAdapter_spec.js b/test/spec/modules/haxmediaBidAdapter_spec.js deleted file mode 100644 index 2e39d771bdf..00000000000 --- a/test/spec/modules/haxmediaBidAdapter_spec.js +++ /dev/null @@ -1,304 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/haxmediaBidAdapter.js'; -import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; - -describe('haxmediaBidAdapter', function () { - const bid = { - bidId: '23fhj33i987f', - bidder: 'haxmedia', - mediaTypes: { - [BANNER]: { - sizes: [[300, 250]] - } - }, - params: { - placementId: 783, - traffic: BANNER - } - }; - - const bidderRequest = { - refererInfo: { - referer: 'test.com' - } - }; - - describe('isBidRequestValid', function () { - it('Should return true if there are bidId, params and key parameters present', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false if at least one of parameters is not present', function () { - delete bid.params.placementId; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid], 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://balancer.haxmedia.io/?c=o&m=multi'); - }); - it('Returns valid data if array of bids is valid', function () { - let data = serverRequest.data; - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); - 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.gdpr).to.not.exist; - expect(data.ccpa).to.not.exist; - let placement = data['placements'][0]; - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes', 'schain'); - expect(placement.placementId).to.equal(783); - expect(placement.bidId).to.equal('23fhj33i987f'); - expect(placement.traffic).to.equal(BANNER); - expect(placement.schain).to.be.an('object'); - expect(placement.sizes).to.be.an('array'); - }); - - it('Returns valid data for mediatype video', function () { - const playerSize = [300, 300]; - bid.mediaTypes = {}; - bid.params.traffic = VIDEO; - bid.mediaTypes[VIDEO] = { - playerSize - }; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data).to.be.an('object'); - let placement = data['placements'][0]; - expect(placement).to.be.an('object'); - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'wPlayer', 'hPlayer', 'schain'); - expect(placement.traffic).to.equal(VIDEO); - expect(placement.wPlayer).to.equal(playerSize[0]); - expect(placement.hPlayer).to.equal(playerSize[1]); - }); - - it('Returns valid data for mediatype native', function () { - const native = { - title: { - required: true - }, - body: { - required: true - }, - icon: { - required: true, - size: [64, 64] - } - }; - - bid.mediaTypes = {}; - bid.params.traffic = NATIVE; - bid.mediaTypes[NATIVE] = native; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data).to.be.an('object'); - let placement = data['placements'][0]; - expect(placement).to.be.an('object'); - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'native', 'schain'); - expect(placement.traffic).to.equal(NATIVE); - expect(placement.native).to.equal(native); - }); - - it('Returns data with gdprConsent and without uspConsent', function () { - bidderRequest.gdprConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data.gdpr).to.exist; - expect(data.gdpr).to.be.a('string'); - expect(data.gdpr).to.equal(bidderRequest.gdprConsent); - expect(data.ccpa).to.not.exist; - delete bidderRequest.gdprConsent; - }); - - it('Returns data with uspConsent and without gdprConsent', function () { - bidderRequest.uspConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); - let 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; - }); - - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); - }); - 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' - }] - }; - let bannerResponses = spec.interpretResponse(banner); - expect(bannerResponses).to.be.an('array').that.is.not.empty; - let dataItem = bannerResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - expect(dataItem.requestId).to.equal('23fhj33i987f'); - expect(dataItem.cpm).to.equal(0.4); - expect(dataItem.width).to.equal(300); - expect(dataItem.height).to.equal(250); - expect(dataItem.ad).to.equal('Test'); - expect(dataItem.ttl).to.equal(120); - expect(dataItem.creativeId).to.equal('2'); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal('USD'); - }); - 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' - }] - }; - let videoResponses = spec.interpretResponse(video); - expect(videoResponses).to.be.an('array').that.is.not.empty; - - let dataItem = videoResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - 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'); - }); - 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', - }] - }; - let nativeResponses = spec.interpretResponse(native); - expect(nativeResponses).to.be.an('array').that.is.not.empty; - - let dataItem = nativeResponses[0]; - expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); - 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'); - }); - 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' - }] - }; - - let 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' - }] - }; - let 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', - }] - }; - let 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' - }] - }; - let serverResponses = spec.interpretResponse(invalid); - expect(serverResponses).to.be.an('array').that.is.empty; - }); - }); -}); diff --git a/test/spec/modules/hpmdnetworkBidAdapter_spec.js b/test/spec/modules/hpmdnetworkBidAdapter_spec.js deleted file mode 100644 index 9023fb248e9..00000000000 --- a/test/spec/modules/hpmdnetworkBidAdapter_spec.js +++ /dev/null @@ -1,148 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/hpmdnetworkBidAdapter.js'; - -describe('HPMDNetwork Adapter', function() { - describe('isBidRequestValid', function () { - it('should return true when required params found', function () { - const validBid = { - bidder: 'hpmdnetwork', - params: { - placementId: '1' - } - }; - - expect(spec.isBidRequestValid(validBid)).to.equal(true); - }); - - it('should return false for when required params are not passed', function () { - const invalidBid = { - bidder: 'hpmdnetwork', - params: {} - }; - - expect(spec.isBidRequestValid(invalidBid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const bidRequests = [ - { - bidId: 'bid1', - bidder: 'hpmdnetwork', - params: { - placementId: '1' - } - }, - { - bidId: 'bid2', - bidder: 'hpmdnetwork', - params: { - placementId: '2', - } - } - ]; - const bidderRequest = { - refererInfo: { - referer: 'https://example.com?foo=bar' - } - }; - - const bidRequest = spec.buildRequests(bidRequests, bidderRequest); - - it('should build single POST request for multiple bids', function() { - expect(bidRequest.method).to.equal('POST'); - expect(bidRequest.url).to.equal('https://banner.hpmdnetwork.ru/bidder/request'); - expect(bidRequest.data).to.be.an('object'); - expect(bidRequest.data.places).to.be.an('array'); - expect(bidRequest.data.places).to.have.lengthOf(2); - }); - - it('should pass bid parameters', function() { - const place1 = bidRequest.data.places[0]; - const place2 = bidRequest.data.places[1]; - - expect(place1.placementId).to.equal('1'); - expect(place2.placementId).to.equal('2'); - expect(place1.id).to.equal('bid1'); - expect(place2.id).to.equal('bid2'); - }); - - it('should pass site parameters', function() { - const url = bidRequest.data.url; - - expect(url).to.be.an('String'); - expect(url).to.equal('https://example.com?foo=bar'); - }); - - it('should pass settings', function() { - const settings = bidRequest.data.settings; - - expect(settings).to.be.an('object'); - expect(settings.currency).to.equal('RUB'); - }); - }); - - describe('interpretResponse', function () { - const serverResponse = { - body: { - 'bids': - [ - { - 'cpm': 20, - 'currency': 'RUB', - 'displayUrl': 'https://banner.hpmdnetwork.ru/bidder/display?dbid=0&vbid=168', - 'id': '1', - 'creativeId': '11111', - }, - { - 'cpm': 30, - 'currency': 'RUB', - 'displayUrl': 'https://banner.hpmdnetwork.ru/bidder/display?dbid=0&vbid=170', - 'id': '2', - 'creativeId': '22222', - 'width': 300, - 'height': 250, - }, - ] - } - }; - - const bids = spec.interpretResponse(serverResponse); - - it('should return empty array for response with no bids', function() { - const emptyBids = spec.interpretResponse({ body: {} }); - - expect(emptyBids).to.have.lengthOf(0); - }); - - it('should parse all bids from response', function() { - expect(bids).to.have.lengthOf(2); - }); - - it('should parse bid without sizes', function() { - expect(bids[0].requestId).to.equal('1'); - expect(bids[0].cpm).to.equal(20); - expect(bids[0].width).to.equal(1); - expect(bids[0].height).to.equal(1); - expect(bids[0].ttl).to.equal(300); - expect(bids[0].currency).to.equal('RUB'); - expect(bids[0]).to.have.property('creativeId'); - expect(bids[0].creativeId).to.equal('11111'); - expect(bids[0].netRevenue).to.equal(true); - expect(bids[0].ad).to.include(''); - }); - - it('should parse bid with sizes', function() { - expect(bids[1].requestId).to.equal('2'); - expect(bids[1].cpm).to.equal(30); - expect(bids[1].width).to.equal(300); - expect(bids[1].height).to.equal(250); - expect(bids[1].ttl).to.equal(300); - expect(bids[1].currency).to.equal('RUB'); - expect(bids[1]).to.have.property('creativeId'); - expect(bids[1].creativeId).to.equal('22222'); - expect(bids[1].netRevenue).to.equal(true); - expect(bids[1].ad).to.include(''); - }); - }); -}); diff --git a/test/spec/modules/hybridBidAdapter_spec.js b/test/spec/modules/hybridBidAdapter_spec.js deleted file mode 100644 index d1899ef3d81..00000000000 --- a/test/spec/modules/hybridBidAdapter_spec.js +++ /dev/null @@ -1,337 +0,0 @@ -import { expect } from 'chai' -import { spec } from 'modules/hybridBidAdapter.js' - -function getSlotConfigs(mediaTypes, params) { - return { - params: params, - sizes: [], - bidId: '2df8c0733f284e', - bidder: 'hybrid', - mediaTypes: mediaTypes, - transactionId: '31a58515-3634-4e90-9c96-f86196db1459' - } -} - -describe('Hybrid.ai Adapter', function() { - const PLACE_ID = '5af45ad34d506ee7acad0c26'; - const bidderRequest = { - refererInfo: { referer: 'referer' } - } - const bannerMandatoryParams = { - placeId: PLACE_ID, - placement: 'banner' - } - const videoMandatoryParams = { - placeId: PLACE_ID, - placement: 'video' - } - const inImageMandatoryParams = { - placeId: PLACE_ID, - placement: 'inImage', - imageUrl: 'https://hybrid.ai/images/image.jpg' - } - const validBidRequests = [ - getSlotConfigs({ banner: {} }, bannerMandatoryParams), - 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: {}}, - { - placeId: PLACE_ID, - placement: 'banner' - } - ) - const isBidRequestValid = spec.isBidRequestValid(slotConfig) - expect(isBidRequestValid).to.equal(true) - }) - describe('and In-Image placement has the correct value', function() { - const slotConfig = getSlotConfigs( - { - banner: { - sizes: [[0, 0]] - } - }, - { - placeId: PLACE_ID, - placement: 'inImage', - imageUrl: 'imageUrl' - } - ) - const isBidRequestValid = spec.isBidRequestValid(slotConfig) - expect(isBidRequestValid).to.equal(true) - }) - describe('when video slot has all mandatory params.', function() { - it('should return true, when video mediatype object are correct.', function() { - const slotConfig = getSlotConfigs( - { - video: { - context: 'instream', - playerSize: [[640, 480]] - } - }, - { - placeId: PLACE_ID, - placement: 'video' - } - ) - const isBidRequestValid = spec.isBidRequestValid(slotConfig) - expect(isBidRequestValid).to.equal(true) - }) - }) - }) - }) - describe('returns false', function() { - describe('when params are not correct', function() { - function createSlotconfig(params) { - return getSlotConfigs({ banner: {} }, params) - } - it('does not have the placeId.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createSlotconfig({ - placement: 'banner' - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('does not have the placement.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createSlotconfig({ - placeId: PLACE_ID - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('does not have the imageUrl.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createSlotconfig({ - placeId: PLACE_ID, - placement: 'inImage' - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('does not have a the correct placement.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createSlotconfig({ - placeId: PLACE_ID, - placement: 'something' - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - }) - describe('when video mediaType object is not correct.', function() { - function createVideoSlotconfig(mediaType) { - return getSlotConfigs(mediaType, { - placeId: PLACE_ID, - placement: 'video' - }) - } - it('is a void object', function() { - const isBidRequestValid = spec.isBidRequestValid( - createVideoSlotconfig({ video: {} }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('does not have playerSize.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createVideoSlotconfig({ video: { context: 'instream' } }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('does not have context', function() { - const isBidRequestValid = spec.isBidRequestValid( - createVideoSlotconfig({ - video: { - playerSize: [[640, 480]] - } - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - }) - }) - }) - it('Url params should be correct ', function() { - const request = spec.buildRequests(validBidRequests, bidderRequest) - expect(request.method).to.equal('POST') - expect(request.url).to.equal('https://hbe198.hybrid.ai/prebidhb') - }) - - describe('buildRequests method', function() { - it('Common data request should be correct', function() { - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(Array.isArray(data.bidRequests)).to.equal(true) - expect(data.url).to.equal('referer') - data.bidRequests.forEach(bid => { - expect(bid.bidId).to.equal('2df8c0733f284e') - expect(bid.placeId).to.equal(PLACE_ID) - expect(bid.transactionId).to.equal('31a58515-3634-4e90-9c96-f86196db1459') - }) - }) - - describe('GDPR params', function() { - describe('when there are not consent management platform', function() { - it('cmp should be false', function() { - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(data.cmp).to.equal(false) - }) - }) - describe('when there are consent management platform', function() { - it('cmps should be true and ga should not sended, when gdprApplies is undefined', function() { - bidderRequest['gdprConsent'] = { - gdprApplies: undefined, - consentString: 'consentString' - } - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(data.cmp).to.equal(true) - expect(Object.keys(data).indexOf('data')).to.equal(-1) - expect(data.cs).to.equal('consentString') - }) - it('cmps should be true and all gdpr parameters should be sended, when there are gdprApplies', function() { - bidderRequest['gdprConsent'] = { - gdprApplies: true, - consentString: 'consentString' - } - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(data.cmp).to.equal(true) - expect(data.ga).to.equal(true) - expect(data.cs).to.equal('consentString') - }) - }) - }) - - describe('BidRequests params', function() { - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - const bidRequests = data.bidRequests - it('should request a Banner', function() { - const bannerBid = bidRequests[0] - expect(bannerBid.placement).to.equal(spec.placementTypes[bannerMandatoryParams.placement]) - }) - it('should request a Video', function() { - const bannerBid = bidRequests[1] - expect(bannerBid.placement).to.equal(spec.placementTypes[videoMandatoryParams.placement]) - }) - }) - }) - - describe('interpret response method', function() { - it('should return a void array, when the server response are not correct.', function() { - const request = { data: JSON.stringify({}) } - const serverResponse = { - body: {} - } - const bids = spec.interpretResponse(serverResponse, request) - expect(typeof bids).to.equal('object') - expect(bids.length).to.equal(0) - }) - it('should return a void array, when the server response have not got bids.', function() { - const request = { data: JSON.stringify({}) } - const serverResponse = { body: { bids: [] } } - const bids = spec.interpretResponse(serverResponse, request) - expect(typeof bids).to.equal('object') - expect(bids.length).to.equal(0) - }) - describe('when the server response return a bid', function() { - describe('the bid is a banner', function() { - it('should return a banner bid', function() { - const request = spec.buildRequests([validBidRequests[0]], bidderRequest) - const serverResponse = { - body: { - bids: [ - { - bidId: '2df8c0733f284e', - price: 0.5, - currency: 'USD', - content: 'html', - width: 100, - height: 100 - } - ] - } - } - const bids = spec.interpretResponse(serverResponse, request) - expect(bids.length).to.equal(1) - expect(bids[0].requestId).to.equal('2df8c0733f284e') - expect(bids[0].mediaType).to.equal(spec.supportedMediaTypes[0]) - expect(bids[0].cpm).to.equal(0.5) - expect(bids[0].width).to.equal(100) - expect(bids[0].height).to.equal(100) - expect(bids[0].currency).to.equal('USD') - expect(bids[0].netRevenue).to.equal(true) - expect(typeof bids[0].ad).to.equal('string') - }) - it('should return a In-Image bid', function() { - const request = spec.buildRequests([validBidRequests[2]], bidderRequest) - const serverResponse = { - body: { - bids: [ - { - bidId: '2df8c0733f284e', - price: 0.5, - currency: 'USD', - content: 'html', - inImage: { - actionUrls: {} - }, - width: 100, - height: 100, - ttl: 360 - } - ] - } - } - const bids = spec.interpretResponse(serverResponse, request) - expect(bids.length).to.equal(1) - expect(bids[0].requestId).to.equal('2df8c0733f284e') - expect(bids[0].cpm).to.equal(0.5) - expect(bids[0].width).to.equal(100) - expect(bids[0].height).to.equal(100) - expect(bids[0].currency).to.equal('USD') - expect(bids[0].netRevenue).to.equal(true) - expect(typeof bids[0].ad).to.equal('string') - }) - }) - describe('the bid is a video', function() { - it('should return a video bid', function() { - const request = spec.buildRequests([validBidRequests[1]], bidderRequest) - const serverResponse = { - body: { - bids: [ - { - bidId: '2df8c0733f284e', - price: 0.5, - currency: 'USD', - content: 'html', - width: 100, - height: 100, - transactionId: '31a58515-3634-4e90-9c96-f86196db1459' - } - ] - } - } - const bids = spec.interpretResponse(serverResponse, request) - expect(bids.length).to.equal(1) - expect(bids[0].requestId).to.equal('2df8c0733f284e') - expect(bids[0].mediaType).to.equal(spec.supportedMediaTypes[1]) - expect(bids[0].cpm).to.equal(0.5) - expect(bids[0].width).to.equal(100) - expect(bids[0].height).to.equal(100) - expect(bids[0].currency).to.equal('USD') - expect(bids[0].netRevenue).to.equal(true) - expect(typeof bids[0].vastXml).to.equal('string') - }) - }) - }) - }) -}) diff --git a/test/spec/modules/iasBidAdapter_spec.js b/test/spec/modules/iasBidAdapter_spec.js deleted file mode 100644 index 1743ac947e6..00000000000 --- a/test/spec/modules/iasBidAdapter_spec.js +++ /dev/null @@ -1,343 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/iasBidAdapter.js'; - -describe('iasBidAdapter is an adapter that', function () { - it('has the correct bidder code', function () { - expect(spec.code).to.equal('ias'); - }); - describe('has a method `isBidRequestValid` that', function () { - it('exists', function () { - expect(spec.isBidRequestValid).to.be.a('function'); - }); - it('returns false if bid params misses `pubId`', function () { - expect(spec.isBidRequestValid( - { - params: { - adUnitPath: 'someAdUnitPath' - } - })).to.equal(false); - }); - it('returns false if bid params misses `adUnitPath`', function () { - expect(spec.isBidRequestValid( - { - params: { - pubId: 'somePubId' - } - })).to.equal(false); - }); - it('returns true otherwise', function () { - expect(spec.isBidRequestValid( - { - params: { - adUnitPath: 'someAdUnitPath', - pubId: 'somePubId', - someOtherParam: 'abc' - } - })).to.equal(true); - }); - }); - - describe('has a method `buildRequests` that', function () { - it('exists', function () { - expect(spec.buildRequests).to.be.a('function'); - }); - describe('given bid requests, returns a `ServerRequest` instance that', function () { - let bidRequests, IAS_HOST; - beforeEach(function () { - IAS_HOST = 'https://pixel.adsafeprotected.com/services/pub'; - bidRequests = [ - { - adUnitCode: 'one-div-id', - auctionId: 'someAuctionId', - bidId: 'someBidId', - bidder: 'ias', - bidderRequestId: 'someBidderRequestId', - params: { - pubId: '1234', - adUnitPath: '/a/b/c' - }, - sizes: [ - [10, 20], - [300, 400] - ], - transactionId: 'someTransactionId' - }, - { - adUnitCode: 'two-div-id', - auctionId: 'someAuctionId', - bidId: 'someBidId', - bidder: 'ias', - bidderRequestId: 'someBidderRequestId', - params: { - pubId: '1234', - adUnitPath: '/d/e/f' - }, - sizes: [ - [50, 60] - ], - transactionId: 'someTransactionId' - } - ]; - }); - it('has property `method` of `GET`', function () { - expect(spec.buildRequests(bidRequests)).to.deep.include({ - method: 'GET' - }); - }); - it('has property `url` to be the correct IAS endpoint', function () { - expect(spec.buildRequests(bidRequests)).to.deep.include({ - url: IAS_HOST - }); - }); - it('only includes the first `bidRequest` as the bidRequest variable on a multiple slot request', function () { - expect(spec.buildRequests(bidRequests).bidRequest.adUnitCode).to.equal(bidRequests[0].adUnitCode); - }); - describe('has property `data` that is an encode query string containing information such as', function () { - let val; - const ANID_PARAM = 'anId'; - const SLOT_PARAM = 'slot'; - const SLOT_ID_PARAM = 'id'; - const SLOT_SIZE_PARAM = 'ss'; - const SLOT_AD_UNIT_PATH_PARAM = 'p'; - - beforeEach(function () { - val = decodeURI(spec.buildRequests(bidRequests).data); - }); - it('publisher id', function () { - expect(val).to.have.string(`${ANID_PARAM}=1234`); - }); - it('ad slot`s id, size and ad unit path', function () { - expect(val).to.have.string(`${SLOT_PARAM}={${SLOT_ID_PARAM}:one-div-id,${SLOT_SIZE_PARAM}:[10.20,300.400],${SLOT_AD_UNIT_PATH_PARAM}:/a/b/c}`); - expect(val).to.have.string(`${SLOT_PARAM}={${SLOT_ID_PARAM}:two-div-id,${SLOT_SIZE_PARAM}:[50.60],${SLOT_AD_UNIT_PATH_PARAM}:/d/e/f}`); - }); - it('window size', function () { - expect(val).to.match(/.*wr=[0-9]*\.[0-9]*/); - }); - it('screen size', function () { - expect(val).to.match(/.*sr=[0-9]*\.[0-9]*/); - }); - it('url value', function () { - expect(val).to.match(/.*url=https?%3A%2F%2F[^\s$.?#].[^\s]*/); - }); - }); - it('has property `bidRequest` that is the first passed in bid request', function () { - expect(spec.buildRequests(bidRequests)).to.deep.include({ - bidRequest: bidRequests[0] - }); - }); - }); - }); - describe('has a method `interpretResponse` that', function () { - it('exists', function () { - expect(spec.interpretResponse).to.be.a('function'); - }); - describe('returns a list of bid response that', function () { - let bidRequests, bidResponse, slots, serverResponse; - beforeEach(function () { - bidRequests = [ - { - adUnitCode: 'one-div-id', - auctionId: 'someAuctionId', - bidId: 'someBidId1', - bidder: 'ias', - bidderRequestId: 'someBidderRequestId', - params: { - pubId: '1234', - adUnitPath: '/a/b/c' - }, - sizes: [ - [10, 20], - [300, 400] - ], - transactionId: 'someTransactionId' - }, - { - adUnitCode: 'two-div-id', - auctionId: 'someAuctionId', - bidId: 'someBidId2', - bidder: 'ias', - bidderRequestId: 'someBidderRequestId', - params: { - pubId: '1234', - adUnitPath: '/d/e/f' - }, - sizes: [ - [50, 60] - ], - transactionId: 'someTransactionId' - } - ]; - const request = { - bidRequest: { - bidId: '102938' - } - }; - slots = {}; - slots['test-div-id'] = { - id: '1234', - vw: ['60', '70'] - }; - slots['test-div-id-two'] = { - id: '5678', - vw: ['80', '90'] - }; - serverResponse = { - body: { - brandSafety: { - adt: 'adtVal', - alc: 'alcVal', - dlm: 'dlmVal', - drg: 'drgVal', - hat: 'hatVal', - off: 'offVal', - vio: 'vioVal' - }, - fr: 'false', - slots: slots - }, - headers: {} - }; - bidResponse = spec.interpretResponse(serverResponse, request); - }); - it('has IAS keyword `adt` as property', function () { - expect(bidResponse[0]).to.deep.include({ adt: 'adtVal' }); - }); - it('has IAS keyword `alc` as property', function () { - expect(bidResponse[0]).to.deep.include({ alc: 'alcVal' }); - }); - it('has IAS keyword `dlm` as property', function () { - expect(bidResponse[0]).to.deep.include({ dlm: 'dlmVal' }); - }); - it('has IAS keyword `drg` as property', function () { - expect(bidResponse[0]).to.deep.include({ drg: 'drgVal' }); - }); - it('has IAS keyword `hat` as property', function () { - expect(bidResponse[0]).to.deep.include({ hat: 'hatVal' }); - }); - it('has IAS keyword `off` as property', function () { - expect(bidResponse[0]).to.deep.include({ off: 'offVal' }); - }); - it('has IAS keyword `vio` as property', function () { - expect(bidResponse[0]).to.deep.include({ vio: 'vioVal' }); - }); - it('has IAS keyword `fr` as property', function () { - expect(bidResponse[0]).to.deep.include({ fr: 'false' }); - }); - it('has property `slots`', function () { - expect(bidResponse[0]).to.deep.include({ slots: slots }); - }); - it('response is the same for multiple slots', function () { - var adapter = spec; - var requests = adapter.buildRequests(bidRequests); - expect(adapter.interpretResponse(serverResponse, requests)).to.length(2); - }); - }); - describe('returns a list of bid response that with custom value', function () { - let bidRequests, bidResponse, slots, custom, serverResponse; - beforeEach(function () { - bidRequests = [ - { - adUnitCode: 'one-div-id', - auctionId: 'someAuctionId', - bidId: 'someBidId1', - bidder: 'ias', - bidderRequestId: 'someBidderRequestId', - params: { - pubId: '1234', - adUnitPath: '/a/b/c' - }, - sizes: [ - [10, 20], - [300, 400] - ], - transactionId: 'someTransactionId' - }, - { - adUnitCode: 'two-div-id', - auctionId: 'someAuctionId', - bidId: 'someBidId2', - bidder: 'ias', - bidderRequestId: 'someBidderRequestId', - params: { - pubId: '1234', - adUnitPath: '/d/e/f' - }, - sizes: [ - [50, 60] - ], - transactionId: 'someTransactionId' - } - ]; - const request = { - bidRequest: { - bidId: '102938' - } - }; - slots = {}; - slots['test-div-id'] = { - id: '1234', - vw: ['60', '70'] - }; - slots['test-div-id-two'] = { - id: '5678', - vw: ['80', '90'] - }; - custom = {}; - custom['ias-kw'] = ['IAS_1_KW', 'IAS_2_KW']; - serverResponse = { - body: { - brandSafety: { - adt: 'adtVal', - alc: 'alcVal', - dlm: 'dlmVal', - drg: 'drgVal', - hat: 'hatVal', - off: 'offVal', - vio: 'vioVal' - }, - fr: 'false', - slots: slots, - custom: custom - }, - headers: {} - }; - bidResponse = spec.interpretResponse(serverResponse, request); - }); - it('has IAS keyword `adt` as property', function () { - expect(bidResponse[0]).to.deep.include({ adt: 'adtVal' }); - }); - it('has IAS keyword `alc` as property', function () { - expect(bidResponse[0]).to.deep.include({ alc: 'alcVal' }); - }); - it('has IAS keyword `dlm` as property', function () { - expect(bidResponse[0]).to.deep.include({ dlm: 'dlmVal' }); - }); - it('has IAS keyword `drg` as property', function () { - expect(bidResponse[0]).to.deep.include({ drg: 'drgVal' }); - }); - it('has IAS keyword `hat` as property', function () { - expect(bidResponse[0]).to.deep.include({ hat: 'hatVal' }); - }); - it('has IAS keyword `off` as property', function () { - expect(bidResponse[0]).to.deep.include({ off: 'offVal' }); - }); - it('has IAS keyword `vio` as property', function () { - expect(bidResponse[0]).to.deep.include({ vio: 'vioVal' }); - }); - it('has IAS keyword `fr` as property', function () { - expect(bidResponse[0]).to.deep.include({ fr: 'false' }); - }); - it('has property `slots`', function () { - expect(bidResponse[0]).to.deep.include({ slots: slots }); - }); - it('has property `custom`', function () { - expect(bidResponse[0]).to.deep.include({ custom: custom }); - }); - it('response is the same for multiple slots', function () { - var adapter = spec; - var requests = adapter.buildRequests(bidRequests); - expect(adapter.interpretResponse(serverResponse, requests)).to.length(3); - }); - }); - }); -}); diff --git a/test/spec/modules/id5IdSystem_spec.js b/test/spec/modules/id5IdSystem_spec.js deleted file mode 100644 index 9ba9aee9c63..00000000000 --- a/test/spec/modules/id5IdSystem_spec.js +++ /dev/null @@ -1,632 +0,0 @@ -import { - id5IdSubmodule, - ID5_STORAGE_NAME, - ID5_PRIVACY_STORAGE_NAME, - getFromLocalStorage, - storeInLocalStorage, - expDaysStr, - nbCacheName, - getNbFromCache, - storeNbInCache, - isInControlGroup -} from 'modules/id5IdSystem.js'; -import { init, requestBidsHook, setSubmoduleRegistry, coreStorage } from 'modules/userId/index.js'; -import { config } from 'src/config.js'; -import { server } from 'test/mocks/xhr.js'; -import events from 'src/events.js'; -import CONSTANTS from 'src/constants.json'; -import * as utils from 'src/utils.js'; - -let expect = require('chai').expect; - -describe('ID5 ID System', function() { - const ID5_MODULE_NAME = 'id5Id'; - const ID5_EIDS_NAME = ID5_MODULE_NAME.toLowerCase(); - const ID5_SOURCE = 'id5-sync.com'; - const ID5_TEST_PARTNER_ID = 173; - const ID5_ENDPOINT = `https://id5-sync.com/g/v2/${ID5_TEST_PARTNER_ID}.json`; - const ID5_NB_STORAGE_NAME = nbCacheName(ID5_TEST_PARTNER_ID); - const ID5_STORED_ID = 'storedid5id'; - const ID5_STORED_SIGNATURE = '123456'; - const ID5_STORED_LINK_TYPE = 1; - const ID5_STORED_OBJ = { - 'universal_uid': ID5_STORED_ID, - 'signature': ID5_STORED_SIGNATURE, - 'link_type': ID5_STORED_LINK_TYPE - }; - const ID5_RESPONSE_ID = 'newid5id'; - const ID5_RESPONSE_SIGNATURE = 'abcdef'; - const ID5_RESPONSE_LINK_TYPE = 2; - const ID5_JSON_RESPONSE = { - 'universal_uid': ID5_RESPONSE_ID, - 'signature': ID5_RESPONSE_SIGNATURE, - 'link_type': ID5_RESPONSE_LINK_TYPE - }; - - function getId5FetchConfig(storageName = ID5_STORAGE_NAME, storageType = 'html5') { - return { - name: ID5_MODULE_NAME, - params: { - partner: ID5_TEST_PARTNER_ID - }, - storage: { - name: storageName, - type: storageType, - expires: 90 - } - } - } - function getId5ValueConfig(value) { - return { - name: ID5_MODULE_NAME, - value: { - id5id: { - uid: value - } - } - } - } - function getUserSyncConfig(userIds) { - return { - userSync: { - userIds: userIds, - syncDelay: 0 - } - } - } - function getFetchCookieConfig() { - return getUserSyncConfig([getId5FetchConfig(ID5_STORAGE_NAME, 'cookie')]); - } - function getFetchLocalStorageConfig() { - return getUserSyncConfig([getId5FetchConfig(ID5_STORAGE_NAME, 'html5')]); - } - function getValueConfig(value) { - return getUserSyncConfig([getId5ValueConfig(value)]); - } - function getAdUnitMock(code = 'adUnit-code') { - return { - code, - mediaTypes: {banner: {}, native: {}}, - sizes: [[300, 200], [300, 600]], - bids: [{bidder: 'sampleBidder', params: {placementId: 'banner-only-bidder'}}] - }; - } - - describe('Check for valid publisher config', function() { - it('should fail with invalid config', function() { - // no config - expect(id5IdSubmodule.getId()).to.be.eq(undefined); - expect(id5IdSubmodule.getId({ })).to.be.eq(undefined); - - // valid params, invalid storage - expect(id5IdSubmodule.getId({ params: { partner: 123 } })).to.be.eq(undefined); - expect(id5IdSubmodule.getId({ params: { partner: 123 }, storage: {} })).to.be.eq(undefined); - expect(id5IdSubmodule.getId({ params: { partner: 123 }, storage: { name: '' } })).to.be.eq(undefined); - expect(id5IdSubmodule.getId({ params: { partner: 123 }, storage: { type: '' } })).to.be.eq(undefined); - - // valid storage, invalid params - expect(id5IdSubmodule.getId({ storage: { name: 'name', type: 'html5', }, })).to.be.eq(undefined); - expect(id5IdSubmodule.getId({ storage: { name: 'name', type: 'html5', }, params: { } })).to.be.eq(undefined); - expect(id5IdSubmodule.getId({ storage: { name: 'name', type: 'html5', }, params: { partner: 'abc' } })).to.be.eq(undefined); - }); - - it('should warn with non-recommended storage params', function() { - let logWarnStub = sinon.stub(utils, 'logWarn'); - - id5IdSubmodule.getId({ storage: { name: 'name', type: 'html5', }, params: { partner: 123 } }); - expect(logWarnStub.calledOnce).to.be.true; - logWarnStub.restore(); - - id5IdSubmodule.getId({ storage: { name: ID5_STORAGE_NAME, type: 'cookie', }, params: { partner: 123 } }); - expect(logWarnStub.calledOnce).to.be.true; - logWarnStub.restore(); - }); - }); - - describe('Xhr Requests from getId()', function() { - const responseHeader = { 'Content-Type': 'application/json' }; - let callbackSpy = sinon.spy(); - - beforeEach(function() { - callbackSpy.resetHistory(); - }); - afterEach(function () { - - }); - - it('should call the ID5 server and handle a valid response', function () { - let submoduleCallback = id5IdSubmodule.getId(getId5FetchConfig(), undefined, undefined).callback; - submoduleCallback(callbackSpy); - - let request = server.requests[0]; - let requestBody = JSON.parse(request.requestBody); - expect(request.url).to.contain(ID5_ENDPOINT); - expect(request.withCredentials).to.be.true; - expect(requestBody.partner).to.eq(ID5_TEST_PARTNER_ID); - expect(requestBody.o).to.eq('pbjs'); - expect(requestBody.pd).to.be.undefined; - expect(requestBody.s).to.be.undefined; - expect(requestBody.provider).to.be.undefined - expect(requestBody.v).to.eq('$prebid.version$'); - expect(requestBody.gdpr).to.exist; - expect(requestBody.gdpr_consent).to.be.undefined; - expect(requestBody.us_privacy).to.be.undefined; - - request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); - expect(callbackSpy.calledOnce).to.be.true; - expect(callbackSpy.lastCall.lastArg).to.deep.equal(ID5_JSON_RESPONSE); - }); - - it('should call the ID5 server with no signature field when no stored object', function () { - let submoduleCallback = id5IdSubmodule.getId(getId5FetchConfig(), undefined, undefined).callback; - submoduleCallback(callbackSpy); - - let request = server.requests[0]; - let requestBody = JSON.parse(request.requestBody); - expect(requestBody.s).to.be.undefined; - - request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); - }); - - it('should call the ID5 server with signature field from stored object', function () { - let submoduleCallback = id5IdSubmodule.getId(getId5FetchConfig(), undefined, ID5_STORED_OBJ).callback; - submoduleCallback(callbackSpy); - - let request = server.requests[0]; - let requestBody = JSON.parse(request.requestBody); - expect(requestBody.s).to.eq(ID5_STORED_SIGNATURE); - - request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); - }); - - it('should call the ID5 server with pd field when pd config is set', function () { - const pubData = 'b50ca08271795a8e7e4012813f23d505193d75c0f2e2bb99baa63aa822f66ed3'; - - let id5Config = getId5FetchConfig(); - id5Config.params.pd = pubData; - - let submoduleCallback = id5IdSubmodule.getId(id5Config, undefined, ID5_STORED_OBJ).callback; - submoduleCallback(callbackSpy); - - let request = server.requests[0]; - let requestBody = JSON.parse(request.requestBody); - expect(requestBody.pd).to.eq(pubData); - - request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); - }); - - it('should call the ID5 server with no pd field when pd config is not set', function () { - let id5Config = getId5FetchConfig(); - id5Config.params.pd = undefined; - - let submoduleCallback = id5IdSubmodule.getId(id5Config, undefined, ID5_STORED_OBJ).callback; - submoduleCallback(callbackSpy); - - let request = server.requests[0]; - let requestBody = JSON.parse(request.requestBody); - expect(requestBody.pd).to.be.undefined; - - request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); - }); - - it('should call the ID5 server with nb=1 when no stored value exists and reset after', function () { - coreStorage.removeDataFromLocalStorage(ID5_NB_STORAGE_NAME); - - let submoduleCallback = id5IdSubmodule.getId(getId5FetchConfig(), undefined, ID5_STORED_OBJ).callback; - submoduleCallback(callbackSpy); - - let request = server.requests[0]; - let requestBody = JSON.parse(request.requestBody); - expect(requestBody.nbPage).to.eq(1); - - request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); - - expect(getNbFromCache(ID5_TEST_PARTNER_ID)).to.be.eq(0); - }); - - it('should call the ID5 server with incremented nb when stored value exists and reset after', function () { - storeNbInCache(ID5_TEST_PARTNER_ID, 1); - - let submoduleCallback = id5IdSubmodule.getId(getId5FetchConfig(), undefined, ID5_STORED_OBJ).callback; - submoduleCallback(callbackSpy); - - let request = server.requests[0]; - let requestBody = JSON.parse(request.requestBody); - expect(requestBody.nbPage).to.eq(2); - - request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); - - expect(getNbFromCache(ID5_TEST_PARTNER_ID)).to.be.eq(0); - }); - - it('should call the ID5 server with ab feature = 1 when abTesting is turned on', function () { - let id5Config = getId5FetchConfig(); - id5Config.params.abTesting = { enabled: true, controlGroupPct: 10 } - - let submoduleCallback = id5IdSubmodule.getId(id5Config, undefined, ID5_STORED_OBJ).callback; - submoduleCallback(callbackSpy); - - let request = server.requests[0]; - let requestBody = JSON.parse(request.requestBody); - expect(requestBody.features.ab).to.eq(1); - - request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); - }); - - it('should call the ID5 server without ab feature when abTesting is turned off', function () { - let id5Config = getId5FetchConfig(); - id5Config.params.abTesting = { enabled: false, controlGroupPct: 10 } - - let submoduleCallback = id5IdSubmodule.getId(id5Config, undefined, ID5_STORED_OBJ).callback; - submoduleCallback(callbackSpy); - - let request = server.requests[0]; - let requestBody = JSON.parse(request.requestBody); - expect(requestBody.features).to.be.undefined; - - request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); - }); - - it('should call the ID5 server without ab feature when when abTesting is not set', function () { - let id5Config = getId5FetchConfig(); - - let submoduleCallback = id5IdSubmodule.getId(id5Config, undefined, ID5_STORED_OBJ).callback; - submoduleCallback(callbackSpy); - - let request = server.requests[0]; - let requestBody = JSON.parse(request.requestBody); - expect(requestBody.features).to.be.undefined; - - request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); - }); - - it('should store the privacy object from the ID5 server response', function () { - let submoduleCallback = id5IdSubmodule.getId(getId5FetchConfig(), undefined, ID5_STORED_OBJ).callback; - submoduleCallback(callbackSpy); - - let request = server.requests[0]; - - let responseObject = utils.deepClone(ID5_JSON_RESPONSE); - responseObject.privacy = { - jurisdiction: 'gdpr', - id5_consent: true - }; - request.respond(200, responseHeader, JSON.stringify(responseObject)); - expect(getFromLocalStorage(ID5_PRIVACY_STORAGE_NAME)).to.be.eq(JSON.stringify(responseObject.privacy)); - coreStorage.removeDataFromLocalStorage(ID5_PRIVACY_STORAGE_NAME); - }); - - it('should not store a privacy object if not part of ID5 server response', function () { - coreStorage.removeDataFromLocalStorage(ID5_PRIVACY_STORAGE_NAME); - let submoduleCallback = id5IdSubmodule.getId(getId5FetchConfig(), undefined, ID5_STORED_OBJ).callback; - submoduleCallback(callbackSpy); - - let request = server.requests[0]; - - request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); - expect(getFromLocalStorage(ID5_PRIVACY_STORAGE_NAME)).to.be.null; - }); - }); - - describe('Request Bids Hook', function() { - let adUnits; - - beforeEach(function() { - sinon.stub(events, 'getEvents').returns([]); - coreStorage.removeDataFromLocalStorage(ID5_STORAGE_NAME); - coreStorage.removeDataFromLocalStorage(`${ID5_STORAGE_NAME}_last`); - coreStorage.removeDataFromLocalStorage(ID5_NB_STORAGE_NAME); - adUnits = [getAdUnitMock()]; - }); - afterEach(function() { - events.getEvents.restore(); - coreStorage.removeDataFromLocalStorage(ID5_STORAGE_NAME); - coreStorage.removeDataFromLocalStorage(`${ID5_STORAGE_NAME}_last`); - coreStorage.removeDataFromLocalStorage(ID5_NB_STORAGE_NAME); - }); - - it('should add stored ID from cache to bids', function (done) { - storeInLocalStorage(ID5_STORAGE_NAME, JSON.stringify(ID5_STORED_OBJ), 1); - - setSubmoduleRegistry([id5IdSubmodule]); - init(config); - config.setConfig(getFetchLocalStorageConfig()); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property(`userId.${ID5_EIDS_NAME}`); - expect(bid.userId.id5id.uid).to.equal(ID5_STORED_ID); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: ID5_SOURCE, - uids: [{ - id: ID5_STORED_ID, - atype: 1, - ext: { - linkType: ID5_STORED_LINK_TYPE - } - }] - }); - }); - }); - done(); - }, { adUnits }); - }); - - it('should add config value ID to bids', function (done) { - setSubmoduleRegistry([id5IdSubmodule]); - init(config); - config.setConfig(getValueConfig(ID5_STORED_ID)); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property(`userId.${ID5_EIDS_NAME}`); - expect(bid.userId.id5id.uid).to.equal(ID5_STORED_ID); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: ID5_SOURCE, - uids: [{ id: ID5_STORED_ID, atype: 1 }] - }); - }); - }); - done(); - }, { adUnits }); - }); - - it('should set nb=1 in cache when no stored nb value exists and cached ID', function () { - storeInLocalStorage(ID5_STORAGE_NAME, JSON.stringify(ID5_STORED_OBJ), 1); - coreStorage.removeDataFromLocalStorage(ID5_NB_STORAGE_NAME); - - setSubmoduleRegistry([id5IdSubmodule]); - init(config); - config.setConfig(getFetchLocalStorageConfig()); - - let innerAdUnits; - requestBidsHook((adUnitConfig) => { innerAdUnits = adUnitConfig.adUnits }, {adUnits}); - - expect(getNbFromCache(ID5_TEST_PARTNER_ID)).to.be.eq(1); - }); - - it('should increment nb in cache when stored nb value exists and cached ID', function () { - storeInLocalStorage(ID5_STORAGE_NAME, JSON.stringify(ID5_STORED_OBJ), 1); - storeNbInCache(ID5_TEST_PARTNER_ID, 1); - - setSubmoduleRegistry([id5IdSubmodule]); - init(config); - config.setConfig(getFetchLocalStorageConfig()); - - let innerAdUnits; - requestBidsHook((adUnitConfig) => { innerAdUnits = adUnitConfig.adUnits }, {adUnits}); - - expect(getNbFromCache(ID5_TEST_PARTNER_ID)).to.be.eq(2); - }); - - it('should call ID5 servers with signature and incremented nb post auction if refresh needed', function () { - storeInLocalStorage(ID5_STORAGE_NAME, JSON.stringify(ID5_STORED_OBJ), 1); - storeInLocalStorage(`${ID5_STORAGE_NAME}_last`, expDaysStr(-1), 1); - storeNbInCache(ID5_TEST_PARTNER_ID, 1); - - let id5Config = getFetchLocalStorageConfig(); - id5Config.userSync.userIds[0].storage.refreshInSeconds = 2; - - setSubmoduleRegistry([id5IdSubmodule]); - init(config); - config.setConfig(id5Config); - - let innerAdUnits; - requestBidsHook((adUnitConfig) => { innerAdUnits = adUnitConfig.adUnits }, {adUnits}); - - expect(getNbFromCache(ID5_TEST_PARTNER_ID)).to.be.eq(2); - - expect(server.requests).to.be.empty; - events.emit(CONSTANTS.EVENTS.AUCTION_END, {}); - - let request = server.requests[0]; - let requestBody = JSON.parse(request.requestBody); - expect(request.url).to.contain(ID5_ENDPOINT); - expect(requestBody.s).to.eq(ID5_STORED_SIGNATURE); - expect(requestBody.nbPage).to.eq(2); - - const responseHeader = { 'Content-Type': 'application/json' }; - request.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); - - expect(decodeURIComponent(getFromLocalStorage(ID5_STORAGE_NAME))).to.be.eq(JSON.stringify(ID5_JSON_RESPONSE)); - expect(getNbFromCache(ID5_TEST_PARTNER_ID)).to.be.eq(0); - }); - }); - - describe('Decode stored object', function() { - const expectedDecodedObject = { id5id: { uid: ID5_STORED_ID, ext: { linkType: ID5_STORED_LINK_TYPE } } }; - - it('should properly decode from a stored object', function() { - expect(id5IdSubmodule.decode(ID5_STORED_OBJ, getId5FetchConfig())).to.deep.equal(expectedDecodedObject); - }); - it('should return undefined if passed a string', function() { - expect(id5IdSubmodule.decode('somestring', getId5FetchConfig())).to.eq(undefined); - }); - }); - - describe('A/B Testing', function() { - 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 } } }; - const expectedDecodedObjectWithoutIdAbOn = { id5id: { uid: '', ext: { linkType: 0, abTestingControlGroup: true } } }; - let testConfig; - - beforeEach(function() { - testConfig = getId5FetchConfig(); - }); - - describe('Configuration Validation', function() { - let logErrorSpy; - let logInfoSpy; - - beforeEach(function() { - logErrorSpy = sinon.spy(utils, 'logError'); - logInfoSpy = sinon.spy(utils, 'logInfo'); - }); - afterEach(function() { - logErrorSpy.restore(); - logInfoSpy.restore(); - }); - - // A/B Testing ON, but invalid config - let testInvalidAbTestingConfigsWithError = [ - { enabled: true }, - { enabled: true, controlGroupPct: 2 }, - { enabled: true, controlGroupPct: -1 }, - { enabled: true, controlGroupPct: 'a' }, - { enabled: true, controlGroupPct: true } - ]; - testInvalidAbTestingConfigsWithError.forEach((testAbTestingConfig) => { - it('should be undefined if ratio is invalid', () => { - expect(isInControlGroup('userId', testAbTestingConfig.controlGroupPct)).to.be.undefined; - }); - it('should error if config is invalid, and always return an ID', function () { - testConfig.params.abTesting = testAbTestingConfig; - let decoded = id5IdSubmodule.decode(ID5_STORED_OBJ, testConfig); - expect(decoded).to.deep.equal(expectedDecodedObjectWithIdAbOn); - sinon.assert.calledOnce(logErrorSpy); - }); - }); - - // A/B Testing OFF, with invalid config (ignore) - let testInvalidAbTestingConfigsWithoutError = [ - { enabled: false, controlGroupPct: -1 }, - { enabled: false, controlGroupPct: 2 }, - { enabled: false, controlGroupPct: 'a' }, - { enabled: false, controlGroupPct: true } - ]; - testInvalidAbTestingConfigsWithoutError.forEach((testAbTestingConfig) => { - it('should be undefined if ratio is invalid', () => { - expect(isInControlGroup('userId', testAbTestingConfig.controlGroupPct)).to.be.undefined; - }); - it('should not error if config is invalid but A/B testing is off, and always return an ID', function () { - testConfig.params.abTesting = testAbTestingConfig; - let decoded = id5IdSubmodule.decode(ID5_STORED_OBJ, testConfig); - expect(decoded).to.deep.equal(expectedDecodedObjectWithIdAbOff); - sinon.assert.notCalled(logErrorSpy); - }); - }); - - // A/B Testing ON, with valid config - let testValidConfigs = [ - { enabled: true, controlGroupPct: 0 }, - { enabled: true, controlGroupPct: 0.5 }, - { enabled: true, controlGroupPct: 1 } - ]; - testValidConfigs.forEach((testAbTestingConfig) => { - it('should not be undefined if ratio is valid', () => { - expect(isInControlGroup('userId', testAbTestingConfig.controlGroupPct)).to.not.be.undefined; - }); - it('should not error if config is valid', function () { - testConfig.params.abTesting = testAbTestingConfig; - id5IdSubmodule.decode(ID5_STORED_OBJ, testConfig); - sinon.assert.notCalled(logErrorSpy); - }); - }); - }); - - describe('A/B Testing Config is not Set', function() { - let randStub; - - beforeEach(function() { - randStub = sinon.stub(Math, 'random').callsFake(function() { - return 0; - }); - }); - afterEach(function () { - randStub.restore(); - }); - - it('should expose ID when A/B config is not set', function () { - let decoded = id5IdSubmodule.decode(ID5_STORED_OBJ, testConfig); - expect(decoded).to.deep.equal(expectedDecodedObjectWithIdAbOff); - }); - - it('should expose ID when A/B config is empty', function () { - testConfig.params.abTesting = { }; - - let decoded = id5IdSubmodule.decode(ID5_STORED_OBJ, testConfig); - expect(decoded).to.deep.equal(expectedDecodedObjectWithIdAbOff); - }); - }); - - describe('A/B Testing Config is Set', function() { - let randStub; - - beforeEach(function() { - randStub = sinon.stub(Math, 'random').callsFake(function() { - return 0.25; - }); - }); - afterEach(function () { - randStub.restore(); - }); - - describe('IsInControlGroup', function () { - it('Nobody is in a 0% control group', function () { - expect(isInControlGroup('dsdndskhsdks', 0)).to.be.false; - expect(isInControlGroup('3erfghyuijkm', 0)).to.be.false; - expect(isInControlGroup('', 0)).to.be.false; - expect(isInControlGroup(undefined, 0)).to.be.false; - }); - - it('Everybody is in a 100% control group', function () { - expect(isInControlGroup('dsdndskhsdks', 1)).to.be.true; - expect(isInControlGroup('3erfghyuijkm', 1)).to.be.true; - expect(isInControlGroup('', 1)).to.be.true; - expect(isInControlGroup(undefined, 1)).to.be.true; - }); - - it('Being in the control group must be consistant', function () { - const inControlGroup = isInControlGroup('dsdndskhsdks', 0.5); - expect(inControlGroup === isInControlGroup('dsdndskhsdks', 0.5)).to.be.true; - expect(inControlGroup === isInControlGroup('dsdndskhsdks', 0.5)).to.be.true; - expect(inControlGroup === isInControlGroup('dsdndskhsdks', 0.5)).to.be.true; - }); - - it('Control group ratio must be within a 10% error on a large sample', function () { - let nbInControlGroup = 0; - const sampleSize = 100; - for (let i = 0; i < sampleSize; i++) { - nbInControlGroup = nbInControlGroup + (isInControlGroup('R$*df' + i, 0.5) ? 1 : 0); - } - expect(nbInControlGroup).to.be.greaterThan(sampleSize / 2 - sampleSize / 10); - expect(nbInControlGroup).to.be.lessThan(sampleSize / 2 + sampleSize / 10); - }); - }); - - describe('Decode', function() { - it('should expose ID when A/B testing is off', function () { - testConfig.params.abTesting = { - enabled: false, - controlGroupPct: 0.5 - }; - - let decoded = id5IdSubmodule.decode(ID5_STORED_OBJ, testConfig); - expect(decoded).to.deep.equal(expectedDecodedObjectWithIdAbOff); - }); - - it('should expose ID when no one is in control group', function () { - testConfig.params.abTesting = { - enabled: true, - controlGroupPct: 0 - }; - - let decoded = id5IdSubmodule.decode(ID5_STORED_OBJ, testConfig); - expect(decoded).to.deep.equal(expectedDecodedObjectWithIdAbOn); - }); - - it('should not expose ID when everyone is in control group', function () { - testConfig.params.abTesting = { - enabled: true, - controlGroupPct: 1 - }; - - let decoded = id5IdSubmodule.decode(ID5_STORED_OBJ, testConfig); - expect(decoded).to.deep.equal(expectedDecodedObjectWithoutIdAbOn); - }); - }); - }); - }); -}); diff --git a/test/spec/modules/idImportLibrary_spec.js b/test/spec/modules/idImportLibrary_spec.js deleted file mode 100644 index 699c2c43a94..00000000000 --- a/test/spec/modules/idImportLibrary_spec.js +++ /dev/null @@ -1,61 +0,0 @@ -import * as utils from 'src/utils.js'; -import * as idImportlibrary from 'modules/idImportLibrary.js'; - -var expect = require('chai').expect; - -describe('currency', function () { - let fakeCurrencyFileServer; - let sandbox; - let clock; - - let fn = sinon.spy(); - - beforeEach(function () { - fakeCurrencyFileServer = sinon.fakeServer.create(); - sinon.stub(utils, 'logInfo'); - sinon.stub(utils, 'logError'); - }); - - afterEach(function () { - utils.logInfo.restore(); - utils.logError.restore(); - fakeCurrencyFileServer.restore(); - idImportlibrary.setConfig({}); - }); - - describe('setConfig', function () { - beforeEach(function() { - sandbox = sinon.sandbox.create(); - clock = sinon.useFakeTimers(1046952000000); // 2003-03-06T12:00:00Z - }); - - afterEach(function () { - sandbox.restore(); - clock.restore(); - }); - - it('results when no config available', function () { - idImportlibrary.setConfig({}); - sinon.assert.called(utils.logError); - }); - it('results with config available', function () { - idImportlibrary.setConfig({ 'url': 'URL' }); - sinon.assert.called(utils.logInfo); - }); - it('results with config default debounce ', function () { - let config = { 'url': 'URL' } - idImportlibrary.setConfig(config); - expect(config.debounce).to.be.equal(250); - }); - it('results with config default fullscan ', function () { - let config = { 'url': 'URL' } - idImportlibrary.setConfig(config); - expect(config.fullscan).to.be.equal(false); - }); - it('results with config fullscan ', function () { - let config = { 'url': 'URL', 'fullscan': true } - idImportlibrary.setConfig(config); - expect(config.fullscan).to.be.equal(true); - }); - }); -}); diff --git a/test/spec/modules/identityLinkIdSystem_spec.js b/test/spec/modules/identityLinkIdSystem_spec.js deleted file mode 100644 index a31270c86c7..00000000000 --- a/test/spec/modules/identityLinkIdSystem_spec.js +++ /dev/null @@ -1,168 +0,0 @@ -import {identityLinkSubmodule} from 'modules/identityLinkIdSystem.js'; -import * as utils from 'src/utils.js'; -import {server} from 'test/mocks/xhr.js'; -import {getStorageManager} from '../../../src/storageManager.js'; - -export const storage = getStorageManager(); - -const pid = '14'; -let defaultConfigParams; -const responseHeader = {'Content-Type': 'application/json'} - -describe('IdentityLinkId tests', function () { - let logErrorStub; - - beforeEach(function () { - 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'); - }); - - afterEach(function () { - defaultConfigParams = {}; - logErrorStub.restore(); - }); - - it('should log an error if no configParams were passed when getId', function () { - identityLinkSubmodule.getId({ params: {} }); - expect(logErrorStub.calledOnce).to.be.true; - }); - - it('should log an error if pid configParam was not passed when getId', function () { - identityLinkSubmodule.getId({ params: {} }); - expect(logErrorStub.calledOnce).to.be.true; - }); - - it('should call the LiveRamp envelope endpoint', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq('https://api.rlcdn.com/api/identity/envelope?pid=14'); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should NOT call the LiveRamp envelope endpoint if gdpr applies but consent string is empty string', function () { - let consentData = { - gdprApplies: true, - consentString: '' - }; - let submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams, consentData); - expect(submoduleCallback).to.be.undefined; - }); - - it('should NOT call the LiveRamp envelope endpoint if gdpr applies but consent string is missing', function () { - let consentData = { gdprApplies: true }; - let submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams, consentData); - expect(submoduleCallback).to.be.undefined; - }); - - it('should call the LiveRamp envelope endpoint with IAB consent string v1', function () { - let callBackSpy = sinon.spy(); - let consentData = { - gdprApplies: true, - consentString: 'BOkIpDSOkIpDSADABAENCc-AAAApOAFAAMAAsAMIAcAA_g' - }; - let submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams, consentData).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq('https://api.rlcdn.com/api/identity/envelope?pid=14&ct=1&cv=BOkIpDSOkIpDSADABAENCc-AAAApOAFAAMAAsAMIAcAA_g'); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should call the LiveRamp envelope endpoint with IAB consent string v2', function () { - let callBackSpy = sinon.spy(); - let consentData = { - gdprApplies: true, - consentString: 'CO4VThZO4VTiuADABBENAzCgAP_AAEOAAAAAAwwAgAEABhAAgAgAAA.YAAAAAAAAAA', - vendorData: { - tcfPolicyVersion: 2 - } - }; - let submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams, consentData).callback; - submoduleCallback(callBackSpy); - let 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'); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should not throw Uncaught TypeError when envelope endpoint returns empty response', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq('https://api.rlcdn.com/api/identity/envelope?pid=14'); - request.respond( - 204, - responseHeader, - '' - ); - expect(callBackSpy.calledOnce).to.be.true; - expect(request.response).to.equal(''); - expect(logErrorStub.calledOnce).to.not.be.true; - }); - - it('should log an error and continue to callback if ajax request errors', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq('https://api.rlcdn.com/api/identity/envelope?pid=14'); - request.respond( - 503, - responseHeader, - 'Unavailable' - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should not call the LiveRamp envelope endpoint if cookie _lr_retry_request exist', function () { - let now = new Date(); - now.setTime(now.getTime() + 3000); - storage.setCookie('_lr_retry_request', 'true', now.toUTCString()); - let callBackSpy = sinon.spy(); - let submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request).to.be.eq(undefined); - }); - - it('should call the LiveRamp envelope endpoint if cookie _lr_retry_request does not exist and notUse3P config property was not set', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.be.eq('https://api.rlcdn.com/api/identity/envelope?pid=14'); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should not call the LiveRamp envelope endpoint if config property notUse3P is set to true', function () { - defaultConfigParams.params.notUse3P = true; - let callBackSpy = sinon.spy(); - let submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request).to.be.eq(undefined); - }); -}); diff --git a/test/spec/modules/idxIdSystem_spec.js b/test/spec/modules/idxIdSystem_spec.js deleted file mode 100644 index 14cd9a88d13..00000000000 --- a/test/spec/modules/idxIdSystem_spec.js +++ /dev/null @@ -1,117 +0,0 @@ -import { expect } from 'chai'; -import find from 'core-js-pure/features/array/find.js'; -import { config } from 'src/config.js'; -import { init, requestBidsHook, setSubmoduleRegistry } from 'modules/userId/index.js'; -import { storage, idxIdSubmodule } from 'modules/idxIdSystem.js'; - -const IDX_COOKIE_NAME = '_idx'; -const IDX_DUMMY_VALUE = 'idx value for testing'; -const IDX_COOKIE_STORED = '{ "idx": "' + IDX_DUMMY_VALUE + '" }'; -const ID_COOKIE_OBJECT = { id: IDX_DUMMY_VALUE }; -const IDX_COOKIE_OBJECT = { idx: IDX_DUMMY_VALUE }; - -function getConfigMock() { - return { - userSync: { - syncDelay: 0, - userIds: [{ - name: 'idx' - }] - } - } -} - -function getAdUnitMock(code = 'adUnit-code') { - return { - code, - mediaTypes: {banner: {}, native: {}}, - sizes: [ - [300, 200], - [300, 600] - ], - bids: [{ - bidder: 'sampleBidder', - params: { placementId: 'banner-only-bidder' } - }] - }; -} - -describe('IDx ID System', () => { - let getDataFromLocalStorageStub, localStorageIsEnabledStub; - let getCookieStub, cookiesAreEnabledStub; - - beforeEach(() => { - getDataFromLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage'); - localStorageIsEnabledStub = sinon.stub(storage, 'localStorageIsEnabled'); - getCookieStub = sinon.stub(storage, 'getCookie'); - cookiesAreEnabledStub = sinon.stub(storage, 'cookiesAreEnabled'); - }); - - afterEach(() => { - getDataFromLocalStorageStub.restore(); - localStorageIsEnabledStub.restore(); - getCookieStub.restore(); - cookiesAreEnabledStub.restore(); - }); - - describe('IDx: test "getId" method', () => { - it('provides the stored IDx if a cookie exists', () => { - getCookieStub.withArgs(IDX_COOKIE_NAME).returns(IDX_COOKIE_STORED); - let idx = idxIdSubmodule.getId(); - expect(idx).to.deep.equal(ID_COOKIE_OBJECT); - }); - - it('provides the stored IDx if cookie is absent but present in local storage', () => { - getDataFromLocalStorageStub.withArgs(IDX_COOKIE_NAME).returns(IDX_COOKIE_STORED); - let idx = idxIdSubmodule.getId(); - expect(idx).to.deep.equal(ID_COOKIE_OBJECT); - }); - - it('returns undefined if both cookie and local storage are empty', () => { - let idx = idxIdSubmodule.getId(); - expect(idx).to.be.undefined; - }) - }); - - describe('IDx: test "decode" method', () => { - it('provides the IDx from a stored object', () => { - expect(idxIdSubmodule.decode(ID_COOKIE_OBJECT)).to.deep.equal(IDX_COOKIE_OBJECT); - }); - - it('provides the IDx from a stored string', () => { - expect(idxIdSubmodule.decode(IDX_DUMMY_VALUE)).to.deep.equal(IDX_COOKIE_OBJECT); - }); - }); - - describe('requestBids hook', () => { - let adUnits; - - beforeEach(() => { - adUnits = [getAdUnitMock()]; - setSubmoduleRegistry([idxIdSubmodule]); - init(config); - config.setConfig(getConfigMock()); - getCookieStub.withArgs(IDX_COOKIE_NAME).returns(IDX_COOKIE_STORED); - }); - - it('when a stored IDx exists it is added to bids', (done) => { - requestBidsHook(() => { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.idx'); - expect(bid.userId.idx).to.equal(IDX_DUMMY_VALUE); - const idxIdAsEid = find(bid.userIdAsEids, e => e.source == 'idx.lat'); - expect(idxIdAsEid).to.deep.equal({ - source: 'idx.lat', - uids: [{ - id: IDX_DUMMY_VALUE, - atype: 1, - }] - }); - }); - }); - done(); - }, { adUnits }); - }); - }); -}); diff --git a/test/spec/modules/imonomyBidAdapter_spec.js b/test/spec/modules/imonomyBidAdapter_spec.js deleted file mode 100644 index 45b3bed6e77..00000000000 --- a/test/spec/modules/imonomyBidAdapter_spec.js +++ /dev/null @@ -1,164 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/imonomyBidAdapter.js'; - -describe('Imonomy Adapter Tests', function () { - const bidsRequest = [ - { - bidder: 'imonomy', - params: { - placementId: '170577', - hbid: '14567718624', - }, - placementCode: 'div-gpt-ad-1460505748561-0', - transactionId: '9f801c02-bbe8-4683-8ed4-bc816ea186bb', - sizes: [ - [300, 250] - ], - bidId: '2faedf1095f815', - bidderRequestId: '18065867f8ae39', - auctionId: '529e1518-b872-45cf-807c-2d41dfa5bcd3' - }, - { - bidder: 'imonomy', - params: { - placementId: '281277', - hbid: '14567718624', - floorPrice: 0.5 - }, - placementCode: 'div-gpt-ad-1460505748561-0', - transactionId: '9f801c02-bbe8-4683-8ed4-bc816ea186bb', - sizes: [ - [728, 90] - ], - bidId: '3c34e2367a3f59', - bidderRequestId: '18065867f8ae39', - auctionId: '529e1518-b872-45cf-807c-2d41dfa5bcd3' - }]; - - const bidsResponse = { - body: { - bids: [ - { - placementid: '170577', - uuid: '2faedf1095f815', - width: 300, - height: 250, - cpm: 0.51, - creative: '', - ttl: 360, - currency: 'USD', - netRevenue: true, - creativeId: 'd30b58c2ba' - } - ] - } - }; - - it('Verifies imonomyAdapter bidder code', function () { - expect(spec.code).to.equal('imonomy'); - }); - - it('Verifies imonomyAdapter bid request validation', function () { - expect(spec.isBidRequestValid(bidsRequest[0])).to.equal(true); - expect(spec.isBidRequestValid(bidsRequest[1])).to.equal(true); - expect(spec.isBidRequestValid({})).to.equal(false); - expect(spec.isBidRequestValid({ params: {} })).to.equal(false); - expect(spec.isBidRequestValid({ params: { hbid: 12345 } })).to.equal(false); - expect(spec.isBidRequestValid({ params: { placementid: 12345 } })).to.equal(false); - expect(spec.isBidRequestValid({ params: { hbid: 12345, placementId: 67890 } })).to.equal(true); - expect(spec.isBidRequestValid({ params: { hbid: 12345, placementId: 67890, floorPrice: 0.8 } })).to.equal(true); - }); - - it('Verify imonomyAdapter build request', function () { - var startTime = new Date().getTime(); - - const request = spec.buildRequests(bidsRequest); - expect(request.url).to.equal('https://b.imonomy.com/openrtb/hb/14567718624'); - expect(request.method).to.equal('POST'); - const requestData = JSON.parse(request.data); - - // bids object - let bids = requestData.bids; - expect(bids).to.have.lengthOf(2); - - // first bid request: no floor price - expect(bids[0].uuid).to.equal('2faedf1095f815'); - expect(bids[0].floorprice).to.be.undefined; - expect(bids[0].placementid).to.equal('170577'); - expect(bids[0].hbid).to.equal('14567718624'); - expect(bids[0].trid).to.equal('9f801c02-bbe8-4683-8ed4-bc816ea186bb'); - expect(bids[0].sizes).to.have.lengthOf(1); - expect(bids[0].sizes[0][0]).to.equal(300); - expect(bids[0].sizes[0][1]).to.equal(250); - - // second bid request: with floor price - expect(bids[1].uuid).to.equal('3c34e2367a3f59'); - expect(bids[1].floorprice).to.equal(0.5); - expect(bids[1].placementid).to.equal('281277'); - expect(bids[1].hbid).to.equal('14567718624'); - expect(bids[1].trid).to.equal('9f801c02-bbe8-4683-8ed4-bc816ea186bb'); - expect(bids[1]).to.have.property('sizes') - .that.is.an('array') - .of.length(1) - .that.deep.equals([[728, 90]]); - - // kbConf object - let kbConf = requestData.kbConf; - expect(kbConf.hdbdid).to.equal(bids[0].hbid); - expect(kbConf.hdbdid).to.equal(bids[1].hbid); - expect(kbConf.encode_bid).to.be.undefined; - // kbConf timezone and cb - expect(kbConf.cb).not.to.be.undefined; - expect(kbConf.ts_as).to.be.above(startTime - 1); - expect(kbConf.tz).to.equal(new Date().getTimezoneOffset()); - // kbConf bid ids - expect(kbConf.hb_placement_bidids) - .to.have.property(bids[0].placementid) - .that.equal(bids[0].uuid); - expect(kbConf.hb_placement_bidids) - .to.have.property(bids[1].placementid) - .that.equal(bids[1].uuid); - // kbConf floor price - expect(kbConf.hb_floors).not.to.have.property(bids[0].placementid) - expect(kbConf.hb_floors).to.have.property(bids[1].placementid).that.equal(bids[1].floorprice); - // kbConf placement ids - expect(kbConf.hb_placements).to.have.lengthOf(2); - expect(kbConf.hb_placements[0]).to.equal(bids[0].placementid); - expect(kbConf.hb_placements[1]).to.equal(bids[1].placementid); - }); - - it('Verify imonomyAdapter build response', function () { - const request = spec.buildRequests(bidsRequest); - const bids = spec.interpretResponse(bidsResponse, request); - - // 'server' return single bid - expect(bids).to.have.lengthOf(1); - - // verify bid object - const bid = bids[0]; - const responseBids = bidsResponse.body.bids; - - expect(bid.cpm).to.equal(responseBids[0].cpm); - expect(bid.ad).to.equal(responseBids[0].creative); - expect(bid.requestId).equal(responseBids[0].uuid); - expect(bid.uuid).equal(responseBids[0].uuid); - expect(bid.width).to.equal(responseBids[0].width); - expect(bid.height).to.equal(responseBids[0].height); - expect(bid.ttl).to.equal(responseBids[0].ttl); - expect(bid.currency).to.equal('USD'); - expect(bid.netRevenue).to.equal(true); - expect(bid.creativeId).to.equal(responseBids[0].creativeId); - }); - - it('Verifies imonomyAdapter sync options', function () { - // user sync disabled - expect(spec.getUserSyncs({})).to.be.undefined; - expect(spec.getUserSyncs({ iframeEnabled: false })).to.be.undefined; - // user sync enabled - const options = spec.getUserSyncs({ iframeEnabled: true }); - expect(options).to.not.be.undefined; - expect(options).to.have.lengthOf(1); - expect(options[0].type).to.equal('iframe'); - expect(options[0].url).to.equal('https://b.imonomy.com/UserMatching/b/'); - }); -}); diff --git a/test/spec/modules/impactifyBidAdapter_spec.js b/test/spec/modules/impactifyBidAdapter_spec.js deleted file mode 100644 index d14cea8cad3..00000000000 --- a/test/spec/modules/impactifyBidAdapter_spec.js +++ /dev/null @@ -1,398 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/impactifyBidAdapter.js'; -import * as utils from 'src/utils.js'; - -const BIDDER_CODE = 'impactify'; -const BIDDER_ALIAS = ['imp']; -const DEFAULT_CURRENCY = 'USD'; -const DEFAULT_VIDEO_WIDTH = 640; -const DEFAULT_VIDEO_HEIGHT = 480; -const ORIGIN = 'https://sonic.impactify.media'; -const LOGGER_URI = 'https://logger.impactify.media'; -const AUCTIONURI = '/bidder'; -const COOKIESYNCURI = '/static/cookie_sync.html'; -const GVLID = 606; - -var gdprData = { - 'consentString': 'BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA', - 'gdprApplies': true -}; - -describe('ImpactifyAdapter', function () { - describe('isBidRequestValid', function () { - let validBid = { - bidder: 'impactify', - params: { - appId: '1', - format: 'screen', - style: 'inline' - } - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(validBid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, validBid); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when appId is missing', () => { - const bid = utils.deepClone(validBid); - delete bid.params.appId; - - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when appId is not a string', () => { - const bid = utils.deepClone(validBid); - - bid.params.appId = 123; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.appId = false; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.appId = void (0); - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.appId = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when format is missing', () => { - const bid = utils.deepClone(validBid); - delete bid.params.format; - - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when format is not a string', () => { - const bid = utils.deepClone(validBid); - - bid.params.format = 123; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.format = false; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.format = void (0); - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.format = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when format is not equals to screen or display', () => { - const bid = utils.deepClone(validBid); - if (bid.params.format != 'screen' && bid.params.format != 'display') { - expect(spec.isBidRequestValid(bid)).to.equal(false); - } - }); - - it('should return false when style is missing', () => { - const bid = utils.deepClone(validBid); - delete bid.params.style; - - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when style is not a string', () => { - const bid = utils.deepClone(validBid); - - bid.params.style = 123; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.style = false; - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.style = void (0); - expect(spec.isBidRequestValid(bid)).to.equal(false); - - bid.params.style = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - describe('buildRequests', function () { - let videoBidRequests = [ - { - bidder: 'impactify', - params: { - appId: '1', - format: 'screen', - style: 'inline' - }, - mediaTypes: { - video: { - context: 'instream' - } - }, - adUnitCode: 'adunit-code', - sizes: [[DEFAULT_VIDEO_WIDTH, DEFAULT_VIDEO_HEIGHT]], - bidId: '123456789', - bidderRequestId: '987654321', - auctionId: '19ab94a9-b0d7-4ed7-9f80-ad0c033cf1b1', - transactionId: 'f7b2c372-7a7b-11eb-9439-0242ac130002' - } - ]; - let videoBidderRequest = { - bidderRequestId: '98845765110', - auctionId: '165410516454', - bidderCode: 'impactify', - bids: [ - { - ...videoBidRequests[0] - } - ], - refererInfo: { - referer: 'https://impactify.io' - } - }; - - it('sends video bid request to ENDPOINT via POST', function () { - const request = spec.buildRequests(videoBidRequests, videoBidderRequest); - expect(request.url).to.equal(ORIGIN + AUCTIONURI); - expect(request.method).to.equal('POST'); - }); - }); - describe('interpretResponse', function () { - it('should get correct bid response', function () { - let response = { - id: '19ab94a9-b0d7-4ed7-9f80-ad0c033cf1b1', - seatbid: [ - { - bid: [ - { - id: '65820304700829014', - impid: '462c08f20d428', - price: 3.40, - adm: '', - adid: '97517771', - adomain: [ - '' - ], - iurl: 'https://fra1-ib.adnxs.com/cr?id=97517771', - cid: '9325', - crid: '97517771', - w: 1, - h: 1, - ext: { - prebid: { - 'type': 'video' - }, - bidder: { - prebid: { - type: 'video', - video: { - duration: 30, - primary_category: '' - } - }, - bidder: { - appnexus: { - brand_id: 182979, - auction_id: 8657683934873599656, - bidder_id: 2, - bid_ad_type: 1, - creative_info: { - video: { - duration: 30, - mimes: [ - 'video/x-flv', - 'video/mp4', - 'video/webm' - ] - } - } - } - } - } - } - } - ], - seat: 'impactify' - } - ], - cur: DEFAULT_CURRENCY, - ext: { - responsetimemillis: { - impactify: 114 - }, - prebid: { - auctiontimestamp: 1614587024591 - } - } - }; - let bidderRequest = { - bids: [ - { - bidId: '462c08f20d428', - adUnitCode: '/19968336/header-bid-tag-1', - auctionId: '19ab94a9-b0d7-4ed7-9f80-ad0c033cf1b1', - bidder: 'impactify', - sizes: [[DEFAULT_VIDEO_WIDTH, DEFAULT_VIDEO_HEIGHT]], - mediaTypes: { - video: { - context: 'outstream' - } - } - }, - ] - } - let expectedResponse = [ - { - id: '65820304700829014', - requestId: '462c08f20d428', - cpm: 3.40, - currency: DEFAULT_CURRENCY, - netRevenue: true, - ad: '', - width: 1, - height: 1, - hash: 'test', - expiry: 166192938, - ttl: 300, - creativeId: '97517771' - } - ]; - let result = spec.interpretResponse({ body: response }, bidderRequest); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - }); - describe('getUserSyncs', function () { - let videoBidRequests = [ - { - bidder: 'impactify', - params: { - appId: '1', - format: 'screen', - style: 'inline' - }, - mediaTypes: { - video: { - context: 'instream' - } - }, - adUnitCode: 'adunit-code', - sizes: [[DEFAULT_VIDEO_WIDTH, DEFAULT_VIDEO_HEIGHT]], - bidId: '123456789', - bidderRequestId: '987654321', - auctionId: '19ab94a9-b0d7-4ed7-9f80-ad0c033cf1b1', - transactionId: 'f7b2c372-7a7b-11eb-9439-0242ac130002' - } - ]; - let videoBidderRequest = { - bidderRequestId: '98845765110', - auctionId: '165410516454', - bidderCode: 'impactify', - bids: [ - { - ...videoBidRequests[0] - } - ], - refererInfo: { - referer: 'https://impactify.io' - } - }; - let validResponse = { - id: '19ab94a9-b0d7-4ed7-9f80-ad0c033cf1b1', - seatbid: [ - { - bid: [ - { - id: '65820304700829014', - impid: '462c08f20d428', - price: 3.40, - adm: '', - adid: '97517771', - adomain: [ - '' - ], - iurl: 'https://fra1-ib.adnxs.com/cr?id=97517771', - cid: '9325', - crid: '97517771', - w: 1, - h: 1, - ext: { - prebid: { - 'type': 'video' - }, - bidder: { - prebid: { - type: 'video', - video: { - duration: 30, - primary_category: '' - } - }, - bidder: { - appnexus: { - brand_id: 182979, - auction_id: 8657683934873599656, - bidder_id: 2, - bid_ad_type: 1, - creative_info: { - video: { - duration: 30, - mimes: [ - 'video/x-flv', - 'video/mp4', - 'video/webm' - ] - } - } - } - } - } - } - } - ], - seat: 'impactify' - } - ], - cur: DEFAULT_CURRENCY, - ext: { - responsetimemillis: { - impactify: 114 - }, - prebid: { - auctiontimestamp: 1614587024591 - } - } - }; - it('should return empty response if server response is false', function () { - const result = spec.getUserSyncs('bad', false, gdprData); - expect(result).to.be.empty; - }); - it('should return empty response if server response is empty', function () { - const result = spec.getUserSyncs('bad', [], gdprData); - expect(result).to.be.empty; - }); - it('should append the various values if they exist', function() { - const result = spec.getUserSyncs({iframeEnabled: true}, validResponse, gdprData); - expect(result[0].url).to.include('gdpr=1'); - expect(result[0].url).to.include('gdpr_consent=BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA'); - }); - }); - - describe('On winning bid', function () { - const bid = { - ad: '', - cpm: '2' - }; - const result = spec.onBidWon(bid); - assert.ok(result); - }); - - describe('On bid Time out', function () { - const bid = { - ad: '', - cpm: '2' - }; - const result = spec.onTimeout(bid); - assert.ok(result); - }); -}) diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js deleted file mode 100644 index f34a75ef8f3..00000000000 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ /dev/null @@ -1,1016 +0,0 @@ -import { expect } from 'chai'; -import { ImproveDigitalAdServerJSClient, spec } from 'modules/improvedigitalBidAdapter.js'; -import { config } from 'src/config.js'; -import * as utils from 'src/utils.js'; - -describe('Improve Digital Adapter Tests', function () { - const idClient = new ImproveDigitalAdServerJSClient('hb'); - - const METHOD = 'GET'; - const URL = 'https://ice.360yield.com/hb'; - const PARAM_PREFIX = 'jsonp='; - - const simpleBidRequest = { - bidder: 'improvedigital', - params: { - placementId: 1053688 - }, - adUnitCode: 'div-gpt-ad-1499748733608-0', - transactionId: 'f183e871-fbed-45f0-a427-c8a63c4c01eb', - bidId: '33e9500b21129f', - bidderRequestId: '2772c1e566670b', - auctionId: '192721e36a0239', - mediaTypes: { - banner: { - sizes: [[300, 250], [160, 600], ['blah', 150], [-1, 300], [300, -5]] - } - }, - sizes: [[300, 250], [160, 600], ['blah', 150], [-1, 300], [300, -5]] - }; - - const videoParams = { - skip: 1, - skipmin: 5, - skipafter: 30 - } - - const instreamBidRequest = utils.deepClone(simpleBidRequest); - instreamBidRequest.mediaTypes = { - video: { - context: 'instream', - playerSize: [640, 480] - } - }; - - const outstreamBidRequest = utils.deepClone(simpleBidRequest); - outstreamBidRequest.mediaTypes = { - video: { - context: 'outstream', - playerSize: [640, 480] - } - }; - - const multiFormatBidRequest = utils.deepClone(simpleBidRequest); - multiFormatBidRequest.mediaTypes = { - banner: { - sizes: [[300, 250], [160, 600], ['blah', 150], [-1, 300], [300, -5]] - }, - video: { - context: 'outstream', - playerSize: [640, 480] - } - }; - - const simpleSmartTagBidRequest = { - bidder: 'improvedigital', - bidId: '1a2b3c', - placementCode: 'placement1', - params: { - publisherId: 1032, - placementKey: 'data_team_test_hb_smoke_test' - } - }; - - const bidderRequest = { - bids: [simpleBidRequest] - }; - - const instreamBidderRequest = { - bids: [instreamBidRequest] - }; - - const outstreamBidderRequest = { - bids: [outstreamBidRequest] - }; - - const multiFormatBidderRequest = { - bids: [multiFormatBidRequest] - }; - - const bidderRequestGdpr = { - bids: [simpleBidRequest], - gdprConsent: { - consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', - vendorData: {}, - gdprApplies: true - }, - }; - - const bidderRequestReferrer = { - bids: [simpleBidRequest], - refererInfo: { - referer: 'https://blah.com/test.html', - }, - }; - - describe('isBidRequestValid', function () { - it('should return false when no bid', function () { - expect(spec.isBidRequestValid()).to.equal(false); - }); - - it('should return false when no bid.params', function () { - const bid = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when both placementId and placementKey + publisherId are missing', function () { - const bid = { 'params': {} }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when only one of placementKey and publisherId is present', function () { - let bid = { - params: { - publisherId: 1234 - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - bid = { - params: { - placementKey: 'xyz' - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return true when placementId is passed', function () { - expect(spec.isBidRequestValid(simpleBidRequest)).to.equal(true); - }); - - it('should return true when both placementKey and publisherId are passed', function () { - expect(spec.isBidRequestValid(simpleSmartTagBidRequest)).to.equal(true); - }); - }); - - describe('buildRequests', function () { - it('should make a well-formed request objects', function () { - const requests = spec.buildRequests([simpleBidRequest], bidderRequest); - expect(requests).to.be.an('array'); - expect(requests.length).to.equal(1); - - const request = requests[0]; - expect(request.method).to.equal(METHOD); - expect(request.url).to.equal(URL); - expect(request.bidderRequest).to.deep.equal(bidderRequest); - expect(request.data.substring(0, PARAM_PREFIX.length)).to.equal(PARAM_PREFIX); - - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request).to.be.an('object'); - expect(params.bid_request.id).to.be.a('string'); - expect(params.bid_request.version).to.equal(`${spec.version}-${idClient.CONSTANTS.CLIENT_VERSION}`); - expect(params.bid_request.gdpr).to.not.exist; - expect(params.bid_request.us_privacy).to.not.exist; - expect(params.bid_request.schain).to.not.exist; - expect(params.bid_request.user).to.not.exist; - expect(params.bid_request.imp).to.deep.equal([ - { - id: '33e9500b21129f', - pid: 1053688, - tid: 'f183e871-fbed-45f0-a427-c8a63c4c01eb', - banner: {} - } - ]); - }); - - it('should make a well-formed request object for multi-format ad unit', function () { - const requests = spec.buildRequests([multiFormatBidRequest], multiFormatBidderRequest); - expect(requests).to.be.an('array'); - expect(requests.length).to.equal(1); - - const request = requests[0]; - expect(request.method).to.equal(METHOD); - expect(request.url).to.equal(URL); - expect(request.bidderRequest).to.deep.equal(multiFormatBidderRequest); - expect(request.data.substring(0, PARAM_PREFIX.length)).to.equal(PARAM_PREFIX); - - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request).to.be.an('object'); - expect(params.bid_request.id).to.be.a('string'); - expect(params.bid_request.version).to.equal(`${spec.version}-${idClient.CONSTANTS.CLIENT_VERSION}`); - expect(params.bid_request.gdpr).to.not.exist; - expect(params.bid_request.us_privacy).to.not.exist; - expect(params.bid_request.imp).to.deep.equal([ - { - id: '33e9500b21129f', - pid: 1053688, - tid: 'f183e871-fbed-45f0-a427-c8a63c4c01eb', - banner: {} - } - ]); - }); - - it('should set placementKey and publisherId for smart tags', function () { - const requests = spec.buildRequests([simpleSmartTagBidRequest], bidderRequest); - const params = JSON.parse(decodeURIComponent(requests[0].data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].pubid).to.equal(1032); - expect(params.bid_request.imp[0].pkey).to.equal('data_team_test_hb_smoke_test'); - }); - - it('should add keyValues', function () { - const bidRequest = Object.assign({}, simpleBidRequest); - const keyValues = { - testKey: [ - 'testValue' - ] - }; - bidRequest.params.keyValues = keyValues; - const request = spec.buildRequests([bidRequest], bidderRequest)[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].kvw).to.deep.equal(keyValues); - }); - - it('should add single size filter', function () { - const bidRequest = Object.assign({}, simpleBidRequest); - const size = { - w: 800, - h: 600 - }; - bidRequest.params.size = size; - const request = spec.buildRequests([bidRequest], bidderRequest)[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].banner).to.deep.equal(size); - // When single size filter is set, format shouldn't be populated. This - // is to maintain backward compatibily - expect(params.bid_request.imp[0].banner.format).to.not.exist; - }); - - it('should add currency', function () { - const bidRequest = Object.assign({}, simpleBidRequest); - const getConfigStub = sinon.stub(config, 'getConfig').returns('JPY'); - const request = spec.buildRequests([bidRequest], bidderRequest)[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].currency).to.equal('JPY'); - getConfigStub.restore(); - }); - - it('should add bid floor', function () { - const bidRequest = Object.assign({}, simpleBidRequest); - let request = spec.buildRequests([bidRequest], bidderRequest)[0]; - let params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - // Floor price currency shouldn't be populated without a floor price - expect(params.bid_request.imp[0].bidfloorcur).to.not.exist; - - // Default floor price currency - bidRequest.params.bidFloor = 0.05; - request = spec.buildRequests([bidRequest], bidderRequest)[0]; - params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].bidfloor).to.equal(0.05); - expect(params.bid_request.imp[0].bidfloorcur).to.equal('USD'); - - // Floor price currency - bidRequest.params.bidFloorCur = 'eUR'; - request = spec.buildRequests([bidRequest])[0]; - params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].bidfloor).to.equal(0.05); - expect(params.bid_request.imp[0].bidfloorcur).to.equal('EUR'); - }); - - it('should add GDPR consent string', function () { - const bidRequest = Object.assign({}, simpleBidRequest); - const request = spec.buildRequests([bidRequest], bidderRequestGdpr)[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.gdpr).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A=='); - }); - - it('should add CCPA consent string', function () { - const bidRequest = Object.assign({}, simpleBidRequest); - const request = spec.buildRequests([bidRequest], { uspConsent: '1YYY' })[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.us_privacy).to.equal('1YYY'); - }); - - it('should add referrer', function () { - const bidRequest = Object.assign({}, simpleBidRequest); - const request = spec.buildRequests([bidRequest], bidderRequestReferrer)[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.referrer).to.equal('https://blah.com/test.html'); - }); - - it('should not add video params for banner', function () { - const bidRequest = JSON.parse(JSON.stringify(simpleBidRequest)); - bidRequest.params.video = videoParams; - const request = spec.buildRequests([bidRequest], bidderRequest)[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].video).to.not.exist; - }); - - it('should add ad type for instream video', function () { - let bidRequest = JSON.parse(JSON.stringify(simpleBidRequest)); - bidRequest.mediaType = 'video'; - let request = spec.buildRequests([bidRequest], bidderRequest)[0]; - let params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].ad_types).to.deep.equal(['video']); - expect(params.bid_request.imp[0].video).to.not.exist; - - bidRequest = JSON.parse(JSON.stringify(simpleBidRequest)); - bidRequest.mediaTypes = { - video: { - context: 'instream', - playerSize: [640, 480] - } - }; - request = spec.buildRequests([bidRequest], bidderRequest)[0]; - params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].ad_types).to.deep.equal(['video']); - expect(params.bid_request.imp[0].video).to.not.exist; - }); - - it('should not set ad type for outstream video', function() { - const request = spec.buildRequests([outstreamBidRequest])[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].ad_types).to.not.exist; - expect(params.bid_request.imp[0].video).to.not.exist; - }); - - it('should not set ad type for multi-format bids', function() { - const request = spec.buildRequests([multiFormatBidRequest], bidderRequest)[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].ad_types).to.not.exist; - expect(params.bid_request.imp[0].video).to.not.exist; - }); - - it('should set video params for instream', function() { - const bidRequest = JSON.parse(JSON.stringify(instreamBidRequest)); - bidRequest.params.video = videoParams; - const request = spec.buildRequests([bidRequest])[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].video).to.deep.equal(videoParams); - }); - - it('should set skip params only if skip=1', function() { - const bidRequest = JSON.parse(JSON.stringify(instreamBidRequest)); - // 1 - const videoTest = { - skip: 1, - skipmin: 5, - skipafter: 30 - } - bidRequest.params.video = videoTest; - let request = spec.buildRequests([bidRequest])[0]; - let params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].video).to.deep.equal(videoTest); - - // 0 - leave out skipmin and skipafter - videoTest.skip = 0; - bidRequest.params.video = videoTest; - request = spec.buildRequests([bidRequest])[0]; - params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].video).to.deep.equal({ skip: 0 }); - - // other - videoTest.skip = 'blah'; - bidRequest.params.video = videoTest; - request = spec.buildRequests([bidRequest])[0]; - params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].video).to.not.exist; - }); - - it('should ignore invalid/unexpected video params', function() { - const bidRequest = JSON.parse(JSON.stringify(instreamBidRequest)); - // 1 - const videoTest = { - skip: 1, - skipmin: 5, - skipafter: 30 - } - const videoTestInvParam = Object.assign({}, videoTest); - videoTestInvParam.blah = 1; - bidRequest.params.video = videoTestInvParam; - let request = spec.buildRequests([bidRequest])[0]; - let params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].video).to.deep.equal(videoTest); - }); - - it('should set video params for outstream', function() { - const bidRequest = JSON.parse(JSON.stringify(outstreamBidRequest)); - bidRequest.params.video = videoParams; - const request = spec.buildRequests([bidRequest])[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].video).to.deep.equal(videoParams); - }); - - it('should set video params for multi-format', function() { - const bidRequest = JSON.parse(JSON.stringify(multiFormatBidRequest)); - bidRequest.params.video = videoParams; - const request = spec.buildRequests([bidRequest])[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].video).to.deep.equal(videoParams); - }); - - it('should not set Prebid sizes in bid request for instream video', function () { - const getConfigStub = sinon.stub(config, 'getConfig'); - getConfigStub.withArgs('improvedigital.usePrebidSizes').returns(true); - const request = spec.buildRequests([instreamBidRequest], bidderRequest)[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].banner.format).to.not.exist; - getConfigStub.restore(); - }); - - it('should not set Prebid sizes in bid request for outstream video', function () { - const getConfigStub = sinon.stub(config, 'getConfig'); - getConfigStub.withArgs('improvedigital.usePrebidSizes').returns(true); - const request = spec.buildRequests([outstreamBidRequest], bidderRequest)[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].banner.format).to.not.exist; - getConfigStub.restore(); - }); - - it('should not set Prebid sizes in multi-format bid request', function () { - const getConfigStub = sinon.stub(config, 'getConfig'); - getConfigStub.withArgs('improvedigital.usePrebidSizes').returns(true); - const request = spec.buildRequests([multiFormatBidRequest], bidderRequest)[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].banner.format).to.not.exist; - getConfigStub.restore(); - }); - - it('should add schain', function () { - const schain = '{"ver":"1.0","complete":1,"nodes":[{"asi":"headerlift.com","sid":"xyz","hp":1}]}'; - const bidRequest = Object.assign({}, simpleBidRequest); - bidRequest.schain = schain; - const request = spec.buildRequests([bidRequest], bidderRequestReferrer)[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.schain).to.equal(schain); - }); - - it('should add eids', function () { - const userId = { id5id: { uid: '1111' } }; - const expectedUserObject = { ext: { eids: [{ - source: 'id5-sync.com', - uids: [{ - atype: 1, - id: '1111' - }] - }]}}; - const bidRequest = Object.assign({}, simpleBidRequest); - bidRequest.userId = userId; - const request = spec.buildRequests([bidRequest], bidderRequestReferrer)[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.user).to.deep.equal(expectedUserObject); - }); - - it('should return 2 requests', function () { - const requests = spec.buildRequests([ - simpleBidRequest, - simpleSmartTagBidRequest - ], bidderRequest); - expect(requests).to.be.an('array'); - expect(requests.length).to.equal(2); - expect(requests[0].bidderRequest).to.deep.equal(bidderRequest); - expect(requests[1].bidderRequest).to.deep.equal(bidderRequest); - }); - - it('should return one request in a single request mode', function () { - const getConfigStub = sinon.stub(config, 'getConfig'); - getConfigStub.withArgs('improvedigital.singleRequest').returns(true); - const requests = spec.buildRequests([ - simpleBidRequest, - simpleSmartTagBidRequest - ], bidderRequest); - expect(requests).to.be.an('array'); - expect(requests.length).to.equal(1); - getConfigStub.restore(); - }); - - it('should set Prebid sizes in bid request', function () { - const getConfigStub = sinon.stub(config, 'getConfig'); - getConfigStub.withArgs('improvedigital.usePrebidSizes').returns(true); - const request = spec.buildRequests([simpleBidRequest], bidderRequest)[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].banner).to.deep.equal({ - format: [ - { w: 300, h: 250 }, - { w: 160, h: 600 } - ] - }); - getConfigStub.restore(); - }); - - it('should not add single size filter when using Prebid sizes', function () { - const getConfigStub = sinon.stub(config, 'getConfig'); - getConfigStub.withArgs('improvedigital.usePrebidSizes').returns(true); - const bidRequest = Object.assign({}, simpleBidRequest); - const size = { - w: 800, - h: 600 - }; - bidRequest.params.size = size; - const request = spec.buildRequests([bidRequest], bidderRequest)[0]; - const params = JSON.parse(decodeURIComponent(request.data.substring(PARAM_PREFIX.length))); - expect(params.bid_request.imp[0].banner).to.deep.equal({ - format: [ - { w: 300, h: 250 }, - { w: 160, h: 600 } - ] - }); - getConfigStub.restore(); - }); - }); - - const serverResponse = { - 'body': { - 'id': '687a06c541d8d1', - 'site_id': 191642, - 'bid': [ - { - 'isNet': false, - 'id': '33e9500b21129f', - 'advid': '5279', - 'price': 1.45888594164456, - 'nurl': 'https://ice.360yield.com/imp_pixel?ic=wVmhKI07hCVyGC1sNdFp.6buOSiGYOw8jPyZLlcMY2RCwD4ek3Fy6.xUI7U002skGBs3objMBoNU-Frpvmb9js3NKIG0YZJgWaNdcpXY9gOXE9hY4-wxybCjVSNzhOQB-zic73hzcnJnKeoGgcfvt8fMy18-yD0aVdYWt4zbqdoITOkKNCPBEgbPFu1rcje-o7a64yZ7H3dKvtnIixXQYc1Ep86xGSBGXY6xW2KfUOMT6vnkemxO72divMkMdhR8cAuqIubbx-ZID8-xf5c9k7p6DseeBW0I8ionrlTHx.rGosgxhiFaMqtr7HiA7PBzKvPdeEYN0hQ8RYo8JzYL82hA91A3V2m9Ij6y0DfIJnnrKN8YORffhxmJ6DzwEl1zjrVFbD01bqB3Vdww8w8PQJSkKQkd313tr-atU8LS26fnBmOngEkVHwAr2WCKxuUvxHmuVBTA-Lgz7wKwMoOJCA3hFxMavVb0ZFB7CK0BUTVU6z0De92Q.FJKNCHLMbjX3vcAQ90=', - 'h': 290, - 'pid': 1053688, - 'sync': [ - 'https://link1', - 'https://link2' - ], - 'crid': '422031', - 'w': 600, - 'cid': '99006', - 'adm': 'document.writeln(\"\\\"\\\"\\/<\\/a>\");document.writeln(\"<\\/improvedigital_ad_output_information>\");' - } - ], - 'debug': '' - } - }; - - const serverResponseTwoBids = { - 'body': { - 'id': '687a06c541d8d1', - 'site_id': 191642, - 'bid': [ - serverResponse.body.bid[0], - { - 'isNet': true, - 'id': '1234', - 'advid': '5280', - 'price': 1.23, - 'nurl': 'https://link/imp_pixel?ic=wVmhKI07hCVyGC1sNdFp.6buOSiGYOw8jPyZLlcMY2RCwD4ek3Fy6.xUI7U002skGBs3objMBoNU-Frpvmb9js3NKIG0YZJgWaNdcpXY9gOXE9hY4-wxybCjVSNzhOQB-zic73hzcnJnKeoGgcfvt8fMy18-yD0aVdYWt4zbqdoITOkKNCPBEgbPFu1rcje-o7a64yZ7H3dKvtnIixXQYc1Ep86xGSBGXY6xW2KfUOMT6vnkemxO72divMkMdhR8cAuqIubbx-ZID8-xf5c9k7p6DseeBW0I8ionrlTHx.rGosgxhiFaMqtr7HiA7PBzKvPdeEYN0hQ8RYo8JzYL82hA91A3V2m9Ij6y0DfIJnnrKN8YORffhxmJ6DzwEl1zjrVFbD01bqB3Vdww8w8PQJSkKQkd313tr-atU8LS26fnBmOngEkVHwAr2WCKxuUvxHmuVBTA-Lgz7wKwMoOJCA3hFxMavVb0ZFB7CK0BUTVU6z0De92Q.FJKNCHLMbjX3vcAQ90=', - 'h': 400, - 'pid': 1053688, - 'sync': [ - 'https://link3' - ], - 'crid': '422033', - 'w': 700, - 'cid': '99006', - 'adm': 'document.writeln(\"\\\"\\\"\\/<\\/a>\");document.writeln(\"<\\/improvedigital_ad_output_information>\");' - } - ], - 'debug': '' - } - }; - - const serverResponseNative = { - body: { - id: '687a06c541d8d1', - site_id: 191642, - bid: [ - { - isNet: false, - id: '33e9500b21129f', - advid: '5279', - price: 1.45888594164456, - nurl: 'https://ice.360yield.com/imp_pixel?ic=wVm', - h: 290, - pid: 1053688, - sync: [ - 'https://link1', - 'https://link2' - ], - crid: '422031', - w: 600, - cid: '99006', - native: { - assets: [ - { - title: { - text: 'Native title' - } - }, - { - data: { - type: 1, - value: 'Improve Digital' - } - }, - { - data: { - type: 2, - value: 'Native body' - } - }, - { - data: { - type: 3, - value: '4' // rating - } - }, - { - data: { - type: 4, - value: '10105' // likes - } - }, - { - data: { - type: 5, - value: '150000' // downloads - } - }, - { - data: { - type: 6, - value: '3.99' // price - } - }, - { - data: { - type: 7, - value: '4.49' // salePrice - } - }, - { - data: { - type: 8, - value: '(123) 456-7890' // phone - } - }, - { - data: { - type: 9, - value: '123 Main Street, Anywhere USA' // address - } - }, - { - data: { - type: 10, - value: 'body2' - } - }, - { - data: { - type: 11, - value: 'https://myurl.com' // displayUrl - } - }, - { - data: { - type: 12, - value: 'Do it' // cta - } - }, - { - img: { - type: 1, - url: 'Should get ignored', - h: 300, - w: 400 - } - }, - { - img: { - type: 2, - url: 'https://blah.com/icon.jpg', - h: 30, - w: 40 - } - - }, - { - img: { - type: 3, - url: 'https://blah.com/image.jpg', - h: 200, - w: 800 - } - } - ], - link: { - url: 'https://advertiser.com', - clicktrackers: [ - 'https://click.tracker.com/click?impid=123' - ] - }, - imptrackers: [ - 'https://imptrack1.com', - 'https://imptrack2.com' - ], - jstracker: '', - privacy: 'https://www.myprivacyurl.com' - } - } - ], - debug: '' - } - }; - - const serverResponseVideo = { - 'body': { - 'id': '687a06c541d8d1', - 'site_id': 191642, - 'bid': [ - { - 'isNet': false, - 'id': '33e9500b21129f', - 'advid': '5279', - 'price': 1.45888594164456, - 'nurl': 'http://ice.360yield.com/imp_pixel?ic=wVmhKI07hCVyGC1sNdFp.6buOSiGYOw8jPyZLlcMY2RCwD4ek3Fy6.xUI7U002skGBs3objMBoNU-Frpvmb9js3NKIG0YZJgWaNdcpXY9gOXE9hY4-wxybCjVSNzhOQB-zic73hzcnJnKeoGgcfvt8fMy18-yD0aVdYWt4zbqdoITOkKNCPBEgbPFu1rcje-o7a64yZ7H3dKvtnIixXQYc1Ep86xGSBGXY6xW2KfUOMT6vnkemxO72divMkMdhR8cAuqIubbx-ZID8-xf5c9k7p6DseeBW0I8ionrlTHx.rGosgxhiFaMqtr7HiA7PBzKvPdeEYN0hQ8RYo8JzYL82hA91A3V2m9Ij6y0DfIJnnrKN8YORffhxmJ6DzwEl1zjrVFbD01bqB3Vdww8w8PQJSkKQkd313tr-atU8LS26fnBmOngEkVHwAr2WCKxuUvxHmuVBTA-Lgz7wKwMoOJCA3hFxMavVb0ZFB7CK0BUTVU6z0De92Q.FJKNCHLMbjX3vcAQ90=', - 'h': 290, - 'pid': 1053688, - 'sync': [ - 'http://link1', - 'http://link2' - ], - 'crid': '422031', - 'w': 600, - 'cid': '99006', - 'adm': '', - 'ad_type': 'video' - } - ], - 'debug': '' - } - }; - - const nativeEventtrackers = [ - { - event: 1, - method: 1, - url: 'https://www.mytracker.com/imptracker' - }, - { - event: 1, - method: 2, - url: 'https://www.mytracker.com/tracker.js' - } - ]; - - describe('interpretResponse', function () { - const expectedBid = [ - { - 'ad': '', - 'creativeId': '422031', - 'cpm': 1.45888594164456, - 'currency': 'USD', - 'height': 290, - 'mediaType': 'banner', - 'netRevenue': false, - 'requestId': '33e9500b21129f', - 'ttl': 300, - 'width': 600 - } - ]; - - const expectedTwoBids = [ - expectedBid[0], - { - 'ad': '', - 'creativeId': '422033', - 'cpm': 1.23, - 'currency': 'USD', - 'height': 400, - 'mediaType': 'banner', - 'netRevenue': true, - 'requestId': '1234', - 'ttl': 300, - 'width': 700 - } - ]; - - const expectedBidNative = [ - { - mediaType: 'native', - creativeId: '422031', - cpm: 1.45888594164456, - currency: 'USD', - height: 290, - netRevenue: false, - requestId: '33e9500b21129f', - ttl: 300, - width: 600, - native: { - title: 'Native title', - body: 'Native body', - body2: 'body2', - cta: 'Do it', - sponsoredBy: 'Improve Digital', - rating: '4', - likes: '10105', - downloads: '150000', - price: '3.99', - salePrice: '4.49', - phone: '(123) 456-7890', - address: '123 Main Street, Anywhere USA', - displayUrl: 'https://myurl.com', - icon: { - url: 'https://blah.com/icon.jpg', - height: 30, - width: 40 - }, - image: { - url: 'https://blah.com/image.jpg', - height: 200, - width: 800 - }, - clickUrl: 'https://advertiser.com', - clickTrackers: ['https://click.tracker.com/click?impid=123'], - impressionTrackers: [ - 'https://ice.360yield.com/imp_pixel?ic=wVm', - 'https://imptrack1.com', - 'https://imptrack2.com' - ], - javascriptTrackers: '', - privacyLink: 'https://www.myprivacyurl.com' - } - } - ]; - - const expectedBidInstreamVideo = [ - { - 'vastXml': '', - 'creativeId': '422031', - 'cpm': 1.45888594164456, - 'currency': 'USD', - 'height': 290, - 'mediaType': 'video', - 'netRevenue': false, - 'requestId': '33e9500b21129f', - 'ttl': 300, - 'width': 600 - } - ]; - - const expectedBidOutstreamVideo = utils.deepClone(expectedBidInstreamVideo); - expectedBidOutstreamVideo[0].adResponse = { - content: expectedBidOutstreamVideo[0].vastXml, - height: expectedBidOutstreamVideo[0].height, - width: expectedBidOutstreamVideo[0].width - }; - - it('should return a well-formed display bid', function () { - const bids = spec.interpretResponse(serverResponse, {bidderRequest}); - expect(bids).to.deep.equal(expectedBid); - }); - - it('should return a well-formed display bid for multi-format ad unit', function () { - const bids = spec.interpretResponse(serverResponse, {bidderRequest: multiFormatBidderRequest}); - expect(bids).to.deep.equal(expectedBid); - }); - - it('should return two bids', function () { - const bids = spec.interpretResponse(serverResponseTwoBids, {bidderRequest}); - expect(bids).to.deep.equal(expectedTwoBids); - }); - - it('should set dealId correctly', function () { - const response = JSON.parse(JSON.stringify(serverResponse)); - let bids; - - delete response.body.bid[0].lid; - response.body.bid[0].buying_type = 'deal_id'; - bids = spec.interpretResponse(response, {bidderRequest}); - expect(bids[0].dealId).to.not.exist; - - response.body.bid[0].lid = 268515; - delete response.body.bid[0].buying_type; - bids = spec.interpretResponse(response, {bidderRequest}); - expect(bids[0].dealId).to.not.exist; - - response.body.bid[0].lid = 268515; - response.body.bid[0].buying_type = 'rtb'; - bids = spec.interpretResponse(response, {bidderRequest}); - expect(bids[0].dealId).to.not.exist; - - response.body.bid[0].lid = 268515; - response.body.bid[0].buying_type = 'classic'; - bids = spec.interpretResponse(response, {bidderRequest}); - expect(bids[0].dealId).to.equal(268515); - - response.body.bid[0].lid = 268515; - response.body.bid[0].buying_type = 'deal_id'; - bids = spec.interpretResponse(response, {bidderRequest}); - expect(bids[0].dealId).to.equal(268515); - - response.body.bid[0].lid = [ 268515, 12456, 34567 ]; - response.body.bid[0].buying_type = 'deal_id'; - bids = spec.interpretResponse(response, {bidderRequest}); - expect(bids[0].dealId).to.not.exist; - - response.body.bid[0].lid = [ 268515, 12456, 34567 ]; - response.body.bid[0].buying_type = [ 'deal_id', 'classic' ]; - bids = spec.interpretResponse(response, {bidderRequest}); - expect(bids[0].dealId).to.not.exist; - - response.body.bid[0].lid = [ 268515, 12456, 34567 ]; - response.body.bid[0].buying_type = [ 'rtb', 'deal_id', 'deal_id' ]; - bids = spec.interpretResponse(response, {bidderRequest}); - expect(bids[0].dealId).to.equal(12456); - }); - - it('should set currency', function () { - const response = JSON.parse(JSON.stringify(serverResponse)); - response.body.bid[0].currency = 'eur'; - const bids = spec.interpretResponse(response, {bidderRequest}); - expect(bids[0].currency).to.equal('EUR'); - }); - - it('should return empty array for bad response or no price', function () { - let response = JSON.parse(JSON.stringify(serverResponse)); - let bids; - - // Price missing or 0 - response.body.bid[0].price = 0; - bids = spec.interpretResponse(response, {bidderRequest}); - expect(bids).to.deep.equal([]); - delete response.body.bid[0].price; - bids = spec.interpretResponse(response, {bidderRequest}); - expect(bids).to.deep.equal([]); - response.body.bid[0].price = null; - bids = spec.interpretResponse(response, {bidderRequest}); - expect(bids).to.deep.equal([]); - - // errorCode present - response = JSON.parse(JSON.stringify(serverResponse)); - response.body.bid[0].errorCode = undefined; - bids = spec.interpretResponse(response, {bidderRequest}); - expect(bids).to.deep.equal([]); - - // adm and native missing - response = JSON.parse(JSON.stringify(serverResponse)); - delete response.body.bid[0].adm; - bids = spec.interpretResponse(response, {bidderRequest}); - expect(bids).to.deep.equal([]); - response.body.bid[0].adm = null; - bids = spec.interpretResponse(response, {bidderRequest}); - expect(bids).to.deep.equal([]); - }); - - it('should set netRevenue', function () { - const response = JSON.parse(JSON.stringify(serverResponse)); - response.body.bid[0].isNet = true; - const bids = spec.interpretResponse(response, {bidderRequest}); - expect(bids[0].netRevenue).to.equal(true); - }); - - // Native ads - it('should return a well-formed native ad bid', function () { - let bids = spec.interpretResponse(serverResponseNative, {bidderRequest}); - expect(bids[0].ortbNative).to.deep.equal(serverResponseNative.body.bid[0].native); - delete bids[0].ortbNative; - expect(bids).to.deep.equal(expectedBidNative); - - // eventtrackers - const response = JSON.parse(JSON.stringify(serverResponseNative)); - const expectedBids = JSON.parse(JSON.stringify(expectedBidNative)); - response.body.bid[0].native.eventtrackers = nativeEventtrackers; - expectedBids[0].native.impressionTrackers = [ - 'https://ice.360yield.com/imp_pixel?ic=wVm', - 'https://www.mytracker.com/imptracker' - ]; - expectedBids[0].native.javascriptTrackers = ''; - bids = spec.interpretResponse(response, {bidderRequest}); - delete bids[0].ortbNative; - expect(bids).to.deep.equal(expectedBids); - }); - - // Video - it('should return a well-formed instream video bid', function () { - const bids = spec.interpretResponse(serverResponseVideo, {bidderRequest: instreamBidderRequest}); - expect(bids).to.deep.equal(expectedBidInstreamVideo); - }); - - it('should return a well-formed outstream video bid', function () { - const bids = spec.interpretResponse(serverResponseVideo, {bidderRequest: outstreamBidderRequest}); - expect(bids[0].renderer).to.exist; - delete (bids[0].renderer); - expect(bids).to.deep.equal(expectedBidOutstreamVideo); - }); - - it('should return a well-formed outstream video bid for multi-format ad unit', function () { - const bids = spec.interpretResponse(serverResponseVideo, {bidderRequest: multiFormatBidderRequest}); - expect(bids[0].renderer).to.exist; - delete (bids[0].renderer); - expect(bids).to.deep.equal(expectedBidOutstreamVideo); - }); - }); - - describe('getUserSyncs', function () { - const serverResponses = [ serverResponseTwoBids ]; - - it('should return no syncs when pixel syncing is disabled', function () { - const syncs = spec.getUserSyncs({ pixelEnabled: false }, serverResponses); - expect(syncs).to.deep.equal([]); - }); - - it('should return user syncs', function () { - const syncs = spec.getUserSyncs({ pixelEnabled: true }, serverResponses); - const expected = [ - { type: 'image', url: 'https://link1' }, - { type: 'image', url: 'https://link2' }, - { type: 'image', url: 'https://link3' } - ]; - expect(syncs).to.deep.equal(expected); - }); - }); -}); diff --git a/test/spec/modules/inmarBidAdapter_spec.js b/test/spec/modules/inmarBidAdapter_spec.js deleted file mode 100644 index 998fe20d369..00000000000 --- a/test/spec/modules/inmarBidAdapter_spec.js +++ /dev/null @@ -1,240 +0,0 @@ -// import or require modules necessary for the test, e.g.: -import {expect} from 'chai'; // may prefer 'assert' in place of 'expect' -import { - spec -} from 'modules/inmarBidAdapter.js'; -import {config} from 'src/config.js'; - -describe('Inmar adapter tests', function () { - var DEFAULT_PARAMS_NEW_SIZES = [{ - adUnitCode: 'test-div', - bidId: '2c7c8e9c900244', - mediaTypes: { - banner: { - sizes: [ - [300, 250], [300, 600], [728, 90], [970, 250]] - } - }, - bidder: 'inmar', - params: { - partnerId: 12345 - }, - auctionId: '0cb3144c-d084-4686-b0d6-f5dbe917c563', - bidRequestsCount: 1, - bidderRequestId: '1858b7382993ca', - transactionId: '29df2112-348b-4961-8863-1b33684d95e6', - user: {} - }]; - - var DEFAULT_PARAMS_VIDEO = [{ - adUnitCode: 'test-div', - bidId: '2c7c8e9c900244', - mediaTypes: { - video: { - context: 'instream', // or 'outstream' - playerSize: [640, 480], - mimes: ['video/mp4'] - } - }, - bidder: 'inmar', - params: { - partnerId: 12345 - }, - auctionId: '0cb3144c-d084-4686-b0d6-f5dbe917c563', - bidRequestsCount: 1, - bidderRequestId: '1858b7382993ca', - transactionId: '29df2112-348b-4961-8863-1b33684d95e6', - user: {} - }]; - - var DEFAULT_PARAMS_WO_OPTIONAL = [{ - adUnitCode: 'test-div', - bidId: '2c7c8e9c900244', - sizes: [ - [300, 250], - [300, 600], - [728, 90], - [970, 250] - ], - bidder: 'inmar', - params: { - partnerId: 12345, - }, - auctionId: '851adee7-d843-48f9-a7e9-9ff00573fcbf', - bidRequestsCount: 1, - bidderRequestId: '1858b7382993ca', - transactionId: '29df2112-348b-4961-8863-1b33684d95e6' - }]; - - var BID_RESPONSE = { - body: { - cpm: 1.50, - ad: '', - meta: { - mediaType: 'banner', - }, - width: 300, - height: 250, - creativeId: '189198063', - netRevenue: true, - currency: 'USD', - ttl: 300, - dealId: 'dealId' - - } - }; - - var BID_RESPONSE_VIDEO = { - body: { - cpm: 1.50, - meta: { - mediaType: 'video', - }, - width: 1, - height: 1, - creativeId: '189198063', - netRevenue: true, - currency: 'USD', - ttl: 300, - vastUrl: 'https://vast.com/vast.xml', - dealId: 'dealId' - } - }; - - it('Verify build request to prebid 3.0 display test', function() { - const request = spec.buildRequests(DEFAULT_PARAMS_NEW_SIZES, { - gdprConsent: { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }, - refererInfo: { - referer: 'https://domain.com', - numIframes: 0 - } - }); - - expect(request).to.have.property('method').and.to.equal('POST'); - const requestContent = JSON.parse(request.data); - expect(requestContent.bidRequests[0].params).to.have.property('partnerId').and.to.equal(12345); - expect(requestContent.bidRequests[0]).to.have.property('auctionId').and.to.equal('0cb3144c-d084-4686-b0d6-f5dbe917c563'); - expect(requestContent.bidRequests[0]).to.have.property('bidId').and.to.equal('2c7c8e9c900244'); - expect(requestContent.bidRequests[0]).to.have.property('bidRequestsCount').and.to.equal(1); - expect(requestContent.bidRequests[0]).to.have.property('bidder').and.to.equal('inmar'); - expect(requestContent.bidRequests[0]).to.have.property('bidderRequestId').and.to.equal('1858b7382993ca'); - expect(requestContent.bidRequests[0]).to.have.property('adUnitCode').and.to.equal('test-div'); - expect(requestContent.refererInfo).to.have.property('referer').and.to.equal('https://domain.com'); - expect(requestContent.bidRequests[0].mediaTypes.banner).to.have.property('sizes'); - expect(requestContent.bidRequests[0].mediaTypes.banner.sizes[0]).to.have.ordered.members([300, 250]); - expect(requestContent.bidRequests[0].mediaTypes.banner.sizes[1]).to.have.ordered.members([300, 600]); - expect(requestContent.bidRequests[0].mediaTypes.banner.sizes[2]).to.have.ordered.members([728, 90]); - expect(requestContent.bidRequests[0].mediaTypes.banner.sizes[3]).to.have.ordered.members([970, 250]); - expect(requestContent.bidRequests[0]).to.have.property('transactionId').and.to.equal('29df2112-348b-4961-8863-1b33684d95e6'); - expect(requestContent.refererInfo).to.have.property('numIframes').and.to.equal(0); - }) - - it('Verify interprete response', function () { - const request = spec.buildRequests(DEFAULT_PARAMS_NEW_SIZES, { - gdprConsent: { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }, - refererInfo: { - referer: 'https://domain.com', - numIframes: 0 - } - }); - - const bids = spec.interpretResponse(BID_RESPONSE, request); - expect(bids).to.have.lengthOf(1); - const bid = bids[0]; - expect(bid.cpm).to.equal(1.50); - expect(bid.ad).to.equal(''); - expect(bid.meta.mediaType).to.equal('banner'); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.creativeId).to.equal('189198063'); - expect(bid.netRevenue).to.equal(true); - expect(bid.currency).to.equal('USD'); - expect(bid.ttl).to.equal(300); - expect(bid.dealId).to.equal('dealId'); - }); - - it('no banner media response', function () { - const request = spec.buildRequests(DEFAULT_PARAMS_NEW_SIZES, { - gdprConsent: { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }, - refererInfo: { - referer: 'https://domain.com', - numIframes: 0 - } - }); - - const bids = spec.interpretResponse(BID_RESPONSE_VIDEO, request); - const bid = bids[0]; - expect(bid.vastUrl).to.equal('https://vast.com/vast.xml'); - }); - - it('Verifies bidder_code', function () { - expect(spec.code).to.equal('inmar'); - }); - - it('Verifies bidder aliases', function () { - expect(spec.aliases).to.have.lengthOf(1); - expect(spec.aliases[0]).to.equal('inm'); - }); - - it('Verifies if bid request is valid', function () { - expect(spec.isBidRequestValid(DEFAULT_PARAMS_NEW_SIZES[0])).to.equal(true); - expect(spec.isBidRequestValid(DEFAULT_PARAMS_WO_OPTIONAL[0])).to.equal(true); - expect(spec.isBidRequestValid({})).to.equal(false); - expect(spec.isBidRequestValid({ - params: {} - })).to.equal(false); - expect(spec.isBidRequestValid({ - params: { - } - })).to.equal(false); - expect(spec.isBidRequestValid({ - params: { - partnerId: 12345 - } - })).to.equal(true); - }); - - it('Verifies user syncs image', function () { - var syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: true - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - referer: 'http://domain.com', - gdprApplies: true - }) - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('image'); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: true - }, [BID_RESPONSE], { - consentString: '', - referer: 'http://domain.com', - gdprApplies: true - }) - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('image'); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: true - }, [], { - consentString: null, - referer: 'http://domain.com', - gdprApplies: true - }) - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('image'); - }); -}); diff --git a/test/spec/modules/innityBidAdapter_spec.js b/test/spec/modules/innityBidAdapter_spec.js deleted file mode 100644 index 80c00252632..00000000000 --- a/test/spec/modules/innityBidAdapter_spec.js +++ /dev/null @@ -1,106 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/innityBidAdapter.js'; - -describe('innityAdapterTest', () => { - describe('bidRequestValidity', () => { - it('bidRequest with pub ID and zone ID param', () => { - expect(spec.isBidRequestValid({ - bidder: 'innity', - params: { - 'pub': 267, - 'zone': 62546 - }, - })).to.equal(true); - }); - - it('bidRequest with no required params', () => { - expect(spec.isBidRequestValid({ - bidder: 'innity', - params: { - }, - })).to.equal(false); - }); - }); - - describe('bidRequest', () => { - const bidRequests = [{ - 'bidder': 'innity', - 'params': { - 'pub': 267, - 'zone': 62546 - }, - 'adUnitCode': '/19968336/header-bid-tag-0', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'sizes': [300, 250], - 'bidId': '51ef8751f9aead', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757' - }]; - - const bidderRequest = { - refererInfo: { - referer: 'https://example.com' - } - }; - - it('bidRequest HTTP method', () => { - const requests = spec.buildRequests(bidRequests, bidderRequest); - requests.forEach(function(requestItem) { - expect(requestItem.method).to.equal('GET'); - }); - }); - - it('bidRequest data', () => { - const requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests[0].data.pub).to.equal(267); - expect(requests[0].data.zone).to.equal(62546); - expect(requests[0].data.width).to.equal('300'); - expect(requests[0].data.height).to.equal('250'); - expect(requests[0].data.callback_uid).to.equal('51ef8751f9aead'); - }); - }); - - describe('interpretResponse', () => { - const bidRequest = { - 'method': 'GET', - 'url': 'https://as.innity.com/synd/?', - 'data': { - 'ver': 2, - 'hb': 1, - 'output': 'js', - 'pub': 267, - 'zone': 62546, - 'width': '300', - 'height': '250', - 'callback': 'json', - 'callback_uid': '51ef8751f9aead', - 'url': 'https://example.com', - 'cb': '', - } - }; - - const bidResponse = { - body: { - 'cpm': 100, - 'width': '300', - 'height': '250', - 'creative_id': '148186', - 'callback_uid': '51ef8751f9aead', - 'tag': '', - }, - headers: {} - }; - - it('result is correct', () => { - const result = spec.interpretResponse(bidResponse, bidRequest); - expect(result[0].requestId).to.equal('51ef8751f9aead'); - expect(result[0].cpm).to.equal(1); - expect(result[0].width).to.equal('300'); - expect(result[0].height).to.equal('250'); - expect(result[0].creativeId).to.equal('148186'); - expect(result[0].currency).to.equal('USD'); - expect(result[0].ttl).to.equal(60); - expect(result[0].ad).to.equal(''); - }); - }); -}); diff --git a/test/spec/modules/inskinBidAdapter_spec.js b/test/spec/modules/inskinBidAdapter_spec.js deleted file mode 100644 index cedaff2a0cf..00000000000 --- a/test/spec/modules/inskinBidAdapter_spec.js +++ /dev/null @@ -1,376 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/inskinBidAdapter.js'; -import { createBid } from 'src/bidfactory.js'; - -const ENDPOINT = 'https://mfad.inskinad.com/api/v2'; - -const REQUEST = { - 'bidderCode': 'inskin', - 'requestId': 'a4713c32-3762-4798-b342-4ab810ca770d', - 'bidderRequestId': '109f2a181342a9', - 'bidRequest': [{ - 'bidder': 'inskin', - 'params': { - 'networkId': 9874, - 'siteId': 730181 - }, - 'placementCode': 'div-gpt-ad-1487778092495-0', - 'sizes': [ - [728, 90], - [970, 90] - ], - 'bidId': '2b0f82502298c9', - 'bidderRequestId': '109f2a181342a9', - 'requestId': 'a4713c32-3762-4798-b342-4ab810ca770d' - }, - { - 'bidder': 'inskin', - 'params': { - 'networkId': 9874, - 'siteId': 730181 - }, - 'placementCode': 'div-gpt-ad-1487778092495-0', - 'sizes': [ - [728, 90], - [970, 90] - ], - 'bidId': '123', - 'bidderRequestId': '109f2a181342a9', - 'requestId': 'a4713c32-3762-4798-b342-4ab810ca770d' - }], - 'start': 1487883186070, - 'auctionStart': 1487883186069, - 'timeout': 3000 -}; - -const RESPONSE = { - 'headers': null, - 'body': { - 'user': { 'key': 'ue1-2d33e91b71e74929b4aeecc23f4376f1' }, - 'decisions': { - '2b0f82502298c9': { - 'adId': 2364764, - 'creativeId': 1950991, - 'flightId': 2788300, - 'campaignId': 542982, - 'clickUrl': 'https://mfad.inskinad.com/r', - 'impressionUrl': 'https://mfad.inskinad.com/i.gif', - 'contents': [{ - 'type': 'html', - 'body': '', - 'data': { - 'height': 90, - 'width': 728, - 'imageUrl': 'https://static.adzerk.net/Advertisers/b0ab77db8a7848c8b78931aed022a5ef.gif', - 'fileName': 'b0ab77db8a7848c8b78931aed022a5ef.gif' - }, - 'template': 'image' - }], - 'height': 90, - 'width': 728, - 'events': [], - 'pricing': {'price': 0.5, 'clearPrice': 0.5, 'revenue': 0.0005, 'rateType': 2, 'eCPM': 0.5} - }, - '123': { - 'adId': 2364764, - 'creativeId': 1950991, - 'flightId': 2788300, - 'campaignId': 542982, - 'clickUrl': 'https://mfad.inskinad.com/r', - 'impressionUrl': 'https://mfad.inskinad.com/i.gif', - 'contents': [{ - 'type': 'html', - 'body': '', - 'data': { - 'customData': { - 'pubCPM': 1 - }, - 'height': 90, - 'width': 728, - 'imageUrl': 'https://static.adzerk.net/Advertisers/b0ab77db8a7848c8b78931aed022a5ef.gif', - 'fileName': 'b0ab77db8a7848c8b78931aed022a5ef.gif' - }, - 'template': 'image' - }], - 'height': 90, - 'width': 728, - 'events': [], - 'pricing': {'price': 0.5, 'clearPrice': 0.5, 'revenue': 0.0005, 'rateType': 2, 'eCPM': 0.5} - } - } - } -}; - -const consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; -const bidderRequest = { - bidderCode: 'inskin', - gdprConsent: { - consentString: consentString, - gdprApplies: true - }, - refererInfo: { - referer: 'https://www.inskinmedia.com' - } -}; - -describe('InSkin BidAdapter', function () { - let bidRequests; - let adapter = spec; - - beforeEach(function () { - bidRequests = [ - { - bidder: 'inskin', - params: { - networkId: '9874', - siteId: 'xxxxx' - }, - placementCode: 'header-bid-tag-1', - sizes: [[300, 250], [300, 600]], - bidId: '23acc48ad47af5', - requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - } - ]; - }); - - describe('bid request validation', function () { - it('should accept valid bid requests', function () { - let bid = { - bidder: 'inskin', - params: { - networkId: '9874', - siteId: 'xxxxx' - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should accept valid bid requests with extra fields', function () { - let bid = { - bidder: 'inskin', - params: { - networkId: '9874', - siteId: 'xxxxx', - zoneId: 'xxxxx' - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should reject bid requests without siteId', function () { - let bid = { - bidder: 'inskin', - params: { - networkId: '9874' - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should reject bid requests without networkId', function () { - let bid = { - bidder: 'inskin', - params: { - siteId: '9874' - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests validation', function () { - it('creates request data', function () { - let request = spec.buildRequests(bidRequests, bidderRequest); - - expect(request).to.exist.and.to.be.a('object'); - }); - - it('request to inskin should contain a url', function () { - let request = spec.buildRequests(bidRequests, bidderRequest); - - expect(request.url).to.have.string('inskinad.com'); - }); - - it('requires valid bids to make request', function () { - let request = spec.buildRequests([], bidderRequest); - expect(request.bidRequest).to.be.empty; - }); - - it('sends bid request to ENDPOINT via POST', function () { - let request = spec.buildRequests(bidRequests, bidderRequest); - - expect(request.method).to.have.string('POST'); - }); - - it('should add gdpr consent information to the request', function () { - bidderRequest.bids = bidRequests; - - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.consent.gdprConsentString).to.exist; - expect(payload.consent.gdprConsentRequired).to.exist; - expect(payload.consent.gdprConsentString).to.exist.and.to.equal(consentString); - expect(payload.consent.gdprConsentRequired).to.exist.and.to.be.true; - }); - - it('should not add keywords if TCF v2 purposes are granted', function () { - const bidderRequest2 = Object.assign({}, bidderRequest, { - gdprConsent: { - gdprApplies: true, - consentString: 'consentString', - vendorData: { - vendor: { - consents: { - 150: true - } - }, - purpose: { - consents: { - 1: true, - 2: true, - 3: true, - 4: true, - 5: true, - 6: true, - 7: true, - 8: true, - 9: true, - 10: true - } - } - }, - apiVersion: 2 - } - }); - - const request = spec.buildRequests(bidRequests, bidderRequest2); - const payload = JSON.parse(request.data); - - expect(payload.keywords).to.be.an('array').that.is.empty; - expect(payload.placements[0].properties.restrictions).to.be.undefined; - }); - - it('should add keywords if TCF v2 purposes are not granted', function () { - const bidderRequest2 = Object.assign({}, bidderRequest, { - gdprConsent: { - gdprApplies: true, - consentString: 'consentString', - vendorData: { - vendor: { - consents: { - 150: false - } - }, - purpose: { - consents: { - 1: true, - 2: true, - 3: true, - 4: true, - 5: true, - 6: true, - 7: true, - 8: true, - 9: true, - 10: true - } - } - }, - apiVersion: 2 - } - }); - - const request = spec.buildRequests(bidRequests, bidderRequest2); - const payload = JSON.parse(request.data); - - expect(payload.keywords).to.be.an('array').that.includes('cst-nocookies'); - expect(payload.keywords).to.be.an('array').that.includes('cst-nocontext'); - expect(payload.keywords).to.be.an('array').that.includes('cst-nodmp'); - expect(payload.keywords).to.be.an('array').that.includes('cst-nodata'); - expect(payload.keywords).to.be.an('array').that.includes('cst-noclicks'); - expect(payload.keywords).to.be.an('array').that.includes('cst-noresearch'); - - expect(payload.placements[0].properties.restrictions).to.be.an('array').that.includes('nocookies'); - expect(payload.placements[0].properties.restrictions).to.be.an('array').that.includes('nocontext'); - expect(payload.placements[0].properties.restrictions).to.be.an('array').that.includes('nodmp'); - expect(payload.placements[0].properties.restrictions).to.be.an('array').that.includes('nodata'); - expect(payload.placements[0].properties.restrictions).to.be.an('array').that.includes('noclicks'); - expect(payload.placements[0].properties.restrictions).to.be.an('array').that.includes('noresearch'); - }); - }); - describe('interpretResponse validation', function () { - it('response should have valid bidderCode', function () { - let bidRequest = spec.buildRequests(REQUEST.bidRequest, bidderRequest); - let bid = createBid(1, bidRequest.bidRequest[0]); - - expect(bid.bidderCode).to.equal('inskin'); - }); - - it('response should include objects for all bids', function () { - let bids = spec.interpretResponse(RESPONSE, REQUEST); - - expect(bids.length).to.equal(2); - }); - - it('registers bids', function () { - let bids = spec.interpretResponse(RESPONSE, REQUEST); - bids.forEach(b => { - expect(b).to.have.property('cpm'); - expect(b.cpm).to.be.above(0); - expect(b).to.have.property('requestId'); - expect(b).to.have.property('cpm'); - expect(b).to.have.property('width'); - expect(b).to.have.property('height'); - expect(b).to.have.property('ad'); - expect(b).to.have.property('currency', 'USD'); - expect(b).to.have.property('creativeId'); - expect(b).to.have.property('ttl', 360); - expect(b).to.have.property('netRevenue', true); - }); - }); - - it('cpm is correctly set', function () { - let bids = spec.interpretResponse(RESPONSE, REQUEST); - - expect(bids[0].cpm).to.equal(0.5); - expect(bids[1].cpm).to.equal(1); - }); - - it('handles nobid responses', function () { - let EMPTY_RESP = Object.assign({}, RESPONSE, {'body': {'decisions': null}}) - let bids = spec.interpretResponse(EMPTY_RESP, REQUEST); - - expect(bids).to.be.empty; - }); - - it('handles no server response', function () { - let bids = spec.interpretResponse(null, REQUEST); - - expect(bids).to.be.empty; - }); - }); - describe('getUserSyncs', function () { - it('handles empty sync options', function () { - let opts = spec.getUserSyncs({}); - - expect(opts).to.be.empty; - }); - - it('should return two sync urls if pixel syncs are enabled', function () { - let syncOptions = {'pixelEnabled': true}; - let opts = spec.getUserSyncs(syncOptions); - - expect(opts.length).to.equal(2); - }); - - it('should return three sync urls if pixel and iframe syncs are enabled', function () { - let syncOptions = {'iframeEnabled': true, 'pixelEnabled': true}; - let opts = spec.getUserSyncs(syncOptions); - - expect(opts.length).to.equal(3); - }); - }); -}); diff --git a/test/spec/modules/instreamTracking_spec.js b/test/spec/modules/instreamTracking_spec.js deleted file mode 100644 index 8d795fec88b..00000000000 --- a/test/spec/modules/instreamTracking_spec.js +++ /dev/null @@ -1,221 +0,0 @@ -import { assert } from 'chai'; -import { trackInstreamDeliveredImpressions } from 'modules/instreamTracking.js'; -import { config } from 'src/config.js'; -import events from 'src/events.js'; -import * as utils from 'src/utils.js'; -import * as sinon from 'sinon'; -import { INSTREAM, OUTSTREAM } from 'src/video.js'; - -const BIDDER_CODE = 'sampleBidder'; -const VIDEO_CACHE_KEY = '4cf395af-8fee-4960-af0e-88d44e399f14'; - -let sandbox; - -function enableInstreamTracking(regex) { - let configStub = sandbox.stub(config, 'getConfig'); - configStub.withArgs('instreamTracking').returns(Object.assign( - { - enabled: true, - maxWindow: 10, - pollingFreq: 0 - }, - regex && {urlPattern: regex}, - )); -} - -function mockPerformanceApi({adServerCallSent, videoPresent}) { - let performanceStub = sandbox.stub(window.performance, 'getEntriesByType'); - let entries = [{ - name: 'https://domain.com/img.png', - initiatorType: 'img' - }, { - name: 'https://domain.com/script.js', - initiatorType: 'script' - }, { - name: 'https://domain.com/xhr', - initiatorType: 'xmlhttprequest' - }, { - name: 'https://domain.com/fetch', - initiatorType: 'fetch' - }]; - - if (adServerCallSent || videoPresent) { - entries.push({ - name: 'https://adserver.com/ads?custom_params=hb_uuid%3D' + VIDEO_CACHE_KEY + '%26pos%3D' + VIDEO_CACHE_KEY, - initiatorType: 'xmlhttprequest' - }); - } - - if (videoPresent) { - entries.push({ - name: 'https://prebid-vast-cache.com/cache?key=' + VIDEO_CACHE_KEY, - initiatorType: 'xmlhttprequest' - }); - } - - performanceStub.withArgs('resource').returns(entries); -} - -function mockBidResponse(adUnit, requestId) { - const bid = { - 'adUnitCod': adUnit.code, - 'bidderCode': adUnit.bids[0].bidder, - 'width': adUnit.sizes[0][0], - 'height': adUnit.sizes[0][1], - 'statusMessage': 'Bid available', - 'adId': 'id', - 'requestId': requestId, - 'source': 'client', - 'no_bid': false, - 'cpm': '1.1495', - 'ttl': 180, - 'creativeId': 'id', - 'netRevenue': true, - 'currency': 'USD', - } - if (adUnit.mediaTypes.video) { - bid.videoCacheKey = VIDEO_CACHE_KEY; - } - return bid -} - -function mockBidRequest(adUnit, bidResponse) { - return { - 'bidderCode': bidResponse.bidderCode, - 'auctionId': '20882439e3238c', - 'bidderRequestId': 'bidderRequestId', - 'bids': [ - { - 'adUnitCode': adUnit.code, - 'mediaTypes': adUnit.mediaTypes, - 'bidder': bidResponse.bidderCode, - 'bidId': bidResponse.requestId, - 'sizes': adUnit.sizes, - 'params': adUnit.bids[0].params, - 'bidderRequestId': 'bidderRequestId', - 'auctionId': '20882439e3238c', - } - ], - 'auctionStart': 1505250713622, - 'timeout': 3000 - }; -} - -function getMockInput(mediaType) { - const bannerAdUnit = { - code: 'banner', - mediaTypes: {banner: {sizes: [[300, 250]]}}, - sizes: [[300, 250]], - bids: [{bidder: BIDDER_CODE, params: {placementId: 'id'}}] - }; - const outStreamAdUnit = { - code: 'video-' + OUTSTREAM, - mediaTypes: {video: {playerSize: [640, 480], context: OUTSTREAM}}, - sizes: [[640, 480]], - bids: [{bidder: BIDDER_CODE, params: {placementId: 'id'}}] - }; - const inStreamAdUnit = { - code: 'video-' + INSTREAM, - mediaTypes: {video: {playerSize: [640, 480], context: INSTREAM}}, - sizes: [[640, 480]], - bids: [{bidder: BIDDER_CODE, params: {placementId: 'id'}}] - }; - - let adUnit; - switch (mediaType) { - default: - case 'banner': - adUnit = bannerAdUnit; - break; - case OUTSTREAM: - adUnit = outStreamAdUnit; - break; - case INSTREAM: - adUnit = inStreamAdUnit; - break; - } - - const bidResponse = mockBidResponse(adUnit, utils.getUniqueIdentifierStr()); - const bidderRequest = mockBidRequest(adUnit, bidResponse); - return { - adUnits: [adUnit], - bidsReceived: [bidResponse], - bidderRequests: [bidderRequest], - }; -} - -describe('Instream Tracking', function () { - beforeEach(function () { - sandbox = sinon.sandbox.create(); - }); - - afterEach(function () { - sandbox.restore(); - }); - - describe('gaurd checks', function () { - it('skip if tracking not enable', function () { - sandbox.stub(config, 'getConfig').withArgs('instreamTracking').returns(undefined); - assert.isNotOk(trackInstreamDeliveredImpressions({ - adUnits: [], - bidsReceived: [], - bidderRequests: [] - }), 'should not start tracking when tracking is disabled'); - }); - - it('run only if instream bids are present', function () { - enableInstreamTracking(); - assert.isNotOk(trackInstreamDeliveredImpressions({adUnits: [], bidsReceived: [], bidderRequests: []})); - }); - - it('checks for instream bids', function (done) { - enableInstreamTracking(); - assert.isNotOk(trackInstreamDeliveredImpressions(getMockInput('banner')), 'should not start tracking when banner bids are present') - assert.isNotOk(trackInstreamDeliveredImpressions(getMockInput(OUTSTREAM)), 'should not start tracking when outstream bids are present') - mockPerformanceApi({}); - assert.isOk(trackInstreamDeliveredImpressions(getMockInput(INSTREAM)), 'should start tracking when instream bids are present') - setTimeout(done, 10); - }); - }); - - describe('instream bids check', function () { - let spyEventsOn; - - beforeEach(function () { - spyEventsOn = sandbox.spy(events, 'emit'); - }); - - it('BID WON event is not emitted when no video cache key entries are present', function (done) { - enableInstreamTracking(); - trackInstreamDeliveredImpressions(getMockInput(INSTREAM)); - mockPerformanceApi({}); - setTimeout(function () { - assert.isNotOk(spyEventsOn.calledWith('bidWon')) - done() - }, 10); - }); - - it('BID WON event is not emitted when ad server call is sent', function (done) { - enableInstreamTracking(); - mockPerformanceApi({adServerCallSent: true}); - setTimeout(function () { - assert.isNotOk(spyEventsOn.calledWith('bidWon')) - done() - }, 10); - }); - - it('BID WON event is emitted when video cache key is present', function (done) { - enableInstreamTracking(/cache/); - const bidWonSpy = sandbox.spy(); - events.on('bidWon', bidWonSpy); - mockPerformanceApi({adServerCallSent: true, videoPresent: true}); - - trackInstreamDeliveredImpressions(getMockInput(INSTREAM)); - setTimeout(function () { - assert.isOk(spyEventsOn.calledWith('bidWon')) - assert(bidWonSpy.args[0][0].videoCacheKey, VIDEO_CACHE_KEY, 'Video cache key in bid won should be equal to video cache call'); - done() - }, 10); - }); - }); -}); diff --git a/test/spec/modules/intentIqIdSystem_spec.js b/test/spec/modules/intentIqIdSystem_spec.js deleted file mode 100644 index 7e819195b9f..00000000000 --- a/test/spec/modules/intentIqIdSystem_spec.js +++ /dev/null @@ -1,181 +0,0 @@ -import { expect } from 'chai'; -import {intentIqIdSubmodule, readData, FIRST_PARTY_KEY} from 'modules/intentIqIdSystem.js'; -import * as utils from 'src/utils.js'; -import {server} from 'test/mocks/xhr.js'; - -const partner = 10; -const pai = '11'; -const pcid = '12'; -const defaultConfigParams = { params: {partner: partner} }; -const paiConfigParams = { params: {partner: partner, pai: pai} }; -const pcidConfigParams = { params: {partner: partner, pcid: pcid} }; -const allConfigParams = { params: {partner: partner, pai: pai, pcid: pcid} }; -const responseHeader = {'Content-Type': 'application/json'} - -describe('IntentIQ tests', function () { - let logErrorStub; - - beforeEach(function () { - logErrorStub = sinon.stub(utils, 'logError'); - }); - - afterEach(function () { - logErrorStub.restore(); - }); - - it('should log an error if no configParams were passed when getId', function () { - let submodule = intentIqIdSubmodule.getId({ params: {} }); - expect(logErrorStub.calledOnce).to.be.true; - expect(submodule).to.be.undefined; - }); - - it('should log an error if partner configParam was not passed when getId', function () { - let submodule = intentIqIdSubmodule.getId({ params: {} }); - expect(logErrorStub.calledOnce).to.be.true; - expect(submodule).to.be.undefined; - }); - - it('should log an error if partner configParam was not a numeric value', function () { - let submodule = intentIqIdSubmodule.getId({ params: {partner: '10'} }); - expect(logErrorStub.calledOnce).to.be.true; - expect(submodule).to.be.undefined; - }); - - it('should call the IntentIQ endpoint with only partner', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = intentIqIdSubmodule.getId(defaultConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.contain('https://api.intentiq.com/profiles_engine/ProfilesEngineServlet?at=39&mi=10&dpi=10&pt=17&dpn=1&iiqidtype=2&iiqpcid='); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should ignore NA and invalid responses in decode', function () { - // let resp = JSON.stringify({'RESULT': 'NA'}); - // expect(intentIqIdSubmodule.decode(resp)).to.equal(undefined); - expect(intentIqIdSubmodule.decode('NA')).to.equal(undefined); - expect(intentIqIdSubmodule.decode('')).to.equal(undefined); - expect(intentIqIdSubmodule.decode(undefined)).to.equal(undefined); - }); - - it('should call the IntentIQ endpoint with only partner, pai', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = intentIqIdSubmodule.getId(paiConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.contain('https://api.intentiq.com/profiles_engine/ProfilesEngineServlet?at=39&mi=10&dpi=10&pt=17&dpn=1&pai=11&iiqidtype=2&iiqpcid='); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should call the IntentIQ endpoint with only partner, pcid', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = intentIqIdSubmodule.getId(pcidConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.contain('https://api.intentiq.com/profiles_engine/ProfilesEngineServlet?at=39&mi=10&dpi=10&pt=17&dpn=1&pcid=12&iiqidtype=2&iiqpcid='); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should call the IntentIQ endpoint with partner, pcid, pai', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = intentIqIdSubmodule.getId(allConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.contain('https://api.intentiq.com/profiles_engine/ProfilesEngineServlet?at=39&mi=10&dpi=10&pt=17&dpn=1&pcid=12&pai=11&iiqidtype=2&iiqpcid='); - request.respond( - 200, - responseHeader, - JSON.stringify({}) - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should not throw Uncaught TypeError when IntentIQ endpoint returns empty response', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = intentIqIdSubmodule.getId(defaultConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.contain('https://api.intentiq.com/profiles_engine/ProfilesEngineServlet?at=39&mi=10&dpi=10&pt=17&dpn=1&iiqidtype=2&iiqpcid='); - request.respond( - 204, - responseHeader, - '' - ); - expect(callBackSpy.calledOnce).to.be.true; - expect(request.response).to.equal(''); - }); - - it('should log an error and continue to callback if ajax request errors', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = intentIqIdSubmodule.getId(defaultConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.contain('https://api.intentiq.com/profiles_engine/ProfilesEngineServlet?at=39&mi=10&dpi=10&pt=17&dpn=1&iiqidtype=2&iiqpcid='); - request.respond( - 503, - responseHeader, - 'Unavailable' - ); - expect(callBackSpy.calledOnce).to.be.true; - }); - - it('should ignore {RESULT: NA} in get id', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = intentIqIdSubmodule.getId(defaultConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.contain('https://api.intentiq.com/profiles_engine/ProfilesEngineServlet?at=39&mi=10&dpi=10&pt=17&dpn=1&iiqidtype=2&iiqpcid='); - request.respond( - 200, - responseHeader, - JSON.stringify({RESULT: 'NA'}) - ); - expect(callBackSpy.calledOnce).to.be.true; - expect(callBackSpy.args[0][0]).to.be.undefined; - }); - - it('should ignore NA in get id', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = intentIqIdSubmodule.getId(defaultConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.contain('https://api.intentiq.com/profiles_engine/ProfilesEngineServlet?at=39&mi=10&dpi=10&pt=17&dpn=1&iiqidtype=2&iiqpcid='); - request.respond( - 200, - responseHeader, - 'NA' - ); - expect(callBackSpy.calledOnce).to.be.true; - expect(callBackSpy.args[0][0]).to.be.undefined; - }); - - it('should parse result from json response', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = intentIqIdSubmodule.getId(allConfigParams).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.contain('https://api.intentiq.com/profiles_engine/ProfilesEngineServlet?at=39&mi=10&dpi=10&pt=17&dpn=1&pcid=12&pai=11&iiqidtype=2&iiqpcid='); - request.respond( - 200, - responseHeader, - JSON.stringify({pid: 'test_pid', data: 'test_personid'}) - ); - expect(callBackSpy.calledOnce).to.be.true; - expect(callBackSpy.args[0][0]).to.be.eq('test_personid'); - }); -}); diff --git a/test/spec/modules/interactiveOffersBidAdapter_spec.js b/test/spec/modules/interactiveOffersBidAdapter_spec.js deleted file mode 100644 index 2ea620dc30c..00000000000 --- a/test/spec/modules/interactiveOffersBidAdapter_spec.js +++ /dev/null @@ -1,43 +0,0 @@ -import { expect } from 'chai'; -import {spec} from 'modules/interactiveOffersBidAdapter.js'; - -describe('Interactive Offers Prebbid.js Adapter', function() { - describe('isBidRequestValid function', function() { - let bid = {bidder: 'interactiveOffers', params: {pubid: 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; - }); - - it('returns false if any if the required params is missing', function() { - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - - it('returns false if any if the required params is not properly formatted', function() { - bid.params = {pubid: 'abcd123', tmax: 250}; - expect(spec.isBidRequestValid(bid)).to.be.false; - bid.params = {pubid: 100, tmax: '+250'}; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - describe('buildRequests function', function() { - let validBidRequests = [{bidder: 'interactiveOffers', params: {pubid: 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}]; - let bidderRequest = {bidderCode: 'interactiveOffers', auctionId: '1aad860c-e04b-482b-acac-0da55ed491c8', bidderRequestId: '1eb79bc9dd44a', bids: [{bidder: 'interactiveOffers', params: {pubid: 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() { - let request = spec.buildRequests(validBidRequests, bidderRequest); - expect(request.data).length !== 0; - }); - }); - describe('interpretResponse function', function() { - let 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': {}}; - let 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: {pubid: 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() { - let prebidResponses = spec.interpretResponse(openRTBResponse, prebidRequest); - expect(prebidResponses).to.not.be.empty; - expect(prebidResponses[0].meta.advertiserDomains[0]).to.equal('url.com'); - }); - }); -}); diff --git a/test/spec/modules/invibesBidAdapter_spec.js b/test/spec/modules/invibesBidAdapter_spec.js deleted file mode 100644 index ee3624b5b16..00000000000 --- a/test/spec/modules/invibesBidAdapter_spec.js +++ /dev/null @@ -1,842 +0,0 @@ -import {expect} from 'chai'; -import {spec, resetInvibes, stubDomainOptions, readGdprConsent} from 'modules/invibesBidAdapter.js'; - -describe('invibesBidAdapter:', function () { - const BIDDER_CODE = 'invibes'; - const PLACEMENT_ID = '12345'; - const ENDPOINT = 'https://bid.videostep.com/Bid/VideoAdContent'; - const SYNC_ENDPOINT = 'https://k.r66net.com/GetUserSync'; - - let bidRequests = [ - { - bidId: 'b1', - bidder: BIDDER_CODE, - bidderRequestId: 'r1', - params: { - placementId: PLACEMENT_ID - }, - adUnitCode: 'test-div', - auctionId: 'a1', - sizes: [ - [300, 250], - [400, 300], - [125, 125] - ], - transactionId: 't1', - userId: { - pubcid: 'pub-cid-code', - pubProvidedId: 'pub-provided-id' - } - }, { - bidId: 'b2', - bidder: BIDDER_CODE, - bidderRequestId: 'r2', - params: { - placementId: 'abcde' - }, - adUnitCode: 'test-div', - auctionId: 'a2', - sizes: [ - [300, 250], - [400, 300] - ], - transactionId: 't2' - } - ]; - - let StubbedPersistence = function (initialValue) { - var value = initialValue; - return { - load: function () { - let str = value || ''; - try { - return JSON.parse(str); - } catch (e) { - } - }, - save: function (obj) { - value = JSON.stringify(obj); - } - } - }; - - beforeEach(function () { - resetInvibes(); - document.cookie = ''; - this.cStub1 = sinon.stub(console, 'info'); - }); - - afterEach(function () { - this.cStub1.restore(); - }); - - describe('isBidRequestValid:', function () { - context('valid bid request:', function () { - it('returns true when bidder params.placementId is set', function () { - const validBid = { - bidder: BIDDER_CODE, - params: { - placementId: PLACEMENT_ID - } - } - - expect(spec.isBidRequestValid(validBid)).to.be.true; - }) - }); - - context('invalid bid request:', function () { - it('returns false when no params', function () { - const invalidBid = { - bidder: BIDDER_CODE - } - - expect(spec.isBidRequestValid(invalidBid)).to.be.false; - }); - - it('returns false when placementId is not set', function () { - const invalidBid = { - bidder: BIDDER_CODE, - params: { - id: '5' - } - } - - expect(spec.isBidRequestValid(invalidBid)).to.be.false; - }); - - it('returns false when bid response was previously received', function () { - const validBid = { - bidder: BIDDER_CODE, - params: { - placementId: PLACEMENT_ID - } - } - - top.window.invibes.bidResponse = {prop: 'prop'}; - expect(spec.isBidRequestValid(validBid)).to.be.false; - }); - }); - }); - - describe('buildRequests', function () { - it('sends bid request to ENDPOINT via GET', function () { - const request = spec.buildRequests(bidRequests); - expect(request.url).to.equal(ENDPOINT); - expect(request.method).to.equal('GET'); - }); - - it('sends cookies with the bid request', function () { - const request = spec.buildRequests(bidRequests); - expect(request.options.withCredentials).to.equal(true); - }); - - it('has location, html id, placement and width/height', function () { - const request = spec.buildRequests(bidRequests, {auctionStart: Date.now()}); - const parsedData = request.data; - expect(parsedData.location).to.exist; - expect(parsedData.videoAdHtmlId).to.exist; - expect(parsedData.vId).to.exist; - expect(parsedData.width).to.exist; - expect(parsedData.height).to.exist; - }); - - it('has capped ids if local storage variable is correctly formatted', function () { - top.window.invibes.optIn = 1; - top.window.invibes.purposes = [true, false, false, false, false, false, false, false, false, false]; - localStorage.ivvcap = '{"9731":[1,1768600800000]}'; - const request = spec.buildRequests(bidRequests, {auctionStart: Date.now()}); - expect(request.data.capCounts).to.equal('9731=1'); - }); - - it('does not have capped ids if local storage variable is correctly formatted but no opt in', function () { - localStorage.ivvcap = '{"9731":[1,1768600800000]}'; - const request = spec.buildRequests(bidRequests, {auctionStart: Date.now()}); - expect(request.data.capCounts).to.equal(''); - }); - - it('does not have capped ids if local storage variable is incorrectly formatted', function () { - localStorage.ivvcap = ':[1,1574334216992]}'; - const request = spec.buildRequests(bidRequests, {auctionStart: Date.now()}); - expect(request.data.capCounts).to.equal(''); - }); - - it('does not have capped ids if local storage variable is expired', function () { - localStorage.ivvcap = '{"9731":[1,1574330064104]}'; - const request = spec.buildRequests(bidRequests, {auctionStart: Date.now()}); - expect(request.data.capCounts).to.equal(''); - }); - - it('sends query string params from localstorage 1', function () { - localStorage.ivbs = JSON.stringify({bvci: 1}); - const request = spec.buildRequests(bidRequests, {auctionStart: Date.now()}); - expect(request.data.bvci).to.equal(1); - }); - - it('sends query string params from localstorage 2', function () { - localStorage.ivbs = JSON.stringify({invibbvlog: true}); - const request = spec.buildRequests(bidRequests, {auctionStart: Date.now()}); - 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}); - const request = spec.buildRequests(bidRequests, {auctionStart: Date.now()}); - expect(request.data.someparam).to.be.undefined; - }); - - it('sends all Placement Ids', function () { - const request = spec.buildRequests(bidRequests); - expect(JSON.parse(request.data.bidParamsJson).placementIds).to.contain(bidRequests[0].params.placementId); - expect(JSON.parse(request.data.bidParamsJson).placementIds).to.contain(bidRequests[1].params.placementId); - }); - - it('sends undefined lid when no cookie', function () { - let request = spec.buildRequests(bidRequests); - expect(request.data.lId).to.be.undefined; - }); - - it('sends lid when comes on cookie', function () { - top.window.invibes.optIn = 1; - top.window.invibes.purposes = [true, false, false, false, false, false, false, false, false, false]; - global.document.cookie = 'ivbsdid={"id":"dvdjkams6nkq","cr":' + Date.now() + ',"hc":0}'; - let bidderRequest = {gdprConsent: {vendorData: {vendorConsents: {436: true}}}}; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.lId).to.exist; - }); - - it('should send purpose 1', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendor: {consents: {436: true}}, - purpose: { - consents: { - 1: true, - 2: true, - 3: true, - 4: true, - 5: true, - 6: true, - 7: true, - 8: true, - 9: true, - 10: true - } - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.purposes.split(',')[0]).to.equal('true'); - }); - - it('should send purpose 2 & 7', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendor: {consents: {436: true}}, - purpose: { - consents: { - 1: true, - 2: true, - 3: true, - 4: true, - 5: true, - 6: true, - 7: true, - 8: true, - 9: true, - 10: true - } - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.purposes.split(',')[1] && request.data.purposes.split(',')[6]).to.equal('true'); - }); - - it('should send purpose 9', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendor: {consents: {436: true}}, - purpose: { - consents: { - 1: true, - 2: true, - 3: true, - 4: true, - 5: true, - 6: true, - 7: true, - 8: true, - 9: true, - 10: true - } - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.purposes.split(',')[9]).to.equal('true'); - }); - - it('should send legitimateInterests 2 & 7', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendor: {consents: {436: true}}, - purpose: { - consents: { - 1: true, - 2: true, - 3: true, - 4: true, - 5: true, - 6: true, - 7: true, - 8: true, - 9: true, - 10: true - }, - legitimateInterests: { - 1: true, - 2: true, - 3: true, - 4: true, - 5: true, - 6: true, - 7: true, - 8: true, - 9: true, - 10: true - } - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.li.split(',')[1] && request.data.li.split(',')[6]).to.equal('true'); - }); - it('should send oi = 0 when vendorData is null', function () { - let bidderRequest = { - gdprConsent: { - vendorData: null - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.oi).to.equal(0); - }); - - it('should send oi = 2 when consent was approved on tcf v2', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendor: {consents: {436: true}}, - purpose: { - consents: { - 1: true, - 2: true, - 3: true, - 4: true, - 5: true, - 6: true, - 7: true, - 8: true, - 9: true, - 10: true - } - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.oi).to.equal(2); - }); - it('should send oi = 0 when vendor consents for invibes are false on tcf v2', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendor: {consents: {436: false}}, - purpose: { - consents: { - 1: true, - 2: true, - 3: true, - 4: true, - 5: true, - 6: true, - 7: true, - 8: true, - 9: true, - 10: true - } - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.oi).to.equal(0); - }); - it('should send oi = 2 when vendor consent for invibes are false and vendor legitimate interest for invibes are true on tcf v2', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendor: {consents: {436: false}, legitimateInterests: {436: true}}, - purpose: { - consents: { - 1: true, - 2: true, - 3: true, - 4: true, - 5: true, - 6: true, - 7: true, - 8: true, - 9: true, - 10: true - } - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.oi).to.equal(2); - }); - it('should send oi = 0 when vendor consents and legitimate interests for invibes are false on tcf v2', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendor: {consents: {436: false}, legitimateInterests: {436: false}}, - purpose: { - consents: { - 1: true, - 2: true, - 3: true, - 4: true, - 5: true, - 6: true, - 7: true, - 8: true, - 9: true, - 10: true - } - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.oi).to.equal(0); - }); - it('should send oi = 0 when purpose consents is null', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendor: {consents: {436: false}}, - purpose: {} - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.oi).to.equal(0); - }); - - it('should send oi = 2 when purpose consents weren\'t approved on tcf v2', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendor: {consents: {436: true}}, - purpose: { - consents: { - 1: true, - 2: false, - 3: false, - 4: true, - 5: true, - 6: true, - 7: true, - 8: true, - 9: true, - 10: true - } - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.oi).to.equal(2); - }); - - it('should send oi = 2 when purpose consents are less then 10 on tcf v2', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendor: {consents: {436: true}}, - purpose: { - consents: { - 1: true, - 2: false, - 3: false, - 4: true, - 5: true - } - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.oi).to.equal(2); - }); - - it('should send oi = 4 when vendor consents are null on tcf v2', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendor: {consents: null}, - purpose: { - consents: { - 1: true, - 2: true, - 3: true, - 4: true, - 5: true, - 6: true, - 7: true, - 8: true, - 9: true, - 10: true - } - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.oi).to.equal(4); - }); - - it('should send oi = 4 when vendor consents for invibes is null on tcf v2', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendor: {consents: {436: null}}, - purpose: { - consents: { - 1: true, - 2: true, - 3: true, - 4: true, - 5: true, - 6: true, - 7: true, - 8: true, - 9: true, - 10: true - } - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.oi).to.equal(4); - }); - - it('should send oi = 4 when vendor consents for invibes is null on tcf v1', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendorConsents: {436: null}, - purposeConsents: { - 1: true, - 2: true, - 3: true, - 4: true, - 5: true - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.oi).to.equal(4); - }); - - it('should send oi = 4 when vendor consents consents are null on tcf v1', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendorConsents: null, - purposeConsents: { - 1: true, - 2: true, - 3: true, - 4: true, - 5: true - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.oi).to.equal(4); - }); - - it('should send oi = 2 when gdpr doesn\'t apply or has global consent', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: false, - hasGlobalConsent: true, - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.oi).to.equal(2); - }); - - it('should send oi = 2 when consent was approved on tcf v1', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendorConsents: {436: true}, - purposeConsents: { - 1: true, - 2: true, - 3: true, - 4: true, - 5: true - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.oi).to.equal(2); - }); - - it('should send oi = 2 when purpose consents weren\'t approved on tcf v1', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendorConsents: {436: true}, - purposeConsents: { - 1: false, - 2: false, - 3: true, - 4: true, - 5: true - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.oi).to.equal(2); - }); - - it('should send oi = 2 when purpose consents are less then 5 on tcf v1', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendorConsents: {436: true}, - purposeConsents: { - 1: false, - 2: false, - 3: true - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.oi).to.equal(2); - }); - - it('should send oi = 0 when vendor consents for invibes are false on tcf v1', function () { - let bidderRequest = { - gdprConsent: { - vendorData: { - gdprApplies: true, - hasGlobalConsent: false, - vendorConsents: {436: false}, - purposeConsents: { - 1: true, - 2: true, - 3: true, - 4: true, - 5: true - } - } - } - }; - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.oi).to.equal(0); - }); - }); - - describe('interpretResponse', function () { - let response = { - Ads: [{ - BidPrice: 0.5, - VideoExposedId: 123 - }], - BidModel: { - BidVersion: 1, - PlacementId: '12345', - AuctionStartTime: Date.now(), - CreativeHtml: '' - } - }; - - let expectedResponse = [{ - requestId: bidRequests[0].bidId, - cpm: 0.5, - width: 400, - height: 300, - creativeId: 123, - currency: 'EUR', - netRevenue: true, - ttl: 300, - ad: ` - - - - - ` - }]; - - context('when the response is not valid', function () { - it('handles response with no bids requested', function () { - let emptyResult = spec.interpretResponse({body: response}); - expect(emptyResult).to.be.empty; - }); - - it('handles empty response', function () { - let emptyResult = spec.interpretResponse(null, {bidRequests}); - expect(emptyResult).to.be.empty; - }); - - it('handles response with bidding is not configured', function () { - let emptyResult = spec.interpretResponse({body: {Ads: [{BidPrice: 1}]}}, {bidRequests}); - expect(emptyResult).to.be.empty; - }); - - it('handles response with no ads are received', function () { - let emptyResult = spec.interpretResponse({ - body: { - BidModel: {PlacementId: '12345'}, - AdReason: 'No ads' - } - }, {bidRequests}); - expect(emptyResult).to.be.empty; - }); - - it('handles response with no ads are received - no ad reason', function () { - let emptyResult = spec.interpretResponse({body: {BidModel: {PlacementId: '12345'}}}, {bidRequests}); - expect(emptyResult).to.be.empty; - }); - - it('handles response when no placement Id matches', function () { - let emptyResult = spec.interpretResponse({ - body: { - BidModel: {PlacementId: '123456'}, - Ads: [{BidPrice: 1}] - } - }, {bidRequests}); - expect(emptyResult).to.be.empty; - }); - - it('handles response when placement Id is not present', function () { - let emptyResult = spec.interpretResponse({BidModel: {}, Ads: [{BidPrice: 1}]}, {bidRequests}); - expect(emptyResult).to.be.empty; - }); - }); - - context('when the response is valid', function () { - it('responds with a valid bid', function () { - // top.window.invibes.setCookie('a', 'b', 370); - // top.window.invibes.setCookie('c', 'd', 0); - let result = spec.interpretResponse({body: response}, {bidRequests}); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('responds with a valid bid and uses logger', function () { - localStorage.InvibesDEBUG = true; - let 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 () { - localStorage.InvibesDEBUG = false; - let result = spec.interpretResponse({body: response}, {bidRequests}); - let secondResult = spec.interpretResponse({body: response}, {bidRequests}); - expect(secondResult).to.be.empty; - }); - }); - }); - - describe('getUserSyncs', function () { - it('returns an iframe if enabled', function () { - let response = spec.getUserSyncs({iframeEnabled: true}); - expect(response.type).to.equal('iframe'); - expect(response.url).to.include(SYNC_ENDPOINT); - }); - - it('returns an iframe with params if enabled', function () { - top.window.invibes.optIn = 1; - global.document.cookie = 'ivvbks=17639.0,1,2'; - let response = spec.getUserSyncs({iframeEnabled: true}); - expect(response.type).to.equal('iframe'); - expect(response.url).to.include(SYNC_ENDPOINT); - expect(response.url).to.include('optIn'); - expect(response.url).to.include('ivvbks'); - }); - - it('returns an iframe with params including if enabled', function () { - top.window.invibes.optIn = 1; - global.document.cookie = 'ivvbks=17639.0,1,2;ivbsdid={"id":"dvdjkams6nkq","cr":' + Date.now() + ',"hc":0}'; - let response = spec.getUserSyncs({iframeEnabled: true}); - expect(response.type).to.equal('iframe'); - expect(response.url).to.include(SYNC_ENDPOINT); - expect(response.url).to.include('optIn'); - expect(response.url).to.include('ivvbks'); - expect(response.url).to.include('ivbsdid'); - }); - - it('returns undefined if iframe not enabled ', function () { - let 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 deleted file mode 100644 index e13b16661b0..00000000000 --- a/test/spec/modules/invisiblyAnalyticsAdapter_spec.js +++ /dev/null @@ -1,583 +0,0 @@ -import invisiblyAdapter from 'modules/invisiblyAnalyticsAdapter.js'; -import { expect } from 'chai'; -let events = require('src/events'); -let constants = require('src/constants.json'); - -describe('Invisibly Analytics Adapter test suite', function () { - let xhr; - let requests = []; - const BID1 = { - width: 980, - height: 240, - cpm: 1.1, - timeToRespond: 200, - bidId: '2ecff0db240757', - requestId: '2ecff0db240757', - adId: '2ecff0db240757', - auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa', - adUnitCode: '/19968336/header-bid-tag-0', - adserverTargeting: { - hb_bidder: 'testBidder', - hb_adid: '2ecff0db240757', - hb_pb: 1.2, - hb_size: '640x480', - hb_source: 'client', - }, - getStatusCode() { - return CONSTANTS.STATUS.GOOD; - }, - }; - - const BID2 = Object.assign({}, BID1, { - width: 300, - height: 250, - cpm: 2.2, - timeToRespond: 300, - bidId: '3ecff0db240757', - requestId: '3ecff0db240757', - adId: '3ecff0db240757', - }); - - const BID3 = { - bidId: '4ecff0db240757', - requestId: '4ecff0db240757', - adId: '4ecff0db240757', - auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa', - adUnitCode: '/19968336/header-bid-tag1', - adserverTargeting: { - hb_bidder: 'testBidder', - hb_adid: '3bd4ebb1c900e2', - hb_pb: '1.500', - hb_size: '728x90', - hb_source: 'server', - }, - getStatusCode() { - return CONSTANTS.STATUS.NO_BID; - }, - }; - - const MOCK = { - config: { - provider: 'invisiblyAnalytics', - options: { - bundleId: '', - account: 'invisibly', - }, - }, - AUCTION_INIT: { - auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa', - }, - BID_REQUESTED: { - bidder: 'mockBidder', - auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa', - bidderRequestId: '1be65d7958826a', - bids: [ - { - bidder: 'mockBidder', - adUnitCode: 'panorama_d_1', - bidId: '2ecff0db240757', - }, - { - bidder: 'mockBidder', - adUnitCode: 'box_d_1', - bidId: '3ecff0db240757', - }, - { - bidder: 'mockBidder', - adUnitCode: 'box_d_2', - bidId: '4ecff0db240757', - }, - ], - start: 1519149562216, - }, - BID_RESPONSE: [BID1, BID2], - AUCTION_END: { - auctionId: 'test_timeout_auction_id', - timestamp: 1234567890, - timeout: 3000, - auctionEnd: 1234567990, - }, - BID_WON: { - bidderCode: 'appnexus', - width: 300, - height: 250, - adId: '1ebb82ec35375e', - mediaType: 'banner', - cpm: 0.5, - requestId: '1582271863760569973', - creative_id: '96846035', - creativeId: '96846035', - ttl: 60, - currency: 'USD', - netRevenue: true, - auctionId: '9c7b70b9-b6ab-4439-9e71-b7b382797c18', - responseTimestamp: 1537521629657, - requestTimestamp: 1537521629331, - bidder: 'appnexus', - adUnitCode: 'div-gpt-ad-1460505748561-0', - timeToRespond: 326, - size: '300x250', - status: 'rendered', - eventType: 'bidWon', - ad: 'some ad', - adUrl: 'ad url', - }, - BIDDER_DONE: { - bidderCode: 'mockBidder', - bids: [BID1, BID2, BID3], - }, - BID_TIMEOUT: [ - { - bidId: '2ecff0db240757', - auctionId: '25c6d7f5-699a-4bfc-87c9-996f915341fa', - }, - ], - BID_ADJUSTMENT: { - ad: 'html', - adId: '298bf14ecbafb', - cpm: 1.01, - creativeId: '2249:92806132', - currency: 'USD', - height: 250, - mediaType: 'banner', - requestId: '298bf14ecbafb', - size: '300x250', - source: 'client', - status: 'rendered', - statusMessage: 'Bid available', - timeToRespond: 421, - ttl: 300, - width: 300, - }, - NO_BID: { - testKey: false, - }, - SET_TARGETING: { - [BID1.adUnitCode]: BID1.adserverTargeting, - [BID3.adUnitCode]: BID3.adserverTargeting, - }, - REQUEST_BIDS: { - call: 'request', - }, - ADD_AD_UNITS: { call: 'addAdUnits' }, - AD_RENDER_FAILED: { call: 'adRenderFailed' }, - INVALID_EVENT: { - mockKey: 'this event should not emit', - }, - }; - - describe('Invisibly Analytic tests specs', function () { - beforeEach(function () { - xhr = sinon.useFakeXMLHttpRequest(); - requests = []; - xhr.onCreate = (xhr) => { - requests.push(xhr); - }; - sinon.stub(events, 'getEvents').returns([]); - sinon.spy(invisiblyAdapter, 'track'); - }); - - afterEach(function () { - invisiblyAdapter.disableAnalytics(); - events.getEvents.restore(); - invisiblyAdapter.track.restore(); - xhr.restore(); - }); - - describe('Send all events as & when they are captured', function () { - beforeEach(function () { - invisiblyAdapter.weightedFilter.filter = true; - }); - // specs to test invisibly account input to enableAnaylitcs - describe('monitor enableAnalytics method', function () { - it('should catch all events triggered with invisibly account config', function () { - invisiblyAdapter.enableAnalytics({ - provider: 'invisiblyAnalytics', - options: { - account: 'invisibly', - }, - }); - events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); - events.emit(constants.EVENTS.BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE); - events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON); - sinon.assert.callCount(invisiblyAdapter.track, 5); - }); - - it('should not catch events triggered without invisibly account config', function () { - invisiblyAdapter.enableAnalytics({ - provider: 'invisiblyAnalytics', - options: {}, - }); - - events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); - events.emit(constants.EVENTS.BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE); - events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON); - invisiblyAdapter.flush(); - sinon.assert.callCount(invisiblyAdapter.track, 0); - }); - // spec to test custom api endpoint - it('support custom endpoint', function () { - let custom_url = 'custom url'; - invisiblyAdapter.enableAnalytics({ - provider: 'invisiblyAnalytics', - options: { - url: custom_url, - bundleId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', - account: 'invisibly', - }, - }); - expect(invisiblyAdapter.getOptions().url).to.equal(custom_url); - }); - }); - - // spec for auction init event - it('auction init event', function () { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse( - requests[1].requestBody.substring(0) - ); - // pageView is default event initially hence expecting 2 requests - expect(requests.length).to.equal(2); - expect(requests[1].url).to.equal( - 'https://api.pymx5.com/v1/sites/events' - ); - expect(invisiblyEvents.event_data.auctionId).to.equal( - MOCK.AUCTION_INIT.auctionId - ); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_type).to.equal('PREBID_auctionInit'); - expect(invisiblyEvents.event_data.ver).to.equal(1); - }); - - // spec for bid adjustment event - it('bid adjustment event', function () { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.BID_ADJUSTMENT, MOCK.BID_ADJUSTMENT); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse( - requests[0].requestBody.substring(0) - ); - expect(requests.length).to.equal(1); - expect(requests[0].url).to.equal( - 'https://api.pymx5.com/v1/sites/events' - ); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_bidAdjustment'); - expect(invisiblyEvents.event_data.bidders.cpm).to.equal( - MOCK.BID_ADJUSTMENT.cpm - ); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); - - // spec for bid timeout event - it('bid timeout event', function () { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.BID_TIMEOUT, MOCK.BID_TIMEOUT); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse( - requests[0].requestBody.substring(0) - ); - expect(requests.length).to.equal(1); - expect(requests[0].url).to.equal( - 'https://api.pymx5.com/v1/sites/events' - ); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_bidTimeout'); - expect(invisiblyEvents.event_data.bidders.bidId).to.equal( - MOCK.BID_TIMEOUT.bidId - ); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); - - // spec for bid requested event - it('bid requested event', function () { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.BID_REQUESTED, MOCK.BID_REQUESTED); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse( - requests[0].requestBody.substring(0) - ); - expect(requests.length).to.equal(1); - expect(requests[0].url).to.equal( - 'https://api.pymx5.com/v1/sites/events' - ); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_bidRequested'); - expect(invisiblyEvents.event_data.auctionId).to.equal( - MOCK.BID_REQUESTED.auctionId - ); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); - - // spec for bid response event - it('bid response event', function () { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse( - requests[0].requestBody.substring(0) - ); - expect(requests.length).to.equal(1); - expect(requests[0].url).to.equal( - 'https://api.pymx5.com/v1/sites/events' - ); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_bidResponse'); - expect(invisiblyEvents.event_data.cpm).to.equal(MOCK.BID_REQUESTED.cpm); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); - - // spec for no bid event - it('no bid event', function () { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.NO_BID, MOCK.NO_BID); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse( - requests[0].requestBody.substring(0) - ); - expect(requests.length).to.equal(1); - expect(requests[0].url).to.equal( - 'https://api.pymx5.com/v1/sites/events' - ); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_noBid'); - expect(invisiblyEvents.event_data.noBid.testKey).to.equal( - MOCK.NO_BID.testKey - ); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); - - // spec for bid won event - it('bid won event', function () { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse( - requests[0].requestBody.substring(0) - ); - expect(requests.length).to.equal(1); - expect(requests[0].url).to.equal( - 'https://api.pymx5.com/v1/sites/events' - ); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_bidWon'); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); - - // spec for bidder done event - it('bidder done event', function () { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.BIDDER_DONE, MOCK.BIDDER_DONE); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse( - requests[0].requestBody.substring(0) - ); - expect(requests.length).to.equal(1); - expect(requests[0].url).to.equal( - 'https://api.pymx5.com/v1/sites/events' - ); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_bidderDone'); - expect(invisiblyEvents.event_data.bidderCode).to.equal( - MOCK.BIDDER_DONE.bidderCode - ); - expect(invisiblyEvents.event_data.bids.length).to.equal( - MOCK.BIDDER_DONE.bids.length - ); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); - - // spec for set targeting event - it('set targeting event', function () { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.SET_TARGETING, MOCK.SET_TARGETING); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse( - requests[0].requestBody.substring(0) - ); - expect(requests.length).to.equal(1); - expect(requests[0].url).to.equal( - 'https://api.pymx5.com/v1/sites/events' - ); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_setTargeting'); - expect( - invisiblyEvents.event_data.targetings[BID1.adUnitCode] - ).to.deep.equal(BID1.adserverTargeting); - expect( - invisiblyEvents.event_data.targetings[BID3.adUnitCode] - ).to.deep.equal(BID3.adserverTargeting); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); - - // spec for request bids event - it('request bids event', function () { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.REQUEST_BIDS, MOCK.REQUEST_BIDS); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse( - requests[0].requestBody.substring(0) - ); - expect(requests.length).to.equal(1); - expect(requests[0].url).to.equal( - 'https://api.pymx5.com/v1/sites/events' - ); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_requestBids'); - expect(invisiblyEvents.event_data.call).to.equal( - MOCK.REQUEST_BIDS.call - ); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); - - // spec for add ad units event - it('add ad units event', function () { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.ADD_AD_UNITS, MOCK.ADD_AD_UNITS); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse( - requests[0].requestBody.substring(0) - ); - expect(requests.length).to.equal(1); - expect(requests[0].url).to.equal( - 'https://api.pymx5.com/v1/sites/events' - ); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_addAdUnits'); - expect(invisiblyEvents.event_data.call).to.equal( - MOCK.ADD_AD_UNITS.call - ); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); - - // spec for ad render failed event - it('ad render failed event', function () { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.AD_RENDER_FAILED, MOCK.AD_RENDER_FAILED); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse( - requests[0].requestBody.substring(0) - ); - expect(requests.length).to.equal(1); - expect(requests[0].url).to.equal( - 'https://api.pymx5.com/v1/sites/events' - ); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_adRenderFailed'); - expect(invisiblyEvents.event_data.call).to.equal( - MOCK.AD_RENDER_FAILED.call - ); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); - - // spec for auction end event - it('auction end event', function () { - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); - invisiblyAdapter.flush(); - - const invisiblyEvents = JSON.parse( - requests[0].requestBody.substring(0) - ); - expect(requests.length).to.equal(1); - expect(requests[0].url).to.equal( - 'https://api.pymx5.com/v1/sites/events' - ); - expect(invisiblyEvents.event_data.pageViewId).to.exist; - expect(invisiblyEvents.event_data.ver).to.equal(1); - expect(invisiblyEvents.event_type).to.equal('PREBID_auctionEnd'); - expect(invisiblyEvents.event_data.auctionId).to.equal( - MOCK.AUCTION_END.auctionId - ); - sinon.assert.callCount(invisiblyAdapter.track, 1); - }); - - // should not call sendEvent for events not supported by the adapter - it('it should not call sendEvent for this event emit', function () { - sinon.spy(invisiblyAdapter, 'sendEvent'); - invisiblyAdapter.enableAnalytics(MOCK.config); - events.emit(constants.EVENTS.INVALID_EVENT, MOCK.INVALID_EVENT); - invisiblyAdapter.flush(); - - expect(requests.length).to.equal(0); - sinon.assert.callCount(invisiblyAdapter.track, 0); - sinon.assert.callCount(invisiblyAdapter.sendEvent, 0); - }); - - // spec to emit all events - it('track all event without errors', function () { - invisiblyAdapter.enableAnalytics(MOCK.config); - - events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); - events.emit(constants.EVENTS.BID_ADJUSTMENT, MOCK.BID_ADJUSTMENT); - events.emit(constants.EVENTS.BID_TIMEOUT, MOCK.BID_TIMEOUT); - events.emit(constants.EVENTS.BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE); - events.emit(constants.EVENTS.NO_BID, MOCK.NO_BID); - events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON); - events.emit(constants.EVENTS.BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(constants.EVENTS.SET_TARGETING, MOCK.SET_TARGETING); - events.emit(constants.EVENTS.REQUEST_BIDS, MOCK.REQUEST_BIDS); - events.emit(constants.EVENTS.ADD_AD_UNITS, MOCK.ADD_AD_UNITS); - events.emit(constants.EVENTS.AD_RENDER_FAILED, MOCK.AD_RENDER_FAILED); - - sinon.assert.callCount(invisiblyAdapter.track, 13); - }); - }); - - describe('Should not send any event even if they are caputured', function () { - beforeEach(function () { - invisiblyAdapter.weightedFilter.filter = false; - }); - it('it should not send any event', function () { - invisiblyAdapter.enableAnalytics({ - provider: 'invisiblyAnalytics', - options: { - account: 'invisibly', - }, - }); - - events.emit(constants.EVENTS.AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(constants.EVENTS.AUCTION_END, MOCK.AUCTION_END); - events.emit(constants.EVENTS.BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(constants.EVENTS.BID_RESPONSE, MOCK.BID_RESPONSE); - events.emit(constants.EVENTS.BID_WON, MOCK.BID_WON); - invisiblyAdapter.flush(); - - sinon.assert.callCount(invisiblyAdapter.sendEvent, 0); - sinon.assert.callCount(invisiblyAdapter.track, 0); - expect(requests.length).to.equal(0); - }); - }); - }); -}); diff --git a/test/spec/modules/ipromBidAdapter_spec.js b/test/spec/modules/ipromBidAdapter_spec.js deleted file mode 100644 index 535cc332b21..00000000000 --- a/test/spec/modules/ipromBidAdapter_spec.js +++ /dev/null @@ -1,193 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/ipromBidAdapter.js'; - -describe('iPROM Adapter', function () { - let bidRequests; - let bidderRequest; - - beforeEach(function () { - bidRequests = [ - { - bidder: 'iprom', - params: { - id: '1234', - dimension: '300x250', - }, - adUnitCode: '/19966331/header-bid-tag-1', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]], - } - }, - bidId: '29a72b151f7bd3', - auctionId: 'e36abb27-g3b1-1ad6-8a4c-701c8919d3hh', - bidderRequestId: '2z76da40m1b3cb8', - transactionId: 'j51lhf58-1ad6-g3b1-3j6s-912c9493g0gu' - } - ]; - - bidderRequest = { - timeout: 3000, - refererInfo: { - referer: 'https://adserver.si/index.html', - reachedTop: true, - numIframes: 1, - stack: [ - 'https://adserver.si/index.html', - 'https://adserver.si/iframe1.html', - ] - } - } - }); - - describe('validating bids', function () { - it('should accept valid bid', function () { - let validBid = { - bidder: 'iprom', - params: { - id: '1234', - dimension: '300x250', - }, - }; - - const isValid = spec.isBidRequestValid(validBid); - - expect(isValid).to.equal(true); - }); - - it('should reject bid if missing dimension and id', function () { - let invalidBid = { - bidder: 'iprom', - params: {} - }; - - const isValid = spec.isBidRequestValid(invalidBid); - - expect(isValid).to.equal(false); - }); - - it('should reject bid if missing dimension', function () { - let invalidBid = { - bidder: 'iprom', - params: { - id: '1234', - } - }; - - const isValid = spec.isBidRequestValid(invalidBid); - - expect(isValid).to.equal(false); - }); - - it('should reject bid if dimension is not a string', function () { - let invalidBid = { - bidder: 'iprom', - params: { - id: '1234', - dimension: 404, - } - }; - - const isValid = spec.isBidRequestValid(invalidBid); - - expect(isValid).to.equal(false); - }); - - it('should reject bid if missing id', function () { - let invalidBid = { - bidder: 'iprom', - params: { - dimension: '300x250', - } - }; - - const isValid = spec.isBidRequestValid(invalidBid); - - expect(isValid).to.equal(false); - }); - - it('should reject bid if id is not a string', function () { - let invalidBid = { - bidder: 'iprom', - params: { - id: 1234, - dimension: '300x250', - } - }; - - const isValid = spec.isBidRequestValid(invalidBid); - - expect(isValid).to.equal(false); - }); - }); - - describe('building requests', function () { - it('should go to correct endpoint', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - - expect(request.method).to.exist; - expect(request.method).to.equal('POST'); - expect(request.url).to.exist; - expect(request.url).to.equal('https://core.iprom.net/programmatic'); - }); - - it('should add referer info', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - const requestparse = JSON.parse(request.data); - - expect(requestparse.referer).to.exist; - expect(requestparse.referer.referer).to.equal('https://adserver.si/index.html'); - }); - - it('should add adapter version', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - const requestparse = JSON.parse(request.data); - - expect(requestparse.version).to.exist; - }); - - it('should contain id and dimension', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - const requestparse = JSON.parse(request.data); - - expect(requestparse.bids[0].params.id).to.equal('1234'); - expect(requestparse.bids[0].params.dimension).to.equal('300x250'); - }); - }); - - describe('handling responses', function () { - it('should return complete bid response', function () { - const serverResponse = { - body: [{ - requestId: '29a72b151f7bd3', - cpm: 0.5, - width: '300', - height: '250', - creativeId: 1234, - ad: 'Iprom Header bidding example' - } - ]}; - - const request = spec.buildRequests(bidRequests, bidderRequest); - const bids = spec.interpretResponse(serverResponse, request); - - expect(bids).to.be.lengthOf(1); - expect(bids[0].requestId).to.equal('29a72b151f7bd3'); - expect(bids[0].cpm).to.equal(0.5); - expect(bids[0].width).to.equal('300'); - expect(bids[0].height).to.equal('250'); - expect(bids[0].ad).to.have.length.above(1); - }); - - it('should return empty bid response', function () { - const emptyServerResponse = { - body: [] - }; - - const request = spec.buildRequests(bidRequests, bidderRequest); - const bids = spec.interpretResponse(emptyServerResponse, request); - - expect(bids).to.be.lengthOf(0); - }); - }); -}); diff --git a/test/spec/modules/ironsourceBidAdapter_spec.js b/test/spec/modules/ironsourceBidAdapter_spec.js deleted file mode 100644 index cca928ff28b..00000000000 --- a/test/spec/modules/ironsourceBidAdapter_spec.js +++ /dev/null @@ -1,381 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/ironsourceBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import { config } from 'src/config.js'; -import { VIDEO } from '../../../src/mediaTypes.js'; - -const ENDPOINT = 'https://hb.yellowblue.io/hb'; -const TEST_ENDPOINT = 'https://hb.yellowblue.io/hb-test'; -const TTL = 360; - -describe('ironsourceAdapter', 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 bid = { - 'bidder': spec.code, - 'adUnitCode': 'adunit-code', - 'sizes': [['640', '480']], - 'params': { - 'isOrg': 'jdye8weeyirk00000001' - } - }; - - it('should return true when required params are passed', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not found', function () { - const newBid = Object.assign({}, bid); - delete newBid.params; - newBid.params = { - 'isOrg': null - }; - expect(spec.isBidRequestValid(newBid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const bidRequests = [ - { - 'bidder': spec.code, - 'adUnitCode': 'adunit-code', - 'sizes': [[640, 480]], - 'params': { - 'isOrg': 'jdye8weeyirk00000001' - }, - 'bidId': '299ffc8cca0b87', - 'bidderRequestId': '1144f487e563f9', - 'auctionId': 'bfc420c3-8577-4568-9766-a8a935fb620d', - } - ]; - - const testModeBidRequests = [ - { - 'bidder': spec.code, - 'adUnitCode': 'adunit-code', - 'sizes': [[640, 480]], - 'params': { - 'isOrg': 'jdye8weeyirk00000001', - 'testMode': true - }, - 'bidId': '299ffc8cca0b87', - 'bidderRequestId': '1144f487e563f9', - 'auctionId': 'bfc420c3-8577-4568-9766-a8a935fb620d', - } - ]; - - const bidderRequest = { - bidderCode: 'ironsource', - } - - const customSessionId = '12345678'; - - it('sends bid request to ENDPOINT via GET', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.url).to.equal(ENDPOINT); - expect(request.method).to.equal('GET'); - } - }); - - it('sends bid request to test ENDPOINT via GET', function () { - const requests = spec.buildRequests(testModeBidRequests, bidderRequest); - for (const request of requests) { - expect(request.url).to.equal(TEST_ENDPOINT); - expect(request.method).to.equal('GET'); - } - }); - - it('should send the correct bid Id', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data.bid_id).to.equal('299ffc8cca0b87'); - } - }); - - it('sends the is_wrapper query param', function () { - bidRequests[0].params.isWrapper = true; - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data.is_wrapper).to.equal(true); - } - }); - - it('sends the custom session id as a query param', function () { - bidRequests[0].params.sessionId = customSessionId; - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data.session_id).to.equal(customSessionId); - } - }); - - it('should send the correct width and height', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.have.property('width', 640); - expect(request.data).to.have.property('height', 480); - } - }); - - it('should respect syncEnabled option', function() { - config.setConfig({ - userSync: { - syncEnabled: false, - filterSettings: { - all: { - bidders: '*', - filter: 'include' - } - } - } - }); - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.not.have.property('cs_method'); - } - }); - - it('should respect "iframe" filter settings', function () { - config.setConfig({ - userSync: { - syncEnabled: true, - filterSettings: { - iframe: { - bidders: [spec.code], - filter: 'include' - } - } - } - }); - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.have.property('cs_method', 'iframe'); - } - }); - - it('should respect "all" filter settings', function () { - config.setConfig({ - userSync: { - syncEnabled: true, - filterSettings: { - all: { - bidders: [spec.code], - filter: 'include' - } - } - } - }); - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.have.property('cs_method', 'iframe'); - } - }); - - it('should send the pixel user sync param if userSync is enabled and no "iframe" or "all" configs are present', function () { - config.setConfig({ - userSync: { - syncEnabled: true - } - }); - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.have.property('cs_method', 'pixel'); - } - }); - - it('should respect total exclusion', function() { - config.setConfig({ - userSync: { - syncEnabled: true, - filterSettings: { - image: { - bidders: [spec.code], - filter: 'exclude' - }, - iframe: { - bidders: [spec.code], - filter: 'exclude' - } - } - } - }); - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.not.have.property('cs_method'); - } - }); - - it('should have us_privacy param if usPrivacy is available in the bidRequest', function () { - const bidderRequestWithUSP = Object.assign({uspConsent: '1YNN'}, bidderRequest); - const requests = spec.buildRequests(bidRequests, bidderRequestWithUSP); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.have.property('us_privacy', '1YNN'); - } - }); - - it('should have an empty us_privacy param if usPrivacy is missing in the bidRequest', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.not.have.property('us_privacy'); - } - }); - - it('should not send the gdpr param if gdprApplies is false in the bidRequest', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {gdprApplies: false}}, bidderRequest); - const requests = spec.buildRequests(bidRequests, bidderRequestWithGDPR); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.not.have.property('gdpr'); - expect(request.data).to.not.have.property('gdpr_consent'); - } - }); - - 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 requests = spec.buildRequests(bidRequests, bidderRequestWithGDPR); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.have.property('gdpr', true); - expect(request.data).to.have.property('gdpr_consent', 'test-consent-string'); - } - }); - - it('should have schain param if it is available in the bidRequest', () => { - const schain = { - ver: '1.0', - complete: 1, - nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1 }], - }; - bidRequests[0].schain = schain; - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.have.property('schain', '1.0,1!indirectseller.com,00001,,,,'); - } - }); - }); - - describe('interpretResponse', function () { - const response = { - cpm: 12.5, - vastXml: '', - width: 640, - height: 480, - requestId: '21e12606d47ba7', - netRevenue: true, - currency: 'USD' - }; - - it('should get correct bid response', function () { - let expectedResponse = [ - { - requestId: '21e12606d47ba7', - cpm: 12.5, - width: 640, - height: 480, - creativeId: '21e12606d47ba7', - currency: 'USD', - netRevenue: true, - ttl: TTL, - vastXml: '', - mediaType: VIDEO - } - ]; - const result = spec.interpretResponse({ body: response }); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - }) - - describe('getUserSyncs', function() { - const imageSyncResponse = { - body: { - userSyncPixels: [ - 'https://image-sync-url.test/1', - 'https://image-sync-url.test/2', - 'https://image-sync-url.test/3' - ] - } - }; - - const iframeSyncResponse = { - body: { - userSyncURL: 'https://iframe-sync-url.test' - } - }; - - it('should register all img urls from the response', function() { - const syncs = spec.getUserSyncs({ pixelEnabled: true }, [imageSyncResponse]); - expect(syncs).to.deep.equal([ - { - type: 'image', - url: 'https://image-sync-url.test/1' - }, - { - type: 'image', - url: 'https://image-sync-url.test/2' - }, - { - type: 'image', - url: 'https://image-sync-url.test/3' - } - ]); - }); - - it('should register the iframe url from the response', function() { - const syncs = spec.getUserSyncs({ iframeEnabled: true }, [iframeSyncResponse]); - expect(syncs).to.deep.equal([ - { - type: 'iframe', - url: 'https://iframe-sync-url.test' - } - ]); - }); - - it('should register both image and iframe urls from the responses', function() { - const syncs = spec.getUserSyncs({ pixelEnabled: true, iframeEnabled: true }, [iframeSyncResponse, imageSyncResponse]); - expect(syncs).to.deep.equal([ - { - type: 'iframe', - url: 'https://iframe-sync-url.test' - }, - { - type: 'image', - url: 'https://image-sync-url.test/1' - }, - { - type: 'image', - url: 'https://image-sync-url.test/2' - }, - { - type: 'image', - url: 'https://image-sync-url.test/3' - } - ]); - }); - - it('should handle an empty response', function() { - const syncs = spec.getUserSyncs({ iframeEnabled: true }, []); - expect(syncs).to.deep.equal([]); - }); - - it('should handle when user syncs are disabled', function() { - const syncs = spec.getUserSyncs({ pixelEnabled: false }, [imageSyncResponse]); - expect(syncs).to.deep.equal([]); - }); - }) -}); diff --git a/test/spec/modules/ixBidAdapter_spec.js b/test/spec/modules/ixBidAdapter_spec.js deleted file mode 100644 index e0d45913fd9..00000000000 --- a/test/spec/modules/ixBidAdapter_spec.js +++ /dev/null @@ -1,2148 +0,0 @@ -import * as utils from 'src/utils.js'; -import { config } from 'src/config.js'; -import { expect } from 'chai'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import { spec } from 'modules/ixBidAdapter.js'; -import { createEidsArray } from 'modules/userId/eids.js'; - -describe('IndexexchangeAdapter', function () { - const IX_SECURE_ENDPOINT = 'https://htlb.casalemedia.com/cygnus'; - const VIDEO_ENDPOINT_VERSION = 8.1; - const BANNER_ENDPOINT_VERSION = 7.2; - - const SAMPLE_SCHAIN = { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'indirectseller.com', - 'sid': '00001', - 'hp': 1 - }, - { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 2 - } - ] - }; - const div_many_sizes = [ - [300, 250], - [600, 410], - [336, 280], - [400, 300], - [320, 50], - [360, 360], - [250, 250], - [320, 250], - [400, 250], - [387, 359], - [300, 50], - [372, 250], - [320, 320], - [412, 412], - [327, 272], - [312, 260], - [384, 320], - [335, 250], - [366, 305], - [374, 250], - [375, 375], - [272, 391], - [364, 303], - [414, 414], - [366, 375], - [272, 360], - [364, 373], - [366, 359], - [320, 100], - [360, 250], - [468, 60], - [480, 300], - [600, 400], - [600, 300], - [33, 28], - [40, 30], - [32, 5], - [36, 36], - [25, 25], - [320, 25], - [400, 25], - [387, 35], - [300, 5], - [372, 20], - [320, 32], - [412, 41], - [327, 27], - [312, 26], - [384, 32], - [335, 25], - [366, 30], - [374, 25], - [375, 37], - [272, 31], - [364, 303], - [414, 41], - [366, 35], - [272, 60], - [364, 73], - [366, 59], - [320, 10], - [360, 25], - [468, 6], - [480, 30], - [600, 40], - [600, 30] - ]; - - const ONE_VIDEO = [ - { - bidder: 'ix', - params: { - siteId: '456', - video: { - skippable: false, - mimes: [ - 'video/mp4', - 'video/webm' - ], - minduration: 0, - maxduration: 60, - protocols: [2] - }, - size: [400, 100] - }, - sizes: [[400, 100]], - mediaTypes: { - video: { - context: 'instream', - playerSize: [[400, 100]] - } - }, - adUnitCode: 'div-gpt-ad-1460505748562-0', - transactionId: '173f49a8-7549-4218-a23c-e7ba59b47230', - bidId: '1a2b3c4e', - bidderRequestId: '11a22b33c44e', - auctionId: '1aa2bb3cc4de', - schain: SAMPLE_SCHAIN - } - ]; - - const ONE_BANNER = [ - { - bidder: 'ix', - params: { - siteId: '123', - size: [300, 250] - }, - sizes: [[300, 250]], - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - adUnitCode: 'div-gpt-ad-1460505748561-0', - transactionId: '173f49a8-7549-4218-a23c-e7ba59b47229', - bidId: '1a2b3c4d', - bidderRequestId: '11a22b33c44d', - auctionId: '1aa2bb3cc4dd', - schain: SAMPLE_SCHAIN - } - ]; - - const DEFAULT_BANNER_VALID_BID = [ - { - bidder: 'ix', - params: { - siteId: '123', - size: [300, 250] - }, - sizes: [[300, 250], [300, 600]], - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - adUnitCode: 'div-gpt-ad-1460505748561-0', - transactionId: '173f49a8-7549-4218-a23c-e7ba59b47229', - bidId: '1a2b3c4d', - bidderRequestId: '11a22b33c44d', - auctionId: '1aa2bb3cc4dd', - schain: SAMPLE_SCHAIN - } - ]; - - const DEFAULT_VIDEO_VALID_BID = [ - { - bidder: 'ix', - params: { - siteId: '456', - video: { - skippable: false, - mimes: [ - 'video/mp4', - 'video/webm' - ], - minduration: 0, - maxduration: 60, - protocols: [2] - }, - size: [400, 100] - }, - sizes: [[400, 100], [200, 400]], - mediaTypes: { - video: { - context: 'instream', - playerSize: [[400, 100], [200, 400]] - } - }, - adUnitCode: 'div-gpt-ad-1460505748562-0', - transactionId: '173f49a8-7549-4218-a23c-e7ba59b47230', - bidId: '1a2b3c4e', - bidderRequestId: '11a22b33c44e', - auctionId: '1aa2bb3cc4de', - schain: SAMPLE_SCHAIN - } - ]; - - const DEFAULT_MULTIFORMAT_BANNER_VALID_BID = [ - { - bidder: 'ix', - params: { - siteId: '123', - size: [300, 250] - }, - sizes: [[300, 250], [300, 600]], - mediaTypes: { - video: { - context: 'outstream', - playerSize: [[400, 100]] - }, - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - adUnitCode: 'div-gpt-ad-1460505748562-0', - transactionId: '173f49a8-7549-4218-a23c-e7ba59b47230', - bidId: '1a2b3c4e', - bidderRequestId: '11a22b33c44e', - auctionId: '1aa2bb3cc4de', - schain: SAMPLE_SCHAIN - } - ]; - - const DEFAULT_MULTIFORMAT_VIDEO_VALID_BID = [ - { - bidder: 'ix', - params: { - siteId: '456', - video: { - skippable: false, - mimes: [ - 'video/mp4', - 'video/webm' - ], - minduration: 0, - maxduration: 60, - protocols: [1] - }, - size: [400, 100] - }, - sizes: [[300, 250], [300, 600]], - mediaTypes: { - video: { - context: 'outstream', - playerSize: [[400, 100]] - }, - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - adUnitCode: 'div-gpt-ad-1460505748562-0', - transactionId: '173f49a8-7549-4218-a23c-e7ba59b47230', - bidId: '1a2b3c4e', - bidderRequestId: '11a22b33c44e', - auctionId: '1aa2bb3cc4de', - schain: SAMPLE_SCHAIN - } - ]; - - const DEFAULT_BANNER_BID_RESPONSE = { - cur: 'USD', - id: '11a22b33c44d', - seatbid: [ - { - bid: [ - { - crid: '12345', - adomain: ['www.abc.com'], - adid: '14851455', - impid: '1a2b3c4d', - cid: '3051266', - price: 100, - w: 300, - h: 250, - id: '1', - ext: { - dspid: 50, - pricelevel: '_100', - advbrandid: 303325, - advbrand: 'OECTA' - }, - adm: '' - } - ], - seat: '3970' - } - ] - }; - - const DEFAULT_BANNER_BID_RESPONSE_WITHOUT_ADOMAIN = { - cur: 'USD', - id: '11a22b33c44d', - seatbid: [ - { - bid: [ - { - crid: '12345', - adid: '14851455', - impid: '1a2b3c4d', - cid: '3051266', - price: 100, - w: 300, - h: 250, - id: '1', - ext: { - dspid: 50, - pricelevel: '_100', - advbrandid: 303325, - advbrand: 'OECTA' - }, - adm: '' - } - ], - seat: '3970' - } - ] - }; - - const DEFAULT_VIDEO_BID_RESPONSE = { - cur: 'USD', - id: '1aa2bb3cc4de', - seatbid: [ - { - bid: [ - { - crid: '12346', - adomain: ['www.abcd.com'], - adid: '14851456', - impid: '1a2b3c4e', - cid: '3051267', - price: 110, - id: '2', - ext: { - vasturl: 'www.abcd.com/vast', - errorurl: 'www.abcd.com/error', - dspid: 51, - pricelevel: '_110', - advbrandid: 303326, - advbrand: 'OECTB' - } - } - ], - seat: '3971' - } - ] - }; - - const DEFAULT_OPTION = { - gdprConsent: { - gdprApplies: true, - consentString: '3huaa11=qu3198ae', - vendorData: {} - }, - refererInfo: { - referer: 'https://www.prebid.org', - canonicalUrl: 'https://www.prebid.org/the/link/to/the/page' - } - }; - - const DEFAULT_IDENTITY_RESPONSE = { - IdentityIp: { - responsePending: false, - data: { - source: 'identityinc.com', - uids: [ - { - id: 'identityid' - } - ] - } - } - }; - - const DEFAULT_BIDDER_REQUEST_DATA = { - ac: 'j', - r: JSON.stringify({ - id: '345', - imp: [ - { - id: '1a2b3c4e', - video: { - w: 640, - h: 480, - placement: 1 - } - } - ], - site: { - ref: 'https://ref.com/ref.html', - page: 'https://page.com' - }, - }), - s: '21', - sd: 1, - t: 1000, - v: 8.1 - }; - - const DEFAULT_USERID_DATA = { - idl_env: '1234-5678-9012-3456', // Liveramp - netId: 'testnetid123', // NetId - IDP: 'userIDP000', // IDP - fabrickId: 'fabrickId9000', // FabrickId - uid2: {id: 'testuid2'} // UID 2.0 - }; - - const DEFAULT_USERIDASEIDS_DATA = createEidsArray(DEFAULT_USERID_DATA); - - const DEFAULT_USERID_PAYLOAD = [ - { - source: 'liveramp.com', - uids: [{ - id: DEFAULT_USERID_DATA.idl_env, - ext: { - rtiPartner: 'idl' - } - }] - }, { - source: 'netid.de', - uids: [{ - id: DEFAULT_USERID_DATA.netId, - ext: { - rtiPartner: 'NETID' - } - }] - }, { - source: 'neustar.biz', - uids: [{ - id: DEFAULT_USERID_DATA.fabrickId, - ext: { - rtiPartner: 'fabrickId' - } - }] - }, { - source: 'zeotap.com', - uids: [{ - id: DEFAULT_USERID_DATA.IDP, - ext: { - rtiPartner: 'zeotapIdPlus' - } - }] - }, { - source: 'uidapi.com', - uids: [{ - // when calling createEidsArray, UID2's getValue func returns .id, which is then set in uids - id: DEFAULT_USERID_DATA.uid2.id, - ext: { - rtiPartner: 'UID2' - } - }] - } - ]; - - const DEFAULT_USERID_BID_DATA = { - lotamePanoramaId: 'bd738d136bdaa841117fe9b331bb4' - }; - - describe('inherited functions', function () { - it('should exists and is a function', function () { - const adapter = newBidder(spec); - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('getUserSync tests', function () { - it('UserSync test : check type = iframe, check usermatch URL', function () { - const syncOptions = { - 'iframeEnabled': true - } - let userSync = spec.getUserSyncs(syncOptions); - expect(userSync[0].type).to.equal('iframe'); - const USER_SYNC_URL = 'https://js-sec.indexww.com/um/ixmatch.html'; - expect(userSync[0].url).to.equal(USER_SYNC_URL); - }); - - it('When iframeEnabled is false, no userSync should be returned', function () { - const syncOptions = { - 'iframeEnabled': false - } - let userSync = spec.getUserSyncs(syncOptions); - expect(userSync).to.be.an('array').that.is.empty; - }); - }); - - describe('isBidRequestValid', function () { - it('should return true when required params found for a banner or video ad', function () { - expect(spec.isBidRequestValid(DEFAULT_BANNER_VALID_BID[0])).to.equal(true); - expect(spec.isBidRequestValid(DEFAULT_VIDEO_VALID_BID[0])).to.equal(true); - }); - - it('should return true when optional bidFloor params found for an ad', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid.params.bidFloor = 50; - bid.params.bidFloorCur = 'USD'; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return true when siteID is number', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid.params.siteId = 123; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when siteID is missing', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - delete bid.params.siteId; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when size is missing', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - delete bid.params.size; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when size array is wrong length', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid.params.size = [ - 300, - 250, - 250 - ]; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when size array is array of strings', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid.params.size = ['300', '250']; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when mediaTypes is not banner or video', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid.mediaTypes = { - native: { - sizes: [[300, 250]] - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when mediaTypes.banner does not have sizes', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid.mediaTypes = { - banner: { - size: [[300, 250]] - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when mediaTypes.video does not have sizes', function () { - const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID[0]); - bid.mediaTypes = { - video: { - size: [[300, 250]] - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when mediaType is native', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - delete bid.params.mediaTypes; - bid.mediaType = 'native'; - bid.sizes = [[300, 250]]; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return true when mediaType is missing and has sizes', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - delete bid.mediaTypes; - bid.sizes = [[300, 250]]; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return true when mediaType is banner', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - delete bid.mediaTypes; - bid.mediaType = 'banner'; - bid.sizes = [[300, 250]]; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return true when mediaType is video', function () { - const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID[0]); - delete bid.mediaTypes; - bid.mediaType = 'video'; - bid.sizes = [[400, 100]]; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return true for banner bid when there are multiple mediaTypes (banner, outstream)', function () { - const bid = utils.deepClone(DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0]); - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return true for video bid when there are multiple mediaTypes (banner, outstream)', function () { - const bid = utils.deepClone(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0]); - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when there is only bidFloor', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid.params.bidFloor = 50; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when there is only bidFloorCur', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid.params.bidFloorCur = 'USD'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when bidFloor is string', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid.params.bidFloor = '50'; - bid.params.bidFloorCur = 'USD'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when bidFloorCur is number', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid.params.bidFloor = 50; - bid.params.bidFloorCur = 70; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when required video properties are missing on both adunit & param levels', function () { - const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID[0]); - delete bid.params.video.mimes; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return true when required video properties are at the adunit level', function () { - const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID[0]); - delete bid.params.video.mimes; - bid.mediaTypes.video.mimes = ['video/mp4']; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return true if protocols exists but protocol doesn\'t', function () { - const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID[0]); - expect(spec.isBidRequestValid(bid)).to.equal(true); - delete bid.params.video.protocols; - bid.mediaTypes.video.protocols = 1; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return true if protocol exists but protocols doesn\'t', function () { - const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID[0]); - delete bid.params.video.protocols; - bid.params.video.protocol = 1; - expect(spec.isBidRequestValid(bid)).to.equal(true); - delete bid.params.video.protocol; - bid.mediaTypes.video.protocol = 1; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false if both protocol/protocols are missing', function () { - const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID[0]); - delete bid.params.video.protocols; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('Roundel alias adapter', function () { - const vaildBids = [DEFAULT_BANNER_VALID_BID, DEFAULT_VIDEO_VALID_BID, DEFAULT_MULTIFORMAT_BANNER_VALID_BID, DEFAULT_MULTIFORMAT_VIDEO_VALID_BID]; - const ALIAS_OPTIONS = Object.assign({ - bidderCode: 'roundel' - }, DEFAULT_OPTION); - - it('should not build requests for mediaTypes if liveramp data is unavaliable', function () { - vaildBids.forEach((validBid) => { - const request = spec.buildRequests(validBid, ALIAS_OPTIONS); - expect(request).to.be.an('array'); - expect(request).to.have.lengthOf(0); - }); - }); - - it('should build requests for mediaTypes if liveramp data is avaliable', function () { - vaildBids.forEach((validBid) => { - const cloneValidBid = utils.deepClone(validBid); - cloneValidBid[0].userIdAsEids = utils.deepClone(DEFAULT_USERIDASEIDS_DATA); - const request = spec.buildRequests(cloneValidBid, ALIAS_OPTIONS); - const payload = JSON.parse(request[0].data.r); - expect(request).to.be.an('array'); - expect(request).to.have.lengthOf(1); - expect(payload.user.eids).to.have.lengthOf(5); - expect(payload.user.eids).to.deep.include(DEFAULT_USERID_PAYLOAD[0]); - }); - }); - }); - - describe('buildRequestsIdentity', function () { - let request; - let query; - let testCopy; - - beforeEach(function () { - window.headertag = {}; - window.headertag.getIdentityInfo = function () { - return testCopy; - }; - request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0]; - query = request.data; - }); - - afterEach(function () { - delete window.headertag; - }); - - describe('buildRequestSingleRTI', function () { - before(function () { - testCopy = JSON.parse(JSON.stringify(DEFAULT_IDENTITY_RESPONSE)); - }); - - it('payload should have correct format and value (single identity partner)', function () { - const payload = JSON.parse(query.r); - - expect(payload.user).to.exist; - expect(payload.user.eids).to.exist; - expect(payload.user.eids).to.be.an('array'); - expect(payload.user.eids).to.have.lengthOf(1); - }); - - it('identity data in impression should have correct format and value (single identity partner)', function () { - const impression = JSON.parse(query.r).user.eids; - expect(impression[0].source).to.equal(testCopy.IdentityIp.data.source); - expect(impression[0].uids[0].id).to.equal(testCopy.IdentityIp.data.uids[0].id); - }); - }); - - describe('buildRequestMultipleIds', function () { - before(function () { - testCopy = JSON.parse(JSON.stringify(DEFAULT_IDENTITY_RESPONSE)); - testCopy.IdentityIp.data.uids.push( - { - id: '1234567' - }, - { - id: '2019-04-01TF2:34:41' - } - ); - }); - - it('payload should have correct format and value (single identity w/ multi ids)', function () { - const payload = JSON.parse(query.r); - - expect(payload.user).to.exist; - expect(payload.user.eids).to.exist; - expect(payload.user.eids).to.be.an('array'); - expect(payload.user.eids).to.have.lengthOf(1); - }); - - it('identity data in impression should have correct format and value (single identity w/ multi ids)', function () { - const impression = JSON.parse(query.r).user.eids; - - expect(impression[0].source).to.equal(testCopy.IdentityIp.data.source); - expect(impression[0].uids).to.have.lengthOf(3); - }); - }); - - describe('buildRequestMultipleRTI', function () { - before(function () { - testCopy = JSON.parse(JSON.stringify(DEFAULT_IDENTITY_RESPONSE)); - testCopy.JackIp = { - responsePending: false, - data: { - source: 'jackinc.com', - uids: [ - { - id: 'jackid' - } - ] - } - } - testCopy.GenericIp = { - responsePending: false, - data: { - source: 'genericip.com', - uids: [ - { - id: 'genericipenvelope' - } - ] - } - } - }); - - it('payload should have correct format and value (multiple identity partners)', function () { - const payload = JSON.parse(query.r); - - expect(payload.user).to.exist; - expect(payload.user.eids).to.exist; - expect(payload.user.eids).to.be.an('array'); - expect(payload.user.eids).to.have.lengthOf(3); - }); - - it('identity data in impression should have correct format and value (multiple identity partners)', function () { - const impression = JSON.parse(query.r).user.eids; - - expect(impression[0].source).to.equal(testCopy.IdentityIp.data.source); - expect(impression[0].uids).to.have.lengthOf(1); - - expect(impression[1].source).to.equal(testCopy.JackIp.data.source); - expect(impression[1].uids).to.have.lengthOf(1); - - expect(impression[2].source).to.equal(testCopy.GenericIp.data.source); - expect(impression[2].uids).to.have.lengthOf(1); - }); - }); - - describe('buildRequestNoData', function () { - beforeEach(function () { - testCopy = JSON.parse(JSON.stringify(DEFAULT_IDENTITY_RESPONSE)); - }); - - it('payload should not have any user eids with an undefined identity data response', function () { - window.headertag.getIdentityInfo = function () { - return undefined; - }; - request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0]; - query = request.data; - const payload = JSON.parse(query.r); - - expect(payload.user).to.exist; - expect(payload.user.eids).to.not.exist; - }); - - it('payload should have user eids if least one partner data is available', function () { - testCopy.GenericIp = { - responsePending: true, - data: {} - } - request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0]; - query = request.data; - const payload = JSON.parse(query.r); - - expect(payload.user).to.exist; - expect(payload.user.eids).to.exist; - }); - - it('payload should not have any user eids if identity data is pending for all partners', function () { - testCopy.IdentityIp.responsePending = true; - request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0]; - query = request.data; - const payload = JSON.parse(query.r); - - expect(payload.user).to.exist; - expect(payload.user.eids).to.not.exist; - }); - - it('payload should not have any user eids if identity data is pending or not available for all partners', function () { - testCopy.IdentityIp.responsePending = false; - testCopy.IdentityIp.data = {}; - request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0]; - query = request.data; - const payload = JSON.parse(query.r); - - expect(payload.user).to.exist; - expect(payload.user.eids).to.not.exist; - }); - }); - }); - - describe('buildRequestsUserId', function () { - let validIdentityResponse; - let validUserIdPayload; - - beforeEach(function () { - window.headertag = {}; - window.headertag.getIdentityInfo = function () { - return validIdentityResponse; - }; - }); - - afterEach(function () { - delete window.headertag; - }); - - it('IX adapter reads supported user modules from Prebid and adds it to Video', function () { - const cloneValidBid = utils.deepClone(DEFAULT_VIDEO_VALID_BID); - cloneValidBid[0].userIdAsEids = utils.deepClone(DEFAULT_USERIDASEIDS_DATA); - const request = spec.buildRequests(cloneValidBid, DEFAULT_OPTION)[0]; - const payload = JSON.parse(request.data.r); - - expect(payload.user.eids).to.have.lengthOf(5); - expect(payload.user.eids).to.deep.include(DEFAULT_USERID_PAYLOAD[0]); - expect(payload.user.eids).to.deep.include(DEFAULT_USERID_PAYLOAD[1]); - expect(payload.user.eids).to.deep.include(DEFAULT_USERID_PAYLOAD[2]); - expect(payload.user.eids).to.deep.include(DEFAULT_USERID_PAYLOAD[3]); - expect(payload.user.eids).to.deep.include(DEFAULT_USERID_PAYLOAD[4]); - }); - - it('We continue to send in IXL identity info and Prebid takes precedence over IXL', function () { - validIdentityResponse = { - AdserverOrgIp: { - responsePending: false, - data: { - source: 'adserver.org', - uids: [ - { - id: '1234-5678-9012-3456', - ext: { - rtiPartner: 'TDID' - } - }, - { - id: 'FALSE', - ext: { - rtiPartner: 'TDID_LOOKUP' - } - }, - { - id: '2020-06-24T14:43:48.860Z', - ext: { - rtiPartner: 'TDID_CREATED_AT' - } - } - ] - } - }, - MerkleIp: { - responsePending: false, - data: { - source: 'merkle.com', - uids: [{ - id: '1234-5678-9012-3456', - ext: { - keyID: '1234-5678', - enc: 1 - } - }] - } - }, - LiveRampIp: { - source: 'liveramp.com', - uids: [ - { - id: '0000-1234-4567-8901', - ext: { - rtiPartner: 'idl' - } - } - ] - }, - NetIdIp: { - source: 'netid.de', - uids: [ - { - id: 'testnetid', - ext: { - rtiPartner: 'NETID' - } - } - ] - }, - NeustarIp: { - source: 'neustar.biz', - uids: [ - { - id: 'testfabrick', - ext: { - rtiPartner: 'fabrickId' - } - } - ] - }, - ZeotapIp: { - source: 'zeotap.com', - uids: [ - { - id: 'testzeotap', - ext: { - rtiPartner: 'zeotapIdPlus' - } - } - ] - } - }; - - const cloneValidBid = utils.deepClone(DEFAULT_BANNER_VALID_BID); - cloneValidBid[0].userIdAsEids = utils.deepClone(DEFAULT_USERIDASEIDS_DATA); - - const request = spec.buildRequests(cloneValidBid, DEFAULT_OPTION)[0]; - const payload = JSON.parse(request.data.r); - - validUserIdPayload = utils.deepClone(DEFAULT_USERID_PAYLOAD); - validUserIdPayload.push({ - source: 'merkle.com', - uids: [{ - id: '1234-5678-9012-3456', - ext: { - keyID: '1234-5678', - enc: 1 - } - }] - }) - validUserIdPayload.push({ - source: 'adserver.org', - uids: [ - { - id: '1234-5678-9012-3456', - ext: { - rtiPartner: 'TDID' - } - }, - { - id: 'FALSE', - ext: { - rtiPartner: 'TDID_LOOKUP' - } - }, - { - id: '2020-06-24T14:43:48.860Z', - ext: { - rtiPartner: 'TDID_CREATED_AT' - } - } - ] - }) - - expect(payload.user).to.exist; - expect(payload.user.eids).to.have.lengthOf(7); - - expect(payload.user.eids).to.deep.include(validUserIdPayload[0]); - expect(payload.user.eids).to.deep.include(validUserIdPayload[1]); - expect(payload.user.eids).to.deep.include(validUserIdPayload[2]); - expect(payload.user.eids).to.deep.include(validUserIdPayload[3]); - expect(payload.user.eids).to.deep.include(validUserIdPayload[4]); - expect(payload.user.eids).to.deep.include(validUserIdPayload[5]); - expect(payload.user.eids).to.deep.include(validUserIdPayload[6]); - }); - - it('IXL and Prebid are mutually exclusive', function () { - validIdentityResponse = { - LiveIntentIp: { - responsePending: false, - data: { - source: 'liveintent.com', - uids: [{ - id: '1234-5678-9012-3456', - ext: { - keyID: '1234-5678', - rtiPartner: 'LDID', - enc: 1 - } - }] - } - } - }; - - const cloneValidBid = utils.deepClone(DEFAULT_VIDEO_VALID_BID); - cloneValidBid[0].userIdAsEids = utils.deepClone(DEFAULT_USERIDASEIDS_DATA); - - const request = spec.buildRequests(cloneValidBid, DEFAULT_OPTION)[0]; - - validUserIdPayload = utils.deepClone(DEFAULT_USERID_PAYLOAD); - validUserIdPayload.push({ - source: 'liveintent.com', - uids: [{ - id: '1234-5678-9012-3456', - ext: { - keyID: '1234-5678', - rtiPartner: 'LDID', - enc: 1 - } - }] - }); - - const payload = JSON.parse(request.data.r); - expect(payload.user.eids).to.have.lengthOf(6); - expect(payload.user.eids).to.deep.include(validUserIdPayload[0]); - expect(payload.user.eids).to.deep.include(validUserIdPayload[1]); - expect(payload.user.eids).to.deep.include(validUserIdPayload[2]); - expect(payload.user.eids).to.deep.include(validUserIdPayload[3]); - expect(payload.user.eids).to.deep.include(validUserIdPayload[4]); - expect(payload.user.eids).to.deep.include(validUserIdPayload[5]); - }); - }); - - describe('getUserIds', function () { - it('request should contain userId information if configured and within bid request', function () { - config.setConfig({ - userSync: { - syncDelay: 0, - userIds: [ - { name: 'lotamePanoramaId' }, - { name: 'merkleId' }, - { name: 'parrableId' }, - ] - } - }); - - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid.userId = DEFAULT_USERID_BID_DATA; - - const request = spec.buildRequests([bid], DEFAULT_OPTION)[0]; - const r = JSON.parse(request.data.r); - - expect(r.ext.ixdiag.userIds).to.be.an('array'); - expect(r.ext.ixdiag.userIds.should.include('lotamePanoramaId')); - expect(r.ext.ixdiag.userIds.should.not.include('merkleId')); - expect(r.ext.ixdiag.userIds.should.not.include('parrableId')); - }); - }); - - describe('buildRequests', function () { - const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0]; - const requestUrl = request.url; - const requestMethod = request.method; - const query = request.data; - - const bidWithoutSchain = utils.deepClone(DEFAULT_BANNER_VALID_BID); - delete bidWithoutSchain[0].schain; - const requestWithoutSchain = spec.buildRequests(bidWithoutSchain, DEFAULT_OPTION)[0]; - const queryWithoutSchain = requestWithoutSchain.data; - - const bidWithoutMediaType = utils.deepClone(DEFAULT_BANNER_VALID_BID); - delete bidWithoutMediaType[0].mediaTypes; - bidWithoutMediaType[0].sizes = [[300, 250], [300, 600]]; - const requestWithoutMediaType = spec.buildRequests(bidWithoutMediaType, DEFAULT_OPTION)[0]; - const queryWithoutMediaType = requestWithoutMediaType.data; - - it('request should be made to IX endpoint with GET method', function () { - expect(requestMethod).to.equal('GET'); - expect(requestUrl).to.equal(IX_SECURE_ENDPOINT); - }); - - it('query object (version, siteID and request) should be correct', function () { - expect(query.v).to.equal(BANNER_ENDPOINT_VERSION); - expect(query.s).to.equal(DEFAULT_BANNER_VALID_BID[0].params.siteId); - expect(query.r).to.exist; - expect(query.ac).to.equal('j'); - expect(query.sd).to.equal(1); - expect(query.nf).not.to.exist; - }); - - it('payload should have correct format and value', function () { - const payload = JSON.parse(query.r); - expect(payload.id).to.equal(DEFAULT_BANNER_VALID_BID[0].bidderRequestId); - expect(payload.site).to.exist; - expect(payload.site.page).to.equal(DEFAULT_OPTION.refererInfo.referer); - expect(payload.site.ref).to.equal(document.referrer); - expect(payload.ext).to.exist; - expect(payload.ext.source).to.equal('prebid'); - expect(payload.source.ext.schain).to.deep.equal(SAMPLE_SCHAIN); - expect(payload.imp).to.exist; - expect(payload.imp).to.be.an('array'); - expect(payload.imp).to.have.lengthOf(2); - }); - - it('payload should not include schain when not provided', function () { - const payload = JSON.parse(queryWithoutSchain.r); - expect(payload.source).to.not.exist; // source object currently only written for schain - }); - - it('impression should have correct format and value', function () { - const impression = JSON.parse(query.r).imp[0]; - const sidValue = `${DEFAULT_BANNER_VALID_BID[0].params.size[0].toString()}x${DEFAULT_BANNER_VALID_BID[0].params.size[1].toString()}`; - - expect(impression.id).to.equal(DEFAULT_BANNER_VALID_BID[0].bidId); - expect(impression.banner).to.exist; - expect(impression.banner.w).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[0]); - expect(impression.banner.h).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[1]); - expect(impression.banner.topframe).to.exist; - expect(impression.banner.topframe).to.be.oneOf([0, 1]); - expect(impression.ext).to.exist; - expect(impression.ext.siteID).to.equal(DEFAULT_BANNER_VALID_BID[0].params.siteId.toString()); - expect(impression.ext.sid).to.equal(sidValue); - }); - - it('video impression has #priceFloors floors', function () { - const bid = utils.deepClone(ONE_VIDEO[0]); - const flr = 5.5 - const floorInfo = {floor: flr, currency: 'USD'}; - bid.getFloor = function () { - return floorInfo; - } - - // check if floors are in imp - const requestBidFloor = spec.buildRequests([bid])[0]; - const imp1 = JSON.parse(requestBidFloor.data.r).imp[0]; - expect(imp1.bidfloor).to.equal(flr); - expect(imp1.bidfloorcur).to.equal('USD'); - expect(imp1.ext.fl).to.equal('p'); - }); - - it('banner imp has floors from #priceFloors module', function () { - const floor300x250 = 3.25 - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]) - - const floorInfo = { floor: floor300x250, currency: 'USD' }; - bid.getFloor = function () { - return floorInfo; - }; - - // check if floors are in imp - const requestBidFloor = spec.buildRequests([bid])[0]; - const imp1 = JSON.parse(requestBidFloor.data.r).imp[0]; - - expect(imp1.bidfloorcur).to.equal('USD'); - expect(imp1.bidfloor).to.equal(floor300x250); - expect(imp1.ext.fl).to.equal('p'); - }); - - it('ix adapter floors chosen over #priceFloors ', function () { - const bid = utils.deepClone(ONE_BANNER[0]); - - const floorhi = 4.5 - const floorlow = 3.5 - - bid.params.bidFloor = floorhi - bid.params.bidFloorCur = 'USD' - - const floorInfo = { floor: floorlow, currency: 'USD' }; - bid.getFloor = function () { - return floorInfo; - }; - - // check if floors are in imp - const requestBidFloor = spec.buildRequests([bid])[0]; - const imp1 = JSON.parse(requestBidFloor.data.r).imp[0]; - expect(imp1.bidfloor).to.equal(floorhi); - expect(imp1.bidfloorcur).to.equal(bid.params.bidFloorCur); - expect(imp1.ext.fl).to.equal('x'); - }); - - it(' #priceFloors floors chosen over ix adapter floors', function () { - const bid = utils.deepClone(ONE_BANNER[0]); - - const floorhi = 4.5 - const floorlow = 3.5 - - bid.params.bidFloor = floorlow - bid.params.bidFloorCur = 'USD' - - const floorInfo = { floor: floorhi, currency: 'USD' }; - bid.getFloor = function () { - return floorInfo; - }; - - // check if floors are in imp - const requestBidFloor = spec.buildRequests([bid])[0]; - const imp1 = JSON.parse(requestBidFloor.data.r).imp[0]; - expect(imp1.bidfloor).to.equal(floorhi); - expect(imp1.bidfloorcur).to.equal(bid.params.bidFloorCur); - expect(imp1.ext.fl).to.equal('p'); - }); - - it('impression should have bidFloor and bidFloorCur if configured', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid.params.bidFloor = 50; - bid.params.bidFloorCur = 'USD'; - const requestBidFloor = spec.buildRequests([bid])[0]; - const impression = JSON.parse(requestBidFloor.data.r).imp[0]; - - expect(impression.bidfloor).to.equal(bid.params.bidFloor); - expect(impression.bidfloorcur).to.equal(bid.params.bidFloorCur); - expect(impression.ext.fl).to.equal('x'); - }); - - it('missing sizes #priceFloors ', function () { - const bid = utils.deepClone(ONE_BANNER[0]); - bid.mediaTypes.banner.sizes.push([500, 400]) - - const floorInfo = { floor: 3.25, currency: 'USD' }; - bid.getFloor = function () { - return floorInfo; - }; - - sinon.spy(bid, 'getFloor'); - - const requestBidFloor = spec.buildRequests([bid])[0]; - // called getFloor with 300 x 250 - expect(bid.getFloor.getCall(0).args[0].mediaType).to.equal('banner'); - expect(bid.getFloor.getCall(0).args[0].size[0]).to.equal(300); - expect(bid.getFloor.getCall(0).args[0].size[1]).to.equal(250); - - // called getFloor with 500 x 400 - expect(bid.getFloor.getCall(1).args[0].mediaType).to.equal('banner'); - expect(bid.getFloor.getCall(1).args[0].size[0]).to.equal(500); - expect(bid.getFloor.getCall(1).args[0].size[1]).to.equal(400); - - // both will have same floors due to mock getFloor - const imp1 = JSON.parse(requestBidFloor.data.r).imp[0]; - expect(imp1.bidfloor).to.equal(3.25); - expect(imp1.bidfloorcur).to.equal('USD'); - - const imp2 = JSON.parse(requestBidFloor.data.r).imp[1]; - expect(imp2.bidfloor).to.equal(3.25); - expect(imp2.bidfloorcur).to.equal('USD'); - }); - - it('#pricefloors inAdUnit, banner impressions should have floors', function () { - const bid = utils.deepClone(ONE_BANNER[0]); - - const flr = 4.3 - bid.floors = { - currency: 'USD', - schema: { - delimiter: '|', - fields: ['mediaType', 'size'] - }, - values: { - 'banner|300x250': flr, - 'banner|600x500': 6.5, - 'banner|*': 7.5 - } - }; - const floorInfo = { floor: flr, currency: 'USD' }; - bid.getFloor = function () { - return floorInfo; - }; - - sinon.spy(bid, 'getFloor'); - - const requestBidFloor = spec.buildRequests([bid])[0]; - // called getFloor with 300 x 250 - expect(bid.getFloor.getCall(0).args[0].mediaType).to.equal('banner'); - expect(bid.getFloor.getCall(0).args[0].size[0]).to.equal(300); - expect(bid.getFloor.getCall(0).args[0].size[1]).to.equal(250); - - const imp1 = JSON.parse(requestBidFloor.data.r).imp[0]; - expect(imp1.bidfloor).to.equal(flr); - expect(imp1.bidfloorcur).to.equal('USD'); - }); - - it('payload without mediaType should have correct format and value', function () { - const payload = JSON.parse(queryWithoutMediaType.r); - - expect(payload.id).to.equal(DEFAULT_BANNER_VALID_BID[0].bidderRequestId); - expect(payload.site).to.exist; - expect(payload.site.page).to.equal(DEFAULT_OPTION.refererInfo.referer); - expect(payload.site.ref).to.equal(document.referrer); - expect(payload.ext).to.exist; - expect(payload.ext.source).to.equal('prebid'); - expect(payload.imp).to.exist; - expect(payload.imp).to.be.an('array'); - expect(payload.imp).to.have.lengthOf(1); - }); - - it('impression without mediaType should have correct format and value', function () { - const impression = JSON.parse(queryWithoutMediaType.r).imp[0]; - const sidValue = `${DEFAULT_BANNER_VALID_BID[0].params.size[0].toString()}x${DEFAULT_BANNER_VALID_BID[0].params.size[1].toString()}`; - - expect(impression.id).to.equal(DEFAULT_BANNER_VALID_BID[0].bidId); - expect(impression.banner).to.exist; - expect(impression.banner.w).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[0]); - expect(impression.banner.h).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[1]); - expect(impression.banner.topframe).to.exist; - expect(impression.banner.topframe).to.be.oneOf([0, 1]); - expect(impression.ext).to.exist; - expect(impression.ext.siteID).to.equal(DEFAULT_BANNER_VALID_BID[0].params.siteId.toString()); - expect(impression.ext.sid).to.equal(sidValue); - }); - - it('impression should have sid if id is configured as number', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid.params.id = 50; - const requestBidFloor = spec.buildRequests([bid])[0]; - const impression = JSON.parse(requestBidFloor.data.r).imp[0]; - - expect(impression.id).to.equal(DEFAULT_BANNER_VALID_BID[0].bidId); - expect(impression.banner).to.exist; - expect(impression.banner.w).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[0]); - expect(impression.banner.h).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[1]); - expect(impression.banner.topframe).to.exist; - expect(impression.banner.topframe).to.be.oneOf([0, 1]); - expect(impression.ext).to.exist; - expect(impression.ext.siteID).to.equal(DEFAULT_BANNER_VALID_BID[0].params.siteId.toString()); - expect(impression.ext.sid).to.equal('50'); - }); - - it('impression should have sid if id is configured as string', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid.params.id = 'abc'; - const requestBidFloor = spec.buildRequests([bid])[0]; - const impression = JSON.parse(requestBidFloor.data.r).imp[0]; - expect(impression.id).to.equal(DEFAULT_BANNER_VALID_BID[0].bidId); - expect(impression.banner).to.exist; - expect(impression.banner.w).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[0]); - expect(impression.banner.h).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[1]); - expect(impression.banner.topframe).to.exist; - expect(impression.banner.topframe).to.be.oneOf([0, 1]); - expect(impression.ext).to.exist; - expect(impression.ext.siteID).to.equal(DEFAULT_BANNER_VALID_BID[0].params.siteId.toString()); - expect(impression.ext.sid).to.equal('abc'); - }); - - it('should add first party data to page url in bid request if it exists in config', function () { - config.setConfig({ - ix: { - firstPartyData: { - ab: 123, - cd: '123#ab', - 'e/f': 456, - 'h?g': '456#cd' - } - } - }); - - const requestWithFirstPartyData = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0]; - const pageUrl = JSON.parse(requestWithFirstPartyData.data.r).site.page; - const expectedPageUrl = DEFAULT_OPTION.refererInfo.referer + '?ab=123&cd=123%23ab&e%2Ff=456&h%3Fg=456%23cd'; - expect(pageUrl).to.equal(expectedPageUrl); - }); - - it('should not set first party data if it is not an object', function () { - config.setConfig({ - ix: { - firstPartyData: 500 - } - }); - - const requestFirstPartyDataNumber = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0]; - const pageUrl = JSON.parse(requestFirstPartyDataNumber.data.r).site.page; - - expect(pageUrl).to.equal(DEFAULT_OPTION.refererInfo.referer); - }); - - it('should not set first party or timeout if it is not present', function () { - config.setConfig({ - ix: {} - }); - - const requestWithoutConfig = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0]; - const pageUrl = JSON.parse(requestWithoutConfig.data.r).site.page; - - expect(pageUrl).to.equal(DEFAULT_OPTION.refererInfo.referer); - expect(requestWithoutConfig.data.t).to.be.undefined; - }); - - it('should not set first party or timeout if it is setConfig is not called', function () { - const requestWithoutConfig = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION)[0]; - const pageUrl = JSON.parse(requestWithoutConfig.data.r).site.page; - - expect(pageUrl).to.equal(DEFAULT_OPTION.refererInfo.referer); - expect(requestWithoutConfig.data.t).to.be.undefined; - }); - - it('should set timeout if publisher set it through setConfig', function () { - config.setConfig({ - ix: { - timeout: 500 - } - }); - const requestWithTimeout = spec.buildRequests(DEFAULT_BANNER_VALID_BID)[0]; - - expect(requestWithTimeout.data.t).to.equal(500); - }); - - it('should set timeout if timeout is a string', function () { - config.setConfig({ - ix: { - timeout: '500' - } - }); - const requestStringTimeout = spec.buildRequests(DEFAULT_BANNER_VALID_BID)[0]; - - expect(requestStringTimeout.data.t).to.be.undefined; - }); - - it('request should contain both banner and video requests', function () { - const request = spec.buildRequests([DEFAULT_BANNER_VALID_BID[0], DEFAULT_VIDEO_VALID_BID[0]]); - - const bannerImp = JSON.parse(request[0].data.r).imp[0]; - expect(JSON.parse(request[0].data.r).imp).to.have.lengthOf(2); - expect(JSON.parse(request[0].data.v)).to.equal(BANNER_ENDPOINT_VERSION); - expect(bannerImp.id).to.equal(DEFAULT_BANNER_VALID_BID[0].bidId); - expect(bannerImp.id).to.equal(DEFAULT_BANNER_VALID_BID[0].bidId); - expect(bannerImp.banner).to.exist; - expect(bannerImp.banner.w).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[0]); - expect(bannerImp.banner.h).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[1]); - - const videoImp = JSON.parse(request[1].data.r).imp[0]; - expect(JSON.parse(request[1].data.v)).to.equal(VIDEO_ENDPOINT_VERSION); - expect(videoImp.id).to.equal(DEFAULT_VIDEO_VALID_BID[0].bidId); - expect(videoImp.video).to.exist; - expect(videoImp.video.w).to.equal(DEFAULT_VIDEO_VALID_BID[0].params.size[0]); - expect(videoImp.video.h).to.equal(DEFAULT_VIDEO_VALID_BID[0].params.size[1]); - }); - - it('single request under 8k size limit for large ad unit', function () { - const options = {}; - const bid1 = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid1.mediaTypes.banner.sizes = div_many_sizes; - const requests = spec.buildRequests([bid1], options); - - const reqSize = new Blob([`${requests[0].url}?${utils.parseQueryStringParameters(requests[0].data)}`]).size; - expect(requests).to.be.an('array'); - expect(requests).to.have.lengthOf(1); - expect(reqSize).to.be.lessThan(8000); - }); - - it('2 requests due to 2 ad units, one larger than url size', function () { - const bid1 = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid1.mediaTypes.banner.sizes = div_many_sizes; - bid1.params.siteId = '124'; - bid1.adUnitCode = 'div-gpt-1' - bid1.transactionId = '152e36d1-1241-4242-t35e-y1dv34d12315'; - bid1.bidId = '2f6g5s5e'; - - const requests = spec.buildRequests([bid1, DEFAULT_BANNER_VALID_BID[0]], DEFAULT_OPTION); - expect(requests).to.be.an('array'); - expect(requests).to.have.lengthOf(2); - expect(requests[0].data.sn).to.be.equal(0); - expect(requests[1].data.sn).to.be.equal(1); - }); - - it('6 ad units should generate only 4 requests', function () { - const bid1 = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid1.mediaTypes.banner.sizes = div_many_sizes; - bid1.params.siteId = '121'; - bid1.adUnitCode = 'div-gpt-1' - bid1.transactionId = 'tr1'; - bid1.bidId = '2f6g5s5e'; - - const bid2 = utils.deepClone(bid1); - bid2.transactionId = 'tr2'; - - const bid3 = utils.deepClone(bid1); - bid3.transactionId = 'tr3'; - - const bid4 = utils.deepClone(bid1); - bid4.transactionId = 'tr4'; - - const bid5 = utils.deepClone(bid1); - bid5.transactionId = 'tr5'; - - const bid6 = utils.deepClone(bid1); - bid6.transactionId = 'tr6'; - - const requests = spec.buildRequests([bid1, bid2, bid3, bid4, bid5, bid6], DEFAULT_OPTION); - - expect(requests).to.be.an('array'); - expect(requests).to.have.lengthOf(4); - - // check if seq number increases - for (var i = 0; i < requests.length; i++) { - const reqSize = new Blob([`${requests[i].url}?${utils.parseQueryStringParameters(requests[i].data)}`]).size; - expect(reqSize).to.be.lessThan(8000); - let payload = JSON.parse(requests[i].data.r); - if (requests.length > 1) { - expect(requests[i].data.sn).to.equal(i); - } - expect(payload.source.ext.schain).to.deep.equal(SAMPLE_SCHAIN); - } - }); - - it('multiple ad units in one request', function () { - const bid1 = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid1.mediaTypes.banner.sizes = [[300, 250], [300, 600], [100, 200]]; - bid1.params.siteId = '121'; - bid1.adUnitCode = 'div-gpt-1' - bid1.transactionId = 'tr1'; - bid1.bidId = '2f6g5s5e'; - - const bid2 = utils.deepClone(bid1); - bid2.transactionId = 'tr2'; - bid2.mediaTypes.banner.sizes = [[220, 221], [222, 223], [300, 250]]; - const bid3 = utils.deepClone(bid1); - bid3.transactionId = 'tr3'; - bid3.mediaTypes.banner.sizes = [[330, 331], [332, 333], [300, 250]]; - - const requests = spec.buildRequests([bid1, bid2, bid3], DEFAULT_OPTION); - expect(requests).to.be.an('array'); - expect(requests).to.have.lengthOf(1); - - const impressions = JSON.parse(requests[0].data.r).imp; - expect(impressions).to.be.an('array'); - expect(impressions).to.have.lengthOf(9); - }); - - it('request should contain the extra banner ad sizes that IX is not configured for using the first site id in the ad unit', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid.sizes.push([336, 280], [970, 90]); - bid.mediaTypes.banner.sizes.push([336, 280], [970, 90]); - const bid2 = utils.deepClone(bid); - bid2.params.siteId = '124'; - bid2.params.size = [300, 600]; - bid2.params.bidId = '2b3c4d5e'; - - const request = spec.buildRequests([bid, bid2], DEFAULT_OPTION)[0]; - const impressions = JSON.parse(request.data.r).imp; - - expect(impressions).to.be.an('array'); - expect(impressions).to.have.lengthOf(4); - - expect(impressions[0].ext.siteID).to.equal(DEFAULT_BANNER_VALID_BID[0].params.siteId.toString()) - expect(impressions[1].ext.siteID).to.equal(bid2.params.siteId) - expect(impressions[2].ext.siteID).to.equal(DEFAULT_BANNER_VALID_BID[0].params.siteId.toString()) - expect(impressions[3].ext.siteID).to.equal(DEFAULT_BANNER_VALID_BID[0].params.siteId.toString()) - - expect(impressions[0].banner.w).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[0]); - expect(impressions[0].banner.h).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[1]); - expect(impressions[1].banner.w).to.equal(bid2.params.size[0]); - expect(impressions[1].banner.h).to.equal(bid2.params.size[1]); - expect(impressions[2].banner.w).to.equal(bid.mediaTypes.banner.sizes[2][0]); - expect(impressions[2].banner.h).to.equal(bid.mediaTypes.banner.sizes[2][1]); - expect(impressions[3].banner.w).to.equal(bid.mediaTypes.banner.sizes[3][0]); - expect(impressions[3].banner.h).to.equal(bid.mediaTypes.banner.sizes[3][1]); - }); - - it('request should contain the extra banner ad sizes and their corresponding site ids when there is multiple ad units', function () { - const bid = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid.params.siteId = '124'; - bid.adUnitCode = 'div-gpt-ad-156456451554-1' - bid.transactionId = '152e36d1-1241-4242-t35e-y1dv34d12315'; - bid.bidId = '2f6g5s5e'; - bid.params.size = [336, 280] - bid.sizes = [[336, 280], [970, 90]] - bid.mediaTypes.banner.sizes = [[336, 280], [970, 90]] - - const request = spec.buildRequests([DEFAULT_BANNER_VALID_BID[0], bid], DEFAULT_OPTION)[0]; - - const impressions = JSON.parse(request.data.r).imp; - expect(impressions).to.be.an('array'); - expect(impressions).to.have.lengthOf(4); - expect(impressions[0].ext.siteID).to.equal(DEFAULT_BANNER_VALID_BID[0].params.siteId.toString()); - expect(impressions[1].ext.siteID).to.equal(bid.params.siteId); - expect(impressions[2].ext.siteID).to.equal(DEFAULT_BANNER_VALID_BID[0].params.siteId.toString()); - expect(impressions[3].ext.siteID).to.equal(bid.params.siteId); - - expect(impressions[0].banner.w).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[0]); - expect(impressions[0].banner.h).to.equal(DEFAULT_BANNER_VALID_BID[0].params.size[1]); - - expect(impressions[1].banner.w).to.equal(bid.params.size[0]); - expect(impressions[1].banner.h).to.equal(bid.params.size[1]); - - expect(impressions[2].banner.w).to.equal(DEFAULT_BANNER_VALID_BID[0].mediaTypes.banner.sizes[1][0]); - expect(impressions[2].banner.h).to.equal(DEFAULT_BANNER_VALID_BID[0].mediaTypes.banner.sizes[1][1]); - - expect(impressions[3].banner.w).to.equal(bid.mediaTypes.banner.sizes[1][0]); - expect(impressions[3].banner.h).to.equal(bid.mediaTypes.banner.sizes[1][1]); - - expect(impressions[0].ext.sid).to.equal(`${DEFAULT_BANNER_VALID_BID[0].params.size[0].toString()}x${DEFAULT_BANNER_VALID_BID[0].params.size[1].toString()}`); - expect(impressions[1].ext.sid).to.equal(`${bid.params.size[0].toString()}x${bid.params.size[1].toString()}`); - - expect(impressions[2].ext.sid).to.equal(`${DEFAULT_BANNER_VALID_BID[0].mediaTypes.banner.sizes[1][0].toString()}x${DEFAULT_BANNER_VALID_BID[0].mediaTypes.banner.sizes[1][1].toString()}`); - expect(impressions[3].ext.sid).to.equal(`${bid.mediaTypes.banner.sizes[1][0].toString()}x${bid.mediaTypes.banner.sizes[1][1].toString()}`); - }); - - it('request should not contain the extra video ad sizes that IX is not configured for', function () { - const request = spec.buildRequests(DEFAULT_VIDEO_VALID_BID, DEFAULT_OPTION); - const impressions = JSON.parse(request[0].data.r).imp; - - expect(impressions).to.be.an('array'); - expect(impressions).to.have.lengthOf(1); - }); - - describe('detect missing sizes', function () { - beforeEach(function () { - config.setConfig({ - ix: { - detectMissingSizes: false - } - }); - }) - - it('request should not contain missing sizes if detectMissingSizes = false', function () { - const bid1 = utils.deepClone(DEFAULT_BANNER_VALID_BID[0]); - bid1.mediaTypes.banner.sizes = div_many_sizes; - - const requests = spec.buildRequests([bid1, DEFAULT_BANNER_VALID_BID[0]], DEFAULT_OPTION); - - const impressions = JSON.parse(requests[0].data.r).imp; - - expect(impressions).to.be.an('array'); - expect(impressions).to.have.lengthOf(2); - }); - }); - }); - - describe('buildRequestVideo', function () { - const request = spec.buildRequests(DEFAULT_VIDEO_VALID_BID, DEFAULT_OPTION); - const query = request[0].data; - - it('query object (version, siteID and request) should be correct', function () { - expect(query.v).to.equal(VIDEO_ENDPOINT_VERSION); - expect(query.s).to.equal(DEFAULT_VIDEO_VALID_BID[0].params.siteId); - expect(query.r).to.exist; - expect(query.ac).to.equal('j'); - expect(query.sd).to.equal(1); - expect(query.nf).to.equal(1); - }); - - it('impression should have correct format and value', function () { - const impression = JSON.parse(query.r).imp[0]; - const sidValue = `${DEFAULT_VIDEO_VALID_BID[0].params.size[0].toString()}x${DEFAULT_VIDEO_VALID_BID[0].params.size[1].toString()}`; - - expect(impression.id).to.equal(DEFAULT_VIDEO_VALID_BID[0].bidId); - expect(impression.video).to.exist; - expect(impression.video.w).to.equal(DEFAULT_VIDEO_VALID_BID[0].params.size[0]); - expect(impression.video.h).to.equal(DEFAULT_VIDEO_VALID_BID[0].params.size[1]); - expect(impression.video.placement).to.exist; - expect(impression.video.placement).to.equal(1); - expect(impression.video.minduration).to.exist; - expect(impression.video.minduration).to.equal(0); - expect(impression.video.mimes).to.exist; - expect(impression.video.mimes[0]).to.equal('video/mp4'); - expect(impression.video.mimes[1]).to.equal('video/webm'); - - expect(impression.video.skippable).to.equal(false); - expect(impression.ext).to.exist; - expect(impression.ext.siteID).to.equal(DEFAULT_VIDEO_VALID_BID[0].params.siteId.toString()); - expect(impression.ext.sid).to.equal(sidValue); - }); - - it('impression should have correct format when mediaType is specified.', function () { - const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID[0]); - delete bid.mediaTypes; - bid.mediaType = 'video'; - const requestBidFloor = spec.buildRequests([bid])[0]; - const impression = JSON.parse(requestBidFloor.data.r).imp[0]; - const sidValue = `${DEFAULT_VIDEO_VALID_BID[0].params.size[0].toString()}x${DEFAULT_VIDEO_VALID_BID[0].params.size[1].toString()}`; - - expect(impression.id).to.equal(DEFAULT_VIDEO_VALID_BID[0].bidId); - expect(impression.video).to.exist; - expect(impression.video.w).to.equal(DEFAULT_VIDEO_VALID_BID[0].params.size[0]); - expect(impression.video.h).to.equal(DEFAULT_VIDEO_VALID_BID[0].params.size[1]); - expect(impression.video.placement).to.not.exist; - expect(impression.ext).to.exist; - expect(impression.ext.siteID).to.equal(DEFAULT_VIDEO_VALID_BID[0].params.siteId.toString()); - expect(impression.ext.sid).to.equal(sidValue); - }); - - it('should set correct placement if context is outstream', function () { - const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID[0]); - bid.mediaTypes.video.context = 'outstream'; - const request = spec.buildRequests([bid])[0]; - const impression = JSON.parse(request.data.r).imp[0]; - - expect(impression.id).to.equal(DEFAULT_VIDEO_VALID_BID[0].bidId); - expect(impression.video).to.exist; - expect(impression.video.placement).to.exist; - expect(impression.video.placement).to.equal(4); - }); - - it('should not override video properties if they are already configured at the params video level', function () { - const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID[0]); - bid.mediaTypes.video.context = 'outstream'; - bid.mediaTypes.video.protocols = [1]; - bid.mediaTypes.video.mimes = ['video/override']; - const request = spec.buildRequests([bid])[0]; - const impression = JSON.parse(request.data.r).imp[0]; - - expect(impression.video.protocols[0]).to.equal(2); - expect(impression.video.mimes[0]).to.not.equal('video/override'); - }); - - it('should not add video adunit level properties in imp object if they are not allowlisted', function () { - const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID[0]); - bid.mediaTypes.video.context = 'outstream'; - bid.mediaTypes.video.random = true; - const request = spec.buildRequests([bid])[0]; - const impression = JSON.parse(request.data.r).imp[0]; - - expect(impression.video.random).to.not.exist; - }); - - it('should add allowlisted adunit level video properties in imp object if they are not configured at params level', function () { - const bid = utils.deepClone(DEFAULT_VIDEO_VALID_BID[0]); - bid.mediaTypes.video.context = 'outstream'; - delete bid.params.video.protocols; - delete bid.params.video.mimes; - bid.mediaTypes.video.protocols = [6]; - bid.mediaTypes.video.mimes = ['video/mp4']; - bid.mediaTypes.video.api = 2; - const request = spec.buildRequests([bid])[0]; - const impression = JSON.parse(request.data.r).imp[0]; - - expect(impression.video.protocols[0]).to.equal(6); - expect(impression.video.api).to.equal(2); - expect(impression.video.mimes[0]).to.equal('video/mp4'); - }); - }); - - describe('buildRequestMultiFormat', function () { - describe('only banner bidder params set', function () { - const request = spec.buildRequests(DEFAULT_MULTIFORMAT_BANNER_VALID_BID) - - const bannerImp = JSON.parse(request[0].data.r).imp[0]; - expect(JSON.parse(request[0].data.r).imp).to.have.lengthOf(2); - expect(JSON.parse(request[0].data.v)).to.equal(BANNER_ENDPOINT_VERSION); - expect(bannerImp.id).to.equal(DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0].bidId); - expect(bannerImp.banner).to.exist; - expect(bannerImp.banner.w).to.equal(DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0].params.size[0]); - expect(bannerImp.banner.h).to.equal(DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0].params.size[1]); - }); - - describe('only video bidder params set', function () { - const request = spec.buildRequests(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID); - - const videoImp = JSON.parse(request[0].data.r).imp[0]; - expect(JSON.parse(request[0].data.r).imp).to.have.lengthOf(1); - expect(JSON.parse(request[0].data.v)).to.equal(VIDEO_ENDPOINT_VERSION); - expect(videoImp.id).to.equal(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0].bidId); - expect(videoImp.video).to.exist; - expect(videoImp.video.w).to.equal(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0].params.size[0]); - expect(videoImp.video.h).to.equal(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0].params.size[1]); - }); - describe('both banner and video bidder params set', function () { - const request = spec.buildRequests([DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0], DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0]]); - - it('should return valid banner and video requests', function () { - const bannerImp = JSON.parse(request[0].data.r).imp[0]; - expect(JSON.parse(request[0].data.r).imp).to.have.lengthOf(2); - expect(JSON.parse(request[0].data.v)).to.equal(BANNER_ENDPOINT_VERSION); - expect(bannerImp.id).to.equal(DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0].bidId); - expect(bannerImp.banner).to.exist; - expect(bannerImp.banner.w).to.equal(DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0].params.size[0]); - expect(bannerImp.banner.h).to.equal(DEFAULT_MULTIFORMAT_BANNER_VALID_BID[0].params.size[1]); - - const videoImp = JSON.parse(request[1].data.r).imp[0]; - expect(JSON.parse(request[1].data.r).imp).to.have.lengthOf(1); - expect(JSON.parse(request[1].data.v)).to.equal(VIDEO_ENDPOINT_VERSION); - expect(videoImp.id).to.equal(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0].bidId); - expect(videoImp.video).to.exist; - expect(videoImp.video.w).to.equal(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0].params.size[0]); - expect(videoImp.video.h).to.equal(DEFAULT_MULTIFORMAT_VIDEO_VALID_BID[0].params.size[1]); - }); - - it('should contain all correct IXdiag properties', function () { - const diagObj = JSON.parse(request[0].data.r).ext.ixdiag; - expect(diagObj.iu).to.equal(0); - expect(diagObj.nu).to.equal(0); - expect(diagObj.ou).to.equal(1); - expect(diagObj.ren).to.equal(false); - expect(diagObj.mfu).to.equal(1); - expect(diagObj.allu).to.equal(1); - expect(diagObj.version).to.equal('$prebid.version$'); - }); - }); - }); - - describe('interpretResponse', function () { - it('should get correct bid response for banner ad', function () { - const expectedParse = [ - { - requestId: '1a2b3c4d', - cpm: 1, - creativeId: '12345', - width: 300, - height: 250, - mediaType: 'banner', - ad: '', - currency: 'USD', - ttl: 300, - netRevenue: true, - dealId: undefined, - meta: { - networkId: 50, - brandId: 303325, - brandName: 'OECTA', - advertiserDomains: ['www.abc.com'] - } - } - ]; - const result = spec.interpretResponse({ body: DEFAULT_BANNER_BID_RESPONSE }, { data: DEFAULT_BIDDER_REQUEST_DATA }); - expect(result[0]).to.deep.equal(expectedParse[0]); - }); - - it('should get correct bid response for banner ad with missing adomain', function () { - const expectedParse = [ - { - requestId: '1a2b3c4d', - cpm: 1, - creativeId: '12345', - width: 300, - height: 250, - mediaType: 'banner', - ad: '', - currency: 'USD', - ttl: 300, - netRevenue: true, - dealId: undefined, - meta: { - networkId: 50, - brandId: 303325, - brandName: 'OECTA' - } - } - ]; - const result = spec.interpretResponse({ body: DEFAULT_BANNER_BID_RESPONSE_WITHOUT_ADOMAIN }, { data: DEFAULT_BIDDER_REQUEST_DATA }); - expect(result[0]).to.deep.equal(expectedParse[0]); - }); - - it('should set creativeId to default value if not provided', function () { - const bidResponse = utils.deepClone(DEFAULT_BANNER_BID_RESPONSE); - delete bidResponse.seatbid[0].bid[0].crid; - const expectedParse = [ - { - requestId: '1a2b3c4d', - cpm: 1, - creativeId: '-', - width: 300, - height: 250, - mediaType: 'banner', - ad: '', - currency: 'USD', - ttl: 300, - netRevenue: true, - dealId: undefined, - meta: { - networkId: 50, - brandId: 303325, - brandName: 'OECTA', - advertiserDomains: ['www.abc.com'] - } - } - ]; - const result = spec.interpretResponse({ body: bidResponse }, { data: DEFAULT_BIDDER_REQUEST_DATA }); - }); - - it('should set Japanese price correctly', function () { - const bidResponse = utils.deepClone(DEFAULT_BANNER_BID_RESPONSE); - bidResponse.cur = 'JPY'; - const expectedParse = [ - { - requestId: '1a2b3c4d', - cpm: 100, - creativeId: '12345', - width: 300, - height: 250, - mediaType: 'banner', - ad: '', - currency: 'JPY', - ttl: 300, - netRevenue: true, - dealId: undefined, - meta: { - networkId: 50, - brandId: 303325, - brandName: 'OECTA', - advertiserDomains: ['www.abc.com'] - } - } - ]; - const result = spec.interpretResponse({ body: bidResponse }, { data: DEFAULT_BIDDER_REQUEST_DATA }); - expect(result[0]).to.deep.equal(expectedParse[0]); - }); - - it('should set dealId correctly', function () { - const bidResponse = utils.deepClone(DEFAULT_BANNER_BID_RESPONSE); - bidResponse.seatbid[0].bid[0].ext.dealid = 'deal'; - const expectedParse = [ - { - requestId: '1a2b3c4d', - cpm: 1, - creativeId: '12345', - width: 300, - height: 250, - mediaType: 'banner', - ad: '', - currency: 'USD', - ttl: 300, - netRevenue: true, - dealId: 'deal', - meta: { - networkId: 50, - brandId: 303325, - brandName: 'OECTA', - advertiserDomains: ['www.abc.com'] - } - } - ]; - const result = spec.interpretResponse({ body: bidResponse }, { data: DEFAULT_BIDDER_REQUEST_DATA }); - expect(result[0]).to.deep.equal(expectedParse[0]); - }); - - it('should get correct bid response for video ad', function () { - const expectedParse = [ - { - requestId: '1a2b3c4e', - cpm: 1.1, - creativeId: '12346', - mediaType: 'video', - width: 640, - height: 480, - currency: 'USD', - ttl: 3600, - netRevenue: true, - dealId: undefined, - vastUrl: 'www.abcd.com/vast', - meta: { - networkId: 51, - brandId: 303326, - brandName: 'OECTB', - advertiserDomains: ['www.abcd.com'] - } - } - ]; - const result = spec.interpretResponse({ body: DEFAULT_VIDEO_BID_RESPONSE }, { data: DEFAULT_BIDDER_REQUEST_DATA }); - expect(result[0]).to.deep.equal(expectedParse[0]); - }); - - it('bidrequest should not have page if options is undefined', function () { - const options = {}; - const validBidWithoutreferInfo = spec.buildRequests(DEFAULT_BANNER_VALID_BID, options); - const requestWithoutreferInfo = JSON.parse(validBidWithoutreferInfo[0].data.r); - - expect(requestWithoutreferInfo.site.page).to.be.undefined; - expect(validBidWithoutreferInfo[0].url).to.equal(IX_SECURE_ENDPOINT); - }); - - it('bidrequest should not have page if options.refererInfo is an empty object', function () { - const options = { - refererInfo: {} - }; - const validBidWithoutreferInfo = spec.buildRequests(DEFAULT_BANNER_VALID_BID, options); - const requestWithoutreferInfo = JSON.parse(validBidWithoutreferInfo[0].data.r); - - expect(requestWithoutreferInfo.site.page).to.be.undefined; - expect(validBidWithoutreferInfo[0].url).to.equal(IX_SECURE_ENDPOINT); - }); - - it('bidrequest should sent to secure endpoint if page url is secure', function () { - const options = { - refererInfo: { - referer: 'https://www.prebid.org' - } - }; - const validBidWithoutreferInfo = spec.buildRequests(DEFAULT_BANNER_VALID_BID, options); - const requestWithoutreferInfo = JSON.parse(validBidWithoutreferInfo[0].data.r); - - expect(requestWithoutreferInfo.site.page).to.equal(options.refererInfo.referer); - expect(validBidWithoutreferInfo[0].url).to.equal(IX_SECURE_ENDPOINT); - }); - }); - - describe('bidrequest consent', function () { - it('should have consent info if gdprApplies and consentString exist', function () { - const validBidWithConsent = spec.buildRequests(DEFAULT_BANNER_VALID_BID, DEFAULT_OPTION); - const requestWithConsent = JSON.parse(validBidWithConsent[0].data.r); - - expect(requestWithConsent.regs.ext.gdpr).to.equal(1); - expect(requestWithConsent.user.ext.consent).to.equal('3huaa11=qu3198ae'); - }); - - it('should not have consent field if consentString is undefined', function () { - const options = { - gdprConsent: { - gdprApplies: true, - vendorData: {} - } - }; - const validBidWithConsent = spec.buildRequests(DEFAULT_BANNER_VALID_BID, options); - const requestWithConsent = JSON.parse(validBidWithConsent[0].data.r); - - expect(requestWithConsent.regs.ext.gdpr).to.equal(1); - expect(requestWithConsent.user).to.be.undefined; - }); - - it('should not have gdpr field if gdprApplies is undefined', function () { - const options = { - gdprConsent: { - consentString: '3huaa11=qu3198ae', - vendorData: {} - } - }; - const validBidWithConsent = spec.buildRequests(DEFAULT_BANNER_VALID_BID, options); - const requestWithConsent = JSON.parse(validBidWithConsent[0].data.r); - - expect(requestWithConsent.regs).to.be.undefined; - expect(requestWithConsent.user.ext.consent).to.equal('3huaa11=qu3198ae'); - }); - - it('should not have consent info if options.gdprConsent is undefined', function () { - const options = {}; - const validBidWithConsent = spec.buildRequests(DEFAULT_BANNER_VALID_BID, options); - const requestWithConsent = JSON.parse(validBidWithConsent[0].data.r); - - expect(requestWithConsent.regs).to.be.undefined; - expect(requestWithConsent.user).to.be.undefined; - }); - - it('should have us_privacy if uspConsent is defined', function () { - const options = { - uspConsent: '1YYN' - }; - const validBidWithUspConsent = spec.buildRequests(DEFAULT_BANNER_VALID_BID, options); - const requestWithUspConsent = JSON.parse(validBidWithUspConsent[0].data.r); - - expect(requestWithUspConsent.regs.ext.us_privacy).to.equal('1YYN'); - }); - - it('should not have us_privacy if uspConsent undefined', function () { - const options = {}; - const validBidWithUspConsent = spec.buildRequests(DEFAULT_BANNER_VALID_BID, options); - const requestWithUspConsent = JSON.parse(validBidWithUspConsent[0].data.r); - - expect(requestWithUspConsent.regs).to.be.undefined; - }); - - it('should have both gdpr and us_privacy if both are defined', function () { - const options = { - gdprConsent: { - gdprApplies: true, - vendorData: {} - }, - uspConsent: '1YYN' - }; - const validBidWithConsent = spec.buildRequests(DEFAULT_BANNER_VALID_BID, options); - const requestWithConsent = JSON.parse(validBidWithConsent[0].data.r); - expect(requestWithConsent.regs.ext.gdpr).to.equal(1); - expect(requestWithConsent.regs.ext.us_privacy).to.equal('1YYN'); - }); - - it('should contain `consented_providers_settings.consented_providers` & consent on user.ext when both are provided', function () { - const options = { - gdprConsent: { - consentString: '3huaa11=qu3198ae', - addtlConsent: '1~1.35.41.101', - } - }; - - const validBidWithConsent = spec.buildRequests(DEFAULT_BANNER_VALID_BID, options); - const requestWithConsent = JSON.parse(validBidWithConsent[0].data.r); - expect(requestWithConsent.user.ext.consented_providers_settings.consented_providers).to.equal('1~1.35.41.101'); - expect(requestWithConsent.user.ext.consent).to.equal('3huaa11=qu3198ae'); - }); - - it('should not contain `consented_providers_settings.consented_providers` on user.ext when consent is not provided', function () { - const options = { - gdprConsent: { - addtlConsent: '1~1.35.41.101', - } - }; - - const validBidWithConsent = spec.buildRequests(DEFAULT_BANNER_VALID_BID, options); - const requestWithConsent = JSON.parse(validBidWithConsent[0].data.r); - expect(utils.deepAccess(requestWithConsent, 'user.ext.consented_providers_settings')).to.not.exist; - expect(utils.deepAccess(requestWithConsent, 'user.ext.consent')).to.not.exist; - }); - }); -}); diff --git a/test/spec/modules/jcmBidAdapter_spec.js b/test/spec/modules/jcmBidAdapter_spec.js deleted file mode 100644 index 9d84bca5513..00000000000 --- a/test/spec/modules/jcmBidAdapter_spec.js +++ /dev/null @@ -1,139 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/jcmBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -const ENDPOINT = 'https://media.adfrontiers.com/'; - -describe('jcmAdapter', 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 () { - let bid = { - 'bidder': 'jcm', - 'params': { - 'siteId': '3608' - }, - '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(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [ - { - 'bidder': 'jcm', - 'params': { - 'siteId': '3608' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - - ]; - - const request = spec.buildRequests(bidRequests); - - it('sends bid request to ENDPOINT via GET', function () { - expect(request.method).to.equal('GET'); - }); - - it('sends correct bid parameters', function () { - const payloadArr = request.data.split('&'); - expect(request.method).to.equal('GET'); - expect(payloadArr.length).to.equal(4); - expect(payloadArr[0]).to.equal('t=hb'); - expect(payloadArr[1]).to.equal('ver=1.0'); - expect(payloadArr[2]).to.equal('compact=true'); - const adReqStr = request.data.split('&bids=')[1]; - const adReq = JSON.parse(decodeURIComponent(adReqStr)); - const adReqBid = JSON.parse(decodeURIComponent(adReqStr)).bids[0]; - expect(adReqBid.siteId).to.equal('3608'); - expect(adReqBid.callbackId).to.equal('30b31c1838de1e'); - expect(adReqBid.adSizes).to.equal('300x250,300x600'); - }); - }); - - describe('interpretResponse', function () { - it('should get correct bid response', function () { - let serverResponse = {'bids': [{'width': 300, 'height': 250, 'creativeId': '29681110', 'ad': '', 'cpm': 0.5, 'callbackId': '30b31c1838de1e'}]}; - - let expectedResponse = [ - { - 'requestId': '30b31c1838de1e', - 'bidderCode': 'jcm', - 'cpm': 0.5, - 'creativeId': '29681110', - 'width': 300, - 'height': 250, - 'ttl': 60, - 'currency': 'USA', - 'netRevenue': true, - 'ad': '', - } - ]; - - let result = spec.interpretResponse({ body: serverResponse }); - expect(Object.keys(result[0]).length).to.equal(Object.keys(expectedResponse[0]).length); - expect(Object.keys(result[0]).requestId).to.equal(Object.keys(expectedResponse[0]).requestId); - expect(Object.keys(result[0]).bidderCode).to.equal(Object.keys(expectedResponse[0]).bidderCode); - expect(Object.keys(result[0]).cpm).to.equal(Object.keys(expectedResponse[0]).cpm); - expect(Object.keys(result[0]).creativeId).to.equal(Object.keys(expectedResponse[0]).creativeId); - expect(Object.keys(result[0]).width).to.equal(Object.keys(expectedResponse[0]).width); - expect(Object.keys(result[0]).height).to.equal(Object.keys(expectedResponse[0]).height); - expect(Object.keys(result[0]).ttl).to.equal(Object.keys(expectedResponse[0]).ttl); - expect(Object.keys(result[0]).currency).to.equal(Object.keys(expectedResponse[0]).currency); - expect(Object.keys(result[0]).netRevenue).to.equal(Object.keys(expectedResponse[0]).netRevenue); - - expect(Object.keys(result[0]).ad).to.equal(Object.keys(expectedResponse[0]).ad); - }); - - it('handles nobid responses', function () { - let serverResponse = {'bids': []}; - - let result = spec.interpretResponse({ body: serverResponse }); - expect(result.length).to.equal(0); - }); - }); - describe('getUserSyncs', function () { - it('Verifies sync iframe option', function () { - expect(spec.getUserSyncs({})).to.be.undefined; - expect(spec.getUserSyncs({ iframeEnabled: false })).to.be.undefined; - const options = spec.getUserSyncs({ iframeEnabled: true }); - expect(options).to.not.be.undefined; - expect(options).to.have.lengthOf(1); - expect(options[0].type).to.equal('iframe'); - expect(options[0].url).to.equal('https://media.adfrontiers.com/hb/jcm_usersync.html'); - }); - - it('Verifies sync image option', function () { - expect(spec.getUserSyncs({ image: false })).to.be.undefined; - const options = spec.getUserSyncs({ image: true }); - expect(options).to.not.be.undefined; - expect(options).to.have.lengthOf(1); - expect(options[0].type).to.equal('image'); - expect(options[0].url).to.equal('https://media.adfrontiers.com/hb/jcm_usersync.png'); - }); - }); -}); diff --git a/test/spec/modules/jixieBidAdapter_spec.js b/test/spec/modules/jixieBidAdapter_spec.js deleted file mode 100644 index 842f9e0ed30..00000000000 --- a/test/spec/modules/jixieBidAdapter_spec.js +++ /dev/null @@ -1,597 +0,0 @@ -import { expect } from 'chai'; -import { spec, internal as jixieaux, storage } from 'modules/jixieBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import { config } from 'src/config.js'; - -describe('jixie Adapter', function () { - const pageurl_ = 'https://testdomain.com/testpage.html'; - const domain_ = 'https://testdomain.com'; - const device_ = 'desktop'; - const timeout_ = 1000; - const currency_ = 'USD'; - - /** - * Basic - */ - 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'); - }); - }); - - /** - * isBidRequestValid - */ - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'jixie', - 'params': { - 'unit': 'prebidsampleunit' - }, - '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(bid)).to.equal(true); - }); - - it('should return false when required params obj does not exist', function () { - let bid0 = Object.assign({}, bid); - delete bid0.params; - expect(spec.isBidRequestValid(bid0)).to.equal(false); - }); - - it('should return false when params obj does not contain unit property', function () { - let bid1 = Object.assign({}, bid); - bid1.params = { rubbish: '' }; - expect(spec.isBidRequestValid(bid1)).to.equal(false); - }); - });// describe - - /** - * buildRequests - */ - describe('buildRequests', function () { - const adUnitCode0_ = 'adunit-code-0'; - const adUnitCode1_ = 'adunit-code-1'; - const adUnitCode2_ = 'adunit-code-2'; - - const bidId0_ = '22a9eb5004cf082'; - const bidId1_ = '230fceb12fd754f'; - const bidId2_ = '24dbe5c4fb80ed8'; - - const bidderRequestId_ = '2131ce076eeaa1b'; - const auctionId_ = '26d68819-d6ce-4a2c-a4d3-f1a97b159d66'; - - const clientIdTest1_ = '1aba6a40-f711-11e9-868c-53a2ae972xxx'; - const sessionIdTest1_ = '1594782644-1aba6a40-f711-11e9-868c-53a2ae972xxx'; - - // to serve as the object that prebid will call jixie buildRequest with: (param2) - const bidderRequest_ = { - refererInfo: {referer: pageurl_}, - auctionId: auctionId_, - timeout: timeout_ - }; - // to serve as the object that prebid will call jixie buildRequest with: (param1) - let bidRequests_ = [ - { - 'bidder': 'jixie', - 'params': { - 'unit': 'prebidsampleunit' - }, - 'sizes': [[300, 250], [300, 600]], - 'adUnitCode': adUnitCode0_, - 'bidId': bidId0_, - 'bidderRequestId': bidderRequestId_, - 'auctionId': auctionId_ - }, - { - 'bidder': 'jixie', - 'params': { - 'unit': 'prebidsampleunit' - }, - 'sizes': [[300, 250]], - 'mediaTypes': { - 'video': { - 'playerSize': [640, 360] - }, - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'adUnitCode': adUnitCode1_, - 'bidId': bidId1_, - 'bidderRequestId': bidderRequestId_, - 'auctionId': auctionId_ - }, - { - 'bidder': 'jixie', - 'params': { - 'unit': 'prebidsampleunit' - }, - 'sizes': [[300, 250], [300, 600]], - 'mediaTypes': { - 'video': { - 'playerSize': [640, 360] - }, - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'adUnitCode': adUnitCode2_, - 'bidId': bidId2_, - 'bidderRequestId': bidderRequestId_, - 'auctionId': auctionId_ - } - ]; - - // To serve as a reference to check against the bids array portion of the blob that the call to - // buildRequest returns - const refBids_ = [ - { - 'bidId': bidId0_, - 'adUnitCode': adUnitCode0_, - 'sizes': [[300, 250], [300, 600]], - 'params': { - 'unit': 'prebidsampleunit' - } - }, - { - 'bidId': bidId1_, - 'adUnitCode': adUnitCode1_, - 'mediaTypes': { - 'video': { - 'playerSize': [640, 360] - }, - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'sizes': [[300, 250]], - 'params': { - 'unit': 'prebidsampleunit' - } - }, - { - 'bidId': bidId2_, - 'adUnitCode': adUnitCode2_, - 'mediaTypes': { - 'video': { - 'playerSize': [640, 360] - }, - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'sizes': [[300, 250], [300, 600]], - 'params': { - 'unit': 'prebidsampleunit' - } - } - ]; - - it('should attach valid params to the adserver endpoint (1)', function () { - // this one we do not intercept the cookie stuff so really don't know - // what will be in there. so we do not check here (using expect) - // The next next below we check - const request = spec.buildRequests(bidRequests_, bidderRequest_); - it('sends bid request to ENDPOINT via POST', function () { - expect(request.method).to.equal('POST') - }) - expect(request.data).to.be.an('string'); - const payload = JSON.parse(request.data); - expect(payload).to.have.property('auctionid', auctionId_); - expect(payload).to.have.property('timeout', timeout_); - expect(payload).to.have.property('currency', currency_); - expect(payload).to.have.property('bids').that.deep.equals(refBids_); - });// it - - it('should attach valid params to the adserver endpoint (2)', function () { - // similar to above test case but here we force some clientid sessionid values - // and domain, pageurl - // get the interceptors ready: - let getCookieStub = sinon.stub(storage, 'getCookie'); - let getLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage'); - getCookieStub - .withArgs('_jx') - .returns(clientIdTest1_); - getCookieStub - .withArgs('_jxs') - .returns(sessionIdTest1_); - getLocalStorageStub - .withArgs('_jx') - .returns(clientIdTest1_); - getLocalStorageStub - .withArgs('_jxs') - .returns(sessionIdTest1_ - ); - let miscDimsStub = sinon.stub(jixieaux, 'getMiscDims'); - miscDimsStub - .returns({ device: device_, pageurl: pageurl_, domain: domain_ }); - - // actual api call: - const request = spec.buildRequests(bidRequests_, bidderRequest_); - it('sends bid request to ENDPOINT via POST', function () { - expect(request.method).to.equal('POST') - }) - expect(request.data).to.be.an('string'); - const payload = JSON.parse(request.data); - expect(payload).to.have.property('auctionid', auctionId_); - expect(payload).to.have.property('client_id_c', clientIdTest1_); - expect(payload).to.have.property('client_id_ls', clientIdTest1_); - expect(payload).to.have.property('session_id_c', sessionIdTest1_); - expect(payload).to.have.property('session_id_ls', sessionIdTest1_); - expect(payload).to.have.property('device', device_); - expect(payload).to.have.property('domain', domain_); - expect(payload).to.have.property('pageurl', pageurl_); - expect(payload).to.have.property('timeout', timeout_); - expect(payload).to.have.property('currency', currency_); - expect(payload).to.have.property('bids').that.deep.equals(refBids_); - - // unwire interceptors - getCookieStub.restore(); - getLocalStorageStub.restore(); - miscDimsStub.restore(); - });// it - });// describe - - /** - * interpretResponse: - */ - const JX_OTHER_OUTSTREAM_RENDERER_URL = 'https://scripts.jixie.io/dummyscript.js'; - const JX_OUTSTREAM_RENDERER_URL = 'https://scripts.jixie.io/jxhboutstream.js'; - - const mockVastXml_ = `JXADSERVERAlway%20Live%20Prebid%20CreativeHybrid in-stream00:00:10`; - const responseBody_ = { - 'bids': [ - // video (vast tag url) returned here - { - 'trackingUrlBase': 'https://tr.jixie.io/sync/ad?', - 'jxBidId': '62847e4c696edcb-028d5dee-2c83-44e3-bed1-b75002475cdf', - 'requestId': '62847e4c696edcb', - 'cpm': 2.19, - 'width': 640, - 'height': 360, - 'ttl': 300, - 'adUnitCode': 'demoslot3-div', - 'netRevenue': true, - 'currency': 'USD', - 'creativeId': 'jixie522', - 'meta': { - 'networkId': 123, - 'networkName': 'network123', - 'agencyId': 123, - 'agencyName': 'agency123', - 'advertiserId': 123, - 'advertiserName': 'advertiser123', - 'brandId': 123, - 'brandName': 'brand123', - 'primaryCatId': 1, - 'secondaryCatIds': [ - 2, - 3, - 4 - ], - 'mediaType': 'VIDEO' - }, - 'vastUrl': 'https://ad.jixie.io/v1/video?creativeid=522' - }, - // display ad returned here: - { - 'trackingUrlBase': 'https://tr.jixie.io/sync/ad?', - 'jxBidId': '600c9ae6fda1acb-028d5dee-2c83-44e3-bed1-b75002475cdf', - 'requestId': '600c9ae6fda1acb', - 'cpm': 1.999, - 'width': 300, - 'height': 250, - 'ttl': 300, - 'adUnitCode': 'demoslot1-div', - 'netRevenue': true, - 'currency': 'USD', - 'creativeId': 'jixie520', - 'meta': { - 'networkId': 123, - 'networkName': 'network123', - 'agencyId': 123, - 'agencyName': 'agency123', - 'advertiserId': 123, - 'advertiserName': 'advertiser123', - 'advertiserDomains': [ - 'advdom1', - 'advdom2', - 'advdom3' - ], - 'brandId': 123, - 'brandName': 'brand123', - 'primaryCatId': 1, - 'secondaryCatIds': [ - 2, - 3, - 4 - ], - 'mediaType': 'BANNER' - }, - 'ad': '
' - }, - // outstream, jx non-default renderer specified: - { - 'trackingUrlBase': 'https://tr.jixie.io/sync/ad?', - 'jxBidId': '99bc539c81b00ce-028d5dee-2c83-44e3-bed1-b75002475cdf', - 'requestId': '99bc539c81b00ce', - 'cpm': 2.99, - 'width': 640, - 'height': 360, - 'ttl': 300, - 'netRevenue': true, - 'currency': 'USD', - 'creativeId': 'jixie521', - 'adUnitCode': 'demoslot4-div', - 'osplayer': 'jixie', - 'osparams': { - 'script': JX_OTHER_OUTSTREAM_RENDERER_URL - }, - 'vastXml': mockVastXml_ - }, - // outstream, jx default renderer: - { - 'trackingUrlBase': 'https://tr.jixie.io/sync/ad?', - 'jxBidId': '61bc539c81b00ce-028d5dee-2c83-44e3-bed1-b75002475cdf', - 'requestId': '61bc539c81b00ce', - 'cpm': 1.99, - 'width': 640, - 'height': 360, - 'ttl': 300, - 'netRevenue': true, - 'currency': 'USD', - 'creativeId': 'jixie521', - 'meta': { - 'networkId': 123, - 'networkName': 'network123', - 'agencyId': 123, - 'agencyName': 'agency123', - 'advertiserId': 123, - 'advertiserName': 'advertiser123', - 'brandId': 123, - 'brandName': 'brand123', - 'primaryCatId': 1, - 'secondaryCatIds': [ - 2, - 3, - 4 - ], - 'mediaType': 'VIDEO' - }, - 'adUnitCode': 'demoslot2-div', - 'osplayer': 'jixie', - 'osparams': {}, - 'vastXml': mockVastXml_ - } - ], - 'setids': { - 'client_id': '43aacc10-f643-11ea-8a10-c5fe2d394e7e', - 'session_id': '1600057934-43aacc10-f643-11ea-8a10-c5fe2d394e7e' - }, - }; - const requestObj_ = - { - 'method': 'POST', - 'url': 'http://localhost:8080/v2/hbpost', - 'data': '{"auctionid":"028d5dee-2c83-44e3-bed1-b75002475cdf","timeout":1000,"currency":"USD","timestamp":1600057934665,"device":"desktop","domain":"mock.com","pageurl":"https://mock.com/tests/jxprebidtest_pbjs.html","bids":[{"bidId":"600c9ae6fda1acb","adUnitCode":"demoslot1-div","mediaTypes":{"banner":{"sizes":[[300,250],[300,600],[728,90]]}},"params":{"unit":"prebidsampleunit"}},{"bidId":"61bc539c81b00ce","adUnitCode":"demoslot2-div","mediaTypes":{"video":{"playerSize":[[640,360]],"context":"outstream"}},"params":{"unit":"prebidsampleunit"}},{"bidId":"99bc539c81b00ce","adUnitCode":"demoslot4-div","mediaTypes":{"video":{"playerSize":[[640,360]],"context":"outstream"}},"params":{"unit":"prebidsampleunit"}},{"bidId":"62847e4c696edcb","adUnitCode":"demoslot3-div","mediaTypes":{"video":{"playerSize":[[640,360]],"context":"instream"}},"params":{"unit":"prebidsampleunit"}},{"bidId":"6360235ab01d2cd","adUnitCode":"woo-div","mediaTypes":{"video":{"context":"outstream","playerSize":[[640,360]]}},"params":{"unit":"80b76fc951e161d7c019d21b6639e408"}},{"bidId":"64d9724c7a5e512","adUnitCode":"test-div","mediaTypes":{"video":{"context":"outstream","playerSize":[[300,250]]}},"params":{"unit":"80b76fc951e161d7c019d21b6639e408"}},{"bidId":"65bea7e80fed44b","adUnitCode":"test-div","mediaTypes":{"banner":{"sizes":[[300,250],[300,600],[728,90]]}},"params":{"unit":"7854f723e932b951b6c51fc80b23a410"}},{"bidId":"6642054c4ba1b7f","adUnitCode":"div-banner-native-1","mediaTypes":{"banner":{"sizes":[[640,360]]},"video":{"context":"outstream","sizes":[[640,361]],"playerSize":[[640,360]]},"native":{"type":"image"}},"params":{"unit":"632e7695f0910ce0fa74c19859060a04"}},{"bidId":"675ecf4b44db228","adUnitCode":"div-banner-native-2","mediaTypes":{"banner":{"sizes":[[300,250]]},"native":{"title":{"required":true},"image":{"required":true},"sponsoredBy":{"required":true}}},"params":{"unit":"1000008-b1Q2UMQfZx"}},{"bidId":"68f2dbf5dc23f94","adUnitCode":"div-Top-MediumRectangle","mediaTypes":{"banner":{"sizes":[[300,250],[300,100],[320,50]]}},"params":{"unit":"1000008-b1Q2UMQfZx"}},{"bidId":"6991cf107bb7f1a","adUnitCode":"div-Middle-MediumRectangle","mediaTypes":{"banner":{"sizes":[[300,250],[300,100],[320,50]]}},"params":{"unit":"1000008-b1Q2UMQfZx"}},{"bidId":"706be1b011eac83","adUnitCode":"div-Inside-MediumRectangle","mediaTypes":{"banner":{"sizes":[[300,600],[300,250],[300,100],[320,480]]}},"params":{"unit":"1000008-b1Q2UMQfZx"}}],"client_id_c":"ebd0dea0-f5c8-11ea-a2c7-a5b37aa7fe95","client_id_ls":"ebd0dea0-f5c8-11ea-a2c7-a5b37aa7fe95","session_id_c":"","session_id_ls":"1600005388-ebd0dea0-f5c8-11ea-a2c7-a5b37aa7fe95"}', - 'currency': 'USD' - }; - - 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) - }); - - it('should get correct bid response', function () { - let setCookieSpy = sinon.spy(storage, 'setCookie'); - let setLocalStorageSpy = sinon.spy(storage, 'setDataInLocalStorage'); - const result = spec.interpretResponse({body: responseBody_}, requestObj_) - expect(setLocalStorageSpy.calledWith('_jx', '43aacc10-f643-11ea-8a10-c5fe2d394e7e')).to.equal(true); - expect(setLocalStorageSpy.calledWith('_jxs', '1600057934-43aacc10-f643-11ea-8a10-c5fe2d394e7e')).to.equal(true); - expect(setCookieSpy.calledWith('_jxs', '1600057934-43aacc10-f643-11ea-8a10-c5fe2d394e7e')).to.equal(true); - expect(setCookieSpy.calledWith('_jx', '43aacc10-f643-11ea-8a10-c5fe2d394e7e')).to.equal(true); - - // video ad with vastUrl returned by adserver - expect(result[0].requestId).to.equal('62847e4c696edcb') - expect(result[0].cpm).to.equal(2.19) - expect(result[0].width).to.equal(640) - expect(result[0].height).to.equal(360) - expect(result[0].creativeId).to.equal('jixie522') - expect(result[0].currency).to.equal('USD') - expect(result[0].netRevenue).to.equal(true) - expect(result[0].ttl).to.equal(300) - expect(result[0].vastUrl).to.include('https://ad.jixie.io/v1/video?creativeid=') - expect(result[0].trackingUrlBase).to.include('sync') - - // display ad - expect(result[1].requestId).to.equal('600c9ae6fda1acb') - expect(result[1].cpm).to.equal(1.999) - expect(result[1].width).to.equal(300) - expect(result[1].height).to.equal(250) - expect(result[1].creativeId).to.equal('jixie520') - expect(result[1].currency).to.equal('USD') - expect(result[1].netRevenue).to.equal(true) - expect(result[1].ttl).to.equal(300) - expect(result[1].ad).to.include('jxoutstream') - expect(result[1].trackingUrlBase).to.include('sync') - - // should pick up about using alternative outstream renderer - expect(result[2].requestId).to.equal('99bc539c81b00ce') - expect(result[2].cpm).to.equal(2.99) - expect(result[2].width).to.equal(640) - expect(result[2].height).to.equal(360) - expect(result[2].creativeId).to.equal('jixie521') - expect(result[2].currency).to.equal('USD') - expect(result[2].netRevenue).to.equal(true) - expect(result[2].ttl).to.equal(300) - expect(result[2].vastXml).to.include('') - expect(result[2].trackingUrlBase).to.include('sync'); - expect(result[2].renderer.id).to.equal('demoslot4-div') - expect(result[2].renderer.url).to.equal(JX_OTHER_OUTSTREAM_RENDERER_URL); - - // should know to use default outstream renderer - expect(result[3].requestId).to.equal('61bc539c81b00ce') - expect(result[3].cpm).to.equal(1.99) - expect(result[3].width).to.equal(640) - expect(result[3].height).to.equal(360) - expect(result[3].creativeId).to.equal('jixie521') - expect(result[3].currency).to.equal('USD') - expect(result[3].netRevenue).to.equal(true) - expect(result[3].ttl).to.equal(300) - expect(result[3].vastXml).to.include('') - expect(result[3].trackingUrlBase).to.include('sync'); - expect(result[3].renderer.id).to.equal('demoslot2-div') - expect(result[3].renderer.url).to.equal(JX_OUTSTREAM_RENDERER_URL) - - setLocalStorageSpy.restore(); - setCookieSpy.restore(); - });// it - });// describe - - /** - * onBidWon - */ - describe('onBidWon', function() { - let ajaxStub; - let miscDimsStub; - beforeEach(function() { - miscDimsStub = sinon.stub(jixieaux, 'getMiscDims'); - ajaxStub = sinon.stub(jixieaux, 'ajax'); - - miscDimsStub - .returns({ device: device_, pageurl: pageurl_, domain: domain_ }); - }) - - afterEach(function() { - miscDimsStub.restore(); - ajaxStub.restore(); - }) - - let TRACKINGURL_ = 'https://abc.com/sync?action=bidwon'; - - it('Should fire if the adserver trackingUrl flag says so', function() { - spec.onBidWon({ trackingUrl: TRACKINGURL_ }) - expect(jixieaux.ajax.calledWith(TRACKINGURL_)).to.equal(true); - }) - - it('Should not fire if the adserver response indicates no firing', function() { - let called = false; - ajaxStub.callsFake(function fakeFn() { - called = true; - }); - spec.onBidWon({ notrack: 1 }) - expect(called).to.equal(false); - }); - - // A reference to check again: - const QPARAMS_ = { - action: 'hbbidwon', - device: device_, - pageurl: encodeURIComponent(pageurl_), - domain: encodeURIComponent(domain_), - cid: 121, - cpid: 99, - jxbidid: '62847e4c696edcb-028d5dee-2c83-44e3-bed1-b75002475cdf', - auctionid: '028d5dee-2c83-44e3-bed1-b75002475cdf', - cpm: 1.11, - requestid: '62847e4c696edcb' - }; - - it('check it is sending the correct ajax url and qparameters', function() { - spec.onBidWon({ - trackingUrlBase: 'https://mytracker.com/sync?', - cid: 121, - cpid: 99, - jxBidId: '62847e4c696edcb-028d5dee-2c83-44e3-bed1-b75002475cdf', - auctionId: '028d5dee-2c83-44e3-bed1-b75002475cdf', - cpm: 1.11, - requestId: '62847e4c696edcb' - }) - expect(jixieaux.ajax.calledWith('https://mytracker.com/sync?', null, QPARAMS_)).to.equal(true); - }); - }); // describe - - /** - * onTimeout - */ - describe('onTimeout', function() { - let ajaxStub; - let miscDimsStub; - beforeEach(function() { - ajaxStub = sinon.stub(jixieaux, 'ajax'); - miscDimsStub = sinon.stub(jixieaux, 'getMiscDims'); - miscDimsStub - .returns({ device: device_, pageurl: pageurl_, domain: domain_ }); - }) - - afterEach(function() { - miscDimsStub.restore(); - ajaxStub.restore(); - }) - - // reference to check against: - const QPARAMS_ = { - action: 'hbtimeout', - device: device_, - pageurl: encodeURIComponent(pageurl_), - domain: encodeURIComponent(domain_), - auctionid: '028d5dee-2c83-44e3-bed1-b75002475cdf', - timeout: 1000, - count: 2 - }; - - it('check it is sending the correct ajax url and qparameters', function() { - spec.onTimeout([ - {auctionId: '028d5dee-2c83-44e3-bed1-b75002475cdf', timeout: 1000}, - {auctionId: '028d5dee-2c83-44e3-bed1-b75002475cdf', timeout: 1000} - ]) - expect(jixieaux.ajax.calledWith(spec.EVENTS_URL, null, QPARAMS_)).to.equal(true); - }) - - it('if turned off via config then dont do onTimeout sending of event', function() { - let getConfigStub = sinon.stub(config, 'getConfig'); - getConfigStub.callsFake(function fakeFn(prop) { - if (prop == 'jixie') { - return { onTimeout: 'off' }; - } - return null; - }); - let called = false; - ajaxStub.callsFake(function fakeFn() { - called = true; - }); - spec.onTimeout([ - {auctionId: '028d5dee-2c83-44e3-bed1-b75002475cdf', timeout: 1000}, - {auctionId: '028d5dee-2c83-44e3-bed1-b75002475cdf', timeout: 1000} - ]) - expect(called).to.equal(false); - getConfigStub.restore(); - }) - - const otherUrl_ = 'https://other.azurewebsites.net/sync/evt?'; - it('if config specifies a different endpoint then should send there instead', function() { - let getConfigStub = sinon.stub(config, 'getConfig'); - getConfigStub.callsFake(function fakeFn(prop) { - if (prop == 'jixie') { - return { onTimeoutUrl: otherUrl_ }; - } - return null; - }); - spec.onTimeout([ - {auctionId: '028d5dee-2c83-44e3-bed1-b75002475cdf', timeout: 1000}, - {auctionId: '028d5dee-2c83-44e3-bed1-b75002475cdf', timeout: 1000} - ]) - expect(jixieaux.ajax.calledWith(otherUrl_, null, QPARAMS_)).to.equal(true); - getConfigStub.restore(); - }) - });// describe -}); diff --git a/test/spec/modules/justpremiumBidAdapter_spec.js b/test/spec/modules/justpremiumBidAdapter_spec.js deleted file mode 100644 index 7cc154254ff..00000000000 --- a/test/spec/modules/justpremiumBidAdapter_spec.js +++ /dev/null @@ -1,170 +0,0 @@ -import { expect } from 'chai' -import { spec } from 'modules/justpremiumBidAdapter.js' - -describe('justpremium adapter', function () { - let sandbox; - - beforeEach(function() { - sandbox = sinon.sandbox.create(); - }); - - afterEach(function() { - sandbox.restore(); - }); - - let adUnits = [ - { - adUnitCode: 'div-gpt-ad-1471513102552-1', - bidder: 'justpremium', - crumbs: { - pubcid: '0000000' - }, - userId: { - tdid: '1111111', - id5id: { - uid: '2222222' - }, - digitrustid: { - data: { - id: '3333333' - } - } - }, - params: { - zone: 28313, - allow: ['lb', 'wp'] - } - }, - { - adUnitCode: 'div-gpt-ad-1471513102552-2', - bidder: 'justpremium', - params: { - zone: 32831, - exclude: ['sa'] - } - }, - ] - - let bidderRequest = { - uspConsent: '1YYN', - refererInfo: { - referer: 'https://justpremium.com' - } - } - - describe('isBidRequestValid', function () { - it('Verifies bidder code', function () { - expect(spec.code).to.equal('justpremium') - }) - - it('Verify build request', function () { - 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) - }) - }) - - describe('buildRequests', function () { - it('Verify build request and parameters', function () { - const request = spec.buildRequests(adUnits, bidderRequest) - expect(request.method).to.equal('POST') - expect(request.url).to.match(/pre.ads.justpremium.com\/v\/2.0\/t\/xhr/) - - const jpxRequest = JSON.parse(request.data) - expect(jpxRequest).to.not.equal(null) - expect(jpxRequest.zone).to.not.equal('undefined') - expect(bidderRequest.refererInfo.referer).to.equal('https://justpremium.com') - expect(jpxRequest.sw).to.equal(window.top.screen.width) - expect(jpxRequest.sh).to.equal(window.top.screen.height) - expect(jpxRequest.ww).to.equal(window.top.innerWidth) - expect(jpxRequest.wh).to.equal(window.top.innerHeight) - expect(jpxRequest.c).to.not.equal('undefined') - expect(jpxRequest.id).to.equal(adUnits[0].params.zone) - expect(jpxRequest.mediaTypes && jpxRequest.mediaTypes.banner && jpxRequest.mediaTypes.banner.sizes).to.not.equal('undefined') - expect(jpxRequest.version.prebid).to.equal('$prebid.version$') - expect(jpxRequest.version.jp_adapter).to.equal('1.7') - expect(jpxRequest.pubcid).to.equal('0000000') - expect(jpxRequest.uids.tdid).to.equal('1111111') - expect(jpxRequest.uids.id5id.uid).to.equal('2222222') - expect(jpxRequest.uids.digitrustid.data.id).to.equal('3333333') - expect(jpxRequest.us_privacy).to.equal('1YYN') - }) - }) - - describe('interpretResponse', function () { - const request = spec.buildRequests(adUnits, bidderRequest) - it('Verify server response', function () { - let response = { - 'bid': { - '28313': [{ - 'id': 3213123, - 'height': 250, - 'width': 970, - 'price': 0.52, - 'format': 'lb', - 'adm': 'creative code' - }] - }, - 'pass': { - '28313': false - }, - 'deals': {} - } - - let expectedResponse = [ - { - requestId: '319a5029c362f4', - creativeId: 3213123, - width: 970, - height: 250, - ad: 'creative code', - cpm: 0.52, - netRevenue: true, - currency: 'USD', - ttl: 60000, - format: 'lb' - } - ] - - let 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) - expect(result[0].width).to.equal(970) - expect(result[0].height).to.equal(250) - expect(result[0].ad).to.equal('creative code') - expect(result[0].cpm).to.equal(0.52) - expect(result[0].currency).to.equal('USD') - expect(result[0].ttl).to.equal(60000) - expect(result[0].creativeId).to.equal(3213123) - expect(result[0].netRevenue).to.equal(true) - expect(result[0].format).to.equal('lb') - }) - - it('Verify wrong server response', function () { - let response = { - 'bid': { - '28313': [] - }, - 'pass': { - '28313': true - } - } - - let result = spec.interpretResponse({body: response}, request) - expect(result.length).to.equal(0) - }) - }) - - describe('getUserSyncs', function () { - it('Verifies sync options', function () { - 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/) - expect(options[0].url).to.match(/&consentString=BOOgjO9OOgjO9APABAENAi-AAAAWd/) - expect(options[0].url).to.match(/&usPrivacy=1YYN/) - }) - }) -}) diff --git a/test/spec/modules/jwplayerRtdProvider_spec.js b/test/spec/modules/jwplayerRtdProvider_spec.js deleted file mode 100644 index 458e45e8ae7..00000000000 --- a/test/spec/modules/jwplayerRtdProvider_spec.js +++ /dev/null @@ -1,751 +0,0 @@ -import { fetchTargetingForMediaId, getVatFromCache, extractPublisherParams, - formatTargetingResponse, getVatFromPlayer, enrichAdUnits, addTargetingToBid, - fetchTargetingInformation, jwplayerSubmodule } from 'modules/jwplayerRtdProvider.js'; -import { server } from 'test/mocks/xhr.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'}; - - describe('Fetch targeting for mediaID tests', function () { - let request; - - describe('Fetch succeeds', function () { - beforeEach(function () { - fetchTargetingForMediaId(testIdForSuccess); - request = server.requests[0]; - }); - - afterEach(function () { - server.respond(); - }); - - it('should reach out to media endpoint', function () { - expect(request.url).to.be.eq(`https://cdn.jwplayer.com/v2/media/${testIdForSuccess}`); - }); - - it('should write to cache when successful', function () { - request.respond( - 200, - responseHeader, - JSON.stringify({ - playlist: [ - { - file: 'test.mp4', - jwpseg: validSegments - } - ] - }) - ); - - const targetingInfo = getVatFromCache(testIdForSuccess); - - const validTargeting = { - segments: validSegments, - mediaID: testIdForSuccess - }; - - expect(targetingInfo).to.deep.equal(validTargeting); - }); - }); - - describe('Fetch fails', function () { - beforeEach(function () { - fetchTargetingForMediaId(testIdForFailure); - request = server.requests[0] - }); - - it('should not write to cache when response is malformed', function() { - request.respond('{]'); - const targetingInfo = getVatFromCache(testIdForFailure); - expect(targetingInfo).to.be.null; - }); - - it('should not write to cache when playlist is absent', function() { - request.respond({}); - const targetingInfo = getVatFromCache(testIdForFailure); - expect(targetingInfo).to.be.null; - }); - - it('should not write to cache when segments are absent', function() { - request.respond( - 200, - responseHeader, - JSON.stringify({ - playlist: [ - { - file: 'test.mp4' - } - ] - }) - ); - const targetingInfo = getVatFromCache(testIdForFailure); - expect(targetingInfo).to.be.null; - }); - - it('should not write to cache when request errors', function() { - request.error(); - const targetingInfo = getVatFromCache(testIdForFailure); - expect(targetingInfo).to.be.null; - }); - }); - }); - - describe('Format targeting response', function () { - it('should exclude segment key when absent', function () { - const targeting = formatTargetingResponse({ mediaID: 'test' }); - expect(targeting).to.not.have.property('segments'); - }); - - it('should exclude content block when mediaId is absent', function () { - const targeting = formatTargetingResponse({ segments: ['test'] }); - expect(targeting).to.not.have.property('content'); - }); - - it('should return proper format', function () { - const segments = ['123']; - const mediaID = 'test'; - const expectedContentId = 'jw_' + mediaID; - const expectedContent = { - id: expectedContentId - }; - const targeting = formatTargetingResponse({ - segments, - mediaID - }); - expect(targeting).to.have.deep.property('segments', segments); - expect(targeting).to.have.deep.property('content', expectedContent); - }); - }); - - describe('Get VAT from player', function () { - const mediaIdWithSegment = 'media_ID_1'; - const mediaIdNoSegment = 'media_ID_2'; - const mediaIdForCurrentItem = 'media_ID_current'; - const mediaIdNotCached = 'media_test_ID'; - - const validPlayerID = 'player_test_ID_valid'; - const invalidPlayerID = 'player_test_ID_invalid'; - - it('returns null when jwplayer.js is absent from page', function () { - const targeting = getVatFromPlayer(invalidPlayerID, mediaIdNotCached); - expect(targeting).to.be.null; - }); - - describe('When jwplayer.js is on page', function () { - const playlistItemWithSegmentMock = { - mediaid: mediaIdWithSegment, - jwpseg: validSegments - }; - - const targetingForMediaWithSegment = { - segments: validSegments, - mediaID: mediaIdWithSegment - }; - - const playlistItemNoSegmentMock = { - mediaid: mediaIdNoSegment - }; - - const currentItemSegments = ['test_seg_3', 'test_seg_4']; - const currentPlaylistItemMock = { - mediaid: mediaIdForCurrentItem, - jwpseg: currentItemSegments - }; - const targetingForCurrentItem = { - segments: currentItemSegments, - mediaID: mediaIdForCurrentItem - }; - - const playerInstanceMock = { - getPlaylist: function () { - return [playlistItemWithSegmentMock, playlistItemNoSegmentMock]; - }, - - getPlaylistItem: function () { - return currentPlaylistItemMock; - } - }; - - const jwplayerMock = function(playerID) { - if (playerID === validPlayerID) { - return playerInstanceMock; - } else { - return {}; - } - }; - - beforeEach(function () { - window.jwplayer = jwplayerMock; - }); - - it('returns null when player ID does not match player on page', function () { - const targeting = getVatFromPlayer(invalidPlayerID, mediaIdNotCached); - expect(targeting).to.be.null; - }); - - it('returns segments when media ID matches a playlist item with segments', function () { - const targeting = getVatFromPlayer(validPlayerID, mediaIdWithSegment); - expect(targeting).to.deep.equal(targetingForMediaWithSegment); - }); - - it('caches segments when media ID matches a playist item with segments', function () { - getVatFromPlayer(validPlayerID, mediaIdWithSegment); - const vat = getVatFromCache(mediaIdWithSegment); - expect(vat.segments).to.deep.equal(validSegments); - }); - - it('returns segments of current item when media ID is missing', function () { - const targeting = getVatFromPlayer(validPlayerID); - expect(targeting).to.deep.equal(targetingForCurrentItem); - }); - - it('caches segments from the current item', function () { - getVatFromPlayer(validPlayerID); - - window.jwplayer = null; - const targeting = getVatFromCache(mediaIdForCurrentItem); - expect(targeting).to.deep.equal(targetingForCurrentItem); - }); - - it('returns undefined segments when segments are absent', function () { - const targeting = getVatFromPlayer(validPlayerID, mediaIdNoSegment); - expect(targeting).to.deep.equal({ - mediaID: mediaIdNoSegment, - segments: undefined - }); - }); - - describe('Get Bid Request Data', function () { - it('executes immediately while request is active if player has item', function () { - const bidRequestSpy = sinon.spy(); - const fakeServer = sinon.createFakeServer(); - fakeServer.respondImmediately = false; - fakeServer.autoRespond = false; - - fetchTargetingForMediaId(mediaIdWithSegment); - - const bid = {}; - const adUnit = { - ortb2Imp: { - ext: { - data: { - jwTargeting: { - mediaID: mediaIdWithSegment, - playerID: validPlayerID - } - } - } - }, - bids: [ - bid - ] - }; - const expectedContentId = 'jw_' + mediaIdWithSegment; - const expectedTargeting = { - segments: validSegments, - content: { - id: expectedContentId - } - }; - jwplayerSubmodule.getBidRequestData({ adUnits: [adUnit] }, bidRequestSpy); - expect(bidRequestSpy.calledOnce).to.be.true; - expect(bid.rtd.jwplayer).to.have.deep.property('targeting', expectedTargeting); - fakeServer.respond(); - expect(bidRequestSpy.calledOnce).to.be.true; - }); - }); - }); - }); - - describe('Enrich ad units', function () { - const contentIdForSuccess = 'jw_' + testIdForSuccess; - const expectedTargetingForSuccess = { - segments: validSegments, - content: { - id: contentIdForSuccess - } - }; - let bidRequestSpy; - let fakeServer; - let clock; - - beforeEach(function () { - bidRequestSpy = sinon.spy(); - - fakeServer = sinon.createFakeServer(); - fakeServer.respondImmediately = false; - fakeServer.autoRespond = false; - - clock = sinon.useFakeTimers(); - }); - - afterEach(function () { - clock.restore(); - fakeServer.respond(); - }); - - it('adds targeting when pending request succeeds', function () { - fetchTargetingForMediaId(testIdForSuccess); - const bids = [ - { - id: 'bid1' - }, - { - id: 'bid2' - } - ]; - const adUnit = { - ortb2Imp: { - ext: { - data: { - jwTargeting: { - mediaID: testIdForSuccess - } - } - } - }, - bids - }; - - enrichAdUnits([adUnit]); - const bid1 = bids[0]; - const bid2 = bids[1]; - expect(bid1).to.not.have.property('rtd'); - expect(bid2).to.not.have.property('rtd'); - - const request = fakeServer.requests[0]; - request.respond( - 200, - responseHeader, - JSON.stringify({ - playlist: [ - { - file: 'test.mp4', - jwpseg: validSegments - } - ] - }) - ); - - expect(bid1.rtd.jwplayer).to.have.deep.property('targeting', expectedTargetingForSuccess); - expect(bid2.rtd.jwplayer).to.have.deep.property('targeting', expectedTargetingForSuccess); - }); - - it('immediately adds cached targeting', function () { - fetchTargetingForMediaId(testIdForSuccess); - const bids = [ - { - id: 'bid1' - }, - { - id: 'bid2' - } - ]; - const adUnit = { - ortb2Imp: { - ext: { - data: { - jwTargeting: { - mediaID: testIdForSuccess - } - } - } - }, - bids - }; - const request = fakeServer.requests[0]; - request.respond( - 200, - responseHeader, - JSON.stringify({ - playlist: [ - { - file: 'test.mp4', - jwpseg: validSegments - } - ] - }) - ); - - enrichAdUnits([adUnit]); - const bid1 = bids[0]; - const bid2 = bids[1]; - expect(bid1.rtd.jwplayer).to.have.deep.property('targeting', expectedTargetingForSuccess); - expect(bid2.rtd.jwplayer).to.have.deep.property('targeting', expectedTargetingForSuccess); - }); - - it('adds content block when segments are absent and no request is pending', function () { - const expectedTargetingForFailure = { - content: { - id: 'jw_' + testIdForFailure - } - }; - const bids = [ - { - id: 'bid1' - }, - { - id: 'bid2' - } - ]; - const adUnit = { - ortb2Imp: { - ext: { - data: { - jwTargeting: { - mediaID: testIdForFailure - } - } - } - }, - bids - }; - - enrichAdUnits([adUnit]); - const bid1 = bids[0]; - const bid2 = bids[1]; - expect(bid1.rtd.jwplayer).to.have.deep.property('targeting', expectedTargetingForFailure); - expect(bid2.rtd.jwplayer).to.have.deep.property('targeting', expectedTargetingForFailure); - }); - }); - - describe(' Extract Publisher Params', function () { - const config = { mediaID: 'test' }; - - it('should exclude adUnits that do not support instream video and do not specify jwTargeting', function () { - const oustreamAdUnit = { mediaTypes: { video: { context: 'outstream' } } }; - const oustreamTargeting = extractPublisherParams(oustreamAdUnit, config); - expect(oustreamTargeting).to.be.undefined; - - const bannerAdUnit = { mediaTypes: { banner: {} } }; - const bannerTargeting = extractPublisherParams(bannerAdUnit, config); - expect(bannerTargeting).to.be.undefined; - - const targeting = extractPublisherParams({}, config); - expect(targeting).to.be.undefined; - }); - - it('should include ad unit when media type is video and is instream', function () { - const adUnit = { mediaTypes: { video: { context: 'instream' } } }; - const targeting = extractPublisherParams(adUnit, config); - expect(targeting).to.deep.equal(config); - }); - - it('should include banner ad units that specify jwTargeting', function() { - const adUnit = { mediaTypes: { banner: {} }, ortb2Imp: { ext: { data: { jwTargeting: {} } } } }; - const targeting = extractPublisherParams(adUnit, config); - expect(targeting).to.deep.equal(config); - }); - - it('should include outstream ad units that specify jwTargeting', function() { - const adUnit = { mediaTypes: { video: { context: 'outstream' } }, ortb2Imp: { ext: { data: { jwTargeting: {} } } } }; - const targeting = extractPublisherParams(adUnit, config); - expect(targeting).to.deep.equal(config); - }); - - it('should fallback to config when empty jwTargeting is defined in ad unit', function () { - const adUnit = { ortb2Imp: { ext: { data: { jwTargeting: {} } } } }; - const targeting = extractPublisherParams(adUnit, config); - expect(targeting).to.deep.equal(config); - }); - - it('should prioritize adUnit properties ', function () { - const expectedMediaID = 'test_media_id'; - const expectedPlayerID = 'test_player_id'; - const config = { playerID: 'bad_id', mediaID: 'bad_id' }; - - const adUnit = { ortb2Imp: { ext: { data: { jwTargeting: { mediaID: expectedMediaID, playerID: expectedPlayerID } } } } }; - const targeting = extractPublisherParams(adUnit, config); - expect(targeting).to.have.property('mediaID', expectedMediaID); - expect(targeting).to.have.property('playerID', expectedPlayerID); - }); - - it('should use config properties as fallbacks', function () { - const expectedMediaID = 'test_media_id'; - const expectedPlayerID = 'test_player_id'; - const config = { playerID: expectedPlayerID, mediaID: 'bad_id' }; - - const adUnit = { ortb2Imp: { ext: { data: { jwTargeting: { mediaID: expectedMediaID } } } } }; - const targeting = extractPublisherParams(adUnit, config); - expect(targeting).to.have.property('mediaID', expectedMediaID); - expect(targeting).to.have.property('playerID', expectedPlayerID); - }); - - it('should return undefined when Publisher Params are absent', function () { - const targeting = extractPublisherParams({}, null); - expect(targeting).to.be.undefined; - }) - }); - - describe('Add Targeting to Bid', function () { - const targeting = {foo: 'bar'}; - - it('creates realTimeData when absent from Bid', function () { - const targeting = {foo: 'bar'}; - const bid = {}; - addTargetingToBid(bid, targeting); - expect(bid).to.have.property('rtd'); - expect(bid).to.have.nested.property('rtd.jwplayer.targeting', targeting); - }); - - it('adds to existing realTimeData', function () { - const otherRtd = { - targeting: { - seg: 'rtd seg' - } - }; - - const bid = { - rtd: { - otherRtd - } - }; - - addTargetingToBid(bid, targeting); - expect(bid).to.have.property('rtd'); - const rtd = bid.rtd; - expect(rtd).to.have.property('jwplayer'); - expect(rtd).to.have.nested.property('jwplayer.targeting', targeting); - - expect(rtd).to.have.deep.property('otherRtd', otherRtd); - }); - - it('adds to existing realTimeData.jwplayer', function () { - const otherInfo = { seg: 'rtd seg' }; - const bid = { - rtd: { - jwplayer: { - otherInfo - } - } - }; - addTargetingToBid(bid, targeting); - - expect(bid).to.have.property('rtd'); - const rtd = bid.rtd; - expect(rtd).to.have.property('jwplayer'); - expect(rtd).to.have.nested.property('jwplayer.otherInfo', otherInfo); - expect(rtd).to.have.nested.property('jwplayer.targeting', targeting); - }); - - it('overrides existing jwplayer.targeting', function () { - const otherInfo = { seg: 'rtd seg' }; - const bid = { - rtd: { - jwplayer: { - targeting: { - otherInfo - } - } - } - }; - addTargetingToBid(bid, targeting); - - expect(bid).to.have.property('rtd'); - const rtd = bid.rtd; - expect(rtd).to.have.property('jwplayer'); - expect(rtd).to.have.nested.property('jwplayer.targeting', targeting); - }); - - it('creates jwplayer when absent from realTimeData', function () { - const bid = { rtd: {} }; - addTargetingToBid(bid, targeting); - - expect(bid).to.have.property('rtd'); - const rtd = bid.rtd; - expect(rtd).to.have.property('jwplayer'); - expect(rtd).to.have.nested.property('jwplayer.targeting', targeting); - }); - }); - - describe('jwplayerSubmodule', function () { - it('successfully instantiates', function () { - expect(jwplayerSubmodule.init()).to.equal(true); - }); - - describe('Get Bid Request Data', function () { - const validMediaIDs = ['media_ID_1', 'media_ID_2', 'media_ID_3']; - let bidRequestSpy; - let fakeServer; - let clock; - let bidReqConfig; - - beforeEach(function () { - bidReqConfig = { - adUnits: [ - { - ortb2Imp: { - ext: { - data: { - jwTargeting: { - mediaID: validMediaIDs[0] - } - } - } - }, - bids: [ - {}, {} - ] - }, - { - ortb2Imp: { - ext: { - data: { - jwTargeting: { - mediaID: validMediaIDs[1] - } - } - } - }, - bids: [ - {}, {} - ] - } - ] - }; - - bidRequestSpy = sinon.spy(); - - fakeServer = sinon.createFakeServer(); - fakeServer.respondImmediately = false; - fakeServer.autoRespond = false; - - clock = sinon.useFakeTimers(); - }); - - afterEach(function () { - clock.restore(); - fakeServer.respond(); - }); - - it('executes callback immediately when ad units are missing', function () { - jwplayerSubmodule.getBidRequestData({ adUnits: [] }, bidRequestSpy); - expect(bidRequestSpy.calledOnce).to.be.true; - }); - - it('executes callback immediately when no requests are pending', function () { - fetchTargetingInformation({ - mediaIDs: [] - }); - jwplayerSubmodule.getBidRequestData(bidReqConfig, bidRequestSpy); - expect(bidRequestSpy.calledOnce).to.be.true; - }); - - it('executes callback only after requests in adUnit complete', function() { - fetchTargetingInformation({ - mediaIDs: validMediaIDs - }); - jwplayerSubmodule.getBidRequestData(bidReqConfig, bidRequestSpy); - expect(bidRequestSpy.notCalled).to.be.true; - - const req1 = fakeServer.requests[0]; - const req2 = fakeServer.requests[1]; - const req3 = fakeServer.requests[2]; - - req1.respond(); - expect(bidRequestSpy.notCalled).to.be.true; - - req2.respond(); - expect(bidRequestSpy.calledOnce).to.be.true; - - req3.respond(); - expect(bidRequestSpy.calledOnce).to.be.true; - }); - - it('sets targeting data in proper structure', function () { - const bid = {}; - const adUnitWithMediaId = { - ortb2Imp: { - ext: { - data: { - jwTargeting: { - mediaID: testIdForSuccess - } - } - } - }, - bids: [ - bid - ] - }; - const adUnitEmpty = { - code: 'test_ad_unit_empty' - }; - const expectedContentId = 'jw_' + testIdForSuccess; - const expectedTargeting = { - segments: validSegments, - content: { - id: expectedContentId - } - }; - jwplayerSubmodule.getBidRequestData({ adUnits: [adUnitWithMediaId, adUnitEmpty] }, bidRequestSpy); - expect(bidRequestSpy.calledOnce).to.be.true; - expect(bid.rtd.jwplayer).to.have.deep.property('targeting', expectedTargeting); - }); - - it('excludes segments when absent', function () { - const adUnitCode = 'test_ad_unit'; - const bid = {}; - const adUnit = { - ortb2Imp: { - ext: { - data: { - jwTargeting: { - mediaID: testIdForFailure - } - } - } - }, - bids: [ bid ] - }; - const expectedContentId = 'jw_' + adUnit.ortb2Imp.ext.data.jwTargeting.mediaID; - const expectedTargeting = { - content: { - id: expectedContentId - } - }; - - 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'); - expect(bid.rtd.jwplayer).to.have.deep.property('targeting', expectedTargeting); - }); - - it('does not modify bid when jwTargeting block is absent', function () { - const adUnitCode = 'test_ad_unit'; - const bid1 = {}; - const bid2 = {}; - const bid3 = {}; - const adUnitWithMediaId = { - code: adUnitCode, - mediaID: testIdForSuccess, - bids: [ bid1 ] - }; - const adUnitEmpty = { - code: 'test_ad_unit_empty', - bids: [ bid2 ] - }; - - const adUnitEmptyfpd = { - code: 'test_ad_unit_empty_fpd', - ortb2Imp: { - ext: { - id: 'sthg' - } - }, - bids: [ bid3 ] - }; - - jwplayerSubmodule.getBidRequestData({ adUnits: [adUnitWithMediaId, adUnitEmpty, adUnitEmptyfpd] }, bidRequestSpy); - expect(bidRequestSpy.calledOnce).to.be.true; - expect(bid1).to.not.have.property('rtd'); - expect(bid2).to.not.have.property('rtd'); - expect(bid3).to.not.have.property('rtd'); - }); - }); - }); -}); diff --git a/test/spec/modules/kargoBidAdapter_spec.js b/test/spec/modules/kargoBidAdapter_spec.js deleted file mode 100644 index 43968bbef5a..00000000000 --- a/test/spec/modules/kargoBidAdapter_spec.js +++ /dev/null @@ -1,667 +0,0 @@ -import {expect, assert} from 'chai'; -import {spec} from 'modules/kargoBidAdapter.js'; -import {config} from 'src/config.js'; - -describe('kargo adapter tests', function () { - var sandbox, clock, frozenNow = new Date(); - - beforeEach(function () { - sandbox = sinon.sandbox.create(); - clock = sinon.useFakeTimers(frozenNow.getTime()); - }); - - afterEach(function () { - sandbox.restore(); - clock.restore(); - }); - - describe('bid request validity', function() { - it('passes when the bid includes a placement ID', function() { - assert(spec.isBidRequestValid({params: {placementId: 'foo'}}) === true); - }); - - it('fails when the bid does not include a placement ID', function() { - assert(spec.isBidRequestValid({params: {}}) === false); - }); - - it('fails when bid is falsey', function() { - assert(spec.isBidRequestValid() === false); - }); - - it('fails when the bid has no params at all', function() { - assert(spec.isBidRequestValid({}) === false); - }); - }); - - describe('build request', function() { - var bids, undefinedCurrency, noAdServerCurrency, cookies = [], localStorageItems = [], sessionIds = [], requestCount = 0; - - beforeEach(function () { - undefinedCurrency = false; - noAdServerCurrency = false; - sandbox.stub(config, 'getConfig').callsFake(function(key) { - if (key === 'currency') { - if (undefinedCurrency) { - return undefined; - } - if (noAdServerCurrency) { - return {}; - } - return {adServerCurrency: 'USD'}; - } - if (key === 'debug') return true; - if (key === 'deviceAccess') return true; - throw new Error(`Config stub incomplete! Missing key "${key}"`) - }); - - bids = [ - { - params: { - placementId: 'foo' - }, - bidId: 1, - userId: { - tdid: 'fake-tdid' - }, - sizes: [[320, 50], [300, 250], [300, 600]] - }, - { - params: { - placementId: 'bar' - }, - bidId: 2, - sizes: [[320, 50], [300, 250], [300, 600]] - }, - { - params: { - placementId: 'bar' - }, - bidId: 3, - sizes: [[320, 50], [300, 250], [300, 600]] - } - ]; - }); - - afterEach(function () { - for (let key in cookies) { - let cookie = cookies[key]; - removeCookie(cookie); - } - - for (let key in localStorageItems) { - let localStorageItem = localStorageItems[key]; - localStorage.removeItem(localStorageItem); - } - - cookies.length = 0; - localStorageItems.length = 0; - }); - - function setCookie(cname, cvalue, exdays = 1) { - _setCookie(cname, cvalue, exdays); - cookies.push(cname); - } - - function removeCookie(cname) { - _setCookie(cname, '', -1); - } - - function _setCookie(cname, cvalue, exdays = 1) { - var d = new Date(), - expires; - - d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); - expires = `expires=${d.toUTCString()}`; - document.cookie = `${cname}=${cvalue};${expires};path=/`; - } - - function setLocalStorageItem(name, val) { - localStorage.setItem(name, val); - localStorageItems.push(name); - } - - function simulateNoLocalStorage() { - return sandbox.stub(localStorage, 'getItem').throws(); - } - - function simulateNoCurrencyObject() { - undefinedCurrency = true; - noAdServerCurrency = false; - } - - function simulateNoAdServerCurrency() { - undefinedCurrency = false; - noAdServerCurrency = true; - } - - function generateGDPR(applies, haveConsent) { - var data = { - consentString: 'gdprconsentstring', - gdprApplies: applies, - }; - return data; - } - - function generateGDPRExpect(applies, haveConsent) { - return { - consent: 'gdprconsentstring', - applies: applies, - }; - } - - function initializeKruxUser() { - setLocalStorageItem('kxkar_user', 'rsgr9pnij'); - } - - function initializeKruxSegments() { - setLocalStorageItem('kxkar_segs', 'qv9v984dy,rpx2gy365,qrd5u4axv,rnub9nmtd,reha00jnu'); - } - - function getKrgCrb() { - return 'eyJzeW5jSWRzIjp7IjIiOiI4MmZhMjU1NS01OTY5LTQ2MTQtYjRjZS00ZGNmMTA4MGU5ZjkiLCIxNiI6IlZveElrOEFvSnowQUFFZENleUFBQUFDMiY1MDIiLCIyMyI6ImQyYTg1NWE1LTFiMWMtNDMwMC05NDBlLWE3MDhmYTFmMWJkZSIsIjI0IjoiVm94SWs4QW9KejBBQUVkQ2V5QUFBQUMyJjUwMiIsIjI1IjoiNWVlMjQxMzgtNWUwMy00YjlkLWE5NTMtMzhlODMzZjI4NDlmIiwiMl84MCI6ImQyYTg1NWE1LTFiMWMtNDMwMC05NDBlLWE3MDhmYTFmMWJkZSIsIjJfOTMiOiI1ZWUyNDEzOC01ZTAzLTRiOWQtYTk1My0zOGU4MzNmMjg0OWYifSwidXNlcklkIjoiNWYxMDg4MzEtMzAyZC0xMWU3LWJmNmItNDU5NWFjZDNiZjZjIiwiY2xpZW50SWQiOiIyNDEwZDhmMi1jMTExLTQ4MTEtODhhNS03YjVlMTkwZTQ3NWYiLCJvcHRPdXQiOmZhbHNlLCJleHBpcmVUaW1lIjoxNDk3NDQ5MzgyNjY4LCJsYXN0U3luY2VkQXQiOjE0OTczNjI5NzkwMTJ9'; - } - - function getKrgCrbOldStyle() { - return '%7B%22v%22%3A%22eyJzeW5jSWRzIjp7IjIiOiI4MmZhMjU1NS01OTY5LTQ2MTQtYjRjZS00ZGNmMTA4MGU5ZjkiLCIxNiI6IlZveElrOEFvSnowQUFFZENleUFBQUFDMiY1MDIiLCIyMyI6ImQyYTg1NWE1LTFiMWMtNDMwMC05NDBlLWE3MDhmYTFmMWJkZSIsIjI0IjoiVm94SWs4QW9KejBBQUVkQ2V5QUFBQUMyJjUwMiIsIjI1IjoiNWVlMjQxMzgtNWUwMy00YjlkLWE5NTMtMzhlODMzZjI4NDlmIiwiMl84MCI6ImQyYTg1NWE1LTFiMWMtNDMwMC05NDBlLWE3MDhmYTFmMWJkZSIsIjJfOTMiOiI1ZWUyNDEzOC01ZTAzLTRiOWQtYTk1My0zOGU4MzNmMjg0OWYifSwidXNlcklkIjoiNWYxMDg4MzEtMzAyZC0xMWU3LWJmNmItNDU5NWFjZDNiZjZjIiwiY2xpZW50SWQiOiIyNDEwZDhmMi1jMTExLTQ4MTEtODhhNS03YjVlMTkwZTQ3NWYiLCJvcHRPdXQiOmZhbHNlLCJleHBpcmVUaW1lIjoxNDk3NDQ5MzgyNjY4LCJsYXN0U3luY2VkQXQiOjE0OTczNjI5NzkwMTJ9%22%7D'; - } - - function initializeKrgCrb(cookieOnly) { - if (!cookieOnly) { - setLocalStorageItem('krg_crb', getKrgCrb()); - } - setCookie('krg_crb', getKrgCrbOldStyle()); - } - - function getInvalidKrgCrbType1() { - return 'invalid-krg-crb'; - } - - function initializeInvalidKrgCrbType1() { - setLocalStorageItem('krg_crb', getInvalidKrgCrbType1()); - } - - function initializeInvalidKrgCrbType1Cookie() { - setCookie('krg_crb', getInvalidKrgCrbType1()); - } - - function getInvalidKrgCrbType2() { - return 'Ly8v'; - } - - function getInvalidKrgCrbType2OldStyle() { - return '%7B%22v%22%3A%22%26%26%26%26%26%26%22%7D'; - } - - function initializeInvalidKrgCrbType2() { - setLocalStorageItem('krg_crb', getInvalidKrgCrbType2()); - } - - function initializeInvalidKrgCrbType2Cookie() { - setCookie('krg_crb', getInvalidKrgCrbType2OldStyle()); - } - - function getInvalidKrgCrbType3OldStyle() { - return '%7B%22v%22%3A%22Ly8v%22%7D'; - } - - function initializeInvalidKrgCrbType3Cookie() { - setCookie('krg_crb', getInvalidKrgCrbType3OldStyle()); - } - - function getInvalidKrgCrbType4OldStyle() { - return '%7B%22v%22%3A%22bnVsbA%3D%3D%22%7D'; - } - - function initializeInvalidKrgCrbType4Cookie() { - setCookie('krg_crb', getInvalidKrgCrbType4OldStyle()); - } - - function getEmptyKrgCrb() { - return 'eyJleHBpcmVUaW1lIjoxNDk3NDQ5MzgyNjY4LCJsYXN0U3luY2VkQXQiOjE0OTczNjI5NzkwMTJ9'; - } - - function getEmptyKrgCrbOldStyle() { - return '%7B%22v%22%3A%22eyJleHBpcmVUaW1lIjoxNDk3NDQ5MzgyNjY4LCJsYXN0U3luY2VkQXQiOjE0OTczNjI5NzkwMTJ9%22%7D'; - } - - function initializeEmptyKrgCrb() { - setLocalStorageItem('krg_crb', getEmptyKrgCrb()); - } - - function initializeEmptyKrgCrbCookie() { - setCookie('krg_crb', getEmptyKrgCrbOldStyle()); - } - - function getSessionId() { - return spec._getSessionId(); - } - - function getExpectedKrakenParams(excludeUserIds, excludeKrux, expectedRawCRB, expectedRawCRBCookie, expectedGDPR) { - var base = { - timeout: 200, - requestCount: requestCount++, - currency: 'USD', - cpmGranularity: 1, - timestamp: frozenNow.getTime(), - cpmRange: { - floor: 0, - ceil: 20 - }, - bidIDs: { - 1: 'foo', - 2: 'bar', - 3: 'bar' - }, - bidSizes: { - 1: [[320, 50], [300, 250], [300, 600]], - 2: [[320, 50], [300, 250], [300, 600]], - 3: [[320, 50], [300, 250], [300, 600]] - }, - userIDs: { - kargoID: '5f108831-302d-11e7-bf6b-4595acd3bf6c', - clientID: '2410d8f2-c111-4811-88a5-7b5e190e475f', - tdID: 'fake-tdid', - crbIDs: { - 2: '82fa2555-5969-4614-b4ce-4dcf1080e9f9', - 16: 'VoxIk8AoJz0AAEdCeyAAAAC2&502', - 23: 'd2a855a5-1b1c-4300-940e-a708fa1f1bde', - 24: 'VoxIk8AoJz0AAEdCeyAAAAC2&502', - 25: '5ee24138-5e03-4b9d-a953-38e833f2849f', - '2_80': 'd2a855a5-1b1c-4300-940e-a708fa1f1bde', - '2_93': '5ee24138-5e03-4b9d-a953-38e833f2849f' - }, - optOut: false, - usp: '1---' - }, - krux: { - userID: 'rsgr9pnij', - segments: [ - 'qv9v984dy', - 'rpx2gy365', - 'qrd5u4axv', - 'rnub9nmtd', - 'reha00jnu' - ] - }, - pageURL: window.location.href, - prebidRawBidRequests: [ - { - bidId: 1, - params: { - placementId: 'foo' - }, - userId: { - tdid: 'fake-tdid' - }, - sizes: [[320, 50], [300, 250], [300, 600]] - }, - { - bidId: 2, - params: { - placementId: 'bar' - }, - sizes: [[320, 50], [300, 250], [300, 600]] - }, - { - bidId: 3, - params: { - placementId: 'bar' - }, - sizes: [[320, 50], [300, 250], [300, 600]] - } - ], - rawCRB: expectedRawCRBCookie, - rawCRBLocalStorage: expectedRawCRB - }; - - if (expectedGDPR) { - base.userIDs['gdpr'] = expectedGDPR; - } - - if (excludeUserIds === true) { - base.userIDs = { - crbIDs: {}, - usp: '1---' - }; - delete base.prebidRawBidRequests[0].userId.tdid; - } - - if (excludeKrux) { - base.krux = { - userID: null, - segments: [] - }; - } - - return base; - } - - function testBuildRequests(excludeTdid, expected, gdpr) { - var clonedBids = JSON.parse(JSON.stringify(bids)); - if (excludeTdid) { - delete clonedBids[0].userId.tdid; - } - var payload = { timeout: 200, uspConsent: '1---', foo: 'bar' }; - if (gdpr) { - payload['gdprConsent'] = gdpr - } - var request = spec.buildRequests(clonedBids, payload); - expected.sessionId = getSessionId(); - sessionIds.push(expected.sessionId); - var krakenParams = JSON.parse(decodeURIComponent(request.data.slice(5))); - expect(request.data.slice(0, 5)).to.equal('json='); - expect(request.url).to.equal('https://krk.kargo.com/api/v2/bid'); - expect(request.method).to.equal('GET'); - expect(request.currency).to.equal('USD'); - expect(request.timeout).to.equal(200); - expect(request.foo).to.equal('bar'); - expect(krakenParams).to.deep.equal(expected); - // Make sure session ID stays the same across requests simulating multiple auctions on one page load - for (let i in sessionIds) { - if (i == 0) { - continue; - } - let sessionId = sessionIds[i]; - expect(sessionIds[0]).to.equal(sessionId); - } - } - - it('works when all params and localstorage and cookies are correctly set', function() { - initializeKruxUser(); - initializeKruxSegments(); - initializeKrgCrb(); - testBuildRequests(false, getExpectedKrakenParams(undefined, undefined, getKrgCrb(), getKrgCrbOldStyle())); - }); - - it('works when all params and cookies are correctly set but no localstorage', function() { - initializeKruxUser(); - initializeKruxSegments(); - initializeKrgCrb(true); - testBuildRequests(false, getExpectedKrakenParams(undefined, undefined, null, getKrgCrbOldStyle())); - }); - - it('gracefully handles nothing being set', function() { - testBuildRequests(true, getExpectedKrakenParams(true, true, null, null)); - }); - - it('gracefully handles browsers without localStorage', function() { - simulateNoLocalStorage(); - testBuildRequests(true, getExpectedKrakenParams(true, true, null, null)); - }); - - it('handles empty yet valid Kargo CRB', function() { - initializeKruxUser(); - initializeKruxSegments(); - initializeEmptyKrgCrb(); - initializeEmptyKrgCrbCookie(); - testBuildRequests(true, getExpectedKrakenParams(true, undefined, getEmptyKrgCrb(), getEmptyKrgCrbOldStyle())); - }); - - it('handles broken Kargo CRBs where base64 encoding is invalid', function() { - initializeKruxUser(); - initializeKruxSegments(); - initializeInvalidKrgCrbType1(); - testBuildRequests(true, getExpectedKrakenParams(true, undefined, getInvalidKrgCrbType1(), null)); - }); - - it('handles broken Kargo CRBs where top level JSON is invalid on cookie', function() { - initializeKruxUser(); - initializeKruxSegments(); - initializeInvalidKrgCrbType1Cookie(); - testBuildRequests(true, getExpectedKrakenParams(true, undefined, null, getInvalidKrgCrbType1())); - }); - - it('handles broken Kargo CRBs where decoded JSON is invalid', function() { - initializeKruxUser(); - initializeKruxSegments(); - initializeInvalidKrgCrbType2(); - testBuildRequests(true, getExpectedKrakenParams(true, undefined, getInvalidKrgCrbType2(), null)); - }); - - it('handles broken Kargo CRBs where inner base 64 is invalid on cookie', function() { - initializeKruxUser(); - initializeKruxSegments(); - initializeInvalidKrgCrbType2Cookie(); - testBuildRequests(true, getExpectedKrakenParams(true, undefined, null, getInvalidKrgCrbType2OldStyle())); - }); - - it('handles broken Kargo CRBs where inner JSON is invalid on cookie', function() { - initializeKruxUser(); - initializeKruxSegments(); - initializeInvalidKrgCrbType3Cookie(); - testBuildRequests(true, getExpectedKrakenParams(true, undefined, null, getInvalidKrgCrbType3OldStyle())); - }); - - it('handles broken Kargo CRBs where inner JSON is falsey', function() { - initializeKruxUser(); - initializeKruxSegments(); - initializeInvalidKrgCrbType4Cookie(); - testBuildRequests(true, getExpectedKrakenParams(true, undefined, null, getInvalidKrgCrbType4OldStyle())); - }); - - it('handles a non-existant currency object on the config', function() { - simulateNoCurrencyObject(); - initializeKruxUser(); - initializeKruxSegments(); - initializeKrgCrb(); - testBuildRequests(false, getExpectedKrakenParams(undefined, undefined, getKrgCrb(), getKrgCrbOldStyle())); - }); - - it('handles no ad server currency being set on the currency object in the config', function() { - simulateNoAdServerCurrency(); - initializeKruxUser(); - initializeKruxSegments(); - initializeKrgCrb(); - testBuildRequests(false, getExpectedKrakenParams(undefined, undefined, getKrgCrb(), getKrgCrbOldStyle())); - }); - - it('sends gdpr consent', function () { - initializeKruxUser(); - initializeKruxSegments(); - initializeKrgCrb(); - testBuildRequests(false, getExpectedKrakenParams(undefined, undefined, getKrgCrb(), getKrgCrbOldStyle(), generateGDPRExpect(true, true)), generateGDPR(true, true)); - testBuildRequests(false, getExpectedKrakenParams(undefined, undefined, getKrgCrb(), getKrgCrbOldStyle(), generateGDPRExpect(false, true)), generateGDPR(false, true)); - testBuildRequests(false, getExpectedKrakenParams(undefined, undefined, getKrgCrb(), getKrgCrbOldStyle(), generateGDPRExpect(false, false)), generateGDPR(false, false)); - }); - }); - - describe('response handler', function() { - it('handles bid responses', function() { - var resp = spec.interpretResponse({body: { - 1: { - id: 'foo', - cpm: 3, - adm: '
', - width: 320, - height: 50, - metadata: {} - }, - 2: { - id: 'bar', - cpm: 2.5, - adm: '
', - width: 300, - height: 250, - targetingCustom: 'dmpmptest1234', - metadata: { - landingPageDomain: 'https://foobar.com' - } - }, - 3: { - id: 'bar', - cpm: 2.5, - adm: '
', - width: 300, - height: 250 - } - }}, { - currency: 'USD', - bids: [{ - bidId: 1, - params: { - placementId: 'foo' - } - }, { - bidId: 2, - params: { - placementId: 'bar' - } - }, { - bidId: 3, - params: { - placementId: 'bar' - } - }] - }); - var expectation = [{ - requestId: '1', - cpm: 3, - width: 320, - height: 50, - ad: '
', - ttl: 300, - creativeId: 'foo', - dealId: undefined, - netRevenue: true, - currency: 'USD', - meta: undefined - }, { - requestId: '2', - cpm: 2.5, - width: 300, - height: 250, - ad: '
', - ttl: 300, - creativeId: 'bar', - dealId: 'dmpmptest1234', - netRevenue: true, - currency: 'USD', - meta: { - clickUrl: 'https://foobar.com', - advertiserDomains: ['https://foobar.com'] - } - }, { - requestId: '3', - cpm: 2.5, - width: 300, - height: 250, - ad: '
', - ttl: 300, - creativeId: 'bar', - dealId: undefined, - netRevenue: true, - currency: 'USD', - meta: undefined - }]; - expect(resp).to.deep.equal(expectation); - }); - }); - - describe('user sync handler', function() { - const clientId = '74c81cbb-7d07-46d9-be9b-68ccb291c949'; - var shouldSimulateOutdatedBrowser, crb, isActuallyOutdatedBrowser; - - beforeEach(() => { - crb = {}; - shouldSimulateOutdatedBrowser = false; - isActuallyOutdatedBrowser = false; - - // IE11 fails these tests in the Prebid test suite. Since this - // browser won't support any of this stuff we expect all user - // syncing to fail gracefully. Kargo is mobile only, so this - // doesn't really matter. - if (!window.crypto) { - isActuallyOutdatedBrowser = true; - } else { - sandbox.stub(crypto, 'getRandomValues').callsFake(function(buf) { - if (shouldSimulateOutdatedBrowser) { - throw new Error('Could not generate random values'); - } - var bytes = [50, 5, 232, 133, 141, 55, 49, 57, 244, 126, 248, 44, 255, 38, 128, 0]; - for (var i = 0; i < bytes.length; i++) { - buf[i] = bytes[i]; - } - return buf; - }); - } - - sandbox.stub(spec, '_getCrb').callsFake(function() { - return crb; - }); - }); - - function getUserSyncsWhenAllowed(gdprConsent, usPrivacy) { - return spec.getUserSyncs({iframeEnabled: true}, null, gdprConsent, usPrivacy); - } - - function getUserSyncsWhenForbidden() { - return spec.getUserSyncs({}); - } - - function turnOnClientId() { - crb.clientId = clientId; - } - - function simulateOutdatedBrowser() { - shouldSimulateOutdatedBrowser = true; - } - - function getSyncUrl(index, gdprApplies, gdprConsentString, usPrivacy) { - return { - type: 'iframe', - url: `https://crb.kargo.com/api/v1/initsyncrnd/${clientId}?seed=3205e885-8d37-4139-b47e-f82cff268000&idx=${index}&gdpr=${gdprApplies}&gdpr_consent=${gdprConsentString}&us_privacy=${usPrivacy}` - }; - } - - function getSyncUrls(gdprApplies, gdprConsentString, usPrivacy) { - var syncs = []; - for (var i = 0; i < 5; i++) { - syncs[i] = getSyncUrl(i, gdprApplies || 0, gdprConsentString || '', usPrivacy || ''); - } - return syncs; - } - - function safelyRun(runExpectation) { - if (isActuallyOutdatedBrowser) { - expect(getUserSyncsWhenAllowed()).to.be.an('array').that.is.empty; - } else { - runExpectation(); - } - } - - it('handles user syncs when there is a client id', function() { - turnOnClientId(); - safelyRun(() => expect(getUserSyncsWhenAllowed()).to.deep.equal(getSyncUrls())); - }); - - it('no user syncs when there is no client id', function() { - safelyRun(() => expect(getUserSyncsWhenAllowed()).to.be.an('array').that.is.empty); - }); - - it('no user syncs when there is no us privacy consent', function() { - turnOnClientId(); - safelyRun(() => expect(getUserSyncsWhenAllowed(null, '1YYY')).to.be.an('array').that.is.empty); - }); - - it('pass through us privacy consent', function() { - turnOnClientId(); - safelyRun(() => expect(getUserSyncsWhenAllowed(null, '1YNY')).to.deep.equal(getSyncUrls(0, '', '1YNY'))); - }); - - it('pass through gdpr consent', function() { - turnOnClientId(); - safelyRun(() => expect(getUserSyncsWhenAllowed({ gdprApplies: true, consentString: 'consentstring' })).to.deep.equal(getSyncUrls(1, 'consentstring', ''))); - }); - - it('no user syncs when there is outdated browser', function() { - turnOnClientId(); - simulateOutdatedBrowser(); - safelyRun(() => expect(getUserSyncsWhenAllowed()).to.be.an('array').that.is.empty); - }); - - it('no user syncs when no iframe syncing allowed', function() { - turnOnClientId(); - safelyRun(() => expect(getUserSyncsWhenForbidden()).to.be.an('array').that.is.empty); - }); - }); -}); diff --git a/test/spec/modules/koblerBidAdapter_spec.js b/test/spec/modules/koblerBidAdapter_spec.js deleted file mode 100644 index 725c9ece118..00000000000 --- a/test/spec/modules/koblerBidAdapter_spec.js +++ /dev/null @@ -1,694 +0,0 @@ -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'; - -function createBidderRequest(auctionId, timeout, pageUrl) { - return { - auctionId: auctionId || 'c1243d83-0bed-4fdb-8c76-42b456be17d0', - timeout: timeout || 2000, - refererInfo: { - referer: pageUrl || 'example.com' - } - }; -} - -function createValidBidRequest(params, bidId, sizes) { - return { - adUnitCode: 'adunit-code', - bidId: bidId || '22c4871113f461', - bidder: 'kobler', - bidderRequestId: '15246a574e859f', - bidRequestsCount: 1, - bidderRequestsCount: 1, - mediaTypes: { - banner: { - sizes: sizes || [[300, 250], [320, 100]] - } - }, - params: params || { - placementId: 'tpw58278' - }, - transactionTd: '04314114-15bd-4638-8664-bdb8bdc60bff' - }; -} - -describe('KoblerAdapter', function () { - describe('inherited functions', function () { - it('exists and is a function', function () { - const adapter = newBidder(spec); - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - it('should not accept a request without bidId as valid', function () { - const bid = { - params: { - someParam: 'abc' - } - }; - - const result = spec.isBidRequestValid(bid); - - expect(result).to.be.false; - }); - - it('should not accept a request without params as valid', function () { - const bid = { - bidId: 'e11768e8-3b71-4453-8698-0a2feb866589' - }; - - const result = spec.isBidRequestValid(bid); - - expect(result).to.be.false; - }); - - it('should not accept a request without placementId as valid', function () { - const bid = { - bidId: 'e11768e8-3b71-4453-8698-0a2feb866589', - params: { - someParam: 'abc' - } - }; - - const result = spec.isBidRequestValid(bid); - - expect(result).to.be.false; - }); - - it('should accept a request with bidId and placementId as valid', function () { - const bid = { - bidId: 'e11768e8-3b71-4453-8698-0a2feb866589', - params: { - someParam: 'abc', - placementId: '8bde0923-1409-4253-9594-495b58d931ba' - } - }; - - const result = spec.isBidRequestValid(bid); - - expect(result).to.be.true; - }); - }); - - describe('buildRequests', function () { - it('should read data from bidder request', function () { - const testUrl = 'kobler.no'; - const auctionId = '8319af54-9795-4642-ba3a-6f57d6ff9100'; - const timeout = 5000; - const validBidRequests = [createValidBidRequest()]; - const bidderRequest = createBidderRequest(auctionId, timeout, testUrl); - - const result = spec.buildRequests(validBidRequests, bidderRequest); - const openRtbRequest = JSON.parse(result.data); - - expect(openRtbRequest.tmax).to.be.equal(timeout); - expect(openRtbRequest.id).to.be.equal(auctionId); - expect(openRtbRequest.site.page).to.be.equal(testUrl); - }); - - it('should read data from valid bid requests', function () { - const firstSize = [400, 800]; - const secondSize = [450, 950]; - const sizes = [firstSize, secondSize]; - const placementId = 'tsjs86325'; - const bidId = '3a56a019-4835-4f75-811c-76fac6853a2c'; - const validBidRequests = [ - createValidBidRequest( - { - placementId: placementId - }, - bidId, - sizes - ) - ]; - const bidderRequest = createBidderRequest(); - - const result = spec.buildRequests(validBidRequests, bidderRequest); - const openRtbRequest = JSON.parse(result.data); - - expect(openRtbRequest.imp.length).to.be.equal(1); - expect(openRtbRequest.imp[0].id).to.be.equal(bidId); - expect(openRtbRequest.imp[0].tagid).to.be.equal(placementId); - expect(openRtbRequest.imp[0].banner.w).to.be.equal(firstSize[0]); - expect(openRtbRequest.imp[0].banner.h).to.be.equal(firstSize[1]); - expect(openRtbRequest.imp[0].banner.format.length).to.be.equal(2); - expect(openRtbRequest.imp[0].banner.format[0].w).to.be.equal(firstSize[0]); - expect(openRtbRequest.imp[0].banner.format[0].h).to.be.equal(firstSize[1]); - expect(openRtbRequest.imp[0].banner.format[1].w).to.be.equal(secondSize[0]); - expect(openRtbRequest.imp[0].banner.format[1].h).to.be.equal(secondSize[1]); - }); - - it('should use 0x0 as default size', function () { - const validBidRequests = [ - createValidBidRequest( - undefined, - undefined, - [] - ) - ]; - const bidderRequest = createBidderRequest(); - - const result = spec.buildRequests(validBidRequests, bidderRequest); - const openRtbRequest = JSON.parse(result.data); - - expect(openRtbRequest.imp.length).to.be.equal(1); - expect(openRtbRequest.imp[0].banner.w).to.be.equal(0); - expect(openRtbRequest.imp[0].banner.h).to.be.equal(0); - expect(openRtbRequest.imp[0].banner.format.length).to.be.equal(1); - expect(openRtbRequest.imp[0].banner.format[0].w).to.be.equal(0); - expect(openRtbRequest.imp[0].banner.format[0].h).to.be.equal(0); - }); - - it('should use 0 as default position', function () { - const validBidRequests = [createValidBidRequest()]; - const bidderRequest = createBidderRequest(); - - const result = spec.buildRequests(validBidRequests, bidderRequest); - const openRtbRequest = JSON.parse(result.data); - - expect(openRtbRequest.imp.length).to.be.equal(1); - expect(openRtbRequest.imp[0].banner.ext.kobler.pos).to.be.equal(0); - }); - - it('should read zip from valid bid requests', function () { - const zip = '700 02'; - const validBidRequests = [ - createValidBidRequest( - { - placementId: 'nmah8324234', - zip: zip - } - ) - ]; - const bidderRequest = createBidderRequest(); - - const result = spec.buildRequests(validBidRequests, bidderRequest); - const openRtbRequest = JSON.parse(result.data); - - expect(openRtbRequest.device.geo.zip).to.be.equal(zip); - }); - - it('should read test from valid bid requests', function () { - const validBidRequests = [ - createValidBidRequest( - { - placementId: 'zwop842799', - test: true - } - ) - ]; - const bidderRequest = createBidderRequest(); - - const result = spec.buildRequests(validBidRequests, bidderRequest); - const openRtbRequest = JSON.parse(result.data); - - expect(openRtbRequest.test).to.be.equal(1); - }); - - it('should read floorPrice from valid bid requests', function () { - const floorPrice = 4.343; - const validBidRequests = [ - createValidBidRequest( - { - placementId: 'oqr3224234', - floorPrice: floorPrice - } - ) - ]; - const bidderRequest = createBidderRequest(); - - const result = spec.buildRequests(validBidRequests, bidderRequest); - const openRtbRequest = JSON.parse(result.data); - - expect(openRtbRequest.imp.length).to.be.equal(1); - expect(openRtbRequest.imp[0].bidfloor).to.be.equal(floorPrice); - }); - - it('should read position from valid bid requests', function () { - const placementId = 'yzksf234592'; - const validBidRequests = [ - createValidBidRequest( - { - placementId: placementId, - position: 1 - } - ), - createValidBidRequest( - { - placementId: placementId, - position: 2 - } - ), - createValidBidRequest( - { - placementId: placementId, - position: 3 - } - ) - ]; - const bidderRequest = createBidderRequest(); - - const result = spec.buildRequests(validBidRequests, bidderRequest); - const openRtbRequest = JSON.parse(result.data); - - expect(openRtbRequest.imp.length).to.be.equal(3); - expect(openRtbRequest.imp[0].banner.ext.kobler.pos).to.be.equal(1); - expect(openRtbRequest.imp[0].tagid).to.be.equal(placementId); - expect(openRtbRequest.imp[1].banner.ext.kobler.pos).to.be.equal(2); - expect(openRtbRequest.imp[1].tagid).to.be.equal(placementId); - expect(openRtbRequest.imp[2].banner.ext.kobler.pos).to.be.equal(3); - expect(openRtbRequest.imp[2].tagid).to.be.equal(placementId); - }); - - it('should read dealIds from valid bid requests', function () { - const dealIds1 = ['78214682234823']; - const dealIds2 = ['89913861235234', '27368423545328640']; - const validBidRequests = [ - createValidBidRequest( - { - placementId: 'rsl1239823', - dealIds: dealIds1 - } - ), - createValidBidRequest( - { - placementId: 'pqw234232', - dealIds: dealIds2 - } - ) - ]; - const bidderRequest = createBidderRequest(); - - const result = spec.buildRequests(validBidRequests, bidderRequest); - const openRtbRequest = JSON.parse(result.data); - - expect(openRtbRequest.imp.length).to.be.equal(2); - expect(openRtbRequest.imp[0].pmp.deals.length).to.be.equal(1); - expect(openRtbRequest.imp[0].pmp.deals[0].id).to.be.equal(dealIds1[0]); - expect(openRtbRequest.imp[1].pmp.deals.length).to.be.equal(2); - expect(openRtbRequest.imp[1].pmp.deals[0].id).to.be.equal(dealIds2[0]); - expect(openRtbRequest.imp[1].pmp.deals[1].id).to.be.equal(dealIds2[1]); - }); - - it('should read timeout from config', function () { - const timeout = 4000; - const validBidRequests = [createValidBidRequest()]; - // No timeout field - const bidderRequest = { - auctionId: 'c1243d83-0bed-4fdb-8c76-42b456be17d0', - refererInfo: { - referer: 'example.com' - } - }; - config.setConfig({ - bidderTimeout: timeout - }); - - const result = spec.buildRequests(validBidRequests, bidderRequest); - const openRtbRequest = JSON.parse(result.data); - - expect(openRtbRequest.tmax).to.be.equal(timeout); - }); - - it('should read floor price using floors module', function () { - const floorPriceFor580x400 = 6.5148; - const floorPriceForAnySize = 4.2343; - const validBidRequests = [ - createValidBidRequest(undefined, '98efe127-f926-4dde-b988-db8e5dba5a76', [[580, 400]]), - createValidBidRequest(undefined, 'c7698d4a-94f4-4a6b-a928-7e1facfbf752', []) - ]; - validBidRequests.forEach(validBidRequest => { - validBidRequest.getFloor = function (params) { - let floorPrice; - if (utils.isArray(params.size) && params.size[0] === 580 && params.size[1] === 400) { - floorPrice = floorPriceFor580x400; - } else if (params.size === '*') { - floorPrice = floorPriceForAnySize - } else { - floorPrice = 0 - } - return { - currency: params.currency, - floor: floorPrice - } - } - }) - const bidderRequest = createBidderRequest(); - - const result = spec.buildRequests(validBidRequests, bidderRequest); - const openRtbRequest = JSON.parse(result.data); - - expect(openRtbRequest.imp.length).to.be.equal(2); - expect(openRtbRequest.imp[0].id).to.be.equal('98efe127-f926-4dde-b988-db8e5dba5a76'); - expect(openRtbRequest.imp[0].bidfloor).to.be.equal(floorPriceFor580x400); - expect(openRtbRequest.imp[1].id).to.be.equal('c7698d4a-94f4-4a6b-a928-7e1facfbf752'); - expect(openRtbRequest.imp[1].bidfloor).to.be.equal(floorPriceForAnySize); - }); - - it('should create whole OpenRTB request', function () { - const validBidRequests = [ - createValidBidRequest( - { - placementId: 'pcha322364', - zip: '0015', - floorPrice: 5.6234, - position: 1, - dealIds: ['623472534328234'] - }, - '953ee65d-d18a-484f-a840-d3056185a060', - [[400, 600]] - ), - createValidBidRequest( - { - placementId: 'sdfgoi32y4', - floorPrice: 3.2543, - position: 2, - dealIds: ['92368234753283', '263845832942'] - }, - '8320bf79-9d90-4a17-87c6-5d505706a921', - [[400, 500], [200, 250], [300, 350]] - ), - createValidBidRequest( - { - placementId: 'gwms2738647', - position: 3 - }, - 'd0de713b-32e3-4191-a2df-a007f08ffe72', - [[800, 900]] - ) - ]; - const bidderRequest = createBidderRequest( - '9ff580cf-e10e-4b66-add7-40ac0c804e21', - 4500, - 'bid.kobler.no' - ); - - const result = spec.buildRequests(validBidRequests, bidderRequest); - const openRtbRequest = JSON.parse(result.data); - - const expectedOpenRtbRequest = { - id: '9ff580cf-e10e-4b66-add7-40ac0c804e21', - at: 1, - tmax: 4500, - cur: ['USD'], - imp: [ - { - id: '953ee65d-d18a-484f-a840-d3056185a060', - banner: { - format: [ - { - w: 400, - h: 600 - } - ], - w: 400, - h: 600, - ext: { - kobler: { - pos: 1 - } - } - }, - tagid: 'pcha322364', - bidfloor: 5.6234, - bidfloorcur: 'USD', - pmp: { - deals: [ - { - id: '623472534328234' - } - ] - } - }, - { - id: '8320bf79-9d90-4a17-87c6-5d505706a921', - banner: { - format: [ - { - w: 400, - h: 500 - }, - { - w: 200, - h: 250 - }, - { - w: 300, - h: 350 - } - ], - w: 400, - h: 500, - ext: { - kobler: { - pos: 2 - } - } - }, - tagid: 'sdfgoi32y4', - bidfloor: 3.2543, - bidfloorcur: 'USD', - pmp: { - deals: [ - { - id: '92368234753283' - }, - { - id: '263845832942' - } - ] - } - }, - { - id: 'd0de713b-32e3-4191-a2df-a007f08ffe72', - banner: { - format: [ - { - w: 800, - h: 900 - } - ], - w: 800, - h: 900, - ext: { - kobler: { - pos: 3 - } - } - }, - tagid: 'gwms2738647', - bidfloor: 0, - bidfloorcur: 'USD', - pmp: {} - } - ], - device: { - devicetype: 2, - geo: { - zip: '0015' - } - }, - site: { - page: 'bid.kobler.no' - }, - test: 0 - }; - - expect(openRtbRequest).to.deep.equal(expectedOpenRtbRequest); - }); - }); - - describe('interpretResponse', function () { - it('should handle empty body', function () { - const responseWithEmptyBody = { - body: undefined - }; - const bids = spec.interpretResponse(responseWithEmptyBody) - - expect(bids.length).to.be.equal(0); - }); - - it('should generate bids from OpenRTB response', function () { - const responseWithTwoBids = { - body: { - seatbid: [ - { - bid: [ - { - impid: '6194ddef-89a4-404f-9efd-6b718fc23308', - price: 7.981, - nurl: 'https://atag.essrtb.com/serve/prebid_win_notification?payload=sdhfusdaobfadslf234324&sp=${AUCTION_PRICE}&asp=${AD_SERVER_PRICE}', - crid: 'edea9b03-3a57-41aa-9c00-abd673e22006', - dealid: '', - w: 320, - h: 250, - adm: '', - adomain: [ - 'https://kobler.no' - ] - }, - { - impid: '2ec0b40f-d3ca-4ba5-8ce3-48290565690f', - price: 6.71234, - nurl: 'https://atag.essrtb.com/serve/prebid_win_notification?payload=nbashgufvishdafjk23432&sp=${AUCTION_PRICE}&asp=${AD_SERVER_PRICE}', - crid: 'fa2d5af7-2678-4204-9023-44c526160742', - dealid: '2783483223432342', - w: 580, - h: 400, - adm: '', - adomain: [ - 'https://bid.kobler.no' - ] - } - ] - } - ], - cur: 'USD' - } - }; - const bids = spec.interpretResponse(responseWithTwoBids) - - const expectedBids = [ - { - requestId: '6194ddef-89a4-404f-9efd-6b718fc23308', - cpm: 7.981, - currency: 'USD', - width: 320, - height: 250, - creativeId: 'edea9b03-3a57-41aa-9c00-abd673e22006', - dealId: '', - netRevenue: true, - ttl: 600, - ad: '', - nurl: 'https://atag.essrtb.com/serve/prebid_win_notification?payload=sdhfusdaobfadslf234324&sp=${AUCTION_PRICE}&asp=${AD_SERVER_PRICE}', - meta: { - advertiserDomains: [ - 'https://kobler.no' - ] - } - }, - { - requestId: '2ec0b40f-d3ca-4ba5-8ce3-48290565690f', - cpm: 6.71234, - currency: 'USD', - width: 580, - height: 400, - creativeId: 'fa2d5af7-2678-4204-9023-44c526160742', - dealId: '2783483223432342', - netRevenue: true, - ttl: 600, - ad: '', - nurl: 'https://atag.essrtb.com/serve/prebid_win_notification?payload=nbashgufvishdafjk23432&sp=${AUCTION_PRICE}&asp=${AD_SERVER_PRICE}', - meta: { - advertiserDomains: [ - 'https://bid.kobler.no' - ] - } - } - ]; - expect(bids).to.deep.equal(expectedBids); - }); - }); - - describe('onBidWon', function () { - beforeEach(function () { - sinon.stub(utils, 'triggerPixel'); - }); - afterEach(function () { - utils.triggerPixel.restore(); - }); - - it('Should not trigger pixel if bid does not contain nurl', function () { - spec.onBidWon({}); - - expect(utils.triggerPixel.called).to.be.false; - }); - - it('Should not trigger pixel if nurl is empty', function () { - spec.onBidWon({ - nurl: '' - }); - - expect(utils.triggerPixel.called).to.be.false; - }); - - it('Should trigger pixel with replaced nurl if nurl is not empty', function () { - spec.onBidWon({ - cpm: 8.341, - nurl: 'https://atag.essrtb.com/serve/prebid_win_notification?payload=sdhfusdaobfadslf234324&sp=${AUCTION_PRICE}&asp=${AD_SERVER_PRICE}', - adserverTargeting: { - hb_pb: 8 - } - }); - - expect(utils.triggerPixel.callCount).to.be.equal(1); - expect(utils.triggerPixel.firstCall.args[0]).to.be.equal( - 'https://atag.essrtb.com/serve/prebid_win_notification?payload=sdhfusdaobfadslf234324&sp=8.341&asp=8' - ); - }); - }); - - describe('onTimeout', function () { - beforeEach(function () { - sinon.stub(utils, 'triggerPixel'); - }); - afterEach(function () { - utils.triggerPixel.restore(); - }); - - it('Should not trigger pixel if timeout data is not array', function () { - spec.onTimeout(null); - - expect(utils.triggerPixel.called).to.be.false; - }); - - it('Should not trigger pixel if timeout data is empty', function () { - spec.onTimeout([]); - - expect(utils.triggerPixel.called).to.be.false; - }); - - it('Should trigger pixel with query parameters if timeout data not empty', function () { - spec.onTimeout([ - { - adUnitCode: 'adunit-code', - auctionId: 'a1fba829-dd41-409f-acfb-b7b0ac5f30c6', - bidId: 'ef236c6c-e934-406b-a877-d7be8e8a839a', - timeout: 100, - params: [ - { - placementId: 'xrwg62731', - } - ], - }, - { - adUnitCode: 'adunit-code-2', - auctionId: 'a1fba829-dd41-409f-acfb-b7b0ac5f30c6', - bidId: 'ca4121c8-9a4a-46ba-a624-e9b64af206f2', - timeout: 100, - params: [ - { - placementId: 'bc482234', - } - ], - } - ]); - - expect(utils.triggerPixel.callCount).to.be.equal(2); - expect(utils.triggerPixel.getCall(0).args[0]).to.be.equal( - 'https://bid.essrtb.com/notify/prebid_timeout?ad_unit_code=adunit-code&' + - 'auction_id=a1fba829-dd41-409f-acfb-b7b0ac5f30c6&bid_id=ef236c6c-e934-406b-a877-d7be8e8a839a&timeout=100&' + - 'placement_id=xrwg62731&page_url=' + encodeURIComponent(getRefererInfo().referer) - ); - expect(utils.triggerPixel.getCall(1).args[0]).to.be.equal( - 'https://bid.essrtb.com/notify/prebid_timeout?ad_unit_code=adunit-code-2&' + - 'auction_id=a1fba829-dd41-409f-acfb-b7b0ac5f30c6&bid_id=ca4121c8-9a4a-46ba-a624-e9b64af206f2&timeout=100&' + - 'placement_id=bc482234&page_url=' + encodeURIComponent(getRefererInfo().referer) - ); - }); - }); -}); diff --git a/test/spec/modules/komoonaBidAdapter_spec.js b/test/spec/modules/komoonaBidAdapter_spec.js deleted file mode 100644 index 3d62f91cae6..00000000000 --- a/test/spec/modules/komoonaBidAdapter_spec.js +++ /dev/null @@ -1,164 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/komoonaBidAdapter.js'; - -describe('Komoona.com Adapter Tests', function () { - const bidsRequest = [ - { - bidder: 'komoona', - params: { - placementId: '170577', - hbid: 'abc12345678', - }, - placementCode: 'div-gpt-ad-1460505748561-0', - transactionId: '9f801c02-bbe8-4683-8ed4-bc816ea186bb', - sizes: [ - [300, 250] - ], - bidId: '2faedf1095f815', - bidderRequestId: '18065867f8ae39', - auctionId: '529e1518-b872-45cf-807c-2d41dfa5bcd3' - }, - { - bidder: 'komoona', - params: { - placementId: '281277', - hbid: 'abc12345678', - floorPrice: 0.5 - }, - placementCode: 'div-gpt-ad-1460505748561-0', - transactionId: '9f801c02-bbe8-4683-8ed4-bc816ea186bb', - sizes: [ - [728, 90] - ], - bidId: '3c34e2367a3f59', - bidderRequestId: '18065867f8ae39', - auctionId: '529e1518-b872-45cf-807c-2d41dfa5bcd3' - }]; - - const bidsResponse = { - body: { - bids: [ - { - placementid: '170577', - uuid: '2faedf1095f815', - width: 300, - height: 250, - cpm: 0.51, - creative: '', - ttl: 360, - currency: 'USD', - netRevenue: true, - creativeId: 'd30b58c2ba' - } - ] - } - }; - - it('Verifies komoonaAdapter bidder code', function () { - expect(spec.code).to.equal('komoona'); - }); - - it('Verifies komoonaAdapter bid request validation', function () { - expect(spec.isBidRequestValid(bidsRequest[0])).to.equal(true); - expect(spec.isBidRequestValid(bidsRequest[1])).to.equal(true); - expect(spec.isBidRequestValid({})).to.equal(false); - expect(spec.isBidRequestValid({ params: {} })).to.equal(false); - expect(spec.isBidRequestValid({ params: { hbid: 12345 } })).to.equal(false); - expect(spec.isBidRequestValid({ params: { placementid: 12345 } })).to.equal(false); - expect(spec.isBidRequestValid({ params: { hbid: 12345, placementId: 67890 } })).to.equal(true); - expect(spec.isBidRequestValid({ params: { hbid: 12345, placementId: 67890, floorPrice: 0.8 } })).to.equal(true); - }); - - it('Verify komoonaAdapter build request', function () { - var startTime = new Date().getTime(); - - const request = spec.buildRequests(bidsRequest); - expect(request.url).to.equal('https://bidder.komoona.com/v1/GetSBids'); - expect(request.method).to.equal('POST'); - const requestData = JSON.parse(request.data); - - // bids object - let bids = requestData.bids; - expect(bids).to.have.lengthOf(2); - - // first bid request: no floor price - expect(bids[0].uuid).to.equal('2faedf1095f815'); - expect(bids[0].floorprice).to.be.undefined; - expect(bids[0].placementid).to.equal('170577'); - expect(bids[0].hbid).to.equal('abc12345678'); - expect(bids[0].trid).to.equal('9f801c02-bbe8-4683-8ed4-bc816ea186bb'); - expect(bids[0].sizes).to.have.lengthOf(1); - expect(bids[0].sizes[0][0]).to.equal(300); - expect(bids[0].sizes[0][1]).to.equal(250); - - // second bid request: with floor price - expect(bids[1].uuid).to.equal('3c34e2367a3f59'); - expect(bids[1].floorprice).to.equal(0.5); - expect(bids[1].placementid).to.equal('281277'); - expect(bids[1].hbid).to.equal('abc12345678'); - expect(bids[1].trid).to.equal('9f801c02-bbe8-4683-8ed4-bc816ea186bb'); - expect(bids[1]).to.have.property('sizes') - .that.is.an('array') - .of.length(1) - .that.deep.equals([[728, 90]]); - - // kbConf object - let kbConf = requestData.kbConf; - expect(kbConf.hdbdid).to.equal(bids[0].hbid); - expect(kbConf.hdbdid).to.equal(bids[1].hbid); - expect(kbConf.encode_bid).to.be.undefined; - // kbConf timezone and cb - expect(kbConf.cb).not.to.be.undefined; - expect(kbConf.ts_as).to.be.above(startTime - 1); - expect(kbConf.tz).to.equal(new Date().getTimezoneOffset()); - // kbConf bid ids - expect(kbConf.hb_placement_bidids) - .to.have.property(bids[0].placementid) - .that.equal(bids[0].uuid); - expect(kbConf.hb_placement_bidids) - .to.have.property(bids[1].placementid) - .that.equal(bids[1].uuid); - // kbConf floor price - expect(kbConf.hb_floors).not.to.have.property(bids[0].placementid) - expect(kbConf.hb_floors).to.have.property(bids[1].placementid).that.equal(bids[1].floorprice); - // kbConf placement ids - expect(kbConf.hb_placements).to.have.lengthOf(2); - expect(kbConf.hb_placements[0]).to.equal(bids[0].placementid); - expect(kbConf.hb_placements[1]).to.equal(bids[1].placementid); - }); - - it('Verify komoonaAdapter build response', function () { - const request = spec.buildRequests(bidsRequest); - const bids = spec.interpretResponse(bidsResponse, request); - - // 'server' return single bid - expect(bids).to.have.lengthOf(1); - - // verify bid object - const bid = bids[0]; - const responseBids = bidsResponse.body.bids; - - expect(bid.cpm).to.equal(responseBids[0].cpm); - expect(bid.ad).to.equal(responseBids[0].creative); - expect(bid.requestId).equal(responseBids[0].uuid); - expect(bid.uuid).equal(responseBids[0].uuid); - expect(bid.width).to.equal(responseBids[0].width); - expect(bid.height).to.equal(responseBids[0].height); - expect(bid.ttl).to.equal(responseBids[0].ttl); - expect(bid.currency).to.equal('USD'); - expect(bid.netRevenue).to.equal(true); - expect(bid.creativeId).to.equal(responseBids[0].creativeId); - }); - - it('Verifies komoonaAdapter sync options', function () { - // user sync disabled - expect(spec.getUserSyncs({})).to.be.undefined; - expect(spec.getUserSyncs({ iframeEnabled: false })).to.be.undefined; - // user sync enabled - const options = spec.getUserSyncs({ iframeEnabled: true }); - expect(options).to.not.be.undefined; - expect(options).to.have.lengthOf(1); - expect(options[0].type).to.equal('iframe'); - expect(options[0].url).to.equal('https://s.komoona.com/sync/usync.html'); - }); -}); diff --git a/test/spec/modules/konduitAnalyticsAdapter_spec.js b/test/spec/modules/konduitAnalyticsAdapter_spec.js deleted file mode 100644 index ac557d27f90..00000000000 --- a/test/spec/modules/konduitAnalyticsAdapter_spec.js +++ /dev/null @@ -1,126 +0,0 @@ -import konduitAnalyticsAdapter from 'modules/konduitAnalyticsAdapter'; -import { expect } from 'chai'; -import { config } from '../../../src/config.js'; -import { server } from 'test/mocks/xhr.js'; -let events = require('src/events'); -let adapterManager = require('src/adapterManager').default; -let CONSTANTS = require('src/constants.json'); - -const eventsData = { - [CONSTANTS.EVENTS.AUCTION_INIT]: { - 'auctionId': 'test_auction_id', - 'timestamp': Date.now(), - 'auctionStatus': 'inProgress', - 'adUnitCodes': ['video-test'], - 'timeout': 700 - }, - [CONSTANTS.EVENTS.BID_REQUESTED]: { - 'bidderCode': 'test_bidder_code', - 'time': Date.now(), - 'bids': [{ - 'transactionId': 'test_transaction_id', - 'adUnitCode': 'video-test', - 'bidId': 'test_bid_id', - 'sizes': '640x480', - 'params': { 'testParam': 'test_param' } - }] - }, - [CONSTANTS.EVENTS.NO_BID]: { - 'bidderCode': 'test_bidder_code2', - 'transactionId': 'test_transaction_id', - 'adUnitCode': 'video-test', - 'bidId': 'test_bid_id' - }, - [CONSTANTS.EVENTS.BID_RESPONSE]: { - 'bidderCode': 'test_bidder_code', - 'adUnitCode': 'video-test', - 'statusMessage': 'Bid available', - 'mediaType': 'video', - 'renderedSize': '640x480', - 'cpm': 0.5, - 'currency': 'USD', - 'netRevenue': true, - 'timeToRespond': 124, - 'requestId': 'test_request_id', - 'creativeId': 144876543 - }, - [CONSTANTS.EVENTS.AUCTION_END]: { - 'auctionId': 'test_auction_id', - 'timestamp': Date.now(), - 'auctionEnd': Date.now() + 400, - 'auctionStatus': 'completed', - 'adUnitCodes': ['video-test'], - 'timeout': 700 - }, - [CONSTANTS.EVENTS.BID_WON]: { - 'bidderCode': 'test_bidder_code', - 'adUnitCode': 'video-test', - 'statusMessage': 'Bid available', - 'mediaType': 'video', - 'renderedSize': '640x480', - 'cpm': 0.5, - 'currency': 'USD', - 'netRevenue': true, - 'timeToRespond': 124, - 'requestId': 'test_request_id', - 'creativeId': 144876543 - }, -}; - -describe(`Konduit Analytics Adapter`, () => { - const konduitId = 'test'; - - beforeEach(function () { - sinon.spy(konduitAnalyticsAdapter, 'track'); - sinon.stub(events, 'getEvents').returns([]); - config.setConfig({ konduit: { konduitId } }); - }); - - afterEach(function () { - events.getEvents.restore(); - konduitAnalyticsAdapter.track.restore(); - konduitAnalyticsAdapter.disableAnalytics(); - }); - - it(`should add all events to an aggregatedEvents queue - inside konduitAnalyticsAdapter.context and send a request with correct data`, function () { - server.respondWith(JSON.stringify({ key: 'test' })); - - adapterManager.registerAnalyticsAdapter({ - code: 'konduit', - adapter: konduitAnalyticsAdapter - }); - - adapterManager.enableAnalytics({ - provider: 'konduit', - }); - - expect(konduitAnalyticsAdapter.context).to.be.an('object'); - expect(konduitAnalyticsAdapter.context.aggregatedEvents).to.be.an('array'); - - const eventTypes = [ - CONSTANTS.EVENTS.AUCTION_INIT, - CONSTANTS.EVENTS.BID_REQUESTED, - CONSTANTS.EVENTS.NO_BID, - CONSTANTS.EVENTS.BID_RESPONSE, - CONSTANTS.EVENTS.BID_WON, - CONSTANTS.EVENTS.AUCTION_END, - ]; - const args = eventTypes.map(eventType => eventsData[eventType]); - - eventTypes.forEach((eventType, i) => { - events.emit(eventType, args[i]); - }); - - server.respond(); - - expect(konduitAnalyticsAdapter.context.aggregatedEvents.length).to.be.equal(6); - expect(server.requests[0].url).to.match(/http(s):\/\/\w*\.konduit\.me\/analytics-initial-event/); - - const requestBody = JSON.parse(server.requests[0].requestBody); - expect(requestBody.konduitId).to.be.equal(konduitId); - expect(requestBody.prebidVersion).to.be.equal('$prebid.version$'); - expect(requestBody.environment).to.be.an('object'); - sinon.assert.callCount(konduitAnalyticsAdapter.track, 6); - }); -}); diff --git a/test/spec/modules/konduitWrapper_spec.js b/test/spec/modules/konduitWrapper_spec.js deleted file mode 100644 index c88287c7066..00000000000 --- a/test/spec/modules/konduitWrapper_spec.js +++ /dev/null @@ -1,292 +0,0 @@ -import { expect } from 'chai'; - -import { processBids, errorMessages } from 'modules/konduitWrapper.js'; -import { config } from 'src/config.js'; -import { server } from 'test/mocks/xhr.js'; - -describe('The Konduit vast wrapper module', function () { - const konduitId = 'test'; - beforeEach(function() { - config.setConfig({ konduit: { konduitId } }); - }); - - describe('processBids function (send one bid)', () => { - beforeEach(function() { - config.setConfig({ enableSendAllBids: false }); - }); - - it(`should make a correct processBids request and add kCpm and konduitCacheKey - to the passed bids and to the adserverTargeting object`, function () { - const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); - - server.respondWith(JSON.stringify({ - kCpmData: { [`${bid.bidderCode}:${bid.creativeId}`]: bid.cpm }, - cacheData: { [`${bid.bidderCode}:${bid.creativeId}`]: 'test_cache_key' }, - })); - - processBids({ bid }); - server.respond(); - - expect(server.requests.length).to.equal(1); - - const requestBody = JSON.parse(server.requests[0].requestBody); - - expect(requestBody.clientId).to.equal(konduitId); - - expect(bid.konduitCacheKey).to.equal('test_cache_key'); - expect(bid.kCpm).to.equal(bid.cpm); - - expect(bid.adserverTargeting).to.be.an('object'); - - expect(bid.adserverTargeting.k_cpm).to.equal(bid.pbCg || bid.pbAg); - expect(bid.adserverTargeting.k_cache_key).to.equal('test_cache_key'); - expect(bid.adserverTargeting.konduit_id).to.equal(konduitId); - }); - - it(`should call callback with error object in arguments if cacheData is empty in the response`, function () { - const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); - - server.respondWith(JSON.stringify({ - kCpmData: { [`${bid.bidderCode}:${bid.creativeId}`]: bid.cpm }, - cacheData: {}, - })); - const callback = sinon.spy(); - processBids({ bid, callback }); - server.respond(); - - expect(server.requests.length).to.equal(1); - - const requestBody = JSON.parse(server.requests[0].requestBody); - - expect(requestBody.clientId).to.equal(konduitId); - - expect(bid.konduitCacheKey).to.be.undefined; - expect(bid.kCpm).to.equal(bid.cpm); - - expect(bid.adserverTargeting.k_cpm).to.equal(bid.pbCg || bid.pbAg); - expect(bid.adserverTargeting.k_cache_key).to.be.undefined; - expect(bid.adserverTargeting.konduit_id).to.be.undefined; - - expect(callback.firstCall.args[0]).to.be.an('error'); - }); - - it('should call callback if processBids request is sent successfully', function () { - const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); - server.respondWith(JSON.stringify({ key: 'test' })); - const callback = sinon.spy(); - processBids({ - bid, - callback - }); - server.respond(); - - expect(callback.calledOnce).to.be.true; - }); - - it('should call callback with error object in arguments if processBids request is failed', function () { - const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); - const callback = sinon.spy(); - processBids({ - bid, - callback - }); - server.respond(); - - expect(callback.calledOnce).to.be.true; - expect(callback.firstCall.args[0]).to.be.an('error'); - }); - - it('should call callback with error object in arguments if no konduitId in configs', function () { - config.setConfig({ konduit: { konduitId: null } }); - - const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); - const callback = sinon.spy(); - processBids({ - bid, - callback - }); - - expect(callback.calledOnce).to.be.true; - expect(callback.firstCall.args[0]).to.be.an('error'); - expect(callback.firstCall.args[0].message).to.equal(errorMessages.NO_KONDUIT_ID); - }); - - it('should call callback with error object in arguments if no bids found', function () { - const callback = sinon.spy(); - processBids({ - bid: null, - bids: [], - callback - }); - - expect(callback.calledOnce).to.be.true; - expect(callback.firstCall.args[0]).to.be.an('error'); - expect(callback.firstCall.args[0].message).to.equal(errorMessages.NO_BIDS); - }); - }); - describe('processBids function (send all bids)', () => { - beforeEach(function() { - config.setConfig({ enableSendAllBids: true }); - }); - - it(`should make a correct processBids request and add kCpm and konduitCacheKey - to the passed bids and to the adserverTargeting object`, function () { - const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); - - server.respondWith(JSON.stringify({ - kCpmData: { [`${bid.bidderCode}:${bid.creativeId}`]: bid.cpm }, - cacheData: { [`${bid.bidderCode}:${bid.creativeId}`]: 'test_cache_key' }, - })); - - processBids({ adUnitCode: 'video1', bids: [bid] }); - server.respond(); - - expect(server.requests.length).to.equal(1); - - const requestBody = JSON.parse(server.requests[0].requestBody); - - expect(requestBody.clientId).to.equal(konduitId); - - expect(bid.konduitCacheKey).to.equal('test_cache_key'); - expect(bid.kCpm).to.equal(bid.cpm); - - expect(bid.adserverTargeting).to.be.an('object'); - - expect(bid.adserverTargeting.k_cpm).to.equal(bid.pbCg || bid.pbAg); - expect(bid.adserverTargeting[`k_cpm_${bid.bidderCode}`]).to.equal(bid.pbCg || bid.pbAg); - expect(bid.adserverTargeting.k_cache_key).to.equal('test_cache_key'); - expect(bid.adserverTargeting[`k_cache_key_${bid.bidderCode}`]).to.equal('test_cache_key'); - expect(bid.adserverTargeting.konduit_id).to.equal(konduitId); - }); - - it(`should call callback with error object in arguments if cacheData is empty in the response`, function () { - const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); - - server.respondWith(JSON.stringify({ - kCpmData: { [`${bid.bidderCode}:${bid.creativeId}`]: bid.cpm }, - cacheData: {}, - })); - const callback = sinon.spy(); - processBids({ adUnitCode: 'video1', bids: [bid], callback }); - server.respond(); - - expect(server.requests.length).to.equal(1); - - const requestBody = JSON.parse(server.requests[0].requestBody); - - expect(requestBody.clientId).to.equal(konduitId); - - expect(bid.konduitCacheKey).to.be.undefined; - expect(bid.kCpm).to.equal(bid.cpm); - - expect(bid.adserverTargeting.k_cpm).to.equal(bid.pbCg || bid.pbAg); - expect(bid.adserverTargeting[`k_cpm_${bid.bidderCode}`]).to.equal(bid.pbCg || bid.pbAg); - expect(bid.adserverTargeting.k_cache_key).to.be.undefined; - expect(bid.adserverTargeting[`k_cache_key_${bid.bidderCode}`]).to.be.undefined; - expect(bid.adserverTargeting.konduit_id).to.be.undefined; - - expect(callback.firstCall.args[0]).to.be.an('error'); - }); - - it('should call callback if processBids request is sent successfully', function () { - const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); - server.respondWith(JSON.stringify({ key: 'test' })); - const callback = sinon.spy(); - processBids({ adUnitCode: 'video1', bid: [bid], callback }); - server.respond(); - - expect(callback.calledOnce).to.be.true; - }); - - it('should call callback with error object in arguments if processBids request is failed', function () { - const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); - const callback = sinon.spy(); - processBids({ adUnitCode: 'video1', bid: [bid], callback }); - server.respond(); - - expect(callback.calledOnce).to.be.true; - expect(callback.firstCall.args[0]).to.be.an('error'); - }); - - it('should call callback with error object in arguments if no konduitId in configs', function () { - config.setConfig({ konduit: { konduitId: null } }); - - const bid = createBid(10, 'video1', 15, '10.00_15s', '123', '395'); - const callback = sinon.spy(); - processBids({ adUnitCode: 'video1', bid: [bid], callback }); - - expect(callback.calledOnce).to.be.true; - expect(callback.firstCall.args[0]).to.be.an('error'); - expect(callback.firstCall.args[0].message).to.equal(errorMessages.NO_KONDUIT_ID); - }); - - it('should call callback with error object in arguments if no bids found', function () { - const callback = sinon.spy(); - processBids({ - bid: null, - bids: [], - callback - }); - - expect(callback.calledOnce).to.be.true; - expect(callback.firstCall.args[0]).to.be.an('error'); - expect(callback.firstCall.args[0].message).to.equal(errorMessages.NO_BIDS); - }); - }); -}); - -function createBid(cpm, adUnitCode, durationBucket, priceIndustryDuration, uuid, label) { - return { - 'bidderCode': 'appnexus', - 'width': 640, - 'height': 360, - 'statusMessage': 'Bid available', - 'adId': '28f24ced14586c', - 'mediaType': 'video', - 'source': 'client', - 'requestId': '28f24ced14586c', - 'cpm': cpm, - 'creativeId': 97517771, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 3600, - 'adUnitCode': adUnitCode, - 'video': { - 'context': 'adpod', - 'durationBucket': durationBucket - }, - 'appnexus': { - 'buyerMemberId': 9325 - }, - 'vastUrl': 'http://some-vast-url.com', - 'vastImpUrl': 'http://some-vast-imp-url.com', - 'auctionId': 'ec266b31-d652-49c5-8295-e83fafe5532b', - 'responseTimestamp': 1548442460888, - 'requestTimestamp': 1548442460827, - 'bidder': 'appnexus', - 'timeToRespond': 61, - 'pbLg': '5.00', - 'pbMg': `${cpm}.00`, - 'pbHg': '5.00', - 'pbAg': `${cpm}.00`, - 'pbDg': '5.00', - 'pbCg': '', - 'size': '640x360', - 'adserverTargeting': { - 'hb_bidder': 'appnexus', - 'hb_adid': '28f24ced14586c', - 'hb_pb': '5.00', - 'hb_size': '640x360', - 'hb_source': 'client', - 'hb_format': 'video', - 'hb_pb_cat_dur': priceIndustryDuration, - 'hb_cache_id': uuid - }, - 'customCacheKey': `${priceIndustryDuration}_${uuid}`, - 'meta': { - 'primaryCatId': 'iab-1', - 'adServerCatId': label - }, - 'videoCacheKey': '4cf395af-8fee-4960-af0e-88d44e399f14' - } -} diff --git a/test/spec/modules/krushmediaBidAdapter_spec.js b/test/spec/modules/krushmediaBidAdapter_spec.js deleted file mode 100644 index 3af9ed64c43..00000000000 --- a/test/spec/modules/krushmediaBidAdapter_spec.js +++ /dev/null @@ -1,329 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/krushmediaBidAdapter.js'; -import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; - -describe('KrushmediabBidAdapter', function () { - const bid = { - bidId: '23fhj33i987f', - bidder: 'krushmedia', - mediaTypes: { - [BANNER]: { - sizes: [[300, 250]] - } - }, - params: { - key: 783, - traffic: BANNER - } - }; - - const bidderRequest = { - refererInfo: { - referer: 'test.com' - } - }; - - describe('isBidRequestValid', function () { - it('Should return true if there are bidId, params and key parameters present', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false if at least one of parameters is not present', function () { - delete bid.params.key; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid], 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://ads4.krushmedia.com/?c=rtb&m=hb'); - }); - it('Returns valid data if array of bids is valid', function () { - let data = serverRequest.data; - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); - 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.gdpr).to.not.exist; - expect(data.ccpa).to.not.exist; - let placement = data['placements'][0]; - expect(placement).to.have.keys('key', 'bidId', 'traffic', 'sizes', 'schain'); - expect(placement.key).to.equal(783); - expect(placement.bidId).to.equal('23fhj33i987f'); - expect(placement.traffic).to.equal(BANNER); - expect(placement.schain).to.be.an('object'); - expect(placement.sizes).to.be.an('array'); - }); - - it('Returns valid data for mediatype video', function () { - const playerSize = [300, 300]; - bid.mediaTypes = {}; - bid.params.traffic = VIDEO; - bid.mediaTypes[VIDEO] = { - playerSize - }; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data).to.be.an('object'); - let placement = data['placements'][0]; - expect(placement).to.be.an('object'); - expect(placement).to.have.keys('key', 'bidId', 'traffic', 'wPlayer', 'hPlayer', 'schain'); - expect(placement.traffic).to.equal(VIDEO); - expect(placement.wPlayer).to.equal(playerSize[0]); - expect(placement.hPlayer).to.equal(playerSize[1]); - }); - - it('Returns valid data for mediatype native', function () { - const native = { - title: { - required: true - }, - body: { - required: true - }, - icon: { - required: true, - size: [64, 64] - } - }; - - bid.mediaTypes = {}; - bid.params.traffic = NATIVE; - bid.mediaTypes[NATIVE] = native; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data).to.be.an('object'); - let placement = data['placements'][0]; - expect(placement).to.be.an('object'); - expect(placement).to.have.keys('key', 'bidId', 'traffic', 'native', 'schain'); - expect(placement.traffic).to.equal(NATIVE); - expect(placement.native).to.equal(native); - }); - - it('Returns data with gdprConsent and without uspConsent', function () { - bidderRequest.gdprConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data.gdpr).to.exist; - expect(data.gdpr).to.be.a('string'); - expect(data.gdpr).to.equal(bidderRequest.gdprConsent); - expect(data.ccpa).to.not.exist; - delete bidderRequest.gdprConsent; - }); - - it('Returns data with uspConsent and without gdprConsent', function () { - bidderRequest.uspConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); - let 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; - }); - - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); - }); - 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' - }] - }; - let bannerResponses = spec.interpretResponse(banner); - expect(bannerResponses).to.be.an('array').that.is.not.empty; - let dataItem = bannerResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - expect(dataItem.requestId).to.equal('23fhj33i987f'); - expect(dataItem.cpm).to.equal(0.4); - expect(dataItem.width).to.equal(300); - expect(dataItem.height).to.equal(250); - expect(dataItem.ad).to.equal('Test'); - expect(dataItem.ttl).to.equal(120); - expect(dataItem.creativeId).to.equal('2'); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal('USD'); - }); - 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' - }] - }; - let videoResponses = spec.interpretResponse(video); - expect(videoResponses).to.be.an('array').that.is.not.empty; - - let dataItem = videoResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - 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'); - }); - 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', - }] - }; - let nativeResponses = spec.interpretResponse(native); - expect(nativeResponses).to.be.an('array').that.is.not.empty; - - let dataItem = nativeResponses[0]; - expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); - 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'); - }); - 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' - }] - }; - - let 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' - }] - }; - let 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', - }] - }; - let 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' - }] - }; - let 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, - }, {}); - 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('iframe') - expect(syncData[0].url).to.be.a('string') - expect(syncData[0].url).to.equal('https://cs.krushmedia.com/html?src=pbjs&gdpr=1&gdpr_consent=ALL') - }); - it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1NNN' - }); - 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('iframe') - expect(syncData[0].url).to.be.a('string') - expect(syncData[0].url).to.equal('https://cs.krushmedia.com/html?src=pbjs&ccpa_consent=1NNN') - }); - }); -}); diff --git a/test/spec/modules/kubientBidAdapter_spec.js b/test/spec/modules/kubientBidAdapter_spec.js deleted file mode 100644 index 1df4370b2ba..00000000000 --- a/test/spec/modules/kubientBidAdapter_spec.js +++ /dev/null @@ -1,259 +0,0 @@ -import { expect, assert } from 'chai'; -import { spec } from 'modules/kubientBidAdapter.js'; - -describe('KubientAdapter', function () { - let bid = { - bidId: '2dd581a2b6281d', - bidder: 'kubient', - bidderRequestId: '145e1d6a7837c9', - params: { - zoneid: '5678', - floor: 0.05, - }, - auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e62', - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '0', - hp: 1, - rid: 'bidrequestid', - domain: 'example.com' - } - ] - } - }; - let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - let uspConsentData = '1YCC'; - let bidderRequest = { - bidderCode: 'kubient', - auctionId: 'fffffff-ffff-ffff-ffff-ffffffffffff', - bidderRequestId: 'ffffffffffffff', - start: 1472239426002, - auctionStart: 1472239426000, - timeout: 5000, - refererInfo: { - referer: 'http://www.example.com', - reachedTop: true, - }, - gdprConsent: { - consentString: consentString, - gdprApplies: true - }, - uspConsent: uspConsentData, - bids: [bid] - }; - describe('buildRequests', function () { - let serverRequests = spec.buildRequests([bid], bidderRequest); - it('Creates a ServerRequest object with method, URL and data', function () { - expect(serverRequests).to.be.an('array'); - }); - for (let i = 0; i < serverRequests.length; i++) { - let serverRequest = serverRequests[i]; - it('Creates a ServerRequest object with method, URL and data', function () { - expect(serverRequest.method).to.be.a('string'); - expect(serverRequest.url).to.be.a('string'); - expect(serverRequest.data).to.be.a('string'); - }); - it('Returns POST method', function () { - expect(serverRequest.method).to.equal('POST'); - }); - it('Returns valid URL', function () { - expect(serverRequest.url).to.equal('https://kssp.kbntx.ch/pbjs'); - }); - it('Returns valid data if array of bids is valid', function () { - let data = JSON.parse(serverRequest.data); - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('v', 'requestId', 'adSlots', 'gdpr', 'referer', 'tmax', 'consent', 'consentGiven', 'uspConsent'); - expect(data.v).to.exist.and.to.be.a('string'); - expect(data.requestId).to.exist.and.to.be.a('string'); - expect(data.referer).to.be.a('string'); - expect(data.tmax).to.exist.and.to.be.a('number'); - expect(data.gdpr).to.exist.and.to.be.within(0, 1); - expect(data.consent).to.equal(consentString); - expect(data.uspConsent).to.exist.and.to.equal(uspConsentData); - for (let j = 0; j < data['adSlots'].length; j++) { - let adSlot = data['adSlots'][i]; - expect(adSlot).to.have.all.keys('bidId', 'zoneId', 'floor', 'sizes', 'schain', 'mediaTypes'); - expect(adSlot.bidId).to.be.a('string'); - expect(adSlot.zoneId).to.be.a('string'); - expect(adSlot.floor).to.be.a('number'); - expect(adSlot.sizes).to.be.an('array'); - expect(adSlot.schain).to.be.an('object'); - expect(adSlot.mediaTypes).to.be.an('object'); - } - }); - } - }); - - describe('isBidRequestValid', function () { - it('Should return true when required params are found', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false when required params are not found', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false when params are not found', function () { - delete bid.params; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('interpretResponse', function () { - it('Should interpret response', function () { - const serverResponse = { - body: - { - seatbid: [ - { - bid: [ - { - bidId: '000', - price: 1.5, - adm: '
test
', - creativeId: 'creativeId', - w: 300, - h: 250, - cur: 'USD', - netRevenue: false, - ttl: 360 - } - ] - } - ] - } - }; - let bannerResponses = spec.interpretResponse(serverResponse); - expect(bannerResponses).to.be.an('array').that.is.not.empty; - let dataItem = bannerResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'ad', 'creativeId', 'width', 'height', 'currency', 'netRevenue', 'ttl'); - expect(dataItem.requestId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].bidId); - expect(dataItem.cpm).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].price); - expect(dataItem.ad).to.exist.and.to.be.a('string').and.to.have.string(serverResponse.body.seatbid[0].bid[0].adm); - expect(dataItem.creativeId).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].creativeId); - expect(dataItem.width).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].w); - expect(dataItem.height).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].h); - expect(dataItem.currency).to.exist.and.to.be.a('string').and.to.equal(serverResponse.body.seatbid[0].bid[0].cur); - expect(dataItem.netRevenue).to.exist.and.to.be.a('boolean').and.to.equal(serverResponse.body.seatbid[0].bid[0].netRevenue); - expect(dataItem.ttl).to.exist.and.to.be.a('number').and.to.equal(serverResponse.body.seatbid[0].bid[0].ttl); - }); - - it('Should return no ad when not given a server response', function () { - const ads = spec.interpretResponse(null); - expect(ads).to.be.an('array').and.to.have.length(0); - }); - }); - - describe('getUserSyncs', function () { - it('should register the sync iframe without gdpr', function () { - let syncOptions = { - iframeEnabled: true - }; - let serverResponses = null; - let gdprConsent = { - consentString: consentString - }; - let uspConsent = null; - let syncs = spec.getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent); - expect(syncs).to.be.an('array').and.to.have.length(1); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.equal('https://kdmp.kbntx.ch/init.html?consent_str=' + consentString + '&consent_given=0'); - }); - it('should register the sync iframe with gdpr', function () { - let syncOptions = { - iframeEnabled: true - }; - let serverResponses = null; - let gdprConsent = { - gdprApplies: true, - consentString: consentString - }; - let uspConsent = null; - let syncs = spec.getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent); - expect(syncs).to.be.an('array').and.to.have.length(1); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.equal('https://kdmp.kbntx.ch/init.html?consent_str=' + consentString + '&gdpr=1&consent_given=0'); - }); - it('should register the sync iframe with gdpr vendor', function () { - let syncOptions = { - iframeEnabled: true - }; - let serverResponses = null; - let gdprConsent = { - gdprApplies: true, - consentString: consentString, - apiVersion: 1, - vendorData: { - vendorConsents: { - 794: 1 - } - } - }; - let uspConsent = null; - let syncs = spec.getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent); - expect(syncs).to.be.an('array').and.to.have.length(1); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.equal('https://kdmp.kbntx.ch/init.html?consent_str=' + consentString + '&gdpr=1&consent_given=1'); - }); - it('should register the sync image without gdpr', function () { - let syncOptions = { - pixelEnabled: true - }; - let serverResponses = null; - let gdprConsent = { - consentString: consentString - }; - let uspConsent = null; - let syncs = spec.getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent); - expect(syncs).to.be.an('array').and.to.have.length(1); - expect(syncs[0].type).to.equal('image'); - expect(syncs[0].url).to.equal('https://kdmp.kbntx.ch/init.png?consent_str=' + consentString + '&consent_given=0'); - }); - it('should register the sync image with gdpr', function () { - let syncOptions = { - pixelEnabled: true - }; - let serverResponses = null; - let gdprConsent = { - gdprApplies: true, - consentString: consentString - }; - let uspConsent = null; - let syncs = spec.getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent); - expect(syncs).to.be.an('array').and.to.have.length(1); - expect(syncs[0].type).to.equal('image'); - expect(syncs[0].url).to.equal('https://kdmp.kbntx.ch/init.png?consent_str=' + consentString + '&gdpr=1&consent_given=0'); - }); - it('should register the sync image with gdpr vendor', function () { - let syncOptions = { - pixelEnabled: true - }; - let serverResponses = null; - let gdprConsent = { - gdprApplies: true, - consentString: consentString, - apiVersion: 2, - vendorData: { - vendor: { - consents: { - 794: 1 - } - } - } - }; - let uspConsent = null; - let syncs = spec.getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent); - expect(syncs).to.be.an('array').and.to.have.length(1); - expect(syncs[0].type).to.equal('image'); - expect(syncs[0].url).to.equal('https://kdmp.kbntx.ch/init.png?consent_str=' + consentString + '&gdpr=1&consent_given=1'); - }); - }) -}); diff --git a/test/spec/modules/lemmaBidAdapter_spec.js b/test/spec/modules/lemmaBidAdapter_spec.js deleted file mode 100644 index a3a70a39731..00000000000 --- a/test/spec/modules/lemmaBidAdapter_spec.js +++ /dev/null @@ -1,426 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/lemmaBidAdapter.js'; -import * as utils from 'src/utils.js'; -const constants = require('src/constants.json'); - -describe('lemmaBidAdapter', function() { - var bidRequests; - var videoBidRequests; - var bidResponses; - beforeEach(function() { - bidRequests = [{ - bidder: 'lemma', - mediaType: 'banner', - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [300, 600] - ], - } - }, - params: { - pubId: 1001, - adunitId: 1, - currency: 'AUD', - bidFloor: 1.3, - geo: { - lat: '12.3', - lon: '23.7', - } - }, - sizes: [ - [300, 250], - [300, 600] - ] - }]; - videoBidRequests = [{ - code: 'video1', - mediaType: 'video', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'instream' - } - }, - bidder: 'lemma', - params: { - pubId: 1001, - adunitId: 1, - bidFloor: 1.3, - video: { - mimes: ['video/mp4', 'video/x-flv'], - skippable: true, - minduration: 5, - maxduration: 30 - } - } - }]; - bidResponses = { - 'body': { - 'id': '93D3BAD6-E2E2-49FB-9D89-920B1761C865', - 'seatbid': [{ - 'bid': [{ - 'id': '74858439-49D7-4169-BA5D-44A046315B2F', - 'impid': '22bddb28db77d', - 'price': 1.3, - 'adm': '

lemma"Connecting Advertisers and Publishers directly"

', - 'adomain': ['amazon.com'], - 'iurl': 'https://thetradedesk-t-general.s3.amazonaws.com/AdvertiserLogos/vgl908z.png', - 'cid': '22918', - 'crid': 'v55jutrh', - 'h': 250, - 'w': 300, - 'ext': {} - }] - }] - } - }; - }); - describe('implementation', function() { - describe('Bid validations', function() { - it('valid bid case', function() { - var validBid = { - bidder: 'lemma', - params: { - pubId: 1001, - adunitId: 1 - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(true); - }); - it('invalid bid case', function() { - var isValid = spec.isBidRequestValid(); - expect(isValid).to.equal(false); - }); - it('invalid bid case: pubId not passed', function() { - var validBid = { - bidder: 'lemma', - params: { - adunitId: 1 - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(false); - }); - it('invalid bid case: pubId is not number', function() { - var validBid = { - bidder: 'lemma', - params: { - pubId: '301', - adunitId: 1 - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(false); - }); - it('invalid bid case: adunitId is not passed', function() { - var validBid = { - bidder: 'lemma', - params: { - pubId: 1001 - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(false); - }); - it('invalid bid case: video bid request mimes is not passed', function() { - var validBid = { - bidder: 'lemma', - params: { - pubId: 1001, - adunitId: 1, - video: { - skippable: true, - minduration: 5, - maxduration: 30 - } - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(false); - validBid.params.video.mimes = []; - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(false); - }); - }); - describe('Request formation', function() { - it('buildRequests function should not modify original bidRequests object', function() { - var originalBidRequests = utils.deepClone(bidRequests); - var request = spec.buildRequests(bidRequests); - expect(bidRequests).to.deep.equal(originalBidRequests); - }); - it('Endpoint checking', function() { - var request = spec.buildRequests(bidRequests); - expect(request.url).to.equal('https://ads.lemmatechnologies.com/lemma/servad?pid=1001&aid=1'); - expect(request.method).to.equal('POST'); - }); - it('Request params check', function() { - var request = spec.buildRequests(bidRequests); - var data = JSON.parse(request.data); - expect(data.site.domain).to.be.a('string'); // domain should be set - expect(data.site.publisher.id).to.equal(bidRequests[0].params.pubId.toString()); // publisher Id - expect(data.imp[0].tagid).to.equal('1'); // tagid - expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency); - expect(data.imp[0].bidfloor).to.equal(bidRequests[0].params.bidFloor); - }); - it('Request params check without mediaTypes object', function() { - var bidRequests = [{ - bidder: 'lemma', - params: { - pubId: 1001, - adunitId: 1, - currency: 'AUD' - }, - sizes: [ - [300, 250], - [300, 600] - ] - }]; - var request = spec.buildRequests(bidRequests); - var data = JSON.parse(request.data); - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(250); // height - expect(data.imp[0].banner.format).exist.and.to.be.an('array'); - expect(data.imp[0].banner.format[0]).exist.and.to.be.an('object'); - expect(data.imp[0].banner.format[0].w).to.equal(300); // width - expect(data.imp[0].banner.format[0].h).to.equal(600); // height - }); - it('Request params check: without tagId', function() { - delete bidRequests[0].params.adunitId; - var request = spec.buildRequests(bidRequests); - var data = JSON.parse(request.data); - expect(data.site.domain).to.be.a('string'); // domain should be set - expect(data.site.publisher.id).to.equal(bidRequests[0].params.pubId.toString()); // publisher Id - expect(data.imp[0].tagid).to.equal(undefined); // tagid - expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency); - expect(data.imp[0].bidfloor).to.equal(bidRequests[0].params.bidFloor); - }); - it('Request params multi size format object check', function() { - var bidRequests = [{ - bidder: 'lemma', - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [300, 600] - ], - } - }, - params: { - pubId: 1001, - adunitId: 1, - currency: 'AUD' - }, - sizes: [ - [300, 250], - [300, 600] - ] - }]; - /* case 1 - size passed in adslot */ - var request = spec.buildRequests(bidRequests); - var data = JSON.parse(request.data); - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(250); // height - /* case 2 - size passed in adslot as well as in sizes array */ - bidRequests[0].sizes = [ - [300, 600], - [300, 250] - ]; - bidRequests[0].mediaTypes = { - banner: { - sizes: [ - [300, 600], - [300, 250] - ] - } - }; - request = spec.buildRequests(bidRequests); - data = JSON.parse(request.data); - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(600); // height - /* case 3 - size passed in sizes but not in adslot */ - bidRequests[0].params.adunitId = 1; - bidRequests[0].sizes = [ - [300, 250], - [300, 600] - ]; - bidRequests[0].mediaTypes = { - banner: { - sizes: [ - [300, 250], - [300, 600] - ] - } - }; - request = spec.buildRequests(bidRequests); - data = JSON.parse(request.data); - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(250); // height - expect(data.imp[0].banner.format).exist.and.to.be.an('array'); - expect(data.imp[0].banner.format[0]).exist.and.to.be.an('object'); - expect(data.imp[0].banner.format[0].w).to.equal(300); // width - expect(data.imp[0].banner.format[0].h).to.equal(250); // height - }); - it('Request params currency check', function() { - var bidRequest = [{ - bidder: 'lemma', - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [300, 600] - ], - } - }, - params: { - pubId: 1001, - adunitId: 1, - currency: 'AUD' - }, - sizes: [ - [300, 250], - [300, 600] - ] - }]; - /* case 1 - - currency specified in adunits - output: imp[0] use currency specified in bidRequests[0].params.currency - */ - var request = spec.buildRequests(bidRequest); - var data = JSON.parse(request.data); - expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency); - /* case 2 - - currency specified in adunit - output: imp[0] use default currency - USD - */ - delete bidRequest[0].params.currency; - request = spec.buildRequests(bidRequest); - data = JSON.parse(request.data); - expect(data.imp[0].bidfloorcur).to.equal('USD'); - }); - it('Request params check for video ad', function() { - var request = spec.buildRequests(videoBidRequests); - var data = JSON.parse(request.data); - expect(data.imp[0].video).to.exist; - expect(data.imp[0].tagid).to.equal('1'); - expect(data.imp[0]['video']['mimes']).to.exist.and.to.be.an('array'); - expect(data.imp[0]['video']['mimes'][0]).to.equal(videoBidRequests[0].params.video['mimes'][0]); - expect(data.imp[0]['video']['mimes'][1]).to.equal(videoBidRequests[0].params.video['mimes'][1]); - expect(data.imp[0]['video']['minduration']).to.equal(videoBidRequests[0].params.video['minduration']); - expect(data.imp[0]['video']['maxduration']).to.equal(videoBidRequests[0].params.video['maxduration']); - expect(data.imp[0]['video']['w']).to.equal(videoBidRequests[0].mediaTypes.video.playerSize[0]); - expect(data.imp[0]['video']['h']).to.equal(videoBidRequests[0].mediaTypes.video.playerSize[1]); - }); - describe('setting imp.floor using floorModule', function() { - /* - Use the minimum value among floor from floorModule per mediaType - If params.bidFloor is set then take max(floor, min(floors from floorModule)) - set imp.bidfloor only if it is more than 0 - */ - - let newRequest; - let floorModuleTestData; - let getFloor = function(req) { - return floorModuleTestData[req.mediaType]; - }; - - beforeEach(() => { - floorModuleTestData = { - 'banner': { - 'currency': 'AUD', - 'floor': 1.50 - }, - 'video': { - 'currency': 'AUD', - 'floor': 2.00 - } - }; - newRequest = utils.deepClone(bidRequests); - newRequest[0].getFloor = getFloor; - }); - - it('bidfloor should be undefined if calculation is <= 0', function() { - floorModuleTestData.banner.floor = 0; // lowest of them all - newRequest[0].params.bidFloor = undefined; - let request = spec.buildRequests(newRequest); - let data = JSON.parse(request.data); - data = data.imp[0]; - expect(data.bidfloor).to.equal(undefined); - }); - - it('ignore floormodule o/p if floor is not number', function() { - floorModuleTestData.banner.floor = 'INR'; - newRequest[0].params.bidFloor = undefined; - let request = spec.buildRequests(newRequest); - let data = JSON.parse(request.data); - data = data.imp[0]; - expect(data.bidfloor).to.equal(undefined); // video will be lowest now - }); - - it('ignore floormodule o/p if currency is not matched', function() { - floorModuleTestData.banner.currency = 'INR'; - newRequest[0].params.bidFloor = undefined; - let request = spec.buildRequests(newRequest); - let data = JSON.parse(request.data); - data = data.imp[0]; - expect(data.bidfloor).to.equal(undefined); // video will be lowest now - }); - - it('bidFloor is not passed, use minimum from floorModule', function() { - newRequest[0].params.bidFloor = undefined; - let request = spec.buildRequests(newRequest); - let data = JSON.parse(request.data); - data = data.imp[0]; - expect(data.bidfloor).to.equal(1.5); - }); - - it('bidFloor is passed as 1, use min of floorModule as it is highest', function() { - newRequest[0].params.bidFloor = '1.0';// yes, we want it as a string - let request = spec.buildRequests(newRequest); - let data = JSON.parse(request.data); - data = data.imp[0]; - expect(data.bidfloor).to.equal(1.5); - }); - }); - describe('Response checking', function() { - it('should check for valid response values', function() { - var request = spec.buildRequests(bidRequests); - var data = JSON.parse(request.data); - var response = spec.interpretResponse(bidResponses, request); - expect(response).to.be.an('array').with.length.above(0); - expect(response[0].requestId).to.equal(bidResponses.body.seatbid[0].bid[0].impid); - expect(response[0].cpm).to.equal((bidResponses.body.seatbid[0].bid[0].price).toFixed(2)); - expect(response[0].width).to.equal(bidResponses.body.seatbid[0].bid[0].w); - expect(response[0].height).to.equal(bidResponses.body.seatbid[0].bid[0].h); - if (bidResponses.body.seatbid[0].bid[0].crid) { - expect(response[0].creativeId).to.equal(bidResponses.body.seatbid[0].bid[0].crid); - } else { - expect(response[0].creativeId).to.equal(bidResponses.body.seatbid[0].bid[0].id); - } - expect(response[0].dealId).to.equal(bidResponses.body.seatbid[0].bid[0].dealid); - expect(response[0].currency).to.equal('USD'); - expect(response[0].netRevenue).to.equal(false); - expect(response[0].ttl).to.equal(300); - }); - }); - }); - describe('getUserSyncs', function() { - const syncurl_iframe = 'https://sync.lemmatechnologies.com/js/usersync.html?pid=1001'; - let sandbox; - beforeEach(function() { - sandbox = sinon.sandbox.create(); - }); - afterEach(function() { - sandbox.restore(); - }); - - it('execute as per config', function() { - expect(spec.getUserSyncs({ iframeEnabled: true }, {}, undefined, undefined)).to.deep.equal([{ - type: 'iframe', url: syncurl_iframe - }]); - }); - }); - }); -}); diff --git a/test/spec/modules/lifestreetBidAdapter_spec.js b/test/spec/modules/lifestreetBidAdapter_spec.js deleted file mode 100644 index d66727da644..00000000000 --- a/test/spec/modules/lifestreetBidAdapter_spec.js +++ /dev/null @@ -1,232 +0,0 @@ -import { expect } from 'chai'; -import { BANNER, VIDEO } from 'src/mediaTypes.js'; -import { spec } from 'modules/lifestreetBidAdapter.js'; - -describe('lifestreetBidAdapter', function() { - let bidRequests; - let videoBidRequests; - let bidResponses; - let videoBidResponses; - beforeEach(function() { - bidRequests = [ - { - bidder: 'lifestreet', - params: { - slot: 'slot166704', - adkey: '78c', - ad_size: '160x600' - }, - mediaTypes: { - banner: { - sizes: [ - [160, 600], - [300, 600] - ] - } - }, - sizes: [ - [160, 600], - [300, 600] - ] - } - ]; - - bidResponses = { - body: { - cpm: 0.1, - netRevenue: true, - content_type: 'display_flash', - width: 160, - currency: 'USD', - ttl: 86400, - content: '', - 'adid': '56380110', - 'cid': '44724710', - 'crid': '443801010', - 'w': 300, - 'h': 250, - 'ext': { - 'prebid': { - 'targeting': { - 'hb_bidder': 'luponmedia', - 'hb_pb': '0.40', - 'hb_size': '300x250' - }, - 'type': 'banner' - } - } - } - ], - 'seat': 'luponmedia' - } - ], - 'cur': 'USD', - 'ext': { - 'responsetimemillis': { - 'luponmedia': 233 - }, - 'tmaxrequest': 1500, - 'usersyncs': { - 'status': 'ok', - 'bidder_status': [] - } - } - }; - - let expectedResponse = [ - { - 'requestId': '2a122246ef72ea', - 'cpm': '0.43', - 'width': 300, - 'height': 250, - 'creativeId': '443801010', - 'currency': 'USD', - 'dealId': '23425', - 'netRevenue': false, - 'ttl': 300, - 'referrer': '', - 'ad': ' ' - } - ]; - - let bidderRequest = { - 'data': '{"site":{"page":"https://novi.ba/clanak/176067/fast-car-beginner-s-guide-to-tuning-turbo-engines"}}' - }; - - let result = spec.interpretResponse({ body: response }, bidderRequest); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('handles nobid responses', function () { - let noBidResponse = []; - - let noBidBidderRequest = { - 'data': '{"site":{"page":""}}' - } - let noBidResult = spec.interpretResponse({ body: noBidResponse }, noBidBidderRequest); - expect(noBidResult.length).to.equal(0); - }); - }); - - describe('getUserSyncs', function () { - const bidResponse1 = { - 'body': { - 'ext': { - 'responsetimemillis': { - 'luponmedia': 233 - }, - 'tmaxrequest': 1500, - 'usersyncs': { - 'status': 'ok', - 'bidder_status': [ - { - 'bidder': 'luponmedia', - 'no_cookie': true, - 'usersync': { - 'url': 'https://adxpremium.services/api/usersync', - 'type': 'redirect' - } - }, - { - 'bidder': 'luponmedia', - 'no_cookie': true, - 'usersync': { - 'url': 'https://adxpremium.services/api/iframeusersync', - 'type': 'iframe' - } - } - ] - } - } - } - }; - - const bidResponse2 = { - 'body': { - 'ext': { - 'responsetimemillis': { - 'luponmedia': 233 - }, - 'tmaxrequest': 1500, - 'usersyncs': { - 'status': 'no_cookie', - 'bidder_status': [] - } - } - } - }; - - it('should use a sync url from first response (pixel and iframe)', function () { - const syncs = spec.getUserSyncs({ pixelEnabled: true, iframeEnabled: true }, [bidResponse1, bidResponse2]); - expect(syncs).to.deep.equal([ - { - type: 'image', - url: 'https://adxpremium.services/api/usersync' - }, - { - type: 'iframe', - url: 'https://adxpremium.services/api/iframeusersync' - } - ]); - }); - - it('handle empty response (e.g. timeout)', function () { - const syncs = spec.getUserSyncs({ pixelEnabled: true, iframeEnabled: true }, []); - expect(syncs).to.deep.equal([]); - }); - - it('returns empty syncs when not pixel enabled and not iframe enabled', function () { - const syncs = spec.getUserSyncs({ pixelEnabled: false, iframeEnabled: false }, [bidResponse1]); - expect(syncs).to.deep.equal([]); - }); - - it('returns pixel syncs when pixel enabled and not iframe enabled', function() { - resetUserSync(); - - const syncs = spec.getUserSyncs({ pixelEnabled: true, iframeEnabled: false }, [bidResponse1]); - expect(syncs).to.deep.equal([ - { - type: 'image', - url: 'https://adxpremium.services/api/usersync' - } - ]); - }); - - it('returns iframe syncs when not pixel enabled and iframe enabled', function() { - resetUserSync(); - - const syncs = spec.getUserSyncs({ pixelEnabled: false, iframeEnabled: true }, [bidResponse1]); - expect(syncs).to.deep.equal([ - { - type: 'iframe', - url: 'https://adxpremium.services/api/iframeusersync' - } - ]); - }); - }); - - describe('hasValidSupplyChainParams', function () { - it('returns true if schain is valid', function () { - const schain = { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'novi.ba', - 'sid': '199424', - 'hp': 1 - } - ] - }; - - const checkSchain = hasValidSupplyChainParams(schain); - expect(checkSchain).to.equal(true); - }); - - it('returns false if schain is invalid', function () { - const schain = { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'invalid': 'novi.ba' - } - ] - }; - - const checkSchain = hasValidSupplyChainParams(schain); - expect(checkSchain).to.equal(false); - }); - }); - - describe('onBidWon', function () { - const bidWonEvent = { - 'bidderCode': 'luponmedia', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '105bbf8c54453ff', - 'requestId': '934b8752185955', - 'mediaType': 'banner', - 'source': 'client', - 'cpm': 0.364, - 'creativeId': '443801010', - 'currency': 'USD', - 'netRevenue': false, - 'ttl': 300, - 'referrer': '', - 'ad': '', - 'auctionId': '926a8ea3-3dd4-4bf2-95ab-c85c2ce7e99b', - 'responseTimestamp': 1598527728026, - 'requestTimestamp': 1598527727629, - 'bidder': 'luponmedia', - 'adUnitCode': 'div-gpt-ad-1533155193780-5', - 'timeToRespond': 397, - 'size': '300x250', - 'status': 'rendered' - }; - - let ajaxStub; - - beforeEach(() => { - ajaxStub = sinon.stub(spec, 'sendWinningsToServer') - }) - - afterEach(() => { - ajaxStub.restore() - }) - - it('calls luponmedia\'s callback endpoint', () => { - const result = spec.onBidWon(bidWonEvent); - expect(result).to.equal(undefined); - expect(ajaxStub.calledOnce).to.equal(true); - expect(ajaxStub.firstCall.args[0]).to.deep.equal(JSON.stringify(bidWonEvent)); - }); - }); -}); diff --git a/test/spec/modules/madvertiseBidAdapter_spec.js b/test/spec/modules/madvertiseBidAdapter_spec.js deleted file mode 100644 index 041b49ef69e..00000000000 --- a/test/spec/modules/madvertiseBidAdapter_spec.js +++ /dev/null @@ -1,203 +0,0 @@ -import {expect} from 'chai'; -import {config} from 'src/config.js'; -import * as utils from 'src/utils.js'; -import {spec} from 'modules/madvertiseBidAdapter.js'; - -describe('madvertise adapater', function () { - describe('Test validate req', function () { - it('should accept minimum valid bid', function () { - let bid = { - bidder: 'madvertise', - sizes: [[728, 90]], - params: { - s: 'test' - } - }; - const isValid = spec.isBidRequestValid(bid); - - expect(isValid).to.equal(true); - }); - it('should reject no sizes', function () { - let bid = { - bidder: 'madvertise', - params: { - s: 'test' - } - }; - const isValid = spec.isBidRequestValid(bid); - - expect(isValid).to.equal(false); - }); - it('should reject empty sizes', function () { - let bid = { - bidder: 'madvertise', - sizes: [], - params: { - s: 'test' - } - }; - const isValid = spec.isBidRequestValid(bid); - - expect(isValid).to.equal(false); - }); - it('should reject wrong format sizes', function () { - let bid = { - bidder: 'madvertise', - sizes: [['728x90']], - params: { - s: 'test' - } - }; - const isValid = spec.isBidRequestValid(bid); - expect(isValid).to.equal(false); - }); - it('should reject no params', function () { - let bid = { - bidder: 'madvertise', - sizes: [[728, 90]] - }; - const isValid = spec.isBidRequestValid(bid); - - expect(isValid).to.equal(false); - }); - it('should reject missing s', function () { - let bid = { - bidder: 'madvertise', - params: {} - }; - const isValid = spec.isBidRequestValid(bid); - - expect(isValid).to.equal(false); - }); - }); - - describe('Test build request', function () { - beforeEach(function () { - let mockConfig = { - consentManagement: { - cmpApi: 'IAB', - timeout: 1111, - allowAuctionWithoutConsent: 'cancel' - } - }; - - sinon.stub(config, 'getConfig').callsFake((key) => { - return utils.deepAccess(mockConfig, key); - }); - }); - afterEach(function () { - config.getConfig.restore(); - }); - let bid = [{ - bidder: 'madvertise', - sizes: [[728, 90], [300, 100]], - bidId: '51ef8751f9aead', - adUnitCode: 'div-gpt-ad-1460505748561-0', - transactionId: 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - auctionId: '18fd8b8b0bd757', - bidderRequestId: '418b37f85e772c', - params: { - s: 'test', - } - }]; - it('minimum request with gdpr consent', function () { - let bidderRequest = { - gdprConsent: { - consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', - vendorData: {}, - gdprApplies: true - } - }; - const req = spec.buildRequests(bid, bidderRequest); - - expect(req).to.exist.and.to.be.a('array'); - expect(req[0]).to.have.property('method'); - expect(req[0].method).to.equal('GET'); - expect(req[0]).to.have.property('url'); - expect(req[0].url).to.contain('https://mobile.mng-ads.com/?rt=bid_request&v=1.0'); - expect(req[0].url).to.contain(`&s=test`); - expect(req[0].url).to.contain(`&sizes[0]=728x90`); - expect(req[0].url).to.contain(`&gdpr=1`); - expect(req[0].url).to.contain(`&consent[0][format]=IAB`); - expect(req[0].url).to.contain(`&consent[0][value]=BOJ/P2HOJ/P2HABABMAAAAAZ+A==`) - }); - - it('minimum request without gdpr consent', function () { - let bidderRequest = {}; - const req = spec.buildRequests(bid, bidderRequest); - - expect(req).to.exist.and.to.be.a('array'); - expect(req[0]).to.have.property('method'); - expect(req[0].method).to.equal('GET'); - expect(req[0]).to.have.property('url'); - expect(req[0].url).to.contain('https://mobile.mng-ads.com/?rt=bid_request&v=1.0'); - expect(req[0].url).to.contain(`&s=test`); - expect(req[0].url).to.contain(`&sizes[0]=728x90`); - expect(req[0].url).not.to.contain(`&gdpr=1`); - expect(req[0].url).not.to.contain(`&consent[0][format]=`); - expect(req[0].url).not.to.contain(`&consent[0][value]=`) - }); - }); - - describe('Test interpret response', function () { - it('General banner response', function () { - let bid = { - bidder: 'madvertise', - sizes: [[728, 90]], - bidId: '51ef8751f9aead', - adUnitCode: 'div-gpt-ad-1460505748561-0', - transactionId: 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - auctionId: '18fd8b8b0bd757', - bidderRequestId: '418b37f85e772c', - params: { - s: 'test', - connection_type: 'WIFI', - age: 25, - } - }; - let 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 - }}, {bidId: bid.bidId}); - - expect(resp).to.exist.and.to.be.a('array'); - expect(resp[0]).to.have.property('requestId', bid.bidId); - expect(resp[0]).to.have.property('cpm', 1); - expect(resp[0]).to.have.property('width', 320); - expect(resp[0]).to.have.property('height', 50); - expect(resp[0]).to.have.property('ad', '

I am an ad

'); - expect(resp[0]).to.have.property('ttl', 180); - expect(resp[0]).to.have.property('creativeId', 'CREATIVE_ID'); - expect(resp[0]).to.have.property('netRevenue', true); - expect(resp[0]).to.have.property('currency', 'EUR'); - expect(resp[0]).to.have.property('dealId', 'DEAL_ID'); - }); - it('No response', function () { - let bid = { - bidder: 'madvertise', - sizes: [[728, 90]], - bidId: '51ef8751f9aead', - adUnitCode: 'div-gpt-ad-1460505748561-0', - transactionId: 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - auctionId: '18fd8b8b0bd757', - bidderRequestId: '418b37f85e772c', - params: { - s: 'test', - connection_type: 'WIFI', - age: 25, - } - }; - let 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/malltvBidAdapter_spec.js b/test/spec/modules/malltvBidAdapter_spec.js deleted file mode 100644 index ffe08ad1a5e..00000000000 --- a/test/spec/modules/malltvBidAdapter_spec.js +++ /dev/null @@ -1,168 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/malltvBidAdapter'; - -describe('malltvAdapterTest', () => { - describe('bidRequestValidity', () => { - it('bidRequest with propertyId and placementId', () => { - expect(spec.isBidRequestValid({ - bidder: 'malltv', - params: { - propertyId: '{propertyId}', - placementId: '{placementId}' - } - })).to.equal(true); - }); - - it('bidRequest without propertyId', () => { - expect(spec.isBidRequestValid({ - bidder: 'malltv', - params: { - placementId: '{placementId}' - } - })).to.equal(false); - }); - - it('bidRequest without placementId', () => { - expect(spec.isBidRequestValid({ - bidder: 'malltv', - params: { - propertyId: '{propertyId}', - } - })).to.equal(false); - }); - - it('bidRequest without propertyId or placementId', () => { - expect(spec.isBidRequestValid({ - bidder: 'malltv', - params: {} - })).to.equal(false); - }); - }); - - describe('bidRequest', () => { - const bidRequests = [{ - 'bidder': 'malltv', - 'params': { - 'propertyId': '{propertyId}', - 'placementId': '{placementId}', - 'data': { - 'catalogs': [{ - 'catalogId': 1, - 'items': ['1', '2', '3'] - }], - 'inventory': { - 'category': ['category1', 'category2'], - 'query': ['query'] - } - } - }, - 'adUnitCode': 'hb-leaderboard', - 'transactionId': 'b6b889bb-776c-48fd-bc7b-d11a1cf0425e', - 'sizes': [[300, 250]], - 'bidId': '10bdc36fe0b48c8', - 'bidderRequestId': '70deaff71c281d', - 'auctionId': 'f9012acc-b6b7-4748-9098-97252914f9dc' - }]; - - it('bidRequest HTTP method', () => { - const requests = spec.buildRequests(bidRequests); - requests.forEach(function (requestItem) { - expect(requestItem.method).to.equal('POST'); - }); - }); - - it('bidRequest url', () => { - const endpointUrl = 'https://central.mall.tv/bid'; - const requests = spec.buildRequests(bidRequests); - requests.forEach(function (requestItem) { - expect(requestItem.url).to.match(new RegExp(`${endpointUrl}`)); - }); - }); - - it('bidRequest data', () => { - const requests = spec.buildRequests(bidRequests); - requests.forEach(function (requestItem) { - expect(requestItem.data).to.exist; - }); - }); - - it('bidRequest sizes', () => { - const requests = spec.buildRequests(bidRequests); - requests.forEach(function (requestItem) { - expect(requestItem.data.placements).to.exist; - expect(requestItem.data.placements.length).to.equal(1); - expect(requestItem.data.placements[0].sizes).to.equal('300x250'); - }); - }); - - it('bidRequest data param', () => { - const requests = spec.buildRequests(bidRequests); - requests.forEach((requestItem) => { - expect(requestItem.data.data).to.exist; - expect(requestItem.data.data.catalogs).to.exist; - expect(requestItem.data.data.inventory).to.exist; - expect(requestItem.data.data.catalogs.length).to.equal(1); - expect(requestItem.data.data.catalogs[0].items.length).to.equal(3); - expect(Object.keys(requestItem.data.data.inventory).length).to.equal(2); - expect(requestItem.data.data.inventory.category.length).to.equal(2); - expect(requestItem.data.data.inventory.query.length).to.equal(1); - }); - }); - }); - - describe('interpretResponse', () => { - const bidRequest = { - 'method': 'POST', - 'url': 'https://central.mall.tv/bid', - 'data': { - 'sizes': '300x250', - 'adUnitId': 'rectangle', - 'placementId': '{placementId}', - 'propertyId': '{propertyId}', - 'pageViewGuid': '{pageViewGuid}', - 'url': 'http://localhost:9999/integrationExamples/gpt/hello_world.html?pbjs_debug=true', - 'requestid': '26ee8fe87940da7', - 'bidid': '2962dbedc4768bf' - } - }; - - const bidResponse = { - body: [{ - 'CPM': 1, - 'Width': 300, - 'Height': 250, - 'Referrer': 'http://localhost:9999/integrationExamples/gpt/hello_world.html?pbjs_debug=true', - 'Ad': '
Test ad
', - 'CreativeId': '123abc', - 'NetRevenue': false, - 'Currency': 'EUR', - 'TTL': 360 - }], - headers: {} - }; - - it('all keys present', () => { - const result = spec.interpretResponse(bidResponse, bidRequest); - - let keys = [ - 'requestId', - 'cpm', - 'width', - 'height', - 'creativeId', - 'currency', - 'netRevenue', - 'ttl', - 'referrer', - 'ad', - 'vastUrl', - 'mediaType' - ]; - - let resultKeys = Object.keys(result[0]); - resultKeys.forEach(function (key) { - expect(keys.indexOf(key) !== -1).to.equal(true); - }); - }) - }); -}); diff --git a/test/spec/modules/mantisBidAdapter_spec.js b/test/spec/modules/mantisBidAdapter_spec.js deleted file mode 100644 index d9ab3c69a24..00000000000 --- a/test/spec/modules/mantisBidAdapter_spec.js +++ /dev/null @@ -1,348 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/mantisBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {sfPostMessage, iframePostMessage} from 'modules/mantisBidAdapter'; - -describe('MantisAdapter', function () { - const adapter = newBidder(spec); - let sandbox; - let clock; - - beforeEach(function() { - sandbox = sinon.sandbox.create(); - clock = sandbox.useFakeTimers(); - }); - - afterEach(function() { - sandbox.restore(); - }); - - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'mantis', - 'params': { - 'property': '10433394', - 'zone': 'zone' - }, - '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(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('viewability', function() { - it('iframe (viewed)', () => { - let viewed = false; - - sandbox.stub(document, 'getElementsByTagName').withArgs('iframe').returns([ - { - name: 'mantis', - getBoundingClientRect: () => ({ - top: 10, - bottom: 260, - left: 10, - right: 190, - width: 300, - height: 250 - }) - } - ]); - - iframePostMessage({innerHeight: 500, innerWidth: 500}, 'mantis', () => viewed = true); - - sandbox.clock.runAll(); - - expect(viewed).to.equal(true); - }); - - it('safeframe (viewed)', () => { - let viewed = false; - - sfPostMessage({ - ext: { - register: (width, height, callback) => { - expect(width).to.equal(100); - expect(height).to.equal(200); - - callback(); - }, - inViewPercentage: () => 60 - } - }, 100, 200, () => viewed = true); - - expect(viewed).to.equal(true); - }); - - it('safeframe (unviewed)', () => { - let viewed = false; - - sfPostMessage({ - ext: { - register: (width, height, callback) => { - expect(width).to.equal(100); - expect(height).to.equal(200); - - callback(); - }, - inViewPercentage: () => 30 - } - }, 100, 200, () => viewed = true); - - expect(viewed).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [ - { - 'bidder': 'mantis', - 'params': { - 'property': '10433394', - 'zone': 'zone' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - it('gdpr consent not required', function () { - 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}}); - - expect(request.url).to.include('consent=false'); - }); - - it('usp consent', function () { - const request = spec.buildRequests(bidRequests, {uspConsent: 'foobar'}); - - expect(request.url).to.include('usp=foobar'); - }); - - it('domain override', function () { - window.mantis_domain = 'https://foo'; - const request = spec.buildRequests(bidRequests); - - expect(request.url).to.include('https://foo'); - - delete window.mantis_domain; - }); - - it('standard request', function () { - const request = spec.buildRequests(bidRequests); - - expect(request.url).to.include('property=10433394'); - expect(request.url).to.include('bids[0][bidId]=30b31c1838de1e'); - expect(request.url).to.include('bids[0][config][zone]=zone'); - expect(request.url).to.include('bids[0][sizes][0][width]=300'); - expect(request.url).to.include('bids[0][sizes][0][height]=250'); - expect(request.url).to.include('bids[0][sizes][1][width]=300'); - expect(request.url).to.include('bids[0][sizes][1][height]=600'); - }); - - it('use window uuid', function () { - window.mantis_uuid = 'foo'; - - const request = spec.buildRequests(bidRequests); - - expect(request.url).to.include('uuid=foo'); - - delete window.mantis_uuid; - }); - - it('use storage uuid', function () { - window.localStorage.setItem('mantis:uuid', 'bar'); - - const request = spec.buildRequests(bidRequests); - - expect(request.url).to.include('uuid=bar'); - - window.localStorage.removeItem('mantis:uuid'); - }); - - it('detect amp', function () { - var oldContext = window.context; - - window.context = {}; - window.context.tagName = 'AMP-AD'; - window.context.canonicalUrl = 'foo'; - - const request = spec.buildRequests(bidRequests); - - expect(request.url).to.include('amp=true'); - expect(request.url).to.include('url=foo'); - - delete window.context.tagName; - delete window.context.canonicalUrl; - - window.context = oldContext; - }); - }); - - describe('getUserSyncs', function () { - it('iframe', function () { - let result = spec.getUserSyncs({ - iframeEnabled: true - }); - - expect(result[0].type).to.equal('iframe'); - expect(result[0].url).to.include('https://mantodea.mantisadnetwork.com/prebid/iframe'); - }); - - it('pixel', function () { - let result = spec.getUserSyncs({ - pixelEnabled: true - }); - - expect(result[0].type).to.equal('image'); - expect(result[0].url).to.include('https://mantodea.mantisadnetwork.com/prebid/pixel'); - }); - }); - - describe('interpretResponse', function () { - it('use ad ttl if provided', function () { - let response = { - body: { - ttl: 360, - uuid: 'uuid', - ads: [ - { - bid: 'bid', - cpm: 1, - view: 'view', - width: 300, - ttl: 250, - height: 250, - html: '' - } - ] - } - }; - - let expectedResponse = [ - { - requestId: 'bid', - cpm: 1, - width: 300, - height: 250, - ttl: 250, - ad: '', - creativeId: 'view', - netRevenue: true, - currency: 'USD' - } - ]; - let bidderRequest; - - let result = spec.interpretResponse(response, {bidderRequest}); - expect(result[0]).to.deep.equal(expectedResponse[0]); - }); - - it('use global ttl if provded', function () { - let response = { - body: { - ttl: 360, - uuid: 'uuid', - ads: [ - { - bid: 'bid', - cpm: 1, - view: 'view', - width: 300, - height: 250, - html: '' - } - ] - } - }; - - let expectedResponse = [ - { - requestId: 'bid', - cpm: 1, - width: 300, - height: 250, - ttl: 360, - ad: '', - creativeId: 'view', - netRevenue: true, - currency: 'USD' - } - ]; - let bidderRequest; - - let result = spec.interpretResponse(response, {bidderRequest}); - expect(result[0]).to.deep.equal(expectedResponse[0]); - }); - - it('display ads returned', function () { - let response = { - body: { - uuid: 'uuid', - ads: [ - { - bid: 'bid', - cpm: 1, - view: 'view', - width: 300, - height: 250, - html: '' - } - ] - } - }; - - let expectedResponse = [ - { - requestId: 'bid', - cpm: 1, - width: 300, - height: 250, - ttl: 86400, - ad: '', - creativeId: 'view', - netRevenue: true, - currency: 'USD' - } - ]; - let bidderRequest; - - let result = spec.interpretResponse(response, {bidderRequest}); - expect(result[0]).to.deep.equal(expectedResponse[0]); - expect(window.mantis_uuid).to.equal(response.body.uuid); - expect(window.localStorage.getItem('mantis:uuid')).to.equal(response.body.uuid); - }); - - it('no ads returned', function () { - let response = { - body: { - ads: [] - } - }; - let bidderRequest; - - let 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 deleted file mode 100644 index cf074b0f3d6..00000000000 --- a/test/spec/modules/marsmediaBidAdapter_spec.js +++ /dev/null @@ -1,708 +0,0 @@ -import { spec } from 'modules/marsmediaBidAdapter.js'; -import * as utils from 'src/utils.js'; -import { config } from 'src/config.js'; - -var marsAdapter = spec; - -describe('marsmedia adapter tests', function () { - let element, win; - let sandbox; - - beforeEach(function() { - element = { - x: 0, - y: 0, - - width: 0, - height: 0, - - getBoundingClientRect: () => { - return { - width: element.width, - height: element.height, - - left: element.x, - top: element.y, - right: element.x + element.width, - bottom: element.y + element.height - }; - } - }; - win = { - document: { - visibilityState: 'visible' - }, - - innerWidth: 800, - innerHeight: 600 - }; - this.defaultBidderRequest = { - 'refererInfo': { - 'referer': 'Reference Page', - 'stack': [ - 'aodomain.dvl', - 'page.dvl' - ] - } - }; - - this.defaultBidRequestList = [ - { - 'bidder': 'marsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'adUnitCode': 'Unit-Code', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - sandbox = sinon.sandbox.create(); - sandbox.stub(document, 'getElementById').withArgs('Unit-Code').returns(element); - sandbox.stub(utils, 'getWindowTop').returns(win); - sandbox.stub(utils, 'getWindowSelf').returns(win); - }); - - afterEach(function() { - sandbox.restore(); - }); - - describe('Verify 1.0 POST Banner Bid Request', function () { - it('buildRequests works', function () { - var bidRequest = marsAdapter.buildRequests(this.defaultBidRequestList, this.defaultBidderRequest); - - expect(bidRequest.url).to.have.string('https://hb.go2speed.media/bidder/?bid=3mhdom&zoneId=9999&hbv='); - expect(bidRequest.method).to.equal('POST'); - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.site).to.not.equal(null); - expect(openrtbRequest.site.ref).to.equal('Reference Page'); - expect(openrtbRequest.device).to.not.equal(null); - expect(openrtbRequest.device.ua).to.equal(navigator.userAgent); - expect(openrtbRequest.device.dnt).to.equal(0); - expect(openrtbRequest.imp[0].banner).to.not.equal(null); - expect(openrtbRequest.imp[0].banner.format[0].w).to.equal(300); - expect(openrtbRequest.imp[0].banner.format[0].h).to.equal(250); - expect(openrtbRequest.imp[0].ext.bidder.zoneId).to.equal(9999); - }); - - /* it('interpretResponse works', function() { - var bidList = { - 'body': [ - { - 'impid': 'Unit-Code', - 'w': 300, - 'h': 250, - 'adm': '
My Compelling Ad
', - 'price': 1, - 'crid': 'cr-cfy24', - 'nurl': '' - } - ] - }; - - var bannerBids = marsAdapter.interpretResponse(bidList); - - expect(bannerBids.length).to.equal(1); - const bid = bannerBids[0]; - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.creativeId).to.equal('cr-cfy24'); - expect(bid.currency).to.equal('USD'); - expect(bid.netRevenue).to.equal(true); - expect(bid.cpm).to.equal(1.0); - expect(bid.ttl).to.equal(350); - }); */ - }); - - describe('Verify POST Video Bid Request', function() { - it('buildRequests works', function () { - var bidRequestList = [ - { - 'bidder': 'marsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'video': { - 'playerSize': [640, 480], - 'context': 'instream' - } - }, - 'adUnitCode': 'Unit-Code', - 'sizes': [ - [300, 250] - ], - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = marsAdapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - expect(bidRequest.url).to.have.string('https://hb.go2speed.media/bidder/?bid=3mhdom&zoneId=9999&hbv='); - expect(bidRequest.method).to.equal('POST'); - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.site).to.not.equal(null); - expect(openrtbRequest.device).to.not.equal(null); - expect(openrtbRequest.device.ua).to.equal(navigator.userAgent); - expect(openrtbRequest.device).to.have.property('dnt'); - expect(openrtbRequest.imp[0].video).to.not.equal(null); - expect(openrtbRequest.imp[0].video.w).to.equal(640); - expect(openrtbRequest.imp[0].video.h).to.equal(480); - expect(openrtbRequest.imp[0].video.mimes[0]).to.equal('video/mp4'); - expect(openrtbRequest.imp[0].video.protocols).to.eql([2, 3, 5, 6]); - expect(openrtbRequest.imp[0].video.startdelay).to.equal(0); - expect(openrtbRequest.imp[0].video.skip).to.equal(0); - expect(openrtbRequest.imp[0].video.playbackmethod).to.eql([1, 2, 3, 4]); - expect(openrtbRequest.imp[0].video.delivery[0]).to.equal(1); - expect(openrtbRequest.imp[0].video.api).to.eql([1, 2, 5]); - }); - - it('interpretResponse with vast url works', function() { - var bidList = { - 'body': [ - { - 'impid': 'Unit-Code', - 'price': 1, - 'adm': 'https://example.com/', - 'adomain': [ - 'test.com' - ], - 'cid': '467415', - 'crid': 'cr-vid', - 'w': 800, - 'h': 600, - 'nurl': '' - } - ] - }; - - var videoBids = marsAdapter.interpretResponse(bidList); - - expect(videoBids.length).to.equal(1); - const bid = videoBids[0]; - expect(bid.width).to.equal(800); - expect(bid.height).to.equal(600); - expect(bid.vastUrl).to.equal('https://example.com/'); - expect(bid.mediaType).to.equal('video'); - expect(bid.creativeId).to.equal('cr-vid'); - expect(bid.currency).to.equal('USD'); - expect(bid.netRevenue).to.equal(true); - expect(bid.cpm).to.equal(1.0); - expect(bid.ttl).to.equal(600); - }); - - it('interpretResponse with xml works', function() { - var bidList = { - 'body': [ - { - 'impid': 'Unit-Code', - 'price': 1, - 'adm': '', - 'adomain': [ - 'test.com' - ], - 'cid': '467415', - 'crid': 'cr-vid', - 'w': 800, - 'h': 600, - 'nurl': '' - } - ] - }; - - var videoBids = marsAdapter.interpretResponse(bidList); - - expect(videoBids.length).to.equal(1); - const bid = videoBids[0]; - expect(bid.width).to.equal(800); - expect(bid.height).to.equal(600); - expect(bid.vastXml).to.equal(''); - expect(bid.mediaType).to.equal('video'); - expect(bid.creativeId).to.equal('cr-vid'); - expect(bid.currency).to.equal('USD'); - expect(bid.netRevenue).to.equal(true); - expect(bid.cpm).to.equal(1.0); - expect(bid.ttl).to.equal(600); - }); - }); - - describe('misc buildRequests', function() { - it('should send GDPR Consent data to Marsmedia tag', function () { - var consentString = 'testConsentString'; - var gdprBidderRequest = this.defaultBidderRequest; - gdprBidderRequest.gdprConsent = { - 'gdprApplies': true, - 'consentString': consentString - }; - - var bidRequest = marsAdapter.buildRequests(this.defaultBidRequestList, gdprBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.user.ext.consent).to.equal(consentString); - expect(openrtbRequest.regs.ext.gdpr).to.equal(true); - }); - - it('should have CCPA Consent if defined', function () { - const ccpaBidderRequest = this.defaultBidderRequest; - ccpaBidderRequest.uspConsent = '1YYN'; - const bidRequest = marsAdapter.buildRequests(this.defaultBidRequestList, ccpaBidderRequest); - const openrtbRequest = JSON.parse(bidRequest.data); - - expect(openrtbRequest.regs.ext.us_privacy).to.equal('1YYN'); - }); - - it('should submit coppa if set in config', function () { - sinon.stub(config, 'getConfig') - .withArgs('coppa') - .returns(true); - const request = marsAdapter.buildRequests(this.defaultBidRequestList, this.defaultBidderRequest); - const requestparse = JSON.parse(request.data); - expect(requestparse.regs.coppa).to.equal(1); - config.getConfig.restore(); - }); - - it('should process floors module if available', function() { - const floorBidderRequest = this.defaultBidRequestList; - const floorInfo = { - currency: 'USD', - floor: 1.20 - }; - floorBidderRequest[0].getFloor = () => floorInfo; - const request = marsAdapter.buildRequests(floorBidderRequest, this.defaultBidderRequest); - const requestparse = JSON.parse(request.data); - expect(requestparse.imp[0].bidfloor).to.equal(1.20); - }); - - it('should have 0 bidfloor value', function() { - const request = marsAdapter.buildRequests(this.defaultBidRequestList, this.defaultBidderRequest); - const requestparse = JSON.parse(request.data); - expect(requestparse.imp[0].bidfloor).to.equal(0); - }); - - it('prefer 2.0 sizes', function () { - var bidRequestList = [ - { - 'bidder': 'marsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 600]] - } - }, - 'adUnitCode': 'Unit-Code', - 'sizes': [[300, 250]], - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = marsAdapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.imp[0].banner.format[0].w).to.equal(300); - expect(openrtbRequest.imp[0].banner.format[0].h).to.equal(600); - }); - - it('does not return request for invalid banner size configuration', function () { - var bidRequestList = [ - { - 'bidder': 'marsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300]] - } - }, - 'adUnitCode': 'Unit-Code', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = marsAdapter.buildRequests(bidRequestList, this.defaultBidderRequest); - expect(bidRequest.method).to.be.undefined; - }); - - it('does not return request for missing banner size configuration', function () { - var bidRequestList = [ - { - 'bidder': 'marsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'banner': {} - }, - 'adUnitCode': 'Unit-Code', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = marsAdapter.buildRequests(bidRequestList, this.defaultBidderRequest); - expect(bidRequest.method).to.be.undefined; - }); - - it('reject bad sizes', function () { - var bidRequestList = [ - { - 'bidder': 'marsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'banner': {'sizes': [['400', '500'], ['4n0', '5g0']]} - }, - 'adUnitCode': 'Unit-Code', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = marsAdapter.buildRequests(bidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.imp[0].banner.format.length).to.equal(1); - }); - - it('dnt is correctly set to 1', function () { - var dntStub = sinon.stub(utils, 'getDNT').returns(1); - - var bidRequest = marsAdapter.buildRequests(this.defaultBidRequestList, this.defaultBidderRequest); - - dntStub.restore(); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.device.dnt).to.equal(1); - }); - - it('supports string video sizes', function () { - var bidRequestList = [ - { - 'bidder': 'marsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'video': { - 'context': 'instream', - 'playerSize': ['600', '300'] - } - }, - 'adUnitCode': 'Unit-Code', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = marsAdapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.imp[0].video.w).to.equal(600); - expect(openrtbRequest.imp[0].video.h).to.equal(300); - }); - - it('rejects bad video sizes', function () { - var bidRequestList = [ - { - 'bidder': 'marsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'video': { - 'context': 'instream', - 'playerSize': ['badWidth', 'badHeight'] - } - }, - 'adUnitCode': 'Unit-Code', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = marsAdapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.imp[0].video.w).to.be.undefined; - expect(openrtbRequest.imp[0].video.h).to.be.undefined; - }); - - it('supports missing video size', function () { - var bidRequestList = [ - { - 'bidder': 'marsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'video': { - 'context': 'instream' - } - }, - 'adUnitCode': 'Unit-Code', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = marsAdapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.imp[0].video.w).to.be.undefined; - expect(openrtbRequest.imp[0].video.h).to.be.undefined; - }); - - it('should return empty site data when refererInfo is missing', function() { - delete this.defaultBidderRequest.refererInfo; - var bidRequest = marsAdapter.buildRequests(this.defaultBidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(bidRequest.data); - - expect(openrtbRequest.site.domain).to.equal(''); - expect(openrtbRequest.site.page).to.equal(''); - expect(openrtbRequest.site.ref).to.equal(''); - }); - - context('when element is fully in view', function() { - it('returns 100', function() { - Object.assign(element, { width: 600, height: 400 }); - const request = marsAdapter.buildRequests(this.defaultBidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(request.data); - expect(openrtbRequest.imp[0].ext.viewability).to.equal(100); - }); - }); - - context('when element is out of view', function() { - it('returns 0', function() { - Object.assign(element, { x: -300, y: 0, width: 207, height: 320 }); - const request = marsAdapter.buildRequests(this.defaultBidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(request.data); - expect(openrtbRequest.imp[0].ext.viewability).to.equal(0); - }); - }); - - context('when element is partially in view', function() { - it('returns percentage', function() { - Object.assign(element, { width: 800, height: 800 }); - const request = marsAdapter.buildRequests(this.defaultBidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(request.data); - expect(openrtbRequest.imp[0].ext.viewability).to.equal(75); - }); - }); - - context('when nested iframes', function() { - it('returns \'na\'', function() { - Object.assign(element, { width: 600, height: 400 }); - - utils.getWindowTop.restore(); - utils.getWindowSelf.restore(); - sandbox.stub(utils, 'getWindowTop').returns(win); - sandbox.stub(utils, 'getWindowSelf').returns({}); - - const request = marsAdapter.buildRequests(this.defaultBidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(request.data); - expect(openrtbRequest.imp[0].ext.viewability).to.equal('na'); - }); - }); - - context('when tab is inactive', function() { - it('returns 0', function() { - Object.assign(element, { width: 600, height: 400 }); - - utils.getWindowTop.restore(); - win.document.visibilityState = 'hidden'; - sandbox.stub(utils, 'getWindowTop').returns(win); - - const request = marsAdapter.buildRequests(this.defaultBidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(request.data); - expect(openrtbRequest.imp[0].ext.viewability).to.equal(0); - }); - }); - }); - - it('should return empty site.domain and site.page when refererInfo.stack is empty', function() { - this.defaultBidderRequest.refererInfo.stack = []; - var bidRequest = marsAdapter.buildRequests(this.defaultBidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(bidRequest.data); - - expect(openrtbRequest.site.domain).to.equal(''); - expect(openrtbRequest.site.page).to.equal(''); - expect(openrtbRequest.site.ref).to.equal('Reference Page'); - }); - - it('should secure correctly', function() { - this.defaultBidderRequest.refererInfo.stack[0] = ['https://securesite.dvl']; - var bidRequest = marsAdapter.buildRequests(this.defaultBidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(bidRequest.data); - - expect(openrtbRequest.imp[0].secure).to.equal(1); - }); - - it('should pass schain', function() { - var schain = { - 'ver': '1.0', - 'complete': 1, - 'nodes': [{ - 'asi': 'indirectseller.com', - 'sid': '00001', - 'hp': 1 - }, { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 1 - }] - }; - var bidRequestList = [ - { - 'bidder': 'marsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'adUnitCode': 'Unit-Code', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead', - 'schain': schain - } - ]; - - var bidRequest = marsAdapter.buildRequests(bidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(bidRequest.data); - - expect(openrtbRequest.source.ext.schain).to.deep.equal(schain); - }); - - describe('misc interpretResponse', function () { - it('No bid response', function() { - var noBidResponse = marsAdapter.interpretResponse({ - 'body': '' - }); - expect(noBidResponse.length).to.equal(0); - }); - }); - - describe('isBidRequestValid', function () { - var bid = { - 'bidder': 'marsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'adUnitCode': 'Unit-Code' - }; - - it('should return true when required params found', function () { - expect(marsAdapter.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when placementId missing', function () { - delete bid.params.zoneId; - expect(marsAdapter.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('getUserSyncs', function () { - it('returns an empty string', function () { - expect(marsAdapter.getUserSyncs()).to.deep.equal([]); - }); - }); - - describe('on bidWon', function () { - beforeEach(function() { - sinon.stub(utils, 'triggerPixel'); - }); - afterEach(function() { - utils.triggerPixel.restore(); - }); - it('exists and is a function', () => { - expect(spec.onBidWon).to.exist.and.to.be.a('function'); - }); - it('should return nothing', function () { - var response = spec.onBidWon({}); - expect(response).to.be.an('undefined') - expect(utils.triggerPixel.called).to.equal(true); - }); - }); - - describe('on Timeout', function () { - beforeEach(function() { - sinon.stub(utils, 'triggerPixel'); - }); - afterEach(function() { - utils.triggerPixel.restore(); - }); - it('exists and is a function', () => { - expect(spec.onTimeout).to.exist.and.to.be.a('function'); - }); - it('should return nothing', function () { - var response = spec.onTimeout({}); - expect(response).to.be.an('undefined') - expect(utils.triggerPixel.called).to.equal(true); - }); - }); - - describe('on Set Targeting', function () { - beforeEach(function() { - sinon.stub(utils, 'triggerPixel'); - }); - afterEach(function() { - utils.triggerPixel.restore(); - }); - it('exists and is a function', () => { - expect(spec.onSetTargeting).to.exist.and.to.be.a('function'); - }); - it('should return nothing', function () { - var response = spec.onSetTargeting({}); - expect(response).to.be.an('undefined') - expect(utils.triggerPixel.called).to.equal(true); - }); - }); -}); diff --git a/test/spec/modules/mass_spec.js b/test/spec/modules/mass_spec.js deleted file mode 100644 index a4a87ce113f..00000000000 --- a/test/spec/modules/mass_spec.js +++ /dev/null @@ -1,151 +0,0 @@ -import { expect } from 'chai'; -import { - init, - addBidResponseHook, - addListenerOnce, - isMassBid, - useDefaultMatch, - useDefaultRender, - updateRenderers, - listenerAdded, - isEnabled -} from 'modules/mass'; -import { logInfo } from 'src/utils.js'; - -// mock a MASS bid: -const mockedMassBids = [ - { - bidder: 'ix', - bidId: 'mass-bid-1', - requestId: 'mass-bid-1', - bidderRequestId: 'bidder-request-id-1', - dealId: 'MASS1234', - ad: 'mass://provider/product/etc...', - meta: {} - }, - { - bidder: 'ix', - bidId: 'mass-bid-2', - requestId: 'mass-bid-2', - bidderRequestId: 'bidder-request-id-1', - dealId: '1234', - ad: 'mass://provider/product/etc...', - meta: { - mass: true - } - }, -]; - -// mock non-MASS bids: -const mockedNonMassBids = [ - { - bidder: 'ix', - bidId: 'non-mass-bid-1', - requstId: 'non-mass-bid-1', - bidderRequestId: 'bidder-request-id-1', - dealId: 'MASS1234', - ad: '', - meta: { - mass: true - } - }, - { - bidder: 'ix', - bidId: 'non-mass-bid-2', - requestId: 'non-mass-bid-2', - bidderRequestId: 'bidder-request-id-1', - dealId: '1234', - ad: 'mass://provider/product/etc...', - meta: {} - }, -]; - -// mock bidder request: -const mockedBidderRequest = { - bidderCode: 'ix', - bidderRequestId: 'bidder-request-id-1' -}; - -const noop = function() {}; - -describe('MASS Module', function() { - let bidderRequest = Object.assign({}, mockedBidderRequest); - - it('should be enabled by default', function() { - expect(isEnabled).to.equal(true); - }); - - it('can be disabled', function() { - init({enabled: false}); - expect(isEnabled).to.equal(false); - }); - - it('should only affect MASS bids', function() { - init({renderUrl: 'https://...'}); - mockedNonMassBids.forEach(function(mockedBid) { - const originalBid = Object.assign({}, mockedBid); - const bid = Object.assign({}, originalBid); - - bidderRequest.bids = [bid]; - - addBidResponseHook.call({bidderRequest}, noop, 'ad-code-id', bid); - - expect(bid).to.deep.equal(originalBid); - }); - }); - - it('should only update the ad markup field', function() { - init({renderUrl: 'https://...'}); - mockedMassBids.forEach(function(mockedBid) { - const originalBid = Object.assign({}, mockedBid); - const bid = Object.assign({}, originalBid); - - bidderRequest.bids = [bid]; - - addBidResponseHook.call({bidderRequest}, noop, 'ad-code-id', bid); - - expect(bid.ad).to.not.equal(originalBid.ad); - - delete bid.ad; - delete originalBid.ad; - - expect(bid).to.deep.equal(originalBid); - }); - }); - - it('should add a message listener', function() { - addListenerOnce(); - expect(listenerAdded).to.equal(true); - }); - - it('should support custom renderers', function() { - init({ - renderUrl: 'https://...', - custom: [ - { - dealIdPattern: /abc/, - render: function() {} - } - ] - }); - - const renderers = updateRenderers(); - - expect(renderers.length).to.equal(2); - }); - - it('should match bids by deal ID with the default matcher', function() { - const match = useDefaultMatch(/abc/); - - expect(match({dealId: 'abc'})).to.equal(true); - expect(match({dealId: 'xyz'})).to.equal(false); - }); - - it('should have a default renderer', function() { - const render = useDefaultRender('https://example.com/render.js', 'abc'); - render({}); - - expect(window.abc.loaded).to.equal(true); - expect(window.abc.queue.length).to.equal(1); - }); -}); diff --git a/test/spec/modules/meazyBidAdapter_spec.js b/test/spec/modules/meazyBidAdapter_spec.js deleted file mode 100644 index 2c24791f515..00000000000 --- a/test/spec/modules/meazyBidAdapter_spec.js +++ /dev/null @@ -1,177 +0,0 @@ -import * as utils from 'src/utils.js'; -import { expect } from 'chai'; -import { spec } from 'modules/meazyBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -const MEAZY_PID = '6910b7344ae566a1' -const VALID_ENDPOINT = `https://rtb-filter.meazy.co/pbjs?host=${utils.getOrigin()}&api_key=${MEAZY_PID}`; - -const bidderRequest = { - refererInfo: { - referer: 'page', - stack: ['page', 'page1'] - } -}; - -const bidRequest = { - bidder: 'meazy', - adUnitCode: 'test-div', - sizes: [[300, 250], [300, 600]], - params: { - pid: MEAZY_PID - }, - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', -}; - -const bidContent = { - 'id': '30b31c1838de1e', - 'bidid': '9780a52ff05c0e92780f5baf9cf3f4e8', - 'cur': 'USD', - 'seatbid': [{ - 'bid': [{ - 'id': 'ccf05fb8effb3d02', - 'impid': 'B19C34BBD69DAF9F', - 'burl': 'https://track.meazy.co/imp?bidid=9780a52ff05c0e92780f5baf9cf3f4e8&user=fdc401a2-92f1-42bd-ac22-d570520ad0ec&burl=1&ssp=5&project=2&cost=${AUCTION_PRICE}', - 'adm': '', - 'adid': 'ad-2.6.75.300x250', - 'price': 1.5, - 'w': 300, - 'h': 250, - 'cid': '2.6.75', - 'crid': '2.6.75.300x250', - 'dealid': 'default' - }], - 'seat': '2' - }] -}; - -const bidContentExt = { - ...bidContent, - ext: { - 'syncUrl': 'https://sync.meazy.co/sync/img?api_key=6910b7344ae566a1' - } -}; - -const bidResponse = { - body: bidContent -}; - -const noBidResponse = { body: {'nbr': 2} }; - -describe('meazyBidAdapter', 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 () { - it('should return false', function () { - let bid = Object.assign({}, bidRequest); - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return true', function () { - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }); - }); - - describe('buildRequests', function () { - it('should format valid url', function () { - const request = spec.buildRequests([bidRequest], bidderRequest); - expect(request.url).to.equal(VALID_ENDPOINT); - }); - - it('should format valid url', function () { - const request = spec.buildRequests([bidRequest], bidderRequest); - expect(request.url).to.equal(VALID_ENDPOINT); - }); - - it('should format valid request body', function () { - const request = spec.buildRequests([bidRequest], bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.id).to.exist; - expect(payload.imp).to.exist; - expect(payload.imp[0]).to.exist; - expect(payload.imp[0].banner).to.exist; - expect(payload.imp[0].banner.format).to.exist; - expect(payload.device).to.exist; - expect(payload.site).to.exist; - expect(payload.site.domain).to.exist; - expect(payload.cur).to.exist; - }); - - it('should format valid url', function () { - const request = spec.buildRequests([bidRequest], bidderRequest); - expect(request.url).to.equal(VALID_ENDPOINT); - }); - - it('should not fill user.ext object', function () { - const request = spec.buildRequests([bidRequest], bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.user.ext).to.equal(undefined); - }); - - it('should fill user.ext object', function () { - const consentString = 'hellogdpr'; - const request = spec.buildRequests([bidRequest], { ...bidderRequest, gdprConsent: { gdprApplies: true, consentString } }); - const payload = JSON.parse(request.data); - expect(payload.user.ext).to.exist.and.to.be.a('object'); - expect(payload.user.ext.consent).to.equal(consentString); - expect(payload.user.ext.gdpr).to.equal(1); - }); - }); - - describe('interpretResponse', function () { - it('should get correct bid response', function () { - const result = spec.interpretResponse(bidResponse); - const validResponse = [{ - requestId: '30b31c1838de1e', - cpm: 1.5, - width: 300, - height: 250, - creativeId: '2.6.75.300x250', - netRevenue: true, - dealId: 'default', - currency: 'USD', - ttl: 900, - ad: '' - }]; - - expect(result).to.deep.equal(validResponse); - }); - - it('handles nobid responses', function () { - let result = spec.interpretResponse(noBidResponse); - expect(result.length).to.equal(0); - }); - }); - - describe('getUserSyncs', function () { - const syncOptionsFF = { iframeEnabled: false }; - const syncOptionsEF = { iframeEnabled: true }; - const syncOptionsEE = { pixelEnabled: true, iframeEnabled: true }; - const syncOptionsFE = { pixelEnabled: true, iframeEnabled: false }; - - const successIFrame = { type: 'iframe', url: 'https://sync.meazy.co/sync/iframe' }; - const successPixel = { type: 'image', url: 'https://sync.meazy.co/sync/img?api_key=6910b7344ae566a1' }; - - it('should return an empty array', function () { - expect(spec.getUserSyncs(syncOptionsFF, [])).to.be.empty; - expect(spec.getUserSyncs(syncOptionsFF, [ bidResponse ])).to.be.empty; - expect(spec.getUserSyncs(syncOptionsFE, [ bidResponse ])).to.be.empty; - }); - - it('should be equal to the expected result', function () { - expect(spec.getUserSyncs(syncOptionsEF, [ bidResponse ])).to.deep.equal([successIFrame]); - expect(spec.getUserSyncs(syncOptionsFE, [ { body: bidContentExt } ])).to.deep.equal([successPixel]); - expect(spec.getUserSyncs(syncOptionsEE, [ { body: bidContentExt } ])).to.deep.equal([successPixel, successIFrame]); - expect(spec.getUserSyncs(syncOptionsEE, [])).to.deep.equal([successIFrame]); - }) - }); -}); diff --git a/test/spec/modules/mediaforceBidAdapter_spec.js b/test/spec/modules/mediaforceBidAdapter_spec.js deleted file mode 100644 index 24326afe5c0..00000000000 --- a/test/spec/modules/mediaforceBidAdapter_spec.js +++ /dev/null @@ -1,599 +0,0 @@ -import {assert} from 'chai'; -import {spec} from 'modules/mediaforceBidAdapter.js'; -import * as utils from '../../../src/utils.js'; -import {BANNER, NATIVE} from '../../../src/mediaTypes.js'; - -describe('mediaforce bid adapter', function () { - let sandbox; - - beforeEach(function () { - sandbox = sinon.sandbox.create(); - }); - - afterEach(function () { - sandbox.restore(); - }); - - function getLanguage() { - let language = navigator.language ? 'language' : 'userLanguage'; - return navigator[language].split('-')[0]; - } - - const language = getLanguage(); - const baseUrl = 'https://rtb.mfadsrvr.com'; - - describe('isBidRequestValid()', function () { - const defaultBid = { - bidder: 'mediaforce', - params: { - property: '10433394', - bidfloor: 0.3, - }, - }; - - it('should not accept bid without required params', function () { - assert.equal(spec.isBidRequestValid(defaultBid), false); - }); - - it('should return false when params are not passed', function () { - let bid = utils.deepClone(defaultBid); - delete bid.params; - assert.equal(spec.isBidRequestValid(bid), false); - }); - - it('should return false when valid params are not passed', function () { - let bid = utils.deepClone(defaultBid); - bid.params = {placement_id: '', publisher_id: ''}; - assert.equal(spec.isBidRequestValid(bid), false); - }); - - it('should return true when valid params are passed', function () { - let bid = utils.deepClone(defaultBid); - bid.mediaTypes = { - banner: { - sizes: [[300, 250]] - } - }; - bid.params = {publisher_id: 2, placement_id: '123'}; - assert.equal(spec.isBidRequestValid(bid), true); - }); - }); - - describe('buildRequests()', function () { - const defaultBid = { - bidder: 'mediaforce', - params: { - publisher_id: 'pub123', - placement_id: '202', - }, - nativeParams: { - title: { - required: true, - len: 800 - }, - image: { - required: true, - sizes: [300, 250], - }, - sponsoredBy: { - required: true - } - }, - mediaTypes: { - banner: { - sizes: [[300, 250]] - }, - native: { - title: { - required: true, - len: 800 - }, - image: { - required: true, - sizes: [300, 250], - }, - sponsoredBy: { - required: true - } - } - }, - transactionId: 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b', - }; - - const multiBid = [ - { - publisher_id: 'pub123', - placement_id: '202', - }, - { - publisher_id: 'pub123', - placement_id: '203', - }, - { - publisher_id: 'pub124', - placement_id: '202', - }, - { - publisher_id: 'pub123', - placement_id: '203', - transactionId: '8df76688-1618-417a-87b1-60ad046841c9' - } - ].map(({publisher_id, placement_id, transactionId}) => { - return { - bidder: 'mediaforce', - params: {publisher_id, placement_id}, - mediaTypes: { - banner: { - sizes: [[300, 250], [600, 400]] - } - }, - transactionId: transactionId || 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b' - } - }); - - const refererInfo = { - referer: 'https://www.prebid.org', - reachedTop: true, - stack: [ - 'https://www.prebid.org/page.html', - 'https://www.prebid.org/iframe1.html', - ] - }; - - const requestUrl = `${baseUrl}/header_bid`; - const dnt = utils.getDNT() ? 1 : 0; - const secure = window.location.protocol === 'https:' ? 1 : 0; - const pageUrl = window.location.href; - const timeout = 1500; - - it('should return undefined if no validBidRequests passed', function () { - assert.equal(spec.buildRequests([]), undefined); - }); - - it('should return proper request url: no refererInfo', function () { - let [request] = spec.buildRequests([defaultBid]); - assert.equal(request.url, requestUrl); - }); - - it('should return proper banner imp', function () { - let bid = utils.deepClone(defaultBid); - bid.params.bidfloor = 0.5; - - let bidRequests = [bid]; - let bidderRequest = { - bids: bidRequests, - refererInfo: refererInfo, - timeout: timeout, - auctionId: '210a474e-88f0-4646-837f-4253b7cf14fb' - }; - - let [request] = spec.buildRequests(bidRequests, bidderRequest); - - let data = JSON.parse(request.data); - assert.deepEqual(data, { - id: data.id, - tmax: timeout, - ext: { - mediaforce: { - hb_key: bidderRequest.auctionId - } - }, - site: { - id: bid.params.publisher_id, - publisher: {id: bid.params.publisher_id}, - ref: encodeURIComponent(refererInfo.referer), - page: pageUrl, - }, - device: { - ua: navigator.userAgent, - dnt: dnt, - js: 1, - language: language, - }, - imp: [{ - tagid: bid.params.placement_id, - secure: secure, - bidfloor: bid.params.bidfloor, - ext: { - mediaforce: { - transactionId: bid.transactionId - } - }, - 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: 1} - ], - context: 1, - plcmttype: 1, - ver: '1.2' - } - }, - }], - }); - - assert.deepEqual(request, { - method: 'POST', - url: requestUrl, - data: '{"id":"' + data.id + '","site":{"page":"' + pageUrl + '","ref":"https%3A%2F%2Fwww.prebid.org","id":"pub123","publisher":{"id":"pub123"}},"device":{"ua":"' + navigator.userAgent + '","js":1,"dnt":' + dnt + ',"language":"' + language + '"},"ext":{"mediaforce":{"hb_key":"210a474e-88f0-4646-837f-4253b7cf14fb"}},"tmax":1500,"imp":[{"tagid":"202","secure":' + secure + ',"bidfloor":0.5,"ext":{"mediaforce":{"transactionId":"d45dd707-a418-42ec-b8a7-b70a6c6fab0b"}},"banner":{"w":300,"h":250},"native":{"ver":"1.2","request":{"assets":[{"required":1,"id":1,"title":{"len":800}},{"required":1,"id":3,"img":{"type":3,"w":300,"h":250}},{"required":1,"id":5,"data":{"type":1}}],"context":1,"plcmttype":1,"ver":"1.2"}}}]}', - }); - }); - - it('multiple sizes', function () { - let bid = utils.deepClone(defaultBid); - bid.mediaTypes = { - banner: { - sizes: [[300, 600], [300, 250]], - } - }; - - let [request] = spec.buildRequests([bid]); - let data = JSON.parse(request.data); - assert.deepEqual(data.imp[0].banner, {w: 300, h: 600, format: [{w: 300, h: 250}]}); - }); - - it('should return proper requests for multiple imps', function () { - let bidderRequest = { - bids: multiBid, - refererInfo: refererInfo, - timeout: timeout, - auctionId: '210a474e-88f0-4646-837f-4253b7cf14fb' - }; - - let requests = spec.buildRequests(multiBid, bidderRequest); - assert.equal(requests.length, 2); - requests.forEach((req) => { - req.data = JSON.parse(req.data); - }); - - assert.deepEqual(requests, [ - { - method: 'POST', - url: requestUrl, - data: { - id: requests[0].data.id, - tmax: timeout, - ext: { - mediaforce: { - hb_key: bidderRequest.auctionId - } - }, - site: { - id: 'pub123', - publisher: {id: 'pub123'}, - ref: encodeURIComponent(refererInfo.referer), - page: pageUrl, - }, - device: { - ua: navigator.userAgent, - dnt: dnt, - js: 1, - language: language, - }, - imp: [{ - tagid: '202', - secure: secure, - bidfloor: 0, - ext: { - mediaforce: { - transactionId: 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b' - } - }, - banner: {w: 300, h: 250, format: [{w: 600, h: 400}]}, - }, { - tagid: '203', - secure: secure, - bidfloor: 0, - ext: { - mediaforce: { - transactionId: 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b' - } - }, - banner: {w: 300, h: 250, format: [{w: 600, h: 400}]}, - }, { - tagid: '203', - secure: secure, - bidfloor: 0, - ext: { - mediaforce: { - transactionId: '8df76688-1618-417a-87b1-60ad046841c9' - } - }, - banner: {w: 300, h: 250, format: [{w: 600, h: 400}]}, - }] - } - }, - { - method: 'POST', - url: requestUrl, - data: { - id: requests[1].data.id, - tmax: timeout, - ext: { - mediaforce: { - hb_key: bidderRequest.auctionId - } - }, - site: { - id: 'pub124', - publisher: {id: 'pub124'}, - ref: encodeURIComponent(refererInfo.referer), - page: pageUrl, - }, - device: { - ua: navigator.userAgent, - dnt: dnt, - js: 1, - language: language, - }, - imp: [{ - tagid: '202', - secure: secure, - bidfloor: 0, - ext: { - mediaforce: { - transactionId: 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b' - } - }, - banner: {w: 300, h: 250, format: [{w: 600, h: 400}]}, - }] - } - } - ]); - }); - }); - - describe('interpretResponse() banner', function () { - it('not successfull response', function () { - assert.deepEqual(spec.interpretResponse(), []); - }); - - it('successfull response', function () { - let bid = { - price: 3, - w: 100, - id: '65599d0a-42d2-446a-9d39-6086c1433ffe', - burl: `${baseUrl}/burl/\${AUCTION_PRICE}`, - cid: '2_ssl', - h: 100, - cat: ['IAB1-1'], - dealid: '3901521', - crid: '2_ssl', - impid: '2b3c9d103723a7', - adid: '2_ssl', - adm: `` - }; - - let response = { - body: { - seatbid: [{ - bid: [bid] - }], - cur: 'USD', - id: '620190c2-7eef-42fa-91e2-f5c7fbc2bdd3' - } - }; - - let bids = spec.interpretResponse(response); - assert.deepEqual(bids, ([{ - ad: bid.adm, - cpm: bid.price, - dealId: bid.dealid, - creativeId: bid.adid, - currency: response.body.cur, - height: bid.h, - netRevenue: true, - burl: bid.burl, - mediaType: BANNER, - requestId: bid.impid, - ttl: 300, - width: bid.w, - }])); - }); - }); - - describe('interpretResponse() native as object', function () { - it('successfull response', function () { - let titleText = 'Colorado Drivers With No DUI\'s Getting A Pay Day on Friday'; - let imgData = { - url: `${baseUrl}/image`, - w: 1200, - h: 627 - }; - let nativeLink = `${baseUrl}/click/`; - let nativeTracker = `${baseUrl}/imp-image`; - let sponsoredByValue = 'Comparisons.org'; - let bodyValue = 'Drivers With No Tickets In 3 Years Should Do This On June'; - let bid = { - price: 3, - id: '65599d0a-42d2-446a-9d39-6086c1433ffe', - burl: `${baseUrl}/burl/\${AUCTION_PRICE}`, - cid: '2_ssl', - cat: ['IAB1-1'], - crid: '2_ssl', - impid: '2b3c9d103723a7', - adid: '2_ssl', - ext: { - advertiser_name: 'MediaForce', - native: { - link: {url: nativeLink}, - assets: [{ - id: 1, - title: {text: titleText}, - required: 1 - }, { - id: 3, - img: imgData - }, { - id: 5, - data: {value: sponsoredByValue} - }, { - id: 4, - data: {value: bodyValue} - }], - imptrackers: [nativeTracker], - ver: '1' - }, - language: 'en', - agency_name: 'MediaForce DSP' - } - }; - - let response = { - body: { - seatbid: [{ - bid: [bid] - }], - cur: 'USD', - id: '620190c2-7eef-42fa-91e2-f5c7fbc2bdd3' - } - }; - - let bids = spec.interpretResponse(response); - assert.deepEqual(bids, ([{ - native: { - clickUrl: nativeLink, - clickTrackers: [], - impressionTrackers: [nativeTracker], - javascriptTrackers: [], - title: titleText, - image: { - url: imgData.url, - width: imgData.w, - height: imgData.h - }, - sponsoredBy: sponsoredByValue, - body: bodyValue - }, - cpm: bid.price, - creativeId: bid.adid, - currency: response.body.cur, - netRevenue: true, - burl: bid.burl, - mediaType: NATIVE, - requestId: bid.impid, - ttl: 300, - }])); - }); - }); - - describe('interpretResponse() native as string', function () { - it('successfull response', function () { - let titleText = 'Colorado Drivers With No DUI\'s Getting A Pay Day on Friday'; - let imgData = { - url: `${baseUrl}/image`, - w: 1200, - h: 627 - }; - let nativeLink = `${baseUrl}/click/`; - let nativeTracker = `${baseUrl}/imp-image`; - let sponsoredByValue = 'Comparisons.org'; - let bodyValue = 'Drivers With No Tickets In 3 Years Should Do This On June'; - let adm = JSON.stringify({ - native: { - link: {url: nativeLink}, - assets: [{ - id: 1, - title: {text: titleText}, - required: 1 - }, { - id: 3, - img: imgData - }, { - id: 5, - data: {value: sponsoredByValue} - }, { - id: 4, - data: {value: bodyValue} - }], - imptrackers: [nativeTracker], - ver: '1' - } - }); - let bid = { - price: 3, - id: '65599d0a-42d2-446a-9d39-6086c1433ffe', - burl: `${baseUrl}/burl/\${AUCTION_PRICE}`, - cid: '2_ssl', - cat: ['IAB1-1'], - crid: '2_ssl', - impid: '2b3c9d103723a7', - adid: '2_ssl', - adm: adm - }; - - let response = { - body: { - seatbid: [{ - bid: [bid] - }], - cur: 'USD', - id: '620190c2-7eef-42fa-91e2-f5c7fbc2bdd3' - } - }; - - let bids = spec.interpretResponse(response); - assert.deepEqual(bids, ([{ - native: { - clickUrl: nativeLink, - clickTrackers: [], - impressionTrackers: [nativeTracker], - javascriptTrackers: [], - title: titleText, - image: { - url: imgData.url, - width: imgData.w, - height: imgData.h - }, - sponsoredBy: sponsoredByValue, - body: bodyValue - }, - cpm: bid.price, - creativeId: bid.adid, - currency: response.body.cur, - netRevenue: true, - burl: bid.burl, - mediaType: NATIVE, - requestId: bid.impid, - ttl: 300, - }])); - }); - }); - - describe('onBidWon()', function () { - beforeEach(function() { - sinon.stub(utils, 'triggerPixel'); - }); - afterEach(function() { - utils.triggerPixel.restore(); - }); - it('should expand price macros in burl', function () { - let burl = 'burl&s=${AUCTION_PRICE}'; - let bid = { - bidder: 'mediaforce', - width: 300, - height: 250, - adId: '330a22bdea4cac', - mediaType: 'banner', - cpm: 0.28, - ad: '...', - requestId: '418b37f85e772c', - adUnitCode: 'div-gpt-ad-1460505748561-0', - size: '350x250', - burl: burl, - adserverTargeting: { - hb_bidder: 'mediaforce', - hb_adid: '330a22bdea4cac', - hb_pb: '0.20', - hb_size: '350x250' - } - } - spec.onBidWon(bid); - assert.equal(bid.burl, 'burl&s=0.20'); - }); - }); -}); diff --git a/test/spec/modules/mediagoBidAdapter_spec.js b/test/spec/modules/mediagoBidAdapter_spec.js deleted file mode 100644 index 25cfc72672b..00000000000 --- a/test/spec/modules/mediagoBidAdapter_spec.js +++ /dev/null @@ -1,101 +0,0 @@ -import { - expect -} from 'chai'; -import { - spec -} from 'modules/mediagoBidAdapter.js'; - -describe('mediago:BidAdapterTests', function() { - let bidRequestData = { - 'bidderCode': 'mediago', - 'auctionId': '7fae02a9-0195-472f-ba94-708d3bc2c0d9', - 'bidderRequestId': '4fec04e87ad785', - 'bids': [{ - 'bidder': 'mediago', - 'params': { - 'token': '85a6b01e41ac36d49744fad726e3655d' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': '5e24a2ce-db03-4565-a8a3-75dbddca9377', - 'sizes': [ - [ - 300, - 250 - ] - ], - 'bidId': '54d73f19c9d47a', - 'bidderRequestId': '4fec04e87ad785', - 'auctionId': '7fae02a9-0195-472f-ba94-708d3bc2c0d9', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - }] - }; - let request = []; - - it('mediago:validate_pub_params', function() { - expect( - spec.isBidRequestValid({ - bidder: 'mediago', - params: { - token: ['85a6b01e41ac36d49744fad726e3655d'] - } - }) - ).to.equal(true); - }); - - it('mediago:validate_generated_params', function() { - request = spec.buildRequests(bidRequestData.bids, bidRequestData); - // console.log(request); - let req_data = JSON.parse(request.data); - expect(req_data.imp).to.have.lengthOf(1); - }); - - it('mediago:validate_response_params', function() { - let serverResponse = { - body: { - 'id': '7244645c-a81a-4760-8fd6-9d908d2c4a44', - 'seatbid': [{ - 'bid': [{ - 'id': 'aa86796a857ebedda9a2d7128a87dab1', - 'impid': '1', - 'price': 0.05, - 'nurl': 'http://d21uzv52i0cqie.cloudfront.net/api/winnotice?tn=341443089c0cb829164455a42d216ee3\u0026winloss=1\u0026id=aa86796a857ebedda9a2d7128a87dab1\u0026seat_id=${AUCTION_SEAT_ID}\u0026currency=${AUCTION_CURRENCY}\u0026bid_id=${AUCTION_BID_ID}\u0026ad_id=${AUCTION_AD_ID}\u0026loss=${AUCTION_LOSS}\u0026imp_id=1\u0026price=${AUCTION_PRICE}\u0026test=0\u0026time=1597714943\u0026adp=Dtnz0O4U8sdAU-XGGijCAgMbjDIeMGyCLXeSg1laXxM\u0026dsp_id=22\u0026url=-BFDu2NYtc4PYTplFW_2JcnDSRVLOOfaERbwJABjFyG6NUB4ywA3dUaXt5zPlyCUpBCOxjH9gk4E6yWTshzuSfQSx7g_TxvcXYUgh7YtY9NQZxx14InmNCTsezqID5UztV7llz8SXWHQ-ZsutH1nJIZzl1jH3i2uCPi91shqIZLN1bLJ5guAr5O4WyxVeOqIKyD_GiVcY9Olm51iI_3wgwFyDEN_dIDv-ObgNxpbPD0L11-62bjhGw3__7RuEo6XLdox-g46Fcqk6i0zayfsPM4QeMAhWJ4lsg-xswSI0YAfzyoOIeTWB78mdpt_GmN5PKZZPqyO7VkbwHEasn-mTyYTddbz5v2fzEkRO0AQZtAZx96PANGrNvcOHnRVmCdkzN96b5Ur1_8ipdyzHOFRtJ-z_KmKaxig6himvMCePozZvrvihiGhigP4RGiFT7ytVYKHyUGAV2PF5SwtgnB0uGCltd7o1CLhZyZEQNgE7LSESyGztZ5kM9N_VZV9gPZVhvlJDfYFNRW9i6D2pZxV0Gd63rA9gpeUJ3mhbkj-B27VRKrNTBSrwIAU7P0RPD5_opl3G8nPD1Ce2vKuQK8qynHWQblfeA61nDok-fRezSKbzwepqi8oxXadFrCmN7KxP_mPqA794xYzIw5-mS64NA', - 'burl': 'http://d21uzv52i0cqie.cloudfront.net/api/winnotice?tn=341443089c0cb829164455a42d216ee3\u0026winloss=2\u0026id=aa86796a857ebedda9a2d7128a87dab1\u0026seat_id=${AUCTION_SEAT_ID}\u0026currency=${AUCTION_CURRENCY}\u0026bid_id=${AUCTION_BID_ID}\u0026ad_id=${AUCTION_AD_ID}\u0026loss=${AUCTION_LOSS}\u0026imp_id=1\u0026price=${AUCTION_PRICE}\u0026test=0\u0026time=1597714943\u0026adp=Dtnz0O4U8sdAU-XGGijCAgMbjDIeMGyCLXeSg1laXxM\u0026dsp_id=22\u0026url=dXerAvyp4zYQzsQ56eGB4JtiA4yFaYlTqcHffccrvCg', - 'lurl': 'http://d21uzv52i0cqie.cloudfront.net/api/winnotice?tn=341443089c0cb829164455a42d216ee3\u0026winloss=0\u0026id=aa86796a857ebedda9a2d7128a87dab1\u0026seat_id=${AUCTION_SEAT_ID}\u0026currency=${AUCTION_CURRENCY}\u0026bid_id=${AUCTION_BID_ID}\u0026ad_id=${AUCTION_AD_ID}\u0026loss=${AUCTION_LOSS}\u0026imp_id=1\u0026price=${AUCTION_PRICE}\u0026test=0\u0026time=1597714943\u0026adp=Dtnz0O4U8sdAU-XGGijCAgMbjDIeMGyCLXeSg1laXxM\u0026dsp_id=22\u0026url=ptSxg_vR7-fdx-WAkkUADJb__BntE5a6-RSeYdUewvk', - 'adm': '\u003clink rel=\"stylesheet\" href=\"//cdn.mediago.io/js/style/style_banner_300*250.css\"\u003e\u003cdiv id=\"mgcontainer-583ce3286b442001205b2fb9a5488efc\" class=\"mediago-placement imgTopTitleBottom\" style=\"position:relative;width:298px;height:248px;overflow:hidden\"\u003e\u003ca href=\"http://trace.mediago.io/api/bidder/track?tn=341443089c0cb829164455a42d216ee3\u0026price=PRMC8pCHtH55ipgXubUs8jlsKTBxWRSEweH8Mee_aUQ\u0026evt=102\u0026rid=aa86796a857ebedda9a2d7128a87dab1\u0026campaignid=1003540\u0026impid=25-300x175-1\u0026offerid=1107782\u0026test=0\u0026time=1597714943\u0026cp=GJA03gjm-ugPTmN7prOpvhfu1aA04IgpTcW4oRX22Lg\u0026clickid=25_aa86796a857ebedda9a2d7128a87dab1_25-300x175-1\u0026acid=164\u0026trackingid=583ce3286b442001205b2fb9a5488efc\u0026uid=6dda6c6b70eb4e2d9ab3469d921f2c74\u0026jt=2\u0026url=PQFFci337KgCVkx7KTgRItClLaWH0lgTcIlgBRTpfKngVJES4uKLfxXz9mjLcDWIbWQcEVVk_gfTcIaK8oKO2YyVG5lc3hjZeZr0VaIDHbWggPJaqtfDK9T0HZIKvrpe\" target=\"_blank\"\u003e\u003cimg alt=\"Robert Vowed To Keep Silent, But Decided To Put The People First And Speak\" src=\"https://d2cli4kgl5uxre.cloudfront.net/ML/b5e361889beef5eaf69987384b7a56e8__300x175.png\" style=\"height:70%;width:100%;border-width:0;border:none;\"\u003e\u003ch3 class=\"title\" style=\"font-size:16px;\"\u003eRobert Vowed To Keep Silent, But Decided To Put The People First And Speak\u003c/h3\u003e\u003c/a\u003e\u003cspan class=\"source\"\u003e\u003ca class=\"sourcename\" href=\"//www.mediago.io\" target=\"_blank\"\u003e\u003cspan\u003eAd\u003c/span\u003e \u003c/a\u003e\u003ca class=\"srcnameadslabelurl\" href=\"//www.mediago.io/privacy\" target=\"_blank\"\u003e\u003cspan\u003eViral Net News\u003c/span\u003e\u003c/a\u003e\u003c/span\u003e\u003c/div\u003e\u003cscript\u003e!function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){\"undefined\"!=typeof Symbol\u0026\u0026Symbol.toStringTag\u0026\u0026Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(e,\"__esModule\",{value:!0})},n.t=function(e,t){if(1\u0026t\u0026\u0026(e=n(e)),8\u0026t)return e;if(4\u0026t\u0026\u0026\"object\"==typeof e\u0026\u0026e\u0026\u0026e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,\"default\",{enumerable:!0,value:e}),2\u0026t\u0026\u0026\"string\"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e\u0026\u0026e.__esModule?function(){return e.default}:function(){return e};return n.d(t,\"a\",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p=\"\",n(n.s=24)}({24:function(e,t,n){\"use strict\";function o(e){var t=new Image;t.src=e,t.style=\"display:none;visibility:hidden\",t.width=0,t.height=0,document.body.appendChild(t)}o(\"http://d21uzv52i0cqie.cloudfront.net/api/bidder/track?tn=341443089c0cb829164455a42d216ee3\u0026price=PRMC8pCHtH55ipgXubUs8jlsKTBxWRSEweH8Mee_aUQ\u0026evt=101\u0026rid=aa86796a857ebedda9a2d7128a87dab1\u0026campaignid=1003540\u0026impid=25-300x175-1\u0026offerid=1107782\u0026test=0\u0026time=1597714943\u0026cp=GJA03gjm-ugPTmN7prOpvhfu1aA04IgpTcW4oRX22Lg\u0026acid=164\u0026trackingid=583ce3286b442001205b2fb9a5488efc\u0026uid=6dda6c6b70eb4e2d9ab3469d921f2c74\");var r=document.getElementById(\"mgcontainer-583ce3286b442001205b2fb9a5488efc\"),i=!1;!function e(){setTimeout((function(){var t,n;!i\u0026\u0026(t=r,n=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight,(t.getBoundingClientRect()\u0026\u0026t.getBoundingClientRect().top)\u003c=n-.75*(t.offsetHeight||t.clientHeight))?(i=!0,o(\"http://d21uzv52i0cqie.cloudfront.net/api/bidder/track?tn=341443089c0cb829164455a42d216ee3\u0026price=PRMC8pCHtH55ipgXubUs8jlsKTBxWRSEweH8Mee_aUQ\u0026evt=104\u0026rid=aa86796a857ebedda9a2d7128a87dab1\u0026campaignid=1003540\u0026impid=25-300x175-1\u0026offerid=1107782\u0026test=0\u0026time=1597714943\u0026cp=GJA03gjm-ugPTmN7prOpvhfu1aA04IgpTcW4oRX22Lg\u0026acid=164\u0026trackingid=583ce3286b442001205b2fb9a5488efc\u0026uid=6dda6c6b70eb4e2d9ab3469d921f2c74\u0026sid=16__11__13\u0026format=\u0026crid=b5e361889beef5eaf69987384b7a56e8\")):e()}),500)}()}});\u003c/script\u003e\u003cscript type=\"text/javascript\" src=\"http://d21uzv52i0cqie.cloudfront.net/api/track?tn=341443089c0cb829164455a42d216ee3\u0026price=${AUCTION_PRICE}\u0026evt=5\u0026rid=aa86796a857ebedda9a2d7128a87dab1\u0026impid=1\u0026offerid=\u0026tagid=\u0026test=0\u0026time=1597714943\u0026adp=5zrCZ2rC-WLafYkNpeTnzA72tDqVZUlOA3Js6_eJjYU\u0026dsp_id=22\u0026cp=${cp}\u0026url=\u0026type=script\"\u003e\u003c/script\u003e\u003cscript\u003edocument.addEventListener\u0026\u0026document.addEventListener(\"click\",function(){var a=document.createElement(\"script\");a.src=\"http://d21uzv52i0cqie.cloudfront.net/api/track?tn=341443089c0cb829164455a42d216ee3\u0026price=${AUCTION_PRICE}\u0026evt=6\u0026rid=aa86796a857ebedda9a2d7128a87dab1\u0026impid=1\u0026offerid=\u0026tagid=\u0026test=0\u0026time=1597714943\u0026adp=5zrCZ2rC-WLafYkNpeTnzA72tDqVZUlOA3Js6_eJjYU\u0026dsp_id=22\u0026cp=${cp}\u0026url=\u0026clickid=25_aa86796a857ebedda9a2d7128a87dab1_1\";document.body.appendChild(a)});\u003c/script\u003e', - 'cid': '1003540', - 'crid': 'b5e361889beef5eaf69987384b7a56e8', - 'w': 300, - 'h': 250 - }] - }], - 'cur': 'USD' - } - }; - - let bids = spec.interpretResponse(serverResponse); - // console.log({ - // bids - // }); - expect(bids).to.have.lengthOf(1); - - let bid = bids[0]; - - expect(bid.creativeId).to.equal('b5e361889beef5eaf69987384b7a56e8'); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.currency).to.equal('USD'); - }); -}); diff --git a/test/spec/modules/medianetAnalyticsAdapter_spec.js b/test/spec/modules/medianetAnalyticsAdapter_spec.js deleted file mode 100644 index 41a6338225e..00000000000 --- a/test/spec/modules/medianetAnalyticsAdapter_spec.js +++ /dev/null @@ -1,237 +0,0 @@ -import { expect } from 'chai'; -import medianetAnalytics from 'modules/medianetAnalyticsAdapter.js'; -import * as utils from 'src/utils.js'; -import CONSTANTS from 'src/constants.json'; -import events from 'src/events.js'; - -const { - EVENTS: { AUCTION_INIT, BID_REQUESTED, BID_RESPONSE, NO_BID, BID_TIMEOUT, AUCTION_END, SET_TARGETING, BID_WON } -} = CONSTANTS; - -const MOCK = { - Ad_Units: [{'code': 'div-gpt-ad-1460505748561-0', 'mediaTypes': {'banner': {'sizes': [[300, 250]]}}, 'bids': [], 'ext': {'prop1': 'value1'}}], - MULTI_FORMAT_TWIN_AD_UNITS: [{'code': 'div-gpt-ad-1460505748561-0', 'mediaTypes': {'banner': {'sizes': [[300, 250]]}, 'native': {'image': {'required': true, 'sizes': [150, 50]}}}, 'bids': [], 'ext': {'prop1': 'value1'}}, {'code': 'div-gpt-ad-1460505748561-0', 'mediaTypes': {'video': {'playerSize': [640, 480], 'context': 'instream'}}, 'bids': [], 'ext': {'prop1': 'value1'}}], - AUCTION_INIT: {'auctionId': '8e0d5245-deb3-406c-96ca-9b609e077ff7', 'timestamp': 1584563605739, 'timeout': 6000}, - AUCTION_INIT_WITH_FLOOR: {'auctionId': '8e0d5245-deb3-406c-96ca-9b609e077ff7', 'timestamp': 1584563605739, 'timeout': 6000, 'bidderRequests': [{'bids': [{ 'floorData': {'enforcements': {'enforceJS': true}} }]}]}, - BID_REQUESTED: {'bidderCode': 'medianet', 'auctionId': '8e0d5245-deb3-406c-96ca-9b609e077ff7', 'bids': [{'bidder': 'medianet', 'params': {'cid': 'TEST_CID', 'crid': '451466393'}, 'mediaTypes': {'banner': {'sizes': [[300, 250]], 'ext': ['asdads']}}, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'sizes': [[300, 250]], 'bidId': '28248b0e6aece2', 'auctionId': '8e0d5245-deb3-406c-96ca-9b609e077ff7', 'src': 'client'}], 'auctionStart': 1584563605739, 'timeout': 6000, 'uspConsent': '1YY', 'start': 1584563605743}, - MULTI_FORMAT_BID_REQUESTED: {'bidderCode': 'medianet', 'auctionId': '8e0d5245-deb3-406c-96ca-9b609e077ff7', 'bids': [{'bidder': 'medianet', 'params': {'cid': 'TEST_CID', 'crid': '451466393'}, 'mediaTypes': {'banner': {'sizes': [[300, 250]]}, 'video': {'playerSize': [640, 480], 'context': 'instream'}, 'native': {'image': {'required': true, 'sizes': [150, 50]}, 'title': {'required': true, 'len': 80}}}, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'sizes': [[300, 250]], 'bidId': '28248b0e6aece2', 'auctionId': '8e0d5245-deb3-406c-96ca-9b609e077ff7', 'src': 'client'}], 'auctionStart': 1584563605739, 'timeout': 6000, 'uspConsent': '1YY', 'start': 1584563605743}, - BID_RESPONSE: {'bidderCode': 'medianet', 'width': 300, 'height': 250, 'adId': '3e6e4bce5c8fb3', 'requestId': '28248b0e6aece2', 'mediaType': 'banner', 'source': 'client', 'ext': {'pvid': 123, 'crid': '321'}, 'no_bid': false, 'cpm': 2.299, 'ad': 'AD_CODE', 'ttl': 180, 'creativeId': 'Test1', 'netRevenue': true, 'currency': 'USD', 'dfp_id': 'div-gpt-ad-1460505748561-0', 'originalCpm': 1.1495, 'originalCurrency': 'USD', 'floorData': {'floorValue': 1.10, 'floorRule': 'banner'}, 'auctionId': '8e0d5245-deb3-406c-96ca-9b609e077ff7', 'responseTimestamp': 1584563606009, 'requestTimestamp': 1584563605743, 'bidder': 'medianet', 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'timeToRespond': 266, 'pbLg': '2.00', 'pbMg': '2.20', 'pbHg': '2.29', 'pbAg': '2.25', 'pbDg': '2.29', 'pbCg': '2.00', 'size': '300x250', 'adserverTargeting': {'hb_bidder': 'medianet', 'hb_adid': '3e6e4bce5c8fb3', 'hb_pb': '2.00', 'hb_size': '300x250', 'hb_source': 'client', 'hb_format': 'banner', 'prebid_test': 1}, 'status': 'rendered', 'params': [{'cid': 'test123', 'crid': '451466393'}]}, - AUCTION_END: {'auctionId': '8e0d5245-deb3-406c-96ca-9b609e077ff7', 'auctionEnd': 1584563605739}, - SET_TARGETING: {'div-gpt-ad-1460505748561-0': {'prebid_test': '1', 'hb_format': 'banner', 'hb_source': 'client', 'hb_size': '300x250', 'hb_pb': '2.00', 'hb_adid': '3e6e4bce5c8fb3', 'hb_bidder': 'medianet', 'hb_format_medianet': 'banner', 'hb_source_medianet': 'client', 'hb_size_medianet': '300x250', 'hb_pb_medianet': '2.00', 'hb_adid_medianet': '3e6e4bce5c8fb3', 'hb_bidder_medianet': 'medianet'}}, - NO_BID_SET_TARGETING: {'div-gpt-ad-1460505748561-0': {}}, - BID_WON: {'bidderCode': 'medianet', 'width': 300, 'height': 250, 'statusMessage': 'Bid available', 'adId': '3e6e4bce5c8fb3', 'requestId': '28248b0e6aece2', 'mediaType': 'banner', 'source': 'client', 'no_bid': false, 'cpm': 2.299, 'ad': 'AD_CODE', 'ttl': 180, 'creativeId': 'Test1', 'netRevenue': true, 'currency': 'USD', 'dfp_id': 'div-gpt-ad-1460505748561-0', 'originalCpm': 1.1495, 'originalCurrency': 'USD', 'auctionId': '8e0d5245-deb3-406c-96ca-9b609e077ff7', 'responseTimestamp': 1584563606009, 'requestTimestamp': 1584563605743, 'bidder': 'medianet', 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'timeToRespond': 266, 'pbLg': '2.00', 'pbMg': '2.20', 'pbHg': '2.29', 'pbAg': '2.25', 'pbDg': '2.29', 'pbCg': '2.00', 'size': '300x250', 'adserverTargeting': {'hb_bidder': 'medianet', 'hb_adid': '3e6e4bce5c8fb3', 'hb_pb': '2.00', 'hb_size': '300x250', 'hb_source': 'client', 'hb_format': 'banner', 'prebid_test': 1}, 'status': 'rendered', 'params': [{'cid': 'test123', 'crid': '451466393'}]}, - NO_BID: {'bidder': 'medianet', 'params': {'cid': 'test123', 'crid': '451466393', 'site': {}}, 'mediaTypes': {'banner': {'sizes': [[300, 250]], 'ext': ['asdads']}}, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'transactionId': '303fa0c6-682f-4aea-8e4a-dc68f0d5c7d5', 'sizes': [[300, 250], [300, 600]], 'bidId': '28248b0e6aece2', 'bidderRequestId': '13fccf3809fe43', 'auctionId': '8e0d5245-deb3-406c-96ca-9b609e077ff7', 'src': 'client'}, - BID_TIMEOUT: [{'bidId': '28248b0e6aece2', 'bidder': 'medianet', 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'auctionId': '8e0d5245-deb3-406c-96ca-9b609e077ff7', 'params': [{'cid': 'test123', 'crid': '451466393', 'site': {}}, {'cid': '8CUX0H51P', 'crid': '451466393', 'site': {}}], 'timeout': 6}] -} - -function performAuctionWithFloorConfig() { - events.emit(AUCTION_INIT, {...MOCK.AUCTION_INIT_WITH_FLOOR, adUnits: MOCK.Ad_Units}); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON); -} - -function performStandardAuctionWithWinner() { - events.emit(AUCTION_INIT, {...MOCK.AUCTION_INIT, adUnits: MOCK.Ad_Units}); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON); -} - -function performMultiFormatAuctionWithNoBid() { - events.emit(AUCTION_INIT, {...MOCK.AUCTION_INIT, adUnits: MOCK.MULTI_FORMAT_TWIN_AD_UNITS}); - events.emit(BID_REQUESTED, MOCK.MULTI_FORMAT_BID_REQUESTED); - events.emit(NO_BID, MOCK.NO_BID); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.NO_BID_SET_TARGETING); -} - -function performStandardAuctionWithNoBid() { - events.emit(AUCTION_INIT, {...MOCK.AUCTION_INIT, adUnits: MOCK.Ad_Units}); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(NO_BID, MOCK.NO_BID); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.NO_BID_SET_TARGETING); -} - -function performStandardAuctionWithTimeout() { - events.emit(AUCTION_INIT, {...MOCK.AUCTION_INIT, adUnits: MOCK.Ad_Units}); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(BID_TIMEOUT, MOCK.BID_TIMEOUT); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.NO_BID_SET_TARGETING); -} - -function getQueryData(url) { - const queryArgs = url.split('?')[1].split('&'); - return queryArgs.reduce((data, arg) => { - const [key, val] = arg.split('='); - if (data[key] !== undefined) { - if (!Array.isArray(data[key])) { - data[key] = [data[key]]; - } - data[key].push(val); - } else { - data[key] = val; - } - return data; - }, {}); -} - -describe('Media.net Analytics Adapter', function() { - let sandbox; - let CUSTOMER_ID = 'test123'; - let VALID_CONFIGURATION = { - options: { - cid: CUSTOMER_ID - } - } - beforeEach(function () { - sandbox = sinon.sandbox.create(); - }); - - afterEach(function () { - sandbox.restore(); - }); - - describe('Configuration', function() { - it('should log error if publisher id is not passed', function() { - sandbox.stub(utils, 'logError'); - - medianetAnalytics.enableAnalytics(); - expect( - utils.logError.calledWith( - 'Media.net Analytics adapter: cid is required.' - ) - ).to.be.true; - }); - - it('should not log error if valid config is passed', function() { - sandbox.stub(utils, 'logError'); - - medianetAnalytics.enableAnalytics(VALID_CONFIGURATION); - expect(utils.logError.called).to.equal(false); - medianetAnalytics.disableAnalytics(); - }); - }); - - describe('Events', function() { - beforeEach(function () { - medianetAnalytics.enableAnalytics({ - options: { - cid: 'test123' - } - }); - medianetAnalytics.clearlogsQueue(); - }); - afterEach(function () { - medianetAnalytics.clearlogsQueue(); - medianetAnalytics.disableAnalytics(); - }); - - it('should not log if only Auction Init', function() { - medianetAnalytics.clearlogsQueue(); - medianetAnalytics.track({ AUCTION_INIT }) - expect(medianetAnalytics.getlogsQueue().length).to.equal(0); - }); - - it('should have all applicable sizes in request', function() { - medianetAnalytics.clearlogsQueue(); - performMultiFormatAuctionWithNoBid(); - const noBidLog = medianetAnalytics.getlogsQueue().map((log) => getQueryData(log))[0]; - medianetAnalytics.clearlogsQueue(); - expect(noBidLog.mtype).to.have.ordered.members([encodeURIComponent('banner|native|video'), encodeURIComponent('banner|video|native')]); - expect(noBidLog.szs).to.have.ordered.members([encodeURIComponent('300x250|1x1|640x480'), encodeURIComponent('300x250|1x1|640x480')]); - expect(noBidLog.vplcmtt).to.equal('instream'); - }); - - it('should have winner log in standard auction', function() { - medianetAnalytics.clearlogsQueue(); - performStandardAuctionWithWinner(); - let winnerLog = medianetAnalytics.getlogsQueue().map((log) => getQueryData(log)).filter((log) => log.winner); - medianetAnalytics.clearlogsQueue(); - - expect(winnerLog.length).to.equal(1); - }); - - it('should have correct values in winner log', function() { - medianetAnalytics.clearlogsQueue(); - performStandardAuctionWithWinner(); - let winnerLog = medianetAnalytics.getlogsQueue().map((log) => getQueryData(log)).filter((log) => log.winner); - medianetAnalytics.clearlogsQueue(); - - expect(winnerLog[0]).to.include({ - winner: '1', - pvnm: 'medianet', - curr: 'USD', - src: 'client', - size: '300x250', - mtype: 'banner', - gdpr: '0', - cid: 'test123', - lper: '1', - ogbdp: '1.1495', - flt: '1', - supcrid: 'div-gpt-ad-1460505748561-0', - mpvid: '123', - bidflr: '1.1' - }); - }); - - it('should have correct bid floor data in winner log', function() { - medianetAnalytics.clearlogsQueue(); - performAuctionWithFloorConfig(); - let winnerLog = medianetAnalytics.getlogsQueue().map((log) => getQueryData(log)).filter((log) => log.winner); - medianetAnalytics.clearlogsQueue(); - - expect(winnerLog[0]).to.include({ - winner: '1', - curr: 'USD', - ogbdp: '1.1495', - bidflr: '1.1', - flrrule: 'banner', - flrdata: encodeURIComponent('ln=||skp=||enfj=true||enfd=||sr=||fs=') - }); - }); - - it('should have no bid status', function() { - medianetAnalytics.clearlogsQueue(); - performStandardAuctionWithNoBid(); - let noBidLog = medianetAnalytics.getlogsQueue().map((log) => getQueryData(log)); - noBidLog = noBidLog[0]; - - medianetAnalytics.clearlogsQueue(); - expect(noBidLog.pvnm).to.have.ordered.members(['-2', 'medianet']); - expect(noBidLog.iwb).to.have.ordered.members(['0', '0']); - expect(noBidLog.status).to.have.ordered.members(['1', '2']); - expect(noBidLog.src).to.have.ordered.members(['client', 'client']); - expect(noBidLog.curr).to.have.ordered.members(['', '']); - expect(noBidLog.mtype).to.have.ordered.members(['banner', 'banner']); - expect(noBidLog.ogbdp).to.have.ordered.members(['', '']); - expect(noBidLog.mpvid).to.have.ordered.members(['', '']); - expect(noBidLog.crid).to.have.ordered.members(['', '451466393']); - }); - - it('should have timeout status', function() { - medianetAnalytics.clearlogsQueue(); - performStandardAuctionWithTimeout(); - let timeoutLog = medianetAnalytics.getlogsQueue().map((log) => getQueryData(log)); - timeoutLog = timeoutLog[0]; - - medianetAnalytics.clearlogsQueue(); - expect(timeoutLog.pvnm).to.have.ordered.members(['-2', 'medianet']); - expect(timeoutLog.iwb).to.have.ordered.members(['0', '0']); - expect(timeoutLog.status).to.have.ordered.members(['1', '3']); - expect(timeoutLog.src).to.have.ordered.members(['client', 'client']); - expect(timeoutLog.curr).to.have.ordered.members(['', '']); - expect(timeoutLog.mtype).to.have.ordered.members(['banner', 'banner']); - expect(timeoutLog.ogbdp).to.have.ordered.members(['', '']); - expect(timeoutLog.mpvid).to.have.ordered.members(['', '']); - expect(timeoutLog.crid).to.have.ordered.members(['', '451466393']); - }); - }); -}); diff --git a/test/spec/modules/medianetBidAdapter_spec.js b/test/spec/modules/medianetBidAdapter_spec.js deleted file mode 100644 index 1eeb167601e..00000000000 --- a/test/spec/modules/medianetBidAdapter_spec.js +++ /dev/null @@ -1,1449 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/medianetBidAdapter.js'; -import { makeSlot } from '../integration/faker/googletag.js'; -import { config } from 'src/config.js'; - -$$PREBID_GLOBAL$$.version = $$PREBID_GLOBAL$$.version || 'version'; -let VALID_BID_REQUEST = [{ - 'bidder': 'medianet', - 'params': { - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': '277b631f-92f5-4844-8b19-ea13c095d3f1', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]], - } - }, - 'bidId': '28f8f8130a583e', - 'bidderRequestId': '1e9b1f07797c1c', - 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'bidRequestsCount': 1 - }, { - 'bidder': 'medianet', - 'params': { - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-123', - 'transactionId': 'c52a5c62-3c2b-4b90-9ff8-ec1487754822', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 251]], - } - }, - 'sizes': [[300, 251]], - 'bidId': '3f97ca71b1e5c2', - 'bidderRequestId': '1e9b1f07797c1c', - 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'bidRequestsCount': 1 - }], - - VALID_BID_REQUEST_WITH_CRID = [{ - 'bidder': 'medianet', - 'params': { - 'crid': 'crid', - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': '277b631f-92f5-4844-8b19-ea13c095d3f1', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]], - } - }, - 'bidId': '28f8f8130a583e', - 'bidderRequestId': '1e9b1f07797c1c', - 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'bidRequestsCount': 1 - }, { - 'bidder': 'medianet', - 'params': { - 'crid': 'crid', - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-123', - 'transactionId': 'c52a5c62-3c2b-4b90-9ff8-ec1487754822', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 251]], - } - }, - 'sizes': [[300, 251]], - 'bidId': '3f97ca71b1e5c2', - 'bidderRequestId': '1e9b1f07797c1c', - 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'bidRequestsCount': 1 - }], - VALID_BID_REQUEST_WITH_USERID = [{ - 'bidder': 'medianet', - 'params': { - 'crid': 'crid', - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - }, - userId: { - britepoolid: '82efd5e1-816b-4f87-97f8-044f407e2911' - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': '277b631f-92f5-4844-8b19-ea13c095d3f1', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]], - } - }, - 'bidId': '28f8f8130a583e', - 'bidderRequestId': '1e9b1f07797c1c', - 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'bidRequestsCount': 1 - }, { - 'bidder': 'medianet', - 'params': { - 'crid': 'crid', - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-123', - 'transactionId': 'c52a5c62-3c2b-4b90-9ff8-ec1487754822', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 251]], - } - }, - 'sizes': [[300, 251]], - 'bidId': '3f97ca71b1e5c2', - 'bidderRequestId': '1e9b1f07797c1c', - 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'bidRequestsCount': 1 - }], - - VALID_BID_REQUEST_INVALID_BIDFLOOR = [{ - 'bidder': 'medianet', - 'params': { - 'cid': 'customer_id', - 'bidfloor': 'abcdef', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': '277b631f-92f5-4844-8b19-ea13c095d3f1', - 'sizes': [[300, 250]], - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]], - } - }, - 'bidId': '28f8f8130a583e', - 'bidderRequestId': '1e9b1f07797c1c', - 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'bidRequestsCount': 1 - }, { - 'bidder': 'medianet', - 'params': { - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-123', - 'transactionId': 'c52a5c62-3c2b-4b90-9ff8-ec1487754822', - 'sizes': [[300, 251]], - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 251]], - } - }, - 'bidId': '3f97ca71b1e5c2', - 'bidderRequestId': '1e9b1f07797c1c', - 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'bidRequestsCount': 1 - }], - VALID_NATIVE_BID_REQUEST = [{ - 'bidder': 'medianet', - 'params': { - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': '277b631f-92f5-4844-8b19-ea13c095d3f1', - 'sizes': [[300, 250]], - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]], - } - }, - 'bidId': '28f8f8130a583e', - 'bidderRequestId': '1e9b1f07797c1c', - 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'bidRequestsCount': 1, - 'nativeParams': { - 'image': { - 'required': true, - 'sizes': [ - 150, - 50 - ], - 'wmin': 50 - }, - 'title': { - 'required': true, - 'len': 80 - }, - 'sponsoredBy': { - 'required': true - }, - 'clickUrl': { - 'required': true - }, - 'body': { - 'required': true - }, - 'icon': { - 'required': true, - 'sizes': [ - 50, - 50 - ] - } - } - }, { - 'bidder': 'medianet', - 'params': { - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-123', - 'transactionId': 'c52a5c62-3c2b-4b90-9ff8-ec1487754822', - 'sizes': [[300, 251]], - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 251]], - } - }, - 'bidId': '3f97ca71b1e5c2', - 'bidderRequestId': '1e9b1f07797c1c', - 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'bidRequestsCount': 1, - 'nativeParams': { - 'image': { - 'required': true, - 'sizes': [ - 150, - 50 - ], - 'wmin': 50 - }, - 'title': { - 'required': true, - 'len': 80 - }, - 'sponsoredBy': { - 'required': true - }, - 'clickUrl': { - 'required': true - }, - 'body': { - 'required': true - }, - 'icon': { - 'required': true, - 'sizes': [ - 50, - 50 - ] - } - } - }], - VALID_AUCTIONDATA = { - 'timeout': config.getConfig('bidderTimeout'), - 'refererInfo': { - referer: 'http://media.net/prebidtest', - stack: ['http://media.net/prebidtest'], - reachedTop: true - } - }, - VALID_PAYLOAD_INVALID_BIDFLOOR = { - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - }, - 'ext': { - 'customer_id': 'customer_id', - 'prebid_version': $$PREBID_GLOBAL$$.version, - 'gdpr_applies': false, - 'usp_applies': false, - 'coppa_applies': false, - 'screen': { - 'w': 1000, - 'h': 1000 - } - }, - 'id': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'imp': [{ - 'id': '28f8f8130a583e', - 'ext': { - 'dfp_id': 'div-gpt-ad-1460505748561-0', - 'visibility': 1, - 'viewability': 1, - 'coordinates': { - 'top_left': { - x: 50, - y: 50 - }, - 'bottom_right': { - x: 100, - y: 100 - } - }, - 'display_count': 1 - }, - 'banner': [{ - 'w': 300, - 'h': 250 - }], - 'all': { - 'cid': 'customer_id', - 'bidfloor': 'abcdef', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - } - }, { - 'id': '3f97ca71b1e5c2', - 'ext': { - 'dfp_id': 'div-gpt-ad-1460505748561-123', - 'visibility': 1, - 'viewability': 1, - 'coordinates': { - 'top_left': { - x: 50, - y: 50 - }, - 'bottom_right': { - x: 100, - y: 100 - } - }, - 'display_count': 1 - }, - 'banner': [{ - 'w': 300, - 'h': 251 - }], - 'all': { - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - } - }], - 'tmax': config.getConfig('bidderTimeout') - }, - VALID_PAYLOAD_NATIVE = { - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - }, - 'ext': { - 'customer_id': 'customer_id', - 'prebid_version': $$PREBID_GLOBAL$$.version, - 'gdpr_applies': false, - 'usp_applies': false, - 'coppa_applies': false, - 'screen': { - 'w': 1000, - 'h': 1000 - } - }, - 'id': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'imp': [{ - 'id': '28f8f8130a583e', - 'ext': { - 'dfp_id': 'div-gpt-ad-1460505748561-0', - 'visibility': 1, - 'viewability': 1, - 'coordinates': { - 'top_left': { - x: 50, - y: 50 - }, - 'bottom_right': { - x: 100, - y: 100 - } - }, - 'display_count': 1 - }, - 'banner': [{ - 'w': 300, - 'h': 250 - }], - 'native': '{\"image\":{\"required\":true,\"sizes\":[150,50],\"wmin\":50},\"title\":{\"required\":true,\"len\":80},\"sponsoredBy\":{\"required\":true},\"clickUrl\":{\"required\":true},\"body\":{\"required\":true},\"icon\":{\"required\":true,\"sizes\":[50,50]}}', - 'all': { - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - } - }, { - 'id': '3f97ca71b1e5c2', - 'ext': { - 'dfp_id': 'div-gpt-ad-1460505748561-123', - 'visibility': 1, - 'viewability': 1, - 'coordinates': { - 'top_left': { - x: 50, - y: 50 - }, - 'bottom_right': { - x: 100, - y: 100 - } - }, - 'display_count': 1 - }, - 'banner': [{ - 'w': 300, - 'h': 251 - }], - 'native': '{\"image\":{\"required\":true,\"sizes\":[150,50],\"wmin\":50},\"title\":{\"required\":true,\"len\":80},\"sponsoredBy\":{\"required\":true},\"clickUrl\":{\"required\":true},\"body\":{\"required\":true},\"icon\":{\"required\":true,\"sizes\":[50,50]}}', - 'all': { - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - } - }], - 'tmax': config.getConfig('bidderTimeout') - }, - VALID_PAYLOAD = { - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - }, - 'ext': { - 'customer_id': 'customer_id', - 'prebid_version': $$PREBID_GLOBAL$$.version, - 'gdpr_applies': false, - 'usp_applies': false, - 'coppa_applies': false, - 'screen': { - 'w': 1000, - 'h': 1000 - } - }, - 'id': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'imp': [{ - 'id': '28f8f8130a583e', - 'ext': { - 'dfp_id': 'div-gpt-ad-1460505748561-0', - 'visibility': 1, - 'viewability': 1, - 'coordinates': { - 'top_left': { - x: 50, - y: 50 - }, - 'bottom_right': { - x: 100, - y: 100 - } - }, - 'display_count': 1 - }, - 'banner': [{ - 'w': 300, - 'h': 250 - }], - 'all': { - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - } - }, { - 'id': '3f97ca71b1e5c2', - 'ext': { - 'dfp_id': 'div-gpt-ad-1460505748561-123', - 'visibility': 1, - 'viewability': 1, - 'coordinates': { - 'top_left': { - x: 50, - y: 50 - }, - 'bottom_right': { - x: 100, - y: 100 - } - }, - 'display_count': 1 - }, - 'banner': [{ - 'w': 300, - 'h': 251 - }], - 'all': { - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - } - }], - 'tmax': config.getConfig('bidderTimeout') - }, - VALID_PAYLOAD_WITH_USERID = { - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - }, - 'ext': { - 'customer_id': 'customer_id', - 'prebid_version': $$PREBID_GLOBAL$$.version, - 'gdpr_applies': false, - 'user_id': { - britepoolid: '82efd5e1-816b-4f87-97f8-044f407e2911' - }, - 'usp_applies': false, - 'coppa_applies': false, - 'screen': { - 'w': 1000, - 'h': 1000 - } - }, - 'id': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'imp': [{ - 'id': '28f8f8130a583e', - 'tagid': 'crid', - 'ext': { - 'dfp_id': 'div-gpt-ad-1460505748561-0', - 'visibility': 1, - 'viewability': 1, - 'coordinates': { - 'top_left': { - x: 50, - y: 50 - }, - 'bottom_right': { - x: 100, - y: 100 - } - }, - 'display_count': 1 - }, - 'banner': [{ - 'w': 300, - 'h': 250 - }], - 'all': { - 'cid': 'customer_id', - 'crid': 'crid', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - } - }, { - 'id': '3f97ca71b1e5c2', - 'tagid': 'crid', - 'ext': { - 'dfp_id': 'div-gpt-ad-1460505748561-123', - 'visibility': 1, - 'viewability': 1, - 'coordinates': { - 'top_left': { - x: 50, - y: 50 - }, - 'bottom_right': { - x: 100, - y: 100 - } - }, - 'display_count': 1 - }, - 'banner': [{ - 'w': 300, - 'h': 251 - }], - 'all': { - 'cid': 'customer_id', - 'crid': 'crid', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - } - }], - 'tmax': config.getConfig('bidderTimeout') - }, - VALID_PAYLOAD_WITH_CRID = { - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - }, - 'ext': { - 'customer_id': 'customer_id', - 'prebid_version': $$PREBID_GLOBAL$$.version, - 'gdpr_applies': false, - 'usp_applies': false, - 'coppa_applies': true, - 'screen': { - 'w': 1000, - 'h': 1000 - } - }, - 'id': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'imp': [{ - 'id': '28f8f8130a583e', - 'tagid': 'crid', - 'ext': { - 'dfp_id': 'div-gpt-ad-1460505748561-0', - 'visibility': 1, - 'viewability': 1, - 'coordinates': { - 'top_left': { - x: 50, - y: 50 - }, - 'bottom_right': { - x: 100, - y: 100 - } - }, - 'display_count': 1 - }, - 'banner': [{ - 'w': 300, - 'h': 250 - }], - 'all': { - 'cid': 'customer_id', - 'crid': 'crid', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - } - }, { - 'id': '3f97ca71b1e5c2', - 'tagid': 'crid', - 'ext': { - 'dfp_id': 'div-gpt-ad-1460505748561-123', - 'visibility': 1, - 'viewability': 1, - 'coordinates': { - 'top_left': { - x: 50, - y: 50 - }, - 'bottom_right': { - x: 100, - y: 100 - } - }, - 'display_count': 1 - }, - 'banner': [{ - 'w': 300, - 'h': 251 - }], - 'all': { - 'cid': 'customer_id', - 'crid': 'crid', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - } - }], - 'tmax': config.getConfig('bidderTimeout') - }, - - VALID_VIDEO_BID_REQUEST = [{ - 'bidder': 'medianet', - 'params': { - 'cid': 'customer_id', - 'video': { - 'skipppable': true - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': '277b631f-92f5-4844-8b19-ea13c095d3f1', - 'mediaTypes': { - 'video': { - 'context': 'instream', - } - }, - 'bidId': '28f8f8130a583e', - 'bidderRequestId': '1e9b1f07797c1c', - 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'bidRequestsCount': 1 - }], - - VALID_PAYLOAD_PAGE_META = (() => { - let PAGE_META; - try { - PAGE_META = JSON.parse(JSON.stringify(VALID_PAYLOAD)); - } catch (e) {} - PAGE_META.site = Object.assign(PAGE_META.site, { - 'canonical_url': 'http://localhost:9999/canonical-test', - 'twitter_url': 'http://localhost:9999/twitter-test', - 'og_url': 'http://localhost:9999/fb-test' - }); - return PAGE_META; - })(), - VALID_PARAMS = { - bidder: 'medianet', - params: { - cid: '8CUV090' - } - }, - PARAMS_MISSING = { - bidder: 'medianet', - }, - PARAMS_WITHOUT_CID = { - bidder: 'medianet', - params: {} - }, - PARAMS_WITH_INTEGER_CID = { - bidder: 'medianet', - params: { - cid: 8867587 - } - }, - PARAMS_WITH_EMPTY_CID = { - bidder: 'medianet', - params: { - cid: '' - } - }, - SYNC_OPTIONS_BOTH_ENABLED = { - iframeEnabled: true, - pixelEnabled: true, - }, - SYNC_OPTIONS_PIXEL_ENABLED = { - iframeEnabled: false, - pixelEnabled: true, - }, - SYNC_OPTIONS_IFRAME_ENABLED = { - iframeEnabled: true, - pixelEnabled: false, - }, - SERVER_CSYNC_RESPONSE = [{ - body: { - ext: { - csUrl: [{ - type: 'iframe', - url: 'iframe-url' - }, { - type: 'image', - url: 'pixel-url' - }] - } - } - }], - ENABLED_SYNC_IFRAME = [{ - type: 'iframe', - url: 'iframe-url' - }], - ENABLED_SYNC_PIXEL = [{ - type: 'image', - url: 'pixel-url' - }], - SERVER_RESPONSE_CPM_MISSING = { - body: { - 'id': 'd90ca32f-3877-424a-b2f2-6a68988df57a', - 'bidList': [{ - 'no_bid': false, - 'requestId': '27210feac00e96', - 'ad': 'ad', - 'width': 300, - 'height': 250, - 'creativeId': '375068987', - 'netRevenue': true - }], - 'ext': { - 'csUrl': [{ - 'type': 'image', - 'url': 'http://cs.media.net/cksync.php' - }, { - 'type': 'iframe', - 'url': 'http://contextual.media.net/checksync.php?&vsSync=1' - }] - } - } - }, - SERVER_RESPONSE_CPM_ZERO = { - body: { - 'id': 'd90ca32f-3877-424a-b2f2-6a68988df57a', - 'bidList': [{ - 'no_bid': false, - 'requestId': '27210feac00e96', - 'ad': 'ad', - 'width': 300, - 'height': 250, - 'creativeId': '375068987', - 'netRevenue': true, - 'cpm': 0.0 - }], - 'ext': { - 'csUrl': [{ - 'type': 'image', - 'url': 'http://cs.media.net/cksync.php' - }, { - 'type': 'iframe', - 'url': 'http://contextual.media.net/checksync.php?&vsSync=1' - }] - } - } - }, - SERVER_RESPONSE_NOBID = { - body: { - 'id': 'd90ca32f-3877-424a-b2f2-6a68988df57a', - 'bidList': [{ - 'no_bid': true, - 'requestId': '3a62cf7a853f84', - 'width': 0, - 'height': 0, - 'ttl': 0, - 'netRevenue': false - }], - 'ext': { - 'csUrl': [{ - 'type': 'image', - 'url': 'http://cs.media.net/cksync.php' - }, { - 'type': 'iframe', - 'url': 'http://contextual.media.net/checksync.php?&vsSync=1' - }] - } - } - }, - SERVER_RESPONSE_NOBODY = { - - }, - SERVER_RESPONSE_EMPTY_BIDLIST = { - body: { - 'id': 'd90ca32f-3877-424a-b2f2-6a68988df57a', - 'bidList': 'bid', - 'ext': { - 'csUrl': [{ - 'type': 'image', - 'url': 'http://cs.media.net/cksync.php' - }, { - 'type': 'iframe', - 'url': 'http://contextual.media.net/checksync.php?&vsSync=1' - }] - } - } - - }, - SERVER_RESPONSE_VALID_BID = { - body: { - 'id': 'd90ca32f-3877-424a-b2f2-6a68988df57a', - 'bidList': [{ - 'no_bid': false, - 'requestId': '27210feac00e96', - 'ad': 'ad', - 'width': 300, - 'height': 250, - 'creativeId': '375068987', - 'netRevenue': true, - 'cpm': 0.1 - }], - 'ext': { - 'csUrl': [{ - 'type': 'image', - 'url': 'http://cs.media.net/cksync.php' - }, { - 'type': 'iframe', - 'url': 'http://contextual.media.net/checksync.php?&vsSync=1' - }] - } - } - }, - SERVER_VIDEO_OUTSTREAM_RESPONSE_VALID_BID = { - body: { - 'id': 'd90ca32f-3877-424a-b2f2-6a68988df57a', - 'bidList': [{ - 'no_bid': false, - 'requestId': '27210feac00e96', - 'cpm': 12.00, - 'width': 640, - 'height': 480, - 'ttl': 180, - 'creativeId': '370637746', - 'netRevenue': true, - 'vastXml': '', - 'currency': 'USD', - 'dfp_id': 'video1', - 'mediaType': 'video', - 'vto': 5000, - 'mavtr': 10, - 'avp': true, - 'ap': true, - 'pl': true, - 'mt': true, - 'jslt': 3000, - 'context': 'outstream' - }], - 'ext': { - 'csUrl': [{ - 'type': 'image', - 'url': 'http://cs.media.net/cksync.php' - }, { - 'type': 'iframe', - 'url': 'http://contextual.media.net/checksync.php?&vsSync=1' - }] - } - } - }, - SERVER_VALID_BIDS = [{ - 'no_bid': false, - 'requestId': '27210feac00e96', - 'ad': 'ad', - 'width': 300, - 'height': 250, - 'creativeId': '375068987', - 'netRevenue': true, - 'cpm': 0.1 - }], - BID_REQUEST_SIZE_AS_1DARRAY = [{ - 'bidder': 'medianet', - 'params': { - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': '277b631f-92f5-4844-8b19-ea13c095d3f1', - 'sizes': [300, 250], - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]], - } - }, - 'bidId': '28f8f8130a583e', - 'bidderRequestId': '1e9b1f07797c1c', - 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'bidRequestsCount': 1 - }, { - 'bidder': 'medianet', - 'params': { - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-123', - 'transactionId': 'c52a5c62-3c2b-4b90-9ff8-ec1487754822', - 'sizes': [300, 251], - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 251]], - } - }, - 'bidId': '3f97ca71b1e5c2', - 'bidderRequestId': '1e9b1f07797c1c', - 'auctionId': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'bidRequestsCount': 1 - }], - VALID_BIDDER_REQUEST_WITH_GDPR = { - 'gdprConsent': { - 'consentString': 'consentString', - 'gdprApplies': true, - }, - 'uspConsent': '1NYN', - 'timeout': 3000, - refererInfo: { - referer: 'http://media.net/prebidtest', - stack: ['http://media.net/prebidtest'], - reachedTop: true - } - }, - VALID_PAYLOAD_FOR_GDPR = { - 'site': { - 'domain': 'media.net', - 'page': 'http://media.net/prebidtest', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - - }, - 'ext': { - 'customer_id': 'customer_id', - 'prebid_version': $$PREBID_GLOBAL$$.version, - 'gdpr_consent_string': 'consentString', - 'gdpr_applies': true, - 'usp_applies': true, - 'coppa_applies': false, - 'usp_consent_string': '1NYN', - 'screen': { - 'w': 1000, - 'h': 1000 - } - }, - 'id': 'aafabfd0-28c0-4ac0-aa09-99689e88b81d', - 'imp': [{ - 'id': '28f8f8130a583e', - 'ext': { - 'dfp_id': 'div-gpt-ad-1460505748561-0', - 'visibility': 1, - 'viewability': 1, - 'coordinates': { - 'top_left': { - x: 50, - y: 50 - }, - 'bottom_right': { - x: 100, - y: 100 - } - }, - 'display_count': 1 - }, - 'banner': [{ - 'w': 300, - 'h': 250 - }], - 'all': { - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - } - }, { - 'id': '3f97ca71b1e5c2', - 'ext': { - 'dfp_id': 'div-gpt-ad-1460505748561-123', - 'visibility': 1, - 'viewability': 1, - 'coordinates': { - 'top_left': { - x: 50, - y: 50 - }, - 'bottom_right': { - x: 100, - y: 100 - } - }, - 'display_count': 1 - }, - 'banner': [{ - 'w': 300, - 'h': 251 - }], - 'all': { - 'cid': 'customer_id', - 'site': { - 'page': 'http://media.net/prebidtest', - 'domain': 'media.net', - 'ref': 'http://media.net/prebidtest', - 'isTop': true - } - } - }], - 'tmax': 3000, - }; -describe('Media.net bid adapter', function () { - let sandbox; - beforeEach(function () { - sandbox = sinon.sandbox.create(); - }); - - afterEach(function () { - sandbox.restore(); - }); - - describe('isBidRequestValid', function () { - it('should accept valid bid params', function () { - let isValid = spec.isBidRequestValid(VALID_PARAMS); - expect(isValid).to.equal(true); - }); - - it('should reject bid if cid is not present', function () { - let isValid = spec.isBidRequestValid(PARAMS_WITHOUT_CID); - expect(isValid).to.equal(false); - }); - - it('should reject bid if cid is not a string', function () { - let isValid = spec.isBidRequestValid(PARAMS_WITH_INTEGER_CID); - expect(isValid).to.equal(false); - }); - - it('should reject bid if cid is a empty string', function () { - let isValid = spec.isBidRequestValid(PARAMS_WITH_EMPTY_CID); - expect(isValid).to.equal(false); - }); - - it('should have missing params', function () { - let isValid = spec.isBidRequestValid(PARAMS_MISSING); - expect(isValid).to.equal(false); - }); - }); - - describe('buildRequests', function () { - beforeEach(function () { - $$PREBID_GLOBAL$$.medianetGlobals = {}; - - let documentStub = sandbox.stub(document, 'getElementById'); - let boundingRect = { - top: 50, - left: 50, - bottom: 100, - right: 100 - }; - documentStub.withArgs('div-gpt-ad-1460505748561-123').returns({ - getBoundingClientRect: () => boundingRect - }); - documentStub.withArgs('div-gpt-ad-1460505748561-0').returns({ - getBoundingClientRect: () => boundingRect - }); - let windowSizeStub = sandbox.stub(spec, 'getWindowSize'); - windowSizeStub.returns({ - w: 1000, - h: 1000 - }); - }); - - it('should build valid payload on bid', function () { - let requestObj = spec.buildRequests(VALID_BID_REQUEST, VALID_AUCTIONDATA); - expect(JSON.parse(requestObj.data)).to.deep.equal(VALID_PAYLOAD); - }); - - it('should accept size as a one dimensional array', function () { - let bidReq = spec.buildRequests(BID_REQUEST_SIZE_AS_1DARRAY, VALID_AUCTIONDATA); - expect(JSON.parse(bidReq.data)).to.deep.equal(VALID_PAYLOAD); - }); - - it('should ignore bidfloor if not a valid number', function () { - let bidReq = spec.buildRequests(VALID_BID_REQUEST_INVALID_BIDFLOOR, VALID_AUCTIONDATA); - expect(JSON.parse(bidReq.data)).to.deep.equal(VALID_PAYLOAD_INVALID_BIDFLOOR); - }); - - it('should add gdpr to response ext', function () { - let bidReq = spec.buildRequests(VALID_BID_REQUEST, VALID_BIDDER_REQUEST_WITH_GDPR); - expect(JSON.parse(bidReq.data)).to.deep.equal(VALID_PAYLOAD_FOR_GDPR); - }); - - it('should parse params for native request', function () { - let bidReq = spec.buildRequests(VALID_NATIVE_BID_REQUEST, VALID_AUCTIONDATA); - expect(JSON.parse(bidReq.data)).to.deep.equal(VALID_PAYLOAD_NATIVE); - }); - - it('should parse params for video request', function () { - let bidReq = spec.buildRequests(VALID_VIDEO_BID_REQUEST, VALID_AUCTIONDATA); - expect(JSON.stringify(bidReq.data)).to.include('instream'); - }); - - it('should have valid crid present in bid request', function() { - sandbox.stub(config, 'getConfig').callsFake((key) => { - const config = { - 'coppa': true - }; - return config[key]; - }); - let bidreq = spec.buildRequests(VALID_BID_REQUEST_WITH_CRID, VALID_AUCTIONDATA); - expect(JSON.parse(bidreq.data)).to.deep.equal(VALID_PAYLOAD_WITH_CRID); - }); - - it('should have userid in bid request', function () { - let bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_USERID, VALID_AUCTIONDATA); - expect(JSON.parse(bidReq.data)).to.deep.equal(VALID_PAYLOAD_WITH_USERID); - }); - - describe('build requests: when page meta-data is available', () => { - beforeEach(() => { - spec.clearMnData(); - }); - it('should pass canonical, twitter and fb paramters if available', () => { - let documentStub = sandbox.stub(window.top.document, 'querySelector'); - documentStub.withArgs('link[rel="canonical"]').returns({ - href: 'http://localhost:9999/canonical-test' - }); - documentStub.withArgs('meta[property="og:url"]').returns({ - content: 'http://localhost:9999/fb-test' - }); - documentStub.withArgs('meta[name="twitter:url"]').returns({ - content: 'http://localhost:9999/twitter-test' - }); - let bidReq = spec.buildRequests(VALID_BID_REQUEST, VALID_AUCTIONDATA); - expect(JSON.parse(bidReq.data)).to.deep.equal(VALID_PAYLOAD_PAGE_META); - }); - }); - }); - - describe('slot visibility', function () { - let documentStub; - beforeEach(function () { - let windowSizeStub = sandbox.stub(spec, 'getWindowSize'); - windowSizeStub.returns({ - w: 1000, - h: 1000 - }); - documentStub = sandbox.stub(document, 'getElementById'); - }); - it('slot visibility should be 2 and ratio 0 when ad unit is BTF', function () { - let boundingRect = { - top: 1010, - left: 1010, - bottom: 1050, - right: 1050 - }; - documentStub.withArgs('div-gpt-ad-1460505748561-123').returns({ - getBoundingClientRect: () => boundingRect - }); - documentStub.withArgs('div-gpt-ad-1460505748561-0').returns({ - getBoundingClientRect: () => boundingRect - }); - - let bidReq = spec.buildRequests(VALID_BID_REQUEST, VALID_AUCTIONDATA); - let data = JSON.parse(bidReq.data); - expect(data.imp[0].ext.visibility).to.equal(2); - expect(data.imp[0].ext.viewability).to.equal(0); - }); - it('slot visibility should be 2 and ratio < 0.5 when ad unit is partially inside viewport', function () { - let boundingRect = { - top: 990, - left: 990, - bottom: 1050, - right: 1050 - }; - documentStub.withArgs('div-gpt-ad-1460505748561-123').returns({ - getBoundingClientRect: () => boundingRect - }); - documentStub.withArgs('div-gpt-ad-1460505748561-0').returns({ - getBoundingClientRect: () => boundingRect - }); - let bidReq = spec.buildRequests(VALID_BID_REQUEST, VALID_AUCTIONDATA); - let data = JSON.parse(bidReq.data); - expect(data.imp[0].ext.visibility).to.equal(2); - expect(data.imp[0].ext.viewability).to.equal(100 / 75000); - }); - it('slot visibility should be 1 and ratio > 0.5 when ad unit mostly in viewport', function () { - let boundingRect = { - top: 800, - left: 800, - bottom: 1050, - right: 1050 - }; - documentStub.withArgs('div-gpt-ad-1460505748561-123').returns({ - getBoundingClientRect: () => boundingRect - }); - documentStub.withArgs('div-gpt-ad-1460505748561-0').returns({ - getBoundingClientRect: () => boundingRect - }); - let bidReq = spec.buildRequests(VALID_BID_REQUEST, VALID_AUCTIONDATA); - let data = JSON.parse(bidReq.data); - expect(data.imp[0].ext.visibility).to.equal(1); - expect(data.imp[0].ext.viewability).to.equal(40000 / 75000); - }); - it('co-ordinates should not be sent and slot visibility should be 0 when ad unit is not present', function () { - let bidReq = spec.buildRequests(VALID_BID_REQUEST, VALID_AUCTIONDATA); - let data = JSON.parse(bidReq.data); - expect(data.imp[1].ext).to.not.have.ownPropertyDescriptor('viewability'); - expect(data.imp[1].ext.visibility).to.equal(0); - }); - it('slot visibility should be calculable even in case of adUnitPath', function () { - const code = '/19968336/header-bid-tag-0'; - const divId = 'div-gpt-ad-1460505748561-0'; - window.googletag.pubads().setSlots([makeSlot({ code, divId })]); - - let boundingRect = { - top: 1010, - left: 1010, - bottom: 1050, - right: 1050 - }; - documentStub.withArgs(divId).returns({ - getBoundingClientRect: () => boundingRect - }); - documentStub.withArgs('div-gpt-ad-1460505748561-123').returns({ - getBoundingClientRect: () => boundingRect - }); - - 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); - expect(data.imp[0].ext.viewability).to.equal(0); - }); - }); - - describe('getUserSyncs', function () { - it('should exclude iframe syncs if iframe is disabled', function () { - let userSyncs = spec.getUserSyncs(SYNC_OPTIONS_PIXEL_ENABLED, SERVER_CSYNC_RESPONSE); - expect(userSyncs).to.deep.equal(ENABLED_SYNC_PIXEL); - }); - - it('should exclude pixel syncs if pixel is disabled', function () { - let userSyncs = spec.getUserSyncs(SYNC_OPTIONS_IFRAME_ENABLED, SERVER_CSYNC_RESPONSE); - expect(userSyncs).to.deep.equal(ENABLED_SYNC_IFRAME); - }); - - it('should choose iframe sync urls if both sync options are enabled', function () { - let userSyncs = spec.getUserSyncs(SYNC_OPTIONS_BOTH_ENABLED, SERVER_CSYNC_RESPONSE); - expect(userSyncs).to.deep.equal(ENABLED_SYNC_IFRAME); - }); - - it('should have empty user sync array', function() { - let userSyncs = spec.getUserSyncs(SYNC_OPTIONS_IFRAME_ENABLED, {}); - expect(userSyncs).to.deep.equal([]); - }); - }); - - describe('interpretResponse', function () { - it('should not push bid response if cpm missing', function () { - let validBids = []; - let bids = spec.interpretResponse(SERVER_RESPONSE_CPM_MISSING, []); - expect(bids).to.deep.equal(validBids); - }); - - it('should not push bid response if cpm 0', function () { - let validBids = []; - let bids = spec.interpretResponse(SERVER_RESPONSE_CPM_ZERO, []); - expect(bids).to.deep.equal(validBids); - }); - - it('should not push response if no-bid', function () { - let validBids = []; - let bids = spec.interpretResponse(SERVER_RESPONSE_NOBID, []); - expect(bids).to.deep.equal(validBids); - }); - - it('should have empty bid response', function() { - let bids = spec.interpretResponse(SERVER_RESPONSE_NOBODY, []); - expect(bids).to.deep.equal([]); - }); - - it('should have valid bids', function () { - let bids = spec.interpretResponse(SERVER_RESPONSE_VALID_BID, []); - expect(bids).to.deep.equal(SERVER_VALID_BIDS); - }); - - it('should have empty bid list', function() { - let validBids = []; - let bids = spec.interpretResponse(SERVER_RESPONSE_EMPTY_BIDLIST, []); - expect(bids).to.deep.equal(validBids); - }); - }); - - describe('onTimeout', function () { - it('should have valid timeout data', function() { - let response = spec.onTimeout({}); - expect(response).to.deep.equal(undefined); - }); - }); - - describe('onBidWon', function () { - it('should have valid bid data', function() { - let response = spec.onBidWon(undefined); - expect(response).to.deep.equal(undefined); - }); - }); - - it('context should be outstream', function () { - let bids = spec.interpretResponse(SERVER_VIDEO_OUTSTREAM_RESPONSE_VALID_BID, []); - expect(bids[0].context).to.equal('outstream'); - }); -}); diff --git a/test/spec/modules/mediasquareBidAdapter_spec.js b/test/spec/modules/mediasquareBidAdapter_spec.js deleted file mode 100644 index 796be3420e8..00000000000 --- a/test/spec/modules/mediasquareBidAdapter_spec.js +++ /dev/null @@ -1,197 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/mediasquareBidAdapter.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/consentManagement.js'; - -describe('MediaSquare bid adapter tests', function () { - var DEFAULT_PARAMS = [{ - adUnitCode: 'banner-div', - bidId: 'aaaa1234', - auctionId: 'bbbb1234', - transactionId: 'cccc1234', - mediaTypes: { - banner: { - sizes: [ - [300, 250] - ] - } - }, - bidder: 'mediasquare', - params: { - owner: 'test', - code: 'publishername_atf_desktop_rg_pave' - }, - }]; - var VIDEO_PARAMS = [{ - adUnitCode: 'banner-div', - bidId: 'aaaa1234', - auctionId: 'bbbb1234', - transactionId: 'cccc1234', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480], - mimes: ['video/mp4'], - } - }, - bidder: 'mediasquare', - params: { - owner: 'test', - code: 'publishername_atf_desktop_rg_pave' - }, - }]; - var NATIVE_PARAMS = [{ - adUnitCode: 'banner-div', - bidId: 'aaaa1234', - auctionId: 'bbbb1234', - transactionId: 'cccc1234', - mediaTypes: { - native: { - title: { - required: true, - len: 80 - }, - } - }, - bidder: 'mediasquare', - params: { - owner: 'test', - code: 'publishername_atf_desktop_rg_pave' - }, - }]; - - var BID_RESPONSE = {'body': { - 'responses': [{ - 'transaction_id': 'cccc1234', - 'cpm': 22.256608, - 'width': 300, - 'height': 250, - 'creative_id': '158534630', - 'currency': 'USD', - 'net_revenue': true, - 'ttl': 300, - 'ad': '< --- creative code --- >', - 'bidder': 'msqClassic', - 'code': 'test/publishername_atf_desktop_rg_pave', - 'bid_id': 'aaaa1234', - }], - }}; - - 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: '111222333', - 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('Verify build request', function () { - const request = spec.buildRequests(DEFAULT_PARAMS, DEFAULT_OPTIONS); - expect(request).to.have.property('url').and.to.equal('https://pbs-front.mediasquare.fr/msq_prebid'); - expect(request).to.have.property('method').and.to.equal('POST'); - const requestContent = JSON.parse(request.data); - expect(requestContent.codes[0]).to.have.property('owner').and.to.equal('test'); - expect(requestContent.codes[0]).to.have.property('code').and.to.equal('publishername_atf_desktop_rg_pave'); - expect(requestContent.codes[0]).to.have.property('adunit').and.to.equal('banner-div'); - expect(requestContent.codes[0]).to.have.property('bidId').and.to.equal('aaaa1234'); - expect(requestContent.codes[0]).to.have.property('auctionId').and.to.equal('bbbb1234'); - expect(requestContent.codes[0]).to.have.property('transactionId').and.to.equal('cccc1234'); - expect(requestContent.codes[0]).to.have.property('mediatypes').exist; - }); - - it('Verify parse response', function () { - const request = spec.buildRequests(DEFAULT_PARAMS, DEFAULT_OPTIONS); - const response = spec.interpretResponse(BID_RESPONSE, request); - expect(response).to.have.lengthOf(1); - const bid = response[0]; - expect(bid.cpm).to.equal(22.256608); - expect(bid.ad).to.equal('< --- creative code --- >'); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.creativeId).to.equal('158534630'); - expect(bid.currency).to.equal('USD'); - expect(bid.netRevenue).to.equal(true); - expect(bid.ttl).to.equal(300); - expect(bid.requestId).to.equal('aaaa1234'); - expect(bid.mediasquare).to.exist; - expect(bid.mediasquare.bidder).to.equal('msqClassic'); - expect(bid.mediasquare.code).to.equal([DEFAULT_PARAMS[0].params.owner, DEFAULT_PARAMS[0].params.code].join('/')); - }); - - it('Verifies bidder code', function () { - expect(spec.code).to.equal('mediasquare'); - }); - - it('Verifies bidder aliases', function () { - expect(spec.aliases).to.have.lengthOf(1); - expect(spec.aliases[0]).to.equal('msq'); - }); - it('Verifies if bid request valid', function () { - expect(spec.isBidRequestValid(DEFAULT_PARAMS[0])).to.equal(true); - }); - it('Verifies bid won', function () { - const request = spec.buildRequests(DEFAULT_PARAMS, DEFAULT_OPTIONS); - const response = spec.interpretResponse(BID_RESPONSE, request); - const won = spec.onBidWon(response[0]); - expect(won).to.equal(true); - }); - it('Verifies user sync without cookie in bid response', function () { - var syncs = spec.getUserSyncs({}, [BID_RESPONSE], DEFAULT_OPTIONS.gdprConsent, DEFAULT_OPTIONS.uspConsent); - expect(syncs).to.have.property('type').and.to.equal('iframe'); - }); - it('Verifies user sync with cookies in bid response', function () { - 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'); - expect(syncs[0]).to.have.property('url').and.to.equal('http://www.cookie.sync.org/'); - }); - it('Verifies user sync with no bid response', function() { - var syncs = spec.getUserSyncs({}, null, DEFAULT_OPTIONS.gdprConsent, DEFAULT_OPTIONS.uspConsent); - expect(syncs).to.have.property('type').and.to.equal('iframe'); - }); - it('Verifies user sync with no bid body response', function() { - var syncs = spec.getUserSyncs({}, [], DEFAULT_OPTIONS.gdprConsent, DEFAULT_OPTIONS.uspConsent); - expect(syncs).to.have.property('type').and.to.equal('iframe'); - var syncs = spec.getUserSyncs({}, [{}], DEFAULT_OPTIONS.gdprConsent, DEFAULT_OPTIONS.uspConsent); - expect(syncs).to.have.property('type').and.to.equal('iframe'); - }); - it('Verifies native in bid response', function () { - const request = spec.buildRequests(NATIVE_PARAMS, DEFAULT_OPTIONS); - 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]; - expect(bid).to.have.property('native'); - delete BID_RESPONSE.body.responses[0].native; - }); - 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'}; - const response = spec.interpretResponse(BID_RESPONSE, request); - expect(response).to.have.lengthOf(1); - const bid = response[0]; - expect(bid).to.have.property('vastXml'); - expect(bid).to.have.property('vastUrl'); - delete BID_RESPONSE.body.responses[0].video; - }); -}); diff --git a/test/spec/modules/mgidBidAdapter_spec.js b/test/spec/modules/mgidBidAdapter_spec.js deleted file mode 100644 index 16f4f0b4607..00000000000 --- a/test/spec/modules/mgidBidAdapter_spec.js +++ /dev/null @@ -1,702 +0,0 @@ -import {assert, expect} from 'chai'; -import {spec} from 'modules/mgidBidAdapter.js'; -import * as utils from '../../../src/utils.js'; - -describe('Mgid bid adapter', function () { - let sandbox; - let logErrorSpy; - let logWarnSpy; - beforeEach(function () { - sandbox = sinon.sandbox.create(); - logErrorSpy = sinon.spy(utils, 'logError'); - logWarnSpy = sinon.spy(utils, 'logWarn'); - }); - - afterEach(function () { - sandbox.restore(); - utils.logError.restore(); - utils.logWarn.restore(); - }); - const ua = navigator.userAgent; - const screenHeight = screen.height; - const screenWidth = screen.width; - const dnt = (navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0; - const language = navigator.language ? 'language' : 'userLanguage'; - let lang = navigator[language].split('-')[0]; - if (lang.length != 2 && lang.length != 3) { - lang = ''; - } - const secure = window.location.protocol === 'https:' ? 1 : 0; - const mgid_ver = spec.VERSION; - const prebid_ver = $$PREBID_GLOBAL$$.version; - const utcOffset = (new Date()).getTimezoneOffset().toString(); - - describe('isBidRequestValid', function () { - let bid = { - 'adUnitCode': 'div', - 'bidder': 'mgid', - 'params': { - 'property': '10433394', - 'zone': 'zone' - }, - }; - - it('should not accept bid without required params', function () { - let isValid = spec.isBidRequestValid(bid); - expect(isValid).to.equal(false); - }); - - it('should return false when params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when valid params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {accountId: '', placementId: ''}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when valid params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.adUnitCode = ''; - bid.mediaTypes = { - banner: { - sizes: [[300, 250]] - } - }; - bid.params = {accountId: 2, placementId: 1}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when adUnitCode not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.adUnitCode = ''; - bid.mediaTypes = { - banner: { - sizes: [[300, 250]] - } - }; - bid.params = {accountId: 2, placementId: 1}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return true when valid params are passed as nums', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.adUnitCode = 'div'; - bid.mediaTypes = { - banner: { - sizes: [[300, 250]] - } - }; - bid.params = {accountId: 2, placementId: 1}; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when valid params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.mediaTypes = { - native: { - sizes: [[300, 250]] - } - }; - bid.params = {accountId: '0', placementId: '00'}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when valid mediaTypes are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - 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 () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {accountId: '1', placementId: '1'}; - bid.mediaTypes = { - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when valid mediaTypes.banner.sizes are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {accountId: '1', placementId: '1'}; - bid.mediaTypes = { - sizes: [] - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when valid mediaTypes.banner.sizes are not valid', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {accountId: '1', placementId: '1'}; - bid.mediaTypes = { - sizes: [300, 250] - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return true when valid params are passed as strings', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.adUnitCode = 'div'; - bid.params = {accountId: '1', placementId: '1'}; - bid.mediaTypes = { - banner: { - sizes: [[300, 250]] - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when valid mediaTypes.native is not object', function () { - let bid = Object.assign({}, bid); - bid.params = {accountId: '1', placementId: '1'}; - bid.mediaTypes = { - native: [] - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when mediaTypes.native is empty object', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {accountId: '1', placementId: '1'}; - bid.mediaTypes = { - native: {} - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when mediaTypes.native is invalid object', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {accountId: '1', placementId: '1'}; - bid.mediaTypes = { - native: { - image: { - sizes: [80, 80] - }, - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when mediaTypes.native has unsupported required asset', function () { - let bid = Object.assign({}, bid); - bid.params = {accountId: '2', placementId: '1'}; - bid.mediaTypes = { - native: { - 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}, - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return true when mediaTypes.native all assets needed', function () { - let bid = Object.assign({}, bid); - bid.adUnitCode = 'div'; - bid.params = {accountId: '2', placementId: '1'}; - bid.mediaTypes = { - native: { - 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}, - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - }); - - describe('override defaults', function () { - let bid = { - bidder: 'mgid', - params: { - accountId: '1', - placementId: '2', - }, - }; - it('should return object', function () { - let bid = Object.assign({}, bid); - bid.mediaTypes = { - banner: { - sizes: [[300, 250]] - } - }; - let bidRequests = [bid]; - const request = spec.buildRequests(bidRequests); - expect(request).to.exist.and.to.be.a('object'); - }); - - it('should return overwrite default bidurl', function () { - let bid = Object.assign({}, bid); - bid.params = { - bidUrl: 'https://newbidurl.com/', - accountId: '1', - placementId: '2', - }; - bid.mediaTypes = { - banner: { - sizes: [[300, 250]] - } - }; - let bidRequests = [bid]; - const request = spec.buildRequests(bidRequests); - expect(request.url).to.include('https://newbidurl.com/1'); - }); - it('should return overwrite default bidFloor', function () { - let bid = Object.assign({}, bid); - bid.params = { - bidFloor: 1.1, - accountId: '1', - placementId: '2', - }; - bid.mediaTypes = { - banner: { - sizes: [[300, 250]] - } - }; - let bidRequests = [bid]; - const request = spec.buildRequests(bidRequests); - expect(request.data).to.be.a('string'); - const data = JSON.parse(request.data); - expect(data).to.be.a('object'); - expect(data.imp).to.be.a('array'); - expect(data.imp).to.have.lengthOf(1); - expect(data.imp[0].bidfloor).to.deep.equal(1.1); - }); - it('should return overwrite default currency', function () { - let bid = Object.assign({}, bid); - bid.params = { - cur: 'GBP', - accountId: '1', - placementId: '2', - }; - bid.mediaTypes = { - banner: { - sizes: [[300, 250]] - } - }; - let bidRequests = [bid]; - const request = spec.buildRequests(bidRequests); - expect(request.data).to.be.a('string'); - const data = JSON.parse(request.data); - expect(data).to.be.a('object'); - expect(data.cur).to.deep.equal(['GBP']); - }); - }); - - describe('buildRequests', function () { - it('should return undefined if no validBidRequests passed', function () { - expect(spec.buildRequests([])).to.be.undefined; - }); - - let abid = { - adUnitCode: 'div', - bidder: 'mgid', - params: { - accountId: '1', - placementId: '2', - }, - }; - it('should return proper request url', function () { - localStorage.setItem('mgMuidn', 'xxx'); - let bid = Object.assign({}, abid); - bid.mediaTypes = { - banner: { - sizes: [[300, 250]] - } - }; - let bidRequests = [bid]; - const request = spec.buildRequests(bidRequests); - expect(request.url).deep.equal('https://prebid.mgid.com/prebid/1?muid=xxx'); - localStorage.removeItem('mgMuidn') - }); - it('should proper handle gdpr', function () { - let bid = Object.assign({}, abid); - bid.mediaTypes = { - banner: { - sizes: [[300, 250]] - } - }; - let bidRequests = [bid]; - const request = spec.buildRequests(bidRequests, {gdprConsent: {consentString: 'gdpr', gdprApplies: true}}); - 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}}); - }); - it('should return proper banner imp', function () { - let bid = Object.assign({}, abid); - bid.mediaTypes = { - banner: { - sizes: [[300, 250]] - } - }; - let bidRequests = [bid]; - const page = top.location.href; - const domain = utils.parseUrl(page).hostname; - const request = spec.buildRequests(bidRequests); - 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.site.domain).to.deep.equal(domain); - expect(data.site.page).to.deep.equal(page); - expect(data.cur).to.deep.equal(['USD']); - expect(data.device.ua).to.deep.equal(ua); - expect(data.device.dnt).equal(dnt); - expect(data.device.h).equal(screenHeight); - 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: 250}); - expect(data.imp[0].secure).to.deep.equal(secure); - expect(request).to.deep.equal({ - 'method': 'POST', - 'url': 'https://prebid.mgid.com/prebid/1', - 'data': '{\"site\":{\"domain\":\"' + domain + '\",\"page\":\"' + page + '\"},\"cur\":[\"USD\"],\"geo\":{\"utcoffset\":' + utcOffset + '},\"device\":{\"ua\":\"' + ua + '\",\"js\":1,\"dnt\":' + dnt + ',\"h\":' + screenHeight + ',\"w\":' + screenWidth + ',\"language\":\"' + lang + '\"},\"ext\":{\"mgid_ver\":\"' + mgid_ver + '\",\"prebid_ver\":\"' + prebid_ver + '\"},\"imp\":[{\"tagid\":\"2/div\",\"secure\":' + secure + ',\"banner\":{\"w\":300,\"h\":250}}]}', - }); - }); - it('should not return native imp if minimum asset list not requested', function () { - let bid = Object.assign({}, abid); - bid.mediaTypes = { - native: '', - }; - bid.nativeParams = { - title: {required: true}, - image: {sizes: [80, 80]}, - }; - let bidRequests = [bid]; - const request = spec.buildRequests(bidRequests); - expect(request).to.be.undefined; - }); - it('should return proper native imp', function () { - let bid = Object.assign({}, abid); - bid.mediaTypes = { - native: '', - }; - bid.nativeParams = { - title: {required: true}, - image: {sizes: [80, 80]}, - sponsored: { }, - }; - - let bidRequests = [bid]; - const page = top.location.href; - const domain = utils.parseUrl(page).hostname; - const request = spec.buildRequests(bidRequests); - expect(request).to.be.a('object'); - 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.site.domain).to.deep.equal(domain); - expect(data.site.page).to.deep.equal(page); - expect(data.cur).to.deep.equal(['USD']); - expect(data.device.ua).to.deep.equal(ua); - expect(data.device.dnt).equal(dnt); - expect(data.device.h).equal(screenHeight); - 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': 11, 'required': 0}], 'plcmtcnt': 1}}); - expect(data.imp[0].secure).to.deep.equal(secure); - expect(request).to.deep.equal({ - 'method': 'POST', - 'url': 'https://prebid.mgid.com/prebid/1', - 'data': '{\"site\":{\"domain\":\"' + domain + '\",\"page\":\"' + page + '\"},\"cur\":[\"USD\"],\"geo\":{\"utcoffset\":' + utcOffset + '},\"device\":{\"ua\":\"' + ua + '\",\"js\":1,\"dnt\":' + dnt + ',\"h\":' + screenHeight + ',\"w\":' + screenWidth + ',\"language\":\"' + lang + '\"},\"ext\":{\"mgid_ver\":\"' + mgid_ver + '\",\"prebid_ver\":\"' + prebid_ver + '\"},\"imp\":[{\"tagid\":\"2/div\",\"secure\":' + secure + ',\"native\":{\"request\":{\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":80}},{\"id\":2,\"required\":0,\"img\":{\"type\":3,\"w\":80,\"h\":80}},{\"id\":11,\"required\":0,\"data\":{\"type\":1}}]}}}]}', - }); - }); - it('should return proper native imp', function () { - let bid = Object.assign({}, abid); - bid.mediaTypes = { - native: '', - }; - bid.nativeParams = { - title: {required: true}, - image: {wmin: 50, hmin: 50, required: true}, - icon: {}, - sponsored: { }, - }; - - let bidRequests = [bid]; - const page = top.location.href; - const domain = utils.parseUrl(page).hostname; - const request = spec.buildRequests(bidRequests); - expect(request).to.be.a('object'); - 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.site.domain).to.deep.equal(domain); - expect(data.site.page).to.deep.equal(page); - expect(data.cur).to.deep.equal(['USD']); - expect(data.device.ua).to.deep.equal(ua); - expect(data.device.dnt).equal(dnt); - expect(data.device.h).equal(screenHeight); - 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].secure).to.deep.equal(secure); - expect(request).to.deep.equal({ - 'method': 'POST', - 'url': 'https://prebid.mgid.com/prebid/1', - 'data': '{\"site\":{\"domain\":\"' + domain + '\",\"page\":\"' + page + '\"},\"cur\":[\"USD\"],\"geo\":{\"utcoffset\":' + utcOffset + '},\"device\":{\"ua\":\"' + ua + '\",\"js\":1,\"dnt\":' + dnt + ',\"h\":' + screenHeight + ',\"w\":' + screenWidth + ',\"language\":\"' + lang + '\"},\"ext\":{\"mgid_ver\":\"' + mgid_ver + '\",\"prebid_ver\":\"' + prebid_ver + '\"},\"imp\":[{\"tagid\":\"2/div\",\"secure\":' + secure + ',\"native\":{\"request\":{\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":80}},{\"id\":2,\"required\":1,\"img\":{\"type\":3,\"w\":492,\"h\":328,\"wmin\":50,\"hmin\":50}},{\"id\":3,\"required\":0,\"img\":{\"type\":1,\"w\":50,\"h\":50}},{\"id\":11,\"required\":0,\"data\":{\"type\":1}}]}}}]}', - }); - }); - it('should return proper native imp with sponsoredBy', function () { - let bid = Object.assign({}, abid); - bid.mediaTypes = { - native: '', - }; - bid.nativeParams = { - title: {required: true}, - image: {sizes: [80, 80]}, - sponsoredBy: { }, - }; - - let bidRequests = [bid]; - const page = top.location.href; - const domain = utils.parseUrl(page).hostname; - const request = spec.buildRequests(bidRequests); - expect(request).to.be.a('object'); - 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.site.domain).to.deep.equal(domain); - expect(data.site.page).to.deep.equal(page); - expect(data.cur).to.deep.equal(['USD']); - expect(data.device.ua).to.deep.equal(ua); - expect(data.device.dnt).equal(dnt); - expect(data.device.h).equal(screenHeight); - 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].secure).to.deep.equal(secure); - expect(request).to.deep.equal({ - 'method': 'POST', - 'url': 'https://prebid.mgid.com/prebid/1', - 'data': '{\"site\":{\"domain\":\"' + domain + '\",\"page\":\"' + page + '\"},\"cur\":[\"USD\"],\"geo\":{\"utcoffset\":' + utcOffset + '},\"device\":{\"ua\":\"' + ua + '\",\"js\":1,\"dnt\":' + dnt + ',\"h\":' + screenHeight + ',\"w\":' + screenWidth + ',\"language\":\"' + lang + '\"},\"ext\":{\"mgid_ver\":\"' + mgid_ver + '\",\"prebid_ver\":\"' + prebid_ver + '\"},\"imp\":[{\"tagid\":\"2/div\",\"secure\":' + secure + ',\"native\":{\"request\":{\"plcmtcnt\":1,\"assets\":[{\"id\":1,\"required\":1,\"title\":{\"len\":80}},{\"id\":2,\"required\":0,\"img\":{\"type\":3,\"w\":80,\"h\":80}},{\"id\":4,\"required\":0,\"data\":{\"type\":1}}]}}}]}', - }); - }); - it('should return proper banner request', function () { - let bid = Object.assign({}, abid); - bid.mediaTypes = { - banner: { - sizes: [[300, 600], [300, 250]], - } - }; - let bidRequests = [bid]; - const request = spec.buildRequests(bidRequests); - - const page = top.location.href; - const domain = utils.parseUrl(page).hostname; - 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.site.domain).to.deep.equal(domain); - expect(data.site.page).to.deep.equal(page); - expect(data.cur).to.deep.equal(['USD']); - expect(data.device.ua).to.deep.equal(ua); - expect(data.device.dnt).equal(dnt); - expect(data.device.h).equal(screenHeight); - 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}]}); - expect(data.imp[0].secure).to.deep.equal(secure); - - expect(request).to.deep.equal({ - 'method': 'POST', - 'url': 'https://prebid.mgid.com/prebid/1', - 'data': '{\"site\":{\"domain\":\"' + domain + '\",\"page\":\"' + page + '\"},\"cur\":[\"USD\"],\"geo\":{\"utcoffset\":' + utcOffset + '},\"device\":{\"ua\":\"' + ua + '\",\"js\":1,\"dnt\":' + dnt + ',\"h\":' + screenHeight + ',\"w\":' + screenWidth + ',\"language\":\"' + lang + '\"},\"ext\":{\"mgid_ver\":\"' + mgid_ver + '\",\"prebid_ver\":\"' + prebid_ver + '\"},\"imp\":[{\"tagid\":\"2/div\",\"secure\":' + secure + ',\"banner\":{\"w\":300,\"h\":600,\"format\":[{\"w\":300,\"h\":600},{\"w\":300,\"h\":250}]}}]}', - }); - }); - }); - describe('interpretResponse banner', function () { - it('should not push bid response', function () { - let bids = spec.interpretResponse(); - expect(bids).to.be.undefined; - }); - it('should push proper banner bid response', function () { - let 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']}], 'seat': '44082'}]} - }; - let bids = spec.interpretResponse(resp); - expect(bids).to.deep.equal([ - { - 'ad': 'html: adm', - 'cpm': 1.5, - 'creativeId': '2898532/2419121/2592854/2499195', - 'currency': 'USD', - 'dealId': '', - 'height': 600, - 'isBurl': true, - 'mediaType': 'banner', - 'netRevenue': true, - 'nurl': 'https nurl', - 'burl': 'https burl', - 'requestId': '61e40632c53fc2', - 'ttl': 300, - 'width': 300, - } - ]); - }); - }); - describe('interpretResponse native', function () { - it('should not push proper native bid response if adm is missing', function () { - let 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'}}], 'seat': '44082'}]} - }; - let bids = spec.interpretResponse(resp); - expect(bids).to.deep.equal([]) - }); - it('should not push proper native bid response if assets is empty', function () { - let 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'}}], 'seat': '44082'}]} - }; - let bids = spec.interpretResponse(resp); - expect(bids).to.deep.equal([]) - }); - it('should push proper native bid response', function () { - let 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'}}], 'seat': '44082'}], ext: {'muidn': 'userid'}} - }; - let bids = spec.interpretResponse(resp); - expect(bids).to.deep.equal([{ - 'ad': '{\"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\"]}}', - 'burl': 'https burl', - 'cpm': 1.5, - 'creativeId': '2898532/2419121/2592854/2499195', - 'currency': 'GBP', - 'dealId': '', - 'height': 0, - 'isBurl': true, - 'mediaType': 'native', - 'native': { - 'clickTrackers': [], - 'clickUrl': 'link_url', - 'data': 'price1', - 'icon': { - 'height': 50, - 'url': 'icon_src', - 'width': 50 - }, - 'image': { - 'height': 80, - 'url': 'image_src', - 'width': 80 - }, - 'impressionTrackers': [ - 'imptrackers1' - ], - 'jstracker': [], - 'sponsoredBy': 'sponsored', - 'title': 'title1' - }, - 'netRevenue': true, - 'nurl': 'https nurl', - 'requestId': '61e40632c53fc2', - 'ttl': 300, - 'width': 0 - }]) - }); - it('should push proper native bid response', function () { - let 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'}}], 'seat': '44082'}]} - }; - let bids = spec.interpretResponse(resp); - expect(bids).to.deep.equal([ - { - 'ad': '{\"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\"]}}', - 'cpm': 1.5, - 'creativeId': '2898532/2419121/2592854/2499195', - 'currency': 'GBP', - 'dealId': '', - 'height': 0, - 'isBurl': true, - 'mediaType': 'native', - 'netRevenue': true, - 'nurl': 'https nurl', - 'burl': 'https burl', - 'requestId': '61e40632c53fc2', - 'ttl': 300, - 'width': 0, - 'native': { - clickTrackers: [], - title: 'title1', - image: { - url: 'image_src', - width: 80, - height: 80, - }, - icon: { - url: 'icon_src', - width: 50, - height: 50, - }, - impressionTrackers: ['imptrackers1'], - jstracker: [], - clickUrl: 'link_url', - } - } - ]); - }); - }); - - describe('getUserSyncs', function () { - it('should do nothing on getUserSyncs', function () { - spec.getUserSyncs() - }); - }); - describe('on bidWon', function () { - beforeEach(function() { - sinon.stub(utils, 'triggerPixel'); - }); - afterEach(function() { - utils.triggerPixel.restore(); - }); - 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'}]}; - spec.onBidWon(bid); - expect(bid.nurl).to.deep.equal('nurl&s=0.66'); - expect(bid.burl).to.deep.equal('burl&s=0.66'); - }); - 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'}]}; - spec.onBidWon(bid); - expect(bid.nurl).to.deep.equal('nurl&s=0.66'); - expect(bid.burl).to.deep.equal(burl); - expect(bid.ad).to.deep.equal('burl&s=0.66'); - }); - }); -}); diff --git a/test/spec/modules/microadBidAdapter_spec.js b/test/spec/modules/microadBidAdapter_spec.js deleted file mode 100644 index 8298e2bd559..00000000000 --- a/test/spec/modules/microadBidAdapter_spec.js +++ /dev/null @@ -1,388 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/microadBidAdapter.js'; -import * as utils from 'src/utils.js'; - -describe('microadBidAdapter', () => { - const bidRequestTemplate = { - bidder: 'microad', - mediaTypes: { - banner: {} - }, - params: { - spot: 'spot-code' - }, - bidId: 'bid-id', - transactionId: 'transaction-id' - }; - - describe('isBidRequestValid', () => { - it('should return true when required parameters are set', () => { - const validBids = [ - bidRequestTemplate, - Object.assign({}, bidRequestTemplate, { - mediaTypes: { - native: {} - } - }), - Object.assign({}, bidRequestTemplate, { - mediaTypes: { - video: {} - } - }) - ]; - validBids.forEach(validBid => { - expect(spec.isBidRequestValid(validBid)).to.equal(true); - }); - }); - - it('should return false when required parameters are not set', () => { - const bidWithoutParams = utils.deepClone(bidRequestTemplate); - delete bidWithoutParams.params; - const bidWithoutSpot = utils.deepClone(bidRequestTemplate); - delete bidWithoutSpot.params.spot; - const bidWithoutMediaTypes = utils.deepClone(bidRequestTemplate); - delete bidWithoutMediaTypes.mediaTypes; - - const invalidBids = [ - {}, - bidWithoutParams, - bidWithoutSpot, - bidWithoutMediaTypes, - Object.assign({}, bidRequestTemplate, { - mediaTypes: {} - }) - ]; - invalidBids.forEach(invalidBid => { - expect(spec.isBidRequestValid(invalidBid)).to.equal(false); - }); - }); - }); - - describe('buildRequests', () => { - const bidderRequest = { - refererInfo: { - canonicalUrl: 'https://example.com/to', - referer: 'https://example.com/from' - } - }; - const expectedResultTemplate = { - spot: 'spot-code', - url: 'https://example.com/to', - referrer: 'https://example.com/from', - bid_id: 'bid-id', - transaction_id: 'transaction-id', - media_types: 1 - }; - - it('should generate valid media_types', () => { - const bidRequests = [ - bidRequestTemplate, - Object.assign({}, bidRequestTemplate, { - mediaTypes: { - banner: {}, native: {} - } - }), - Object.assign({}, bidRequestTemplate, { - mediaTypes: { - banner: {}, native: {}, video: {} - } - }), - Object.assign({}, bidRequestTemplate, { - mediaTypes: { - native: {} - } - }), - Object.assign({}, bidRequestTemplate, { - mediaTypes: { - native: {}, video: {} - } - }), - Object.assign({}, bidRequestTemplate, { - mediaTypes: { - video: {} - } - }), - Object.assign({}, bidRequestTemplate, { - mediaTypes: { - banner: {}, video: {} - } - }) - ]; - - const results = bidRequests.map(bid => { - const requests = spec.buildRequests([bid], bidderRequest); - return requests[0].data.media_types; - }); - expect(results).to.deep.equal([ - 1, // BANNER - 3, // BANNER + NATIVE - 7, // BANNER + NATIVE + VIDEO - 2, // NATIVE - 6, // NATIVE + VIDEO - 4, // VIDEO - 5 // BANNER + VIDEO - ]); - }); - - it('should use window.location.href if there is no canonicalUrl', () => { - const bidderRequestWithoutCanonicalUrl = { - refererInfo: { - referer: 'https://example.com/from' - } - }; - const requests = spec.buildRequests([bidRequestTemplate], bidderRequestWithoutCanonicalUrl); - requests.forEach(request => { - expect(request.data).to.deep.equal( - Object.assign({}, expectedResultTemplate, { - cbt: request.data.cbt, - url: window.location.href - }) - ); - }); - }); - - it('should generate valid request with no optional parameters', () => { - const requests = spec.buildRequests([bidRequestTemplate], bidderRequest); - requests.forEach(request => { - expect(request.data).to.deep.equal( - Object.assign({}, expectedResultTemplate, { - cbt: request.data.cbt - }) - ); - }); - }); - - it('should add url_macro parameter to response if request parameters contain url', () => { - const bidRequestWithUrl = Object.assign({}, bidRequestTemplate, { - params: { - spot: 'spot-code', - url: '${COMPASS_EXT_URL}url-macro' - } - }); - const requests = spec.buildRequests([bidRequestWithUrl], bidderRequest); - requests.forEach(request => { - expect(request.data).to.deep.equal( - Object.assign({}, expectedResultTemplate, { - cbt: request.data.cbt, - url_macro: 'url-macro' - }) - ); - }); - }); - - it('should add referrer_macro parameter to response if request parameters contain referrer', () => { - const bidRequestWithReferrer = Object.assign({}, bidRequestTemplate, { - params: { - spot: 'spot-code', - referrer: '${COMPASS_EXT_REF}referrer-macro' - } - }); - const requests = spec.buildRequests([bidRequestWithReferrer], bidderRequest); - requests.forEach(request => { - expect(request.data).to.deep.equal( - Object.assign({}, expectedResultTemplate, { - cbt: request.data.cbt, - referrer_macro: 'referrer-macro' - }) - ); - }); - }); - - it('should add ifa parameter to response if request parameters contain ifa', () => { - const bidRequestWithIfa = Object.assign({}, bidRequestTemplate, { - params: { - spot: 'spot-code', - ifa: '${COMPASS_EXT_IFA}ifa' - } - }); - const requests = spec.buildRequests([bidRequestWithIfa], bidderRequest); - requests.forEach(request => { - expect(request.data).to.deep.equal( - Object.assign({}, expectedResultTemplate, { - cbt: request.data.cbt, - ifa: 'ifa' - }) - ); - }); - }); - - it('should add appid parameter to response if request parameters contain appid', () => { - const bidRequestWithAppid = Object.assign({}, bidRequestTemplate, { - params: { - spot: 'spot-code', - appid: '${COMPASS_EXT_APPID}appid' - } - }); - const requests = spec.buildRequests([bidRequestWithAppid], bidderRequest); - requests.forEach(request => { - expect(request.data).to.deep.equal( - Object.assign({}, expectedResultTemplate, { - cbt: request.data.cbt, - appid: 'appid' - }) - ); - }); - }); - - it('should add geo parameter to response if request parameters contain geo', () => { - const bidRequestWithGeo = Object.assign({}, bidRequestTemplate, { - params: { - spot: 'spot-code', - geo: '${COMPASS_EXT_GEO}35.655275,139.693771' - } - }); - const requests = spec.buildRequests([bidRequestWithGeo], bidderRequest); - requests.forEach(request => { - expect(request.data).to.deep.equal( - Object.assign({}, expectedResultTemplate, { - cbt: request.data.cbt, - geo: '35.655275,139.693771' - }) - ); - }); - }); - - it('should not add geo parameter to response if request parameters contain invalid geo', () => { - const bidRequestWithGeo = Object.assign({}, bidRequestTemplate, { - params: { - spot: 'spot-code', - geo: '${COMPASS_EXT_GEO}invalid format geo' - } - }); - const requests = spec.buildRequests([bidRequestWithGeo], bidderRequest); - requests.forEach(request => { - expect(request.data).to.deep.equal( - Object.assign({}, expectedResultTemplate, { - cbt: request.data.cbt - }) - ); - }); - }); - - it('should always use the HTTPS endpoint https://s-rtb-pb.send.microad.jp/prebid even if it is served via HTTP', () => { - const requests = spec.buildRequests([bidRequestTemplate], bidderRequest); - requests.forEach(request => { - expect(request.url.lastIndexOf('https', 0) === 0).to.be.true; - }); - }); - }); - - describe('interpretResponse', () => { - const serverResponseTemplate = { - body: { - requestId: 'request-id', - cpm: 0.1, - width: 200, - height: 100, - ad: '
test
', - ttl: 10, - creativeId: 'creative-id', - netRevenue: true, - currency: 'JPY' - } - }; - const expectedBidResponseTemplate = { - requestId: 'request-id', - cpm: 0.1, - width: 200, - height: 100, - ad: '
test
', - ttl: 10, - creativeId: 'creative-id', - netRevenue: true, - currency: 'JPY' - }; - - it('should return nothing if server response body does not contain cpm', () => { - const emptyResponse = { - body: {} - }; - - expect(spec.interpretResponse(emptyResponse)).to.deep.equal([]); - }); - - it('should return nothing if returned cpm is zero', () => { - const serverResponse = { - body: { - cpm: 0 - } - }; - - expect(spec.interpretResponse(serverResponse)).to.deep.equal([]); - }); - - it('should return a valid bidResponse without deal id if serverResponse is valid, has a nonzero cpm and no deal id', () => { - expect(spec.interpretResponse(serverResponseTemplate)).to.deep.equal([expectedBidResponseTemplate]); - }); - - it('should return a valid bidResponse with deal id if serverResponse is valid, has a nonzero cpm and a deal id', () => { - const serverResponseWithDealId = Object.assign({}, utils.deepClone(serverResponseTemplate)); - serverResponseWithDealId.body['dealId'] = 10001; - const expectedBidResponse = Object.assign({}, expectedBidResponseTemplate, { - dealId: 10001 - }); - - expect(spec.interpretResponse(serverResponseWithDealId)).to.deep.equal([expectedBidResponse]); - }); - }); - - describe('getUserSyncs', () => { - const BOTH_ENABLED = { - iframeEnabled: true, pixelEnabled: true - }; - const IFRAME_ENABLED = { - iframeEnabled: true, pixelEnabled: false - }; - const PIXEL_ENABLED = { - iframeEnabled: false, pixelEnabled: true - }; - const BOTH_DISABLED = { - iframeEnabled: false, pixelEnabled: false - }; - const serverResponseTemplate = { - body: { - syncUrls: { - iframe: ['https://www.exmaple.com/iframe1', 'https://www.exmaple.com/iframe2'], - image: ['https://www.exmaple.com/image1', 'https://www.exmaple.com/image2'] - } - } - }; - const expectedIframeSyncs = [ - {type: 'iframe', url: 'https://www.exmaple.com/iframe1'}, - {type: 'iframe', url: 'https://www.exmaple.com/iframe2'} - ]; - const expectedImageSyncs = [ - {type: 'image', url: 'https://www.exmaple.com/image1'}, - {type: 'image', url: 'https://www.exmaple.com/image2'} - ]; - - it('should return nothing if no sync urls are set', () => { - const serverResponse = utils.deepClone(serverResponseTemplate); - serverResponse.body.syncUrls.iframe = []; - serverResponse.body.syncUrls.image = []; - - const syncs = spec.getUserSyncs(BOTH_ENABLED, [serverResponse]); - expect(syncs).to.deep.equal([]); - }); - - it('should return nothing if sync is disabled', () => { - const syncs = spec.getUserSyncs(BOTH_DISABLED, [serverResponseTemplate]); - expect(syncs).to.deep.equal([]); - }); - - it('should register iframe and image sync urls if sync is enabled', () => { - const syncs = spec.getUserSyncs(BOTH_ENABLED, [serverResponseTemplate]); - expect(syncs).to.deep.equal(expectedIframeSyncs.concat(expectedImageSyncs)); - }); - - it('should register iframe sync urls if iframe is enabled', () => { - const syncs = spec.getUserSyncs(IFRAME_ENABLED, [serverResponseTemplate]); - expect(syncs).to.deep.equal(expectedIframeSyncs); - }); - - it('should register image sync urls if image is enabled', () => { - const syncs = spec.getUserSyncs(PIXEL_ENABLED, [serverResponseTemplate]); - expect(syncs).to.deep.equal(expectedImageSyncs); - }); - }); -}); diff --git a/test/spec/modules/missenaBidAdapter_spec.js b/test/spec/modules/missenaBidAdapter_spec.js deleted file mode 100644 index 026e79c6d5a..00000000000 --- a/test/spec/modules/missenaBidAdapter_spec.js +++ /dev/null @@ -1,131 +0,0 @@ -import { expect } from 'chai'; -import { spec, _getPlatform } from 'modules/missenaBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('Missena Adapter', function () { - const adapter = newBidder(spec); - - const bidId = 'abc'; - - const bid = { - bidder: 'missena', - bidId: bidId, - sizes: [[1, 1]], - params: { - apiKey: 'PA-34745704', - }, - }; - - describe('codes', function () { - it('should return a bidder code of missena', function () { - expect(spec.code).to.equal('missena'); - }); - }); - - describe('isBidRequestValid', function () { - it('should return true if the apiKey param is present', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false if the apiKey is missing', function () { - expect( - spec.isBidRequestValid(Object.assign(bid, { params: {} })) - ).to.equal(false); - }); - - it('should return false if the apiKey is an empty string', function () { - expect( - spec.isBidRequestValid(Object.assign(bid, { params: { apiKey: '' } })) - ).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const consentString = 'AAAAAAAAA=='; - - const bidderRequest = { - gdprConsent: { - consentString: consentString, - gdprApplies: true, - }, - refererInfo: { - referer: 'https://referer', - canonicalUrl: 'https://canonical', - }, - }; - - const requests = spec.buildRequests([bid, bid], bidderRequest); - const request = requests[0]; - const payload = JSON.parse(request.data); - - it('should return as many server requests as bidder requests', function () { - expect(requests.length).to.equal(2); - }); - - it('should have a post method', function () { - expect(request.method).to.equal('POST'); - }); - - it('should send the bidder id', function () { - expect(payload.request_id).to.equal(bidId); - }); - - it('should send referer information to the request', function () { - expect(payload.referer).to.equal('https://referer'); - expect(payload.referer_canonical).to.equal('https://canonical'); - }); - - it('should send gdpr consent information to the request', function () { - expect(payload.consent_string).to.equal(consentString); - expect(payload.consent_required).to.equal(true); - }); - }); - - describe('interpretResponse', function () { - const serverResponse = { - requestId: bidId, - cpm: 0.5, - currency: 'USD', - ad: '', - }; - - const serverTimeoutResponse = { - requestId: bidId, - timeout: true, - ad: '', - }; - - const serverEmptyAdResponse = { - requestId: bidId, - cpm: 0.5, - currency: 'USD', - ad: '', - }; - - it('should return a proper bid response', function () { - const result = spec.interpretResponse({ body: serverResponse }, bid); - - expect(result.length).to.equal(1); - - expect(Object.keys(result[0])).to.have.members( - Object.keys(serverResponse) - ); - }); - - it('should return an empty response when the server answers with a timeout', function () { - const result = spec.interpretResponse( - { body: serverTimeoutResponse }, - bid - ); - expect(result).to.deep.equal([]); - }); - - it('should return an empty response when the server answers with an empty ad', function () { - const result = spec.interpretResponse( - { body: serverEmptyAdResponse }, - bid - ); - expect(result).to.deep.equal([]); - }); - }); -}); diff --git a/test/spec/modules/mobfoxBidAdapter_spec.js b/test/spec/modules/mobfoxBidAdapter_spec.js deleted file mode 100644 index d3178d77a1a..00000000000 --- a/test/spec/modules/mobfoxBidAdapter_spec.js +++ /dev/null @@ -1,123 +0,0 @@ -describe('mobfox adapter tests', function () { - const expect = require('chai').expect; - const utils = require('src/utils'); - const adapter = require('modules/mobfoxBidAdapter'); - - const bidRequest = [{ - code: 'div-gpt-ad-1460505748561-0', - sizes: [[320, 480], [300, 250], [300, 600]], - // Replace this object to test a new Adapter! - bidder: 'mobfox', - bidId: '5t5t5t5', - params: { - s: '267d72ac3f77a3f447b32cf7ebf20673', // required - The hash of your inventory to identify which app is making the request, - imp_instl: 1 // optional - set to 1 if using interstitial otherwise delete or set to 0 - }, - placementCode: 'div-gpt-ad-1460505748561-0', - auctionId: 'c241c810-18d9-4aa4-a62f-8c1980d8d36b', - transactionId: '31f42cba-5920-4e47-adad-69c79d0d4fb4' - }]; - - describe('validRequests', function () { - let bidRequestInvalid1 = [{ - code: 'div-gpt-ad-1460505748561-0', - sizes: [[320, 480], [300, 250], [300, 600]], - // Replace this object to test a new Adapter! - bidder: 'mobfox', - bidId: '5t5t5t5', - params: { - imp_instl: 1 // optional - set to 1 if using interstitial otherwise delete or set to 0 - }, - placementCode: 'div-gpt-ad-1460505748561-0', - auctionId: 'c241c810-18d9-4aa4-a62f-8c1980d8d36b', - transactionId: '31f42cba-5920-4e47-adad-69c79d0d4fb4' - }]; - - it('test valid MF request success', function () { - let isValid = adapter.spec.isBidRequestValid(bidRequest[0]); - expect(isValid).to.equal(true); - }); - - it('test valid MF request failed1', function () { - let isValid = adapter.spec.isBidRequestValid(bidRequestInvalid1[0]); - expect(isValid).to.equal(false); - }); - }) - - describe('buildRequests', function () { - it('test build MF request', function () { - let request = adapter.spec.buildRequests(bidRequest); - let payload = request.data.split('&'); - expect(payload[0]).to.equal('rt=api-fetchip'); - expect(payload[1]).to.equal('r_type=banner'); - expect(payload[2]).to.equal('r_resp=json'); - expect(payload[3]).to.equal('s=267d72ac3f77a3f447b32cf7ebf20673'); - expect(payload[5]).to.equal('adspace_width=320'); - expect(payload[6]).to.equal('adspace_height=480'); - expect(payload[7]).to.equal('imp_instl=1'); - }); - - it('test build MF request', function () { - let request = adapter.spec.buildRequests(bidRequest); - let payload = request.data.split('&'); - expect(payload[0]).to.equal('rt=api-fetchip'); - expect(payload[1]).to.equal('r_type=banner'); - expect(payload[2]).to.equal('r_resp=json'); - expect(payload[3]).to.equal('s=267d72ac3f77a3f447b32cf7ebf20673'); - expect(payload[5]).to.equal('adspace_width=320'); - expect(payload[6]).to.equal('adspace_height=480'); - expect(payload[7]).to.equal('imp_instl=1'); - }); - }) - - describe('interceptResponse', function () { - let mockServerResponse = { - body: { - request: { - clicktype: 'safari', - clickurl: 'https://tokyo-my.mobfox.com/exchange.click.php?h=494ef76d5b0287a8b5ac8724855cb5e0', - cpmPrice: 50, - htmlString: 'test', - refresh: '30', - scale: 'no', - skippreflight: 'yes', - type: 'textAd', - urltype: 'link' - } - }, - headers: { - get: function (header) { - if (header === 'X-Pricing-CPM') { - return 50; - } - } - } - }; - it('test intercept response', function () { - let request = adapter.spec.buildRequests(bidRequest); - let bidResponses = adapter.spec.interpretResponse(mockServerResponse, request); - expect(bidResponses.length).to.equal(1); - expect(bidResponses[0].ad).to.equal('test'); - expect(bidResponses[0].cpm).to.equal(50); - expect(bidResponses[0].creativeId).to.equal('267d72ac3f77a3f447b32cf7ebf20673'); - expect(bidResponses[0].requestId).to.equal('5t5t5t5'); - expect(bidResponses[0].currency).to.equal('USD'); - expect(bidResponses[0].height).to.equal('480'); - expect(bidResponses[0].netRevenue).to.equal(true); - expect(bidResponses[0].referrer).to.equal('https://tokyo-my.mobfox.com/exchange.click.php?h=494ef76d5b0287a8b5ac8724855cb5e0'); - expect(bidResponses[0].ttl).to.equal(360); - expect(bidResponses[0].width).to.equal('320'); - }); - - it('test intercept response with empty server response', function () { - let request = adapter.spec.buildRequests(bidRequest); - let serverResponse = { - request: { - error: 'cannot get response' - } - }; - let bidResponses = adapter.spec.interpretResponse(serverResponse, request); - expect(bidResponses.length).to.equal(0); - }) - }) -}); diff --git a/test/spec/modules/mobfoxpbBidAdapter_spec.js b/test/spec/modules/mobfoxpbBidAdapter_spec.js deleted file mode 100644 index a02d580ab88..00000000000 --- a/test/spec/modules/mobfoxpbBidAdapter_spec.js +++ /dev/null @@ -1,304 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/mobfoxpbBidAdapter.js'; -import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; - -describe('MobfoxHBBidAdapter', function () { - const bid = { - bidId: '23fhj33i987f', - bidder: 'mobfoxpb', - mediaTypes: { - [BANNER]: { - sizes: [[300, 250]] - } - }, - params: { - placementId: 783, - traffic: BANNER - } - }; - - const bidderRequest = { - refererInfo: { - referer: 'test.com' - } - }; - - describe('isBidRequestValid', function () { - it('Should return true if there are bidId, params and key parameters present', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false if at least one of parameters is not present', function () { - delete bid.params.placementId; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid], 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://bes.mobfox.com/?c=o&m=multi'); - }); - it('Returns valid data if array of bids is valid', function () { - let data = serverRequest.data; - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); - 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.gdpr).to.not.exist; - expect(data.ccpa).to.not.exist; - let placement = data['placements'][0]; - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes', 'schain'); - expect(placement.placementId).to.equal(783); - expect(placement.bidId).to.equal('23fhj33i987f'); - expect(placement.traffic).to.equal(BANNER); - expect(placement.schain).to.be.an('object'); - expect(placement.sizes).to.be.an('array'); - }); - - it('Returns valid data for mediatype video', function () { - const playerSize = [300, 300]; - bid.mediaTypes = {}; - bid.params.traffic = VIDEO; - bid.mediaTypes[VIDEO] = { - playerSize - }; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data).to.be.an('object'); - let placement = data['placements'][0]; - expect(placement).to.be.an('object'); - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'wPlayer', 'hPlayer', 'schain'); - expect(placement.traffic).to.equal(VIDEO); - expect(placement.wPlayer).to.equal(playerSize[0]); - expect(placement.hPlayer).to.equal(playerSize[1]); - }); - - it('Returns valid data for mediatype native', function () { - const native = { - title: { - required: true - }, - body: { - required: true - }, - icon: { - required: true, - size: [64, 64] - } - }; - - bid.mediaTypes = {}; - bid.params.traffic = NATIVE; - bid.mediaTypes[NATIVE] = native; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data).to.be.an('object'); - let placement = data['placements'][0]; - expect(placement).to.be.an('object'); - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'native', 'schain'); - expect(placement.traffic).to.equal(NATIVE); - expect(placement.native).to.equal(native); - }); - - it('Returns data with gdprConsent and without uspConsent', function () { - bidderRequest.gdprConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data.gdpr).to.exist; - expect(data.gdpr).to.be.a('string'); - expect(data.gdpr).to.equal(bidderRequest.gdprConsent); - expect(data.ccpa).to.not.exist; - delete bidderRequest.gdprConsent; - }); - - it('Returns data with uspConsent and without gdprConsent', function () { - bidderRequest.uspConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); - let 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; - }); - - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); - }); - 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' - }] - }; - let bannerResponses = spec.interpretResponse(banner); - expect(bannerResponses).to.be.an('array').that.is.not.empty; - let dataItem = bannerResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - expect(dataItem.requestId).to.equal('23fhj33i987f'); - expect(dataItem.cpm).to.equal(0.4); - expect(dataItem.width).to.equal(300); - expect(dataItem.height).to.equal(250); - expect(dataItem.ad).to.equal('Test'); - expect(dataItem.ttl).to.equal(120); - expect(dataItem.creativeId).to.equal('2'); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal('USD'); - }); - 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' - }] - }; - let videoResponses = spec.interpretResponse(video); - expect(videoResponses).to.be.an('array').that.is.not.empty; - - let dataItem = videoResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - 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'); - }); - 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', - }] - }; - let nativeResponses = spec.interpretResponse(native); - expect(nativeResponses).to.be.an('array').that.is.not.empty; - - let dataItem = nativeResponses[0]; - expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); - 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'); - }); - 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' - }] - }; - - let 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' - }] - }; - let 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', - }] - }; - let 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' - }] - }; - let serverResponses = spec.interpretResponse(invalid); - expect(serverResponses).to.be.an('array').that.is.empty; - }); - }); -}); diff --git a/test/spec/modules/mobsmartBidAdapter_spec.js b/test/spec/modules/mobsmartBidAdapter_spec.js deleted file mode 100644 index b48878adff6..00000000000 --- a/test/spec/modules/mobsmartBidAdapter_spec.js +++ /dev/null @@ -1,214 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/mobsmartBidAdapter.js'; - -describe('mobsmartBidAdapter', function () { - describe('isBidRequestValid', function () { - let bid; - beforeEach(function() { - bid = { - bidder: 'mobsmart', - params: { - floorPrice: 100, - currency: 'JPY' - }, - mediaTypes: { - banner: { - size: [[300, 250]] - } - } - }; - }); - - it('should return true when valid bid request is set', function() { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when bidder is not set to "mobsmart"', function() { - bid.bidder = 'bidder'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return true when params are not set', function() { - delete bid.params.floorPrice; - delete bid.params.currency; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - }); - - describe('buildRequests', function () { - let bidRequests; - beforeEach(function() { - bidRequests = [ - { - bidder: 'mobsmart', - adUnitCode: 'mobsmart-ad-code', - auctionId: 'auctionid-123', - bidId: 'bidid123', - bidRequestsCount: 1, - bidderRequestId: 'bidderrequestid123', - transactionId: 'transaction-id-123', - sizes: [[300, 250]], - requestId: 'requestid123', - params: { - floorPrice: 100, - currency: 'JPY' - }, - mediaTypes: { - banner: { - size: [[300, 250]] - } - }, - userId: { - pubcid: 'pubc-id-123' - } - }, { - bidder: 'mobsmart', - adUnitCode: 'mobsmart-ad-code2', - auctionId: 'auctionid-456', - bidId: 'bidid456', - bidRequestsCount: 1, - bidderRequestId: 'bidderrequestid456', - transactionId: 'transaction-id-456', - sizes: [[320, 50]], - requestId: 'requestid456', - params: { - floorPrice: 100, - currency: 'JPY' - }, - mediaTypes: { - banner: { - size: [[320, 50]] - } - }, - userId: { - pubcid: 'pubc-id-456' - } - } - ]; - }); - - let bidderRequest = { - refererInfo: { - referer: 'https://example.com' - } - }; - - it('should not contain a sizes when sizes is not set', function() { - delete bidRequests[0].sizes; - delete bidRequests[1].sizes; - let requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests[0].data.sizes).to.be.an('undefined'); - expect(requests[1].data.sizes).to.be.an('undefined'); - }); - - it('should not contain a userId when userId is not set', function() { - delete bidRequests[0].userId; - delete bidRequests[1].userId; - let requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests[0].data.userId).to.be.an('undefined'); - expect(requests[1].data.userId).to.be.an('undefined'); - }); - - it('should have a post method', function() { - let requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests[0].method).to.equal('POST'); - expect(requests[1].method).to.equal('POST'); - }); - - it('should contain a request id equals to the bid id', function() { - let requests = spec.buildRequests(bidRequests, bidderRequest); - expect(JSON.parse(requests[0].data).requestId).to.equal(bidRequests[0].bidId); - expect(JSON.parse(requests[1].data).requestId).to.equal(bidRequests[1].bidId); - }); - - it('should have an url that match the default endpoint', function() { - let requests = spec.buildRequests(bidRequests, bidderRequest); - expect(requests[0].url).to.equal('https://prebid.mobsmart.net/prebid/endpoint'); - expect(requests[1].url).to.equal('https://prebid.mobsmart.net/prebid/endpoint'); - }); - }); - - describe('interpretResponse', function () { - let serverResponse; - beforeEach(function() { - serverResponse = { - body: { - 'requestId': 'request-id', - 'cpm': 100, - 'width': 300, - 'height': 250, - 'ad': '
ad
', - 'ttl': 300, - 'creativeId': 'creative-id', - 'netRevenue': true, - 'currency': 'JPY' - } - }; - }); - - it('should return a valid response', () => { - var responses = spec.interpretResponse(serverResponse); - expect(responses).to.be.an('array').that.is.not.empty; - - let response = responses[0]; - expect(response).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency'); - expect(response.requestId).to.equal('request-id'); - expect(response.cpm).to.equal(100); - expect(response.width).to.equal(300); - expect(response.height).to.equal(250); - expect(response.ad).to.equal('
ad
'); - expect(response.ttl).to.equal(300); - expect(response.creativeId).to.equal('creative-id'); - expect(response.netRevenue).to.be.true; - expect(response.currency).to.equal('JPY'); - }); - - it('should return an empty array when serverResponse is empty', () => { - serverResponse = {}; - var responses = spec.interpretResponse(serverResponse); - expect(responses).to.deep.equal([]); - }); - }); - - describe('getUserSyncs', function () { - it('should return nothing when sync is disabled', function () { - const syncOptions = { - 'iframeEnabled': false, - 'pixelEnabled': false - } - let syncs = spec.getUserSyncs(syncOptions); - expect(syncs).to.deep.equal([]); - }); - - it('should register iframe sync when iframe is enabled', function () { - const syncOptions = { - 'iframeEnabled': true, - 'pixelEnabled': false - } - let syncs = spec.getUserSyncs(syncOptions); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.equal('https://tags.mobsmart.net/tags/iframe'); - }); - - it('should register image sync when image is enabled', function () { - const syncOptions = { - 'iframeEnabled': false, - 'pixelEnabled': true - } - let syncs = spec.getUserSyncs(syncOptions); - expect(syncs[0].type).to.equal('image'); - expect(syncs[0].url).to.equal('https://tags.mobsmart.net/tags/image'); - }); - - it('should register iframe sync when iframe is enabled', function () { - const syncOptions = { - 'iframeEnabled': true, - 'pixelEnabled': true - } - let syncs = spec.getUserSyncs(syncOptions); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.equal('https://tags.mobsmart.net/tags/iframe'); - }); - }); -}); diff --git a/test/spec/modules/multibid_spec.js b/test/spec/modules/multibid_spec.js deleted file mode 100644 index e849392ee4b..00000000000 --- a/test/spec/modules/multibid_spec.js +++ /dev/null @@ -1,845 +0,0 @@ -import {expect} from 'chai'; -import { - validateMultibid, - adjustBidderRequestsHook, - addBidResponseHook, - resetMultibidUnits, - sortByMultibid, - targetBidPoolHook, - resetMultiConfig -} from 'modules/multibid/index.js'; -import {parse as parseQuery} from 'querystring'; -import {config} from 'src/config.js'; -import * as utils from 'src/utils.js'; -import find from 'core-js-pure/features/array/find.js'; - -describe('multibid adapter', function () { - let bidArray = [{ - 'bidderCode': 'bidderA', - 'requestId': '1c5f0a05d3629a', - 'cpm': 75, - 'originalCpm': 75, - 'bidder': 'bidderA', - }, { - 'bidderCode': 'bidderA', - 'cpm': 52, - 'requestId': '2e6j8s05r4363h', - 'originalCpm': 52, - 'bidder': 'bidderA', - }]; - let bidCacheArray = [{ - 'bidderCode': 'bidderA', - 'requestId': '1c5f0a05d3629a', - 'cpm': 66, - 'originalCpm': 66, - 'bidder': 'bidderA', - 'originalBidder': 'bidderA', - 'multibidPrefix': 'bidA' - }, { - 'bidderCode': 'bidderA', - 'cpm': 38, - 'requestId': '2e6j8s05r4363h', - 'originalCpm': 38, - 'bidder': 'bidderA', - 'originalBidder': 'bidderA', - 'multibidPrefix': 'bidA' - }]; - let bidArrayAlt = [{ - 'bidderCode': 'bidderA', - 'requestId': '1c5f0a05d3629a', - 'cpm': 29, - 'originalCpm': 29, - 'bidder': 'bidderA' - }, { - 'bidderCode': 'bidderA', - 'cpm': 52, - 'requestId': '2e6j8s05r4363h', - 'originalCpm': 52, - 'bidder': 'bidderA' - }, { - 'bidderCode': 'bidderB', - 'cpm': 3, - 'requestId': '7g8h5j45l7654i', - 'originalCpm': 3, - 'bidder': 'bidderB' - }, { - 'bidderCode': 'bidderC', - 'cpm': 12, - 'requestId': '9d7f4h56t6483u', - 'originalCpm': 12, - 'bidder': 'bidderC' - }]; - let bidderRequests = [{ - 'bidderCode': 'bidderA', - 'auctionId': 'e6bd4400-28fc-459b-9905-ad64d044daaa', - 'bidderRequestId': '10e78266423c0e', - 'bids': [{ - 'bidder': 'bidderA', - 'params': {'placementId': 1234567}, - 'crumbs': {'pubcid': 'fb4cfc66-ff3d-4fda-bef8-3f2cb6fe9412'}, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'adUnitCode': 'test-div', - 'transactionId': 'c153f3da-84f0-4be8-95cb-0647c458bc60', - 'sizes': [[300, 250]], - 'bidId': '2408ef83b84c9d', - 'bidderRequestId': '10e78266423c0e', - 'auctionId': 'e6bd4400-28fc-459b-9905-ad64d044daaa', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - }] - }, { - 'bidderCode': 'bidderB', - 'auctionId': 'e6bd4400-28fc-459b-9905-ad64d044daaa', - 'bidderRequestId': '10e78266423c0e', - 'bids': [{ - 'bidder': 'bidderB', - 'params': {'placementId': 1234567}, - 'crumbs': {'pubcid': 'fb4cfc66-ff3d-4fda-bef8-3f2cb6fe9412'}, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'adUnitCode': 'test-div', - 'transactionId': 'c153f3da-84f0-4be8-95cb-0647c458bc60', - 'sizes': [[300, 250]], - 'bidId': '2408ef83b84c9d', - 'bidderRequestId': '10e78266423c0e', - 'auctionId': 'e6bd4400-28fc-459b-9905-ad64d044daaa', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - }] - }]; - - afterEach(function () { - config.resetConfig(); - resetMultiConfig(); - resetMultibidUnits(); - }); - - describe('adjustBidderRequestsHook', function () { - let result; - let callbackFn = function (bidderRequests) { - result = bidderRequests; - }; - - beforeEach(function() { - result = null; - }); - - it('does not modify bidderRequest when no multibid config exists', function () { - let bidRequests = [{...bidderRequests[0]}]; - - adjustBidderRequestsHook(callbackFn, bidRequests); - - expect(result).to.not.equal(null); - expect(result).to.deep.equal(bidRequests); - }); - - it('does modify bidderRequest when multibid config exists', function () { - let bidRequests = [{...bidderRequests[0]}]; - - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2}]}); - - adjustBidderRequestsHook(callbackFn, [{...bidderRequests[0]}]); - - expect(result).to.not.equal(null); - expect(result).to.not.deep.equal(bidRequests); - expect(result[0].bidLimit).to.equal(2); - }); - - it('does modify bidderRequest when multibid config exists using bidders array', function () { - let bidRequests = [{...bidderRequests[0]}]; - - config.setConfig({multibid: [{bidders: ['bidderA'], maxBids: 2}]}); - - adjustBidderRequestsHook(callbackFn, [{...bidderRequests[0]}]); - - expect(result).to.not.equal(null); - expect(result).to.not.deep.equal(bidRequests); - expect(result[0].bidLimit).to.equal(2); - }); - - it('does only modifies bidderRequest when multibid config exists for bidder', function () { - let bidRequests = [{...bidderRequests[0]}, {...bidderRequests[1]}]; - - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2}]}); - - adjustBidderRequestsHook(callbackFn, [{...bidderRequests[0]}, {...bidderRequests[1]}]); - - expect(result).to.not.equal(null); - expect(result[0]).to.not.deep.equal(bidRequests[0]); - expect(result[0].bidLimit).to.equal(2); - expect(result[1]).to.deep.equal(bidRequests[1]); - expect(result[1].bidLimit).to.equal(undefined); - }); - }); - - describe('addBidResponseHook', function () { - let result; - let callbackFn = function (adUnitCode, bid) { - result = { - 'adUnitCode': adUnitCode, - 'bid': bid - }; - }; - - beforeEach(function() { - result = null; - }); - - it('adds original bids and does not modify', function () { - let adUnitCode = 'test-div'; - let bids = [{...bidArray[0]}, {...bidArray[1]}]; - - addBidResponseHook(callbackFn, adUnitCode, {...bids[0]}); - - expect(result).to.not.equal(null); - expect(result.adUnitCode).to.not.equal(null); - expect(result.adUnitCode).to.equal('test-div'); - expect(result.bid).to.not.equal(null); - expect(result.bid).to.deep.equal(bids[0]); - - result = null; - - addBidResponseHook(callbackFn, adUnitCode, {...bids[1]}); - - expect(result).to.not.equal(null); - expect(result.adUnitCode).to.not.equal(null); - expect(result.adUnitCode).to.equal('test-div'); - expect(result.bid).to.not.equal(null); - expect(result.bid).to.deep.equal(bids[1]); - }); - - it('modifies and adds both bids based on multibid configuration', function () { - let adUnitCode = 'test-div'; - let bids = [{...bidArray[0]}, {...bidArray[1]}]; - - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA'}]}); - - addBidResponseHook(callbackFn, adUnitCode, {...bids[0]}); - - bids[0].multibidPrefix = 'bidA'; - bids[0].originalBidder = 'bidderA'; - - expect(result).to.not.equal(null); - expect(result.adUnitCode).to.not.equal(null); - expect(result.adUnitCode).to.equal('test-div'); - expect(result.bid).to.not.equal(null); - expect(result.bid).to.deep.equal(bids[0]); - - result = null; - - addBidResponseHook(callbackFn, adUnitCode, {...bids[1]}); - - bids[1].multibidPrefix = 'bidA'; - bids[1].originalBidder = 'bidderA'; - bids[1].targetingBidder = 'bidA2'; - bids[1].originalRequestId = '2e6j8s05r4363h'; - - delete bids[1].requestId; - delete result.bid.requestId; - - expect(result).to.not.equal(null); - expect(result.adUnitCode).to.not.equal(null); - expect(result.adUnitCode).to.equal('test-div'); - expect(result.bid).to.not.equal(null); - expect(result.bid).to.deep.equal(bids[1]); - }); - - it('only modifies bids defined in the multibid configuration', function () { - let adUnitCode = 'test-div'; - let bids = [{...bidArray[0]}, {...bidArray[1]}]; - - bids.push({ - 'bidderCode': 'bidderB', - 'cpm': 33, - 'requestId': '1j8s5f89y2345l', - 'originalCpm': 33, - 'bidder': 'bidderB', - }); - - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA'}]}); - - addBidResponseHook(callbackFn, adUnitCode, {...bids[0]}); - - bids[0].multibidPrefix = 'bidA'; - bids[0].originalBidder = 'bidderA'; - - expect(result).to.not.equal(null); - expect(result.adUnitCode).to.not.equal(null); - expect(result.adUnitCode).to.equal('test-div'); - expect(result.bid).to.not.equal(null); - expect(result.bid).to.deep.equal(bids[0]); - - result = null; - - addBidResponseHook(callbackFn, adUnitCode, {...bids[1]}); - - bids[1].multibidPrefix = 'bidA'; - bids[1].originalBidder = 'bidderA'; - bids[1].targetingBidder = 'bidA2'; - bids[1].originalRequestId = '2e6j8s05r4363h'; - bids[1].requestId = result.bid.requestId; - - expect(result).to.not.equal(null); - expect(result.adUnitCode).to.not.equal(null); - expect(result.adUnitCode).to.equal('test-div'); - expect(result.bid).to.not.equal(null); - expect(result.bid).to.deep.equal(bids[1]); - - result = null; - - addBidResponseHook(callbackFn, adUnitCode, {...bids[2]}); - - expect(result).to.not.equal(null); - expect(result.adUnitCode).to.not.equal(null); - expect(result.adUnitCode).to.equal('test-div'); - expect(result.bid).to.not.equal(null); - expect(result.bid).to.deep.equal(bids[2]); - }); - - it('only modifies and returns bids under limit for a specifc bidder in the multibid configuration', function () { - let adUnitCode = 'test-div'; - let bids = [{...bidArray[0]}, {...bidArray[1]}]; - - bids.push({ - 'bidderCode': 'bidderA', - 'cpm': 33, - 'requestId': '1j8s5f89y2345l', - 'originalCpm': 33, - 'bidder': 'bidderA', - }); - - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA'}]}); - - addBidResponseHook(callbackFn, adUnitCode, {...bids[0]}); - - bids[0].multibidPrefix = 'bidA'; - bids[0].originalBidder = 'bidderA'; - - expect(result).to.not.equal(null); - expect(result.adUnitCode).to.not.equal(null); - expect(result.adUnitCode).to.equal('test-div'); - expect(result.bid).to.not.equal(null); - expect(result.bid).to.deep.equal(bids[0]); - - result = null; - - addBidResponseHook(callbackFn, adUnitCode, {...bids[1]}); - - bids[1].multibidPrefix = 'bidA'; - bids[1].originalBidder = 'bidderA'; - bids[1].targetingBidder = 'bidA2'; - bids[1].originalRequestId = '2e6j8s05r4363h'; - bids[1].requestId = result.bid.requestId; - - expect(result).to.not.equal(null); - expect(result.adUnitCode).to.not.equal(null); - expect(result.adUnitCode).to.equal('test-div'); - expect(result.bid).to.not.equal(null); - expect(result.bid).to.deep.equal(bids[1]); - - result = null; - - 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 () { - let adUnitCode = 'test-div'; - let bids = [{...bidArray[0]}, {...bidArray[1]}]; - - bids.push({ - 'bidderCode': 'bidderA', - 'cpm': 33, - 'requestId': '1j8s5f89y2345l', - 'originalCpm': 33, - 'bidder': 'bidderA', - }); - - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2}]}); - - addBidResponseHook(callbackFn, adUnitCode, {...bids[0]}); - - bids[0].originalBidder = 'bidderA'; - - expect(result).to.not.equal(null); - expect(result.adUnitCode).to.not.equal(null); - expect(result.adUnitCode).to.equal('test-div'); - expect(result.bid).to.not.equal(null); - expect(result.bid).to.deep.equal(bids[0]); - - result = null; - - addBidResponseHook(callbackFn, adUnitCode, {...bids[1]}); - - bids[1].originalBidder = 'bidderA'; - bids[1].originalRequestId = '2e6j8s05r4363h'; - bids[1].requestId = result.bid.requestId; - - expect(result).to.not.equal(null); - expect(result.adUnitCode).to.not.equal(null); - expect(result.adUnitCode).to.equal('test-div'); - expect(result.bid).to.not.equal(null); - expect(result.bid).to.deep.equal(bids[1]); - - result = null; - - addBidResponseHook(callbackFn, adUnitCode, {...bids[2]}); - - expect(result).to.equal(null); - }); - - it('does not include extra bids if cpm is less than floor value', function () { - let adUnitCode = 'test-div'; - let bids = [{...bidArrayAlt[1]}, {...bidArrayAlt[0]}, {...bidArrayAlt[2]}, {...bidArrayAlt[3]}]; - - bids.map(bid => { - bid.floorData = { - cpmAfterAdjustments: bid.cpm, - enforcements: { - enforceJS: true, - enforcePBS: false, - floorDeals: false, - bidAdjustment: true - }, - floorCurrency: 'USD', - floorRule: '*|banner', - floorRuleValue: 65, - floorValue: 65, - matchedFields: { - gptSlot: 'test-div', - mediaType: 'banner' - } - } - - return bid; - }); - - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA'}]}); - - addBidResponseHook(callbackFn, adUnitCode, {...bids[0]}); - - bids[0].multibidPrefix = 'bidA'; - bids[0].originalBidder = 'bidderA'; - - expect(result).to.not.equal(null); - expect(result.adUnitCode).to.not.equal(null); - expect(result.adUnitCode).to.equal('test-div'); - expect(result.bid).to.not.equal(null); - expect(result.bid.bidder).to.equal('bidderA'); - expect(result.bid.targetingBidder).to.equal(undefined); - - result = null; - - addBidResponseHook(callbackFn, adUnitCode, {...bids[1]}); - - expect(result).to.equal(null); - - result = null; - - addBidResponseHook(callbackFn, adUnitCode, {...bids[2]}); - - expect(result).to.not.equal(null); - expect(result.adUnitCode).to.not.equal(null); - expect(result.adUnitCode).to.equal('test-div'); - expect(result.bid).to.not.equal(null); - expect(result.bid.bidder).to.equal('bidderB'); - expect(result.bid.targetingBidder).to.equal(undefined); - - result = null; - - addBidResponseHook(callbackFn, adUnitCode, {...bids[3]}); - - expect(result).to.not.equal(null); - expect(result.adUnitCode).to.not.equal(null); - expect(result.adUnitCode).to.equal('test-div'); - expect(result.bid).to.not.equal(null); - expect(result.bid.bidder).to.equal('bidderC'); - expect(result.bid.targetingBidder).to.equal(undefined); - }); - - it('does include extra bids if cpm is not less than floor value', function () { - let adUnitCode = 'test-div'; - let bids = [{...bidArrayAlt[1]}, {...bidArrayAlt[0]}]; - - bids.map(bid => { - bid.floorData = { - cpmAfterAdjustments: bid.cpm, - enforcements: { - enforceJS: true, - enforcePBS: false, - floorDeals: false, - bidAdjustment: true - }, - floorCurrency: 'USD', - floorRule: '*|banner', - floorRuleValue: 25, - floorValue: 25, - matchedFields: { - gptSlot: 'test-div', - mediaType: 'banner' - } - } - - return bid; - }); - - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA'}]}); - - addBidResponseHook(callbackFn, adUnitCode, {...bids[0]}); - - bids[0].multibidPrefix = 'bidA'; - bids[0].originalBidder = 'bidderA'; - - expect(result).to.not.equal(null); - expect(result.adUnitCode).to.not.equal(null); - expect(result.adUnitCode).to.equal('test-div'); - expect(result.bid).to.not.equal(null); - expect(result.bid.bidder).to.equal('bidderA'); - expect(result.bid.targetingBidder).to.equal(undefined); - - result = null; - - addBidResponseHook(callbackFn, adUnitCode, {...bids[0]}); - - bids[0].multibidPrefix = 'bidA'; - bids[0].originalBidder = 'bidderA'; - - expect(result).to.not.equal(null); - expect(result.adUnitCode).to.not.equal(null); - expect(result.adUnitCode).to.equal('test-div'); - expect(result.bid).to.not.equal(null); - expect(result.bid.bidder).to.equal('bidderA'); - expect(result.bid.targetingBidder).to.equal('bidA2'); - }); - }); - - describe('targetBidPoolHook', function () { - let result; - let bidResult; - let callbackFn = function (bidsReceived, highestCpmCallback, adUnitBidLimit = 0, hasModified = false) { - result = { - 'bidsReceived': bidsReceived, - 'adUnitBidLimit': adUnitBidLimit, - 'hasModified': hasModified - }; - }; - let bidResponseCallback = function (adUnitCode, bid) { - bidResult = bid; - }; - - beforeEach(function() { - result = null; - bidResult = null; - }); - - it('it does not run filter on bidsReceived if no multibid configuration found', function () { - let bids = [{...bidArray[0]}, {...bidArray[1]}]; - targetBidPoolHook(callbackFn, bids, utils.getHighestCpm); - - expect(result).to.not.equal(null); - expect(result.bidsReceived).to.not.equal(null); - expect(result.bidsReceived.length).to.equal(2); - expect(result.bidsReceived).to.deep.equal(bids); - expect(result.adUnitBidLimit).to.not.equal(null); - expect(result.adUnitBidLimit).to.equal(0); - expect(result.hasModified).to.not.equal(null); - expect(result.hasModified).to.equal(false); - }); - - it('it does filter on bidsReceived if multibid configuration found with no prefix', function () { - let bids = [{...bidArray[0]}, {...bidArray[1]}]; - - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2}]}); - - targetBidPoolHook(callbackFn, bids, utils.getHighestCpm); - bids.pop(); - - expect(result).to.not.equal(null); - expect(result.bidsReceived).to.not.equal(null); - expect(result.bidsReceived.length).to.equal(1); - expect(result.bidsReceived).to.deep.equal(bids); - expect(result.adUnitBidLimit).to.not.equal(null); - expect(result.adUnitBidLimit).to.equal(0); - expect(result.hasModified).to.not.equal(null); - expect(result.hasModified).to.equal(true); - }); - - it('it sorts and creates dynamic alias on bidsReceived if multibid configuration found with prefix', function () { - let modifiedBids = [{...bidArray[1]}, {...bidArray[0]}].map(bid => { - addBidResponseHook(bidResponseCallback, 'test-div', {...bid}); - - return bidResult; - }); - - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA'}]}); - - targetBidPoolHook(callbackFn, modifiedBids, utils.getHighestCpm); - - expect(result).to.not.equal(null); - expect(result.bidsReceived).to.not.equal(null); - expect(result.bidsReceived.length).to.equal(2); - expect(result.bidsReceived).to.deep.equal([modifiedBids[1], modifiedBids[0]]); - expect(result.bidsReceived[0].bidderCode).to.equal('bidderA'); - expect(result.bidsReceived[0].bidder).to.equal('bidderA'); - expect(result.bidsReceived[1].bidderCode).to.equal('bidA2'); - expect(result.bidsReceived[1].bidder).to.equal('bidderA'); - expect(result.adUnitBidLimit).to.not.equal(null); - expect(result.adUnitBidLimit).to.equal(0); - expect(result.hasModified).to.not.equal(null); - expect(result.hasModified).to.equal(true); - }); - - it('it sorts by cpm treating dynamic alias as unique bid when no bid limit defined', function () { - let 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'}]}); - - targetBidPoolHook(callbackFn, modifiedBids, utils.getHighestCpm); - - expect(result).to.not.equal(null); - expect(result.bidsReceived).to.not.equal(null); - expect(result.bidsReceived.length).to.equal(4); - expect(result.bidsReceived).to.deep.equal([modifiedBids[3], modifiedBids[0], modifiedBids[2], modifiedBids[1]]); - expect(result.bidsReceived[0].bidderCode).to.equal('bidderA'); - expect(result.bidsReceived[0].bidder).to.equal('bidderA'); - expect(result.bidsReceived[0].cpm).to.equal(52); - expect(result.bidsReceived[1].bidderCode).to.equal('bidA2'); - expect(result.bidsReceived[1].bidder).to.equal('bidderA'); - expect(result.bidsReceived[1].cpm).to.equal(29); - expect(result.bidsReceived[2].bidderCode).to.equal('bidderC'); - expect(result.bidsReceived[2].bidder).to.equal('bidderC'); - expect(result.bidsReceived[2].cpm).to.equal(12); - expect(result.bidsReceived[3].bidderCode).to.equal('bidderB'); - expect(result.bidsReceived[3].bidder).to.equal('bidderB'); - expect(result.bidsReceived[3].cpm).to.equal(3); - expect(result.adUnitBidLimit).to.not.equal(null); - expect(result.adUnitBidLimit).to.equal(0); - expect(result.hasModified).to.not.equal(null); - expect(result.hasModified).to.equal(true); - }); - - it('it should filter out dynamic bid when bid limit is less than unique bid pool', function () { - let 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'}] }); - - targetBidPoolHook(callbackFn, modifiedBids, utils.getHighestCpm, 3); - - expect(result).to.not.equal(null); - expect(result.bidsReceived).to.not.equal(null); - expect(result.bidsReceived.length).to.equal(3); - expect(result.bidsReceived).to.deep.equal([modifiedBids[3], modifiedBids[2], modifiedBids[1]]); - expect(result.bidsReceived[0].bidderCode).to.equal('bidderA'); - expect(result.bidsReceived[1].bidderCode).to.equal('bidderC'); - expect(result.bidsReceived[2].bidderCode).to.equal('bidderB'); - expect(result.adUnitBidLimit).to.not.equal(null); - expect(result.adUnitBidLimit).to.equal(3); - expect(result.hasModified).to.not.equal(null); - expect(result.hasModified).to.equal(true); - }); - - 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'}] }); - - let modifiedBids = [{...bidArrayAlt[0]}, {...bidArrayAlt[2]}, {...bidArrayAlt[3]}, {...bidArrayAlt[1]}].map(bid => { - addBidResponseHook(bidResponseCallback, 'test-div', {...bid}); - - return bidResult; - }); - - let bidPool = [].concat.apply(modifiedBids, [{...bidCacheArray[0]}, {...bidCacheArray[1]}]); - - expect(bidPool.length).to.equal(6); - - targetBidPoolHook(callbackFn, bidPool, utils.getHighestCpm); - - expect(result).to.not.equal(null); - expect(result.bidsReceived).to.not.equal(null); - expect(result.bidsReceived.length).to.equal(4); - expect(result.bidsReceived).to.deep.equal([bidPool[4], bidPool[3], bidPool[2], bidPool[1]]); - expect(result.bidsReceived[0].bidderCode).to.equal('bidderA'); - expect(result.bidsReceived[1].bidderCode).to.equal('bidA2'); - expect(result.bidsReceived[2].bidderCode).to.equal('bidderC'); - expect(result.bidsReceived[3].bidderCode).to.equal('bidderB'); - expect(result.adUnitBidLimit).to.not.equal(null); - expect(result.adUnitBidLimit).to.equal(0); - expect(result.hasModified).to.not.equal(null); - expect(result.hasModified).to.equal(true); - }); - }); - - describe('validate multibid', function () { - it('should fail validation for missing bidder name in entry', function () { - let conf = [{maxBids: 1}]; - let result = validateMultibid(conf); - - expect(result).to.equal(false); - }); - - it('should pass validation on all multibid entries', function () { - let conf = [{bidder: 'bidderA', maxBids: 1}, {bidder: 'bidderB', maxBids: 2}]; - let result = validateMultibid(conf); - - expect(result).to.equal(true); - }); - - it('should fail validation for maxbids less than 1 in entry', function () { - let conf = [{bidder: 'bidderA', maxBids: 0}, {bidder: 'bidderB', maxBids: 2}]; - let result = validateMultibid(conf); - - expect(result).to.equal(false); - }); - - it('should fail validation for maxbids greater than 9 in entry', function () { - let conf = [{bidder: 'bidderA', maxBids: 10}, {bidder: 'bidderB', maxBids: 2}]; - let result = validateMultibid(conf); - - expect(result).to.equal(false); - }); - - it('should add multbid entries to global config', function () { - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 1}]}); - let conf = config.getConfig('multibid'); - - 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}]}); - let conf = config.getConfig('multibid'); - - 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}]}); - let conf = config.getConfig('multibid'); - - expect(conf.length).to.equal(1); - expect(conf).to.deep.equal([{bidder: 'bidderA', maxBids: 1}]); - }); - }); - - describe('sort multibid', function () { - it('should not alter order', function () { - let bids = [{ - 'bidderCode': 'bidderA', - 'cpm': 75, - 'originalCpm': 75, - 'multibidPrefix': 'bidA', - 'originalBidder': 'bidderA', - 'bidder': 'bidderA', - }, { - 'bidderCode': 'bidA2', - 'cpm': 75, - 'originalCpm': 75, - 'multibidPrefix': 'bidA', - 'originalBidder': 'bidderA', - 'bidder': 'bidderA', - }]; - - let expected = [{ - 'bidderCode': 'bidderA', - 'cpm': 75, - 'originalCpm': 75, - 'multibidPrefix': 'bidA', - 'originalBidder': 'bidderA', - 'bidder': 'bidderA', - }, { - 'bidderCode': 'bidA2', - 'cpm': 75, - 'originalCpm': 75, - 'multibidPrefix': 'bidA', - 'originalBidder': 'bidderA', - 'bidder': 'bidderA', - }]; - let result = bids.sort(sortByMultibid); - - expect(result).to.deep.equal(expected); - }); - - it('should sort dynamic alias bidders to end', function () { - let bids = [{ - 'bidderCode': 'bidA2', - 'cpm': 75, - 'originalCpm': 75, - 'multibidPrefix': 'bidA', - 'originalBidder': 'bidderA', - 'bidder': 'bidderA', - }, { - 'bidderCode': 'bidderA', - 'cpm': 22, - 'originalCpm': 22, - 'multibidPrefix': 'bidA', - 'originalBidder': 'bidderA', - 'bidder': 'bidderA', - }, { - 'bidderCode': 'bidderB', - 'cpm': 4, - 'originalCpm': 4, - 'multibidPrefix': 'bidB', - 'originalBidder': 'bidderB', - 'bidder': 'bidderB', - }, { - 'bidderCode': 'bidB', - 'cpm': 2, - 'originalCpm': 2, - 'multibidPrefix': 'bidB', - 'originalBidder': 'bidderB', - 'bidder': 'bidderB', - }]; - let expected = [{ - 'bidderCode': 'bidderA', - 'cpm': 22, - 'originalCpm': 22, - 'multibidPrefix': 'bidA', - 'originalBidder': 'bidderA', - 'bidder': 'bidderA', - }, { - 'bidderCode': 'bidderB', - 'cpm': 4, - 'originalCpm': 4, - 'multibidPrefix': 'bidB', - 'originalBidder': 'bidderB', - 'bidder': 'bidderB', - }, { - 'bidderCode': 'bidA2', - 'cpm': 75, - 'originalCpm': 75, - 'multibidPrefix': 'bidA', - 'originalBidder': 'bidderA', - 'bidder': 'bidderA', - }, { - 'bidderCode': 'bidB', - 'cpm': 2, - 'originalCpm': 2, - 'multibidPrefix': 'bidB', - 'originalBidder': 'bidderB', - 'bidder': 'bidderB', - }]; - let result = bids.sort(sortByMultibid); - - expect(result).to.deep.equal(expected); - }); - }); -}); diff --git a/test/spec/modules/mwOpenLinkIdSystem_spec.js b/test/spec/modules/mwOpenLinkIdSystem_spec.js deleted file mode 100644 index fb082b8cd16..00000000000 --- a/test/spec/modules/mwOpenLinkIdSystem_spec.js +++ /dev/null @@ -1,20 +0,0 @@ -import { writeCookie, mwOpenLinkIdSubModule } from 'modules/mwOpenLinkIdSystem.js'; - -const P_CONFIG_MOCK = { - params: { - accountId: '123', - partnerId: '123' - } -}; - -describe('mwOpenLinkId module', function () { - beforeEach(function() { - writeCookie(''); - }); - - it('getId() should return a MediaWallah openLink Id when the MediaWallah openLink first party cookie exists', function () { - 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'}}); - }); -}); diff --git a/test/spec/modules/my6senseBidAdapter_spec.js b/test/spec/modules/my6senseBidAdapter_spec.js deleted file mode 100644 index 5e51280d70b..00000000000 --- a/test/spec/modules/my6senseBidAdapter_spec.js +++ /dev/null @@ -1,151 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/my6senseBidAdapter.js'; - -describe('My6sense Bid adapter test', function () { - let bidRequests, serverResponses; - beforeEach(function () { - bidRequests = [ - { - // valid 1 - bidder: 'my6sense', - params: { - key: 'DTAeOJN67pCjY36dbhrM3G', - dataVersion: 3, - pageUrl: 'liran.com', - zone: '[ZONE]', - dataParams: '', - dataView: '', - organicClicks: '', - paidClicks: '' - } - }, - { - // invalid 2- no params - bidder: 'my6sense' - }, - { - // invalid 3 - no key in params - bidder: 'my6sense', - params: { - dataVersion: 3, - pageUrl: 'liran.com', - zone: '[ZONE]', - dataParams: '', - dataView: '', - organicClicks: '', - paidClicks: '' - } - }, - { - // invalid 3 - wrong bidder name - bidder: 'test', - params: { - key: 'ZxA0bNhlO9tf5EZ1Q9ZYdS', - dataVersion: 3, - pageUrl: 'liran.com', - zone: '[ZONE]', - dataParams: '', - dataView: '', - organicClicks: '', - paidClicks: '' - } - } - ]; - serverResponses = [ - { - headers: {}, - body: { - cpm: 1.5, - width: 300, - height: 250, - placement_id: 1, - adm: '' - } - }, - { - headers: {}, - body: { - cpm: 0, - width: 0, - height: 0, - placement_id: 1, - adm: '' - } - }, - { - headers: {}, - body: { - cpm: 0, - width: 0, - height: 0, - placement_id: 0, - adm: '' - } - }, - { - headers: {}, - body: { - cpm: 5, - creativeId: '5b29f5d1e4b086e3ee8de36b', - currency: 'USD', - height: 250, - netRevenue: false, - requestId: '2954a0957643bb', - ttl: 360, - width: 300, - adm: '' - } - } - ] - }); - - describe('test if requestIsValid function', function () { - it('with valid data 1', function () { - expect(spec.isBidRequestValid(bidRequests[0])).to.equal(true); - }); - it('with invalid data 2', function () { - expect(spec.isBidRequestValid(bidRequests[1])).to.equal(false); - }); - it('with invalid data 3', function () { - expect(spec.isBidRequestValid(bidRequests[2])).to.equal(false); - }); - it('with invalid data 3', function () { - expect(spec.isBidRequestValid(bidRequests[3])).to.equal(false); - }); - }); - - describe('test if buildRequests function', function () { - it('normal', function () { - var requests = spec.buildRequests([bidRequests[0]]); - expect(requests).to.be.lengthOf(1); - }); - }); - describe('test bid responses', function () { - it('success 1', function () { - 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); - expect(bids[0].height).to.equal(250); - expect(bids[0].adm).to.have.length.above(1); - }); - it('success 2', function () { - var bids = spec.interpretResponse(serverResponses[3]); - expect(bids).to.be.lengthOf(1); - expect(bids[0].cpm).to.equal(5); - expect(bids[0].width).to.equal(300); - expect(bids[0].height).to.equal(250); - expect(bids[0].netRevenue).to.equal(false); - expect(bids[0].ttl).to.equal(360); - expect(bids[0].currency).to.equal('USD'); - }); - it('fail 1 (cpm=0)', function () { - var bids = spec.interpretResponse(serverResponses[1]); - expect(bids).to.be.lengthOf(1); - }); - it('fail 2 (no response)', function () { - var bids = spec.interpretResponse([]); - expect(bids).to.be.lengthOf(0); - }); - }); -}); diff --git a/test/spec/modules/mytargetBidAdapter_spec.js b/test/spec/modules/mytargetBidAdapter_spec.js deleted file mode 100644 index ea998303fe3..00000000000 --- a/test/spec/modules/mytargetBidAdapter_spec.js +++ /dev/null @@ -1,229 +0,0 @@ -import { expect } from 'chai'; -import { config } from 'src/config.js'; -import { spec } from 'modules/mytargetBidAdapter.js'; - -describe('MyTarget Adapter', function() { - describe('isBidRequestValid', function () { - it('should return true when required params found', function () { - let validBid = { - bidder: 'mytarget', - params: { - placementId: '1' - } - }; - - expect(spec.isBidRequestValid(validBid)).to.equal(true); - }); - - it('should return false for when required params are not passed', function () { - let invalidBid = { - bidder: 'mytarget', - params: {} - }; - - expect(spec.isBidRequestValid(invalidBid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [ - { - bidId: 'bid1', - bidder: 'mytarget', - params: { - placementId: '1' - } - }, - { - bidId: 'bid2', - bidder: 'mytarget', - params: { - placementId: '2', - position: 1, - response: 1, - bidfloor: 10000 - } - } - ]; - let bidderRequest = { - refererInfo: { - referer: 'https://example.com?param=value' - } - }; - - let bidRequest = spec.buildRequests(bidRequests, bidderRequest); - - it('should build single POST request for multiple bids', function() { - expect(bidRequest.method).to.equal('POST'); - expect(bidRequest.url).to.equal('https://ad.mail.ru/hbid_prebid/'); - expect(bidRequest.data).to.be.an('object'); - expect(bidRequest.data.places).to.be.an('array'); - expect(bidRequest.data.places).to.have.lengthOf(2); - }); - - it('should pass bid parameters', function() { - let place1 = bidRequest.data.places[0]; - let place2 = bidRequest.data.places[1]; - - expect(place1.placementId).to.equal('1'); - expect(place2.placementId).to.equal('2'); - expect(place1.id).to.equal('bid1'); - expect(place2.id).to.equal('bid2'); - }); - - it('should pass default position and response type', function() { - let place = bidRequest.data.places[0]; - - expect(place.position).to.equal(0); - expect(place.response).to.equal(0); - }); - - it('should pass provided position and response type', function() { - let place = bidRequest.data.places[1]; - - expect(place.position).to.equal(1); - expect(place.response).to.equal(1); - }); - - it('should not pass default bidfloor', function() { - let place = bidRequest.data.places[0]; - - expect(place.bidfloor).not.to.exist; - }); - - it('should not pass provided bidfloor', function() { - let place = bidRequest.data.places[1]; - - expect(place.bidfloor).to.exist; - expect(place.bidfloor).to.equal(10000); - }); - - it('should pass site parameters', function() { - let site = bidRequest.data.site; - - expect(site).to.be.an('object'); - expect(site.sitename).to.equal('example.com'); - expect(site.page).to.equal('https://example.com?param=value'); - }); - - it('should pass settings', function() { - let settings = bidRequest.data.settings; - - expect(settings).to.be.an('object'); - expect(settings.currency).to.equal('RUB'); - expect(settings.windowSize).to.be.an('object'); - expect(settings.windowSize.width).to.equal(window.screen.width); - expect(settings.windowSize.height).to.equal(window.screen.height); - }); - - it('should pass currency from currency.adServerCurrency', function() { - const configStub = sinon.stub(config, 'getConfig').callsFake( - key => key === 'currency.adServerCurrency' ? 'USD' : ''); - - let bidRequest = spec.buildRequests(bidRequests, bidderRequest); - let settings = bidRequest.data.settings; - - expect(settings).to.be.an('object'); - expect(settings.currency).to.equal('USD'); - expect(settings.windowSize).to.be.an('object'); - expect(settings.windowSize.width).to.equal(window.screen.width); - expect(settings.windowSize.height).to.equal(window.screen.height); - - configStub.restore(); - }); - - it('should ignore currency other than "RUB" or "USD"', function() { - const configStub = sinon.stub(config, 'getConfig').callsFake( - key => key === 'currency.adServerCurrency' ? 'EUR' : ''); - - let bidRequest = spec.buildRequests(bidRequests, bidderRequest); - let settings = bidRequest.data.settings; - - expect(settings).to.be.an('object'); - expect(settings.currency).to.equal('RUB'); - - configStub.restore(); - }); - }); - - describe('interpretResponse', function () { - let serverResponse = { - body: { - 'bidder_status': - [ - { - 'bidder': 'mail.ru', - 'response_time_ms': 100, - 'num_bids': 2 - } - ], - 'bids': - [ - { - 'displayUrl': 'https://ad.mail.ru/hbid_imp/12345', - 'size': - { - 'height': '400', - 'width': '240' - }, - 'id': '1', - 'currency': 'RUB', - 'price': 100, - 'ttl': 360, - 'creativeId': '123456' - }, - { - 'adm': '

Ad

', - 'size': - { - 'height': '250', - 'width': '300' - }, - 'id': '2', - 'price': 200 - } - ] - } - }; - - let bids = spec.interpretResponse(serverResponse); - - it('should return empty array for response with no bids', function() { - let emptyBids = spec.interpretResponse({ body: {} }); - - expect(emptyBids).to.have.lengthOf(0); - }); - - it('should parse all bids from response', function() { - expect(bids).to.have.lengthOf(2); - }); - - it('should parse bid with ad url', function() { - expect(bids[0].requestId).to.equal('1'); - expect(bids[0].cpm).to.equal(100); - expect(bids[0].width).to.equal('240'); - expect(bids[0].height).to.equal('400'); - expect(bids[0].ttl).to.equal(360); - expect(bids[0].currency).to.equal('RUB'); - expect(bids[0]).to.have.property('creativeId'); - expect(bids[0].creativeId).to.equal('123456'); - expect(bids[0].netRevenue).to.equal(true); - expect(bids[0].adUrl).to.equal('https://ad.mail.ru/hbid_imp/12345'); - expect(bids[0]).to.not.have.property('ad'); - }); - - it('should parse bid with ad markup', function() { - expect(bids[1].requestId).to.equal('2'); - expect(bids[1].cpm).to.equal(200); - expect(bids[1].width).to.equal('300'); - expect(bids[1].height).to.equal('250'); - expect(bids[1].ttl).to.equal(180); - expect(bids[1].currency).to.equal('RUB'); - expect(bids[1]).to.have.property('creativeId'); - expect(bids[1].creativeId).not.to.equal('123456'); - expect(bids[1].netRevenue).to.equal(true); - expect(bids[1].ad).to.equal('

Ad

'); - expect(bids[1]).to.not.have.property('adUrl'); - }); - }); -}); diff --git a/test/spec/modules/nafdigitalBidAdapter_spec.js b/test/spec/modules/nafdigitalBidAdapter_spec.js deleted file mode 100644 index c8ffb9fbbaf..00000000000 --- a/test/spec/modules/nafdigitalBidAdapter_spec.js +++ /dev/null @@ -1,283 +0,0 @@ -import { expect } from 'chai'; -import * as utils from 'src/utils.js'; -import { spec } from 'modules/nafdigitalBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -const URL = 'https://nafdigitalbidder.com/hb'; - -describe('nafdigitalBidAdapter', function() { - const adapter = newBidder(spec); - let element, win; - let bidRequests; - let sandbox; - - beforeEach(function() { - element = { - x: 0, - y: 0, - - width: 0, - height: 0, - - getBoundingClientRect: () => { - return { - width: element.width, - height: element.height, - - left: element.x, - top: element.y, - right: element.x + element.width, - bottom: element.y + element.height - }; - } - }; - win = { - document: { - visibilityState: 'visible' - }, - - innerWidth: 800, - innerHeight: 600 - }; - bidRequests = [{ - 'bidder': 'nafdigital', - 'params': { - 'publisherId': 1234567 - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '5fb26ac22bde4', - 'bidderRequestId': '4bf93aeb730cb9', - 'auctionId': 'ffe9a1f7-7b67-4bda-a8e0-9ee5dc9f442e' - }]; - - sandbox = sinon.sandbox.create(); - sandbox.stub(document, 'getElementById').withArgs('adunit-code').returns(element); - sandbox.stub(utils, 'getWindowTop').returns(win); - sandbox.stub(utils, 'getWindowSelf').returns(win); - }); - - afterEach(function() { - sandbox.restore(); - }); - - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'nafdigital', - 'params': { - 'publisherId': 1234567 - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '5fb26ac22bde4', - 'bidderRequestId': '4bf93aeb730cb9', - 'auctionId': 'ffe9a1f7-7b67-4bda-a8e0-9ee5dc9f442e', - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when tagid not passed correctly', function () { - bid.params.publisherId = undefined; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when require params are not passed', function () { - let bid = Object.assign({}, bid); - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - it('sends bid request to our endpoint via POST', function () { - const request = spec.buildRequests(bidRequests); - expect(request.method).to.equal('POST'); - }); - - it('request url should match our endpoint url', function () { - const request = spec.buildRequests(bidRequests); - expect(request.url).to.equal(URL); - }); - - 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}]); - }); - - it('accepts a single array as a size', function() { - bidRequests[0].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}]); - }); - - it('sends bidfloor param if present', function () { - bidRequests[0].params.bidFloor = 0.05; - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.imp[0].bidfloor).to.equal(0.05); - }); - - it('sends tagid', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.imp[0].tagid).to.equal('adunit-code'); - }); - - it('sends publisher id', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.site.publisher.id).to.equal(1234567); - }); - - context('when element is fully in view', function() { - it('returns 100', function() { - 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); - }); - }); - - context('when element is out of view', function() { - it('returns 0', function() { - 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); - }); - }); - - context('when element is partially in view', function() { - it('returns percentage', function() { - 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); - }); - }); - - context('when width or height of the element is zero', function() { - it('try to use alternative values', function() { - Object.assign(element, { width: 0, height: 0 }); - bidRequests[0].sizes = [[800, 2400]]; - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.imp[0].banner.ext.viewability).to.equal(25); - }); - }); - - context('when nested iframes', function() { - it('returns \'na\'', function() { - Object.assign(element, { width: 600, height: 400 }); - - utils.getWindowTop.restore(); - utils.getWindowSelf.restore(); - sandbox.stub(utils, 'getWindowTop').returns(win); - sandbox.stub(utils, 'getWindowSelf').returns({}); - - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.imp[0].banner.ext.viewability).to.equal('na'); - }); - }); - - context('when tab is inactive', function() { - it('returns 0', function() { - Object.assign(element, { width: 600, height: 400 }); - - utils.getWindowTop.restore(); - win.document.visibilityState = 'hidden'; - sandbox.stub(utils, 'getWindowTop').returns(win); - - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.imp[0].banner.ext.viewability).to.equal(0); - }); - }); - }); - - describe('interpretResponse', function () { - let response; - beforeEach(function () { - response = { - body: { - 'id': '37386aade21a71', - 'seatbid': [{ - 'bid': [{ - 'id': '376874781', - 'impid': '283a9f4cd2415d', - 'price': 0.35743275, - 'nurl': '', - 'adm': '', - 'w': 300, - 'h': 250 - }] - }] - } - }; - }); - - it('should get the correct bid response', function () { - let expectedResponse = [{ - 'requestId': '283a9f4cd2415d', - 'cpm': 0.35743275, - 'width': 300, - 'height': 250, - 'creativeId': '376874781', - 'currency': 'USD', - 'netRevenue': true, - 'mediaType': 'banner', - 'ad': `
`, - 'ttl': 60 - }]; - - let result = spec.interpretResponse(response); - expect(result[0]).to.deep.equal(expectedResponse[0]); - }); - - it('crid should default to the bid id if not on the response', function () { - let expectedResponse = [{ - 'requestId': '283a9f4cd2415d', - 'cpm': 0.35743275, - 'width': 300, - 'height': 250, - 'creativeId': response.body.seatbid[0].bid[0].id, - 'currency': 'USD', - 'netRevenue': true, - 'mediaType': 'banner', - 'ad': `
`, - 'ttl': 60 - }]; - - let result = spec.interpretResponse(response); - expect(result[0]).to.deep.equal(expectedResponse[0]); - }); - - it('handles empty bid response', function () { - let response = { - body: '' - }; - let result = spec.interpretResponse(response); - expect(result.length).to.equal(0); - }); - }); - - describe('getUserSyncs ', () => { - let syncOptions = {iframeEnabled: true, pixelEnabled: true}; - - it('should not return', () => { - let returnStatement = spec.getUserSyncs(syncOptions, []); - expect(returnStatement).to.be.empty; - }); - }); -}); diff --git a/test/spec/modules/nanointeractiveBidAdapter_spec.js b/test/spec/modules/nanointeractiveBidAdapter_spec.js deleted file mode 100644 index 715a26a4597..00000000000 --- a/test/spec/modules/nanointeractiveBidAdapter_spec.js +++ /dev/null @@ -1,466 +0,0 @@ -import {expect} from 'chai'; -import * as utils from 'src/utils.js'; -import * as sinon from 'sinon'; - -import { - BIDDER_CODE, - CATEGORY, - CATEGORY_NAME, - SSP_PLACEMENT_ID, - END_POINT_URL, - NQ, - NQ_NAME, - REF, - spec, - SUB_ID -} from '../../../modules/nanointeractiveBidAdapter.js'; - -describe('nanointeractive adapter tests', function () { - const SIZES_PARAM = 'sizes'; - const BID_ID_PARAM = 'bidId'; - const BID_ID_VALUE = '24a1c9ec270973'; - const DATA_PARTNER_PIXEL_ID_VALUE = 'testPID'; - const NQ_VALUE = 'rumpelstiltskin'; - const NQ_NAME_QUERY_PARAM = 'nqName'; - const CATEGORY_VALUE = 'some category'; - const CATEGORY_NAME_QUERY_PARAM = 'catName'; - const SUB_ID_VALUE = '123'; - const REF_NO_VALUE = 'none'; - const REF_OTHER_VALUE = 'other'; - const WIDTH1 = 300; - const HEIGHT1 = 250; - const WIDTH2 = 468; - const HEIGHT2 = 60; - const SIZES_VALUE = [[WIDTH1, HEIGHT1], [WIDTH2, HEIGHT2]]; - const AD = ' '; - const CPM = 1; - - function getBidRequest(params) { - return { - bidder: BIDDER_CODE, - params: params, - placementCode: 'div-gpt-ad-1460505748561-0', - transactionId: 'ee335735-ddd3-41f2-b6c6-e8aa99f81c0f', - [SIZES_PARAM]: SIZES_VALUE, - [BID_ID_PARAM]: BID_ID_VALUE, - bidderRequestId: '189135372acd55', - auctionId: 'ac15bb68-4ef0-477f-93f4-de91c47f00a9' - }; - } - - describe('NanoAdapter', function () { - let nanoBidAdapter = spec; - - describe('Methods', function () { - it('Test isBidRequestValid() with valid param(s): pid', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({ - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - }))).to.equal(true); - }); - it('Test isBidRequestValid() with valid param(s): pid, nq', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({ - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ]: NQ, - }))).to.equal(true); - }); - it('Test isBidRequestValid() with valid param(s): pid, nq, category', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({ - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ]: NQ, - [CATEGORY]: CATEGORY_VALUE, - }))).to.equal(true); - }); - it('Test isBidRequestValid() with valid param(s): pid, nq, categoryName', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({ - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ]: NQ, - [CATEGORY_NAME_QUERY_PARAM]: CATEGORY_NAME_QUERY_PARAM, - }))).to.equal(true); - }); - it('Test isBidRequestValid() with valid param(s): pid, nq, subId', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({ - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ]: NQ, - [SUB_ID]: SUB_ID_VALUE, - }))).to.equal(true); - }); - it('Test isBidRequestValid() with valid param(s): pid, nqName', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({ - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ_NAME]: NQ_NAME_QUERY_PARAM, - }))).to.equal(true); - }); - it('Test isBidRequestValid() with valid param(s): pid, nqName, category', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({ - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ_NAME]: NQ_NAME_QUERY_PARAM, - [CATEGORY]: CATEGORY_VALUE, - }))).to.equal(true); - }); - it('Test isBidRequestValid() with valid param(s): pid, nqName, categoryName', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({ - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ_NAME]: NQ_NAME_QUERY_PARAM, - [CATEGORY_NAME_QUERY_PARAM]: CATEGORY_NAME_QUERY_PARAM, - }))).to.equal(true); - }); - it('Test isBidRequestValid() with valid param(s): pid, nqName, subId', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({ - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ_NAME]: NQ_NAME_QUERY_PARAM, - [SUB_ID]: SUB_ID_VALUE, - }))).to.equal(true); - }); - it('Test isBidRequestValid() with valid param(s): pid, category', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({ - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [CATEGORY]: CATEGORY_VALUE, - }))).to.equal(true); - }); - it('Test isBidRequestValid() with valid param(s): pid, category, subId', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({ - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [CATEGORY]: CATEGORY_VALUE, - [SUB_ID]: SUB_ID_VALUE, - }))).to.equal(true); - }); - it('Test isBidRequestValid() with valid param(s): pid, subId', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({ - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [SUB_ID]: SUB_ID_VALUE, - }))).to.equal(true); - }); - it('Test isBidRequestValid() with valid param(s): pid, nq, category, subId', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({ - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ]: NQ_VALUE, - [CATEGORY]: CATEGORY_VALUE, - [SUB_ID]: SUB_ID_VALUE, - }))).to.equal(true); - }); - it('Test isBidRequestValid() with valid param(s): pid, nqName, categoryName, subId', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({ - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ_NAME]: NQ_NAME_QUERY_PARAM, - [CATEGORY_NAME]: CATEGORY_NAME_QUERY_PARAM, - [SUB_ID]: SUB_ID_VALUE, - }))).to.equal(true); - }); - it('Test isBidRequestValid() with valid param(s): pid, nq, category, subId, ref (value none)', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({ - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ]: NQ_VALUE, - [CATEGORY]: CATEGORY_VALUE, - [SUB_ID]: SUB_ID_VALUE, - [REF]: REF_NO_VALUE, - }))).to.equal(true); - }); - it('Test isBidRequestValid() with valid param(s): pid, nq, category, subId, ref (value other)', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({ - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ]: NQ_VALUE, - [CATEGORY]: CATEGORY_VALUE, - [SUB_ID]: SUB_ID_VALUE, - [REF]: REF_OTHER_VALUE, - }))).to.equal(true); - }); - it('Test isBidRequestValid() with invalid param(s): empty', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({}))).to.equal(false); - }); - it('Test isBidRequestValid() with invalid param(s): pid missing', function () { - expect(nanoBidAdapter.isBidRequestValid(getBidRequest({ - [NQ]: NQ_VALUE, - [CATEGORY]: CATEGORY_VALUE, - [SUB_ID]: SUB_ID_VALUE, - }))).to.equal(false); - }); - - let sandbox; - - function getMocks() { - let mockOriginAddress = 'https://localhost'; - let mockRefAddress = 'https://some-ref.test'; - return { - 'windowLocationAddress': mockRefAddress, - 'originAddress': mockOriginAddress, - 'refAddress': '', - }; - } - - function setUpMocks() { - sinon.sandbox.restore(); - sandbox = sinon.sandbox.create(); - sandbox.stub(utils, 'getOrigin').callsFake(() => getMocks()['originAddress']); - sandbox.stub(utils, 'deepAccess').callsFake(() => getMocks()['windowLocationAddress']); - - sandbox.stub(utils, 'getParameterByName').callsFake((arg) => { - switch (arg) { - case CATEGORY_NAME_QUERY_PARAM: - return CATEGORY_VALUE; - case NQ_NAME_QUERY_PARAM: - return NQ_VALUE; - } - }); - } - - function assert( - request, - expectedPid, - expectedNq, - expectedCategory, - expectedSubId - ) { - const requestData = JSON.parse(request.data); - - expect(request.method).to.equal('POST'); - expect(request.url).to.equal(END_POINT_URL + '/hb'); - expect(requestData[0].pid).to.equal(expectedPid); - expect(requestData[0].nq.toString()).to.equal(expectedNq.toString()); - expect(requestData[0].category.toString()).to.equal(expectedCategory.toString()); - expect(requestData[0].subId).to.equal(expectedSubId); - } - - function tearDownMocks() { - sandbox.restore(); - } - - it('Test buildRequest() - pid', function () { - setUpMocks(); - let requestParams = { - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - }; - let expectedPid = DATA_PARTNER_PIXEL_ID_VALUE; - let expectedNq = [null]; - let expectedCategory = [null]; - let expectedSubId = null; - - let request = nanoBidAdapter.buildRequests([getBidRequest(requestParams)]); - - assert(request, expectedPid, expectedNq, expectedCategory, expectedSubId); - tearDownMocks(); - }); - it('Test buildRequest() - pid, nq', function () { - setUpMocks(); - let requestParams = { - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ]: NQ_VALUE, - }; - let expectedPid = DATA_PARTNER_PIXEL_ID_VALUE; - let expectedNq = [NQ_VALUE]; - let expectedCategory = [null]; - let expectedSubId = null; - - let request = nanoBidAdapter.buildRequests([getBidRequest(requestParams)]); - - assert(request, expectedPid, expectedNq, expectedCategory, expectedSubId); - tearDownMocks(); - }); - it('Test buildRequest() - pid, nq, category', function () { - setUpMocks(); - let requestParams = { - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ]: NQ_VALUE, - [CATEGORY]: CATEGORY_VALUE, - }; - let expectedPid = DATA_PARTNER_PIXEL_ID_VALUE; - let expectedNq = [NQ_VALUE]; - let expectedCategory = [CATEGORY_VALUE]; - let expectedSubId = null; - - let request = nanoBidAdapter.buildRequests([getBidRequest(requestParams)]); - - assert(request, expectedPid, expectedNq, expectedCategory, expectedSubId); - tearDownMocks(); - }); - it('Test buildRequest() - pid, nq, categoryName', function () { - setUpMocks(); - - let requestParams = { - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ]: NQ_VALUE, - [CATEGORY_NAME]: CATEGORY_NAME_QUERY_PARAM, - }; - let expectedPid = DATA_PARTNER_PIXEL_ID_VALUE; - let expectedNq = [NQ_VALUE]; - let expectedCategory = [CATEGORY_VALUE]; - let expectedSubId = null; - - let request = nanoBidAdapter.buildRequests([getBidRequest(requestParams)]); - - assert(request, expectedPid, expectedNq, expectedCategory, expectedSubId); - tearDownMocks(); - }); - it('Test buildRequest() - pid, nq, subId', function () { - setUpMocks(); - let requestParams = { - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ]: NQ_VALUE, - [SUB_ID]: SUB_ID_VALUE, - }; - let expectedPid = DATA_PARTNER_PIXEL_ID_VALUE; - let expectedNq = [NQ_VALUE]; - let expectedCategory = [null]; - let expectedSubId = SUB_ID_VALUE; - - let request = nanoBidAdapter.buildRequests([getBidRequest(requestParams)]); - - assert(request, expectedPid, expectedNq, expectedCategory, expectedSubId); - tearDownMocks(); - }); - it('Test buildRequest() - pid, category', function () { - setUpMocks(); - let requestParams = { - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [CATEGORY]: CATEGORY_VALUE, - }; - let expectedPid = DATA_PARTNER_PIXEL_ID_VALUE; - let expectedNq = [null]; - let expectedCategory = [CATEGORY_VALUE]; - let expectedSubId = null; - - let request = nanoBidAdapter.buildRequests([getBidRequest(requestParams)]); - - assert(request, expectedPid, expectedNq, expectedCategory, expectedSubId); - tearDownMocks(); - }); - it('Test buildRequest() - pid, category, subId', function () { - setUpMocks(); - let requestParams = { - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [CATEGORY]: CATEGORY_VALUE, - [SUB_ID]: SUB_ID_VALUE, - }; - let expectedPid = DATA_PARTNER_PIXEL_ID_VALUE; - let expectedNq = [null]; - let expectedCategory = [CATEGORY_VALUE]; - let expectedSubId = SUB_ID_VALUE; - - let request = nanoBidAdapter.buildRequests([getBidRequest(requestParams)]); - - assert(request, expectedPid, expectedNq, expectedCategory, expectedSubId); - tearDownMocks(); - }); - it('Test buildRequest() - pid, subId', function () { - setUpMocks(); - let requestParams = { - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [SUB_ID]: SUB_ID_VALUE, - }; - let expectedPid = DATA_PARTNER_PIXEL_ID_VALUE; - let expectedNq = [null]; - let expectedCategory = [null]; - let expectedSubId = SUB_ID_VALUE; - - let request = nanoBidAdapter.buildRequests([getBidRequest(requestParams)]); - - assert(request, expectedPid, expectedNq, expectedCategory, expectedSubId); - tearDownMocks(); - }); - it('Test buildRequest() - pid, nq, category, subId', function () { - setUpMocks(); - let requestParams = { - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ]: NQ_VALUE, - [CATEGORY]: CATEGORY_VALUE, - [SUB_ID]: SUB_ID_VALUE, - }; - let expectedPid = DATA_PARTNER_PIXEL_ID_VALUE; - let expectedNq = [NQ_VALUE]; - let expectedCategory = [CATEGORY_VALUE]; - let expectedSubId = SUB_ID_VALUE; - - let request = nanoBidAdapter.buildRequests([getBidRequest(requestParams)]); - - assert(request, expectedPid, expectedNq, expectedCategory, expectedSubId); - tearDownMocks(); - }); - it('Test buildRequest() - pid, nqName, categoryName, subId', function () { - setUpMocks(); - let requestParams = { - [SSP_PLACEMENT_ID]: DATA_PARTNER_PIXEL_ID_VALUE, - [NQ_NAME]: NQ_NAME_QUERY_PARAM, - [CATEGORY_NAME]: CATEGORY_NAME_QUERY_PARAM, - [SUB_ID]: SUB_ID_VALUE, - }; - let expectedPid = DATA_PARTNER_PIXEL_ID_VALUE; - let expectedNq = [NQ_VALUE]; - let expectedCategory = [CATEGORY_VALUE]; - let expectedSubId = SUB_ID_VALUE; - - let request = nanoBidAdapter.buildRequests([getBidRequest(requestParams)]); - - assert(request, expectedPid, expectedNq, expectedCategory, expectedSubId); - tearDownMocks(); - }); - it('Test interpretResponse() length', function () { - let bids = nanoBidAdapter.interpretResponse({ - body: [ - // valid - { - id: '24a1c9ec270973', - cpm: CPM, - width: WIDTH1, - height: HEIGHT1, - ad: AD, - ttl: 360, - creativeId: 'TEST_ID', - netRevenue: false, - currency: 'EUR', - }, - // invalid - { - id: '24a1c9ec270973', - cpm: null, - width: WIDTH1, - height: HEIGHT1, - ad: AD, - ttl: 360, - creativeId: 'TEST_ID', - netRevenue: false, - currency: 'EUR', - } - ] - }); - expect(bids.length).to.equal(1); - }); - it('Test interpretResponse() bids', function () { - let bid = nanoBidAdapter.interpretResponse({ - body: [ - // valid - { - id: '24a1c9ec270973', - cpm: CPM, - width: WIDTH1, - height: HEIGHT1, - ad: AD, - ttl: 360, - creativeId: 'TEST_ID', - netRevenue: false, - currency: 'EUR', - }, - // invalid - { - id: '24a1c9ec270973', - cpm: null, - width: WIDTH1, - height: HEIGHT1, - ad: AD, - ttl: 360, - creativeId: 'TEST_ID', - netRevenue: false, - currency: 'EUR', - } - ] - })[0]; - expect(bid.requestId).to.equal('24a1c9ec270973'); - expect(bid.cpm).to.equal(CPM); - expect(bid.width).to.equal(WIDTH1); - expect(bid.height).to.equal(HEIGHT1); - expect(bid.ad).to.equal(AD); - expect(bid.ttl).to.equal(360); - expect(bid.creativeId).to.equal('TEST_ID'); - expect(bid.currency).to.equal('EUR'); - }); - }); - }); -}); diff --git a/test/spec/modules/nasmediaAdmixerBidAdapter_spec.js b/test/spec/modules/nasmediaAdmixerBidAdapter_spec.js deleted file mode 100644 index 4731b1a77d3..00000000000 --- a/test/spec/modules/nasmediaAdmixerBidAdapter_spec.js +++ /dev/null @@ -1,143 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/nasmediaAdmixerBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; - -describe('nasmediaAdmixerBidAdapter', 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 bid = { - 'bidder': 'nasmediaAdmixer', - 'params': { - 'media_key': 'media_key', - 'adunit_id': 'adunit_id', - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250]], - 'bidId': '3361d01e67dbd6', - 'bidderRequestId': '2b60dcd392628a', - 'auctionId': '124cb070528662', - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - const bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'media_key': '', - 'adunit_id': '', - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const bidRequests = [ - { - 'bidder': 'nasmediaAdmixer', - 'params': { - 'media_key': '19038695', - 'adunit_id': '24190632', - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250]], - 'bidId': '3361d01e67dbd6', - 'bidderRequestId': '2b60dcd392628a', - 'auctionId': '124cb070528662', - } - ]; - const bidderRequest = {refererInfo: {referer: 'https://example.com'}}; - - it('sends bid request to url via GET', function () { - const request = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(request.method).to.equal('GET'); - expect(request.url).to.match(new RegExp(`https://adn.admixer.co.kr`)); - }); - }); - - describe('interpretResponse', function () { - const response = { - 'body': { - 'bidder': 'nasmediaAdmixer', - 'req_id': '861a8e7952c82c', - 'error_code': 0, - 'error_msg': 'OK', - 'body': [{ - 'ad_id': '20049', - 'width': 300, - 'height': 250, - 'currency': 'USD', - 'cpm': 1.769221, - 'ad': '' - }] - }, - 'headers': { - 'get': function () { - } - } - }; - - const bidRequest = { - 'bidder': 'nasmediaAdmixer', - 'params': { - 'media_key': '19038695', - 'adunit_id': '24190632', - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [320, 480]], - 'bidId': '31300c8b9697cd', - 'bidderRequestId': '2bf570adcf83fa', - 'auctionId': '169827a33f03cc', - }; - - it('should get correct bid response', function () { - const expectedResponse = [ - { - 'requestId': '861a8e7952c82c', - 'cpm': 1.769221, - 'currency': 'USD', - 'width': 300, - 'height': 250, - 'ad': '', - 'creativeId': '20049', - 'ttl': 360, - 'netRevenue': false - } - ]; - - const result = spec.interpretResponse(response, bidRequest); - expect(result).to.have.lengthOf(1); - let resultKeys = Object.keys(result[0]); - expect(resultKeys.sort()).to.deep.equal(Object.keys(expectedResponse[0]).sort()); - resultKeys.forEach(function (k) { - if (k === 'ad') { - expect(result[0][k]).to.match(/$/); - } else { - expect(result[0][k]).to.equal(expectedResponse[0][k]); - } - }); - }); - - it('handles nobid responses', function () { - response.body = { - 'bidder': 'nasmediaAdmixer', - 'req_id': '861a8e7952c82c', - 'error_code': 0, - 'error_msg': 'OK', - 'body': [] - }; - - const result = spec.interpretResponse(response, bidRequest); - expect(result).to.have.lengthOf(0); - }); - }); -}); diff --git a/test/spec/modules/nativoBidAdapter_spec.js b/test/spec/modules/nativoBidAdapter_spec.js deleted file mode 100644 index e1132bf1b74..00000000000 --- a/test/spec/modules/nativoBidAdapter_spec.js +++ /dev/null @@ -1,227 +0,0 @@ -import { expect } from 'chai' -import { spec } from 'modules/nativoBidAdapter.js' -// import { newBidder } from 'src/adapters/bidderFactory.js' -// import * as bidderFactory from 'src/adapters/bidderFactory.js' -// import { deepClone } from 'src/utils.js' -// import { config } from 'src/config.js' - -describe('nativoBidAdapterTests', function () { - describe('isBidRequestValid', function () { - let bid = { - bidder: 'nativo', - params: { - placementId: '10433394', - }, - adUnitCode: 'adunit-code', - sizes: [ - [300, 250], - [300, 600], - ], - bidId: '27b02036ccfa6e', - bidderRequestId: '1372cd8bd8d6a8', - auctionId: 'cfc467e4-2707-48da-becb-bcaab0b2c114', - } - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true) - }) - - it('should return false when required params are not passed', function () { - let bid2 = Object.assign({}, bid) - delete bid2.params - bid2.params = {} - expect(spec.isBidRequestValid(bid2)).to.equal(false) - }) - }) - - describe('buildRequests', function () { - let bidRequests = [ - { - bidder: 'nativo', - params: { - placementId: '10433394', - }, - adUnitCode: 'adunit-code', - sizes: [ - [300, 250], - [300, 600], - ], - bidId: '27b02036ccfa6e', - bidderRequestId: '1372cd8bd8d6a8', - auctionId: 'cfc467e4-2707-48da-becb-bcaab0b2c114', - transactionId: '3b36e7e0-0c3e-4006-a279-a741239154ff', - }, - ] - - it('url should contain query string parameters', function () { - const request = spec.buildRequests(bidRequests, { - bidderRequestId: 123456, - refererInfo: { - referer: 'https://www.test.com', - }, - }) - - expect(request.url).to.exist - expect(request.url).to.be.a('string') - - expect(request.url).to.include('?') - expect(request.url).to.include('ntv_url') - expect(request.url).to.include('ntv_ptd') - }) - }) -}) - -describe('interpretResponse', function () { - let response = { - id: '126456', - seatbid: [ - { - seat: 'seat_0', - bid: [ - { - id: 'f70362ac-f3cf-4225-82a5-948b690927a6', - impid: '1', - price: 3.569, - adm: '', - h: 300, - w: 250, - cat: [], - adomain: ['test.com'], - crid: '1060_72_6760217', - }, - ], - }, - ], - cur: 'USD', - } - - it('should get correct bid response', function () { - let expectedResponse = [ - { - requestId: '1F254428-AB11-4D5E-9887-567B3F952CA5', - cpm: 3.569, - currency: 'USD', - width: 300, - height: 250, - creativeId: '1060_72_6760217', - dealId: 'f70362ac-f3cf-4225-82a5-948b690927a6', - netRevenue: true, - ttl: 360, - ad: '', - meta: { - advertiserDomains: ['test.com'], - }, - }, - ] - - let bidderRequest = { - id: 123456, - bids: [ - { - params: { - placementId: 1 - } - }, - ], - } - - // mock - spec.getRequestId = () => 123456 - - let result = spec.interpretResponse({ body: response }, { bidderRequest }) - expect(Object.keys(result[0])).to.have.deep.members( - Object.keys(expectedResponse[0]) - ) - }) - - it('handles nobid responses', function () { - let response = {} - let bidderRequest - - let result = spec.interpretResponse({ body: response }, { bidderRequest }) - expect(result.length).to.equal(0) - }) -}) - -describe('getUserSyncs', function () { - const response = [ - { - body: { - cur: 'USD', - id: 'a136dbd8-4387-48bf-b8e4-ff9c1d6056ee', - seatbid: [ - { - bid: [{}], - seat: 'seat_0', - syncUrls: [ - { - type: 'image', - url: 'pixel-tracker-test-url/?{GDPR_params}', - }, - { - type: 'iframe', - url: 'iframe-tracker-test-url/?{GDPR_params}', - }, - ], - }, - ], - }, - }, - ] - - const gdprConsent = { - gdprApplies: true, - consentString: '111111' - } - - const uspConsent = { - uspConsent: '1YYY' - } - - it('Returns empty array if no supported user syncs', function () { - let userSync = spec.getUserSyncs( - { - iframeEnabled: false, - pixelEnabled: false, - }, - response, - gdprConsent, - uspConsent - ) - expect(userSync).to.be.an('array').with.lengthOf(0) - }) - - it('Returns valid iframe user sync', function () { - let userSync = spec.getUserSyncs( - { - iframeEnabled: true, - pixelEnabled: false, - }, - response, - gdprConsent, - uspConsent - ) - expect(userSync).to.be.an('array').with.lengthOf(1) - expect(userSync[0].type).to.exist - expect(userSync[0].url).to.exist - expect(userSync[0].type).to.be.equal('iframe') - expect(userSync[0].url).to.contain('gdpr=1&gdpr_consent=111111&us_privacy=1YYY') - }) - - it('Returns valid URL and type', function () { - let userSync = spec.getUserSyncs( - { - iframeEnabled: false, - pixelEnabled: true, - }, - response, - gdprConsent, - uspConsent - ) - expect(userSync).to.be.an('array').with.lengthOf(1) - expect(userSync[0].type).to.exist - expect(userSync[0].url).to.exist - expect(userSync[0].type).to.be.equal('image') - expect(userSync[0].url).to.contain('gdpr=1&gdpr_consent=111111&us_privacy=1YYY') - }) -}) diff --git a/test/spec/modules/newborntownWebBidAdapter_spec.js b/test/spec/modules/newborntownWebBidAdapter_spec.js deleted file mode 100644 index 3d3285328fe..00000000000 --- a/test/spec/modules/newborntownWebBidAdapter_spec.js +++ /dev/null @@ -1,152 +0,0 @@ -import { expect } from 'chai'; -import {spec} from 'modules/newborntownWebBidAdapter.js'; -describe('NewborntownWebAdapter', function() { - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'newborntownWeb', - 'params': { - 'publisher_id': '1238122', - 'slot_id': '123123', - 'bidfloor': 0.3 - }, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'sizes': [[300, 250]], - 'bidId': '2e9cf65f23dbd9', - 'bidderRequestId': '1f01d9d22ee657', - 'auctionId': '2bf455a4-a889-41d5-b48f-9b56b89fbec7', - } - it('should return true where required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }) - describe('buildRequests', function () { - let bidderRequest = { - 'bidderCode': 'newborntownWeb', - 'bidderRequestId': '1f5c279a4c5de3', - 'bids': [ - { - 'bidder': 'newborntownWeb', - 'params': { - 'publisher_id': '1238122', - 'slot_id': '123123', - 'bidfloor': 0.3 - }, - 'mediaTypes': { - 'banner': {'sizes': [[300, 250]]} - }, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'transactionId': '9b954797-d6f4-4730-9cbe-5a1bc8480f52', - 'sizes': [[300, 250]], - 'bidId': '215f48d07eb8b8', - 'bidderRequestId': '1f5c279a4c5de3', - 'auctionId': '5ed4f607-e11c-45b0-aba9-f67768e1f9f4', - 'src': 'client', - 'bidRequestsCount': 1 - } - ], - 'auctionStart': 1573123289380, - 'timeout': 9000, - 'start': 1573123289383 - } - it('Returns POST method', function () { - const request = spec.buildRequests(bidderRequest['bids'], bidderRequest); - expect(request[0].method).to.equal('POST'); - expect(request[0].url.indexOf('//us-west.solortb.com/adx/api/rtb?from=4') !== -1).to.equal(true); - expect(request[0].data).to.exist; - }); - it('request params multi size format object check', function () { - let bidderRequest = { - 'bidderCode': 'newborntownWeb', - 'bidderRequestId': '1f5c279a4c5de3', - 'bids': [ - { - 'bidder': 'newborntownWeb', - 'params': { - 'publisher_id': '1238122', - 'slot_id': '123123', - 'bidfloor': 0.3 - }, - 'mediaTypes': { - 'native': {'sizes': [[300, 250]]} - }, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'transactionId': '9b954797-d6f4-4730-9cbe-5a1bc8480f52', - 'sizes': [300, 250], - 'bidId': '215f48d07eb8b8', - 'bidderRequestId': '1f5c279a4c5de3', - 'auctionId': '5ed4f607-e11c-45b0-aba9-f67768e1f9f4', - 'src': 'client', - 'bidRequestsCount': 1 - } - ], - 'auctionStart': 1573123289380, - 'timeout': 9000, - 'start': 1573123289383 - } - let requstTest = spec.buildRequests(bidderRequest['bids'], bidderRequest) - expect(requstTest[0].data.imp[0].banner.w).to.equal(300); - expect(requstTest[0].data.imp[0].banner.h).to.equal(250); - }); - }) - describe('interpretResponse', function () { - let serverResponse; - let bidRequest = { - data: { - bidId: '2d359291dcf53b' - } - }; - beforeEach(function () { - serverResponse = { - 'body': { - 'id': '174548259807190369860081', - 'seatbid': [ - { - 'bid': [ - { - 'id': '1573540665390298996', - 'impid': '1', - 'price': 0.3001, - 'adid': '1573540665390299172', - 'nurl': 'https://us-west.solortb.com/winnotice?price=${AUCTION_PRICE}&ssp=4&req_unique_id=740016d1-175b-4c19-9744-58a59632dabe&unique_id=06b08e40-2489-439a-8f9e-6413f3dd0bc8&isbidder=1&up=bQyvVo7tgbBVW2dDXzTdBP95Mv35YqqEika0T_btI1h6xjqA8GSXQe51_2CCHQcfuwAEOgdwN8u3VgUHmCuqNPKiBmIPaYUOQBBKjJr05zeKtabKnGT7_JJKcurrXqQ5Sl804xJear_qf2-jOaKB4w', - 'adm': "
", - 'adomain': [ - 'newborntown.com' - ], - 'iurl': 'https://sdkvideo.s3.amazonaws.com/4aa1d9533c4ce71bb1cf750ed38e3a58.png', - 'cid': '345', - 'crid': '41_11113', - 'cat': [ - '' - ], - 'h': 250, - 'w': 300 - } - ], - 'seat': '1' - } - ], - 'bidid': 'bid1573540665390298585' - }, - 'headers': { - - } - } - }); - it('result is correct', function () { - const result = spec.interpretResponse(serverResponse, bidRequest); - if (result && result[0]) { - expect(result[0].requestId).to.equal('2d359291dcf53b'); - expect(result[0].cpm).to.equal(0.3001); - expect(result[0].width).to.equal(300); - expect(result[0].height).to.equal(250); - expect(result[0].creativeId).to.equal('345'); - } - }); - }) -}) diff --git a/test/spec/modules/nextMillenniumBidAdapter_spec.js b/test/spec/modules/nextMillenniumBidAdapter_spec.js deleted file mode 100644 index f4d929b439c..00000000000 --- a/test/spec/modules/nextMillenniumBidAdapter_spec.js +++ /dev/null @@ -1,91 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/nextMillenniumBidAdapter.js'; - -describe('nextMillenniumBidAdapterTests', function() { - let bidRequestData = { - bids: [ - { - bidId: 'transaction_1234', - bidder: 'nextMillennium', - params: { - placement_id: 12345 - }, - sizes: [[300, 250]] - } - ] - }; - let request = []; - - it('validate_pub_params', function() { - expect( - spec.isBidRequestValid({ - bidder: 'nextMillennium', - params: { - placement_id: 12345 - } - }) - ).to.equal(true); - }); - - it('validate_generated_params', function() { - let bidRequestData = [ - { - bidId: 'bid1234', - bidder: 'nextMillennium', - params: { placement_id: -1 }, - sizes: [[300, 250]] - } - ]; - let request = spec.buildRequests(bidRequestData); - expect(request[0].bidId).to.equal('bid1234'); - }); - - it('validate_getUserSyncs_function', function() { - expect(spec.getUserSyncs({ iframeEnabled: true })).to.have.lengthOf(1); - expect(spec.getUserSyncs({ iframeEnabled: false })).to.have.lengthOf(0); - - let pixel = spec.getUserSyncs({ iframeEnabled: true }); - expect(pixel[0].type).to.equal('iframe'); - expect(pixel[0].url).to.equal('https://brainlyads.com/hb/s2s/matching'); - }); - - it('validate_response_params', function() { - let serverResponse = { - body: { - cpm: 1.7, - width: 300, - height: 250, - creativeId: 'p35t0enob6twbt9mofjc8e', - ad: 'Hello! It\'s a test ad!' - } - }; - - let bids = spec.interpretResponse(serverResponse, bidRequestData.bids[0]); - expect(bids).to.have.lengthOf(1); - - let bid = bids[0]; - - expect(bid.creativeId).to.equal('p35t0enob6twbt9mofjc8e'); - expect(bid.ad).to.equal('Hello! It\'s a test ad!'); - expect(bid.cpm).to.equal(1.7); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.currency).to.equal('USD'); - }); - - it('validate_response_params_with passback', function() { - let serverResponse = { - body: [ - { - hash: '1e100887dd614b0909bf6c49ba7f69fdd1360437', - content: 'Ad html passback', - size: [300, 250], - is_passback: 1 - } - ] - }; - let bids = spec.interpretResponse(serverResponse); - - expect(bids).to.have.lengthOf(0); - }); -}); diff --git a/test/spec/modules/nextrollBidAdapter_spec.js b/test/spec/modules/nextrollBidAdapter_spec.js deleted file mode 100644 index 7722443e584..00000000000 --- a/test/spec/modules/nextrollBidAdapter_spec.js +++ /dev/null @@ -1,268 +0,0 @@ -import { expect } from 'chai'; -import { spec, tryGetPubtag, hasCCPAConsent } from 'modules/nextrollBidAdapter.js'; -import * as utils from 'src/utils.js'; - -describe('nextrollBidAdapter', function() { - let utilsMock; - beforeEach(function () { - utilsMock = sinon.mock(utils); - }); - - afterEach(function() { - global.NextRoll = undefined; - utilsMock.restore(); - }); - - let validBid = { - bidder: 'nextroll', - adUnitCode: 'adunit-code', - bidId: 'bid_id', - sizes: [[300, 200]], - params: { - bidfloor: 1, - zoneId: 'zone1', - publisherId: 'publisher_id' - } - }; - let bidWithoutValidId = { id: '' }; - let bidWithoutId = { params: { zoneId: 'zone1' } }; - - describe('nativeBidRequest', () => { - it('validates native spec', () => { - let nativeAdUnit = [{ - bidder: 'nextroll', - adUnitCode: 'adunit-code', - 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 - } - }, - params: { - bidfloor: 1, - zoneId: 'zone1', - publisherId: 'publisher_id' - } - }]; - - let request = spec.buildRequests(nativeAdUnit) - let assets = request[0].data.imp.native.request.native.assets - - let 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}} - ] - expect(assets).to.be.deep.equal(excptedAssets) - }) - }) - - describe('isBidRequestValid', function() { - it('validates the bids correctly when the bid has an id', function() { - expect(spec.isBidRequestValid(validBid)).to.be.true; - }); - - it('validates the bids correcly when the bid does not have an id', function() { - expect(spec.isBidRequestValid(bidWithoutValidId)).to.be.false; - expect(spec.isBidRequestValid(bidWithoutId)).to.be.false; - }); - }); - - describe('buildRequests', function() { - it('builds the same amount of requests as valid requests it takes', function() { - expect(spec.buildRequests([validBid, validBid], {})).to.be.lengthOf(2); - }); - - it('doest not build a request when there is no valid requests', function () { - expect(spec.buildRequests([], {})).to.be.lengthOf(0); - }); - - it('builds a request with POST method', function () { - expect(spec.buildRequests([validBid], {})[0].method).to.equal('POST'); - }); - - it('builds a request with cookies method', function () { - expect(spec.buildRequests([validBid], {})[0].options.withCredentials).to.be.true; - }); - - it('builds a request with id, url and imp object', function () { - const request = spec.buildRequests([validBid], {})[0]; - expect(request.data.id).to.be.an('string').that.is.not.empty; - expect(request.url).to.equal('https://d.adroll.com/bid/prebid/'); - expect(request.data.imp).to.exist.and.to.be.a('object'); - }); - - it('builds a request with site and device information', function () { - const request = spec.buildRequests([validBid], {})[0]; - - expect(request.data.site).to.exist.and.to.be.a('object'); - expect(request.data.device).to.exist.and.to.be.a('object'); - }); - - it('builds a request with a complete imp object', function () { - const request = spec.buildRequests([validBid], {})[0]; - - expect(request.data.imp.id).to.equal('bid_id'); - expect(request.data.imp.bidfloor).to.be.equal(1); - expect(request.data.imp.banner).to.exist.and.to.be.a('object'); - expect(request.data.imp.ext.zone.id).to.be.equal('zone1'); - }); - - it('includes the sizes into the request correctly', function () { - const bannerObject = spec.buildRequests([validBid], {})[0].data.imp.banner; - - expect(bannerObject.format).to.exist; - expect(bannerObject.format).to.be.lengthOf(1); - expect(bannerObject.format[0].w).to.be.equal(300); - expect(bannerObject.format[0].h).to.be.equal(200); - }); - - it('sets the CCPA consent string', function () { - const us_privacy = '1YYY'; - const request = spec.buildRequests([validBid], {'uspConsent': us_privacy})[0]; - - expect(request.data.regs.ext.us_privacy).to.be.equal(us_privacy); - }); - }); - - describe('interpretResponse', function () { - let responseBody = { - id: 'bidresponse_id', - dealId: 'deal_id', - seatbid: [ - { - bid: [ - { - price: 1.2, - w: 300, - h: 200, - crid: 'crid1', - adm: 'adm1' - } - ] - }, - { - bid: [ - { - price: 2.1, - w: 250, - h: 300, - crid: 'crid2', - adm: 'adm2' - } - ] - } - ] - }; - - it('returns an empty list when there is no response body', function () { - expect(spec.interpretResponse({}, {})).to.be.eql([]); - }); - - it('builds the same amount of responses as server responses it receives', function () { - 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]; - - expect(response.requestId).to.be.equal('bidresponse_id'); - expect(response.cpm).to.be.equal(1.2); - expect(response.width).to.be.equal(300); - expect(response.height).to.be.equal(200); - expect(response.creativeId).to.be.equal('crid1'); - expect(response.dealId).to.be.equal('deal_id'); - expect(response.currency).to.be.equal('USD'); - expect(response.netRevenue).to.be.equal(true); - expect(response.ttl).to.be.equal(300); - expect(response.ad).to.be.equal('adm1'); - }); - }); - - describe('interpret native response', () => { - let clickUrl = 'https://clickurl.com/with/some/path' - let titleText = 'Some title' - let imgW = 300 - let imgH = 250 - let imgUrl = 'https://clickurl.com/img.png' - let brandText = 'Some Brand' - let impUrl = 'https://clickurl.com/imptracker' - - let responseBody = { - body: { - id: 'bidresponse_id', - seatbid: [{ - bid: [{ - price: 1.2, - crid: 'crid1', - adm: { - link: {url: clickUrl}, - assets: [ - {id: 1, title: {text: titleText}}, - {id: 2, img: {w: imgW, h: imgH, url: imgUrl}}, - {id: 5, data: {value: brandText}} - ], - imptrackers: [impUrl] - } - }] - }] - } - }; - - it('Should interpret response', () => { - let response = spec.interpretResponse(utils.deepClone(responseBody)) - let expectedResponse = { - clickUrl: clickUrl, - impressionTrackers: [impUrl], - privacyLink: 'https://info.evidon.com/pub_info/573', - privacyIcon: 'https://c.betrad.com/pub/icon1.png', - title: titleText, - image: {url: imgUrl, width: imgW, height: imgH}, - sponsoredBy: brandText, - clickTrackers: [], - jstracker: [] - } - - expect(response[0].native).to.be.deep.equal(expectedResponse) - }) - - it('Should interpret all assets', () => { - let allAssetsResponse = utils.deepClone(responseBody) - let iconUrl = imgUrl + '?icon=true', iconW = 10, iconH = 15 - let logoUrl = imgUrl + '?logo=true', logoW = 20, logoH = 25 - let 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}} - ]) - - let response = spec.interpretResponse(allAssetsResponse) - let expectedResponse = { - clickUrl: clickUrl, - impressionTrackers: [impUrl], - jstracker: [], - clickTrackers: [], - privacyLink: 'https://info.evidon.com/pub_info/573', - privacyIcon: 'https://c.betrad.com/pub/icon1.png', - title: titleText, - 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 - } - - expect(response[0].native).to.be.deep.equal(expectedResponse) - }) - }) -}); diff --git a/test/spec/modules/nextrollIdSystem_spec.js b/test/spec/modules/nextrollIdSystem_spec.js deleted file mode 100644 index d89c7fe3c98..00000000000 --- a/test/spec/modules/nextrollIdSystem_spec.js +++ /dev/null @@ -1,56 +0,0 @@ -import { nextrollIdSubmodule, storage } from 'modules/nextrollIdSystem.js'; - -const LS_VALUE = `{ - "AdID":{"id":"adid","key":"AdID"}, - "AdID:1002": {"id":"adid","key":"AdID:1002","value":"id_value"}}`; - -describe('NextrollId module', function () { - let sandbox = sinon.sandbox.create(); - let hasLocalStorageStub; - let getLocalStorageStub; - - beforeEach(function() { - hasLocalStorageStub = sandbox.stub(storage, 'hasLocalStorage'); - getLocalStorageStub = sandbox.stub(storage, 'getDataFromLocalStorage'); - }); - - afterEach(function () { - sandbox.restore(); - }) - - const testCases = [ - { - expect: { - id: {nextrollId: 'id_value'}, - }, - params: {partnerId: '1002'}, - localStorage: LS_VALUE - }, - { - expect: {id: undefined}, - params: {partnerId: '1003'}, - localStorage: LS_VALUE - }, - { - expect: {id: undefined}, - params: {partnerId: ''}, - localStorage: LS_VALUE - }, - { - expect: {id: undefined}, - params: {partnerId: '102'}, - localStorage: undefined - }, - { - expect: {id: undefined}, - params: undefined, - localStorage: undefined - } - ] - testCases.forEach( - (testCase, i) => it(`getId() (TC #${i}) should return the nextroll id if it exists`, function () { - getLocalStorageStub.withArgs('dca0.com').returns(testCase.localStorage); - const id = nextrollIdSubmodule.getId({params: testCase.params}); - expect(id).to.be.deep.equal(testCase.expect); - })) -}); diff --git a/test/spec/modules/nobidBidAdapter_spec.js b/test/spec/modules/nobidBidAdapter_spec.js deleted file mode 100644 index 8dc15fbc89e..00000000000 --- a/test/spec/modules/nobidBidAdapter_spec.js +++ /dev/null @@ -1,755 +0,0 @@ -import { expect } from 'chai'; -import * as utils from 'src/utils.js'; -import { spec } from 'modules/nobidBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import * as bidderFactory from 'src/adapters/bidderFactory.js'; - -describe('Nobid Adapter', 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 () { - let bid = { - 'bidder': 'nobid', - 'params': { - 'siteId': 2 - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return true when required params found', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'siteId': 2 - }; - - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'siteId': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('isVideoBidRequestValid', function () { - let bid = { - bidder: 'nobid', - params: { - siteId: 2, - video: { - skippable: true, - playback_methods: ['auto_play_sound_off'], - position: 'atf', - mimes: ['video/x-flv', 'video/mp4', 'video/x-ms-wmv', 'application/x-shockwave-flash', 'application/javascript'], - minduration: 1, - maxduration: 30, - frameworks: [1, 2, 3, 4, 5, 6] - } - }, - adUnitCode: 'adunit-code', - sizes: [[640, 480]], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - mediaTypes: { - video: { - context: 'instream' - } - } - }; - const SITE_ID = 2; - const REFERER = 'https://www.examplereferer.com'; - let bidRequests = [ - { - bidder: 'nobid', - params: { - siteId: SITE_ID, - video: { - skippable: true, - playback_methods: ['auto_play_sound_off'], - position: 'atf', - mimes: ['video/x-flv', 'video/mp4', 'video/x-ms-wmv', 'application/x-shockwave-flash', 'application/javascript'], - minduration: 1, - maxduration: 30, - frameworks: [1, 2, 3, 4, 5, 6] - } - }, - adUnitCode: 'adunit-code', - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'instream' - } - } - } - ]; - - let bidderRequest = { - refererInfo: {referer: REFERER} - } - - it('should add source and version to the tag', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.sid).to.equal(SITE_ID); - expect(payload.l).to.exist.and.to.equal(encodeURIComponent(REFERER)); - expect(payload.a).to.exist; - expect(payload.t).to.exist; - expect(payload.tz).to.exist; - expect(payload.r).to.exist.and.to.equal('100x100'); - expect(payload.lang).to.exist; - expect(payload.ref).to.exist; - expect(payload.a[0].d).to.exist.and.to.equal('adunit-code'); - expect(payload.a[0].at).to.exist.and.to.equal('video'); - expect(payload.a[0].params.video).to.exist; - expect(payload.a[0].params.video.skippable).to.exist.and.to.equal(true); - expect(payload.a[0].params.video.playback_methods).to.exist.and.to.contain('auto_play_sound_off'); - expect(payload.a[0].params.video.position).to.exist.and.to.equal('atf'); - expect(payload.a[0].params.video.mimes).to.exist.and.to.contain('video/x-flv'); - expect(payload.a[0].params.video.minduration).to.exist.and.to.equal(1); - expect(payload.a[0].params.video.maxduration).to.exist.and.to.equal(30); - expect(payload.a[0].params.video.frameworks[0]).to.exist.and.to.equal(1); - expect(payload.a[0].params.video.frameworks[1]).to.exist.and.to.equal(2); - expect(payload.a[0].params.video.frameworks[2]).to.exist.and.to.equal(3); - expect(payload.a[0].params.video.frameworks[3]).to.exist.and.to.equal(4); - expect(payload.a[0].params.video.frameworks[4]).to.exist.and.to.equal(5); - expect(payload.a[0].params.video.frameworks[5]).to.exist.and.to.equal(6); - }); - }); - - describe('isVideoBidRequestValid', function () { - let bid = { - bidder: 'nobid', - params: { - siteId: 2, - video: { - skippable: true, - playback_methods: ['auto_play_sound_off'], - position: 'atf', - mimes: ['video/x-flv', 'video/mp4', 'video/x-ms-wmv', 'application/x-shockwave-flash', 'application/javascript'], - minduration: 1, - maxduration: 30, - frameworks: [1, 2, 3, 4, 5, 6] - } - }, - adUnitCode: 'adunit-code', - sizes: [[640, 480]], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - mediaTypes: { - video: { - context: 'outstream' - } - } - }; - const SITE_ID = 2; - const REFERER = 'https://www.examplereferer.com'; - let bidRequests = [ - { - bidder: 'nobid', - params: { - siteId: SITE_ID, - video: { - skippable: true, - playback_methods: ['auto_play_sound_off'], - position: 'atf', - mimes: ['video/x-flv', 'video/mp4', 'video/x-ms-wmv', 'application/x-shockwave-flash', 'application/javascript'], - minduration: 1, - maxduration: 30, - frameworks: [1, 2, 3, 4, 5, 6] - } - }, - adUnitCode: 'adunit-code', - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'outstream' - } - } - } - ]; - - let bidderRequest = { - refererInfo: {referer: REFERER} - } - - it('should add source and version to the tag', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.sid).to.equal(SITE_ID); - expect(payload.l).to.exist.and.to.equal(encodeURIComponent(REFERER)); - expect(payload.a).to.exist; - expect(payload.t).to.exist; - expect(payload.tz).to.exist; - expect(payload.r).to.exist; - expect(payload.lang).to.exist; - expect(payload.ref).to.exist; - expect(payload.a[0].d).to.exist.and.to.equal('adunit-code'); - expect(payload.a[0].at).to.exist.and.to.equal('video'); - expect(payload.a[0].params.video).to.exist; - expect(payload.a[0].params.video.skippable).to.exist.and.to.equal(true); - expect(payload.a[0].params.video.playback_methods).to.exist.and.to.contain('auto_play_sound_off'); - expect(payload.a[0].params.video.position).to.exist.and.to.equal('atf'); - expect(payload.a[0].params.video.mimes).to.exist.and.to.contain('video/x-flv'); - expect(payload.a[0].params.video.minduration).to.exist.and.to.equal(1); - expect(payload.a[0].params.video.maxduration).to.exist.and.to.equal(30); - expect(payload.a[0].params.video.frameworks[0]).to.exist.and.to.equal(1); - expect(payload.a[0].params.video.frameworks[1]).to.exist.and.to.equal(2); - expect(payload.a[0].params.video.frameworks[2]).to.exist.and.to.equal(3); - expect(payload.a[0].params.video.frameworks[3]).to.exist.and.to.equal(4); - expect(payload.a[0].params.video.frameworks[4]).to.exist.and.to.equal(5); - expect(payload.a[0].params.video.frameworks[5]).to.exist.and.to.equal(6); - }); - }); - - describe('buildRequestsEIDs', function () { - const SITE_ID = 2; - const REFERER = 'https://www.examplereferer.com'; - let bidRequests = [ - { - 'bidder': 'nobid', - 'params': { - 'siteId': SITE_ID - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'userIdAsEids': [ - { - 'source': 'criteo.com', - 'uids': [ - { - 'id': 'CRITEO_ID', - 'atype': 1 - } - ] - }, - { - 'source': 'id5-sync.com', - 'uids': [ - { - 'id': 'ID5_ID', - 'atype': 1, - 'ext': { - 'linkType': 0 - } - } - ] - }, - { - 'source': 'adserver.org', - 'uids': [ - { - 'id': 'TD_ID', - 'atype': 1, - 'ext': { - 'rtiPartner': 'TDID' - } - } - ] - } - ] - } - ]; - - let bidderRequest = { - refererInfo: {referer: REFERER} - } - - it('should get user ids from eids', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.sid).to.exist.and.to.equal(2); - expect(payload.eids[0].source).to.exist.and.to.equal('criteo.com'); - expect(payload.eids[0].uids[0].id).to.exist.and.to.equal('CRITEO_ID'); - expect(payload.eids[1].source).to.exist.and.to.equal('id5-sync.com'); - expect(payload.eids[1].uids[0].id).to.exist.and.to.equal('ID5_ID'); - expect(payload.eids[2].source).to.exist.and.to.equal('adserver.org'); - expect(payload.eids[2].uids[0].id).to.exist.and.to.equal('TD_ID'); - }); - }); - - describe('buildRequests', function () { - const SITE_ID = 2; - const REFERER = 'https://www.examplereferer.com'; - let bidRequests = [ - { - 'bidder': 'nobid', - 'params': { - 'siteId': SITE_ID - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - let bidderRequest = { - refererInfo: {referer: REFERER} - } - - it('should add source and version to the tag', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.sid).to.equal(SITE_ID); - expect(payload.l).to.exist.and.to.equal(encodeURIComponent(REFERER)); - expect(payload.tt).to.exist; - expect(payload.a).to.exist; - expect(payload.t).to.exist; - expect(payload.tz).to.exist; - expect(payload.r).to.exist; - expect(payload.lang).to.exist; - expect(payload.ref).to.exist; - expect(payload.gdpr).to.exist; - }); - - it('sends bid request to ad size', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.a).to.exist; - expect(payload.a.length).to.exist.and.to.equal(1); - expect(payload.a[0].z[0][0]).to.equal(300); - expect(payload.a[0].z[0][1]).to.equal(250); - }); - - it('sends bid request to div id', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.a).to.exist; - expect(payload.a[0].d).to.equal('adunit-code'); - }); - - it('sends bid request to site id', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.a).to.exist; - expect(payload.a[0].sid).to.equal(2); - expect(payload.a[0].at).to.equal('banner'); - expect(payload.a[0].params.siteId).to.equal(2); - }); - - it('sends bid request to ad type', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.a).to.exist; - expect(payload.a[0].at).to.equal('banner'); - }); - - it('sends bid request to ENDPOINT via POST', function () { - const request = spec.buildRequests(bidRequests); - expect(request.url).to.contain('ads.servenobid.com/adreq'); - expect(request.method).to.equal('POST'); - }); - - it('should add gdpr consent information to the request', function () { - let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - let bidderRequest = { - 'bidderCode': 'nobid', - 'auctionId': '1d1a030790a475', - 'bidderRequestId': '22edbae2733bf6', - 'timeout': 3000, - 'gdprConsent': { - consentString: consentString, - gdprApplies: true - } - }; - bidderRequest.bids = bidRequests; - - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.gdpr).to.exist; - expect(payload.gdpr.consentString).to.exist.and.to.equal(consentString); - expect(payload.gdpr.consentRequired).to.exist.and.to.be.true; - }); - - it('should add gdpr consent information to the request', function () { - let bidderRequest = { - 'bidderCode': 'nobid', - 'auctionId': '1d1a030790a475', - 'bidderRequestId': '22edbae2733bf6', - 'timeout': 3000, - 'gdprConsent': { - gdprApplies: false - } - }; - bidderRequest.bids = bidRequests; - - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.gdpr).to.exist; - expect(payload.gdpr.consentString).to.not.exist; - expect(payload.gdpr.consentRequired).to.exist.and.to.be.false; - }); - - it('should add usp consent information to the request', function () { - let bidderRequest = { - 'bidderCode': 'nobid', - 'auctionId': '1d1a030790a475', - 'bidderRequestId': '22edbae2733bf6', - 'timeout': 3000, - 'uspConsent': '1Y-N' - }; - bidderRequest.bids = bidRequests; - - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.usp).to.exist; - expect(payload.usp).to.exist.and.to.equal('1Y-N'); - }); - }); - - describe('buildRequestsRefreshCount', function () { - const SITE_ID = 2; - const REFERER = 'https://www.examplereferer.com'; - let bidRequests = [ - { - 'bidder': 'nobid', - 'params': { - 'siteId': SITE_ID - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - let bidderRequest = { - refererInfo: {referer: REFERER} - } - - it('should refreshCount = 4', function () { - nobid.refreshLimit = 2; - nobid.refreshCount = 0; - spec.buildRequests(bidRequests, bidderRequest); - spec.buildRequests(bidRequests, bidderRequest); - spec.buildRequests(bidRequests, bidderRequest); - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(nobid.refreshCount).to.equal(3); - expect(typeof request).to.equal('undefined'); - }); - }); - - describe('interpretResponse', function () { - const CREATIVE_ID_300x250 = 'CREATIVE-100'; - const ADUNIT_300x250 = 'ADUNIT-1'; - const ADMARKUP_300x250 = 'ADMARKUP-300x250'; - const PRICE_300x250 = 0.51; - const REQUEST_ID = '3db3773286ee59'; - const DEAL_ID = 'deal123'; - let response = { - country: 'US', - ip: '68.83.15.75', - device: 'COMPUTER', - site: 2, - bids: [ - {id: 1, - bdrid: 101, - divid: ADUNIT_300x250, - dealid: DEAL_ID, - creativeid: CREATIVE_ID_300x250, - size: {'w': 300, 'h': 250}, - adm: ADMARKUP_300x250, - price: '' + PRICE_300x250 - } - ] - }; - - it('should get correct bid response', function () { - let expectedResponse = [ - { - requestId: REQUEST_ID, - cpm: PRICE_300x250, - width: 300, - height: 250, - creativeId: CREATIVE_ID_300x250, - dealId: DEAL_ID, - currency: 'USD', - netRevenue: true, - ttl: 300, - ad: ADMARKUP_300x250, - mediaType: 'banner' - } - ]; - - let bidderRequest = { - bids: [{ - bidId: REQUEST_ID, - adUnitCode: ADUNIT_300x250 - }] - } - let 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); - expect(result[0].cpm).to.equal(expectedResponse[0].cpm); - }); - - it('should get correct empty response', function () { - let bidderRequest = { - bids: [{ - bidId: REQUEST_ID, - adUnitCode: ADUNIT_300x250 + '1' - }] - } - let result = spec.interpretResponse({ body: response }, {bidderRequest: bidderRequest}); - expect(result.length).to.equal(0); - }); - - it('should get correct deal id', function () { - let expectedResponse = [ - { - requestId: REQUEST_ID, - cpm: PRICE_300x250, - width: 300, - height: 250, - creativeId: CREATIVE_ID_300x250, - dealId: DEAL_ID, - currency: 'USD', - netRevenue: true, - ttl: 300, - ad: ADMARKUP_300x250, - mediaType: 'banner' - } - ]; - - let bidderRequest = { - bids: [{ - bidId: REQUEST_ID, - adUnitCode: ADUNIT_300x250 - }] - } - let result = spec.interpretResponse({ body: response }, {bidderRequest: bidderRequest}); - expect(result.length).to.equal(expectedResponse.length); - expect(result[0].dealId).to.equal(expectedResponse[0].dealId); - }); - }); - - describe('interpretResponseWithRefreshLimit', function () { - const CREATIVE_ID_300x250 = 'CREATIVE-100'; - const ADUNIT_300x250 = 'ADUNIT-1'; - const ADMARKUP_300x250 = 'ADMARKUP-300x250'; - const PRICE_300x250 = 0.51; - const REQUEST_ID = '3db3773286ee59'; - const DEAL_ID = 'deal123'; - const REFRESH_LIMIT = 3; - let response = { - country: 'US', - ip: '68.83.15.75', - device: 'COMPUTER', - site: 2, - rlimit: REFRESH_LIMIT, - bids: [ - {id: 1, - bdrid: 101, - divid: ADUNIT_300x250, - dealid: DEAL_ID, - creativeid: CREATIVE_ID_300x250, - size: {'w': 300, 'h': 250}, - adm: ADMARKUP_300x250, - price: '' + PRICE_300x250 - } - ] - }; - - it('should refreshLimit be respected', function () { - let bidderRequest = { - bids: [{ - bidId: REQUEST_ID, - adUnitCode: ADUNIT_300x250 - }] - } - let result = spec.interpretResponse({ body: response }, {bidderRequest: bidderRequest}); - expect(nobid.refreshLimit).to.equal(REFRESH_LIMIT); - }); - }); - - describe('buildRequestsWithSupplyChain', function () { - const SITE_ID = 2; - let bidRequests = [ - { - bidder: 'nobid', - params: { - siteId: SITE_ID - }, - adUnitCode: 'adunit-code', - sizes: [[300, 250]], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - coppa: true, - schain: { - validation: 'strict', - config: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - name: 'name.com', - hp: 1 - } - ] - } - } - } - ]; - - it('schain exist', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.schain).to.exist; - expect(payload.schain.validation).to.exist.and.to.equal('strict'); - expect(payload.schain.config.ver).to.exist.and.to.equal('1.0'); - expect(payload.schain.config.complete).to.exist.and.to.equal(1); - expect(payload.schain.config.nodes[0].asi).to.exist.and.to.equal('indirectseller.com'); - expect(payload.schain.config.nodes[0].sid).to.exist.and.to.equal('00001'); - expect(payload.schain.config.nodes[0].name).to.exist.and.to.equal('name.com'); - expect(payload.schain.config.nodes[0].hp).to.exist.and.to.equal(1); - expect(payload.coppa).to.exist; - expect(payload.coppa).to.exist.and.to.be.true; - expect(payload.a).to.be.lengthOf(1); - expect(request.method).to.equal('POST'); - }); - }); - - describe('interpretResponseWithUserLimit', function () { - const CREATIVE_ID_300x250 = 'CREATIVE-100'; - const ADUNIT_300x250 = 'ADUNIT-1'; - const ADMARKUP_300x250 = 'ADMARKUP-300x250'; - const PRICE_300x250 = 0.51; - const REQUEST_ID = '3db3773286ee59'; - const DEAL_ID = 'deal123'; - const ULIMIT = 1; - let response = { - country: 'US', - ip: '68.83.15.75', - device: 'COMPUTER', - site: 2, - ublock: ULIMIT, - bids: [ - {id: 1, - bdrid: 101, - divid: ADUNIT_300x250, - dealid: DEAL_ID, - creativeid: CREATIVE_ID_300x250, - size: {'w': 300, 'h': 250}, - adm: ADMARKUP_300x250, - price: '' + PRICE_300x250 - } - ] - }; - - it('should ULimit be respected', function () { - const bidderRequest = { - bids: [{ - bidId: REQUEST_ID, - adUnitCode: ADUNIT_300x250 - }] - } - const bidRequests = [ - { - 'bidder': 'nobid', - 'params': { - 'siteId': 2 - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - spec.interpretResponse({ body: response }, {bidderRequest: bidderRequest}); - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request).to.equal(undefined); - }); - }); - - describe('getUserSyncs', function () { - const GDPR_CONSENT_STRING = 'GDPR_CONSENT_STRING'; - it('should get correct user sync when iframeEnabled', function () { - let 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 () { - let 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 () { - let 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 () { - let pixel = spec.getUserSyncs({iframeEnabled: false}) - expect(pixel.length).to.equal(0); - }); - - it('should get correct user sync when !iframeEnabled and pixelEnabled', function () { - let 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'); - }); - - it('should get correct user sync when !iframeEnabled', function () { - let pixel = spec.getUserSyncs({}) - expect(pixel.length).to.equal(0); - }); - }); - - describe('onTimeout', function (syncOptions) { - it('should increment timeoutTotal', function () { - let timeoutTotal = spec.onTimeout() - expect(timeoutTotal).to.equal(1); - }); - }); - - describe('onBidWon', function (syncOptions) { - it('should increment bidWonTotal', function () { - let bidWonTotal = spec.onBidWon() - expect(bidWonTotal).to.equal(1); - }); - }); -}); diff --git a/test/spec/modules/novatiqIdSystem_spec.js b/test/spec/modules/novatiqIdSystem_spec.js deleted file mode 100644 index 60c82626450..00000000000 --- a/test/spec/modules/novatiqIdSystem_spec.js +++ /dev/null @@ -1,70 +0,0 @@ -import { novatiqIdSubmodule } from 'modules/novatiqIdSystem.js'; -import * as utils from 'src/utils.js'; -import { server } from 'test/mocks/xhr.js'; - -describe('novatiqIdSystem', function () { - describe('getSrcId', function() { - it('getSrcId should set srcId value to 000 due to undefined parameter in config section', function() { - const config = { params: { } }; - const configParams = config.params || {}; - const response = novatiqIdSubmodule.getSrcId(configParams); - expect(response).to.eq('000'); - }); - - it('getSrcId should set srcId value to 000 due to missing value in config section', function() { - const config = { params: { sourceid: '' } }; - const configParams = config.params || {}; - const response = novatiqIdSubmodule.getSrcId(configParams); - expect(response).to.eq('000'); - }); - - it('getSrcId should set value to 000 due to null value in config section', function() { - const config = { params: { sourceid: null } }; - const configParams = config.params || {}; - const response = novatiqIdSubmodule.getSrcId(configParams); - expect(response).to.eq('000'); - }); - - it('getSrcId should set value to 001 due to wrong length in config section max 3 chars', function() { - const config = { params: { sourceid: '1234' } }; - const configParams = config.params || {}; - const response = novatiqIdSubmodule.getSrcId(configParams); - expect(response).to.eq('001'); - }); - - it('getSrcId should set value to 002 due to wrong format in config section', function() { - const config = { params: { sourceid: '1xc' } }; - const configParams = config.params || {}; - const response = novatiqIdSubmodule.getSrcId(configParams); - expect(response).to.eq('002'); - }); - }); - - describe('getId', function() { - it('should log message if novatiqId has wrong format', function() { - const config = { params: { sourceid: '123' } }; - const response = novatiqIdSubmodule.getId(config); - expect(response.id).to.have.length(40); - }); - - it('should log message if novatiqId not provided', function() { - const config = { params: { sourceid: '123' } }; - const response = novatiqIdSubmodule.getId(config); - expect(response.id).should.be.not.empty; - }); - }); - - describe('decode', function() { - it('should log message if novatiqId has wrong format', function() { - const novatiqId = '81b001ec-8914-488c-a96e-8c220d4ee08895ef'; - const response = novatiqIdSubmodule.decode(novatiqId); - expect(response.novatiq.snowflake).to.have.length(40); - }); - - it('should log message if novatiqId has wrong format', function() { - const novatiqId = '81b001ec-8914-488c-a96e-8c220d4ee08895ef'; - const response = novatiqIdSubmodule.decode(novatiqId); - expect(response.novatiq.snowflake).should.be.not.empty; - }); - }); -}) diff --git a/test/spec/modules/oneVideoBidAdapter_spec.js b/test/spec/modules/oneVideoBidAdapter_spec.js deleted file mode 100644 index 3f5304dce0a..00000000000 --- a/test/spec/modules/oneVideoBidAdapter_spec.js +++ /dev/null @@ -1,976 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/oneVideoBidAdapter.js'; - -describe('OneVideoBidAdapter', function () { - let bidRequest; - let bidderRequest = { - 'bidderCode': 'oneVideo', - 'auctionId': 'e158486f-8c7f-472f-94ce-b0cbfbb50ab4', - 'bidderRequestId': '1e498b84fffc39', - 'bids': bidRequest, - 'auctionStart': 1520001292880, - 'timeout': 3000, - 'start': 1520001292884, - 'doneCbCallCount': 0, - 'refererInfo': { - 'numIframes': 1, - 'reachedTop': true, - 'referer': 'test.com' - } - }; - let mockConfig; - - beforeEach(function () { - bidRequest = { - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480] - } - }, - bidder: 'oneVideo', - sizes: [640, 480], - bidId: '30b3efwfwe1e', - adUnitCode: 'video1', - params: { - video: { - playerWidth: 640, - playerHeight: 480, - mimes: ['video/mp4', 'application/javascript'], - protocols: [2, 5], - api: [2], - position: 1, - delivery: [2], - playbackmethod: [1, 5], - sid: 134, - rewarded: 1, - placement: 1, - hp: 1, - inventoryid: 123 - }, - site: { - id: 1, - page: 'https://news.yahoo.com/portfolios', - referrer: 'http://www.yahoo.com' - }, - pubId: 'brxd' - } - }; - }); - - describe('spec.isBidRequestValid', function () { - it('should return true when the required params are passed', function () { - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }); - - it('should return false when the "video" param is missing', function () { - bidRequest.params = { - pubId: 'brxd' - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when the "pubId" param is missing', function () { - bidRequest.params = { - video: { - playerWidth: 480, - playerHeight: 640, - mimes: ['video/mp4', 'application/javascript'], - protocols: [2, 5], - api: [2], - position: 1, - delivery: [2], - playbackmethod: [1, 5], - sid: 134, - rewarded: 1, - placement: 1, - inventoryid: 123 - } - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - it('should return true when the "pubId" param exists', function () { - bidRequest.params = { - video: { - playerWidth: 480, - playerHeight: 640, - mimes: ['video/mp4', 'application/javascript'], - protocols: [2, 5], - api: [2], - position: 1, - delivery: [2], - playbackmethod: [1, 5], - sid: 134, - rewarded: 1, - placement: 1, - inventoryid: 123 - }, - pubId: 'brxd' - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }); - - it('should return false when no bid params are passed', function () { - bidRequest.params = {}; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when the mediaType is "banner" and display="undefined" (DAP 3P)', function () { - bidRequest = { - mediaTypes: { - banner: { - sizes: [640, 480] - } - } - } - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }) - - it('should return true when the mediaType is "banner" and display=1 (DAP 3P)', function () { - bidRequest = { - mediaTypes: { - banner: { - sizes: [640, 480] - } - }, - bidder: 'oneVideo', - sizes: [640, 480], - bidId: '30b3efwfwe1e', - adUnitCode: 'video1', - params: { - video: { - playerWidth: 640, - playerHeight: 480, - mimes: ['video/mp4', 'application/javascript'], - protocols: [2, 5], - api: [2], - position: 1, - delivery: [2], - playbackmethod: [1, 5], - sid: 134, - rewarded: 1, - placement: 1, - inventoryid: 123, - display: 1 - }, - site: { - id: 1, - page: 'https://news.yahoo.com/portfolios', - referrer: 'http://www.yahoo.com' - }, - pubId: 'brxd' - } - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }) - - it('should return false when the mediaType is "video" and context="outstream" and display=1 (DAP 3P)', function () { - bidRequest = { - mediaTypes: { - video: { - context: 'outstream', - playerSize: [640, 480] - } - }, - params: { - video: { - display: 1 - } - } - } - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }) - - it('should return true for Multi-Format AdUnits, when the mediaTypes are both "banner" and "video" (Multi-Format Support)', function () { - bidRequest = { - mediaTypes: { - banner: { - sizes: [640, 480] - }, - video: { - context: 'outstream', - playerSize: [640, 480] - } - } - } - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }) - }); - - describe('spec.buildRequests', function () { - it('should create a POST request for every bid', function () { - const requests = spec.buildRequests([bidRequest], bidderRequest); - expect(requests[0].method).to.equal('POST'); - expect(requests[0].url).to.equal(spec.ENDPOINT + bidRequest.params.pubId); - }); - - it('should attach the bid request object', function () { - const requests = spec.buildRequests([bidRequest], bidderRequest); - expect(requests[0].bidRequest).to.equal(bidRequest); - }); - - it('should attach request data', function () { - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - const [width, height] = bidRequest.sizes; - const placement = bidRequest.params.video.placement; - const rewarded = bidRequest.params.video.rewarded; - const inventoryid = bidRequest.params.video.inventoryid; - const VERSION = '3.1.0'; - expect(data.imp[0].video.w).to.equal(width); - expect(data.imp[0].video.h).to.equal(height); - expect(data.imp[0].bidfloor).to.equal(bidRequest.params.bidfloor); - expect(data.imp[0].ext.rewarded).to.equal(rewarded); - expect(data.imp[0].video.placement).to.equal(placement); - expect(data.imp[0].ext.inventoryid).to.equal(inventoryid); - expect(data.imp[0].ext.prebidver).to.equal('$prebid.version$'); - expect(data.imp[0].ext.adapterver).to.equal(VERSION); - }); - - it('must parse bid size from a nested array', function () { - const width = 640; - const height = 480; - bidRequest.sizes = [ - [width, height] - ]; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.imp[0].video.w).to.equal(width); - expect(data.imp[0].video.h).to.equal(height); - }); - - it('should set pubId to HBExchange when bid.params.video.e2etest = true', function () { - bidRequest.params.video.e2etest = true; - const requests = spec.buildRequests([bidRequest], bidderRequest); - expect(requests[0].method).to.equal('POST'); - expect(requests[0].url).to.equal(spec.E2ETESTENDPOINT + 'HBExchange'); - }); - - it('should attach End 2 End test data', function () { - bidRequest.params.video.e2etest = true; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.imp[0].bidfloor).to.not.exist; - expect(data.imp[0].video.w).to.equal(300); - expect(data.imp[0].video.h).to.equal(250); - expect(data.imp[0].video.mimes).to.eql(['video/mp4', 'application/javascript']); - expect(data.imp[0].video.api).to.eql([2]); - expect(data.site.page).to.equal('https://verizonmedia.com'); - expect(data.site.ref).to.equal('https://verizonmedia.com'); - expect(data.tmax).to.equal(1000); - }); - - it('it should create new schain and send it if video.params.sid exists', function () { - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - const schain = data.source.ext.schain; - expect(schain.nodes.length).to.equal(1); - expect(schain.nodes[0].sid).to.equal(bidRequest.params.video.sid); - expect(schain.nodes[0].rid).to.equal(data.id); - }) - - it('should send Global or Bidder specific schain if sid is not passed in video.params.sid', function () { - bidRequest.params.video.sid = null; - const globalSchain = { - ver: '1.0', - complete: 1, - nodes: [{ - asi: 'some-platform.com', - sid: '111111', - rid: bidRequest.id, - hp: 1 - }] - }; - bidRequest.schain = globalSchain; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - const schain = data.source.ext.schain; - expect(schain.nodes.length).to.equal(1); - expect(schain).to.equal(globalSchain); - }); - - it('should ignore Global or Bidder specific schain if video.params.sid exists and send new schain', function () { - const globalSchain = { - ver: '1.0', - complete: 1, - nodes: [{ - asi: 'some-platform.com', - sid: '111111', - rid: bidRequest.id, - hp: 1 - }] - }; - bidRequest.schain = globalSchain; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - const schain = data.source.ext.schain; - expect(schain.nodes.length).to.equal(1); - expect(schain.complete).to.equal(1); - expect(schain.nodes[0].sid).to.equal(bidRequest.params.video.sid); - expect(schain.nodes[0].rid).to.equal(data.id); - }) - - it('should append hp to new schain created by sid if video.params.hp is passed', function () { - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - const schain = data.source.ext.schain; - expect(schain.nodes[0].hp).to.equal(bidRequest.params.video.hp); - }) - it('should not accept key values pairs if custom is Undefined ', function () { - bidRequest.params.video.custom = null; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.imp[0].ext.custom).to.be.undefined; - }); - it('should not accept key values pairs if custom is Array ', function () { - bidRequest.params.video.custom = []; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.imp[0].ext.custom).to.be.undefined; - }); - it('should not accept key values pairs if custom is Number ', function () { - bidRequest.params.video.custom = 123456; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.imp[0].ext.custom).to.be.undefined; - }); - it('should not accept key values pairs if custom is String ', function () { - bidRequest.params.video.custom = 'keyValuePairs'; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.imp[0].ext.custom).to.be.undefined; - }); - it('should not accept key values pairs if custom is Boolean ', function () { - bidRequest.params.video.custom = true; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.imp[0].ext.custom).to.be.undefined; - }); - it('should accept key values pairs if custom is Object ', function () { - bidRequest.params.video.custom = {}; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.imp[0].ext.custom).to.be.a('object'); - }); - it('should accept key values pairs if custom is Object ', function () { - bidRequest.params.video.custom = { - key1: 'value1', - key2: 'value2', - key3: 4444444, - key4: false, - key5: { - nested: 'object' - }, - key6: ['string', 2, true, null], - key7: null, - key8: undefined - }; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const custom = requests[0].data.imp[0].ext.custom; - expect(custom['key1']).to.be.a('string'); - expect(custom['key2']).to.be.a('string'); - expect(custom['key3']).to.be.a('number'); - expect(custom['key4']).to.not.exist; - expect(custom['key5']).to.not.exist; - expect(custom['key6']).to.not.exist; - expect(custom['key7']).to.not.exist; - expect(custom['key8']).to.not.exist; - }); - - describe('content object validations', function () { - it('should not accept content object if value is Undefined ', function () { - bidRequest.params.video.content = null; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.site.content).to.be.undefined; - }); - it('should not accept content object if value is is Array ', function () { - bidRequest.params.video.content = []; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.site.content).to.be.undefined; - }); - it('should not accept content object if value is Number ', function () { - bidRequest.params.video.content = 123456; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.site.content).to.be.undefined; - }); - it('should not accept content object if value is String ', function () { - bidRequest.params.video.content = 'keyValuePairs'; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.site.content).to.be.undefined; - }); - it('should not accept content object if value is Boolean ', function () { - bidRequest.params.video.content = true; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.site.content).to.be.undefined; - }); - it('should accept content object if value is Object ', function () { - bidRequest.params.video.content = {}; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.site.content).to.be.a('object'); - }); - - it('should not append unsupported content object keys', function () { - bidRequest.params.video.content = { - fake: 'news', - unreal: 'param', - counterfit: 'data' - }; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.site.content).to.be.empty; - }); - - it('should not append content string parameters if value is not string ', function () { - bidRequest.params.video.content = { - id: 1234, - title: ['Title'], - series: ['Series'], - season: ['Season'], - genre: ['Genre'], - contentrating: {1: 'C-Rating'}, - language: {1: 'EN'} - }; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.site.content).to.be.a('object'); - expect(data.site.content).to.be.empty - }); - it('should not append content Number parameters if value is not Number ', function () { - bidRequest.params.video.content = { - episode: '1', - context: 'context', - livestream: {0: 'stream'}, - len: [360], - prodq: [1], - }; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.site.content).to.be.a('object'); - expect(data.site.content).to.be.empty - }); - it('should not append content Array parameters if value is not Array ', function () { - bidRequest.params.video.content = { - cat: 'categories', - }; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.site.content).to.be.a('object'); - expect(data.site.content).to.be.empty - }); - it('should not append content ext if value is not Object ', function () { - bidRequest.params.video.content = { - ext: 'content.ext', - }; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.site.content).to.be.a('object'); - expect(data.site.content).to.be.empty - }); - it('should append supported parameters if value match validations ', function () { - bidRequest.params.video.content = { - id: '1234', - title: 'Title', - series: 'Series', - season: 'Season', - cat: [ - 'IAB1' - ], - genre: 'Genre', - contentrating: 'C-Rating', - language: 'EN', - episode: 1, - prodq: 1, - context: 1, - livestream: 0, - len: 360, - ext: {} - }; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.site.content).to.deep.equal(bidRequest.params.video.content); - }); - }); - }); - - describe('price floor module validations', function () { - beforeEach(function () { - bidRequest.getFloor = (floorObj) => { - return { - floor: bidRequest.floors.values[floorObj.mediaType + '|640x480'], - currency: floorObj.currency, - mediaType: floorObj.mediaType - } - } - }); - - it('should get bidfloor from getFloor method', function () { - bidRequest.params.cur = 'EUR'; - bidRequest.floors = { - currency: 'EUR', - values: { - 'video|640x480': 5.55 - } - }; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.cur).is.a('string'); - expect(data.cur).to.equal('EUR'); - expect(data.imp[0].bidfloor).is.a('number'); - expect(data.imp[0].bidfloor).to.equal(5.55); - }); - - it('should use adUnit/module currency & floor instead of bid.params.bidfloor', function () { - bidRequest.params.cur = 'EUR'; - bidRequest.params.bidfloor = 3.33; - bidRequest.floors = { - currency: 'EUR', - values: { - 'video|640x480': 5.55 - } - }; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.cur).is.a('string'); - expect(data.cur).to.equal('EUR'); - expect(data.imp[0].bidfloor).is.a('number'); - expect(data.imp[0].bidfloor).to.equal(5.55); - }); - - it('should load banner instead of video floor when DAP is active bid.params.video.display = 1', function () { - bidRequest.params.video.display = 1; - bidRequest.params.cur = 'EUR'; - bidRequest.mediaTypes = { - banner: { - sizes: [ - [640, 480] - ] - } - }; - bidRequest.floors = { - currency: 'EUR', - values: { - 'banner|640x480': 2.22, - 'video|640x480': 9.99 - } - }; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.cur).is.a('string'); - expect(data.cur).to.equal('EUR'); - expect(data.imp[0].bidfloor).is.a('number'); - expect(data.imp[0].bidfloor).to.equal(2.22); - }) - - it('should load video floor when multi-format adUnit is present', function () { - bidRequest.params.cur = 'EUR'; - bidRequest.mediaTypes.banner = { - sizes: [ - [640, 480] - ] - }; - bidRequest.floors = { - currency: 'EUR', - values: { - 'banner|640x480': 2.22, - 'video|640x480': 9.99 - } - }; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - expect(data.cur).is.a('string'); - expect(data.cur).to.equal('EUR'); - expect(data.imp[0].bidfloor).is.a('number'); - expect(data.imp[0].bidfloor).to.equal(9.99); - }) - }) - - describe('spec.interpretResponse', function () { - it('should return no bids if the response is not valid', function () { - const bidResponse = spec.interpretResponse({ - body: null - }, { - bidRequest - }); - expect(bidResponse.length).to.equal(0); - }); - - it('should return no bids if the response "nurl" and "adm" are missing', function () { - const serverResponse = { - seatbid: [{ - bid: [{ - price: 6.01 - }] - }] - }; - const bidResponse = spec.interpretResponse({ - body: serverResponse - }, { - bidRequest - }); - expect(bidResponse.length).to.equal(0); - }); - - it('should return no bids if the response "price" is missing', function () { - const serverResponse = { - seatbid: [{ - bid: [{ - adm: '' - }] - }] - }; - const bidResponse = spec.interpretResponse({ - body: serverResponse - }, { - bidRequest - }); - expect(bidResponse.length).to.equal(0); - }); - - it('should return a valid video bid response with just "adm"', function () { - const serverResponse = { - seatbid: [{ - bid: [{ - id: 1, - adid: 123, - crid: 2, - price: 6.01, - adm: '' - }] - }], - cur: 'USD' - }; - const bidResponse = spec.interpretResponse({ - body: serverResponse - }, { - bidRequest - }); - let o = { - requestId: bidRequest.bidId, - bidderCode: spec.code, - cpm: serverResponse.seatbid[0].bid[0].price, - creativeId: serverResponse.seatbid[0].bid[0].crid, - vastXml: serverResponse.seatbid[0].bid[0].adm, - width: 640, - height: 480, - mediaType: 'video', - currency: 'USD', - ttl: 300, - netRevenue: true, - adUnitCode: bidRequest.adUnitCode, - renderer: (bidRequest.mediaTypes.video.context === 'outstream') ? newRenderer(bidRequest, bidResponse) : undefined, - }; - expect(bidResponse).to.deep.equal(o); - }); - // @abrowning14 check that banner DAP response is appended to o.ad + mediaType: 'banner' - it('should return a valid DAP banner bid-response', function () { - bidRequest = { - mediaTypes: { - banner: { - sizes: [640, 480] - } - }, - params: { - video: { - display: 1 - } - } - } - const serverResponse = { - seatbid: [{ - bid: [{ - id: 1, - adid: 123, - crid: 2, - price: 6.01, - adm: '
DAP UNIT HERE
' - }] - }], - cur: 'USD' - }; - const bidResponse = spec.interpretResponse({ - body: serverResponse - }, { - bidRequest - }); - expect(bidResponse.ad).to.equal('
DAP UNIT HERE
'); - expect(bidResponse.mediaType).to.equal('banner'); - expect(bidResponse.renderer).to.be.undefined; - }); - - it('should default ttl to 300', function () { - const serverResponse = {seatbid: [{bid: [{id: 1, adid: 123, crid: 2, price: 6.01, adm: ''}]}], cur: 'USD'}; - const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest }); - expect(bidResponse.ttl).to.equal(300); - }); - it('should not allow ttl above 3601, default to 300', function () { - bidRequest.params.video.ttl = 3601; - const serverResponse = {seatbid: [{bid: [{id: 1, adid: 123, crid: 2, price: 6.01, adm: ''}]}], cur: 'USD'}; - const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest }); - expect(bidResponse.ttl).to.equal(300); - }); - it('should not allow ttl below 1, default to 300', function () { - bidRequest.params.video.ttl = 0; - const serverResponse = {seatbid: [{bid: [{id: 1, adid: 123, crid: 2, price: 6.01, adm: ''}]}], cur: 'USD'}; - const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest }); - expect(bidResponse.ttl).to.equal(300); - }); - it('should use custom ttl if under 3600', function () { - bidRequest.params.video.ttl = 1000; - const serverResponse = {seatbid: [{bid: [{id: 1, adid: 123, crid: 2, price: 6.01, adm: ''}]}], cur: 'USD'}; - const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest }); - expect(bidResponse.ttl).to.equal(1000); - }); - }); - - describe('when GDPR and uspConsent applies', function () { - beforeEach(function () { - bidderRequest = { - 'gdprConsent': { - 'consentString': 'test-gdpr-consent-string', - 'gdprApplies': true - }, - 'uspConsent': '1YN-', - 'bidderCode': 'oneVideo', - 'auctionId': 'e158486f-8c7f-472f-94ce-b0cbfbb50ab4', - 'bidderRequestId': '1e498b84fffc39', - 'bids': bidRequest, - 'auctionStart': 1520001292880, - 'timeout': 3000, - 'start': 1520001292884, - 'doneCbCallCount': 0, - 'refererInfo': { - 'numIframes': 1, - 'reachedTop': true, - 'referer': 'test.com' - } - }; - - mockConfig = { - consentManagement: { - gdpr: { - cmpApi: 'iab', - timeout: 3000, - allowAuctionWithoutConsent: 'cancel' - }, - usp: { - cmpApi: 'iab', - timeout: 1000, - allowAuctionWithoutConsent: 'cancel' - } - } - }; - }); - - it('should send a signal to specify that GDPR applies to this request', function () { - const request = spec.buildRequests([bidRequest], bidderRequest); - expect(request[0].data.regs.ext.gdpr).to.equal(1); - }); - - it('should send the consent string', function () { - const request = spec.buildRequests([bidRequest], bidderRequest); - expect(request[0].data.user.ext.consent).to.equal(bidderRequest.gdprConsent.consentString); - }); - - it('should send the uspConsent string', function () { - const request = spec.buildRequests([bidRequest], bidderRequest); - expect(request[0].data.regs.ext.us_privacy).to.equal(bidderRequest.uspConsent); - }); - - it('should send the uspConsent and GDPR ', function () { - const request = spec.buildRequests([bidRequest], bidderRequest); - expect(request[0].data.regs.ext.gdpr).to.equal(1); - expect(request[0].data.regs.ext.us_privacy).to.equal(bidderRequest.uspConsent); - }); - }); - - describe('should send banner object', function () { - it('should send banner object when display is 1 and context="instream" (DAP O&O)', function () { - bidRequest = { - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480] - } - }, - bidder: 'oneVideo', - sizes: [640, 480], - bidId: '30b3efwfwe1e', - adUnitCode: 'video1', - params: { - video: { - playerWidth: 640, - playerHeight: 480, - mimes: ['video/mp4', 'application/javascript'], - protocols: [2, 5], - api: [2], - position: 1, - delivery: [2], - playbackmethod: [1, 5], - placement: 1, - inventoryid: 123, - sid: 134, - display: 1, - minduration: 10, - maxduration: 30 - }, - site: { - id: 1, - page: 'https://www.yahoo.com/', - referrer: 'http://www.yahoo.com' - }, - pubId: 'OneMDisplay' - } - }; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - const width = bidRequest.params.video.playerWidth; - const height = bidRequest.params.video.playerHeight; - const position = bidRequest.params.video.position; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - expect(data.imp[0].banner.w).to.equal(width); - expect(data.imp[0].banner.h).to.equal(height); - expect(data.imp[0].banner.pos).to.equal(position); - expect(data.imp[0].ext.inventoryid).to.equal(bidRequest.params.video.inventoryid); - expect(data.imp[0].banner.mimes).to.equal(bidRequest.params.video.mimes); - expect(data.imp[0].banner.placement).to.equal(bidRequest.params.video.placement); - expect(data.imp[0].banner.ext.minduration).to.equal(bidRequest.params.video.minduration); - expect(data.imp[0].banner.ext.maxduration).to.equal(bidRequest.params.video.maxduration); - expect(data.site.id).to.equal(bidRequest.params.site.id); - }); - it('should send video object when display is other than 1 (VAST for All)', function () { - bidRequest = { - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480] - } - }, - bidder: 'oneVideo', - sizes: [640, 480], - bidId: '30b3efwfwe1e', - adUnitCode: 'video1', - params: { - video: { - playerWidth: 640, - playerHeight: 480, - mimes: ['video/mp4', 'application/javascript'], - protocols: [2, 5], - api: [2], - position: 1, - delivery: [2], - playbackmethod: [1, 5], - placement: 123, - sid: 134, - display: 12 - }, - site: { - id: 1, - page: 'https://www.yahoo.com/', - referrer: 'http://www.yahoo.com' - }, - pubId: 'OneMDisplay' - } - }; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - const width = bidRequest.params.video.playerWidth; - const height = bidRequest.params.video.playerHeight; - const position = bidRequest.params.video.position; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - expect(data.imp[0].video.w).to.equal(width); - expect(data.imp[0].video.h).to.equal(height); - expect(data.imp[0].video.pos).to.equal(position); - expect(data.imp[0].video.mimes).to.equal(bidRequest.params.video.mimes); - }); - it('should send video object when display is not passed (VAST for All)', function () { - bidRequest = { - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480] - } - }, - bidder: 'oneVideo', - sizes: [640, 480], - bidId: '30b3efwfwe1e', - adUnitCode: 'video1', - params: { - video: { - playerWidth: 640, - playerHeight: 480, - mimes: ['video/mp4', 'application/javascript'], - protocols: [2, 5], - api: [2], - position: 1, - delivery: [2], - playbackmethod: [1, 5], - placement: 123, - sid: 134, - minduration: 10, - maxduration: 30 - }, - site: { - id: 1, - page: 'https://www.yahoo.com/', - referrer: 'http://www.yahoo.com' - }, - pubId: 'OneMDisplay' - } - }; - const requests = spec.buildRequests([bidRequest], bidderRequest); - const data = requests[0].data; - const width = bidRequest.params.video.playerWidth; - const height = bidRequest.params.video.playerHeight; - const position = bidRequest.params.video.position; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - expect(data.imp[0].video.w).to.equal(width); - expect(data.imp[0].video.h).to.equal(height); - expect(data.imp[0].video.pos).to.equal(position); - expect(data.imp[0].video.mimes).to.equal(bidRequest.params.video.mimes); - expect(data.imp[0].video.protocols).to.equal(bidRequest.params.video.protocols); - expect(data.imp[0].video.linearity).to.equal(1); - expect(data.imp[0].video.maxduration).to.equal(bidRequest.params.video.maxduration); - expect(data.imp[0].video.minduration).to.equal(bidRequest.params.video.minduration); - }); - describe('getUserSyncs', function () { - const GDPR_CONSENT_STRING = 'GDPR_CONSENT_STRING'; - - it('should get correct user sync when iframeEnabled', function () { - let pixel = spec.getUserSyncs({ - pixelEnabled: true - }, {}, { - gdprApplies: true, - consentString: GDPR_CONSENT_STRING - }) - expect(pixel[1].type).to.equal('image'); - expect(pixel[1].url).to.equal('https://sync-tm.everesttech.net/upi/pid/m7y5t93k?gdpr=1&gdpr_consent=' + GDPR_CONSENT_STRING + '&redir=https%3A%2F%2Fpixel.advertising.com%2Fups%2F55986%2Fsync%3Fuid%3D%24%7BUSER_ID%7D%26_origin%3D0&gdpr=1&gdpr_consent=' + encodeURI(GDPR_CONSENT_STRING)); - }); - - it('should default to gdprApplies=0 when consentData is undefined', function () { - let pixel = spec.getUserSyncs({ - pixelEnabled: true - }, {}, undefined); - expect(pixel[1].url).to.equal('https://sync-tm.everesttech.net/upi/pid/m7y5t93k?gdpr=0&gdpr_consent=&redir=https%3A%2F%2Fpixel.advertising.com%2Fups%2F55986%2Fsync%3Fuid%3D%24%7BUSER_ID%7D%26_origin%3D0&gdpr=0&gdpr_consent='); - }); - }); - - describe('verify sync pixels', function () { - let pixel = spec.getUserSyncs({ - pixelEnabled: true - }, {}, undefined); - it('should be UPS sync pixel for DBM', function () { - expect(pixel[0].url).to.equal('https://pixel.advertising.com/ups/57304/sync?gdpr=&gdpr_consent=&_origin=0&redir=true') - }); - - it('should be TTD sync pixel', function () { - expect(pixel[2].url).to.equal('https://match.adsrvr.org/track/cmf/generic?ttd_pid=adaptv&ttd_tpi=1') - }); - }) - }); -}); diff --git a/test/spec/modules/onetagBidAdapter_spec.js b/test/spec/modules/onetagBidAdapter_spec.js deleted file mode 100644 index c1462c3814d..00000000000 --- a/test/spec/modules/onetagBidAdapter_spec.js +++ /dev/null @@ -1,411 +0,0 @@ -import { spec, isValid, hasTypeVideo } from 'modules/onetagBidAdapter.js'; -import { expect } from 'chai'; -import find from 'core-js-pure/features/array/find.js'; -import { BANNER, VIDEO } from 'src/mediaTypes.js'; -import {INSTREAM, OUTSTREAM} from 'src/video.js'; - -describe('onetag', function () { - function createBid() { - return { - 'bidder': 'onetag', - 'params': { - 'pubId': '386276e072', - }, - 'adUnitCode': 'adunit-code', - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'transactionId': 'qwerty123' - }; - } - - function createBannerBid(bidRequest) { - const bid = bidRequest || createBid(); - bid.mediaTypes = bid.mediaTypes || {}; - bid.mediaTypes.banner = { - sizes: [[300, 250]] - }; - return bid; - } - - function createInstreamVideoBid(bidRequest) { - const bid = bidRequest || createBid(); - bid.mediaTypes = bid.mediaTypes || {}; - bid.mediaTypes.video = { - context: 'instream', - mimes: ['video/mp4', 'video/webm', 'application/javascript', 'video/ogg'], - playerSize: [640, 480] - }; - return bid; - } - - function createOutstreamVideoBid(bidRequest) { - const bid = bidRequest || createBid(); - bid.mediaTypes = bid.mediaTypes || {}; - bid.mediaTypes.video = { - context: 'outstream', - mimes: ['video/mp4', 'video/webm', 'application/javascript', 'video/ogg'], - playerSize: [640, 480] - }; - return bid; - } - - function createMultiFormatBid() { - return createInstreamVideoBid(createBannerBid()); - } - - const bannerBid = createBannerBid(); - const instreamVideoBid = createInstreamVideoBid(); - const outstreamVideoBid = createOutstreamVideoBid(); - - describe('isBidRequestValid', function () { - it('Should return true when required params are found', function () { - expect(spec.isBidRequestValid(bannerBid)).to.be.true; - }); - it('Should return false when pubId is not a string', function () { - bannerBid.params.pubId = 30; - expect(spec.isBidRequestValid(bannerBid)).to.be.false; - }); - it('Should return false when pubId is undefined', function () { - bannerBid.params.pubId = undefined; - expect(spec.isBidRequestValid(bannerBid)).to.be.false; - }); - describe('banner bidRequest', function () { - it('Should return false when the sizes array is empty', function () { - bannerBid.sizes = []; - expect(spec.isBidRequestValid(bannerBid)).to.be.false; - }); - }); - describe('video bidRequest', function () { - it('Should return false when the context is undefined', function () { - instreamVideoBid.mediaTypes.video.context = undefined; - expect(spec.isBidRequestValid(instreamVideoBid)).to.be.false; - }); - it('Should return false when the context is not instream or outstream', function () { - instreamVideoBid.mediaTypes.video.context = 'wrong'; - expect(spec.isBidRequestValid(instreamVideoBid)).to.be.false; - }); - it('Should return false when playerSize is undefined', function () { - const videoBid = createInstreamVideoBid(); - videoBid.mediaTypes.video.playerSize = undefined; - expect(spec.isBidRequestValid(videoBid)).to.be.false; - }); - it('Should return false when playerSize is not an array', function () { - const videoBid = createInstreamVideoBid(); - videoBid.mediaTypes.video.playerSize = 30; - expect(spec.isBidRequestValid(videoBid)).to.be.false; - }); - it('Should return false when playerSize is an empty array', function () { - const videoBid = createInstreamVideoBid(); - videoBid.mediaTypes.video.playerSize = []; - expect(spec.isBidRequestValid(videoBid)).to.be.false; - }); - it('Should return true when context is outstream', function () { - expect(spec.isBidRequestValid(outstreamVideoBid)).to.be.true; - }); - }); - describe('multi format bidRequest', function () { - const multiFormatBid = createMultiFormatBid(); - it('Should return true when correct multi format bid is passed', function () { - expect(spec.isBidRequestValid(multiFormatBid)).to.be.true; - }); - }); - }); - - describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bannerBid, instreamVideoBid]); - 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://onetag-sys.com/prebid-request'); - }); - - const d = serverRequest.data; - try { - const data = JSON.parse(d); - it('Should contain all keys', function () { - expect(data).to.be.an('object'); - expect(data).to.include.all.keys('location', 'referrer', 'masked', 'sHeight', 'sWidth', 'docHeight', 'wHeight', 'wWidth', 'oHeight', 'oWidth', 'aWidth', 'aHeight', 'sLeft', 'sTop', 'hLength', 'bids', 'docHidden', 'xOffset', 'yOffset', 'timing', 'version'); - expect(data.location).to.be.a('string'); - expect(data.masked).to.be.oneOf([0, 1, 2]); - expect(data.referrer).to.satisfy(referrer => referrer === null || typeof referrer === 'string'); - expect(data.sHeight).to.be.a('number'); - expect(data.sWidth).to.be.a('number'); - expect(data.wWidth).to.be.a('number'); - expect(data.wHeight).to.be.a('number'); - expect(data.oHeight).to.be.a('number'); - expect(data.oWidth).to.be.a('number'); - expect(data.aWidth).to.be.a('number'); - expect(data.aHeight).to.be.a('number'); - expect(data.sLeft).to.be.a('number'); - expect(data.sTop).to.be.a('number'); - expect(data.hLength).to.be.a('number'); - expect(data.bids).to.be.an('array'); - expect(data.version).to.have.all.keys('prebid', 'adapter'); - const bids = data['bids']; - for (let i = 0; i < bids.length; i++) { - const bid = bids[i]; - if (hasTypeVideo(bid)) { - expect(bid).to.have.all.keys('adUnitCode', 'auctionId', 'bidId', 'bidderRequestId', 'pubId', 'transactionId', 'context', 'mimes', 'playerSize', 'protocols', 'maxDuration', 'api', 'type'); - } else if (isValid(BANNER, bid)) { - expect(bid).to.have.all.keys('adUnitCode', 'auctionId', 'bidId', 'bidderRequestId', 'pubId', 'transactionId', 'sizes', 'type'); - } - expect(bid.bidId).to.be.a('string'); - expect(bid.pubId).to.be.a('string'); - } - }); - } catch (e) {} - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); - let dataString = serverRequest.data; - try { - let dataObj = JSON.parse(dataString); - expect(dataObj.bids).to.be.an('array').that.is.empty; - } catch (e) {} - }); - it('should send GDPR consent data', function () { - let consentString = 'consentString'; - let bidderRequest = { - 'bidderCode': 'onetag', - 'auctionId': '1d1a030790a475', - 'bidderRequestId': '22edbae2733bf6', - 'timeout': 3000, - 'gdprConsent': { - consentString: consentString, - gdprApplies: true - } - }; - let serverRequest = spec.buildRequests([bannerBid], bidderRequest); - const payload = JSON.parse(serverRequest.data); - - expect(payload).to.exist; - expect(payload.gdprConsent).to.exist; - expect(payload.gdprConsent.consentString).to.exist.and.to.equal(consentString); - expect(payload.gdprConsent.consentRequired).to.exist.and.to.be.true; - }); - it('Should send us privacy string', function () { - let consentString = 'us_foo'; - let bidderRequest = { - 'bidderCode': 'onetag', - 'auctionId': '1d1a030790a475', - 'bidderRequestId': '22edbae2733bf6', - 'timeout': 3000, - 'uspConsent': consentString - }; - let serverRequest = spec.buildRequests([bannerBid], bidderRequest); - const payload = JSON.parse(serverRequest.data); - - expect(payload.usPrivacy).to.exist; - expect(payload.usPrivacy).to.exist.and.to.equal(consentString); - }); - }); - describe('interpretResponse', function () { - const request = getBannerVideoRequest(); - const response = getBannerVideoResponse(); - const requestData = JSON.parse(request.data); - it('Returns an array of valid server responses if response object is valid', function () { - const interpretedResponse = spec.interpretResponse(response, request); - expect(interpretedResponse).to.be.an('array').that.is.not.empty; - for (let i = 0; i < interpretedResponse.length; i++) { - let dataItem = interpretedResponse[i]; - expect(dataItem).to.include.all.keys('requestId', 'cpm', 'width', 'height', 'ttl', 'creativeId', 'netRevenue', 'currency', 'meta', 'dealId'); - if (dataItem.meta.mediaType === VIDEO) { - const {context} = find(requestData.bids, (item) => item.bidId === dataItem.requestId); - if (context === INSTREAM) { - expect(dataItem).to.include.all.keys('videoCacheKey', 'vastUrl'); - expect(dataItem.vastUrl).to.be.a('string'); - expect(dataItem.videoCacheKey).to.be.a('string'); - } else if (context === OUTSTREAM) { - expect(dataItem).to.include.all.keys('renderer', 'vastXml', 'vastUrl'); - expect(dataItem.renderer).to.be.an('object'); - expect(dataItem.vastUrl).to.be.a('string'); - expect(dataItem.vastXml).to.be.a('string'); - } - } else if (dataItem.meta.mediaType === BANNER) { - expect(dataItem).to.include.all.keys('ad'); - expect(dataItem.ad).to.be.a('string'); - } - 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.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'); - } - }); - it('Returns an empty array if response is not valid', function () { - const serverResponses = spec.interpretResponse('invalid_response', { data: '{}' }); - expect(serverResponses).to.be.an('array').that.is.empty; - }); - }); - describe('getUserSyncs', function () { - const sync_endpoint = 'https://onetag-sys.com/usync/'; - it('Returns an iframe if iframeEnabled is true', function () { - const syncs = spec.getUserSyncs({iframeEnabled: true}); - 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_endpoint); - }); - it('Returns an empty array if iframeEnabled is false', function () { - const syncs = spec.getUserSyncs({ iframeEnabled: false }); - expect(syncs).to.be.an('array').that.is.empty; - }); - it('Must pass gdpr params when gdprApplies is true', function () { - const syncs = spec.getUserSyncs({ iframeEnabled: true }, {}, { - gdprApplies: true, consentString: 'foo' - }); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.include(sync_endpoint); - expect(syncs[0].url).to.match(/(?:[?&](?:gdpr_consent=foo([^&]*)|gdpr=1([^&]*)|[^&]*))+$/); - }); - it('Must pass gdpr params when gdprApplies is false', function () { - const syncs = spec.getUserSyncs({ iframeEnabled: true }, {}, { - gdprApplies: false, consentString: 'foo' - }); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.include(sync_endpoint); - expect(syncs[0].url).to.match(/(?:[?&](?:gdpr_consent=foo([^&]*)|gdpr=0([^&]*)))+$/); - }); - it('Must pass gdpr consent string param when gdprApplies is undefined', function () { - const syncs = spec.getUserSyncs({ iframeEnabled: true }, {}, { - consentString: 'foo' - }); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.include(sync_endpoint); - expect(syncs[0].url).to.match(/(?:[?&](?:gdpr_consent=foo([^&]*)))+$/); - }); - it('Must pass no gdpr params when consentString is null', function () { - const syncs = spec.getUserSyncs({ iframeEnabled: true }, {}, { - consentString: null - }); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.include(sync_endpoint); - expect(syncs[0].url).to.not.match(/(?:[?&](?:gdpr_consent=([^&]*)|gdpr=([^&]*)))+$/); - }); - it('Must pass no gdpr param when gdprConsent is empty', function () { - const syncs = spec.getUserSyncs({ iframeEnabled: true }, {}, {}); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.include(sync_endpoint); - expect(syncs[0].url).to.not.match(/(?:[?&](?:gdpr_consent=([^&]*)|gdpr=([^&]*)))+$/); - }); - it('Should send us privacy string', function () { - let usConsentString = 'us_foo'; - const syncs = spec.getUserSyncs({ iframeEnabled: true }, {}, {}, usConsentString); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.include(sync_endpoint); - expect(syncs[0].url).to.match(/(?:[?&](?:us_privacy=us_foo(?:[&][^&]*)*))+$/); - }); - }); -}); - -function getBannerVideoResponse() { - return { - body: { - nobid: false, - bids: [ - { - ad: '
Advertising
', - cpm: 13, - width: 300, - height: 250, - creativeId: '1820', - dealId: 'dishfo', - currency: 'USD', - requestId: 'banner', - mediaType: BANNER, - }, - { - cpm: 13, - width: 300, - height: 250, - creativeId: '1820', - dealId: 'dishfo', - currency: 'USD', - requestId: 'videoInstream', - vastUrl: 'https://videoinstream.org', - videoCacheKey: 'key', - mediaType: VIDEO - }, - { - cpm: 13, - width: 300, - height: 250, - creativeId: '1820', - dealId: 'dishfo', - currency: 'USD', - vastUrl: 'https://videooutstream.org', - requestId: 'videoOutstream', - ad: '', - rendererUrl: 'https://testRenderer', - mediaType: VIDEO - } - ] - } - }; -} - -function getBannerVideoRequest() { - return { - data: JSON.stringify({ - bids: [ - { - adUnitCode: 'target-div', - bidId: 'videoOutstream', - bidderRequestId: '12bb1e0f9fb669', - auctionId: '80784b4d-79ad-49ef-a006-75d8888b7609', - transactionId: '5f132731-3091-49b2-8fab-0e9c917733bc', - pubId: '386276e072', - context: 'outstream', - mimes: [], - playerSize: [], - type: 'video' - }, - { - adUnitCode: 'target-div', - bidId: 'videoInstream', - bidderRequestId: '12bb1e0f9fb669', - auctionId: '80784b4d-79ad-49ef-a006-75d8888b7609', - transactionId: '5f132731-3091-49b2-8fab-0e9c917733bc', - pubId: '386276e072', - context: 'instream', - mimes: [], - playerSize: [], - type: 'video' - } - ], - location: 'https%3A%2F%2Flocal.onetag.net%3A9000%2Fv2%2Fprebid-video%2Fvideo.html%3Fpbjs_debug%3Dtrue', - referrer: '0', - masked: 0, - wWidth: 860, - wHeight: 949, - oWidth: 1853, - oHeight: 1053, - sWidth: 1920, - sHeight: 1080, - aWidth: 1920, - aHeight: 1053, - sLeft: 1987, - sTop: 27, - xOffset: 0, - yOffset: 0, - docHidden: false, - hLength: 2, - timing: { - pageLoadTime: -1593433770022, - connectTime: 42, - renderTime: -1593433770092 - }, - onetagSid: 'user_id' - }) - } -} diff --git a/test/spec/modules/onomagicBidAdapter_spec.js b/test/spec/modules/onomagicBidAdapter_spec.js deleted file mode 100644 index 7c71c3e5764..00000000000 --- a/test/spec/modules/onomagicBidAdapter_spec.js +++ /dev/null @@ -1,285 +0,0 @@ -import { expect } from 'chai'; -import * as utils from 'src/utils.js'; -import { spec } from 'modules/onomagicBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -const URL = 'https://bidder.onomagic.com/hb'; - -describe('onomagicBidAdapter', function() { - const adapter = newBidder(spec); - let element, win; - let bidRequests; - let sandbox; - - beforeEach(function() { - element = { - x: 0, - y: 0, - - width: 0, - height: 0, - - getBoundingClientRect: () => { - return { - width: element.width, - height: element.height, - - left: element.x, - top: element.y, - right: element.x + element.width, - bottom: element.y + element.height - }; - } - }; - win = { - document: { - visibilityState: 'visible' - }, - - innerWidth: 800, - innerHeight: 600 - }; - bidRequests = [{ - 'bidder': 'onomagic', - 'params': { - 'publisherId': 1234567 - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'bidId': '5fb26ac22bde4', - 'bidderRequestId': '4bf93aeb730cb9', - 'auctionId': 'ffe9a1f7-7b67-4bda-a8e0-9ee5dc9f442e' - }]; - - sandbox = sinon.sandbox.create(); - sandbox.stub(document, 'getElementById').withArgs('adunit-code').returns(element); - sandbox.stub(utils, 'getWindowTop').returns(win); - sandbox.stub(utils, 'getWindowSelf').returns(win); - }); - - afterEach(function() { - sandbox.restore(); - }); - - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'onomagic', - 'params': { - 'publisherId': 1234567 - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'bidId': '5fb26ac22bde4', - 'bidderRequestId': '4bf93aeb730cb9', - 'auctionId': 'ffe9a1f7-7b67-4bda-a8e0-9ee5dc9f442e', - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when publisherId not passed correctly', function () { - bid.params.publisherId = undefined; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when require params are not passed', function () { - let bid = Object.assign({}, bid); - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - it('sends bid request to our endpoint via POST', function () { - const request = spec.buildRequests(bidRequests); - expect(request.method).to.equal('POST'); - }); - - it('request url should match our endpoint url', function () { - const request = spec.buildRequests(bidRequests); - expect(request.url).to.equal(URL); - }); - - 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}]); - }); - - 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}]); - }); - - it('sends bidfloor param if present', function () { - bidRequests[0].params.bidFloor = 0.05; - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.imp[0].bidfloor).to.equal(0.05); - }); - - it('sends tagid', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.imp[0].tagid).to.equal('adunit-code'); - }); - - it('sends publisher id', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.site.publisher.id).to.equal(1234567); - }); - - context('when element is fully in view', function() { - it('returns 100', function() { - 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); - }); - }); - - context('when element is out of view', function() { - it('returns 0', function() { - 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); - }); - }); - - context('when element is partially in view', function() { - it('returns percentage', function() { - 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); - }); - }); - - context('when width or height of the element is zero', function() { - it('try to use alternative values', function() { - 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); - expect(payload.imp[0].banner.ext.viewability).to.equal(25); - }); - }); - - context('when nested iframes', function() { - it('returns \'na\'', function() { - Object.assign(element, { width: 600, height: 400 }); - - utils.getWindowTop.restore(); - utils.getWindowSelf.restore(); - sandbox.stub(utils, 'getWindowTop').returns(win); - sandbox.stub(utils, 'getWindowSelf').returns({}); - - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.imp[0].banner.ext.viewability).to.equal('na'); - }); - }); - - context('when tab is inactive', function() { - it('returns 0', function() { - Object.assign(element, { width: 600, height: 400 }); - - utils.getWindowTop.restore(); - win.document.visibilityState = 'hidden'; - sandbox.stub(utils, 'getWindowTop').returns(win); - - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.imp[0].banner.ext.viewability).to.equal(0); - }); - }); - }); - - describe('interpretResponse', function () { - let response; - beforeEach(function () { - response = { - body: { - 'id': '37386aade21a71', - 'seatbid': [{ - 'bid': [{ - 'id': '376874781', - 'impid': '283a9f4cd2415d', - 'price': 0.35743275, - 'nurl': '', - 'adm': '', - 'w': 300, - 'h': 250 - }] - }] - } - }; - }); - - it('should get the correct bid response', function () { - let expectedResponse = [{ - 'requestId': '283a9f4cd2415d', - 'cpm': 0.35743275, - 'width': 300, - 'height': 250, - 'creativeId': '376874781', - 'currency': 'USD', - 'netRevenue': true, - 'mediaType': 'banner', - 'ad': `
`, - 'ttl': 60 - }]; - - let result = spec.interpretResponse(response); - expect(result[0]).to.deep.equal(expectedResponse[0]); - }); - - it('crid should default to the bid id if not on the response', function () { - let expectedResponse = [{ - 'requestId': '283a9f4cd2415d', - 'cpm': 0.35743275, - 'width': 300, - 'height': 250, - 'creativeId': response.body.seatbid[0].bid[0].id, - 'currency': 'USD', - 'netRevenue': true, - 'mediaType': 'banner', - 'ad': `
`, - 'ttl': 60 - }]; - - let result = spec.interpretResponse(response); - expect(result[0]).to.deep.equal(expectedResponse[0]); - }); - - it('handles empty bid response', function () { - let response = { - body: '' - }; - let result = spec.interpretResponse(response); - expect(result.length).to.equal(0); - }); - }); - - describe('getUserSyncs ', () => { - let syncOptions = {iframeEnabled: true, pixelEnabled: true}; - - it('should not return', () => { - let returnStatement = spec.getUserSyncs(syncOptions, []); - expect(returnStatement).to.be.empty; - }); - }); -}); diff --git a/test/spec/modules/ooloAnalyticsAdapter_spec.js b/test/spec/modules/ooloAnalyticsAdapter_spec.js deleted file mode 100644 index f82f7856fb2..00000000000 --- a/test/spec/modules/ooloAnalyticsAdapter_spec.js +++ /dev/null @@ -1,793 +0,0 @@ -import ooloAnalytics, { PAGEVIEW_ID } from 'modules/ooloAnalyticsAdapter.js'; -import {expect} from 'chai'; -import {server} from 'test/mocks/xhr.js'; -import constants from 'src/constants.json' -import events from 'src/events' -import { config } from 'src/config'; -import { buildAuctionData, generatePageViewId } from 'modules/ooloAnalyticsAdapter'; - -const auctionId = '0ea14159-2058-4b87-a966-9d7652176a56'; -const auctionStart = 1598513385415 -const timeout = 3000 -const adUnit1 = 'top_1'; -const adUnit2 = 'top_2'; -const bidId1 = '392b5a6b05d648' -const bidId2 = '392b5a6b05d649' -const bidId3 = '392b5a6b05d650' - -const auctionInit = { - timestamp: auctionStart, - auctionId: auctionId, - timeout: timeout, - auctionStart, - adUnits: [{ - code: adUnit1, - transactionId: 'abalksdkjfh-12sade' - }, { - code: adUnit2, - transactionId: 'abalksdkjfh-12sadf' - }] -}; - -const bidRequested = { - auctionId, - bidderCode: 'appnexus', - bidderRequestId: '2946b569352ef2', - start: 1598513405254, - bids: [ - { - auctionId, - bidId: bidId1, - bidderRequestId: '2946b569352ef2', - bidder: 'appnexus', - adUnitCode: adUnit1, - sizes: [[728, 90], [970, 90]], - mediaTypes: { - banner: { - sizes: [[728, 90], [970, 90]], - }, - }, - params: { - placementId: '4799418', - }, - schain: {} - }, - { - auctionId, - bidId: bidId2, - bidderRequestId: '2946b569352ef3', - bidder: 'rubicon', - adUnitCode: adUnit2, - sizes: [[728, 90], [970, 90]], - mediaTypes: { - banner: { - sizes: [[728, 90], [970, 90]], - }, - }, - params: { - placementId: '4799418', - }, - schain: {} - }, - { - auctionId, - bidId: bidId3, - bidderRequestId: '2946b569352ef4', - bidder: 'ix', - adUnitCode: adUnit2, - sizes: [[728, 90], [970, 90]], - mediaTypes: { - banner: { - sizes: [[728, 90], [970, 90]], - }, - }, - params: { - placementId: '4799418', - }, - schain: {} - }, - ], -} - -const noBid = { - auctionId, - adUnitCode: adUnit2, - bidId: bidId2, - requestId: bidId2 -} - -const bidResponse = { - auctionId, - bidderCode: 'appnexus', - mediaType: 'banner', - width: 0, - height: 0, - statusMessage: 'Bid available', - adId: '222bb26f9e8bd', - cpm: 0.112256, - responseTimestamp: 1598513485254, - requestTimestamp: 1462919238936, - bidder: 'appnexus', - adUnitCode: adUnit1, - timeToRespond: 401, - pbLg: '0.00', - pbMg: '0.10', - pbHg: '0.11', - pbAg: '0.10', - size: '0x0', - requestId: bidId1, - creativeId: '123456', - adserverTargeting: { - hb_bidder: 'appnexus', - hb_adid: '222bb26f9e8bd', - hb_pb: '10.00', - hb_size: '0x0', - foobar: '0x0', - }, - netRevenue: true, - currency: 'USD', - ttl: 300, -} - -const auctionEnd = { - auctionId: auctionId -}; - -const bidTimeout = [ - { - adUnitCode: adUnit2, - auctionId: auctionId, - bidId: bidId3, - bidder: 'ix', - timeout: timeout - } -]; - -const bidWon = { - auctionId, - adUnitCode: adUnit1, - bidId: bidId1, - cpm: 0.5 -} - -function simulateAuction () { - events.emit(constants.EVENTS.AUCTION_INIT, auctionInit); - events.emit(constants.EVENTS.BID_REQUESTED, bidRequested); - events.emit(constants.EVENTS.BID_RESPONSE, bidResponse); - events.emit(constants.EVENTS.NO_BID, noBid); - events.emit(constants.EVENTS.BID_TIMEOUT, bidTimeout); - events.emit(constants.EVENTS.AUCTION_END, auctionEnd); -} - -describe('oolo Prebid Analytic', () => { - let clock - - beforeEach(() => { - sinon.stub(events, 'getEvents').returns([]); - clock = sinon.useFakeTimers() - }); - - afterEach(() => { - ooloAnalytics.disableAnalytics(); - events.getEvents.restore() - clock.restore(); - }) - - describe('enableAnalytics init options', () => { - it('should not enable analytics if invalid config', () => { - ooloAnalytics.enableAnalytics({ - provider: 'oolo', - options: { - pid: undefined - } - }) - - expect(server.requests).to.have.length(0) - }) - - it('should send prebid config to the server', () => { - ooloAnalytics.enableAnalytics({ - provider: 'oolo', - options: { - pid: 123 - } - }) - - const conf = {} - const pbjsConfig = config.getConfig() - - Object.keys(pbjsConfig).forEach(key => { - if (key[0] !== '_') { - conf[key] = pbjsConfig[key] - } - }) - - expect(server.requests[1].url).to.contain('/hbconf') - expect(JSON.parse(server.requests[1].requestBody)).to.deep.equal(conf) - }) - - it('should request server config and send page data', () => { - ooloAnalytics.enableAnalytics({ - provider: 'oolo', - options: { - pid: 123 - } - }) - clock.next() - - expect(server.requests[0].url).to.contain('?pid=123') - - const pageData = JSON.parse(server.requests[2].requestBody) - - expect(pageData).to.have.property('timestamp') - expect(pageData).to.have.property('screenWidth') - expect(pageData).to.have.property('screenHeight') - expect(pageData).to.have.property('url') - expect(pageData).to.have.property('protocol') - expect(pageData).to.have.property('origin') - expect(pageData).to.have.property('referrer') - expect(pageData).to.have.property('pbVersion') - expect(pageData).to.have.property('pvid') - expect(pageData).to.have.property('pid') - expect(pageData).to.have.property('pbModuleVersion') - expect(pageData).to.have.property('domContentLoadTime') - expect(pageData).to.have.property('pageLoadTime') - }) - }) - - describe('data handling and sending events', () => { - it('should send an "auction" event to the server', () => { - ooloAnalytics.enableAnalytics({ - provider: 'oolo', - options: { - pid: 123 - } - }) - clock.next() - - server.requests[0].respond(500) - - simulateAuction() - - expect(server.requests.length).to.equal(3) - clock.tick(2000) - expect(server.requests.length).to.equal(4) - - const request = JSON.parse(server.requests[3].requestBody); - - expect(request).to.include({ - eventType: 'auction', - pid: 123, - auctionId, - auctionStart, - auctionEnd: 0, - timeout, - }) - expect(request.pvid).to.be.a('number') - expect(request.adUnits).to.have.length(2) - - const auctionAdUnit1 = request.adUnits.filter(adUnit => adUnit.adunid === adUnit1)[0] - const auctionAdUnit2 = request.adUnits.filter(adUnit => adUnit.adunid === adUnit2)[0] - - expect(auctionAdUnit1.auctionId).to.equal(auctionId) - expect(auctionAdUnit1.bids).to.be.an('array') - expect(auctionAdUnit1.bids).to.have.length(1) - - // bid response - expect(auctionAdUnit1.bids[0].bidId).to.equal(bidId1) - expect(auctionAdUnit1.bids[0].bst).to.equal('bidReceived') - expect(auctionAdUnit1.bids[0].bidder).to.equal('appnexus') - expect(auctionAdUnit1.bids[0].cpm).to.equal(0.112256) - expect(auctionAdUnit1.bids[0].cur).to.equal('USD') - expect(auctionAdUnit1.bids[0].s).to.equal(bidRequested.start) - expect(auctionAdUnit1.bids[0].e).to.equal(bidResponse.responseTimestamp) - expect(auctionAdUnit1.bids[0].rs).to.equal(bidRequested.start - auctionStart) - expect(auctionAdUnit1.bids[0].re).to.equal(bidResponse.responseTimestamp - auctionStart) - expect(auctionAdUnit1.bids[0].h).to.equal(0) - expect(auctionAdUnit1.bids[0].w).to.equal(0) - expect(auctionAdUnit1.bids[0].mt).to.equal('banner') - expect(auctionAdUnit1.bids[0].nrv).to.equal(true) - expect(auctionAdUnit1.bids[0].params).to.have.keys('placementId') - expect(auctionAdUnit1.bids[0].size).to.equal('0x0') - expect(auctionAdUnit1.bids[0].crId).to.equal('123456') - expect(auctionAdUnit1.bids[0].ttl).to.equal(bidResponse.ttl) - expect(auctionAdUnit1.bids[0].ttr).to.equal(bidResponse.timeToRespond) - - expect(auctionAdUnit2.auctionId).to.equal(auctionId) - expect(auctionAdUnit2.bids).to.be.an('array') - expect(auctionAdUnit2.bids).to.have.length(2) - - // no bid - expect(auctionAdUnit2.bids[0].bidId).to.equal(bidId2) - expect(auctionAdUnit2.bids[0].bst).to.equal('noBid') - expect(auctionAdUnit2.bids[0].bidder).to.equal('rubicon') - expect(auctionAdUnit2.bids[0].s).to.be.a('number') - expect(auctionAdUnit2.bids[0].e).to.be.a('number') - expect(auctionAdUnit2.bids[0].params).to.have.keys('placementId') - - // timeout - expect(auctionAdUnit2.bids[1].bidId).to.equal(bidId3) - expect(auctionAdUnit2.bids[1].bst).to.equal('bidTimedOut') - expect(auctionAdUnit2.bids[1].bidder).to.equal('ix') - expect(auctionAdUnit2.bids[1].s).to.be.a('number') - expect(auctionAdUnit2.bids[1].e).to.be.a('undefined') - }) - - it('should push events to a queue and process them once server configuration returns', () => { - ooloAnalytics.enableAnalytics({ - provider: 'oolo', - options: { - pid: 123 - } - }) - - events.emit(constants.EVENTS.AUCTION_INIT, auctionInit); - events.emit(constants.EVENTS.BID_REQUESTED, bidRequested); - events.emit(constants.EVENTS.BID_RESPONSE, bidResponse); - - // configuration returned in an arbitrary moment - server.requests[0].respond(500) - - events.emit(constants.EVENTS.NO_BID, noBid); - events.emit(constants.EVENTS.BID_TIMEOUT, bidTimeout); - events.emit(constants.EVENTS.AUCTION_END, auctionEnd); - - clock.tick(1500) - - const request = JSON.parse(server.requests[3].requestBody); - - expect(request).to.include({ - eventType: 'auction', - pid: 123, - auctionId, - auctionStart, - auctionEnd: 0, - timeout, - }) - expect(request.pvid).to.be.a('number') - expect(request.adUnits).to.have.length(2) - - const auctionAdUnit1 = request.adUnits.filter(adUnit => adUnit.adunid === adUnit1)[0] - const auctionAdUnit2 = request.adUnits.filter(adUnit => adUnit.adunid === adUnit2)[0] - - expect(auctionAdUnit1.auctionId).to.equal(auctionId) - expect(auctionAdUnit1.bids).to.be.an('array') - expect(auctionAdUnit1.bids).to.have.length(1) - - // bid response - expect(auctionAdUnit1.bids[0].bidId).to.equal(bidId1) - expect(auctionAdUnit1.bids[0].bst).to.equal('bidReceived') - expect(auctionAdUnit1.bids[0].bidder).to.equal('appnexus') - expect(auctionAdUnit1.bids[0].cpm).to.equal(0.112256) - expect(auctionAdUnit1.bids[0].cur).to.equal('USD') - expect(auctionAdUnit1.bids[0].s).to.equal(bidRequested.start) - expect(auctionAdUnit1.bids[0].e).to.equal(bidResponse.responseTimestamp) - expect(auctionAdUnit1.bids[0].rs).to.equal(bidRequested.start - auctionStart) - expect(auctionAdUnit1.bids[0].re).to.equal(bidResponse.responseTimestamp - auctionStart) - expect(auctionAdUnit1.bids[0].h).to.equal(0) - expect(auctionAdUnit1.bids[0].w).to.equal(0) - expect(auctionAdUnit1.bids[0].mt).to.equal('banner') - expect(auctionAdUnit1.bids[0].nrv).to.equal(true) - expect(auctionAdUnit1.bids[0].params).to.have.keys('placementId') - expect(auctionAdUnit1.bids[0].size).to.equal('0x0') - expect(auctionAdUnit1.bids[0].crId).to.equal('123456') - expect(auctionAdUnit1.bids[0].ttl).to.equal(bidResponse.ttl) - expect(auctionAdUnit1.bids[0].ttr).to.equal(bidResponse.timeToRespond) - - expect(auctionAdUnit2.auctionId).to.equal(auctionId) - expect(auctionAdUnit2.bids).to.be.an('array') - expect(auctionAdUnit2.bids).to.have.length(2) - - // no bid - expect(auctionAdUnit2.bids[0].bidId).to.equal(bidId2) - expect(auctionAdUnit2.bids[0].bst).to.equal('noBid') - expect(auctionAdUnit2.bids[0].bidder).to.equal('rubicon') - expect(auctionAdUnit2.bids[0].s).to.be.a('number') - expect(auctionAdUnit2.bids[0].e).to.be.a('number') - expect(auctionAdUnit2.bids[0].params).to.have.keys('placementId') - - // timeout - expect(auctionAdUnit2.bids[1].bidId).to.equal(bidId3) - expect(auctionAdUnit2.bids[1].bst).to.equal('bidTimedOut') - expect(auctionAdUnit2.bids[1].bidder).to.equal('ix') - expect(auctionAdUnit2.bids[1].s).to.be.a('number') - expect(auctionAdUnit2.bids[1].e).to.be.a('undefined') - }) - - it('should send "auction" event without all the fields that were set to undefined', () => { - ooloAnalytics.enableAnalytics({ - provider: 'oolo', - options: { - pid: 123 - } - }) - - server.requests[0].respond(500) - - simulateAuction() - clock.tick(1500) - - const request = JSON.parse(server.requests[3].requestBody); - - const auctionAdUnit1 = request.adUnits.filter(adUnit => adUnit.adunid === adUnit1)[0] - const auctionAdUnit2 = request.adUnits.filter(adUnit => adUnit.adunid === adUnit2)[0] - - expect(auctionAdUnit1.code).to.equal(undefined) - expect(auctionAdUnit1.transactionId).to.equal(undefined) - expect(auctionAdUnit1.adUnitCode).to.equal(undefined) - expect(auctionAdUnit1.bids[0].auctionStart).to.equal(undefined) - expect(auctionAdUnit1.bids[0].bids).to.equal(undefined) - expect(auctionAdUnit1.bids[0].refererInfo).to.equal(undefined) - expect(auctionAdUnit1.bids[0].bidRequestsCount).to.equal(undefined) - expect(auctionAdUnit1.bids[0].bidderRequestId).to.equal(undefined) - expect(auctionAdUnit1.bids[0].bidderRequestsCount).to.equal(undefined) - expect(auctionAdUnit1.bids[0].bidderWinsCount).to.equal(undefined) - expect(auctionAdUnit1.bids[0].schain).to.equal(undefined) - expect(auctionAdUnit1.bids[0].src).to.equal(undefined) - expect(auctionAdUnit1.bids[0].transactionId).to.equal(undefined) - - // no bid - expect(auctionAdUnit2.bids[0].schain).to.equal(undefined) - expect(auctionAdUnit2.bids[0].src).to.equal(undefined) - expect(auctionAdUnit2.bids[0].transactionId).to.equal(undefined) - }) - - it('should mark bid winner and send to the server along with the auction data', () => { - ooloAnalytics.enableAnalytics({ - provider: 'oolo', - options: { - pid: 123 - } - }) - - server.requests[0].respond(500) - simulateAuction() - events.emit(constants.EVENTS.BID_WON, bidWon); - clock.tick(1500) - - // no bidWon - expect(server.requests).to.have.length(4) - - const request = JSON.parse(server.requests[3].requestBody); - expect(request.adUnits[0].bids[0].isW).to.equal(true) - }) - - it('should take BID_WON_TIMEOUT from server config if exists', () => { - ooloAnalytics.enableAnalytics({ - provider: 'oolo', - options: { - pid: 123 - } - }) - - server.requests[0].respond(200, {}, JSON.stringify({ - 'events': {}, - 'BID_WON_TIMEOUT': 500 - })) - - simulateAuction() - events.emit(constants.EVENTS.BID_WON, bidWon); - clock.tick(499) - - // no auction data - expect(server.requests).to.have.length(3) - - clock.tick(1) - - // auction data - expect(server.requests).to.have.length(4) - const request = JSON.parse(server.requests[3].requestBody); - expect(request.adUnits[0].bids[0].isW).to.equal(true) - }) - - it('should send a "bidWon" event to the server', () => { - ooloAnalytics.enableAnalytics({ - provider: 'oolo', - options: { - pid: 123 - } - }) - - server.requests[0].respond(500) - simulateAuction() - clock.tick(1500) - events.emit(constants.EVENTS.BID_WON, bidWon); - - expect(server.requests).to.have.length(5) - - const request = JSON.parse(server.requests[4].requestBody); - - expect(request.eventType).to.equal('bidWon') - expect(request.auctionId).to.equal(auctionId) - expect(request.adunid).to.equal(adUnit1) - expect(request.bid.bst).to.equal('bidWon') - expect(request.bid.cur).to.equal('USD') - expect(request.bid.cpm).to.equal(0.5) - }) - - it('should sent adRenderFailed to the server', () => { - ooloAnalytics.enableAnalytics({ - provider: 'oolo', - options: { - pid: 123 - } - }) - - server.requests[0].respond(500) - simulateAuction() - clock.tick(1500) - events.emit(constants.EVENTS.AD_RENDER_FAILED, { bidId: 'abcdef', reason: 'exception' }); - - expect(server.requests).to.have.length(5) - - const request = JSON.parse(server.requests[4].requestBody); - - expect(request.eventType).to.equal('adRenderFailed') - expect(request.pvid).to.equal(PAGEVIEW_ID) - expect(request.bidId).to.equal('abcdef') - expect(request.reason).to.equal('exception') - }) - - it('should pick fields according to server configuration', () => { - ooloAnalytics.enableAnalytics({ - provider: 'oolo', - options: { - pid: 123 - } - }) - - server.requests[0].respond(200, {}, JSON.stringify({ - 'events': { - 'bidRequested': { - 'sendRaw': 0, - 'pickFields': ['transactionId'] - }, - 'noBid': { - 'sendRaw': 0, - 'pickFields': ['src'] - }, - 'bidResponse': { - 'sendRaw': 0, - 'pickFields': ['adUrl', 'statusMessage'] - }, - 'auctionEnd': { - 'sendRaw': 0, - 'pickFields': ['winningBids'] - }, - } - })) - - events.emit(constants.EVENTS.AUCTION_INIT, { ...auctionInit }); - events.emit(constants.EVENTS.BID_REQUESTED, { ...bidRequested, bids: bidRequested.bids.map(b => { b.transactionId = '123'; return b }) }); - events.emit(constants.EVENTS.NO_BID, { ...noBid, src: 'client' }); - events.emit(constants.EVENTS.BID_RESPONSE, { ...bidResponse, adUrl: '...' }); - events.emit(constants.EVENTS.AUCTION_END, { ...auctionEnd, winningBids: [] }); - events.emit(constants.EVENTS.BID_WON, { ...bidWon, statusMessage: 'msg2' }); - - clock.tick(1500) - - const request = JSON.parse(server.requests[3].requestBody) - - expect(request.adUnits[0].bids[0].transactionId).to.equal('123') - expect(request.adUnits[0].bids[0].adUrl).to.equal('...') - expect(request.adUnits[0].bids[0].statusMessage).to.equal('msg2') - expect(request.adUnits[1].bids[0].src).to.equal('client') - }) - - it('should omit fields according to server configuration', () => { - ooloAnalytics.enableAnalytics({ - provider: 'oolo', - options: { - pid: 123 - } - }) - clock.next() - - server.requests[0].respond(200, {}, JSON.stringify({ - 'events': { - 'auctionInit': { - 'sendRaw': 0, - 'omitFields': ['custom_1'] - }, - 'bidResponse': { - 'sendRaw': 0, - 'omitFields': ['custom_2', 'custom_4', 'custom_5'] - } - } - })) - - events.emit(constants.EVENTS.AUCTION_INIT, { ...auctionInit, custom_1: true }); - events.emit(constants.EVENTS.BID_REQUESTED, { ...bidRequested, bids: bidRequested.bids.map(b => { b.custom_2 = true; return b }) }); - events.emit(constants.EVENTS.NO_BID, { ...noBid, custom_3: true }); - events.emit(constants.EVENTS.BID_RESPONSE, { ...bidResponse, custom_4: true }); - events.emit(constants.EVENTS.AUCTION_END, { ...auctionEnd }); - events.emit(constants.EVENTS.BID_WON, { ...bidWon, custom_5: true }); - - clock.tick(1500) - - const request = JSON.parse(server.requests[3].requestBody) - - expect(request.custom_1).to.equal(undefined) - expect(request.custom_6).to.equal(undefined) - expect(request.adUnits[0].bids[0].custom_2).to.equal(undefined) - expect(request.adUnits[0].bids[0].custom_4).to.equal(undefined) - expect(request.adUnits[0].bids[0].custom_5).to.equal(undefined) - expect(request.adUnits[0].bids[0].custom_7).to.equal(undefined) - }) - - it('should omit fields from raw data according to server configuration', () => { - ooloAnalytics.enableAnalytics({ - provider: 'oolo', - options: { - pid: 123 - } - }) - clock.next() - - server.requests[0].respond(200, {}, JSON.stringify({ - 'events': { - 'auctionInit': { - 'sendRaw': 1, - 'omitRawFields': ['custom_1'] - }, - } - })) - - events.emit(constants.EVENTS.AUCTION_INIT, { ...auctionInit, custom_1: true }); - - clock.tick(1500) - - const request = JSON.parse(server.requests[3].requestBody) - - expect(request.eventType).to.equal('auctionInit') - expect(request.custom_1).to.equal(undefined) - }) - - it('should send raw data to custom endpoint if exists in server configuration', () => { - ooloAnalytics.enableAnalytics({ - provider: 'oolo', - options: { - pid: 123 - } - }) - clock.next() - - server.requests[0].respond(200, {}, JSON.stringify({ - 'events': { - 'auctionInit': { - 'sendRaw': 1, - 'endpoint': 'https://pbjs.com' - }, - } - })) - - events.emit(constants.EVENTS.AUCTION_INIT, { ...auctionInit }); - - expect(server.requests[3].url).to.equal('https://pbjs.com') - }) - - it('should send raw events based on server configuration', () => { - ooloAnalytics.enableAnalytics({ - provider: 'oolo', - options: { - pid: 123 - } - }) - clock.next() - - server.requests[0].respond(200, {}, JSON.stringify({ - 'events': { - 'auctionInit': { - 'sendRaw': 0, - }, - 'bidRequested': { - 'sendRaw': 1, - } - } - })) - - events.emit(constants.EVENTS.AUCTION_INIT, auctionInit) - events.emit(constants.EVENTS.BID_REQUESTED, bidRequested); - - const request = JSON.parse(server.requests[3].requestBody) - - expect(request).to.deep.equal({ - eventType: 'bidRequested', - pid: 123, - pvid: PAGEVIEW_ID, - pbModuleVersion: '1.0.0', - ...bidRequested - }) - }) - - it('should queue events and raw events until server configuration resolves', () => { - ooloAnalytics.enableAnalytics({ - provider: 'oolo', - options: { - pid: 123 - } - }) - - simulateAuction() - clock.tick(1500) - - expect(server.requests).to.have.length(3) - - server.requests[0].respond(200, {}, JSON.stringify({ - 'events': { - 'auctionInit': { - 'sendRaw': 1, - }, - 'bidRequested': { - 'sendRaw': 1, - } - } - })) - - expect(server.requests).to.have.length(5) - expect(JSON.parse(server.requests[3].requestBody).eventType).to.equal('auctionInit') - expect(JSON.parse(server.requests[4].requestBody).eventType).to.equal('bidRequested') - }) - }); - - describe('buildAuctionData', () => { - let auction = { - auctionId, - auctionStart, - auctionEnd, - adUnitCodes: ['mid_1'], - auctionStatus: 'running', - bidderRequests: [], - bidsReceived: [], - noBids: [], - winningBids: [], - timestamp: 1234567, - config: {}, - adUnits: { - mid_1: { - adUnitCode: 'mid_1', - code: 'mid_1', - transactionId: '123dsafasdf', - bids: { - [bidId1]: { - adUnitCode: 'mid_1', - cpm: 0.5 - } - } - } - } - } - - it('should turn adUnits and bids objects into arrays', () => { - const auctionData = buildAuctionData(auction, []) - - expect(auctionData.adUnits).to.be.an('array') - expect(auctionData.adUnits[0].bids).to.be.an('array') - }) - - it('should remove fields from the auction', () => { - const auctionData = buildAuctionData(auction, []) - const auctionFields = Object.keys(auctionData) - const adUnitFields = Object.keys(auctionData.adUnits[0]) - - expect(auctionFields).not.to.contain('adUnitCodes') - expect(auctionFields).not.to.contain('auctionStatus') - expect(auctionFields).not.to.contain('bidderRequests') - expect(auctionFields).not.to.contain('bidsReceived') - expect(auctionFields).not.to.contain('noBids') - expect(auctionFields).not.to.contain('winningBids') - expect(auctionFields).not.to.contain('timestamp') - expect(auctionFields).not.to.contain('config') - - expect(adUnitFields).not.to.contain('adUnitCoe') - expect(adUnitFields).not.to.contain('code') - expect(adUnitFields).not.to.contain('transactionId') - }) - }) - - describe('generatePageViewId', () => { - it('should generate a 19 digits number', () => { - expect(generatePageViewId()).length(19) - }) - }) -}); diff --git a/test/spec/modules/open8BidAdapter_spec.js b/test/spec/modules/open8BidAdapter_spec.js deleted file mode 100644 index 506742bef9e..00000000000 --- a/test/spec/modules/open8BidAdapter_spec.js +++ /dev/null @@ -1,251 +0,0 @@ -import { spec } from 'modules/open8BidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -const ENDPOINT = 'https://as.vt.open8.com/v1/control/prebid'; - -describe('Open8Adapter', function() { - const adapter = newBidder(spec); - - describe('isBidRequestValid', function() { - let bid = { - 'bidder': 'open8', - 'params': { - 'slotKey': 'slotkey1234' - }, - 'adUnitCode': 'adunit', - 'sizes': [[300, 250]], - 'bidId': 'bidid1234', - 'bidderRequestId': 'requestid1234', - 'auctionId': 'auctionid1234', - }; - - it('should return true when required params found', function() { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function() { - bid.params = { - ' slotKey': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function() { - let bidRequests = [ - { - 'bidder': 'open8', - 'params': { - 'slotKey': 'slotkey1234' - }, - 'adUnitCode': 'adunit', - 'sizes': [[300, 250]], - 'bidId': 'bidid1234', - 'bidderRequestId': 'requestid1234', - 'auctionId': 'auctionid1234', - } - ]; - - it('sends bid request to ENDPOINT via GET', function() { - const requests = spec.buildRequests(bidRequests); - expect(requests[0].url).to.equal(ENDPOINT); - expect(requests[0].method).to.equal('GET'); - }); - }); - describe('interpretResponse', function() { - const bannerResponse = { - slotKey: 'slotkey1234', - userId: 'userid1234', - impId: 'impid1234', - media: 'TEST_MEDIA', - nurl: 'https://example/win', - isAdReturn: true, - syncPixels: ['https://example/sync/pixel.gif'], - syncIFs: [], - ad: { - bidId: 'TEST_BID_ID', - price: 1234.56, - creativeId: 'creativeid1234', - dealId: 'TEST_DEAL_ID', - currency: 'JPY', - ds: 876, - spd: 1234, - fa: 5678, - pr: 'pr1234', - mr: 'mr1234', - nurl: 'https://example/win', - adType: 2, - banner: { - w: 300, - h: 250, - adm: '
', - imps: ['https://example.com/imp'] - } - } - }; - const videoResponse = { - slotKey: 'slotkey1234', - userId: 'userid1234', - impId: 'impid1234', - media: 'TEST_MEDIA', - isAdReturn: true, - syncPixels: ['https://example/sync/pixel.gif'], - syncIFs: [], - ad: { - bidId: 'TEST_BID_ID', - price: 1234.56, - creativeId: 'creativeid1234', - dealId: 'TEST_DEAL_ID', - currency: 'JPY', - ds: 876, - spd: 1234, - fa: 5678, - pr: 'pr1234', - mr: 'mr1234', - nurl: 'https://example/win', - adType: 1, - video: { - purl: 'https://playerexample.js', - vastXml: '', - w: 320, - h: 180 - }, - } - }; - - it('should get correct banner bid response', function() { - let expectedResponse = [{ - 'slotKey': 'slotkey1234', - 'userId': 'userid1234', - 'impId': 'impid1234', - 'media': 'TEST_MEDIA', - 'ds': 876, - 'spd': 1234, - 'fa': 5678, - 'pr': 'pr1234', - 'mr': 'mr1234', - 'nurl': 'https://example/win', - 'requestId': 'requestid1234', - 'cpm': 1234.56, - 'creativeId': 'creativeid1234', - 'dealId': 'TEST_DEAL_ID', - 'width': 300, - 'height': 250, - 'ad': "
", - 'mediaType': 'banner', - 'currency': 'JPY', - 'ttl': 360, - 'netRevenue': true - }]; - - let bidderRequest; - let result = spec.interpretResponse({ body: bannerResponse }, { bidderRequest }); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('handles video responses', function() { - let expectedResponse = [{ - 'slotKey': 'slotkey1234', - 'userId': 'userid1234', - 'impId': 'impid1234', - 'media': 'TEST_MEDIA', - 'ds': 876, - 'spd': 1234, - 'fa': 5678, - 'pr': 'pr1234', - 'mr': 'mr1234', - 'nurl': 'https://example/win', - 'requestId': 'requestid1234', - 'cpm': 1234.56, - 'creativeId': 'creativeid1234', - 'dealId': 'TEST_DEAL_ID', - 'width': 320, - 'height': 180, - 'vastXml': '', - 'mediaType': 'video', - 'renderer': {}, - 'adResponse': {}, - 'currency': 'JPY', - 'ttl': 360, - 'netRevenue': true - }]; - - let bidderRequest; - let result = spec.interpretResponse({ body: videoResponse }, { bidderRequest }); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('handles nobid responses', function() { - let response = { - isAdReturn: false, - 'ad': {} - }; - - let bidderRequest; - let result = spec.interpretResponse({ body: response }, { bidderRequest }); - expect(result.length).to.equal(0); - }); - }); - - describe('getUserSyncs', function() { - const imgResponse1 = { - body: { - 'isAdReturn': true, - 'ad': { /* ad body */ }, - 'syncPixels': [ - 'https://example.test/1' - ] - } - }; - - const imgResponse2 = { - body: { - 'isAdReturn': true, - 'ad': { /* ad body */ }, - 'syncPixels': [ - 'https://example.test/2' - ] - } - }; - - const ifResponse = { - body: { - 'isAdReturn': true, - 'ad': { /* ad body */ }, - 'syncIFs': [ - 'https://example.test/3' - ] - } - }; - - it('should use a sync img url from first response', function() { - const syncs = spec.getUserSyncs({ pixelEnabled: true }, [imgResponse1, imgResponse2, ifResponse]); - expect(syncs).to.deep.equal([ - { - type: 'image', - url: 'https://example.test/1' - } - ]); - }); - - it('handle ifs response', function() { - const syncs = spec.getUserSyncs({ iframeEnabled: true }, [ifResponse]); - expect(syncs).to.deep.equal([ - { - type: 'iframe', - url: 'https://example.test/3' - } - ]); - }); - - it('handle empty response (e.g. timeout)', function() { - const syncs = spec.getUserSyncs({ pixelEnabled: true }, []); - expect(syncs).to.deep.equal([]); - }); - - it('returns empty syncs when not enabled', function() { - const syncs = spec.getUserSyncs({ pixelEnabled: false }, [imgResponse1]); - expect(syncs).to.deep.equal([]); - }); - }); -}); diff --git a/test/spec/modules/openxAnalyticsAdapter_spec.js b/test/spec/modules/openxAnalyticsAdapter_spec.js deleted file mode 100644 index b946efe922d..00000000000 --- a/test/spec/modules/openxAnalyticsAdapter_spec.js +++ /dev/null @@ -1,640 +0,0 @@ -import { expect } from 'chai'; -import openxAdapter, {AUCTION_STATES} from 'modules/openxAnalyticsAdapter.js'; -import events from 'src/events.js'; -import CONSTANTS from 'src/constants.json'; -import * as utils from 'src/utils.js'; -import { server } from 'test/mocks/xhr.js'; -import find from 'core-js-pure/features/array/find.js'; - -const { - EVENTS: { AUCTION_INIT, BID_REQUESTED, BID_RESPONSE, BID_TIMEOUT, BID_WON, AUCTION_END } -} = CONSTANTS; -const SLOT_LOADED = 'slotOnload'; -const CURRENT_TIME = 1586000000000; - -describe('openx analytics adapter', function() { - describe('when validating the configuration', function () { - let spy; - beforeEach(function () { - spy = sinon.spy(utils, 'logError'); - }); - - afterEach(function() { - utils.logError.restore(); - }); - - it('should require organization id when no configuration is passed', function() { - openxAdapter.enableAnalytics(); - expect(spy.firstCall.args[0]).to.match(/publisherPlatformId/); - expect(spy.firstCall.args[0]).to.match(/to exist/); - }); - - it('should require publisher id when no orgId is passed', function() { - openxAdapter.enableAnalytics({ - provider: 'openx', - options: { - publisherAccountId: 12345 - } - }); - expect(spy.firstCall.args[0]).to.match(/publisherPlatformId/); - expect(spy.firstCall.args[0]).to.match(/to exist/); - }); - - it('should validate types', function() { - openxAdapter.enableAnalytics({ - provider: 'openx', - options: { - orgId: 'test platformId', - sampling: 'invalid-float' - } - }); - - expect(spy.firstCall.args[0]).to.match(/sampling/); - expect(spy.firstCall.args[0]).to.match(/type 'number'/); - }); - }); - - describe('when tracking analytic events', function () { - const AD_UNIT_CODE = 'test-div-1'; - const SLOT_LOAD_WAIT_TIME = 10; - - const DEFAULT_V2_ANALYTICS_CONFIG = { - orgId: 'test-org-id', - publisherAccountId: 123, - publisherPlatformId: 'test-platform-id', - sample: 1.0, - enableV2: true, - payloadWaitTime: SLOT_LOAD_WAIT_TIME, - payloadWaitTimePadding: SLOT_LOAD_WAIT_TIME - }; - - const auctionInit = { - auctionId: 'test-auction-id', - timestamp: CURRENT_TIME, - timeout: 3000, - adUnitCodes: [AD_UNIT_CODE], - }; - - const bidRequestedOpenX = { - auctionId: 'test-auction-id', - auctionStart: CURRENT_TIME, - timeout: 2000, - bids: [ - { - adUnitCode: AD_UNIT_CODE, - bidId: 'test-openx-request-id', - bidder: 'openx', - params: { unit: 'test-openx-ad-unit-id' }, - userId: { - tdid: 'test-tradedesk-id', - empty_id: '', - null_id: null, - bla_id: '', - digitrustid: { data: { id: '1' } }, - lipbid: { lipb: '2' } - } - } - ], - start: CURRENT_TIME + 10 - }; - - const bidRequestedCloseX = { - auctionId: 'test-auction-id', - auctionStart: CURRENT_TIME, - timeout: 1000, - bids: [ - { - adUnitCode: AD_UNIT_CODE, - bidId: 'test-closex-request-id', - bidder: 'closex', - params: { unit: 'test-closex-ad-unit-id' }, - userId: { - bla_id: '2', - tdid: 'test-tradedesk-id' - } - } - ], - start: CURRENT_TIME + 20 - }; - - const bidResponseOpenX = { - adUnitCode: AD_UNIT_CODE, - cpm: 0.5, - netRevenue: true, - requestId: 'test-openx-request-id', - mediaType: 'banner', - width: 300, - height: 250, - adId: 'test-openx-ad-id', - auctionId: 'test-auction-id', - creativeId: 'openx-crid', - currency: 'USD', - timeToRespond: 100, - responseTimestamp: CURRENT_TIME + 30, - ts: 'test-openx-ts' - }; - - const bidResponseCloseX = { - adUnitCode: AD_UNIT_CODE, - cpm: 0.3, - netRevenue: true, - requestId: 'test-closex-request-id', - mediaType: 'video', - width: 300, - height: 250, - adId: 'test-closex-ad-id', - auctionId: 'test-auction-id', - creativeId: 'closex-crid', - currency: 'USD', - timeToRespond: 200, - dealId: 'test-closex-deal-id', - responseTimestamp: CURRENT_TIME + 40, - ts: 'test-closex-ts' - }; - - const bidTimeoutOpenX = { - 0: { - adUnitCode: AD_UNIT_CODE, - auctionId: 'test-auction-id', - bidId: 'test-openx-request-id' - }}; - - const bidTimeoutCloseX = { - 0: { - adUnitCode: AD_UNIT_CODE, - auctionId: 'test-auction-id', - bidId: 'test-closex-request-id' - } - }; - - const bidWonOpenX = { - requestId: 'test-openx-request-id', - adId: 'test-openx-ad-id', - adUnitCode: AD_UNIT_CODE, - auctionId: 'test-auction-id' - }; - - const auctionEnd = { - auctionId: 'test-auction-id', - timestamp: CURRENT_TIME, - auctionEnd: CURRENT_TIME + 100, - timeout: 3000, - adUnitCodes: [AD_UNIT_CODE], - }; - - const bidWonCloseX = { - requestId: 'test-closex-request-id', - adId: 'test-closex-ad-id', - adUnitCode: AD_UNIT_CODE, - auctionId: 'test-auction-id' - }; - - function simulateAuction(events) { - let highestBid; - - events.forEach(event => { - const [eventType, args] = event; - if (eventType === BID_RESPONSE) { - highestBid = highestBid || args; - if (highestBid.cpm < args.cpm) { - highestBid = args; - } - } - - if (eventType === SLOT_LOADED) { - const slotLoaded = { - slot: { - getAdUnitPath: () => { - return '/12345678/test_ad_unit'; - }, - getSlotElementId: () => { - return AD_UNIT_CODE; - }, - getTargeting: (key) => { - if (key === 'hb_adid') { - return highestBid ? [highestBid.adId] : []; - } else { - return []; - } - } - } - }; - openxAdapter.track({ eventType, args: slotLoaded }); - } else { - openxAdapter.track({ eventType, args }); - } - }); - } - - let clock; - - beforeEach(function() { - sinon.stub(events, 'getEvents').returns([]); - clock = sinon.useFakeTimers(CURRENT_TIME); - }); - - afterEach(function() { - events.getEvents.restore(); - clock.restore(); - }); - - describe('when there is an auction', function () { - let auction; - let auction2; - beforeEach(function () { - openxAdapter.enableAnalytics({options: DEFAULT_V2_ANALYTICS_CONFIG}); - - simulateAuction([ - [AUCTION_INIT, auctionInit], - [SLOT_LOADED] - ]); - - simulateAuction([ - [AUCTION_INIT, {...auctionInit, auctionId: 'second-auction-id'}], - [SLOT_LOADED] - ]); - - clock.tick(SLOT_LOAD_WAIT_TIME); - auction = JSON.parse(server.requests[0].requestBody)[0]; - auction2 = JSON.parse(server.requests[1].requestBody)[0]; - }); - - afterEach(function () { - openxAdapter.reset(); - openxAdapter.disableAnalytics(); - }); - - it('should track auction start time', function () { - expect(auction.startTime).to.equal(auctionInit.timestamp); - }); - - it('should track auction time limit', function () { - expect(auction.timeLimit).to.equal(auctionInit.timeout); - }); - - it('should track the \'default\' test code', function () { - expect(auction.testCode).to.equal('default'); - }); - - it('should track auction count', function () { - expect(auction.auctionOrder).to.equal(1); - expect(auction2.auctionOrder).to.equal(2); - }); - - it('should track the orgId', function () { - expect(auction.orgId).to.equal(DEFAULT_V2_ANALYTICS_CONFIG.orgId); - }); - - it('should track the orgId', function () { - expect(auction.publisherPlatformId).to.equal(DEFAULT_V2_ANALYTICS_CONFIG.publisherPlatformId); - }); - - it('should track the orgId', function () { - expect(auction.publisherAccountId).to.equal(DEFAULT_V2_ANALYTICS_CONFIG.publisherAccountId); - }); - }); - - describe('when there is a custom test code', function () { - let auction; - beforeEach(function () { - openxAdapter.enableAnalytics({ - options: { - ...DEFAULT_V2_ANALYTICS_CONFIG, - testCode: 'test-code' - } - }); - - simulateAuction([ - [AUCTION_INIT, auctionInit], - [SLOT_LOADED], - ]); - clock.tick(SLOT_LOAD_WAIT_TIME); - auction = JSON.parse(server.requests[0].requestBody)[0]; - }); - - afterEach(function () { - openxAdapter.reset(); - openxAdapter.disableAnalytics(); - }); - - it('should track the custom test code', function () { - expect(auction.testCode).to.equal('test-code'); - }); - }); - - describe('when there is campaign (utm) data', function () { - let auction; - beforeEach(function () { - - }); - - afterEach(function () { - openxAdapter.reset(); - utils.getWindowLocation.restore(); - openxAdapter.disableAnalytics(); - }); - - it('should track values from query params when they exist', function () { - sinon.stub(utils, 'getWindowLocation').returns({search: '?' + - 'utm_campaign=test%20campaign-name&' + - 'utm_source=test-source&' + - 'utm_medium=test-medium&' - }); - - openxAdapter.enableAnalytics({options: DEFAULT_V2_ANALYTICS_CONFIG}); - - simulateAuction([ - [AUCTION_INIT, auctionInit], - [SLOT_LOADED], - ]); - clock.tick(SLOT_LOAD_WAIT_TIME); - auction = JSON.parse(server.requests[0].requestBody)[0]; - - // ensure that value are URI decoded - expect(auction.campaign.name).to.equal('test campaign-name'); - expect(auction.campaign.source).to.equal('test-source'); - expect(auction.campaign.medium).to.equal('test-medium'); - expect(auction.campaign.content).to.be.undefined; - expect(auction.campaign.term).to.be.undefined; - }); - - it('should override query params if configuration parameters exist', function () { - sinon.stub(utils, 'getWindowLocation').returns({search: '?' + - 'utm_campaign=test-campaign-name&' + - 'utm_source=test-source&' + - 'utm_medium=test-medium&' + - 'utm_content=test-content&' + - 'utm_term=test-term' - }); - - openxAdapter.enableAnalytics({ - options: { - ...DEFAULT_V2_ANALYTICS_CONFIG, - campaign: { - name: 'test-config-name', - source: 'test-config-source', - medium: 'test-config-medium' - } - } - }); - - simulateAuction([ - [AUCTION_INIT, auctionInit], - [SLOT_LOADED], - ]); - clock.tick(SLOT_LOAD_WAIT_TIME); - auction = JSON.parse(server.requests[0].requestBody)[0]; - - expect(auction.campaign.name).to.equal('test-config-name'); - expect(auction.campaign.source).to.equal('test-config-source'); - expect(auction.campaign.medium).to.equal('test-config-medium'); - expect(auction.campaign.content).to.equal('test-content'); - expect(auction.campaign.term).to.equal('test-term'); - }); - }); - - describe('when there are bid requests', function () { - let auction; - let openxBidder; - let closexBidder; - - beforeEach(function () { - openxAdapter.enableAnalytics({options: DEFAULT_V2_ANALYTICS_CONFIG}); - - simulateAuction([ - [AUCTION_INIT, auctionInit], - [BID_REQUESTED, bidRequestedCloseX], - [BID_REQUESTED, bidRequestedOpenX], - [SLOT_LOADED], - ]); - clock.tick(SLOT_LOAD_WAIT_TIME * 2); - auction = JSON.parse(server.requests[0].requestBody)[0]; - openxBidder = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'openx'); - closexBidder = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'closex'); - }); - - afterEach(function () { - openxAdapter.reset(); - openxAdapter.disableAnalytics(); - }); - - it('should track the bidder', function () { - expect(openxBidder.bidder).to.equal('openx'); - expect(closexBidder.bidder).to.equal('closex'); - }); - - it('should track the adunit code', function () { - expect(auction.adUnits[0].code).to.equal(AD_UNIT_CODE); - }); - - it('should track the user ids', function () { - expect(auction.userIdProviders).to.deep.equal(['bla_id', 'digitrustid', 'lipbid', 'tdid']); - }); - - it('should not have responded', function () { - expect(openxBidder.hasBidderResponded).to.equal(false); - expect(closexBidder.hasBidderResponded).to.equal(false); - }); - }); - - describe('when there are request timeouts', function () { - let auction; - let openxBidRequest; - let closexBidRequest; - - beforeEach(function () { - openxAdapter.enableAnalytics({options: DEFAULT_V2_ANALYTICS_CONFIG}); - - simulateAuction([ - [AUCTION_INIT, auctionInit], - [BID_REQUESTED, bidRequestedCloseX], - [BID_REQUESTED, bidRequestedOpenX], - [BID_TIMEOUT, bidTimeoutCloseX], - [BID_TIMEOUT, bidTimeoutOpenX], - [AUCTION_END, auctionEnd] - ]); - clock.tick(SLOT_LOAD_WAIT_TIME * 2); - auction = JSON.parse(server.requests[0].requestBody)[0]; - - openxBidRequest = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'openx'); - closexBidRequest = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'closex'); - }); - - afterEach(function () { - openxAdapter.reset(); - openxAdapter.disableAnalytics(); - }); - - it('should track the timeout', function () { - expect(openxBidRequest.timedOut).to.equal(true); - expect(closexBidRequest.timedOut).to.equal(true); - }); - - it('should track the timeout value ie timeLimit', function () { - expect(openxBidRequest.timeLimit).to.equal(2000); - expect(closexBidRequest.timeLimit).to.equal(1000); - }); - }); - - describe('when there are bid responses', function () { - let auction; - let openxBidResponse; - let closexBidResponse; - - beforeEach(function () { - openxAdapter.enableAnalytics({options: DEFAULT_V2_ANALYTICS_CONFIG}); - - simulateAuction([ - [AUCTION_INIT, auctionInit], - [BID_REQUESTED, bidRequestedCloseX], - [BID_REQUESTED, bidRequestedOpenX], - [BID_RESPONSE, bidResponseOpenX], - [BID_RESPONSE, bidResponseCloseX], - [AUCTION_END, auctionEnd] - ]); - - clock.tick(SLOT_LOAD_WAIT_TIME * 2); - auction = JSON.parse(server.requests[0].requestBody)[0]; - - openxBidResponse = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'openx').bidResponses[0]; - closexBidResponse = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'closex').bidResponses[0]; - }); - - afterEach(function () { - openxAdapter.reset(); - openxAdapter.disableAnalytics(); - }); - - it('should track the cpm in microCPM', function () { - expect(openxBidResponse.microCpm).to.equal(bidResponseOpenX.cpm * 1000000); - expect(closexBidResponse.microCpm).to.equal(bidResponseCloseX.cpm * 1000000); - }); - - it('should track if the bid is in net revenue', function () { - expect(openxBidResponse.netRevenue).to.equal(bidResponseOpenX.netRevenue); - expect(closexBidResponse.netRevenue).to.equal(bidResponseCloseX.netRevenue); - }); - - it('should track the mediaType', function () { - expect(openxBidResponse.mediaType).to.equal(bidResponseOpenX.mediaType); - expect(closexBidResponse.mediaType).to.equal(bidResponseCloseX.mediaType); - }); - - it('should track the currency', function () { - expect(openxBidResponse.currency).to.equal(bidResponseOpenX.currency); - expect(closexBidResponse.currency).to.equal(bidResponseCloseX.currency); - }); - - it('should track the ad width and height', function () { - expect(openxBidResponse.width).to.equal(bidResponseOpenX.width); - expect(openxBidResponse.height).to.equal(bidResponseOpenX.height); - - expect(closexBidResponse.width).to.equal(bidResponseCloseX.width); - expect(closexBidResponse.height).to.equal(bidResponseCloseX.height); - }); - - it('should track the bid dealId', function () { - expect(openxBidResponse.dealId).to.equal(bidResponseOpenX.dealId); // no deal id defined - expect(closexBidResponse.dealId).to.equal(bidResponseCloseX.dealId); // deal id defined - }); - - it('should track the bid\'s latency', function () { - expect(openxBidResponse.latency).to.equal(bidResponseOpenX.timeToRespond); - expect(closexBidResponse.latency).to.equal(bidResponseCloseX.timeToRespond); - }); - - it('should not have any bid winners', function () { - expect(openxBidResponse.winner).to.equal(false); - expect(closexBidResponse.winner).to.equal(false); - }); - - it('should track the bid currency', function () { - expect(openxBidResponse.currency).to.equal(bidResponseOpenX.currency); - expect(closexBidResponse.currency).to.equal(bidResponseCloseX.currency); - }); - - it('should track the auction end time', function () { - expect(auction.endTime).to.equal(auctionEnd.auctionEnd); - }); - - it('should track that the auction ended', function () { - expect(auction.state).to.equal(AUCTION_STATES.ENDED); - }); - }); - - describe('when there are bidder wins', function () { - let auction; - beforeEach(function () { - openxAdapter.enableAnalytics({options: DEFAULT_V2_ANALYTICS_CONFIG}); - - simulateAuction([ - [AUCTION_INIT, auctionInit], - [BID_REQUESTED, bidRequestedOpenX], - [BID_REQUESTED, bidRequestedCloseX], - [BID_RESPONSE, bidResponseOpenX], - [BID_RESPONSE, bidResponseCloseX], - [AUCTION_END, auctionEnd], - [BID_WON, bidWonOpenX] - ]); - - clock.tick(SLOT_LOAD_WAIT_TIME * 2); - auction = JSON.parse(server.requests[0].requestBody)[0]; - }); - - afterEach(function () { - openxAdapter.reset(); - openxAdapter.disableAnalytics(); - }); - - it('should track that bidder as the winner', function () { - let openxBidder = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'openx'); - expect(openxBidder.bidResponses[0]).to.contain({winner: true}); - }); - - it('should track that bidder as the losers', function () { - let closexBidder = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'closex'); - expect(closexBidder.bidResponses[0]).to.contain({winner: false}); - }); - }); - - describe('when a winning bid renders', function () { - let auction; - beforeEach(function () { - openxAdapter.enableAnalytics({options: DEFAULT_V2_ANALYTICS_CONFIG}); - - simulateAuction([ - [AUCTION_INIT, auctionInit], - [BID_REQUESTED, bidRequestedOpenX], - [BID_REQUESTED, bidRequestedCloseX], - [BID_RESPONSE, bidResponseOpenX], - [BID_RESPONSE, bidResponseCloseX], - [AUCTION_END, auctionEnd], - [BID_WON, bidWonOpenX], - [SLOT_LOADED] - ]); - - clock.tick(SLOT_LOAD_WAIT_TIME * 2); - auction = JSON.parse(server.requests[0].requestBody)[0]; - }); - - afterEach(function () { - openxAdapter.reset(); - openxAdapter.disableAnalytics(); - }); - - it('should track that winning bid rendered', function () { - let openxBidder = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'openx'); - expect(openxBidder.bidResponses[0]).to.contain({rendered: true}); - }); - - it('should track that winning bid render time', function () { - let openxBidder = find(auction.adUnits[0].bidRequests, bidderRequest => bidderRequest.bidder === 'openx'); - expect(openxBidder.bidResponses[0]).to.contain({renderTime: CURRENT_TIME}); - }); - - it('should track that the auction completed', function () { - expect(auction.state).to.equal(AUCTION_STATES.COMPLETED); - }); - }); - }); -}); diff --git a/test/spec/modules/openxBidAdapter_spec.js b/test/spec/modules/openxBidAdapter_spec.js deleted file mode 100644 index 7391c8826bc..00000000000 --- a/test/spec/modules/openxBidAdapter_spec.js +++ /dev/null @@ -1,2090 +0,0 @@ -import {expect} from 'chai'; -import {spec, USER_ID_CODE_TO_QUERY_ARG} from 'modules/openxBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from 'src/mediaTypes.js'; -import {userSync} from 'src/userSync.js'; -import {config} from 'src/config.js'; -import * as utils from 'src/utils.js'; - -const URLBASE = '/w/1.0/arj'; -const URLBASEVIDEO = '/v/1.0/avjp'; - -describe('OpenxAdapter', function () { - const adapter = newBidder(spec); - - /** - * Type Definitions - */ - - /** - * @typedef {{ - * impression: string, - * inview: string, - * click: string - * }} - */ - let OxArjTracking; - /** - * @typedef {{ - * ads: { - * version: number, - * count: number, - * pixels: string, - * ad: Array - * } - * }} - */ - let OxArjResponse; - /** - * @typedef {{ - * adunitid: number, - * adid:number, - * type: string, - * htmlz: string, - * framed: number, - * is_fallback: number, - * ts: string, - * cpipc: number, - * pub_rev: string, - * tbd: ?string, - * adv_id: string, - * deal_id: string, - * auct_win_is_deal: number, - * brand_id: string, - * currency: string, - * idx: string, - * creative: Array - * }} - */ - let OxArjAdUnit; - /** - * @typedef {{ - * id: string, - * width: string, - * height: string, - * target: string, - * mime: string, - * media: string, - * tracking: OxArjTracking - * }} - */ - let OxArjCreative; - - // HELPER METHODS - /** - * @type {OxArjCreative} - */ - const DEFAULT_TEST_ARJ_CREATIVE = { - id: '0', - width: 'test-width', - height: 'test-height', - target: 'test-target', - mime: 'test-mime', - media: 'test-media', - tracking: { - impression: 'test-impression', - inview: 'test-inview', - click: 'test-click' - } - }; - - /** - * @type {OxArjAdUnit} - */ - const DEFAULT_TEST_ARJ_AD_UNIT = { - adunitid: 0, - type: 'test-type', - html: 'test-html', - framed: 0, - is_fallback: 0, - ts: 'test-ts', - tbd: 'NaN', - deal_id: undefined, - auct_win_is_deal: undefined, - cpipc: 0, - pub_rev: 'test-pub_rev', - adv_id: 'test-adv_id', - brand_id: 'test-brand_id', - currency: 'test-currency', - idx: '0', - creative: [DEFAULT_TEST_ARJ_CREATIVE] - }; - - /** - * @type {OxArjResponse} - */ - const DEFAULT_ARJ_RESPONSE = { - ads: { - version: 0, - count: 1, - pixels: 'https://testpixels.net', - ad: [DEFAULT_TEST_ARJ_AD_UNIT] - } - }; - - describe('inherited functions', function () { - it('exists and is a function', function () { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - describe('when request is for a banner ad', function () { - let bannerBid; - beforeEach(function () { - bannerBid = { - bidder: 'openx', - params: {}, - adUnitCode: 'adunit-code', - mediaTypes: {banner: {}}, - sizes: [[300, 250], [300, 600]], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475' - }; - }); - - it('should return false when there is no delivery domain', function () { - 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'} - }); - - it('should return false when there is no ad unit id and size', function () { - expect(spec.isBidRequestValid(bannerBid)).to.equal(false); - }); - - it('should return true if there is an adunit id ', function () { - bannerBid.params.unit = '12345678'; - expect(spec.isBidRequestValid(bannerBid)).to.equal(true); - }); - - it('should return true if there is no adunit id and sizes are defined', function () { - bannerBid.mediaTypes.banner.sizes = [720, 90]; - expect(spec.isBidRequestValid(bannerBid)).to.equal(true); - }); - - it('should return false if no sizes are defined ', function () { - expect(spec.isBidRequestValid(bannerBid)).to.equal(false); - }); - - it('should return false if sizes empty ', function () { - bannerBid.mediaTypes.banner.sizes = []; - expect(spec.isBidRequestValid(bannerBid)).to.equal(false); - }); - }); - }); - - describe('when request is for a multiformat ad', function () { - describe('and request config uses mediaTypes video and banner', () => { - const multiformatBid = { - bidder: 'openx', - params: { - unit: '12345678', - delDomain: 'test-del-domain' - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [[300, 250]] - }, - video: { - playerSize: [300, 250] - } - }, - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - transactionId: '4008d88a-8137-410b-aa35-fbfdabcb478e' - }; - it('should return true multisize when required params found', function () { - expect(spec.isBidRequestValid(multiformatBid)).to.equal(true); - }); - }); - }); - - describe('when request is for a video ad', function () { - describe('and request config uses mediaTypes', () => { - const videoBidWithMediaTypes = { - bidder: 'openx', - params: { - unit: '12345678', - delDomain: 'test-del-domain' - }, - adUnitCode: 'adunit-code', - mediaTypes: { - video: { - playerSize: [640, 480] - } - }, - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - transactionId: '4008d88a-8137-410b-aa35-fbfdabcb478e' - }; - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(videoBidWithMediaTypes)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let videoBidWithMediaTypes = Object.assign({}, videoBidWithMediaTypes); - videoBidWithMediaTypes.params = {}; - expect(spec.isBidRequestValid(videoBidWithMediaTypes)).to.equal(false); - }); - }); - describe('and request config uses both delDomain and platform', () => { - const videoBidWithDelDomainAndPlatform = { - bidder: 'openx', - params: { - unit: '12345678', - delDomain: 'test-del-domain', - platform: '1cabba9e-cafe-3665-beef-f00f00f00f00' - }, - adUnitCode: 'adunit-code', - mediaTypes: { - video: { - playerSize: [640, 480] - } - }, - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - transactionId: '4008d88a-8137-410b-aa35-fbfdabcb478e' - }; - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(videoBidWithDelDomainAndPlatform)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let videoBidWithMediaTypes = Object.assign({}, videoBidWithDelDomainAndPlatform); - videoBidWithMediaTypes.params = {}; - expect(spec.isBidRequestValid(videoBidWithMediaTypes)).to.equal(false); - }); - }); - describe('and request config uses mediaType', () => { - const videoBidWithMediaType = { - 'bidder': 'openx', - 'params': { - 'unit': '12345678', - 'delDomain': 'test-del-domain' - }, - 'adUnitCode': 'adunit-code', - 'mediaType': 'video', - 'sizes': [640, 480], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'transactionId': '4008d88a-8137-410b-aa35-fbfdabcb478e' - }; - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(videoBidWithMediaType)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let videoBidWithMediaType = Object.assign({}, videoBidWithMediaType); - delete videoBidWithMediaType.params; - videoBidWithMediaType.params = {}; - expect(spec.isBidRequestValid(videoBidWithMediaType)).to.equal(false); - }); - }); - - describe('and request config uses test', () => { - const videoBidWithTest = { - bidder: 'openx', - params: { - unit: '12345678', - delDomain: 'test-del-domain', - test: true - }, - adUnitCode: 'adunit-code', - mediaTypes: { - video: { - playerSize: [640, 480] - } - }, - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - transactionId: '4008d88a-8137-410b-aa35-fbfdabcb478e' - }; - - let mockBidderRequest = {refererInfo: {}}; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(videoBidWithTest)).to.equal(true); - }); - - it('should send video bid request to openx url via GET, with vtest=1 video parameter', function () { - const request = spec.buildRequests([videoBidWithTest], mockBidderRequest); - expect(request[0].data.vtest).to.equal(1); - }); - }); - }); - }); - - describe('buildRequests for banner ads', function () { - const bidRequestsWithMediaTypes = [{ - 'bidder': 'openx', - 'params': { - 'unit': '11', - 'delDomain': 'test-del-domain' - }, - 'adUnitCode': '/adunit-code/test-path', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - 'bidId': 'test-bid-id-1', - 'bidderRequestId': 'test-bid-request-1', - 'auctionId': 'test-auction-1' - }, { - 'bidder': 'openx', - 'params': { - 'unit': '22', - 'delDomain': 'test-del-domain' - }, - 'adUnitCode': 'adunit-code', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - }, - 'bidId': 'test-bid-id-2', - 'bidderRequestId': 'test-bid-request-2', - 'auctionId': 'test-auction-2' - }]; - - const bidRequestsWithPlatform = [{ - 'bidder': 'openx', - 'params': { - 'unit': '11', - 'platform': '1cabba9e-cafe-3665-beef-f00f00f00f00' - }, - 'adUnitCode': '/adunit-code/test-path', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - 'bidId': 'test-bid-id-1', - 'bidderRequestId': 'test-bid-request-1', - 'auctionId': 'test-auction-1' - }, { - 'bidder': 'openx', - 'params': { - 'unit': '11', - 'platform': '1cabba9e-cafe-3665-beef-f00f00f00f00' - }, - 'adUnitCode': '/adunit-code/test-path', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - 'bidId': 'test-bid-id-1', - 'bidderRequestId': 'test-bid-request-1', - 'auctionId': 'test-auction-1' - }]; - - const mockBidderRequest = {refererInfo: {}}; - - it('should send bid request to openx url via GET, with mediaTypes specified with banner type', function () { - const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest); - expect(request[0].url).to.equal('https://' + bidRequestsWithMediaTypes[0].params.delDomain + URLBASE); - expect(request[0].data.ph).to.be.undefined; - expect(request[0].method).to.equal('GET'); - }); - - it('should send bid request to openx platform url via GET, if platform is present', function () { - const request = spec.buildRequests(bidRequestsWithPlatform, mockBidderRequest); - expect(request[0].url).to.equal(`https://u.openx.net${URLBASE}`); - expect(request[0].data.ph).to.equal(bidRequestsWithPlatform[0].params.platform); - expect(request[0].method).to.equal('GET'); - }); - - it('should send bid request to openx platform url via GET, if both params present', function () { - const bidRequestsWithPlatformAndDelDomain = [{ - 'bidder': 'openx', - 'params': { - 'unit': '11', - 'delDomain': 'test-del-domain', - 'platform': '1cabba9e-cafe-3665-beef-f00f00f00f00' - }, - 'adUnitCode': '/adunit-code/test-path', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - 'bidId': 'test-bid-id-1', - 'bidderRequestId': 'test-bid-request-1', - 'auctionId': 'test-auction-1' - }, { - 'bidder': 'openx', - 'params': { - 'unit': '11', - 'delDomain': 'test-del-domain', - 'platform': '1cabba9e-cafe-3665-beef-f00f00f00f00' - }, - 'adUnitCode': '/adunit-code/test-path', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - 'bidId': 'test-bid-id-1', - 'bidderRequestId': 'test-bid-request-1', - 'auctionId': 'test-auction-1' - }]; - - const request = spec.buildRequests(bidRequestsWithPlatformAndDelDomain, mockBidderRequest); - expect(request[0].url).to.equal(`https://u.openx.net${URLBASE}`); - expect(request[0].data.ph).to.equal(bidRequestsWithPlatform[0].params.platform); - expect(request[0].method).to.equal('GET'); - }); - - it('should send the adunit codes', function () { - const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest); - expect(request[0].data.divIds).to.equal(`${encodeURIComponent(bidRequestsWithMediaTypes[0].adUnitCode)},${encodeURIComponent(bidRequestsWithMediaTypes[1].adUnitCode)}`); - }); - - it('should send ad unit ids when any are defined', function () { - const bidRequestsWithUnitIds = [{ - 'bidder': 'openx', - 'params': { - 'delDomain': 'test-del-domain' - }, - 'adUnitCode': 'adunit-code', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - 'bidId': 'test-bid-id-1', - 'bidderRequestId': 'test-bid-request-1', - 'auctionId': 'test-auction-1' - }, { - 'bidder': 'openx', - 'params': { - 'unit': '22', - 'delDomain': 'test-del-domain' - }, - 'adUnitCode': 'adunit-code', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - }, - 'bidId': 'test-bid-id-2', - 'bidderRequestId': 'test-bid-request-2', - 'auctionId': 'test-auction-2' - }]; - const request = spec.buildRequests(bidRequestsWithUnitIds, mockBidderRequest); - expect(request[0].data.auid).to.equal(`,${bidRequestsWithUnitIds[1].params.unit}`); - }); - - it('should not send any ad unit ids when none are defined', function () { - const bidRequestsWithoutUnitIds = [{ - 'bidder': 'openx', - 'params': { - 'delDomain': 'test-del-domain' - }, - 'adUnitCode': 'adunit-code', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - 'bidId': 'test-bid-id-1', - 'bidderRequestId': 'test-bid-request-1', - 'auctionId': 'test-auction-1' - }, { - 'bidder': 'openx', - 'params': { - 'delDomain': 'test-del-domain' - }, - 'adUnitCode': 'adunit-code', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - }, - 'bidId': 'test-bid-id-2', - 'bidderRequestId': 'test-bid-request-2', - 'auctionId': 'test-auction-2' - }]; - const request = spec.buildRequests(bidRequestsWithoutUnitIds, mockBidderRequest); - expect(request[0].data).to.not.have.any.keys('auid'); - }); - - it('should send out custom params on bids that have customParams specified', function () { - const bidRequest = Object.assign({}, - bidRequestsWithMediaTypes[0], - { - params: { - 'unit': '12345678', - 'delDomain': 'test-del-domain', - 'customParams': {'Test1': 'testval1+', 'test2': ['testval2/', 'testval3']} - } - } - ); - - const request = spec.buildRequests([bidRequest], mockBidderRequest); - const dataParams = request[0].data; - - expect(dataParams.tps).to.exist; - expect(dataParams.tps).to.equal(btoa('test1=testval1.&test2=testval2_,testval3')); - }); - - it('should send out custom bc parameter, if override is present', function () { - const bidRequest = Object.assign({}, - bidRequestsWithMediaTypes[0], - { - params: { - 'unit': '12345678', - 'delDomain': 'test-del-domain', - 'bc': 'hb_override' - } - } - ); - - const request = spec.buildRequests([bidRequest], mockBidderRequest); - const dataParams = request[0].data; - - expect(dataParams.bc).to.exist; - expect(dataParams.bc).to.equal('hb_override'); - }); - - it('should not send any consent management properties', function () { - const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest); - expect(request[0].data.gdpr).to.equal(undefined); - expect(request[0].data.gdpr_consent).to.equal(undefined); - expect(request[0].data.x_gdpr_f).to.equal(undefined); - }); - - describe('when there is a consent management framework', function () { - let bidRequests; - let mockConfig; - let bidderRequest; - const IAB_CONSENT_FRAMEWORK_CODE = 1; - - beforeEach(function () { - bidRequests = [{ - bidder: 'openx', - params: { - unit: '12345678-banner', - delDomain: 'test-del-domain' - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - bidId: 'test-bid-id', - bidderRequestId: 'test-bidder-request-id', - auctionId: 'test-auction-id' - }, { - 'bidder': 'openx', - 'mediaTypes': { - video: { - playerSize: [640, 480] - } - }, - 'params': { - 'unit': '12345678-video', - 'delDomain': 'test-del-domain' - }, - 'adUnitCode': 'adunit-code', - - bidId: 'test-bid-id', - bidderRequestId: 'test-bidder-request-id', - auctionId: 'test-auction-id', - transactionId: '4008d88a-8137-410b-aa35-fbfdabcb478e' - }]; - }); - - afterEach(function () { - config.getConfig.restore(); - }); - - describe('when us_privacy applies', function () { - beforeEach(function () { - bidderRequest = { - uspConsent: '1YYN', - refererInfo: {} - }; - - sinon.stub(config, 'getConfig').callsFake((key) => { - return utils.deepAccess(mockConfig, key); - }); - }); - - it('should send a signal to specify that GDPR applies to this request', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request[0].data.us_privacy).to.equal('1YYN'); - expect(request[1].data.us_privacy).to.equal('1YYN'); - }); - }); - - describe('when us_privacy does not applies', function () { - beforeEach(function () { - bidderRequest = { - refererInfo: {} - }; - - sinon.stub(config, 'getConfig').callsFake((key) => { - return utils.deepAccess(mockConfig, key); - }); - }); - - it('should not send the consent string, when consent string is undefined', function () { - delete bidderRequest.uspConsent; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request[0].data).to.not.have.property('us_privacy'); - expect(request[1].data).to.not.have.property('us_privacy'); - }); - }); - - describe('when GDPR applies', function () { - beforeEach(function () { - bidderRequest = { - gdprConsent: { - consentString: 'test-gdpr-consent-string', - gdprApplies: true - }, - refererInfo: {} - }; - - mockConfig = { - consentManagement: { - cmpApi: 'iab', - timeout: 1111, - allowAuctionWithoutConsent: 'cancel' - } - }; - - sinon.stub(config, 'getConfig').callsFake((key) => { - return utils.deepAccess(mockConfig, key); - }); - }); - - it('should send a signal to specify that GDPR applies to this request', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request[0].data.gdpr).to.equal(1); - expect(request[1].data.gdpr).to.equal(1); - }); - - it('should send the consent string', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request[0].data.gdpr_consent).to.equal(bidderRequest.gdprConsent.consentString); - expect(request[1].data.gdpr_consent).to.equal(bidderRequest.gdprConsent.consentString); - }); - - it('should send the consent management framework code', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request[0].data.x_gdpr_f).to.equal(IAB_CONSENT_FRAMEWORK_CODE); - expect(request[1].data.x_gdpr_f).to.equal(IAB_CONSENT_FRAMEWORK_CODE); - }); - }); - - describe('when GDPR does not apply', function () { - beforeEach(function () { - bidderRequest = { - gdprConsent: { - consentString: 'test-gdpr-consent-string', - gdprApplies: false - }, - refererInfo: {} - }; - - mockConfig = { - consentManagement: { - cmpApi: 'iab', - timeout: 1111, - allowAuctionWithoutConsent: 'cancel' - } - }; - - sinon.stub(config, 'getConfig').callsFake((key) => { - return utils.deepAccess(mockConfig, key); - }); - }); - - it('should not send a signal to specify that GDPR does not apply to this request', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request[0].data.gdpr).to.equal(0); - expect(request[1].data.gdpr).to.equal(0); - }); - - it('should send the consent string', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request[0].data.gdpr_consent).to.equal(bidderRequest.gdprConsent.consentString); - expect(request[1].data.gdpr_consent).to.equal(bidderRequest.gdprConsent.consentString); - }); - - it('should send the consent management framework code', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request[0].data.x_gdpr_f).to.equal(IAB_CONSENT_FRAMEWORK_CODE); - expect(request[1].data.x_gdpr_f).to.equal(IAB_CONSENT_FRAMEWORK_CODE); - }); - }); - - describe('when GDPR consent has undefined data', function () { - beforeEach(function () { - bidderRequest = { - gdprConsent: { - consentString: 'test-gdpr-consent-string', - gdprApplies: true - }, - refererInfo: {} - }; - - mockConfig = { - consentManagement: { - cmpApi: 'iab', - timeout: 1111, - allowAuctionWithoutConsent: 'cancel' - } - }; - - sinon.stub(config, 'getConfig').callsFake((key) => { - return utils.deepAccess(mockConfig, key); - }); - }); - - it('should not send a signal to specify whether GDPR applies to this request, when GDPR application is undefined', function () { - delete bidderRequest.gdprConsent.gdprApplies; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request[0].data).to.not.have.property('gdpr'); - expect(request[1].data).to.not.have.property('gdpr'); - }); - - it('should not send the consent string, when consent string is undefined', function () { - delete bidderRequest.gdprConsent.consentString; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request[0].data).to.not.have.property('gdpr_consent'); - expect(request[1].data).to.not.have.property('gdpr_consent'); - }); - - it('should not send the consent management framework code, when format is undefined', function () { - delete mockConfig.consentManagement.cmpApi; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request[0].data).to.not.have.property('x_gdpr_f'); - expect(request[1].data).to.not.have.property('x_gdpr_f'); - }); - }); - }); - - it('should not send a coppa query param when there are no coppa param settings in the bid requests', function () { - const bidRequestsWithoutCoppa = [{ - bidder: 'openx', - params: { - unit: '11', - delDomain: 'test-del-domain', - coppa: false - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - bidId: 'test-bid-id-1', - bidderRequestId: 'test-bid-request-1', - auctionId: 'test-auction-1' - }, { - bidder: 'openx', - params: { - unit: '22', - delDomain: 'test-del-domain' - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - }, - bidId: 'test-bid-id-2', - bidderRequestId: 'test-bid-request-2', - auctionId: 'test-auction-2' - }]; - const request = spec.buildRequests(bidRequestsWithoutCoppa, mockBidderRequest); - expect(request[0].data).to.not.have.any.keys('tfcd'); - }); - - it('should send a coppa flag there is when there is coppa param settings in the bid requests', function () { - const bidRequestsWithCoppa = [{ - bidder: 'openx', - params: { - unit: '11', - delDomain: 'test-del-domain', - coppa: false - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - bidId: 'test-bid-id-1', - bidderRequestId: 'test-bid-request-1', - auctionId: 'test-auction-1' - }, { - bidder: 'openx', - params: { - unit: '22', - delDomain: 'test-del-domain', - coppa: true - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - }, - bidId: 'test-bid-id-2', - bidderRequestId: 'test-bid-request-2', - auctionId: 'test-auction-2' - }]; - const request = spec.buildRequests(bidRequestsWithCoppa, mockBidderRequest); - expect(request[0].data.tfcd).to.equal(1); - }); - - it('should not send a "no segmentation" flag there no DoNotTrack setting that is set to true', function () { - const bidRequestsWithoutDnt = [{ - bidder: 'openx', - params: { - unit: '11', - delDomain: 'test-del-domain', - doNotTrack: false - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - bidId: 'test-bid-id-1', - bidderRequestId: 'test-bid-request-1', - auctionId: 'test-auction-1' - }, { - bidder: 'openx', - params: { - unit: '22', - delDomain: 'test-del-domain' - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - }, - bidId: 'test-bid-id-2', - bidderRequestId: 'test-bid-request-2', - auctionId: 'test-auction-2' - }]; - const request = spec.buildRequests(bidRequestsWithoutDnt, mockBidderRequest); - expect(request[0].data).to.not.have.any.keys('ns'); - }); - - it('should send a "no segmentation" flag there is any DoNotTrack setting that is set to true', function () { - const bidRequestsWithDnt = [{ - bidder: 'openx', - params: { - unit: '11', - delDomain: 'test-del-domain', - doNotTrack: false - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - bidId: 'test-bid-id-1', - bidderRequestId: 'test-bid-request-1', - auctionId: 'test-auction-1' - }, { - bidder: 'openx', - params: { - unit: '22', - delDomain: 'test-del-domain', - doNotTrack: true - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - }, - bidId: 'test-bid-id-2', - bidderRequestId: 'test-bid-request-2', - auctionId: 'test-auction-2' - }]; - const request = spec.buildRequests(bidRequestsWithDnt, mockBidderRequest); - expect(request[0].data.ns).to.equal(1); - }); - - describe('when schain is provided', function () { - let bidRequests; - let schainConfig; - const supplyChainNodePropertyOrder = ['asi', 'sid', 'hp', 'rid', 'name', 'domain']; - - beforeEach(function () { - schainConfig = { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'exchange1.com', - 'sid': '1234', - 'hp': 1, - 'rid': 'bid-request-1', - 'name': 'publisher', - 'domain': 'publisher.com' - // omitted ext - }, - { - 'asi': 'exchange2.com', - 'sid': 'abcd', - 'hp': 1, - 'rid': 'bid-request-2', - // name field missing - 'domain': 'intermediary.com' - }, - { - 'asi': 'exchange3.com', - 'sid': '4321', - 'hp': 1, - // request id - // name field missing - 'domain': 'intermediary-2.com' - } - ] - }; - - bidRequests = [{ - 'bidder': 'openx', - 'params': { - 'unit': '11', - 'delDomain': 'test-del-domain' - }, - 'adUnitCode': '/adunit-code/test-path', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - 'bidId': 'test-bid-id-1', - 'bidderRequestId': 'test-bid-request-1', - 'auctionId': 'test-auction-1', - 'schain': schainConfig - }]; - }); - - it('should send a schain parameter with the proper delimiter symbols', function () { - const request = spec.buildRequests(bidRequests, mockBidderRequest); - const dataParams = request[0].data; - const numNodes = schainConfig.nodes.length; - - // each node will have a ! to denote beginning of a new node - expect(dataParams.schain.match(/!/g).length).to.equal(numNodes); - - // 1 comma in the front for version - // 5 commas per node - expect(dataParams.schain.match(/,/g).length).to.equal(numNodes * 5 + 1); - }); - - it('should send a schain with the right version', function () { - const request = spec.buildRequests(bidRequests, mockBidderRequest); - const dataParams = request[0].data; - let serializedSupplyChain = dataParams.schain.split('!'); - let version = serializedSupplyChain.shift().split(',')[0]; - - expect(version).to.equal(bidRequests[0].schain.ver); - }); - - it('should send a schain with the right complete value', function () { - const request = spec.buildRequests(bidRequests, mockBidderRequest); - const dataParams = request[0].data; - let serializedSupplyChain = dataParams.schain.split('!'); - let isComplete = serializedSupplyChain.shift().split(',')[1]; - - expect(isComplete).to.equal(String(bidRequests[0].schain.complete)); - }); - - it('should send all available params in the right order', function () { - const request = spec.buildRequests(bidRequests, mockBidderRequest); - const dataParams = request[0].data; - let serializedSupplyChain = dataParams.schain.split('!'); - serializedSupplyChain.shift(); - - serializedSupplyChain.forEach((serializedNode, nodeIndex) => { - let nodeProperties = serializedNode.split(','); - - nodeProperties.forEach((nodeProperty, propertyIndex) => { - let node = schainConfig.nodes[nodeIndex]; - let key = supplyChainNodePropertyOrder[propertyIndex]; - - expect(nodeProperty).to.equal(node[key] ? String(node[key]) : '', - `expected node '${nodeIndex}' property '${nodeProperty}' to key '${key}' to be the same value`) - }); - }); - }); - }); - - describe('when there are userid providers', function () { - const EXAMPLE_DATA_BY_ATTR = { - britepoolid: '1111-britepoolid', - criteoId: '1111-criteoId', - fabrickId: '1111-fabrickid', - haloId: '1111-haloid', - id5id: {uid: '1111-id5id'}, - idl_env: '1111-idl_env', - IDP: '1111-zeotap-idplusid', - idxId: '1111-idxid', - intentIqId: '1111-intentiqid', - lipb: {lipbid: '1111-lipb'}, - lotamePanoramaId: '1111-lotameid', - merkleId: '1111-merkleid', - netId: 'fH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg', - parrableId: { eid: 'eidVersion.encryptionKeyReference.encryptedValue' }, - pubcid: '1111-pubcid', - quantcastId: '1111-quantcastid', - sharedId: '1111-sharedid', - tapadId: '111-tapadid', - tdid: '1111-tdid', - verizonMediaId: '1111-verizonmediaid', - }; - - // generates the same set of tests for each id provider - utils._each(USER_ID_CODE_TO_QUERY_ARG, (userIdQueryArg, userIdProviderKey) => { - describe(`with userId attribute: ${userIdProviderKey}`, function () { - it(`should not send a ${userIdQueryArg} query param when there is no userId.${userIdProviderKey} defined in the bid requests`, function () { - const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest); - expect(request[0].data).to.not.have.any.keys(userIdQueryArg); - }); - - it(`should send a ${userIdQueryArg} query param when userId.${userIdProviderKey} is defined in the bid requests`, function () { - const bidRequestsWithUserId = [{ - bidder: 'openx', - params: { - unit: '11', - delDomain: 'test-del-domain' - }, - userId: { - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - bidId: 'test-bid-id-1', - bidderRequestId: 'test-bid-request-1', - auctionId: 'test-auction-1' - }]; - // enrich bid request with userId key/value - bidRequestsWithUserId[0].userId[userIdProviderKey] = EXAMPLE_DATA_BY_ATTR[userIdProviderKey]; - - const request = spec.buildRequests(bidRequestsWithUserId, mockBidderRequest); - - let userIdValue; - // handle cases where userId key refers to an object - switch (userIdProviderKey) { - case 'lipb': - userIdValue = EXAMPLE_DATA_BY_ATTR.lipb.lipbid; - break; - case 'parrableId': - userIdValue = EXAMPLE_DATA_BY_ATTR.parrableId.eid; - break; - case 'id5id': - userIdValue = EXAMPLE_DATA_BY_ATTR.id5id.uid; - break; - default: - userIdValue = EXAMPLE_DATA_BY_ATTR[userIdProviderKey]; - } - - expect(request[0].data[USER_ID_CODE_TO_QUERY_ARG[userIdProviderKey]]).to.equal(userIdValue); - }); - }); - }); - }); - - describe('floors', function () { - it('should send out custom floors on bids that have customFloors specified', function () { - const bidRequest = Object.assign({}, - bidRequestsWithMediaTypes[0], - { - params: { - 'unit': '12345678', - 'delDomain': 'test-del-domain', - 'customFloor': 1.500001 - } - } - ); - - const request = spec.buildRequests([bidRequest], mockBidderRequest); - const dataParams = request[0].data; - - expect(dataParams.aumfs).to.exist; - expect(dataParams.aumfs).to.equal('1500'); - }); - - context('with floors module', function () { - let adServerCurrencyStub; - - beforeEach(function () { - adServerCurrencyStub = sinon - .stub(config, 'getConfig') - .withArgs('currency.adServerCurrency') - }); - - afterEach(function () { - config.getConfig.restore(); - }); - - it('should send out floors on bids', function () { - const bidRequest1 = Object.assign({}, - bidRequestsWithMediaTypes[0], - { - getFloor: () => { - return { - currency: 'AUS', - floor: 9.99 - } - } - } - ); - - const bidRequest2 = Object.assign({}, - bidRequestsWithMediaTypes[1], - { - getFloor: () => { - return { - currency: 'AUS', - floor: 18.881 - } - } - } - ); - - const request = spec.buildRequests([bidRequest1, bidRequest2], mockBidderRequest); - const dataParams = request[0].data; - - expect(dataParams.aumfs).to.exist; - expect(dataParams.aumfs).to.equal('9990,18881'); - }); - - it('should send out floors on bids in the default currency', function () { - const bidRequest1 = Object.assign({}, - bidRequestsWithMediaTypes[0], - { - getFloor: () => { - return {}; - } - } - ); - - let getFloorSpy = sinon.spy(bidRequest1, 'getFloor'); - - spec.buildRequests([bidRequest1], mockBidderRequest); - expect(getFloorSpy.args[0][0].mediaType).to.equal(BANNER); - expect(getFloorSpy.args[0][0].currency).to.equal('USD'); - }); - - it('should send out floors on bids in the ad server currency if defined', function () { - adServerCurrencyStub.returns('bitcoin'); - - const bidRequest1 = Object.assign({}, - bidRequestsWithMediaTypes[0], - { - getFloor: () => { - return {}; - } - } - ); - - let getFloorSpy = sinon.spy(bidRequest1, 'getFloor'); - - spec.buildRequests([bidRequest1], mockBidderRequest); - expect(getFloorSpy.args[0][0].mediaType).to.equal(BANNER); - expect(getFloorSpy.args[0][0].currency).to.equal('bitcoin'); - }); - }) - }) - }); - - describe('buildRequests for video', function () { - const bidRequestsWithMediaTypes = [{ - 'bidder': 'openx', - 'mediaTypes': { - video: { - playerSize: [640, 480] - } - }, - 'params': { - 'unit': '12345678', - 'delDomain': 'test-del-domain' - }, - 'adUnitCode': 'adunit-code', - - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'transactionId': '4008d88a-8137-410b-aa35-fbfdabcb478e' - }]; - const mockBidderRequest = {refererInfo: {}}; - - it('should send bid request to openx url via GET, with mediaTypes having video parameter', function () { - const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest); - expect(request[0].url).to.equal('https://' + bidRequestsWithMediaTypes[0].params.delDomain + URLBASEVIDEO); - expect(request[0].method).to.equal('GET'); - }); - it('should have the correct parameters', function () { - const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest); - const dataParams = request[0].data; - - expect(dataParams.auid).to.equal('12345678'); - expect(dataParams.vht).to.equal(480); - expect(dataParams.vwd).to.equal(640); - }); - - it('shouldn\'t have the test parameter', function () { - const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest); - expect(request[0].data.vtest).to.be.undefined; - }); - - it('should send a bc parameter', function () { - const request = spec.buildRequests(bidRequestsWithMediaTypes, mockBidderRequest); - const dataParams = request[0].data; - - expect(dataParams.bc).to.have.string('hb_pb'); - }); - - describe('when using the video param', function () { - let videoBidRequest; - let mockBidderRequest = {refererInfo: {}}; - - beforeEach(function () { - videoBidRequest = { - 'bidder': 'openx', - 'mediaTypes': { - video: { - context: 'instream', - playerSize: [640, 480] - } - }, - 'params': { - 'unit': '12345678', - 'delDomain': 'test-del-domain' - }, - 'adUnitCode': 'adunit-code', - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'transactionId': '4008d88a-8137-410b-aa35-fbfdabcb478e' - }; - mockBidderRequest = {refererInfo: {}}; - }); - - it('should not allow you to set a url', function () { - videoBidRequest.params.video = { - url: 'test-url' - }; - const request = spec.buildRequests([videoBidRequest], mockBidderRequest); - - expect(request[0].data.url).to.be.undefined; - }); - - it('should not allow you to override the javascript url', function () { - let myUrl = 'my-url'; - videoBidRequest.params.video = { - ju: myUrl - }; - const request = spec.buildRequests([videoBidRequest], mockBidderRequest); - - expect(request[0].data.ju).to.not.equal(myUrl); - }); - - describe('when using the openRtb param', function () { - it('should covert the param to a JSON string', function () { - let myOpenRTBObject = {}; - videoBidRequest.params.video = { - openrtb: myOpenRTBObject - }; - const request = spec.buildRequests([videoBidRequest], mockBidderRequest); - - expect(request[0].data.openrtb).to.equal(JSON.stringify(myOpenRTBObject)); - }); - - it("should use the bidRequest's playerSize when it is available", function () { - const width = 200; - const height = 100; - const myOpenRTBObject = {v: height, w: width}; - videoBidRequest.params.video = { - openrtb: myOpenRTBObject - }; - const request = spec.buildRequests([videoBidRequest], mockBidderRequest); - const openRtbRequestParams = JSON.parse(request[0].data.openrtb); - - expect(openRtbRequestParams.w).to.not.equal(width); - expect(openRtbRequestParams.v).to.not.equal(height); - }); - - it('should use the the openRTB\'s sizing when the bidRequest\'s playerSize is not available', function () { - const width = 200; - const height = 100; - const myOpenRTBObject = {v: height, w: width}; - videoBidRequest.params.video = { - openrtb: myOpenRTBObject - }; - videoBidRequest.mediaTypes.video.playerSize = undefined; - - const request = spec.buildRequests([videoBidRequest], mockBidderRequest); - const openRtbRequestParams = JSON.parse(request[0].data.openrtb); - - expect(openRtbRequestParams.w).to.equal(width); - expect(openRtbRequestParams.v).to.equal(height); - }); - }); - }); - - describe('floors', function () { - it('should send out custom floors on bids that have customFloors specified', function () { - const bidRequest = Object.assign({}, - bidRequestsWithMediaTypes[0], - { - params: { - 'unit': '12345678', - 'delDomain': 'test-del-domain', - 'customFloor': 1.500001 - } - } - ); - - const request = spec.buildRequests([bidRequest], mockBidderRequest); - const dataParams = request[0].data; - - expect(dataParams.aumfs).to.exist; - expect(dataParams.aumfs).to.equal('1500'); - }); - - context('with floors module', function () { - let adServerCurrencyStub; - function makeBidWithFloorInfo(floorInfo) { - return Object.assign(utils.deepClone(bidRequestsWithMediaTypes[0]), - { - getFloor: () => { - return floorInfo; - } - }); - } - - beforeEach(function () { - adServerCurrencyStub = sinon - .stub(config, 'getConfig') - .withArgs('currency.adServerCurrency') - }); - - afterEach(function () { - config.getConfig.restore(); - }); - - it('should send out floors on bids', function () { - const floors = [9.99, 18.881]; - const bidRequests = floors.map(floor => { - return makeBidWithFloorInfo({ - currency: 'AUS', - floor: floor - }); - }); - const request = spec.buildRequests(bidRequests, mockBidderRequest); - - expect(request[0].data.aumfs).to.exist; - expect(request[0].data.aumfs).to.equal('9990'); - expect(request[1].data.aumfs).to.exist; - expect(request[1].data.aumfs).to.equal('18881'); - }); - - it('should send out floors on bids in the default currency', function () { - const bidRequest1 = makeBidWithFloorInfo({}); - - let getFloorSpy = sinon.spy(bidRequest1, 'getFloor'); - - spec.buildRequests([bidRequest1], mockBidderRequest); - expect(getFloorSpy.args[0][0].mediaType).to.equal(VIDEO); - expect(getFloorSpy.args[0][0].currency).to.equal('USD'); - }); - - it('should send out floors on bids in the ad server currency if defined', function () { - adServerCurrencyStub.returns('bitcoin'); - - const bidRequest1 = makeBidWithFloorInfo({}); - - let getFloorSpy = sinon.spy(bidRequest1, 'getFloor'); - - spec.buildRequests([bidRequest1], mockBidderRequest); - expect(getFloorSpy.args[0][0].mediaType).to.equal(VIDEO); - expect(getFloorSpy.args[0][0].currency).to.equal('bitcoin'); - }); - }) - }) - }); - - describe('buildRequest for multi-format ad', function () { - const multiformatBid = { - bidder: 'openx', - params: { - unit: '12345678', - delDomain: 'test-del-domain' - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [[300, 250]] - }, - video: { - playerSize: [300, 250] - } - }, - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - transactionId: '4008d88a-8137-410b-aa35-fbfdabcb478e' - }; - let mockBidderRequest = {refererInfo: {}}; - - it('should default to a banner request', function () { - const request = spec.buildRequests([multiformatBid], mockBidderRequest); - const dataParams = request[0].data; - - expect(dataParams.divIds).to.have.string(multiformatBid.adUnitCode); - }); - }); - - describe('interpretResponse for banner ads', function () { - beforeEach(function () { - sinon.spy(userSync, 'registerSync'); - }); - - afterEach(function () { - userSync.registerSync.restore(); - }); - - describe('when there is a standard response', function () { - const creativeOverride = { - id: 234, - width: '300', - height: '250', - tracking: { - impression: 'https://openx-d.openx.net/v/1.0/ri?ts=ts' - } - }; - - const adUnitOverride = { - ts: 'test-1234567890-ts', - idx: '0', - currency: 'USD', - pub_rev: '10000', - html: '
OpenX Ad
' - }; - let adUnit; - let bidResponse; - - let bid; - let bidRequest; - let bidRequestConfigs; - - beforeEach(function () { - bidRequestConfigs = [{ - 'bidder': 'openx', - 'params': { - 'unit': '12345678', - 'delDomain': 'test-del-domain' - }, - 'adUnitCode': 'adunit-code', - 'mediaType': 'banner', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }]; - - bidRequest = { - method: 'GET', - url: 'https://openx-d.openx.net/v/1.0/arj', - data: {}, - payload: {'bids': bidRequestConfigs, 'startTime': new Date()} - }; - - adUnit = mockAdUnit(adUnitOverride, creativeOverride); - bidResponse = mockArjResponse(undefined, [adUnit]); - bid = spec.interpretResponse({body: bidResponse}, bidRequest)[0]; - }); - - it('should return a price', function () { - expect(bid.cpm).to.equal(parseInt(adUnitOverride.pub_rev, 10) / 1000); - }); - - it('should return a request id', function () { - expect(bid.requestId).to.equal(bidRequest.payload.bids[0].bidId); - }); - - it('should return width and height for the creative', function () { - expect(bid.width).to.equal(creativeOverride.width); - expect(bid.height).to.equal(creativeOverride.height); - }); - - it('should return a creativeId', function () { - expect(bid.creativeId).to.equal(creativeOverride.id); - }); - - it('should return an ad', function () { - expect(bid.ad).to.equal(adUnitOverride.html); - }); - - it('should have a time-to-live of 5 minutes', function () { - expect(bid.ttl).to.equal(300); - }); - - it('should always return net revenue', function () { - expect(bid.netRevenue).to.equal(true); - }); - - it('should return a currency', function () { - expect(bid.currency).to.equal(adUnitOverride.currency); - }); - - it('should return a transaction state', function () { - expect(bid.ts).to.equal(adUnitOverride.ts); - }); - - it('should return a brand ID', function () { - expect(bid.meta.brandId).to.equal(DEFAULT_TEST_ARJ_AD_UNIT.brand_id); - }); - - it('should return an adomain', function () { - expect(bid.meta.advertiserDomains).to.deep.equal([]); - }); - - it('should return a dsp ID', function () { - expect(bid.meta.dspid).to.equal(DEFAULT_TEST_ARJ_AD_UNIT.adv_id); - }); - }); - - describe('when there is a deal', function () { - const adUnitOverride = { - deal_id: 'ox-1000' - }; - let adUnit; - let bidResponse; - - let bid; - let bidRequestConfigs; - let bidRequest; - - beforeEach(function () { - bidRequestConfigs = [{ - 'bidder': 'openx', - 'params': { - 'unit': '12345678', - 'delDomain': 'test-del-domain' - }, - 'adUnitCode': 'adunit-code', - 'mediaType': 'banner', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }]; - - bidRequest = { - method: 'GET', - url: 'https://openx-d.openx.net/v/1.0/arj', - data: {}, - payload: {'bids': bidRequestConfigs, 'startTime': new Date()} - }; - adUnit = mockAdUnit(adUnitOverride); - bidResponse = mockArjResponse(null, [adUnit]); - bid = spec.interpretResponse({body: bidResponse}, bidRequest)[0]; - mockArjResponse(); - }); - - it('should return a deal id', function () { - expect(bid.dealId).to.equal(adUnitOverride.deal_id); - }); - }); - - describe('when there is no bids in the response', function () { - let bidRequest; - let bidRequestConfigs; - - beforeEach(function () { - bidRequestConfigs = [{ - 'bidder': 'openx', - 'params': { - 'unit': '12345678', - 'delDomain': 'test-del-domain' - }, - 'adUnitCode': 'adunit-code', - 'mediaType': 'banner', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }]; - - bidRequest = { - method: 'GET', - url: 'https://openx-d.openx.net/v/1.0/arj', - data: {}, - payload: {'bids': bidRequestConfigs, 'startTime': new Date()} - }; - }); - - it('handles nobid responses', function () { - const bidResponse = { - 'ads': - { - 'version': 1, - 'count': 1, - 'pixels': 'https://testpixels.net', - 'ad': [] - } - }; - - const result = spec.interpretResponse({body: bidResponse}, bidRequest); - expect(result.length).to.equal(0); - }); - }); - - describe('when adunits return out of order', function () { - const bidRequests = [{ - bidder: 'openx', - params: { - unit: '12345678', - delDomain: 'test-del-domain' - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [[100, 111]] - } - }, - bidId: 'test-bid-request-id-1', - bidderRequestId: 'test-request-1', - auctionId: 'test-auction-id-1' - }, { - bidder: 'openx', - params: { - unit: '12345678', - delDomain: 'test-del-domain' - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [[200, 222]] - } - }, - bidId: 'test-bid-request-id-2', - bidderRequestId: 'test-request-1', - auctionId: 'test-auction-id-1' - }, { - bidder: 'openx', - params: { - unit: '12345678', - delDomain: 'test-del-domain' - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [[300, 333]] - } - }, - 'bidId': 'test-bid-request-id-3', - 'bidderRequestId': 'test-request-1', - 'auctionId': 'test-auction-id-1' - }]; - const bidRequest = { - method: 'GET', - url: 'https://openx-d.openx.net/v/1.0/arj', - data: {}, - payload: {'bids': bidRequests, 'startTime': new Date()} - }; - - let outOfOrderAdunits = [ - mockAdUnit({ - idx: '1' - }, { - width: bidRequests[1].mediaTypes.banner.sizes[0][0], - height: bidRequests[1].mediaTypes.banner.sizes[0][1] - }), - mockAdUnit({ - idx: '2' - }, { - width: bidRequests[2].mediaTypes.banner.sizes[0][0], - height: bidRequests[2].mediaTypes.banner.sizes[0][1] - }), - mockAdUnit({ - idx: '0' - }, { - width: bidRequests[0].mediaTypes.banner.sizes[0][0], - height: bidRequests[0].mediaTypes.banner.sizes[0][1] - }) - ]; - - let bidResponse = mockArjResponse(undefined, outOfOrderAdunits); - - it('should return map adunits back to the proper request', function () { - const bids = spec.interpretResponse({body: bidResponse}, bidRequest); - expect(bids[0].requestId).to.equal(bidRequests[1].bidId); - expect(bids[0].width).to.equal(bidRequests[1].mediaTypes.banner.sizes[0][0]); - expect(bids[0].height).to.equal(bidRequests[1].mediaTypes.banner.sizes[0][1]); - expect(bids[1].requestId).to.equal(bidRequests[2].bidId); - expect(bids[1].width).to.equal(bidRequests[2].mediaTypes.banner.sizes[0][0]); - expect(bids[1].height).to.equal(bidRequests[2].mediaTypes.banner.sizes[0][1]); - expect(bids[2].requestId).to.equal(bidRequests[0].bidId); - expect(bids[2].width).to.equal(bidRequests[0].mediaTypes.banner.sizes[0][0]); - expect(bids[2].height).to.equal(bidRequests[0].mediaTypes.banner.sizes[0][1]); - }); - }); - }); - - describe('interpretResponse for video ads', function () { - beforeEach(function () { - sinon.spy(userSync, 'registerSync'); - }); - - afterEach(function () { - userSync.registerSync.restore(); - }); - - const bidsWithMediaTypes = [{ - 'bidder': 'openx', - 'mediaTypes': {video: {}}, - 'params': { - 'unit': '12345678', - 'delDomain': 'test-del-domain' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [640, 480], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'transactionId': '4008d88a-8137-410b-aa35-fbfdabcb478e' - }]; - const bidsWithMediaType = [{ - 'bidder': 'openx', - 'mediaType': 'video', - 'params': { - 'unit': '12345678', - 'delDomain': 'test-del-domain' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [640, 480], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'transactionId': '4008d88a-8137-410b-aa35-fbfdabcb478e' - }]; - const bidRequestsWithMediaTypes = { - method: 'GET', - url: 'https://openx-d.openx.net/v/1.0/avjp', - data: {}, - payload: {'bid': bidsWithMediaTypes[0], 'startTime': new Date()} - }; - const bidRequestsWithMediaType = { - method: 'GET', - url: 'https://openx-d.openx.net/v/1.0/avjp', - data: {}, - payload: {'bid': bidsWithMediaType[0], 'startTime': new Date()} - }; - const bidResponse = { - 'pub_rev': '1000', - 'width': '640', - 'height': '480', - 'adid': '5678', - 'currency': 'AUD', - 'vastUrl': 'https://testvast.com', - 'pixels': 'https://testpixels.net' - }; - - it('should return correct bid response with MediaTypes', function () { - const expectedResponse = { - 'requestId': '30b31c1838de1e', - 'cpm': 1, - 'width': 640, - 'height': 480, - 'mediaType': 'video', - 'creativeId': '5678', - 'vastUrl': 'https://testvast.com', - 'ttl': 300, - 'netRevenue': true, - 'currency': 'AUD' - }; - - const result = spec.interpretResponse({body: bidResponse}, bidRequestsWithMediaTypes); - expect(result[0]).to.eql(expectedResponse); - }); - - it('should return correct bid response with MediaType', function () { - const expectedResponse = [ - { - 'requestId': '30b31c1838de1e', - 'cpm': 1, - 'width': '640', - 'height': '480', - 'mediaType': 'video', - 'creativeId': '5678', - 'vastUrl': 'https://testvast.com', - 'ttl': 300, - 'netRevenue': true, - 'currency': 'USD' - } - ]; - - const result = spec.interpretResponse({body: bidResponse}, bidRequestsWithMediaType); - expect(JSON.stringify(Object.keys(result[0]).sort())).to.eql(JSON.stringify(Object.keys(expectedResponse[0]).sort())); - }); - - it('should return correct bid response with MediaType and deal_id', function () { - const bidResponseOverride = { 'deal_id': 'OX-mydeal' }; - const bidResponseWithDealId = Object.assign({}, bidResponse, bidResponseOverride); - const result = spec.interpretResponse({body: bidResponseWithDealId}, bidRequestsWithMediaType); - expect(result[0].dealId).to.equal(bidResponseOverride.deal_id); - }); - - it('should handle nobid responses for bidRequests with MediaTypes', function () { - const bidResponse = {'vastUrl': '', 'pub_rev': '', 'width': '', 'height': '', 'adid': '', 'pixels': ''}; - const result = spec.interpretResponse({body: bidResponse}, bidRequestsWithMediaTypes); - expect(result.length).to.equal(0); - }); - - it('should handle nobid responses for bidRequests with MediaType', function () { - const bidResponse = {'vastUrl': '', 'pub_rev': '', 'width': '', 'height': '', 'adid': '', 'pixels': ''}; - const result = spec.interpretResponse({body: bidResponse}, bidRequestsWithMediaType); - expect(result.length).to.equal(0); - }); - }); - - describe('user sync', function () { - const syncUrl = 'https://testpixels.net'; - - describe('iframe sync', function () { - it('should register the pixel iframe from banner ad response', function () { - let syncs = spec.getUserSyncs( - {iframeEnabled: true}, - [{body: {ads: {pixels: syncUrl}}}] - ); - expect(syncs).to.deep.equal([{type: 'iframe', url: syncUrl}]); - }); - - it('should register the pixel iframe from video ad response', function () { - let syncs = spec.getUserSyncs( - {iframeEnabled: true}, - [{body: {pixels: syncUrl}}] - ); - expect(syncs).to.deep.equal([{type: 'iframe', url: syncUrl}]); - }); - - it('should register the default iframe if no pixels available', function () { - let syncs = spec.getUserSyncs( - {iframeEnabled: true}, - [] - ); - expect(syncs).to.deep.equal([{type: 'iframe', url: 'https://u.openx.net/w/1.0/pd'}]); - }); - }); - - describe('pixel sync', function () { - it('should register the image pixel from banner ad response', function () { - let syncs = spec.getUserSyncs( - {pixelEnabled: true}, - [{body: {ads: {pixels: syncUrl}}}] - ); - expect(syncs).to.deep.equal([{type: 'image', url: syncUrl}]); - }); - - it('should register the image pixel from video ad response', function () { - let syncs = spec.getUserSyncs( - {pixelEnabled: true}, - [{body: {pixels: syncUrl}}] - ); - expect(syncs).to.deep.equal([{type: 'image', url: syncUrl}]); - }); - - it('should register the default image pixel if no pixels available', function () { - let syncs = spec.getUserSyncs( - {pixelEnabled: true}, - [] - ); - expect(syncs).to.deep.equal([{type: 'image', url: 'https://u.openx.net/w/1.0/pd'}]); - }); - }); - - it('should prioritize iframe over image for user sync', function () { - let syncs = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, - [{body: {ads: {pixels: syncUrl}}}] - ); - expect(syncs).to.deep.equal([{type: 'iframe', url: syncUrl}]); - }); - - describe('when gdpr applies', function () { - let gdprConsent; - let gdprPixelUrl; - beforeEach(() => { - gdprConsent = { - consentString: 'test-gdpr-consent-string', - gdprApplies: true - }; - - gdprPixelUrl = 'https://testpixels.net?gdpr=1&gdpr_consent=gdpr-pixel-consent' - }); - - it('when there is a response, it should have the gdpr query params', () => { - let [{url}] = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, - [{body: {ads: {pixels: gdprPixelUrl}}}], - gdprConsent - ); - - expect(url).to.have.string('gdpr_consent=gdpr-pixel-consent'); - expect(url).to.have.string('gdpr=1'); - }); - - it('when there is no response, it should append gdpr query params', () => { - let [{url}] = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, - [], - gdprConsent - ); - expect(url).to.have.string('gdpr_consent=test-gdpr-consent-string'); - expect(url).to.have.string('gdpr=1'); - }); - - it('should not send signals if no consent object is available', function () { - let [{url}] = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, - [], - ); - expect(url).to.not.have.string('gdpr_consent='); - expect(url).to.not.have.string('gdpr='); - }); - }); - - describe('when ccpa applies', function () { - let usPrivacyConsent; - let uspPixelUrl; - beforeEach(() => { - usPrivacyConsent = 'TEST'; - uspPixelUrl = 'https://testpixels.net?us_privacy=AAAA' - }); - it('when there is a response, it should send the us privacy string from the response, ', () => { - let [{url}] = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, - [{body: {ads: {pixels: uspPixelUrl}}}], - undefined, - usPrivacyConsent - ); - - expect(url).to.have.string('us_privacy=AAAA'); - }); - it('when there is no response, it send have the us privacy string', () => { - let [{url}] = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, - [], - undefined, - usPrivacyConsent - ); - expect(url).to.have.string(`us_privacy=${usPrivacyConsent}`); - }); - - it('should not send signals if no consent string is available', function () { - let [{url}] = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, - [], - ); - expect(url).to.not.have.string('us_privacy='); - }); - }); - }); - - /** - * Makes sure the override object does not introduce - * new fields against the contract - * - * This does a shallow check in order to make key checking simple - * with respect to what a helper handles. For helpers that have - * nested fields, either check your design on maybe breaking it up - * to smaller, manageable pieces - * - * OR just call this on your nth level field if necessary. - * - * @param {Object} override Object with keys that overrides the default - * @param {Object} contract Original object contains the default fields - * @param {string} typeName Name of the type we're checking for error messages - * @throws {AssertionError} - */ - function overrideKeyCheck(override, contract, typeName) { - expect(contract).to.include.all.keys(Object.keys(override)); - } - - /** - * Creates a mock ArjResponse - * @param {OxArjResponse=} response - * @param {Array=} adUnits - * @throws {AssertionError} - * @return {OxArjResponse} - */ - function mockArjResponse(response, adUnits = []) { - let mockedArjResponse = utils.deepClone(DEFAULT_ARJ_RESPONSE); - - if (response) { - overrideKeyCheck(response, DEFAULT_ARJ_RESPONSE, 'OxArjResponse'); - overrideKeyCheck(response.ads, DEFAULT_ARJ_RESPONSE.ads, 'OxArjResponse'); - Object.assign(mockedArjResponse, response); - } - - if (adUnits.length) { - mockedArjResponse.ads.count = adUnits.length; - mockedArjResponse.ads.ad = adUnits.map((adUnit) => { - overrideKeyCheck(adUnit, DEFAULT_TEST_ARJ_AD_UNIT, 'OxArjAdUnit'); - return Object.assign(utils.deepClone(DEFAULT_TEST_ARJ_AD_UNIT), adUnit); - }); - } - - return mockedArjResponse; - } - - /** - * Creates a mock ArjAdUnit - * @param {OxArjAdUnit=} adUnit - * @param {OxArjCreative=} creative - * @throws {AssertionError} - * @return {OxArjAdUnit} - */ - function mockAdUnit(adUnit, creative) { - overrideKeyCheck(adUnit, DEFAULT_TEST_ARJ_AD_UNIT, 'OxArjAdUnit'); - - let mockedAdUnit = Object.assign(utils.deepClone(DEFAULT_TEST_ARJ_AD_UNIT), adUnit); - - if (creative) { - overrideKeyCheck(creative, DEFAULT_TEST_ARJ_CREATIVE); - if (creative.tracking) { - overrideKeyCheck(creative.tracking, DEFAULT_TEST_ARJ_CREATIVE.tracking, 'OxArjCreative'); - } - Object.assign(mockedAdUnit.creative[0], creative); - } - - return mockedAdUnit; - } -}) -; diff --git a/test/spec/modules/optimeraBidAdapter_spec.js b/test/spec/modules/optimeraBidAdapter_spec.js deleted file mode 100644 index ada07fe25c2..00000000000 --- a/test/spec/modules/optimeraBidAdapter_spec.js +++ /dev/null @@ -1,99 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/optimeraBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('OptimeraAdapter', 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 () { - let bid = { - 'bidder': 'optimera', - 'params': { - 'clientID': '9999' - }, - 'adUnitCode': 'div-0', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - }) - - describe('buildRequests', function () { - let bid = [ - { - 'adUnitCode': 'div-0', - 'auctionId': '1ab30503e03994', - 'bidId': '313e0afede8cdb', - 'bidder': 'optimera', - 'bidderRequestId': '202be1ce3f6194', - 'params': { - 'clientID': '0' - } - } - ]; - it('buildRequests fires', function () { - let request = spec.buildRequests(bid); - expect(request).to.exist; - expect(request.method).to.equal('GET'); - expect(request.payload).to.exist; - }); - }) - - describe('interpretResponse', function () { - let serverResponse = {}; - serverResponse.body = JSON.parse('{"div-0":["RB_K","728x90K"], "timestamp":["RB_K","1507565666"], "device": { "de": { "div-0":["A1","728x90K"] }, "mo": { "div-0":["RB_K","728x90K"] }, "tb": { "div-0":["RB_K","728x90K"] } } }'); - var bidRequest = { - 'method': 'get', - 'payload': [ - { - 'bidder': 'optimera', - 'params': { - 'clientID': '0' - }, - 'adUnitCode': 'div-0', - 'bidId': '307440db8538ab' - } - ] - } - it('interpresResponse fires', function () { - let bidResponses = spec.interpretResponse(serverResponse, bidRequest); - expect(bidResponses[0].dealId[0]).to.equal('RB_K'); - expect(bidResponses[0].dealId[1]).to.equal('728x90K'); - }); - }); - - describe('interpretResponse with optional device param', function () { - let serverResponse = {}; - serverResponse.body = JSON.parse('{"div-0":["RB_K","728x90K"], "timestamp":["RB_K","1507565666"], "device": { "de": { "div-0":["A1","728x90K"] }, "mo": { "div-0":["RB_K","728x90K"] }, "tb": { "div-0":["RB_K","728x90K"] } } }'); - var bidRequest = { - 'method': 'get', - 'payload': [ - { - 'bidder': 'optimera', - 'params': { - 'clientID': '0', - 'device': 'de' - }, - 'adUnitCode': 'div-0', - 'bidId': '307440db8538ab' - } - ] - } - it('interpresResponse fires', function () { - let bidResponses = spec.interpretResponse(serverResponse, bidRequest); - expect(bidResponses[0].dealId[0]).to.equal('A1'); - expect(bidResponses[0].dealId[1]).to.equal('728x90K'); - }); - }); -}); diff --git a/test/spec/modules/optimonAnalyticsAdapter_spec.js b/test/spec/modules/optimonAnalyticsAdapter_spec.js deleted file mode 100644 index b5b76ce3fde..00000000000 --- a/test/spec/modules/optimonAnalyticsAdapter_spec.js +++ /dev/null @@ -1,40 +0,0 @@ -import * as utils from 'src/utils.js'; -import { expect } from 'chai'; -import optimonAnalyticsAdapter from '../../../modules/optimonAnalyticsAdapter.js'; -import adapterManager from 'src/adapterManager'; -import events from 'src/events'; -import constants from 'src/constants.json' - -const AD_UNIT_CODE = 'demo-adunit-1'; -const PUBLISHER_CONFIG = { - pubId: 'optimon_test', - pubAdxAccount: 123456789, - pubTimezone: 'Asia/Jerusalem' -}; - -describe('Optimon Analytics Adapter', () => { - const optmn_currentWindow = utils.getWindowSelf(); - let optmn_queue = []; - - beforeEach(() => { - optmn_currentWindow.OptimonAnalyticsAdapter = (...optmn_args) => optmn_queue.push(optmn_args); - adapterManager.enableAnalytics({ - provider: 'optimon' - }); - optmn_queue = [] - }); - - afterEach(() => { - optimonAnalyticsAdapter.disableAnalytics(); - }); - - it('should forward all events to the queue', () => { - const optmn_arguments = [AD_UNIT_CODE, PUBLISHER_CONFIG]; - - events.emit(constants.EVENTS.AUCTION_END, optmn_arguments) - events.emit(constants.EVENTS.BID_TIMEOUT, optmn_arguments) - events.emit(constants.EVENTS.BID_WON, optmn_arguments) - - expect(optmn_queue.length).to.eql(3); - }); -}); diff --git a/test/spec/modules/orbidderBidAdapter_spec.js b/test/spec/modules/orbidderBidAdapter_spec.js deleted file mode 100644 index df551311c0b..00000000000 --- a/test/spec/modules/orbidderBidAdapter_spec.js +++ /dev/null @@ -1,213 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/orbidderBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; - -describe('orbidderBidAdapter', () => { - const adapter = newBidder(spec); - const defaultBidRequest = { - bidId: 'd66fa86787e0b0ca900a96eacfd5f0bb', - auctionId: 'ccc4c7cdfe11cfbd74065e6dd28413d8', - transactionId: 'd58851660c0c4461e4aa06344fc9c0c6', - bidRequestCount: 1, - adUnitCode: 'adunit-code', - sizes: [[300, 250], [300, 600]], - params: { - 'accountId': 'string1', - 'placementId': 'string2' - } - }; - - const deepClone = function (val) { - return JSON.parse(JSON.stringify(val)); - }; - - const buildRequest = (buildRequest, bidderRequest) => { - if (!Array.isArray(buildRequest)) { - buildRequest = [buildRequest]; - } - - return spec.buildRequests(buildRequest, { - ...bidderRequest || {}, - refererInfo: { - referer: 'https://localhost:9876/' - } - })[0]; - }; - - describe('inherited functions', () => { - it('exists and is a function', () => { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', () => { - it('should return true when required params found', () => { - expect(spec.isBidRequestValid(defaultBidRequest)).to.equal(true); - }); - - it('accepts optional profile object', () => { - const bidRequest = deepClone(defaultBidRequest); - bidRequest.params.profile = {'key': 'value'}; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }); - - it('performs type checking', () => { - const bidRequest = deepClone(defaultBidRequest); - bidRequest.params.accountId = 1; // supposed to be a string - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('doesn\'t accept malformed profile', () => { - const bidRequest = deepClone(defaultBidRequest); - bidRequest.params.profile = 'another not usable string'; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when required params are not passed', () => { - const bidRequest = deepClone(defaultBidRequest); - delete bidRequest.params; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('accepts optional bidfloor', () => { - const bidRequest = deepClone(defaultBidRequest); - bidRequest.params.bidfloor = 123; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - - bidRequest.params.bidfloor = 1.23; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }); - - it('doesn\'t accept malformed bidfloor', () => { - const bidRequest = deepClone(defaultBidRequest); - bidRequest.params.bidfloor = 'another not usable string'; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - }); - - describe('buildRequests', () => { - const request = buildRequest(defaultBidRequest); - - it('sends bid request to endpoint via https using post', () => { - expect(request.method).to.equal('POST'); - expect(request.url.indexOf('https://')).to.equal(0); - expect(request.url).to.equal(`${spec.hostname}/bid`); - }); - - it('contains prebid version parameter', () => { - expect(request.data.v).to.equal($$PREBID_GLOBAL$$.version); - }); - - it('sends correct bid parameters', () => { - // we add two, because we add referer information and version from bidderRequest object - expect(Object.keys(request.data).length).to.equal(Object.keys(defaultBidRequest).length + 2); - expect(request.data.pageUrl).to.equal('https://localhost:9876/'); - // expect(request.data.referrer).to.equal(''); - Object.keys(defaultBidRequest).forEach((key) => { - expect(defaultBidRequest[key]).to.equal(request.data[key]); - }); - }); - - it('handles empty gdpr object', () => { - const request = buildRequest(defaultBidRequest, { - gdprConsent: {} - }); - expect(request.data.gdprConsent.consentRequired).to.be.equal(false); - }); - - it('handles non-existent gdpr object', () => { - const request = buildRequest(defaultBidRequest, { - gdprConsent: null - }); - expect(request.data.gdprConsent).to.be.undefined; - }); - - it('handles properly filled gdpr object where gdpr applies', () => { - const consentString = 'someWeirdString'; - const request = buildRequest(defaultBidRequest, { - gdprConsent: { - gdprApplies: true, - consentString: consentString - } - }); - - const gdprConsent = request.data.gdprConsent; - expect(gdprConsent.consentRequired).to.be.equal(true); - expect(gdprConsent.consentString).to.be.equal(consentString); - }); - - it('handles properly filled gdpr object where gdpr does not apply', () => { - const consentString = 'someWeirdString'; - const request = buildRequest(defaultBidRequest, { - gdprConsent: { - gdprApplies: false, - consentString: consentString - } - }); - - const gdprConsent = request.data.gdprConsent; - expect(gdprConsent.consentRequired).to.be.equal(false); - expect(gdprConsent.consentString).to.be.equal(consentString); - }); - }); - - describe('interpretResponse', () => { - it('should get correct bid response', () => { - const serverResponse = [ - { - 'width': 300, - 'height': 250, - 'creativeId': '29681110', - 'ad': '', - 'cpm': 0.5, - 'requestId': '30b31c1838de1e', - 'ttl': 60, - 'netRevenue': true, - 'currency': 'EUR' - } - ]; - - const expectedResponse = [ - { - 'requestId': '30b31c1838de1e', - 'cpm': 0.5, - 'creativeId': '29681110', - 'width': 300, - 'height': 250, - 'ttl': 60, - 'currency': 'EUR', - 'ad': '', - 'netRevenue': true - } - ]; - - const result = spec.interpretResponse({body: serverResponse}); - - expect(result.length).to.equal(expectedResponse.length); - Object.keys(expectedResponse[0]).forEach((key) => { - expect(result[0][key]).to.equal(expectedResponse[0][key]); - }); - }); - - it('handles broken server response', () => { - const serverResponse = [ - { - 'ad': '', - 'cpm': 0.5, - 'requestId': '30b31c1838de1e', - 'ttl': 60 - } - ]; - const result = spec.interpretResponse({body: serverResponse}); - - expect(result.length).to.equal(0); - }); - - it('handles nobid responses', () => { - const serverResponse = []; - const result = spec.interpretResponse({body: serverResponse}); - - expect(result.length).to.equal(0); - }); - }); -}); diff --git a/test/spec/modules/otmBidAdapter_spec.js b/test/spec/modules/otmBidAdapter_spec.js deleted file mode 100644 index 8ac01c1657e..00000000000 --- a/test/spec/modules/otmBidAdapter_spec.js +++ /dev/null @@ -1,105 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/otmBidAdapter.js'; - -describe('otmBidAdapterTests', function () { - it('validate_pub_params', function () { - expect(spec.isBidRequestValid({ - bidder: 'otm', - params: { - tid: '123', - bidfloor: 20 - } - })).to.equal(true); - }); - - it('validate_generated_params', function () { - let bidRequestData = [{ - bidId: 'bid1234', - bidder: 'otm', - params: { - tid: '123', - bidfloor: 20 - }, - sizes: [[240, 400]] - }]; - - let request = spec.buildRequests(bidRequestData); - let req_data = request[0].data; - - expect(req_data.bidid).to.equal('bid1234'); - }); - - it('validate_best_size_select', function () { - // when: - let bidRequestData = [{ - bidId: 'bid1234', - bidder: 'otm', - params: { - tid: '123', - bidfloor: 20 - }, - sizes: [[300, 500], [300, 600], [240, 400], [300, 50]] - }]; - - let request = spec.buildRequests(bidRequestData); - let req_data = request[0].data; - - // then: - expect(req_data.w).to.equal(240); - expect(req_data.h).to.equal(400); - - // when: - bidRequestData = [{ - bidId: 'bid1234', - bidder: 'otm', - params: { - tid: '123', - bidfloor: 20 - }, - sizes: [[200, 240], [400, 440]] - }]; - - request = spec.buildRequests(bidRequestData); - req_data = request[0].data; - - // then: - expect(req_data.w).to.equal(200); - expect(req_data.h).to.equal(240); - }); - - it('validate_response_params', function () { - let bidRequestData = { - data: { - bidId: 'bid1234' - } - }; - - let serverResponse = { - body: [ - { - 'auctionid': '3c6f8e22-541b-485c-9214-e974d9fb1b6f', - 'cpm': 847.097, - 'ad': 'test html', - 'w': 240, - 'h': 400, - 'currency': 'RUB', - 'ttl': 300, - 'creativeid': '1_7869053', - 'bidid': '101f211def7c99', - 'transactionid': 'transaction_id_1' - } - ] - }; - - let bids = spec.interpretResponse(serverResponse, bidRequestData); - expect(bids).to.have.lengthOf(1); - let bid = bids[0]; - expect(bid.cpm).to.equal(847.097); - expect(bid.currency).to.equal('RUB'); - expect(bid.width).to.equal(240); - expect(bid.height).to.equal(400); - expect(bid.netRevenue).to.equal(true); - expect(bid.requestId).to.equal('101f211def7c99'); - expect(bid.ad).to.equal('test html'); - }); -}); diff --git a/test/spec/modules/outbrainBidAdapter_spec.js b/test/spec/modules/outbrainBidAdapter_spec.js deleted file mode 100644 index 4bdd657f419..00000000000 --- a/test/spec/modules/outbrainBidAdapter_spec.js +++ /dev/null @@ -1,548 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/outbrainBidAdapter.js'; -import {config} from 'src/config.js'; -import {server} from 'test/mocks/xhr'; - -describe('Outbrain Adapter', function () { - describe('Bid request and response', function () { - const commonBidRequest = { - bidder: 'outbrain', - params: { - publisher: { - id: 'publisher-id' - }, - }, - bidId: '2d6815a92ba1ba', - auctionId: '12043683-3254-4f74-8934-f941b085579e', - } - const nativeBidRequestParams = { - nativeParams: { - image: { - required: true, - sizes: [ - 120, - 100 - ], - sendId: true - }, - title: { - required: true, - sendId: true - }, - sponsoredBy: { - required: false - } - }, - } - - const displayBidRequestParams = { - sizes: [ - [ - 300, - 250 - ] - ] - } - - describe('isBidRequestValid', function () { - before(() => { - config.setConfig({ - outbrain: { - bidderUrl: 'https://bidder-url.com', - } - } - ) - }) - after(() => { - config.resetConfig() - }) - - it('should fail when bid is invalid', function () { - const bid = { - bidder: 'outbrain', - params: { - publisher: { - id: 'publisher-id', - } - }, - } - expect(spec.isBidRequestValid(bid)).to.equal(false) - }) - it('should succeed when bid contains native params', function () { - const bid = { - bidder: 'outbrain', - params: { - publisher: { - id: 'publisher-id', - } - }, - ...nativeBidRequestParams, - } - expect(spec.isBidRequestValid(bid)).to.equal(true) - }) - it('should succeed when bid contains sizes', function () { - const bid = { - bidder: 'outbrain', - params: { - publisher: { - id: 'publisher-id', - } - }, - ...displayBidRequestParams, - } - expect(spec.isBidRequestValid(bid)).to.equal(true) - }) - it('should fail if publisher id is not set', function () { - const bid = { - bidder: 'outbrain', - ...nativeBidRequestParams, - } - expect(spec.isBidRequestValid(bid)).to.equal(false) - }) - it('should succeed with outbrain config', function () { - const bid = { - bidder: 'outbrain', - params: { - publisher: { - id: 'publisher-id', - } - }, - ...nativeBidRequestParams, - } - config.resetConfig() - config.setConfig({ - outbrain: { - bidderUrl: 'https://bidder-url.com', - } - }) - expect(spec.isBidRequestValid(bid)).to.equal(true) - }) - it('should fail if bidder url is not set', function () { - const bid = { - bidder: 'outbrain', - params: { - publisher: { - id: 'publisher-id', - } - }, - ...nativeBidRequestParams, - } - config.resetConfig() - expect(spec.isBidRequestValid(bid)).to.equal(false) - }) - }) - - describe('buildRequests', function () { - before(() => { - config.setConfig({ - outbrain: { - bidderUrl: 'https://bidder-url.com', - } - } - ) - }) - after(() => { - config.resetConfig() - }) - - const commonBidderRequest = { - refererInfo: { - referer: 'https://example.com/' - } - } - - it('should build native request', function () { - const bidRequest = { - ...commonBidRequest, - ...nativeBidRequestParams, - } - const expectedNativeAssets = { - assets: [ - { - required: 1, - id: 3, - img: { - type: 3, - w: 120, - h: 100 - } - }, - { - required: 1, - id: 0, - title: {} - }, - { - required: 0, - id: 5, - data: { - type: 1 - } - } - ] - } - const expectedData = { - site: { - page: 'https://example.com/', - publisher: { - id: 'publisher-id' - } - }, - device: { - ua: navigator.userAgent - }, - source: { - fd: 1 - }, - cur: [ - 'USD' - ], - imp: [ - { - id: '1', - native: { - request: JSON.stringify(expectedNativeAssets) - } - } - ] - } - const res = spec.buildRequests([bidRequest], commonBidderRequest) - expect(res.url).to.equal('https://bidder-url.com') - expect(res.data).to.deep.equal(JSON.stringify(expectedData)) - }); - - it('should build display request', function () { - const bidRequest = { - ...commonBidRequest, - ...displayBidRequestParams, - } - const expectedData = { - site: { - page: 'https://example.com/', - publisher: { - id: 'publisher-id' - } - }, - device: { - ua: navigator.userAgent - }, - source: { - fd: 1 - }, - cur: [ - 'USD' - ], - imp: [ - { - id: '1', - banner: { - format: [ - { - w: 300, - h: 250 - } - ] - } - } - ] - } - const res = spec.buildRequests([bidRequest], commonBidderRequest) - expect(res.url).to.equal('https://bidder-url.com') - expect(res.data).to.deep.equal(JSON.stringify(expectedData)) - }) - - it('should pass optional parameters in request', function () { - const bidRequest = { - ...commonBidRequest, - ...nativeBidRequestParams, - } - bidRequest.params.tagid = 'test-tag' - bidRequest.params.publisher.name = 'test-publisher' - bidRequest.params.publisher.domain = 'test-publisher.com' - bidRequest.params.bcat = ['bad-category'] - bidRequest.params.badv = ['bad-advertiser'] - - const res = spec.buildRequests([bidRequest], commonBidderRequest) - const resData = JSON.parse(res.data) - expect(resData.imp[0].tagid).to.equal('test-tag') - expect(resData.site.publisher.name).to.equal('test-publisher') - expect(resData.site.publisher.domain).to.equal('test-publisher.com') - expect(resData.bcat).to.deep.equal(['bad-category']) - expect(resData.badv).to.deep.equal(['bad-advertiser']) - }); - - it('should pass bidder timeout', function () { - const bidRequest = { - ...commonBidRequest, - ...nativeBidRequestParams, - } - const bidderRequest = { - ...commonBidderRequest, - timeout: 500 - } - const res = spec.buildRequests([bidRequest], bidderRequest) - const resData = JSON.parse(res.data) - expect(resData.tmax).to.equal(500) - }); - - it('should pass GDPR consent', function () { - const bidRequest = { - ...commonBidRequest, - ...nativeBidRequestParams, - } - const bidderRequest = { - ...commonBidderRequest, - gdprConsent: { - gdprApplies: true, - consentString: 'consentString', - } - } - const res = spec.buildRequests([bidRequest], bidderRequest) - const resData = JSON.parse(res.data) - expect(resData.user.ext.consent).to.equal('consentString') - expect(resData.regs.ext.gdpr).to.equal(1) - }); - - it('should pass us privacy consent', function () { - const bidRequest = { - ...commonBidRequest, - ...nativeBidRequestParams, - } - const bidderRequest = { - ...commonBidderRequest, - uspConsent: 'consentString' - } - const res = spec.buildRequests([bidRequest], bidderRequest) - const resData = JSON.parse(res.data) - expect(resData.regs.ext.us_privacy).to.equal('consentString') - }); - - it('should pass coppa consent', function () { - const bidRequest = { - ...commonBidRequest, - ...nativeBidRequestParams, - } - config.setConfig({coppa: true}) - - const res = spec.buildRequests([bidRequest], commonBidderRequest) - const resData = JSON.parse(res.data) - expect(resData.regs.coppa).to.equal(1) - - config.resetConfig() - }); - }) - - describe('interpretResponse', function () { - it('should return empty array if no valid bids', function () { - const res = spec.interpretResponse({}, []) - expect(res).to.be.an('array').that.is.empty - }); - - it('should interpret native response', function () { - const serverResponse = { - body: { - id: '0a73e68c-9967-4391-b01b-dda2d9fc54e4', - seatbid: [ - { - bid: [ - { - id: '82822cf5-259c-11eb-8a52-f29e5275aa57', - impid: '1', - price: 1.1, - nurl: 'http://example.com/win/${AUCTION_PRICE}', - adm: '{"ver":"1.2","assets":[{"id":3,"required":1,"img":{"url":"http://example.com/img/url","w":120,"h":100}},{"id":0,"required":1,"title":{"text":"Test title"}},{"id":5,"data":{"value":"Test sponsor"}}],"link":{"url":"http://example.com/click/url"},"eventtrackers":[{"event":1,"method":1,"url":"http://example.com/impression"}]}', - adomain: [ - 'example.com' - ], - cid: '3487171', - crid: '28023739', - cat: [ - 'IAB10-2' - ] - } - ], - seat: 'acc-5537' - } - ], - bidid: '82822cf5-259c-11eb-8a52-b48e7518c657', - cur: 'USD' - }, - } - const request = { - bids: [ - { - ...commonBidRequest, - ...nativeBidRequestParams, - } - ] - } - const expectedRes = [ - { - requestId: request.bids[0].bidId, - cpm: 1.1, - creativeId: '28023739', - ttl: 360, - netRevenue: false, - currency: 'USD', - mediaType: 'native', - nurl: 'http://example.com/win/${AUCTION_PRICE}', - meta: { - 'advertiserDomains': [ - 'example.com' - ] - }, - native: { - clickTrackers: undefined, - clickUrl: 'http://example.com/click/url', - image: { - url: 'http://example.com/img/url', - width: 120, - height: 100 - }, - title: 'Test title', - sponsoredBy: 'Test sponsor', - impressionTrackers: [ - 'http://example.com/impression', - ] - } - } - ] - - const res = spec.interpretResponse(serverResponse, request) - expect(res).to.deep.equal(expectedRes) - }); - - it('should interpret display response', function () { - const serverResponse = { - body: { - id: '6b2eedc8-8ff5-46ef-adcf-e701b508943e', - seatbid: [ - { - bid: [ - { - id: 'd90fe7fa-28d7-11eb-8ce4-462a842a7cf9', - impid: '1', - price: 1.1, - nurl: 'http://example.com/win/${AUCTION_PRICE}', - adm: '
ad
', - adomain: [ - 'example.com' - ], - cid: '3865084', - crid: '29998660', - cat: [ - 'IAB10-2' - ], - w: 300, - h: 250 - } - ], - seat: 'acc-6536' - } - ], - bidid: 'd90fe7fa-28d7-11eb-8ce4-13d94bfa26f9', - cur: 'USD' - } - } - const request = { - bids: [ - { - ...commonBidRequest, - ...displayBidRequestParams - } - ] - } - const expectedRes = [ - { - requestId: request.bids[0].bidId, - cpm: 1.1, - creativeId: '29998660', - ttl: 360, - netRevenue: false, - currency: 'USD', - mediaType: 'banner', - nurl: 'http://example.com/win/${AUCTION_PRICE}', - ad: '
ad
', - width: 300, - height: 250, - meta: { - 'advertiserDomains': [ - 'example.com' - ] - }, - } - ] - - const res = spec.interpretResponse(serverResponse, request) - expect(res).to.deep.equal(expectedRes) - }); - }) - }) - - describe('getUserSyncs', function () { - const usersyncUrl = 'https://usersync-url.com'; - beforeEach(() => { - config.setConfig({ - outbrain: { - usersyncUrl: usersyncUrl, - } - } - ) - }) - after(() => { - config.resetConfig() - }) - - it('should return user sync if pixel enabled with outbrain config', function () { - const ret = spec.getUserSyncs({pixelEnabled: true}) - expect(ret).to.deep.equal([{type: 'image', url: usersyncUrl}]) - }) - - it('should not return user sync if pixel disabled', function () { - 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}) - expect(ret).to.be.an('array').that.is.empty - }) - - it('should pass GDPR consent', function() { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {gdprApplies: true, consentString: 'foo'}, undefined)).to.deep.equal([{ - type: 'image', url: `${usersyncUrl}?gdpr=1&gdpr_consent=foo` - }]); - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {gdprApplies: false, consentString: 'foo'}, undefined)).to.deep.equal([{ - type: 'image', url: `${usersyncUrl}?gdpr=0&gdpr_consent=foo` - }]); - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {gdprApplies: true, consentString: undefined}, undefined)).to.deep.equal([{ - type: 'image', url: `${usersyncUrl}?gdpr=1&gdpr_consent=` - }]); - }); - - it('should pass US consent', function() { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, undefined, '1NYN')).to.deep.equal([{ - type: 'image', url: `${usersyncUrl}?us_privacy=1NYN` - }]); - }); - - it('should pass GDPR and US consent', function() { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {gdprApplies: true, consentString: 'foo'}, '1NYN')).to.deep.equal([{ - type: 'image', url: `${usersyncUrl}?gdpr=1&gdpr_consent=foo&us_privacy=1NYN` - }]); - }); - }) - - describe('onBidWon', function () { - it('should make an ajax call with the original cpm', function () { - const bid = { - nurl: 'http://example.com/win/${AUCTION_PRICE}', - cpm: 2.1, - originalCpm: 1.1, - } - spec.onBidWon(bid) - expect(server.requests[0].url).to.equals('http://example.com/win/1.1') - }); - }) -}) diff --git a/test/spec/modules/outconBidAdapter_spec.js b/test/spec/modules/outconBidAdapter_spec.js deleted file mode 100644 index 81c3fdded62..00000000000 --- a/test/spec/modules/outconBidAdapter_spec.js +++ /dev/null @@ -1,100 +0,0 @@ -import { expect } from 'chai'; -import { spec } from '../../../modules/outconBidAdapter.js'; - -describe('outconBidAdapter', function () { - describe('bidRequestValidity', function () { - it('Check the bidRequest with pod param', function () { - expect(spec.isBidRequestValid({ - bidder: 'outcon', - params: { - pod: '5d603538eba7192ae14e39a4', - env: 'test' - } - })).to.equal(true); - }); - it('Check the bidRequest with internalID and publisherID params', function () { - expect(spec.isBidRequestValid({ - bidder: 'outcon', - params: { - internalId: '12345678', - publisher: '5d5d66f2306ea4114a37c7c2', - env: 'test' - } - })).to.equal(true); - }); - }); - describe('buildRequests', function () { - it('Build requests with pod param', function () { - expect(spec.buildRequests([{ - bidder: 'outcon', - params: { - pod: '5d603538eba7192ae14e39a4', - env: 'test' - } - }])).to.have.keys('method', 'url', 'data'); - }); - it('Build requests with internalID and publisherID params', function () { - expect(spec.buildRequests([{ - bidder: 'outcon', - params: { - internalId: '12345678', - publisher: '5d5d66f2306ea4114a37c7c2', - env: 'test' - } - }])).to.have.keys('method', 'url', 'data'); - }); - }); - describe('interpretResponse', function () { - const bidRequest = { - method: 'GET', - url: 'https://test.outcondigital.com/ad/', - data: { - pod: '5d603538eba7192ae14e39a4', - env: 'test', - vast: 'true' - } - }; - const bidResponse = { - body: { - cpm: 0.10, - cur: 'USD', - exp: 10, - creatives: [ - { - url: 'https://test.outcondigital.com/uploads/5d42e7a7306ea4689b67c122/frutas.mp4', - size: 3, - width: 1920, - height: 1080, - codec: 'video/mp4' - } - ], - ad: '5d6e6aef22063e392bf7f564', - type: 'video', - campaign: '5d42e44b306ea469593c76a2', - trackingURL: 'https://test.outcondigital.com/ad/track?track=5d6e6aef22063e392bf7f564', - vastURL: 'https://test.outcondigital.com/outcon.xml?impression=5d6e6aef22063e392bf7f564&demo=true' - }, - }; - it('check all the keys that are needed to interpret the response', function () { - const result = spec.interpretResponse(bidResponse, bidRequest); - let requiredKeys = [ - 'requestId', - 'cpm', - 'width', - 'height', - 'creativeId', - 'currency', - 'netRevenue', - 'ttl', - 'ad', - 'vastImpUrl', - 'mediaType', - 'vastUrl' - ]; - let resultKeys = Object.keys(result[0]); - resultKeys.forEach(function(key) { - expect(requiredKeys.indexOf(key) !== -1).to.equal(true); - }); - }) - }); -}); diff --git a/test/spec/modules/ozoneBidAdapter_spec.js b/test/spec/modules/ozoneBidAdapter_spec.js deleted file mode 100644 index 10b8ce31d28..00000000000 --- a/test/spec/modules/ozoneBidAdapter_spec.js +++ /dev/null @@ -1,2684 +0,0 @@ -import { expect } from 'chai'; -import { spec, getWidthAndHeightFromVideoObject, playerSizeIsNestedArray, defaultSize } from 'modules/ozoneBidAdapter.js'; -import { config } from 'src/config.js'; -import {Renderer} from '../../../src/Renderer.js'; -import {getGranularityKeyName, getGranularityObject} from '../../../modules/ozoneBidAdapter.js'; -import * as utils from '../../../src/utils.js'; -const OZONEURI = 'https://elb.the-ozone-project.com/openrtb2/auction'; -const BIDDER_CODE = 'ozone'; - -/* - -NOTE - use firefox console to deep copy the objects to use here - - */ -var originalPropertyBag = {'pageId': null}; -var validBidRequests = [ - { - adUnitCode: 'div-gpt-ad-1460505748561-0', - auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', - bidId: '2899ec066a91ff8', - 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 } } ] }, - sizes: [[300, 250], [300, 600]], - transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' - } -]; -var validBidRequestsMulti = [ - { - testId: 1, - adUnitCode: 'div-gpt-ad-1460505748561-0', - auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', - bidId: '2899ec066a91ff8', - 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 } } ] }, - sizes: [[300, 250], [300, 600]], - transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' - }, - { - testId: 2, - adUnitCode: 'div-gpt-ad-1460505748561-0', - auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', - bidId: '2899ec066a91ff0', - 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 } } ] }, - sizes: [[300, 250], [300, 600]], - transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' - } -]; -// use 'pubcid', 'tdid', 'id5id', 'parrableId', 'idl_env', 'criteoId', 'criteortus' -// NOTE THAT criteortus is no longer referenced anywhere - should be removed asap -// see http://prebid.org/dev-docs/modules/userId.html -var validBidRequestsWithUserIdData = [ - { - adUnitCode: 'div-gpt-ad-1460505748561-0', - auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', - bidId: '2899ec066a91ff8', - 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 } } ] }, - sizes: [[300, 250], [300, 600]], - transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87', - userId: { - 'pubcid': '12345678', - 'tdid': '1111tdid', - 'id5id': 'ID5-someId', - 'criteortus': {'ozone': {'userid': 'critId123'}}, - 'criteoId': '1111criteoId', - 'idl_env': 'liverampId', - 'lipb': {'lipbid': 'lipbidId123'}, - 'parrableId': {'eid': '01.5678.parrableid'} - }, - userIdAsEids: [ - { - 'source': 'pubcid.org', - 'uids': [ - { - 'id': '12345678', - 'atype': 1 - } - ] - }, - { - 'source': 'adserver.org', - 'uids': [{ - 'id': '1111tdid', - 'atype': 1, - 'ext': { - 'rtiPartner': 'TDID' - } - }] - }, - { - 'source': 'id5-sync.com', - 'uids': [{ - 'id': 'ID5-someId', - 'atype': 1, - }] - }, - { - 'source': 'criteortus', - 'uids': [{ - 'id': {'ozone': {'userid': 'critId123'}}, - 'atype': 1, - }] - }, - { - 'source': 'criteoId', - 'uids': [{ - 'id': '1111criteoId', - 'atype': 1, - }] - }, - { - 'source': 'idl_env', - 'uids': [{ - 'id': 'liverampId', - 'atype': 1, - }] - }, - { - 'source': 'lipb', - 'uids': [{ - 'id': {'lipbid': 'lipbidId123'}, - 'atype': 1, - }] - }, - { - 'source': 'parrableId', - 'uids': [{ - 'id': {'eid': '01.5678.parrableid'}, - 'atype': 1, - }] - } - ] - - } -]; -var validBidRequestsMinimal = [ - { - adUnitCode: 'div-gpt-ad-1460505748561-0', - auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', - bidId: '2899ec066a91ff8', - 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 } } ] }, - sizes: [[300, 250], [300, 600]], - transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' - } -]; -var validBidRequestsNoSizes = [ - { - adUnitCode: 'div-gpt-ad-1460505748561-0', - auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', - bidId: '2899ec066a91ff8', - 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 } } ] }, - transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' - } -]; - -var validBidRequestsWithBannerMediaType = [ - { - adUnitCode: 'div-gpt-ad-1460505748561-0', - auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', - bidId: '2899ec066a91ff8', - 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]]}}, - transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' - } -]; -var validBidRequestsWithNonBannerMediaTypesAndValidOutstreamVideo = [ - { - adUnitCode: 'div-gpt-ad-1460505748561-0', - auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', - bidId: '2899ec066a91ff8', - 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'}}, - transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' - } -]; - -var validBidRequests1OutstreamVideo2020 = [ - { - 'bidder': 'ozone', - 'testname': 'validBidRequests1OutstreamVideo2020', - 'params': { - 'publisherId': 'OZONERUP0001', - 'placementId': '8000000009', - 'siteId': '4204204201', - 'video': { - 'skippable': true, - 'playback_method': [ - 'auto_play_sound_off' - ] - }, - 'customData': [ - { - 'settings': {}, - 'targeting': { - 'sens': 'f', - 'pt1': '/uk', - 'pt2': 'uk', - 'pt3': 'network-front', - 'pt4': 'ng', - 'pt5': [ - 'uk' - ], - 'pt7': 'desktop', - 'pt8': [ - 'tfmqxwj7q', - 'penl4dfdk', - 'sek9ghqwi' - ], - 'pt9': '|k0xw2vqzp33kklb3j5w4|||' - } - } - ], - 'userId': { - 'pubcid': '2ada6ae6-aeca-4e07-8922-a99b3aaf8a56' - }, - 'userIdAsEids': [ - { - 'source': 'pubcid.org', - 'uids': [ - { - 'id': '2ada6ae6-aeca-4e07-8922-a99b3aaf8a56', - 'atype': 1 - } - ] - } - ] - }, - 'mediaTypes': { - 'video': { - 'playerSize': [ - [ - 640, - 480 - ] - ], - 'mimes': [ - 'video/mp4' - ], - 'context': 'outstream' - } - }, - 'adUnitCode': 'video-ad', - 'transactionId': '02c1ea7d-0bf2-451b-a122-1420040d1cf8', - 'sizes': [ - [ - 640, - 480 - ] - ], - 'bidId': '2899ec066a91ff8', - 'bidderRequestId': '1c1586b27a1b5c8', - 'auctionId': '0456c9b7-5ab2-4fec-9e10-f418d3d1f04c', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - } -]; - -// WHEN sent as bidderRequest to buildRequests you should send the child: .bidderRequest -var validBidderRequest1OutstreamVideo2020 = { - bidderRequest: { - auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', - auctionStart: 1536838908986, - bidderCode: 'ozone', - bidderRequestId: '1c1586b27a1b5c8', - bids: [ - { - 'bidder': 'ozone', - 'params': { - 'publisherId': 'OZONERUP0001', - 'placementId': '8000000009', - 'siteId': '4204204201', - 'video': { - 'skippable': true, - 'playback_method': [ - 'auto_play_sound_off' - ] - }, - 'customData': [ - { - 'settings': {}, - 'targeting': { - 'sens': 'f', - 'pt1': '/uk', - 'pt2': 'uk', - 'pt3': 'network-front', - 'pt4': 'ng', - 'pt5': [ - 'uk' - ], - 'pt7': 'desktop', - 'pt8': [ - 'tfmqxwj7q', - 'penl4dfdk', - 'uayf5jmv3', - 'sek9ghqwi' - ], - 'pt9': '|k0xw2vqzp33kklb3j5w4|||' - } - } - ] - }, - 'userId': { - 'id5id': 'ID5-ZHMOpSv9CkZNiNd1oR4zc62AzCgSS73fPjmQ6Od7OA', - 'pubcid': '2ada6ae6-aeca-4e07-8922-a99b3aaf8a56' - }, - 'userIdAsEids': [ - { - 'source': 'id5-sync.com', - 'uids': [ - { - 'id': 'ID5-ZHMOpSv9CkZNiNd1oR4zc62AzCgSS73fPjmQ6Od7OA', - 'atype': 1 - } - ] - }, - { - 'source': 'pubcid.org', - 'uids': [ - { - 'id': '2ada6ae6-aeca-4e07-8922-a99b3aaf8a56', - 'atype': 1 - } - ] - } - ], - 'mediaTypes': { - 'video': { - 'playerSize': [ - [ - 640, - 480 - ] - ], - 'mimes': [ - 'video/mp4' - ], - 'context': 'outstream' - } - }, - 'adUnitCode': 'video-ad', - 'transactionId': 'ec20cc65-de38-4410-b5b3-50de5b7df66a', - 'sizes': [ - [ - 640, - 480 - ] - ], - 'bidId': '2899ec066a91ff8', - 'bidderRequestId': '1c1586b27a1b5c8', - 'auctionId': '0456c9b7-5ab2-4fec-9e10-f418d3d1f04c', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - }], - doneCbCallCount: 1, - start: 1536838908987, - timeout: 3000 - } -}; -// WHEN sent as bidderRequest to buildRequests you should send the child: .bidderRequest -var validBidderRequest = { - bidderRequest: { - auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', - auctionStart: 1536838908986, - bidderCode: 'ozone', - bidderRequestId: '1c1586b27a1b5c8', - bids: [{ - adUnitCode: 'div-gpt-ad-1460505748561-0', - auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', - bidId: '2899ec066a91ff8', - 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' } ] }, - sizes: [[300, 250], [300, 600]], - transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' - }], - doneCbCallCount: 1, - start: 1536838908987, - timeout: 3000 - } -}; - -// bidder request with GDPR - change the values for testing: -// gdprConsent.gdprApplies (true/false) -// gdprConsent.vendorData.purposeConsents (make empty, make null, remove it) -// gdprConsent.vendorData.vendorConsents (remove 524, remove all, make the element null, remove it) -// WHEN sent as bidderRequest to buildRequests you should send the child: .bidderRequest -var bidderRequestWithFullGdpr = { - bidderRequest: { - auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', - auctionStart: 1536838908986, - bidderCode: 'ozone', - bidderRequestId: '1c1586b27a1b5c8', - bids: [{ - adUnitCode: 'div-gpt-ad-1460505748561-0', - auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', - bidId: '2899ec066a91ff8', - 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' } ] }, - sizes: [[300, 250], [300, 600]], - transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' - }], - doneCbCallCount: 1, - start: 1536838908987, - timeout: 3000, - gdprConsent: { - 'consentString': 'BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA', - 'vendorData': { - 'metadata': 'BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA', - 'gdprApplies': true, - 'hasGlobalScope': false, - 'cookieVersion': '1', - 'created': '2019-05-31T12:46:48.825', - 'lastUpdated': '2019-05-31T12:46:48.825', - 'cmpId': '28', - 'cmpVersion': '1', - 'consentLanguage': 'en', - 'consentScreen': '1', - 'vendorListVersion': 148, - 'maxVendorId': 631, - 'purposeConsents': { - '1': true, - '2': true, - '3': true, - '4': true, - '5': true - }, - 'vendorConsents': { - '468': true, - '522': true, - '524': true, /* 524 is ozone */ - '565': true, - '591': true - } - }, - 'gdprApplies': true - }, } -}; - -var gdpr1 = { - 'consentString': 'BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA', - 'vendorData': { - 'metadata': 'BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA', - 'gdprApplies': true, - 'hasGlobalScope': false, - 'cookieVersion': '1', - 'created': '2019-05-31T12:46:48.825', - 'lastUpdated': '2019-05-31T12:46:48.825', - 'cmpId': '28', - 'cmpVersion': '1', - 'consentLanguage': 'en', - 'consentScreen': '1', - 'vendorListVersion': 148, - 'maxVendorId': 631, - 'purposeConsents': { - '1': true, - '2': true, - '3': true, - '4': true, - '5': true - }, - 'vendorConsents': { - '468': true, - '522': true, - '524': true, /* 524 is ozone */ - '565': true, - '591': true - } - }, - 'gdprApplies': true -}; - -// simulating the Mirror -var bidderRequestWithPartialGdpr = { - bidderRequest: { - auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', - auctionStart: 1536838908986, - bidderCode: 'ozone', - bidderRequestId: '1c1586b27a1b5c8', - bids: [{ - adUnitCode: 'div-gpt-ad-1460505748561-0', - auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', - bidId: '2899ec066a91ff8', - 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' - }] - }, - sizes: [[300, 250], [300, 600]], - transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' - }], - doneCbCallCount: 1, - start: 1536838908987, - timeout: 3000, - gdprConsent: { - 'consentString': 'BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA', - 'gdprApplies': true, - 'vendorData': { - 'metadata': 'BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA', - 'gdprApplies': true - } - } - } -}; - -// make sure the impid matches the request bidId -var validResponse = { - 'body': { - 'id': 'd6198807-7a53-4141-b2db-d2cb754d68ba', - 'seatbid': [ - { - 'bid': [ - { - 'id': '677903815252395017', - 'impid': '2899ec066a91ff8', - 'price': 0.5, - 'adm': '', - 'adid': '98493581', - 'adomain': [ - 'http://prebid.org' - ], - 'iurl': 'https://fra1-ib.adnxs.com/cr?id=98493581', - 'cid': '9325', - 'crid': '98493581', - 'cat': [ - 'IAB3-1' - ], - 'w': 300, - 'h': 600, - 'ext': { - 'prebid': { - 'type': 'banner' - }, - 'bidder': { - 'appnexus': { - 'brand_id': 555545, - 'auction_id': 6500448734132353000, - 'bidder_id': 2, - 'bid_ad_type': 0 - } - } - } - } - ], - 'seat': 'appnexus' - } - ], - 'cur': 'GBP', /* NOTE - this is where cur is, not in the seatbids. */ - 'ext': { - 'responsetimemillis': { - 'appnexus': 47, - 'openx': 30 - } - }, - 'timing': { - 'start': 1536848078.089177, - 'end': 1536848078.142203, - 'TimeTaken': 0.05302619934082031 - } - }, - 'headers': {} -}; - -var validResponse2Bids = { - 'body': { - 'id': 'd6198807-7a53-4141-b2db-d2cb754d68ba', - 'seatbid': [ - { - 'bid': [ - { - 'id': '677903815252395017', - 'impid': '2899ec066a91ff8', - 'price': 0.5, - 'adm': '', - 'adid': '98493581', - 'adomain': [ - 'http://prebid.org' - ], - 'iurl': 'https://fra1-ib.adnxs.com/cr?id=98493581', - 'cid': '9325', - 'crid': '98493581', - 'cat': [ - 'IAB3-1' - ], - 'w': 300, - 'h': 600, - 'ext': { - 'prebid': { - 'type': 'banner' - }, - 'bidder': { - 'appnexus': { - 'brand_id': 555545, - 'auction_id': 6500448734132353000, - 'bidder_id': 2, - 'bid_ad_type': 0 - } - } - } - }, - { - 'id': '677903815252395010', - 'impid': '2899ec066a91ff0', - 'price': 0.9, - 'adm': '', - 'adid': '98493580', - 'adomain': [ - 'http://prebid.org' - ], - 'iurl': 'https://fra1-ib.adnxs.com/cr?id=98493581', - 'cid': '9320', - 'crid': '98493580', - 'cat': [ - 'IAB3-1' - ], - 'w': 300, - 'h': 600, - 'ext': { - 'prebid': { - 'type': 'banner' - }, - 'bidder': { - 'appnexus': { - 'brand_id': 555540, - 'auction_id': 6500448734132353000, - 'bidder_id': 2, - 'bid_ad_type': 0 - } - } - } - } ], - 'seat': 'appnexus' - } - ], - 'cur': 'GBP', /* NOTE - this is where cur is, not in the seatbids. */ - 'ext': { - 'responsetimemillis': { - 'appnexus': 47, - 'openx': 30 - } - }, - 'timing': { - 'start': 1536848078.089177, - 'end': 1536848078.142203, - 'TimeTaken': 0.05302619934082031 - } - }, - 'headers': {} -}; -/* -A bidder returns a bid for both sizes in an adunit - */ -var validResponse2BidsSameAdunit = { - 'body': { - 'id': 'd6198807-7a53-4141-b2db-d2cb754d68ba', - 'seatbid': [ - { - 'bid': [ - { - 'id': '677903815252395017', - 'impid': '2899ec066a91ff8', - 'price': 0.5, - 'adm': '', - 'adid': '98493581', - 'adomain': [ - 'http://prebid.org' - ], - 'iurl': 'https://fra1-ib.adnxs.com/cr?id=98493581', - 'cid': '9325', - 'crid': '98493581', - 'cat': [ - 'IAB3-1' - ], - 'w': 300, - 'h': 600, - 'ext': { - 'prebid': { - 'type': 'banner' - }, - 'bidder': { - 'appnexus': { - 'brand_id': 555545, - 'auction_id': 6500448734132353000, - 'bidder_id': 2, - 'bid_ad_type': 0 - } - } - } - }, - { - 'id': '677903815252395010', - 'impid': '2899ec066a91ff8', - 'price': 0.9, - 'adm': '', - 'adid': '98493580', - 'adomain': [ - 'http://prebid.org' - ], - 'iurl': 'https://fra1-ib.adnxs.com/cr?id=98493581', - 'cid': '9320', - 'crid': '98493580', - 'cat': [ - 'IAB3-1' - ], - 'w': 300, - 'h': 250, - 'ext': { - 'prebid': { - 'type': 'banner' - }, - 'bidder': { - 'appnexus': { - 'brand_id': 555540, - 'auction_id': 6500448734132353000, - 'bidder_id': 2, - 'bid_ad_type': 0 - } - } - } - } ], - 'seat': 'ozappnexus' - } - ], - 'cur': 'GBP', /* NOTE - this is where cur is, not in the seatbids. */ - 'ext': { - 'responsetimemillis': { - 'appnexus': 47, - 'openx': 30 - } - }, - 'timing': { - 'start': 1536848078.089177, - 'end': 1536848078.142203, - 'TimeTaken': 0.05302619934082031 - } - }, - 'headers': {} -}; -/* - -SPECIAL CONSIDERATION FOR VIDEO TESTS: - -DO NOT USE _validVideoResponse directly - the interpretResponse function will modify it (adding a renderer!!!) so all -subsequent calls will already have a renderer attached!!! - -*/ -function getCleanValidVideoResponse() { - return JSON.parse(JSON.stringify(_validVideoResponse)); -} -var _validVideoResponse = { - 'body': { - 'id': 'd6198807-7a53-4141-b2db-d2cb754d68ba', - 'seatbid': [ - { - 'bid': [ - { - 'id': '2899ec066a91ff8', - 'impid': '2899ec066a91ff8', - 'price': 31.7, - 'adm': '', - 'adomain': [ - 'sarr.properties' - ], - 'crid': 'ozone-655', - 'cat': [ - 'IAB21' - ], - 'w': 640, - 'h': 360, - 'ext': { - 'prebid': { - 'type': 'video' - } - }, - 'adId': '2899ec066a91ff8-2', - 'cpm': 31.7, - 'bidId': '2899ec066a91ff8', - 'requestId': '2899ec066a91ff8', - 'width': 640, - 'height': 360, - 'ad': '', - 'netRevenue': true, - 'creativeId': 'ozone-655', - 'currency': 'USD', - 'ttl': 300, - 'adserverTargeting': { - 'oz_ozbeeswax': 'ozbeeswax', - 'oz_ozbeeswax_pb': '31.7', - 'oz_ozbeeswax_crid': 'ozone-655', - 'oz_ozbeeswax_adv': 'sarr.properties', - 'oz_ozbeeswax_imp_id': '49d16ccc28663a8', - 'oz_ozbeeswax_adId': '49d16ccc28663a8-2', - 'oz_ozbeeswax_pb_r': '20.00', - 'oz_ozbeeswax_omp': '1', - 'oz_ozbeeswax_vid': 'outstream', - 'oz_auc_id': 'efa7fea0-7e87-4811-be86-fefb38c35fbb', - 'oz_winner': 'ozbeeswax', - 'oz_response_id': 'efa7fea0-7e87-4811-be86-fefb38c35fbb', - 'oz_winner_auc_id': '49d16ccc28663a8', - 'oz_winner_imp_id': '49d16ccc28663a8', - 'oz_pb_v': '2.4.0', - 'hb_bidder': 'ozone', - 'hb_adid': '49d16ccc28663a8-2', - 'hb_pb': '20.00', - 'hb_size': '640x360', - 'hb_source': 'client', - 'hb_format': 'banner' - }, - 'originalCpm': 31.7, - 'originalCurrency': 'USD' - } - ], - 'seat': 'ozbeeswax' - } - ], - 'ext': { - 'responsetimemillis': { - 'beeswax': 9, - 'openx': 43, - 'ozappnexus': 31, - 'ozbeeswax': 7 - } - }, - 'timing': { - 'start': 1536848078.089177, - 'end': 1536848078.142203, - 'TimeTaken': 0.05302619934082031 - } - }, - 'headers': {} -}; - -var validBidResponse1adWith2Bidders = { - 'body': { - 'id': '91221f96-b931-4acc-8f05-c2a1186fa5ac', - 'seatbid': [ - { - 'bid': [ - { - 'id': 'd6198807-7a53-4141-b2db-d2cb754d68ba', - 'impid': '2899ec066a91ff8', - 'price': 0.36754, - 'adm': '', - 'adid': '134928661', - 'adomain': [ - 'somecompany.com' - ], - 'iurl': 'https:\/\/ams1-ib.adnxs.com\/cr?id=134928661', - 'cid': '8825', - 'crid': '134928661', - 'cat': [ - 'IAB8-15', - 'IAB8-16', - 'IAB8-4', - 'IAB8-1', - 'IAB8-14', - 'IAB8-6', - 'IAB8-13', - 'IAB8-3', - 'IAB8-17', - 'IAB8-12', - 'IAB8-8', - 'IAB8-7', - 'IAB8-2', - 'IAB8-9', - 'IAB8', - 'IAB8-11' - ], - 'w': 300, - 'h': 250, - 'ext': { - 'prebid': { - 'type': 'banner' - }, - 'bidder': { - 'appnexus': { - 'brand_id': 14640, - 'auction_id': 1.8369641905139e+18, - 'bidder_id': 2, - 'bid_ad_type': 0 - } - } - } - } - ], - 'seat': 'appnexus' - }, - { - 'bid': [ - { - 'id': '75665207-a1ca-49db-ba0e-a5e9c7d26f32', - 'impid': '37fff511779365a', - 'price': 1.046, - 'adm': '
removed
', - 'adomain': [ - 'kx.com' - ], - 'crid': '13005', - 'w': 300, - 'h': 250, - 'ext': { - 'prebid': { - 'type': 'banner' - } - } - } - ], - 'seat': 'openx' - } - ], - 'ext': { - 'responsetimemillis': { - 'appnexus': 91, - 'openx': 109, - 'ozappnexus': 46, - 'ozbeeswax': 2, - 'pangaea': 91 - } - } - }, - 'headers': {} -}; - -/* -testing 2 ads, 2 bidders, one bidder bids for both slots in one adunit - */ - -var multiRequest1 = [ - { - 'bidder': 'ozone', - 'params': { - 'publisherId': 'OZONERUP0001', - 'siteId': '4204204201', - 'placementId': '0420420421', - 'customData': [ - { - 'settings': {}, - 'targeting': { - 'sens': 'f', - 'pt1': '/uk', - 'pt2': 'uk', - 'pt3': 'network-front', - 'pt4': 'ng', - 'pt5': [ - 'uk' - ], - 'pt7': 'desktop', - 'pt8': [ - 'tfmqxwj7q', - 'penl4dfdk', - 'uayf5jmv3', - 't8nyiude5', - 'sek9ghqwi' - ], - 'pt9': '|k0xw2vqzp33kklb3j5w4|||' - } - } - ] - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ] - } - }, - 'adUnitCode': 'mpu', - 'transactionId': '6480bac7-31b5-4723-9145-ad8966660651', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '2d30e86db743a8', - 'bidderRequestId': '1d03a1dfc563fc', - 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - }, - { - 'bidder': 'ozone', - 'params': { - 'publisherId': 'OZONERUP0001', - 'siteId': '4204204201', - 'placementId': '0420420421', - 'customData': [ - { - 'settings': {}, - 'targeting': { - 'sens': 'f', - 'pt1': '/uk', - 'pt2': 'uk', - 'pt3': 'network-front', - 'pt4': 'ng', - 'pt5': [ - 'uk' - ], - 'pt7': 'desktop', - 'pt8': [ - 'tfmqxwj7q', - 'penl4dfdk', - 't8nxz6qzd', - 't8nyiude5', - 'sek9ghqwi' - ], - 'pt9': '|k0xw2vqzp33kklb3j5w4|||' - } - } - ] - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 728, - 90 - ], - [ - 970, - 250 - ] - ] - } - }, - 'adUnitCode': 'leaderboard', - 'transactionId': 'a49988e6-ae7c-46c4-9598-f18db49892a0', - 'sizes': [ - [ - 728, - 90 - ], - [ - 970, - 250 - ] - ], - 'bidId': '3025f169863b7f8', - 'bidderRequestId': '1d03a1dfc563fc', - 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - } -]; - -// WHEN sent as bidderRequest to buildRequests you should send the child: .bidderRequest -var multiBidderRequest1 = { - bidderRequest: { - 'bidderCode': 'ozone', - 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f', - 'bidderRequestId': '1d03a1dfc563fc', - 'bids': [ - { - 'bidder': 'ozone', - 'params': { - 'publisherId': 'OZONERUP0001', - 'siteId': '4204204201', - 'placementId': '0420420421', - 'customData': [ - { - 'settings': {}, - 'targeting': { - 'sens': 'f', - 'pt1': '/uk', - 'pt2': 'uk', - 'pt3': 'network-front', - 'pt4': 'ng', - 'pt5': [ - 'uk' - ], - 'pt7': 'desktop', - 'pt8': [ - 'tfmqxwj7q', - 'txeh7uyo0', - 't8nxz6qzd', - 't8nyiude5', - 'sek9ghqwi' - ], - 'pt9': '|k0xw2vqzp33kklb3j5w4|||' - } - } - ] - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ] - } - }, - 'adUnitCode': 'mpu', - 'transactionId': '6480bac7-31b5-4723-9145-ad8966660651', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '2d30e86db743a8', - 'bidderRequestId': '1d03a1dfc563fc', - 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - }, - { - 'bidder': 'ozone', - 'params': { - 'publisherId': 'OZONERUP0001', - 'siteId': '4204204201', - 'placementId': '0420420421', - 'customData': [ - { - 'settings': {}, - 'targeting': { - 'sens': 'f', - 'pt1': '/uk', - 'pt2': 'uk', - 'pt3': 'network-front', - 'pt4': 'ng', - 'pt5': [ - 'uk' - ], - 'pt7': 'desktop', - 'pt8': [ - 'tfmqxwj7q', - 'penl4dfdk', - 't8nxz6qzd', - 't8nyiude5', - 'sek9ghqwi' - ], - 'pt9': '|k0xw2vqzp33kklb3j5w4|||' - } - } - ] - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 728, - 90 - ], - [ - 970, - 250 - ] - ] - } - }, - 'adUnitCode': 'leaderboard', - 'transactionId': 'a49988e6-ae7c-46c4-9598-f18db49892a0', - 'sizes': [ - [ - 728, - 90 - ], - [ - 970, - 250 - ] - ], - 'bidId': '3025f169863b7f8', - 'bidderRequestId': '1d03a1dfc563fc', - 'auctionId': '592ee33b-fb2e-4c00-b2d5-383e99cac57f', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - } - ], - 'auctionStart': 1592918645574, - 'timeout': 3000, - 'refererInfo': { - 'referer': 'http://ozone.ardm.io/adapter/2.4.0/620x350-switch.html?guardian=true&pbjs_debug=true', - 'reachedTop': true, - 'numIframes': 0, - 'stack': [ - 'http://ozone.ardm.io/adapter/2.4.0/620x350-switch.html?guardian=true&pbjs_debug=true' - ] - }, - 'gdprConsent': { - 'consentString': 'BOvy5sFO1dBa2AKAiBENDP-AAAAwVrv7_77-_9f-_f__9uj3Gr_v_f__32ccL5tv3h_7v-_7fi_-0nV4u_1tft9ydk1-5ctDztp507iakiPHmqNeb9n_mz1eZpRP58E09j53z7Ew_v8_v-b7BCPN_Y3v-8K96kA', - 'vendorData': { - 'metadata': 'BOvy5sFO1dBa2AKAiBENDPA', - 'gdprApplies': true, - 'hasGlobalConsent': false, - 'hasGlobalScope': false, - 'purposeConsents': { - '1': true, - '2': true, - '3': true, - '4': true, - '5': true - }, - 'vendorConsents': { - '1': true, - '2': true, - '3': false, - '4': true, - '5': true - } - }, - 'gdprApplies': true - }, - 'start': 1592918645578 - } -}; - -var multiResponse1 = { - 'body': { - 'id': '592ee33b-fb2e-4c00-b2d5-383e99cac57f', - 'seatbid': [ - { - 'bid': [ - { - 'id': '4419718600113204943', - 'impid': '2d30e86db743a8', - 'price': 0.2484, - 'adm': '', - 'adid': '119683582', - 'adomain': [ - 'https://ozoneproject.com' - ], - 'iurl': 'https://ams1-ib.adnxs.com/cr?id=119683582', - 'cid': '9979', - 'crid': '119683582', - 'cat': [ - 'IAB3' - ], - 'w': 300, - 'h': 250, - 'ext': { - 'prebid': { - 'type': 'banner' - }, - 'bidder': { - 'ozone': {}, - 'appnexus': { - 'brand_id': 734921, - 'auction_id': 2995348111857539600, - 'bidder_id': 2, - 'bid_ad_type': 0 - } - } - }, - 'cpm': 0.2484, - 'bidId': '2d30e86db743a8', - 'requestId': '2d30e86db743a8', - 'width': 300, - 'height': 250, - 'ad': '', - 'netRevenue': true, - 'creativeId': '119683582', - 'currency': 'USD', - 'ttl': 300, - 'originalCpm': 0.2484, - 'originalCurrency': 'USD' - }, - { - 'id': '18552976939844681', - 'impid': '3025f169863b7f8', - 'price': 0.0621, - 'adm': '', - 'adid': '120179216', - 'adomain': [ - 'appnexus.com' - ], - 'iurl': 'https://ams1-ib.adnxs.com/cr?id=120179216', - 'cid': '9979', - 'crid': '120179216', - 'w': 970, - 'h': 250, - 'ext': { - 'prebid': { - 'type': 'banner' - }, - 'bidder': { - 'ozone': {}, - 'appnexus': { - 'brand_id': 1, - 'auction_id': 3449036134472542700, - 'bidder_id': 2, - 'bid_ad_type': 0 - } - } - }, - 'cpm': 0.0621, - 'bidId': '3025f169863b7f8', - 'requestId': '3025f169863b7f8', - 'width': 970, - 'height': 250, - 'ad': '', - 'netRevenue': true, - 'creativeId': '120179216', - 'currency': 'USD', - 'ttl': 300, - 'originalCpm': 0.0621, - 'originalCurrency': 'USD' - }, - { - 'id': '18552976939844999', - 'impid': '3025f169863b7f8', - 'price': 0.521, - 'adm': '', - 'adid': '120179216', - 'adomain': [ - 'appnexus.com' - ], - 'iurl': 'https://ams1-ib.adnxs.com/cr?id=120179216', - 'cid': '9999', - 'crid': '120179299', - 'w': 728, - 'h': 90, - 'ext': { - 'prebid': { - 'type': 'banner' - }, - 'bidder': { - 'ozone': {}, - 'appnexus': { - 'brand_id': 1, - 'auction_id': 3449036134472542700, - 'bidder_id': 2, - 'bid_ad_type': 0 - } - } - }, - 'cpm': 0.521, - 'bidId': '3025f169863b7f8', - 'requestId': '3025f169863b7f8', - 'width': 728, - 'height': 90, - 'ad': '', - 'netRevenue': true, - 'creativeId': '120179299', - 'currency': 'USD', - 'ttl': 300, - 'originalCpm': 0.0621, - 'originalCurrency': 'USD' - } - ], - 'seat': 'ozappnexus' - }, - { - 'bid': [ - { - 'id': '1c605e8a-4992-4ec6-8a5c-f82e2938c2db', - 'impid': '2d30e86db743a8', - 'price': 0.01, - 'adm': '
', - 'crid': '540463358', - 'w': 300, - 'h': 250, - 'ext': { - 'prebid': { - 'type': 'banner' - }, - 'bidder': { - 'ozone': {} - } - }, - 'cpm': 0.01, - 'bidId': '2d30e86db743a8', - 'requestId': '2d30e86db743a8', - 'width': 300, - 'height': 250, - 'ad': '
', - 'netRevenue': true, - 'creativeId': '540463358', - 'currency': 'USD', - 'ttl': 300, - 'originalCpm': 0.01, - 'originalCurrency': 'USD' - }, - { - 'id': '3edeb4f7-d91d-44e2-8aeb-4a2f6d295ce5', - 'impid': '3025f169863b7f8', - 'price': 0.01, - 'adm': '
', - 'crid': '540221061', - 'w': 970, - 'h': 250, - 'ext': { - 'prebid': { - 'type': 'banner' - }, - 'bidder': { - 'ozone': {} - } - }, - 'cpm': 0.01, - 'bidId': '3025f169863b7f8', - 'requestId': '3025f169863b7f8', - 'width': 970, - 'height': 250, - 'ad': '
', - 'netRevenue': true, - 'creativeId': '540221061', - 'currency': 'USD', - 'ttl': 300, - 'originalCpm': 0.01, - 'originalCurrency': 'USD' - } - ], - 'seat': 'openx' - } - ], - 'ext': { - 'debug': {}, - 'responsetimemillis': { - 'beeswax': 6, - 'openx': 91, - 'ozappnexus': 40, - 'ozbeeswax': 6 - } - } - }, - 'headers': {} -}; - -/* ---------------------end of 2 slots, 2 ---------------------------- - */ - -describe('ozone Adapter', function () { - describe('isBidRequestValid', function () { - // A test ad unit that will consistently return test creatives - let validBidReq = { - bidder: BIDDER_CODE, - params: { - placementId: '1310000099', - publisherId: '9876abcd12-3', - siteId: '1234567890' - } - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(validBidReq)).to.equal(true); - }); - - var validBidReq2 = { - - bidder: BIDDER_CODE, - params: { - placementId: '1310000099', - publisherId: '9876abcd12-3', - siteId: '1234567890', - customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}] - }, - siteId: 1234567890 - } - - it('should return true when required params found and all optional params are valid', function () { - expect(spec.isBidRequestValid(validBidReq2)).to.equal(true); - }); - - var xEmptyPlacement = { - bidder: BIDDER_CODE, - params: { - placementId: '', - publisherId: '9876abcd12-3', - siteId: '1234567890' - } - }; - - it('should not validate empty placementId', function () { - expect(spec.isBidRequestValid(xEmptyPlacement)).to.equal(false); - }); - - var xMissingPlacement = { - bidder: BIDDER_CODE, - params: { - publisherId: '9876abcd12-3', - siteId: '1234567890' - } - }; - - it('should not validate missing placementId', function () { - expect(spec.isBidRequestValid(xMissingPlacement)).to.equal(false); - }); - - var xBadPlacement = { - bidder: BIDDER_CODE, - params: { - placementId: '123X45', - publisherId: '9876abcd12-3', - siteId: '1234567890' - } - }; - - it('should not validate placementId with a non-numeric value', function () { - expect(spec.isBidRequestValid(xBadPlacement)).to.equal(false); - }); - - var xBadPlacementTooShort = { - bidder: BIDDER_CODE, - params: { - placementId: 123456789, /* should be exactly 10 chars */ - publisherId: '9876abcd12-3', - siteId: '1234567890' - } - }; - - it('should not validate placementId with a numeric value of wrong length', function () { - expect(spec.isBidRequestValid(xBadPlacementTooShort)).to.equal(false); - }); - - var xBadPlacementTooLong = { - bidder: BIDDER_CODE, - params: { - placementId: 12345678901, /* should be exactly 10 chars */ - publisherId: '9876abcd12-3', - siteId: '1234567890' - } - }; - - it('should not validate placementId with a numeric value of wrong length', function () { - expect(spec.isBidRequestValid(xBadPlacementTooLong)).to.equal(false); - }); - - var xMissingPublisher = { - bidder: BIDDER_CODE, - params: { - placementId: '1234567890', - siteId: '1234567890' - } - }; - - it('should not validate missing publisherId', function () { - expect(spec.isBidRequestValid(xMissingPublisher)).to.equal(false); - }); - - var xMissingSiteId = { - bidder: BIDDER_CODE, - params: { - publisherId: '9876abcd12-3', - placementId: '1234567890', - } - }; - - it('should not validate missing sitetId', function () { - expect(spec.isBidRequestValid(xMissingSiteId)).to.equal(false); - }); - - var xBadPublisherTooShort = { - bidder: BIDDER_CODE, - params: { - placementId: '1234567890', - publisherId: '9876abcd12a', - siteId: '1234567890' - } - }; - - it('should not validate publisherId being too short', function () { - expect(spec.isBidRequestValid(xBadPublisherTooShort)).to.equal(false); - }); - - var xBadPublisherTooLong = { - bidder: BIDDER_CODE, - params: { - placementId: '1234567890', - publisherId: '9876abcd12abc', - siteId: '1234567890' - } - }; - - it('should not validate publisherId being too long', function () { - expect(spec.isBidRequestValid(xBadPublisherTooLong)).to.equal(false); - }); - - var publisherNumericOk = { - bidder: BIDDER_CODE, - params: { - placementId: '1234567890', - publisherId: 123456789012, - siteId: '1234567890' - } - }; - - it('should validate publisherId being 12 digits', function () { - expect(spec.isBidRequestValid(publisherNumericOk)).to.equal(true); - }); - - var xEmptyPublisher = { - bidder: BIDDER_CODE, - params: { - placementId: '1234567890', - publisherId: '', - siteId: '1234567890' - } - }; - - it('should not validate empty publisherId', function () { - expect(spec.isBidRequestValid(xEmptyPublisher)).to.equal(false); - }); - - var xBadSite = { - bidder: BIDDER_CODE, - params: { - placementId: '1234567890', - publisherId: '9876abcd12-3', - siteId: '12345Z' - } - }; - - it('should not validate bad siteId', function () { - expect(spec.isBidRequestValid(xBadSite)).to.equal(false); - }); - - var xBadSiteTooLong = { - bidder: BIDDER_CODE, - params: { - placementId: '1234567890', - publisherId: '9876abcd12-3', - siteId: '12345678901' - } - }; - - it('should not validate siteId too long', function () { - expect(spec.isBidRequestValid(xBadSite)).to.equal(false); - }); - - var xBadSiteTooShort = { - bidder: BIDDER_CODE, - params: { - placementId: '1234567890', - publisherId: '9876abcd12-3', - siteId: '123456789' - } - }; - - it('should not validate siteId too short', function () { - expect(spec.isBidRequestValid(xBadSite)).to.equal(false); - }); - - var allNonStrings = { - bidder: BIDDER_CODE, - params: { - placementId: 1234567890, - publisherId: '9876abcd12-3', - siteId: 1234567890 - } - }; - - it('should validate all numeric values being sent as non-string numbers', function () { - expect(spec.isBidRequestValid(allNonStrings)).to.equal(true); - }); - - var emptySiteId = { - bidder: BIDDER_CODE, - params: { - placementId: 1234567890, - publisherId: '9876abcd12-3', - siteId: '' - } - }; - - it('should not validate siteId being empty string (it is required now)', function () { - expect(spec.isBidRequestValid(emptySiteId)).to.equal(false); - }); - - var xBadCustomData = { - bidder: BIDDER_CODE, - params: { - 'placementId': '1234567890', - 'publisherId': '9876abcd12-3', - 'siteId': '1234567890', - 'customData': 'this aint gonna work' - } - }; - - it('should not validate customData not being an array', function () { - expect(spec.isBidRequestValid(xBadCustomData)).to.equal(false); - }); - - var xBadCustomData_OLD_CUSTOMDATA_VALUE = { - bidder: BIDDER_CODE, - params: { - 'placementId': '1234567890', - 'publisherId': '9876abcd12-3', - 'siteId': '1234567890', - 'customData': {'gender': 'bart', 'age': 'low'} - } - }; - - it('should not validate customData being an object, not an array', function () { - expect(spec.isBidRequestValid(xBadCustomData_OLD_CUSTOMDATA_VALUE)).to.equal(false); - }); - - var xBadCustomData_zerocd = { - bidder: BIDDER_CODE, - params: { - 'placementId': '1111111110', - 'publisherId': '9876abcd12-3', - 'siteId': '1234567890', - 'customData': [] - } - }; - - it('should not validate customData array having no elements', function () { - expect(spec.isBidRequestValid(xBadCustomData_zerocd)).to.equal(false); - }); - - var xBadCustomData_notargeting = { - bidder: BIDDER_CODE, - params: { - 'placementId': '1234567890', - 'publisherId': '9876abcd12-3', - 'customData': [{'settings': {}, 'xx': {'gender': 'bart', 'age': 'low'}}], - siteId: '1234567890' - } - }; - it('should not validate customData[] having no "targeting"', function () { - expect(spec.isBidRequestValid(xBadCustomData_notargeting)).to.equal(false); - }); - - var xBadCustomData_tgt_not_obj = { - bidder: BIDDER_CODE, - params: { - 'placementId': '1234567890', - 'publisherId': '9876abcd12-3', - 'customData': [{'settings': {}, 'targeting': 'this should be an object'}], - siteId: '1234567890' - } - }; - it('should not validate customData[0].targeting not being an object', function () { - expect(spec.isBidRequestValid(xBadCustomData_tgt_not_obj)).to.equal(false); - }); - - var xBadCustomParams = { - bidder: BIDDER_CODE, - params: { - 'placementId': '1234567890', - 'publisherId': '9876abcd12-3', - 'siteId': '1234567890', - 'customParams': 'this key is no longer valid' - } - }; - it('should not validate customParams - this is a renamed key', function () { - expect(spec.isBidRequestValid(xBadCustomParams)).to.equal(false); - }); - var xBadVideoContext2 = { - bidder: BIDDER_CODE, - params: { - 'placementId': '1234567890', - 'publisherId': '9876abcd12-3', - siteId: '1234567890' - }, - mediaTypes: { - video: { - mimes: ['video/mp4']} - } - }; - - it('should not validate video without context attribute', function () { - expect(spec.isBidRequestValid(xBadVideoContext2)).to.equal(false); - }); - - let validVideoBidReq = { - bidder: BIDDER_CODE, - params: { - placementId: '1310000099', - publisherId: '9876abcd12-3', - siteId: '1234567890' - }, - mediaTypes: { - video: { - mimes: ['video/mp4'], - 'context': 'outstream'}, - } - }; - - it('should validate video outstream being sent', function () { - expect(spec.isBidRequestValid(validVideoBidReq)).to.equal(true); - }); - it('should validate video instream being sent even though its not properly supported yet', function () { - let instreamVid = JSON.parse(JSON.stringify(validVideoBidReq)); - instreamVid.mediaTypes.video.context = 'instream'; - expect(spec.isBidRequestValid(instreamVid)).to.equal(true); - }); - }); - - describe('buildRequests', function () { - it('sends bid request to OZONEURI via POST', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - expect(request.url).to.equal(OZONEURI); - expect(request.method).to.equal('POST'); - }); - - it('sends data as a string', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - expect(request.data).to.be.a('string'); - }); - - it('sends all bid parameters', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']); - }); - - it('adds all parameters inside the ext object only', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - expect(request.data).to.be.a('string'); - var data = JSON.parse(request.data); - expect(data.imp[0].ext.ozone.customData).to.be.an('array'); - expect(request).not.to.have.key('lotameData'); - expect(request).not.to.have.key('customData'); - }); - - it('adds all parameters inside the ext object only - lightning', function () { - let localBidReq = JSON.parse(JSON.stringify(validBidRequests)); - const request = spec.buildRequests(localBidReq, validBidderRequest.bidderRequest); - expect(request.data).to.be.a('string'); - var data = JSON.parse(request.data); - expect(data.imp[0].ext.ozone.customData).to.be.an('array'); - expect(request).not.to.have.key('lotameData'); - expect(request).not.to.have.key('customData'); - }); - - it('ignores ozoneData in & after version 2.1.1', function () { - let 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'}; - const request = spec.buildRequests(validBidRequestsWithOzoneData, validBidderRequest.bidderRequest); - expect(request.data).to.be.a('string'); - var data = JSON.parse(request.data); - expect(data.imp[0].ext.ozone.customData).to.be.an('array'); - expect(data.imp[0].ext.ozone.ozoneData).to.be.undefined; - expect(request).not.to.have.key('lotameData'); - expect(request).not.to.have.key('customData'); - }); - - it('has correct bidder', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - expect(request.bidderRequest.bids[0].bidder).to.equal(BIDDER_CODE); - }); - - it('handles mediaTypes element correctly', function () { - const request = spec.buildRequests(validBidRequestsWithBannerMediaType, validBidderRequest.bidderRequest); - expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']); - }); - - it('handles no ozone or custom data', function () { - const request = spec.buildRequests(validBidRequestsMinimal, validBidderRequest.bidderRequest); - expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']); - }); - - it('handles video mediaType element correctly, with outstream video', function () { - const request = spec.buildRequests(validBidRequests1OutstreamVideo2020, validBidderRequest.bidderRequest); - expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']); - }); - - it('should not crash when there is no sizes element at all', function () { - const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest); - 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}}); - const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest); - expect(request).to.be.a('array'); - expect(request[0]).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']); - // need to reset the singleRequest config flag: - config.setConfig({'ozone': {'singleRequest': true}}); - }); - - it('should add gdpr consent information to the request when ozone is true', function () { - let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; - let bidderRequest = validBidderRequest.bidderRequest; - bidderRequest.gdprConsent = { - consentString: consentString, - gdprApplies: true, - vendorData: { - metadata: consentString, - gdprApplies: true, - vendorConsents: {524: true}, - purposeConsents: {1: true, 2: true, 3: true, 4: true, 5: true} - } - } - - const request = spec.buildRequests(validBidRequestsNoSizes, bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.regs.ext.gdpr).to.equal(1); - expect(payload.user.ext.consent).to.equal(consentString); - }); - - // mirror - it('should add gdpr consent information to the request when vendorData is missing vendorConsents (Mirror)', function () { - let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; - let bidderRequest = validBidderRequest.bidderRequest; - bidderRequest.gdprConsent = { - consentString: consentString, - gdprApplies: true, - vendorData: { - metadata: consentString, - gdprApplies: true - } - } - - const request = spec.buildRequests(validBidRequestsNoSizes, bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.regs.ext.gdpr).to.equal(1); - expect(payload.user.ext.consent).to.equal(consentString); - }); - - it('should set regs.ext.gdpr flag to 0 when gdprApplies is false', function () { - let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; - let bidderRequest = validBidderRequest.bidderRequest; - bidderRequest.gdprConsent = { - consentString: consentString, - gdprApplies: false, - vendorData: { - metadata: consentString, - gdprApplies: true, - vendorConsents: {}, /* 524 is not present */ - purposeConsents: {1: true, 2: true, 3: true, 4: true, 5: true} - } - }; - - const request = spec.buildRequests(validBidRequestsNoSizes, bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.regs.ext.gdpr).to.equal(0); - }); - - it('should not have imp[N].ext.ozone.userId', function () { - let consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; - let bidderRequest = validBidderRequest.bidderRequest; - bidderRequest.gdprConsent = { - consentString: consentString, - gdprApplies: false, - vendorData: { - metadata: consentString, - gdprApplies: true, - vendorConsents: {524: true}, - purposeConsents: {1: true, 2: true, 3: true, 4: true, 5: true} - } - }; - - let bidRequests = validBidRequests; - // values from http://prebid.org/dev-docs/modules/userId.html#pubcommon-id - bidRequests[0]['userId'] = { - 'criteortus': '1111', - 'digitrustid': {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}}, - 'id5id': '2222', - 'idl_env': '3333', - 'lipb': {'lipbid': '4444'}, - 'parrableid': 'eidVersion.encryptionKeyReference.encryptedValue', - 'pubcid': '5555', - 'tdid': '6666' - }; - bidRequests[0]['userIdAsEids'] = validBidRequestsWithUserIdData[0]['userIdAsEids']; - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - let firstBid = payload.imp[0].ext.ozone; - expect(firstBid).to.not.have.property('userId'); - delete validBidRequests[0].userId; // tidy up now, else it will screw with other tests - }); - - it('should pick up the value of pubcid when built using the pubCommonId module (not userId)', function () { - let bidRequests = validBidRequests; - // values from http://prebid.org/dev-docs/modules/userId.html#pubcommon-id - bidRequests[0]['userId'] = { - 'criteortus': '1111', - 'digitrustid': {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}}, - 'id5id': '2222', - 'idl_env': '3333', - 'lipb': {'lipbid': '4444'}, - 'parrableid': 'eidVersion.encryptionKeyReference.encryptedValue', - // 'pubcid': '5555', // remove pubcid from here to emulate the OLD module & cause the failover code to kick in - 'tdid': '6666' - }; - bidRequests[0]['userIdAsEids'] = validBidRequestsWithUserIdData[0]['userIdAsEids']; - const request = spec.buildRequests(bidRequests, validBidderRequest.bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.ext.ozone.pubcid).to.equal(bidRequests[0]['crumbs']['pubcid']); - delete validBidRequests[0].userId; // tidy up now, else it will screw with other tests - }); - - it('should add a user.ext.eids object to contain user ID data in the new location (Nov 2019) Updated Aug 2020', function() { - const request = spec.buildRequests(validBidRequestsWithUserIdData, validBidderRequest.bidderRequest); - /* - 'pubcid': '12345678', - 'tdid': '1111tdid', - 'id5id': 'ID5-someId', - 'criteortus': {'ozone': {'userid': 'critId123'}}, - 'criteoId': '1111criteoId', - 'idl_env': 'liverampId', - 'lipb': {'lipbid': 'lipbidId123'}, - 'parrableId': {'eid': '01.5678.parrableid'} - */ - - const payload = JSON.parse(request.data); - expect(payload.user).to.exist; - expect(payload.user.ext).to.exist; - expect(payload.user.ext.eids).to.exist; - expect(payload.user.ext.eids[0]['source']).to.equal('pubcid.org'); - expect(payload.user.ext.eids[0]['uids'][0]['id']).to.equal('12345678'); - expect(payload.user.ext.eids[1]['source']).to.equal('adserver.org'); - expect(payload.user.ext.eids[1]['uids'][0]['id']).to.equal('1111tdid'); - expect(payload.user.ext.eids[2]['source']).to.equal('id5-sync.com'); - expect(payload.user.ext.eids[2]['uids'][0]['id']).to.equal('ID5-someId'); - expect(payload.user.ext.eids[3]['source']).to.equal('criteortus'); // this is deprecated - expect(payload.user.ext.eids[3]['uids'][0]['id']['ozone']['userid']).to.equal('critId123'); - expect(payload.user.ext.eids[4]['source']).to.equal('criteoId'); - expect(payload.user.ext.eids[4]['uids'][0]['id']).to.equal('1111criteoId'); - expect(payload.user.ext.eids[5]['source']).to.equal('idl_env'); - expect(payload.user.ext.eids[5]['uids'][0]['id']).to.equal('liverampId'); - expect(payload.user.ext.eids[6]['source']).to.equal('lipb'); - expect(payload.user.ext.eids[6]['uids'][0]['id']['lipbid']).to.equal('lipbidId123'); - expect(payload.user.ext.eids[7]['source']).to.equal('parrableId'); - expect(payload.user.ext.eids[7]['uids'][0]['id']['eid']).to.equal('01.5678.parrableid'); - }); - - it('replaces the auction url for a config override', function () { - spec.propertyBag.whitelabel = null; - let fakeOrigin = 'http://sometestendpoint'; - config.setConfig({'ozone': {'endpointOverride': {'origin': fakeOrigin}}}); - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - expect(request.url).to.equal(fakeOrigin + '/openrtb2/auction'); - expect(request.method).to.equal('POST'); - config.setConfig({'ozone': {'kvpPrefix': null, 'endpointOverride': null}}); - spec.propertyBag.whitelabel = null; - }); - - it('replaces the renderer url for a config override', function () { - spec.propertyBag.whitelabel = null; - let fakeUrl = 'http://renderer.com'; - config.setConfig({'ozone': {'endpointOverride': {'rendererUrl': fakeUrl}}}); - const request = spec.buildRequests(validBidRequests1OutstreamVideo2020, validBidderRequest1OutstreamVideo2020.bidderRequest); - 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}}); - spec.propertyBag.whitelabel = null; - }); - - it('replaces the kvp prefix ', function () { - spec.propertyBag.whitelabel = null; - config.setConfig({'ozone': {'kvpPrefix': 'test'}}); - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const data = JSON.parse(request.data); - expect(data.ext.ozone).to.haveOwnProperty('test_rw'); - config.setConfig({'ozone': {'kvpPrefix': null}}); - spec.propertyBag.whitelabel = null; - }); - - it('handles an alias ', function () { - spec.propertyBag.whitelabel = null; - config.setConfig({'lmc': {'kvpPrefix': 'test'}}); - let br = JSON.parse(JSON.stringify(validBidRequests)); - br[0]['bidder'] = 'lmc'; - const request = spec.buildRequests(br, validBidderRequest.bidderRequest); - const data = JSON.parse(request.data); - expect(data.ext.lmc).to.haveOwnProperty('test_rw'); - config.setConfig({'lmc': {'kvpPrefix': null}}); // I cant remove the key so set the value to null - spec.propertyBag.whitelabel = null; - }); - var specMock = utils.deepClone(spec); - it('should use oztestmode GET value if set', function() { - // mock the getGetParametersAsObject function to simulate GET parameters for oztestmode: - specMock.getGetParametersAsObject = function() { - return {'oztestmode': 'mytestvalue_123'}; - }; - const request = specMock.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const data = JSON.parse(request.data); - expect(data.imp[0].ext.ozone.customData).to.be.an('array'); - expect(data.imp[0].ext.ozone.customData[0].targeting.oztestmode).to.equal('mytestvalue_123'); - }); - it('should use oztestmode GET value if set, even if there is no customdata in config', function() { - // mock the getGetParametersAsObject function to simulate GET parameters for oztestmode: - specMock.getGetParametersAsObject = function() { - return {'oztestmode': 'mytestvalue_123'}; - }; - const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest.bidderRequest); - const data = JSON.parse(request.data); - expect(data.imp[0].ext.ozone.customData).to.be.an('array'); - expect(data.imp[0].ext.ozone.customData[0].targeting.oztestmode).to.equal('mytestvalue_123'); - }); - it('should use a valid ozstoredrequest GET value if set to override the placementId values, and set oz_rw if we find it', function() { - // mock the getGetParametersAsObject function to simulate GET parameters for ozstoredrequest: - specMock.getGetParametersAsObject = function() { - return {'ozstoredrequest': '1122334455'}; // 10 digits are valid - }; - const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest.bidderRequest); - const data = JSON.parse(request.data); - expect(data.ext.ozone.oz_rw).to.equal(1); - expect(data.imp[0].ext.prebid.storedrequest.id).to.equal('1122334455'); - }); - it('should NOT use an invalid ozstoredrequest GET value if set to override the placementId values, and set oz_rw to 0', function() { - // mock the getGetParametersAsObject function to simulate GET parameters for ozstoredrequest: - specMock.getGetParametersAsObject = function() { - return {'ozstoredrequest': 'BADVAL'}; // 10 digits are valid - }; - const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest.bidderRequest); - const data = JSON.parse(request.data); - expect(data.ext.ozone.oz_rw).to.equal(0); - 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}); - const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.regs).to.include.keys('coppa'); - expect(payload.regs.coppa).to.equal(1); - 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}); - const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest); - 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}}); - const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest); - 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'}}); - const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest.bidderRequest); - const payload = JSON.parse(request.data); - expect(utils.deepAccess(payload, 'ext.ozone.oz_omp_floor')).to.be.undefined; - config.resetConfig(); - }); - it('should should contain a unique page view id in the auction request which persists across calls', function () { - let request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - let payload = JSON.parse(request.data); - expect(utils.deepAccess(payload, 'ext.ozone.pv')).to.be.a('string'); - request = spec.buildRequests(validBidRequests1OutstreamVideo2020, validBidderRequest.bidderRequest); - let payload2 = JSON.parse(request.data); - expect(utils.deepAccess(payload2, 'ext.ozone.pv')).to.be.a('string'); - 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']}}); - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.ext.ozone.oz_kvp_rw).to.equal(1); - config.resetConfig(); - }); - it('should indicate that the whitelist was not used when it contains no data', function () { - config.setConfig({'ozone': {'oz_whitelist_adserver_keys': []}}); - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.ext.ozone.oz_kvp_rw).to.equal(0); - config.resetConfig(); - }); - it('should indicate that the whitelist was not used when it is not set in the config', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const payload = JSON.parse(request.data); - expect(payload.ext.ozone.oz_kvp_rw).to.equal(0); - }); - it('should have openrtb video params', function() { - let allowed = ['mimes', 'minduration', 'maxduration', 'protocols', 'w', 'h', 'startdelay', 'placement', 'linearity', 'skip', 'skipmin', 'skipafter', 'sequence', 'battr', 'maxextended', 'minbitrate', 'maxbitrate', 'boxingallowed', 'playbackmethod', 'playbackend', 'delivery', 'pos', 'companionad', 'api', 'companiontype', 'ext']; - const request = spec.buildRequests(validBidRequests1OutstreamVideo2020, validBidderRequest.bidderRequest); - const payload = JSON.parse(request.data); - const vid = (payload.imp[0].video); - const keys = Object.keys(vid); - for (let i = 0; i < keys.length; i++) { - expect(allowed).to.include(keys[i]); - } - expect(payload.imp[0].video.ext).to.include({'context': 'outstream'}); - }); - }); - - describe('interpretResponse', function () { - it('should build bid array', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const result = spec.interpretResponse(validResponse, request); - expect(result.length).to.equal(1); - }); - - it('should have all relevant fields', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const result = spec.interpretResponse(validResponse, request); - const bid = result[0]; - expect(bid.cpm).to.equal(validResponse.body.seatbid[0].bid[0].cpm); - expect(bid.width).to.equal(validResponse.body.seatbid[0].bid[0].width); - expect(bid.height).to.equal(validResponse.body.seatbid[0].bid[0].height); - }); - - it('should build bid array with gdpr', function () { - let validBR = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr.bidderRequest)); - validBR.gdprConsent = {'gdprApplies': 1, 'consentString': 'This is the gdpr consent string'}; - const request = spec.buildRequests(validBidRequests, validBR); // works the old way, with GDPR not enforced by default - const result = spec.interpretResponse(validResponse, request); - expect(result.length).to.equal(1); - }); - - 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'}; - const request = spec.buildRequests(validBidRequests, validBidderRequestWithGdpr); - }); - - it('should fail ok if no seatbid in server response', function () { - const result = spec.interpretResponse({}, {}); - expect(result).to.be.an('array'); - expect(result).to.be.empty; - }); - - it('should fail ok if seatbid is not an array', function () { - const result = spec.interpretResponse({'body': {'seatbid': 'nothing_here'}}, {}); - expect(result).to.be.an('array'); - expect(result).to.be.empty; - }); - - it('should have video renderer for outstream video', function () { - const request = spec.buildRequests(validBidRequests1OutstreamVideo2020, validBidderRequest1OutstreamVideo2020.bidderRequest); - const result = spec.interpretResponse(getCleanValidVideoResponse(), validBidderRequest1OutstreamVideo2020); - const bid = result[0]; - expect(bid.renderer).to.be.an.instanceOf(Renderer); - }); - - it('should have NO video renderer for instream video', function () { - let instreamRequestsObj = JSON.parse(JSON.stringify(validBidRequests1OutstreamVideo2020)); - instreamRequestsObj[0].mediaTypes.video.context = 'instream'; - let instreamBidderReq = JSON.parse(JSON.stringify(validBidderRequest1OutstreamVideo2020)); - instreamBidderReq.bidderRequest.bids[0].mediaTypes.video.context = 'instream'; - const request = spec.buildRequests(instreamRequestsObj, validBidderRequest1OutstreamVideo2020.bidderRequest); - const result = spec.interpretResponse(getCleanValidVideoResponse(), instreamBidderReq); - const bid = result[0]; - expect(bid.hasOwnProperty('renderer')).to.be.false; - }); - - it('should correctly parse response where there are more bidders than ad slots', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const result = spec.interpretResponse(validBidResponse1adWith2Bidders, request); - expect(result.length).to.equal(2); - }); - - it('should have a ttl of 600', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const result = spec.interpretResponse(validResponse, request); - 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}}); - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const result = spec.interpretResponse(validResponse, request); - expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_omp')).to.equal('1'); - config.resetConfig(); - }); - it('should handle oz_omp_floor_dollars correctly, inserting 0 as necessary', function () { - config.setConfig({'ozone': {'oz_omp_floor': 2.50}}); - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const result = spec.interpretResponse(validResponse, request); - expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_omp')).to.equal('0'); - config.resetConfig(); - }); - it('should handle missing oz_omp_floor_dollars correctly, inserting nothing', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - const result = spec.interpretResponse(validResponse, request); - expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_omp')).to.be.undefined; - }); - it('should handle ext.bidder.ozone.floor correctly, setting flr & rid as necessary', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - let vres = JSON.parse(JSON.stringify(validResponse)); - 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'); - config.resetConfig(); - }); - it('should handle ext.bidder.ozone.floor correctly, inserting 0 as necessary', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - let vres = JSON.parse(JSON.stringify(validResponse)); - 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'); - config.resetConfig(); - }); - it('should handle ext.bidder.ozone.floor correctly, inserting nothing as necessary', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - let vres = JSON.parse(JSON.stringify(validResponse)); - vres.body.seatbid[0].bid[0].ext.bidder.ozone = {}; - const result = spec.interpretResponse(vres, request); - expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_flr', null)).to.equal(null); - expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_rid', null)).to.equal(null); - config.resetConfig(); - }); - it('should handle ext.bidder.ozone.floor correctly, when bidder.ozone is not there', function () { - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - let vres = JSON.parse(JSON.stringify(validResponse)); - const result = spec.interpretResponse(vres, request); - expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_flr', null)).to.equal(null); - expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_rid', null)).to.equal(null); - config.resetConfig(); - }); - 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']}}); - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - 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-0'); - config.resetConfig(); - }); - 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}}); - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - 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; - config.resetConfig(); - }); - it('should correctly handle enhancedAdserverTargeting being false', function () { - config.setConfig({'ozone': {'enhancedAdserverTargeting': false}}); - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - 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; - config.resetConfig(); - }); - it('should add flr into ads request if floor exists in the auction response', function () { - const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest.bidderRequest); - let validres = JSON.parse(JSON.stringify(validResponse2Bids)); - 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(''); - }); - it('should add rid into ads request if ruleId exists in the auction response', function () { - const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest.bidderRequest); - let validres = JSON.parse(JSON.stringify(validResponse2Bids)); - 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(''); - }); - it('should add oz_ozappnexus_sid (cid value) for all appnexus bids', function () { - const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest.bidderRequest); - let validres = JSON.parse(JSON.stringify(validResponse2BidsSameAdunit)); - const result = spec.interpretResponse(validres, request); - expect(utils.deepAccess(result[0].adserverTargeting, 'oz_ozappnexus_sid')).to.equal(result[0].cid); - }); - it('should add unique adId values to each bid', function() { - const request = spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - let validres = JSON.parse(JSON.stringify(validResponse2BidsSameAdunit)); - const result = spec.interpretResponse(validres, request); - expect(result.length).to.equal(1); - expect(result[0]['price']).to.equal(0.9); - expect(result[0]['adserverTargeting']['oz_ozappnexus_adId']).to.equal('2899ec066a91ff8-0-1'); - }); - it('should correctly process an auction with 2 adunits & multiple bidders one of which bids for both adslots', function() { - let validres = JSON.parse(JSON.stringify(multiResponse1)); - let request = spec.buildRequests(multiRequest1, multiBidderRequest1.bidderRequest); - let result = spec.interpretResponse(validres, request); - expect(result.length).to.equal(4); // one of the 5 bids will have been removed - expect(result[1]['price']).to.equal(0.521); - expect(result[1]['impid']).to.equal('3025f169863b7f8'); - expect(result[1]['id']).to.equal('18552976939844999'); - expect(result[1]['adserverTargeting']['oz_ozappnexus_adId']).to.equal('3025f169863b7f8-0-2'); - // change the bid values so a different second bid for an impid by the same bidder gets dropped - validres = JSON.parse(JSON.stringify(multiResponse1)); - validres.body.seatbid[0].bid[1].price = 1.1; - validres.body.seatbid[0].bid[1].cpm = 1.1; - request = spec.buildRequests(multiRequest1, multiBidderRequest1.bidderRequest); - result = spec.interpretResponse(validres, request); - expect(result[1]['price']).to.equal(1.1); - expect(result[1]['impid']).to.equal('3025f169863b7f8'); - expect(result[1]['id']).to.equal('18552976939844681'); - expect(result[1]['adserverTargeting']['oz_ozappnexus_adId']).to.equal('3025f169863b7f8-0-1'); - }); - }); - - describe('userSyncs', function () { - it('should fail gracefully if no server response', function () { - const result = spec.getUserSyncs('bad', false, gdpr1); - expect(result).to.be.empty; - }); - it('should fail gracefully if server response is empty', function () { - const result = spec.getUserSyncs('bad', [], gdpr1); - expect(result).to.be.empty; - }); - it('should append the various values if they exist', function() { - // get the cookie bag populated - spec.buildRequests(validBidRequests, validBidderRequest.bidderRequest); - 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'); - expect(result[0].url).to.include('gdpr=1'); - expect(result[0].url).to.include('gdpr_consent=BOh7mtYOh7mtYAcABBENCU-AAAAncgPIXJiiAoao0PxBFkgCAC8ACIAAQAQQAAIAAAIAAAhBGAAAQAQAEQgAAAAAAABAAAAAAAAAAAAAAACAAAAAAAACgAAAAABAAAAQAAAAAAA'); - }); - }); - - describe('video object utils', function () { - it('should find width & height from video object', function () { - let 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 () { - let 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 () { - let obj = {'mimes': ['video/mp4'], 'context': 'outstream'}; - const result = getWidthAndHeightFromVideoObject(obj); - expect(result).to.be.null; - }); - it('should find null from bad video object3', function () { - let 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 () { - let 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 () { - let obj = {'playerSize': [[[640, 480]]], 'mimes': ['video/mp4'], 'context': 'outstream'}; - const result = getWidthAndHeightFromVideoObject(obj); - expect(result).to.be.null; - }); - it('should find that player size is nested', function () { - let obj = {'playerSize': [[640, 480]], 'mimes': ['video/mp4'], 'context': 'outstream'}; - const result = playerSizeIsNestedArray(obj); - expect(result).to.be.true; - }); - it('should find null from bad video object', function () { - let obj = {'playerSize': [], 'mimes': ['video/mp4'], 'context': 'outstream'}; - const result = playerSizeIsNestedArray(obj); - expect(result).to.be.null; - }); - it('should find null from bad video object2', function () { - let obj = {'mimes': ['video/mp4'], 'context': 'outstream'}; - const result = playerSizeIsNestedArray(obj); - expect(result).to.be.null; - }); - it('should find null from bad video object3', function () { - let obj = {'playerSize': 'should be an array', 'mimes': ['video/mp4'], 'context': 'outstream'}; - const result = playerSizeIsNestedArray(obj); - expect(result).to.be.null; - }); - it('should add oz_appnexus_dealid into ads request if dealid exists in the auction response', function () { - const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest.bidderRequest); - let validres = JSON.parse(JSON.stringify(validResponse2Bids)); - validres.body.seatbid[0].bid[0].dealid = '1234'; - const result = spec.interpretResponse(validres, request); - expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_dealid')).to.equal('1234'); - expect(utils.deepAccess(result[1].adserverTargeting, 'oz_appnexus_dealid', '')).to.equal(''); - }); - }); - - describe('default size', function () { - it('should should return default sizes if no obj is sent', function () { - let obj = ''; - const result = defaultSize(obj); - expect(result.defaultHeight).to.equal(250); - expect(result.defaultWidth).to.equal(300); - }); - }); - - describe('getGranularityKeyName', function() { - it('should return a string granularity as-is', function() { - const result = getGranularityKeyName('', 'this is it', ''); - expect(result).to.equal('this is it'); - }); - it('should return "custom" for a mediaTypeGranularity object', function() { - const result = getGranularityKeyName('', {}, ''); - expect(result).to.equal('custom'); - }); - it('should return "custom" for a mediaTypeGranularity object', function() { - const result = getGranularityKeyName('', false, 'string buckets'); - expect(result).to.equal('string buckets'); - }); - }); - - describe('getGranularityObject', function() { - it('should return an object as-is', function() { - const result = getGranularityObject('', {'name': 'mark'}, '', ''); - expect(result.name).to.equal('mark'); - }); - it('should return an object as-is', function() { - const result = getGranularityObject('', false, 'custom', {'name': 'rupert'}); - expect(result.name).to.equal('rupert'); - }); - }); - - describe('blockTheRequest', function() { - it('should return true if oz_request is false', function() { - config.setConfig({'ozone': {'oz_request': false}}); - let result = spec.blockTheRequest(bidderRequestWithFullGdpr); - expect(result).to.be.true; - config.resetConfig(); - }); - it('should return false if oz_request is true', function() { - config.setConfig({'ozone': {'oz_request': true}}); - let result = spec.blockTheRequest(bidderRequestWithFullGdpr); - expect(result).to.be.false; - config.resetConfig(); - }); - }); - describe('getPageId', function() { - it('should return the same Page ID for multiple calls', function () { - let result = spec.getPageId(); - expect(result).to.be.a('string'); - let result2 = spec.getPageId(); - expect(result2).to.equal(result); - }); - }); - describe('getBidRequestForBidId', function() { - it('should locate a bid inside a bid array', function () { - let result = spec.getBidRequestForBidId('2899ec066a91ff8', validBidRequestsMulti); - expect(result.testId).to.equal(1); - result = spec.getBidRequestForBidId('2899ec066a91ff0', validBidRequestsMulti); - expect(result.testId).to.equal(2); - }); - }); - describe('getVideoContextForBidId', function() { - it('should locate the video context inside a bid', function () { - let result = spec.getVideoContextForBidId('2899ec066a91ff8', validBidRequestsWithNonBannerMediaTypesAndValidOutstreamVideo); - expect(result).to.equal('outstream'); - }); - }); - describe('unpackVideoConfigIntoIABformat', function() { - it('should correctly unpack a usual video config', function () { - let mediaTypes = { - playerSize: [640, 480], - mimes: ['video/mp4'], - context: 'outstream', - testKey: 'parent value' - }; - let bid_params_video = { - skippable: true, - playback_method: ['auto_play_sound_off'], - playbackmethod: 2, /* start on load, no sound */ - minduration: 5, - maxduration: 60, - skipmin: 5, - skipafter: 5, - testKey: 'child value' - }; - let result = spec.unpackVideoConfigIntoIABformat(mediaTypes, bid_params_video); - expect(result.mimes).to.be.an('array').that.includes('video/mp4'); - expect(result.ext.context).to.equal('outstream'); - expect(result.ext.skippable).to.be.true; // note - we add skip in a different step: addVideoDefaults - expect(result.ext.testKey).to.equal('child value'); - }); - }); - describe('addVideoDefaults', function() { - it('should correctly add video defaults', function () { - let mediaTypes = { - playerSize: [640, 480], - mimes: ['video/mp4'], - context: 'outstream', - }; - let bid_params_video = { - skippable: true, - playback_method: ['auto_play_sound_off'], - playbackmethod: 2, /* start on load, no sound */ - minduration: 5, - maxduration: 60, - skipmin: 5, - skipafter: 5, - testKey: 'child value' - }; - let result = spec.addVideoDefaults({}, mediaTypes, mediaTypes); - expect(result.placement).to.equal(3); - expect(result.skip).to.equal(0); - result = spec.addVideoDefaults({}, mediaTypes, bid_params_video); - expect(result.skip).to.equal(1); - }); - it('should correctly add video defaults including skippable in parent', function () { - let mediaTypes = { - playerSize: [640, 480], - mimes: ['video/mp4'], - context: 'outstream', - skippable: true - }; - let bid_params_video = { - playback_method: ['auto_play_sound_off'], - playbackmethod: 2, /* start on load, no sound */ - minduration: 5, - maxduration: 60, - skipmin: 5, - skipafter: 5, - testKey: 'child value' - }; - let result = spec.addVideoDefaults({}, mediaTypes, bid_params_video); - expect(result.placement).to.equal(3); - expect(result.skip).to.equal(1); - }); - }); - describe('removeSingleBidderMultipleBids', function() { - it('should remove the multi bid by ozappnexus for adslot 2d30e86db743a8', function() { - let validres = JSON.parse(JSON.stringify(multiResponse1)); - expect(validres.body.seatbid[0].bid.length).to.equal(3); - expect(validres.body.seatbid[0].seat).to.equal('ozappnexus'); - let response = spec.removeSingleBidderMultipleBids(validres.body.seatbid); - expect(response.length).to.equal(2); - expect(response[0].bid.length).to.equal(2); - expect(response[0].seat).to.equal('ozappnexus'); - expect(response[1].bid.length).to.equal(2); - }); - }); -}); diff --git a/test/spec/modules/padsquadBidAdapter_spec.js b/test/spec/modules/padsquadBidAdapter_spec.js deleted file mode 100644 index 7d0858ed25e..00000000000 --- a/test/spec/modules/padsquadBidAdapter_spec.js +++ /dev/null @@ -1,262 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/padsquadBidAdapter.js'; - -const REQUEST = { - 'bidderCode': 'padsquad', - 'auctionId': 'auctionId-56a2-4f71-9098-720a68f2f708', - 'bidderRequestId': 'requestId', - 'bidRequest': [{ - 'bidder': 'padsquad', - 'params': { - 'unitId': 123456, - }, - 'placementCode': 'div-gpt-dummy-placement-code', - 'sizes': [ - [300, 250] - ], - 'bidId': 'bidId1', - 'bidderRequestId': 'bidderRequestId', - 'auctionId': 'auctionId-56a2-4f71-9098-720a68f2f708' - }, - { - 'bidder': 'padsquad', - 'params': { - 'unitId': 123456, - }, - 'placementCode': 'div-gpt-dummy-placement-code', - 'sizes': [ - [300, 250] - ], - 'bidId': 'bidId2', - 'bidderRequestId': 'bidderRequestId', - 'auctionId': 'auctionId-56a2-4f71-9098-720a68f2f708' - }], - 'start': 1487883186070, - 'auctionStart': 1487883186069, - 'timeout': 3000 -}; - -const RESPONSE = { - 'headers': null, - 'body': { - 'id': 'responseId', - 'seatbid': [ - { - 'bid': [ - { - 'id': 'bidId1', - 'impid': 'bidId1', - 'price': 0.18, - 'adm': '', - 'adid': '144762342', - 'adomain': [ - 'https://dummydomain.com' - ], - 'iurl': 'iurl', - 'cid': '109', - 'crid': 'creativeId', - 'cat': [], - 'w': 300, - 'h': 250, - 'ext': { - 'prebid': { - 'type': 'banner' - }, - 'bidder': { - 'appnexus': { - 'brand_id': 334553, - 'auction_id': 514667951122925701, - 'bidder_id': 2, - 'bid_ad_type': 0 - } - } - } - }, - { - 'id': 'bidId2', - 'impid': 'bidId2', - 'price': 0.1, - 'adm': '', - 'adid': '144762342', - 'adomain': [ - 'https://dummydomain.com' - ], - 'iurl': 'iurl', - 'cid': '109', - 'crid': 'creativeId', - 'cat': [], - 'w': 300, - 'h': 250, - 'ext': { - 'prebid': { - 'type': 'banner' - }, - 'bidder': { - 'appnexus': { - 'brand_id': 386046, - 'auction_id': 517067951122925501, - 'bidder_id': 2, - 'bid_ad_type': 0 - } - } - } - } - ], - 'seat': 'seat' - } - ], - 'ext': { - 'usersync': { - 'sovrn': { - 'status': 'none', - 'syncs': [ - { - 'url': 'urlsovrn', - 'type': 'iframe' - } - ] - }, - 'appnexus': { - 'status': 'none', - 'syncs': [ - { - 'url': 'urlappnexus', - 'type': 'pixel' - } - ] - } - }, - 'responsetimemillis': { - 'appnexus': 127 - } - } - } -}; - -describe('Padsquad bid adapter', function () { - describe('isBidRequestValid', function () { - it('should accept request if only unitId is passed', function () { - let bid = { - bidder: 'padsquad', - params: { - unitId: 'unitId', - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - it('should accept request if only networkId is passed', function () { - let bid = { - bidder: 'padsquad', - params: { - networkId: 'networkId', - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - it('should accept request if only publisherId is passed', function () { - let bid = { - bidder: 'padsquad', - params: { - publisherId: 'publisherId', - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('reject requests without params', function () { - let bid = { - bidder: 'padsquad', - params: {} - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - it('creates request data', function () { - let request = spec.buildRequests(REQUEST.bidRequest, REQUEST); - - expect(request).to.exist.and.to.be.a('object'); - const payload = JSON.parse(request.data); - expect(payload.imp[0]).to.have.property('id', REQUEST.bidRequest[0].bidId); - expect(payload.imp[1]).to.have.property('id', REQUEST.bidRequest[1].bidId); - }); - - it('has gdpr data if applicable', function () { - const req = Object.assign({}, REQUEST, { - gdprConsent: { - consentString: 'consentString', - gdprApplies: true, - } - }); - let request = spec.buildRequests(REQUEST.bidRequest, req); - - const payload = JSON.parse(request.data); - expect(payload.user.ext).to.have.property('consent', req.gdprConsent.consentString); - expect(payload.regs.ext).to.have.property('gdpr', 1); - }); - }); - - describe('interpretResponse', function () { - it('have bids', function () { - let bids = spec.interpretResponse(RESPONSE, REQUEST); - expect(bids).to.be.an('array').that.is.not.empty; - validateBidOnIndex(0); - validateBidOnIndex(1); - - function validateBidOnIndex(index) { - expect(bids[index]).to.have.property('currency', 'USD'); - expect(bids[index]).to.have.property('requestId', RESPONSE.body.seatbid[0].bid[index].impid); - expect(bids[index]).to.have.property('cpm', RESPONSE.body.seatbid[0].bid[index].price); - expect(bids[index]).to.have.property('width', RESPONSE.body.seatbid[0].bid[index].w); - expect(bids[index]).to.have.property('height', RESPONSE.body.seatbid[0].bid[index].h); - expect(bids[index]).to.have.property('ad', RESPONSE.body.seatbid[0].bid[index].adm); - expect(bids[index]).to.have.property('creativeId', RESPONSE.body.seatbid[0].bid[index].crid); - expect(bids[index].meta.advertiserDomains).to.deep.equal(RESPONSE.body.seatbid[0].bid[index].adomain); - expect(bids[index]).to.have.property('ttl', 30); - expect(bids[index]).to.have.property('netRevenue', true); - } - }); - - it('handles empty response', function () { - const EMPTY_RESP = Object.assign({}, RESPONSE, {'body': {}}); - const bids = spec.interpretResponse(EMPTY_RESP, REQUEST); - - expect(bids).to.be.empty; - }); - }); - - describe('getUserSyncs', function () { - it('handles no parameters', function () { - let opts = spec.getUserSyncs({}); - 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}); - - 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}, [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('pixel sync enabled should return results', function () { - let 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('all sync enabled should return all results', function () { - let opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [RESPONSE]); - - expect(opts.length).to.equal(2); - }); - }); -}); diff --git a/test/spec/modules/papyrusBidAdapter_spec.js b/test/spec/modules/papyrusBidAdapter_spec.js deleted file mode 100644 index 20fcced2950..00000000000 --- a/test/spec/modules/papyrusBidAdapter_spec.js +++ /dev/null @@ -1,115 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/papyrusBidAdapter.js'; - -const ENDPOINT = 'https://prebid.papyrus.global'; -const BIDDER_CODE = 'papyrus'; - -describe('papyrus Adapter', function () { - describe('isBidRequestValid', function () { - let validBidReq = { - bidder: BIDDER_CODE, - params: { - address: '0xd7e2a771c5dcd5df7f789477356aecdaeee6c985', - placementId: 'b57e55fd18614b0591893e9fff41fbea' - } - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(validBidReq)).to.equal(true); - }); - - let invalidBidReq = { - bidder: BIDDER_CODE, - params: { - 'placementId': '' - } - }; - - it('should not validate incorrect bid request', function () { - expect(spec.isBidRequestValid(invalidBidReq)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [ - { - bidder: BIDDER_CODE, - params: { - address: '0xd7e2a771c5dcd5df7f789477356aecdaeee6c985', - placementId: 'b57e55fd18614b0591893e9fff41fbea' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - it('sends bid request to ENDPOINT via POST', function () { - const request = spec.buildRequests(bidRequests); - expect(request.url).to.equal(ENDPOINT); - expect(request.method).to.equal('POST'); - }); - - it('sends valid bids count', function () { - const request = spec.buildRequests(bidRequests); - expect(request.data.length).to.equal(1); - }); - - it('sends all bid parameters', function () { - const request = spec.buildRequests(bidRequests); - expect(request.data[0]).to.have.all.keys(['address', 'placementId', 'sizes', 'bidId', 'transactionId']); - }); - - it('sedns valid sizes parameter', function () { - const request = spec.buildRequests(bidRequests); - expect(request.data[0].sizes[0]).to.equal('300x250'); - }); - }); - - describe('interpretResponse', function () { - let bidRequests = [ - { - bidder: BIDDER_CODE, - params: { - address: '0xd7e2a771c5dcd5df7f789477356aecdaeee6c985', - placementId: 'b57e55fd18614b0591893e9fff41fbea' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - let bidResponse = { - bids: [ - { - id: '1036e9746c-d186-49ae-90cb-2796d0f9b223', - adm: 'test adm', - cpm: 100, - height: 250, - width: 300 - } - ] - }; - - it('should build bid array', function () { - const request = spec.buildRequests(bidRequests); - const result = spec.interpretResponse({body: bidResponse}, request[0]); - expect(result.length).to.equal(1); - }); - - it('should have all relevant fields', function () { - const request = spec.buildRequests(bidRequests); - const result = spec.interpretResponse({body: bidResponse}, request[0]); - const bid = result[0]; - - expect(bid.cpm).to.equal(bidResponse.bids[0].cpm); - expect(bid.width).to.equal(bidResponse.bids[0].width); - expect(bid.height).to.equal(bidResponse.bids[0].height); - }); - }); -}); diff --git a/test/spec/modules/parrableIdSystem_spec.js b/test/spec/modules/parrableIdSystem_spec.js deleted file mode 100644 index 3f517a66c68..00000000000 --- a/test/spec/modules/parrableIdSystem_spec.js +++ /dev/null @@ -1,574 +0,0 @@ -import { expect } from 'chai'; -import find from 'core-js-pure/features/array/find.js'; -import { config } from 'src/config.js'; -import * as utils from 'src/utils.js'; -import { newStorageManager } from 'src/storageManager.js'; -import { getRefererInfo } from 'src/refererDetection.js'; -import { uspDataHandler } from 'src/adapterManager.js'; -import { init, requestBidsHook, setSubmoduleRegistry } from 'modules/userId/index.js'; -import { parrableIdSubmodule } from 'modules/parrableIdSystem.js'; -import { server } from 'test/mocks/xhr.js'; - -const storage = newStorageManager(); - -const EXPIRED_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:01 GMT'; -const P_COOKIE_NAME = '_parrable_id'; -const P_COOKIE_EID = '01.1563917337.test-eid'; -const P_XHR_EID = '01.1588030911.test-new-eid' -const P_CONFIG_MOCK = { - name: 'parrableId', - params: { - partners: 'parrable_test_partner_123,parrable_test_partner_456' - } -}; - -function getConfigMock() { - return { - userSync: { - syncDelay: 0, - userIds: [P_CONFIG_MOCK] - } - } -} - -function getAdUnitMock(code = 'adUnit-code') { - return { - code, - mediaTypes: {banner: {}, native: {}}, - sizes: [ - [300, 200], - [300, 600] - ], - bids: [{ - bidder: 'sampleBidder', - params: { placementId: 'banner-only-bidder' } - }] - }; -} - -function serializeParrableId(parrableId) { - let str = ''; - if (parrableId.eid) { - str += 'eid:' + parrableId.eid; - } - if (parrableId.ibaOptout) { - str += ',ibaOptout:1'; - } - if (parrableId.ccpaOptout) { - str += ',ccpaOptout:1'; - } - return str; -} - -function writeParrableCookie(parrableId) { - let cookieValue = encodeURIComponent(serializeParrableId(parrableId)); - storage.setCookie( - P_COOKIE_NAME, - cookieValue, - (new Date(Date.now() + 5000).toUTCString()), - 'lax' - ); -} - -function removeParrableCookie() { - storage.setCookie(P_COOKIE_NAME, '', EXPIRED_COOKIE_DATE); -} - -function decodeBase64UrlSafe(encBase64) { - const DEC = { - '-': '+', - '_': '/', - '.': '=' - }; - return encBase64.replace(/[-_.]/g, (m) => DEC[m]); -} - -describe('Parrable ID System', function() { - describe('parrableIdSystem.getId()', function() { - describe('response callback function', function() { - let logErrorStub; - let callbackSpy = sinon.spy(); - - beforeEach(function() { - logErrorStub = sinon.stub(utils, 'logError'); - callbackSpy.resetHistory(); - writeParrableCookie({ eid: P_COOKIE_EID }); - }); - - afterEach(function() { - removeParrableCookie(); - logErrorStub.restore(); - }) - - it('creates xhr to Parrable that synchronizes the ID', function() { - let getIdResult = parrableIdSubmodule.getId(P_CONFIG_MOCK); - - getIdResult.callback(callbackSpy); - - let request = server.requests[0]; - let queryParams = utils.parseQS(request.url.split('?')[1]); - let data = JSON.parse(atob(decodeBase64UrlSafe(queryParams.data))); - - expect(getIdResult.callback).to.be.a('function'); - expect(request.url).to.contain('h.parrable.com'); - - expect(queryParams).to.not.have.property('us_privacy'); - expect(data).to.deep.equal({ - eid: P_COOKIE_EID, - trackers: P_CONFIG_MOCK.params.partners.split(','), - url: getRefererInfo().referer, - prebidVersion: '$prebid.version$', - isIframe: true - }); - - server.requests[0].respond(200, - { 'Content-Type': 'text/plain' }, - JSON.stringify({ eid: P_XHR_EID }) - ); - - expect(callbackSpy.lastCall.lastArg).to.deep.equal({ - eid: P_XHR_EID - }); - - expect(storage.getCookie(P_COOKIE_NAME)).to.equal( - encodeURIComponent('eid:' + P_XHR_EID) - ); - }); - - it('xhr passes the uspString to Parrable', function() { - let uspString = '1YNN'; - uspDataHandler.setConsentData(uspString); - parrableIdSubmodule.getId( - P_CONFIG_MOCK, - null, - null - ).callback(callbackSpy); - uspDataHandler.setConsentData(null); - expect(server.requests[0].url).to.contain('us_privacy=' + uspString); - }); - - it('xhr base64 safely encodes url data object', function() { - const urlSafeBase64EncodedData = '-_.'; - const btoaStub = sinon.stub(window, 'btoa').returns('+/='); - let getIdResult = parrableIdSubmodule.getId(P_CONFIG_MOCK); - - getIdResult.callback(callbackSpy); - - let request = server.requests[0]; - let queryParams = utils.parseQS(request.url.split('?')[1]); - expect(queryParams.data).to.equal(urlSafeBase64EncodedData); - btoaStub.restore(); - }); - - it('should log an error and continue to callback if ajax request errors', function () { - let callBackSpy = sinon.spy(); - let submoduleCallback = parrableIdSubmodule.getId({ params: {partners: 'prebid'} }).callback; - submoduleCallback(callBackSpy); - let request = server.requests[0]; - expect(request.url).to.contain('h.parrable.com'); - request.respond( - 503, - null, - 'Unavailable' - ); - expect(logErrorStub.calledOnce).to.be.true; - expect(callBackSpy.calledOnce).to.be.true; - }); - }); - - describe('response id', function() { - it('provides the stored Parrable values if a cookie exists', function() { - writeParrableCookie({ eid: P_COOKIE_EID }); - let getIdResult = parrableIdSubmodule.getId(P_CONFIG_MOCK); - removeParrableCookie(); - - expect(getIdResult.id).to.deep.equal({ - eid: P_COOKIE_EID - }); - }); - - it('provides the stored legacy Parrable ID values if cookies exist', function() { - let oldEid = '01.111.old-eid'; - let oldEidCookieName = '_parrable_eid'; - let oldOptoutCookieName = '_parrable_optout'; - - storage.setCookie(oldEidCookieName, oldEid); - storage.setCookie(oldOptoutCookieName, 'true'); - - let getIdResult = parrableIdSubmodule.getId(P_CONFIG_MOCK); - expect(getIdResult.id).to.deep.equal({ - eid: oldEid, - ibaOptout: true - }); - - // The ID system is expected to migrate old cookies to the new format - expect(storage.getCookie(P_COOKIE_NAME)).to.equal( - encodeURIComponent('eid:' + oldEid + ',ibaOptout:1') - ); - expect(storage.getCookie(oldEidCookieName)).to.equal(null); - expect(storage.getCookie(oldOptoutCookieName)).to.equal(null); - removeParrableCookie(); - }); - }); - - describe('GDPR consent', () => { - let callbackSpy = sinon.spy(); - - const config = { - params: { - partner: 'partner' - } - }; - - const gdprConsentTestCases = [ - { consentData: { gdprApplies: true, consentString: 'expectedConsentString' }, expected: { gdpr: 1, gdpr_consent: 'expectedConsentString' } }, - { consentData: { gdprApplies: false, consentString: 'expectedConsentString' }, expected: { gdpr: 0 } }, - { consentData: { gdprApplies: true, consentString: undefined }, expected: { gdpr: 1, gdpr_consent: '' } }, - { consentData: { gdprApplies: 'yes', consentString: 'expectedConsentString' }, expected: { gdpr: 0 } }, - { consentData: undefined, expected: { gdpr: 0 } } - ]; - - gdprConsentTestCases.forEach((testCase, index) => { - it(`should call user sync url with the gdprConsent - case ${index}`, () => { - parrableIdSubmodule.getId(config, testCase.consentData).callback(callbackSpy); - - if (testCase.expected.gdpr === 1) { - expect(server.requests[0].url).to.contain('gdpr=' + testCase.expected.gdpr); - expect(server.requests[0].url).to.contain('gdpr_consent=' + testCase.expected.gdpr_consent); - } else { - expect(server.requests[0].url).to.contain('gdpr=' + testCase.expected.gdpr); - expect(server.requests[0].url).to.not.contain('gdpr_consent'); - } - }) - }); - }); - }); - - describe('parrableIdSystem.decode()', function() { - it('provides the Parrable ID (EID) from a stored object', function() { - let eid = '01.123.4567890'; - let parrableId = { - eid, - ibaOptout: true - }; - - expect(parrableIdSubmodule.decode(parrableId)).to.deep.equal({ - parrableId - }); - }); - }); - - describe('timezone filtering', function() { - before(function() { - sinon.stub(Intl, 'DateTimeFormat'); - }); - - after(function() { - Intl.DateTimeFormat.restore(); - }); - - it('permits an impression when no timezoneFilter is configured', function() { - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - } })).to.have.property('callback'); - }); - - it('permits an impression from a blocked timezone when a cookie exists', function() { - const blockedZone = 'Antarctica/South_Pole'; - const resolvedOptions = sinon.stub().returns({ timeZone: blockedZone }); - Intl.DateTimeFormat.returns({ resolvedOptions }); - - writeParrableCookie({ eid: P_COOKIE_EID }); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - blockedZones: [ blockedZone ] - } - } })).to.have.property('callback'); - expect(resolvedOptions.called).to.equal(false); - - removeParrableCookie(); - }) - - it('permits an impression from an allowed timezone', function() { - const allowedZone = 'America/New_York'; - const resolvedOptions = sinon.stub().returns({ timeZone: allowedZone }); - Intl.DateTimeFormat.returns({ resolvedOptions }); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - allowedZones: [ allowedZone ] - } - } })).to.have.property('callback'); - expect(resolvedOptions.called).to.equal(true); - }); - - it('permits an impression from a lower cased allowed timezone', function() { - const allowedZone = 'America/New_York'; - const resolvedOptions = sinon.stub().returns({ timeZone: allowedZone }); - Intl.DateTimeFormat.returns({ resolvedOptions }); - - expect(parrableIdSubmodule.getId({ params: { - partner: 'prebid-test', - timezoneFilter: { - allowedZones: [ allowedZone.toLowerCase() ] - } - } })).to.have.property('callback'); - expect(resolvedOptions.called).to.equal(true); - }); - - it('permits an impression from a timezone that is not blocked', function() { - const blockedZone = 'America/New_York'; - const resolvedOptions = sinon.stub().returns({ timeZone: 'Iceland' }); - Intl.DateTimeFormat.returns({ resolvedOptions }); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - blockedZones: [ blockedZone ] - } - } })).to.have.property('callback'); - expect(resolvedOptions.called).to.equal(true); - }); - - it('does not permit an impression from a blocked timezone', function() { - const blockedZone = 'America/New_York'; - const resolvedOptions = sinon.stub().returns({ timeZone: blockedZone }); - Intl.DateTimeFormat.returns({ resolvedOptions }); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - blockedZones: [ blockedZone ] - } - } })).to.equal(null); - expect(resolvedOptions.called).to.equal(true); - }); - - it('does not permit an impression from a lower cased blocked timezone', function() { - const blockedZone = 'America/New_York'; - const resolvedOptions = sinon.stub().returns({ timeZone: blockedZone }); - Intl.DateTimeFormat.returns({ resolvedOptions }); - - expect(parrableIdSubmodule.getId({ params: { - partner: 'prebid-test', - timezoneFilter: { - blockedZones: [ blockedZone.toLowerCase() ] - } - } })).to.equal(null); - expect(resolvedOptions.called).to.equal(true); - }); - - it('does not permit an impression from a blocked timezone even when also allowed', function() { - const timezone = 'America/New_York'; - const resolvedOptions = sinon.stub().returns({ timeZone: timezone }); - Intl.DateTimeFormat.returns({ resolvedOptions }); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - allowedZones: [ timezone ], - blockedZones: [ timezone ] - } - } })).to.equal(null); - expect(resolvedOptions.called).to.equal(true); - }); - }); - - describe('timezone offset filtering', function() { - before(function() { - sinon.stub(Date.prototype, 'getTimezoneOffset'); - }); - - afterEach(function() { - Date.prototype.getTimezoneOffset.reset(); - }) - - after(function() { - Date.prototype.getTimezoneOffset.restore(); - }); - - it('permits an impression from a blocked offset when a cookie exists', function() { - const blockedOffset = -4; - Date.prototype.getTimezoneOffset.returns(blockedOffset * 60); - - writeParrableCookie({ eid: P_COOKIE_EID }); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - blockedOffsets: [ blockedOffset ] - } - } })).to.have.property('callback'); - - removeParrableCookie(); - }); - - it('permits an impression from an allowed offset', function() { - const allowedOffset = -5; - Date.prototype.getTimezoneOffset.returns(allowedOffset * 60); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - allowedOffsets: [ allowedOffset ] - } - } })).to.have.property('callback'); - expect(Date.prototype.getTimezoneOffset.called).to.equal(true); - }); - - it('permits an impression from an offset that is not blocked', function() { - const allowedOffset = -5; - const blockedOffset = 5; - Date.prototype.getTimezoneOffset.returns(allowedOffset * 60); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - blockedOffsets: [ blockedOffset ] - } - }})).to.have.property('callback'); - expect(Date.prototype.getTimezoneOffset.called).to.equal(true); - }); - - it('does not permit an impression from a blocked offset', function() { - const blockedOffset = -5; - Date.prototype.getTimezoneOffset.returns(blockedOffset * 60); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - blockedOffsets: [ blockedOffset ] - } - } })).to.equal(null); - expect(Date.prototype.getTimezoneOffset.called).to.equal(true); - }); - - it('does not permit an impression from a blocked offset even when also allowed', function() { - const offset = -5; - Date.prototype.getTimezoneOffset.returns(offset * 60); - - expect(parrableIdSubmodule.getId({ params: { - partners: 'prebid-test', - timezoneFilter: { - allowedOffset: [ offset ], - blockedOffsets: [ offset ] - } - } })).to.equal(null); - expect(Date.prototype.getTimezoneOffset.called).to.equal(true); - }); - }); - - describe('userId requestBids hook', function() { - let adUnits; - - beforeEach(function() { - adUnits = [getAdUnitMock()]; - writeParrableCookie({ eid: P_COOKIE_EID, ibaOptout: true }); - setSubmoduleRegistry([parrableIdSubmodule]); - init(config); - config.setConfig(getConfigMock()); - }); - - afterEach(function() { - removeParrableCookie(); - storage.setCookie(P_COOKIE_NAME, '', EXPIRED_COOKIE_DATE); - }); - - it('when a stored Parrable ID exists it is added to bids', function(done) { - requestBidsHook(function() { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.parrableId'); - expect(bid.userId.parrableId.eid).to.equal(P_COOKIE_EID); - expect(bid.userId.parrableId.ibaOptout).to.equal(true); - const parrableIdAsEid = find(bid.userIdAsEids, e => e.source == 'parrable.com'); - expect(parrableIdAsEid).to.deep.equal({ - source: 'parrable.com', - uids: [{ - id: P_COOKIE_EID, - atype: 1, - ext: { - ibaOptout: true - } - }] - }); - }); - }); - done(); - }, { adUnits }); - }); - - it('supplies an optout reason when the EID is missing due to CCPA non-consent', function(done) { - // the ID system itself will not write a cookie with an EID when CCPA=true - writeParrableCookie({ ccpaOptout: true }); - - requestBidsHook(function() { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.parrableId'); - expect(bid.userId.parrableId).to.not.have.property('eid'); - expect(bid.userId.parrableId.ccpaOptout).to.equal(true); - const parrableIdAsEid = find(bid.userIdAsEids, e => e.source == 'parrable.com'); - expect(parrableIdAsEid).to.deep.equal({ - source: 'parrable.com', - uids: [{ - id: '', - atype: 1, - ext: { - ccpaOptout: true - } - }] - }); - }); - }); - done(); - }, { adUnits }); - }); - }); - - describe('partners parsing', () => { - let callbackSpy = sinon.spy(); - - const partnersTestCase = [ - { - name: '"partners" as an array', - config: { params: { partners: ['parrable_test_partner_123', 'parrable_test_partner_456'] } }, - expected: ['parrable_test_partner_123', 'parrable_test_partner_456'] - }, - { - name: '"partners" as a string list', - config: { params: { partners: 'parrable_test_partner_123,parrable_test_partner_456' } }, - expected: ['parrable_test_partner_123', 'parrable_test_partner_456'] - }, - { - name: '"partners" as a string', - config: { params: { partners: 'parrable_test_partner_123' } }, - expected: ['parrable_test_partner_123'] - }, - { - name: '"partner" as a string list', - config: { params: { partner: 'parrable_test_partner_123,parrable_test_partner_456' } }, - expected: ['parrable_test_partner_123', 'parrable_test_partner_456'] - }, - { - name: '"partner" as string', - config: { params: { partner: 'parrable_test_partner_123' } }, - expected: ['parrable_test_partner_123'] - }, - ]; - partnersTestCase.forEach(testCase => { - it(`accepts config property ${testCase.name}`, () => { - parrableIdSubmodule.getId(testCase.config).callback(callbackSpy); - - let request = server.requests[0]; - let queryParams = utils.parseQS(request.url.split('?')[1]); - let data = JSON.parse(atob(decodeBase64UrlSafe(queryParams.data))); - - expect(data.trackers).to.deep.equal(testCase.expected); - }); - }); - }); -}); diff --git a/test/spec/modules/performaxBidAdapter_spec.js b/test/spec/modules/performaxBidAdapter_spec.js deleted file mode 100644 index 43c256b9d13..00000000000 --- a/test/spec/modules/performaxBidAdapter_spec.js +++ /dev/null @@ -1,274 +0,0 @@ -import * as utils from 'src/utils.js'; -import { expect } from 'chai'; -import { spec } from 'modules/performaxBidAdapter'; - -describe('PerformaxAdapter', function () { - let bidRequests, bidderRequest; - let serverResponse, serverRequest; - - const URL = - 'https://dale.performax.cz/hb?slotId[]=3,2&client=hellboy:v0.0.1&auctionId=144b5079-8cbf-49a5-aca7-a68b3296cd6c'; - - bidRequests = [ - { - adUnitCode: 'postbid_iframe', - auctionId: '144b5079-8cbf-49a5-aca7-a68b3296cd6c', - bidId: '2a4332f6b2bc74', - bidRequestsCount: 1, - bidder: 'performax', - bidderRequestId: '1c7d8bf204f11e', - bidderRequestsCount: 1, - bidderWinsCount: 0, - mediaTypes: { - banner: { - sizes: [[300, 300]], - }, - }, - params: { - slotId: 3, - }, - sizes: [[300, 300]], - src: 'client', - transactionId: '14969d09-0068-4d5b-a34e-e35091561dee', - }, - { - adUnitCode: 'postbid_iframe2', - auctionId: '144b5079-8cbf-49a5-aca7-a68b3296cd6c', - bidId: '300bb0ac6a156a', - bidRequestsCount: 1, - bidder: 'performax', - bidderRequestId: '1c7d8bf204f11e', - bidderRequestsCount: 1, - bidderWinsCount: 0, - mediaTypes: { - banner: { - sizes: [[300, 300]], - }, - }, - params: { - slotId: 2, - }, - sizes: [[300, 300]], - src: 'client', - transactionId: '107cbebd-8c36-4456-b28c-91a19ba80151', - }, - ]; - - bidderRequest = { - auctionId: '144b5079-8cbf-49a5-aca7-a68b3296cd6c', - auctionStart: 1594281941845, - bidderCode: 'performax', - bidderRequestId: '1c7d8bf204f11e', - bids: bidRequests, - refererInfo: { - canonicalUrl: '', - numIframes: 0, - reachedTop: true, - referer: '', - }, - stack: [''], - start: 1594281941935, - timeout: 3600, - }; - - serverResponse = { - body: [ - { - ad: { - code: '$SYS_ID$ $VAR_NAME$ rest of the code', - data: { - SYS_ID: 1, - VAR_NAME: 'name', - }, - format_id: 2, - id: 11, - size: { - width: 300, - height: 300, - }, - tag_ids: [], - type: 'creative', - }, - cpm: 30, - creativeId: 'creative:11', - currency: 'CZK', - height: 300, - meta: { - agencyId: 1, - mediaType: 'banner', - }, - netRevenue: true, - requestId: '2a4332f6b2bc74', - ttl: 60, - width: 300, - }, - { - ad: { - code: '', - reason: 'Slot 2 does not allow HB requests', - type: 'empty', - }, - cpm: 0, - creativeId: null, - currency: 'CZK', - height: null, - meta: { - agencyId: null, - mediaType: 'banner', - }, - netRevenue: true, - requestId: '1c7d8bf204f11e', - ttl: 60, - width: 300, - }, - ], - }; - - serverRequest = { - data: { - bidderRequest: bidderRequest, - validBidRequests: bidRequests, - }, - method: 'POST', - options: { - contentType: 'application/json', - }, - url: URL, - }; - - describe('Bid validations', function () { - it('Valid bid', function () { - let validBid = { - bidder: 'performax', - params: { - slotId: 2, - }, - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(true); - }); - - it('Invalid bid: required param is missing', function () { - let invalidBid = { - bidder: 'performax', - params: { - invalidParam: 2, - }, - }, - isValid = spec.isBidRequestValid(invalidBid); - expect(isValid).to.equal(false); - }); - }); - - describe('Build Url', function () { - it('Should return url', function () { - let url = spec.buildUrl(bidRequests, bidderRequest); - expect(url).to.equal(URL); - }); - }); - - describe('Build Request', function () { - it('Should not modify bidRequests and bidder Requests', function () { - let originalBidRequests = utils.deepClone(bidRequests); - let originalBidderRequest = utils.deepClone(bidderRequest); - let request = spec.buildRequests(bidRequests, bidderRequest); - - expect(bidRequests).to.deep.equal(originalBidRequests); - expect(bidderRequest).to.deep.equal(originalBidderRequest); - }); - - it('Endpoint checking', function () { - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.url).to.equal(URL); - expect(request.method).to.equal('POST'); - expect(request.options).to.deep.equal({ - contentType: 'application/json', - }); - }); - - it('Request params checking', function () { - let request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.validBidRequests).to.deep.equal(bidRequests); - expect(request.data.bidderRequest).to.deep.equal(bidderRequest); - }); - }); - - describe('Build Html', function () { - it('Ad with data: should return build html', function () { - let validAd = { - code: '$SYS_ID$ $VAR_NAME$ rest of the code', - data: { - SYS_ID: 1, - VAR_NAME: 'name', - }, - format_id: 2, - id: 11, - size: { - width: 300, - height: 300, - }, - tag_ids: [], - type: 'creative', - }; - let html = spec.buildHtml(validAd); - expect(html).to.equal('1 name rest of the code'); - }); - - it('Ad with partial data: should return html without data change', function () { - let adWithPartialData = { - code: '$SYS_ID$ $VAR_NAME$ rest of the code', - data: { - VAR_NAME: 'name', - }, - format_id: 2, - id: 11, - size: { - width: 300, - height: 300, - }, - tag_ids: [], - type: 'creative', - }; - let html = spec.buildHtml(adWithPartialData); - expect(html).to.equal('$SYS_ID$ name rest of the code'); - }); - - it('Ad without data: should return html without data change', function () { - let adWithoutData = { - code: '$SYS_ID$ $VAR_NAME$ rest of the code', - format_id: 2, - id: 11, - size: { - width: 300, - height: 300, - }, - tag_ids: [], - type: 'creative', - }; - let html = spec.buildHtml(adWithoutData); - expect(html).to.equal('$SYS_ID$ $VAR_NAME$ rest of the code'); - }); - }); - - describe('Interpret Response', function () { - it('Ad without data: should return html without data change', function () { - let ads = spec.interpretResponse(serverResponse, serverRequest); - expect(ads).to.have.length(1); - expect(ads[0]).to.deep.equal({ - ad: '1 name rest of the code', - cpm: 30, - creativeId: 'creative:11', - currency: 'CZK', - height: 300, - meta: { - agencyId: 1, - mediaType: 'banner', - }, - netRevenue: true, - requestId: '2a4332f6b2bc74', - ttl: 60, - width: 300, - }); - }); - }); -}); diff --git a/test/spec/modules/permutiveRtdProvider_spec.js b/test/spec/modules/permutiveRtdProvider_spec.js deleted file mode 100644 index cf1f3861eab..00000000000 --- a/test/spec/modules/permutiveRtdProvider_spec.js +++ /dev/null @@ -1,397 +0,0 @@ -import { permutiveSubmodule, storage, getSegments, initSegments, isAcEnabled, isPermutiveOnPage } from 'modules/permutiveRtdProvider.js' -import { deepAccess } from '../../../src/utils.js' - -describe('permutiveRtdProvider', function () { - before(function () { - const data = getTargetingData() - setLocalStorage(data) - }) - - after(function () { - const data = getTargetingData() - removeLocalStorage(data) - }) - - describe('permutiveSubmodule', function () { - it('should initalise and return true', function () { - expect(permutiveSubmodule.init()).to.equal(true) - }) - }) - - describe('Getting segments', function () { - it('should retrieve segments in the expected structure', function () { - const data = transformedTargeting() - expect(getSegments(250)).to.deep.equal(data) - }) - it('should enforce max segments', function () { - const max = 1 - const segments = getSegments(max) - - for (const key in segments) { - expect(segments[key]).to.have.length(max) - } - }) - }) - - describe('Default segment targeting', function () { - it('sets segment targeting for Xandr', function () { - const data = transformedTargeting() - const adUnits = getAdUnits() - const config = getConfig() - - initSegments({ adUnits }, callback, config) - - function callback () { - adUnits.forEach(adUnit => { - adUnit.bids.forEach(bid => { - const { bidder, params } = bid - - if (bidder === 'appnexus') { - expect(deepAccess(params, 'keywords.permutive')).to.eql(data.appnexus) - expect(deepAccess(params, 'keywords.p_standard')).to.eql(data.ac) - } - }) - }) - } - }) - it('sets segment targeting for Magnite', function () { - const data = transformedTargeting() - const adUnits = getAdUnits() - const config = getConfig() - - initSegments({ adUnits }, callback, config) - - function callback () { - adUnits.forEach(adUnit => { - adUnit.bids.forEach(bid => { - const { bidder, params } = bid - - if (bidder === 'rubicon') { - expect(deepAccess(params, 'visitor.permutive')).to.eql(data.rubicon) - expect(deepAccess(params, 'visitor.p_standard')).to.eql(data.ac) - } - }) - }) - } - }) - it('sets segment targeting for Ozone', function () { - const data = transformedTargeting() - const adUnits = getAdUnits() - const config = getConfig() - - initSegments({ adUnits }, callback, config) - - function callback () { - adUnits.forEach(adUnit => { - adUnit.bids.forEach(bid => { - const { bidder, params } = bid - - if (bidder === 'ozone') { - expect(deepAccess(params, 'customData.0.targeting.p_standard')).to.eql(data.ac) - } - }) - }) - } - }) - it('sets segment targeting for TrustX', function () { - const data = transformedTargeting() - const adUnits = getAdUnits() - const config = getConfig() - - initSegments({ adUnits }, callback, config) - - function callback () { - adUnits.forEach(adUnit => { - adUnit.bids.forEach(bid => { - const { bidder, params } = bid - - if (bidder === 'trustx') { - expect(deepAccess(params, 'keywords.p_standard')).to.eql(data.ac) - } - }) - }) - } - }) - }) - - describe('Custom segment targeting', function () { - it('sets custom segment targeting for Magnite', function () { - const data = transformedTargeting() - const adUnits = getAdUnits() - const config = getConfig() - - config.params.overwrites = { - rubicon: function (bid, data, acEnabled, utils, defaultFn) { - if (defaultFn) { - bid = defaultFn(bid, data, acEnabled) - } - if (data.gam && data.gam.length) { - utils.deepSetValue(bid, 'params.visitor.permutive', data.gam) - } - } - } - - initSegments({ adUnits }, callback, config) - - function callback () { - adUnits.forEach(adUnit => { - adUnit.bids.forEach(bid => { - const { bidder, params } = bid - - if (bidder === 'rubicon') { - expect(deepAccess(params, 'visitor.permutive')).to.eql(data.gam) - expect(deepAccess(params, 'visitor.p_standard')).to.eql(data.ac) - } - }) - }) - } - }) - }) - - describe('Existing key-value targeting', function () { - it('doesn\'t overwrite existing key-values for Xandr', function () { - const adUnits = getAdUnits() - const config = getConfig() - - initSegments({ adUnits }, callback, config) - - function callback () { - adUnits.forEach(adUnit => { - adUnit.bids.forEach(bid => { - const { bidder, params } = bid - - if (bidder === 'appnexus') { - expect(deepAccess(params, 'keywords.test_kv')).to.eql(['true']) - } - }) - }) - } - }) - it('doesn\'t overwrite existing key-values for Magnite', function () { - const adUnits = getAdUnits() - const config = getConfig() - - initSegments({ adUnits }, callback, config) - - function callback () { - adUnits.forEach(adUnit => { - adUnit.bids.forEach(bid => { - const { bidder, params } = bid - - if (bidder === 'rubicon') { - expect(deepAccess(params, 'visitor.test_kv')).to.eql(['true']) - } - }) - }) - } - }) - it('doesn\'t overwrite existing key-values for Ozone', function () { - const adUnits = getAdUnits() - const config = getConfig() - - initSegments({ adUnits }, callback, config) - - function callback () { - adUnits.forEach(adUnit => { - adUnit.bids.forEach(bid => { - const { bidder, params } = bid - - if (bidder === 'ozone') { - expect(deepAccess(params, 'customData.0.targeting.test_kv')).to.eql(['true']) - } - }) - }) - } - }) - it('doesn\'t overwrite existing key-values for TrustX', function () { - const adUnits = getAdUnits() - const config = getConfig() - - initSegments({ adUnits }, callback, config) - - function callback () { - adUnits.forEach(adUnit => { - adUnit.bids.forEach(bid => { - const { bidder, params } = bid - - if (bidder === 'trustx') { - expect(deepAccess(params, 'keywords.test_kv')).to.eql(['true']) - } - }) - }) - } - }) - }) - - describe('Permutive on page', function () { - it('checks if Permutive is on page', function () { - expect(isPermutiveOnPage()).to.equal(false) - }) - }) - - describe('AC is enabled', function () { - it('checks if AC is enabled for Xandr', function () { - expect(isAcEnabled({ params: { acBidders: ['appnexus'] } }, 'appnexus')).to.equal(true) - expect(isAcEnabled({ params: { acBidders: ['kjdbfkvb'] } }, 'appnexus')).to.equal(false) - }) - it('checks if AC is enabled for Magnite', function () { - expect(isAcEnabled({ params: { acBidders: ['rubicon'] } }, 'rubicon')).to.equal(true) - expect(isAcEnabled({ params: { acBidders: ['kjdbfkb'] } }, 'rubicon')).to.equal(false) - }) - it('checks if AC is enabled for Ozone', function () { - expect(isAcEnabled({ params: { acBidders: ['ozone'] } }, 'ozone')).to.equal(true) - expect(isAcEnabled({ params: { acBidders: ['kjdvb'] } }, 'ozone')).to.equal(false) - }) - }) -}) - -function setLocalStorage (data) { - for (const key in data) { - storage.setDataInLocalStorage(key, JSON.stringify(data[key])) - } -} - -function removeLocalStorage (data) { - for (const key in data) { - storage.removeDataFromLocalStorage(key) - } -} - -function getConfig () { - return { - name: 'permutive', - waitForIt: true, - params: { - acBidders: ['appnexus', 'rubicon', 'ozone', 'trustx'], - maxSegs: 500 - } - } -} - -function transformedTargeting () { - const data = getTargetingData() - - return { - ac: [...data._pcrprs, ...data._ppam, ...data._psegs.filter(seg => seg >= 1000000)], - appnexus: data._papns, - rubicon: data._prubicons, - gam: data._pdfps - } -} - -function getTargetingData () { - return { - _pdfps: ['gam1', 'gam2'], - _prubicons: ['rubicon1', 'rubicon2'], - _papns: ['appnexus1', 'appnexus2'], - _psegs: ['1234', '1000001', '1000002'], - _ppam: ['ppam1', 'ppam2'], - _pcrprs: ['pcrprs1', 'pcrprs2'] - } -} - -function getAdUnits () { - const div_1_sizes = [ - [300, 250], - [300, 600] - ] - const div_2_sizes = [ - [728, 90], - [970, 250] - ] - return [ - { - code: '/19968336/header-bid-tag-0', - mediaTypes: { - banner: { - sizes: div_1_sizes - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 13144370, - keywords: { - test_kv: ['true'] - } - } - }, - { - bidder: 'rubicon', - params: { - accountId: '9840', - siteId: '123564', - zoneId: '583584', - inventory: { - area: ['home'] - }, - visitor: { - test_kv: ['true'] - } - } - }, - { - bidder: 'ozone', - params: { - publisherId: 'OZONEGMG0001', - siteId: '4204204209', - placementId: '0420420500', - customData: [ - { - settings: {}, - targeting: { - test_kv: ['true'] - } - } - ], - ozoneData: {} - } - }, - { - bidder: 'trustx', - params: { - uid: 45, - keywords: { - test_kv: ['true'] - } - } - } - ] - }, - { - code: '/19968336/header-bid-tag-1', - mediaTypes: { - banner: { - sizes: div_2_sizes - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 13144370, - keywords: { - test_kv: ['true'] - } - } - }, - { - bidder: 'ozone', - params: { - publisherId: 'OZONEGMG0001', - siteId: '4204204209', - placementId: '0420420500', - customData: [ - { - targeting: { - test_kv: ['true'] - } - } - ] - } - } - ] - } - ] -} diff --git a/test/spec/modules/piximediaBidAdapter_spec.js b/test/spec/modules/piximediaBidAdapter_spec.js deleted file mode 100644 index 88a6433b71d..00000000000 --- a/test/spec/modules/piximediaBidAdapter_spec.js +++ /dev/null @@ -1,103 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/piximediaBidAdapter.js'; - -describe('piximediaAdapterTest', function() { - describe('bidRequestValidity', function() { - it('bidRequest with site ID and placement ID param', function() { - expect(spec.isBidRequestValid({ - bidder: 'piximedia', - params: { - 'siteId': 'PIXIMEDIA_PREBID10', - 'placementId': 'RG' - }, - })).to.equal(true); - }); - - it('bidRequest with no required params', function() { - expect(spec.isBidRequestValid({ - bidder: 'piximedia', - params: { - }, - })).to.equal(false); - }); - }); - - describe('bidRequest', function() { - const bidRequests = [{ - 'bidder': 'piximedia', - 'params': { - 'siteId': 'PIXIMEDIA_PREBID10', - 'placementId': 'RG' - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'sizes': [300, 250], - 'bidId': '51ef8751f9aead', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757' - }]; - - it('bidRequest HTTP method', function() { - const requests = spec.buildRequests(bidRequests); - requests.forEach(function(requestItem) { - expect(requestItem.method).to.equal('GET'); - }); - }); - - it('bidRequest data', function() { - const requests = spec.buildRequests(bidRequests); - expect(typeof requests[0].data.timestamp).to.equal('number'); - expect(requests[0].data.pbsizes).to.equal('["300x250"]'); - expect(requests[0].data.pver).to.equal('1.0'); - expect(requests[0].data.pbparams).to.equal(JSON.stringify(bidRequests[0].params)); - expect(requests[0].data.pbwidth).to.equal('300'); - expect(requests[0].data.pbheight).to.equal('250'); - expect(requests[0].data.pbbidid).to.equal('51ef8751f9aead'); - }); - }); - - describe('interpretResponse', function() { - const bidRequest = { - 'method': 'GET', - 'url': 'https://ad.piximedia.com/', - 'data': { - 'ver': 2, - 'hb': 1, - 'output': 'js', - 'pub': 267, - 'zone': 62546, - 'width': '300', - 'height': '250', - 'callback': 'json', - 'callback_uid': '51ef8751f9aead', - 'url': 'https://example.com', - 'cb': '', - } - }; - - const bidResponse = { - body: { - 'bidId': '51ef8751f9aead', - 'cpm': 4.2, - 'width': '300', - 'height': '250', - 'creative_id': '1234', - 'currency': 'EUR', - 'adm': '
', - }, - headers: {} - }; - - it('result is correct', function() { - const result = spec.interpretResponse(bidResponse, bidRequest); - expect(result[0].requestId).to.equal('51ef8751f9aead'); - expect(result[0].cpm).to.equal(4.2); - expect(result[0].width).to.equal('300'); - expect(result[0].height).to.equal('250'); - expect(result[0].creativeId).to.equal('1234'); - expect(result[0].currency).to.equal('EUR'); - expect(result[0].ttl).to.equal(300); - expect(result[0].ad).to.equal('
'); - }); - }); -}); diff --git a/test/spec/modules/platformioBidAdapter_spec.js b/test/spec/modules/platformioBidAdapter_spec.js deleted file mode 100644 index ee753be17a7..00000000000 --- a/test/spec/modules/platformioBidAdapter_spec.js +++ /dev/null @@ -1,348 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/platformioBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; - -describe('Platform.io Adapter Tests', function () { - const slotConfigs = [{ - placementCode: '/DfpAccount1/slot1', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bidId: 'bid12345', - mediaType: 'banner', - params: { - pubId: '29521', - siteId: '26047', - placementId: '123', - bidFloor: '0.001', - ifa: 'IFA', - latitude: '40.712775', - longitude: '-74.005973' - } - }, { - placementCode: '/DfpAccount2/slot2', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - }, - bidId: 'bid23456', - mediaType: 'banner', - params: { - pubId: '29521', - siteId: '26047', - placementId: '1234', - bidFloor: '0.000001', - } - }]; - const nativeSlotConfig = [{ - placementCode: '/DfpAccount1/slot3', - bidId: 'bid12345', - mediaType: 'native', - nativeParams: { - title: { required: true, len: 200 }, - body: {}, - image: { wmin: 100 }, - sponsoredBy: { }, - icon: { } - }, - params: { - pubId: '29521', - placementId: '123', - siteId: '26047' - } - }]; - const videoSlotConfig = [{ - placementCode: '/DfpAccount1/slot4', - mediaTypes: { - video: { - playerSize: [[640, 480]] - } - }, - bidId: 'bid12345678', - mediaType: 'video', - video: { - skippable: true - }, - params: { - pubId: '29521', - placementId: '1234567', - siteId: '26047', - } - }]; - const appSlotConfig = [{ - placementCode: '/DfpAccount1/slot5', - bidId: 'bid12345', - params: { - pubId: '29521', - placementId: '1234', - app: { - id: '1111', - name: 'app name', - bundle: 'io.platform.apps', - storeUrl: 'https://platform.io/apps', - domain: 'platform.io' - } - } - }]; - - it('Verify build request', function () { - const request = spec.buildRequests(slotConfigs); - expect(request.url).to.equal('https://piohbdisp.hb.adx1.com/'); - expect(request.method).to.equal('POST'); - const ortbRequest = JSON.parse(request.data); - // site object - expect(ortbRequest.site).to.not.equal(null); - expect(ortbRequest.site.publisher).to.not.equal(null); - expect(ortbRequest.site.publisher.id).to.equal('29521'); - expect(ortbRequest.site.ref).to.equal(window.top.document.referrer); - expect(ortbRequest.site.page).to.equal(window.location.href); - expect(ortbRequest.imp).to.have.lengthOf(2); - // device object - expect(ortbRequest.device).to.not.equal(null); - expect(ortbRequest.device.ua).to.equal(navigator.userAgent); - expect(ortbRequest.device.ifa).to.equal('IFA'); - expect(ortbRequest.device.geo.lat).to.equal('40.712775'); - expect(ortbRequest.device.geo.lon).to.equal('-74.005973'); - // slot 1 - expect(ortbRequest.imp[0].tagid).to.equal('123'); - expect(ortbRequest.imp[0].banner).to.not.equal(null); - expect(ortbRequest.imp[0].banner.w).to.equal(300); - expect(ortbRequest.imp[0].banner.h).to.equal(250); - expect(ortbRequest.imp[0].bidfloor).to.equal('0.001'); - // slot 2 - expect(ortbRequest.imp[1].tagid).to.equal('1234'); - expect(ortbRequest.imp[1].banner).to.not.equal(null); - expect(ortbRequest.imp[1].banner.w).to.equal(728); - expect(ortbRequest.imp[1].banner.h).to.equal(90); - expect(ortbRequest.imp[1].bidfloor).to.equal('0.000001'); - }); - - it('Verify parse response', function () { - const request = spec.buildRequests(slotConfigs); - const ortbRequest = JSON.parse(request.data); - const ortbResponse = { - seatbid: [{ - bid: [{ - impid: ortbRequest.imp[0].id, - price: 1.25, - adm: 'This is an Ad', - w: 300, - h: 250 - }] - }], - cur: 'USD' - }; - const bids = spec.interpretResponse({ body: ortbResponse }, request); - expect(bids).to.have.lengthOf(1); - // verify first bid - const bid = bids[0]; - expect(bid.cpm).to.equal(1.25); - expect(bid.ad).to.equal('This is an Ad'); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.adId).to.equal('bid12345'); - expect(bid.creativeId).to.equal('bid12345'); - expect(bid.netRevenue).to.equal(true); - expect(bid.currency).to.equal('USD'); - expect(bid.ttl).to.equal(360); - }); - - it('Verify full passback', function () { - const request = spec.buildRequests(slotConfigs); - const bids = spec.interpretResponse({ body: null }, request) - expect(bids).to.have.lengthOf(0); - }); - - it('Verify Native request', function () { - const request = spec.buildRequests(nativeSlotConfig); - expect(request.url).to.equal('https://piohbdisp.hb.adx1.com/'); - expect(request.method).to.equal('POST'); - const ortbRequest = JSON.parse(request.data); - // native impression - expect(ortbRequest.imp[0].tagid).to.equal('123'); - const nativePart = ortbRequest.imp[0]['native']; - expect(nativePart).to.not.equal(null); - expect(nativePart.ver).to.equal('1.1'); - expect(nativePart.request).to.not.equal(null); - // native request assets - const nativeRequest = JSON.parse(ortbRequest.imp[0]['native'].request); - expect(nativeRequest).to.not.equal(null); - expect(nativeRequest.assets).to.have.lengthOf(5); - expect(nativeRequest.assets[0].id).to.equal(1); - expect(nativeRequest.assets[1].id).to.equal(2); - expect(nativeRequest.assets[2].id).to.equal(3); - expect(nativeRequest.assets[3].id).to.equal(4); - expect(nativeRequest.assets[4].id).to.equal(5); - expect(nativeRequest.assets[0].required).to.equal(1); - expect(nativeRequest.assets[0].title).to.not.equal(null); - expect(nativeRequest.assets[0].title.len).to.equal(200); - expect(nativeRequest.assets[1].title).to.be.undefined; - expect(nativeRequest.assets[1].data).to.not.equal(null); - expect(nativeRequest.assets[1].data.type).to.equal(2); - expect(nativeRequest.assets[1].data.len).to.equal(200); - expect(nativeRequest.assets[2].required).to.equal(0); - expect(nativeRequest.assets[3].img).to.not.equal(null); - expect(nativeRequest.assets[3].img.wmin).to.equal(50); - expect(nativeRequest.assets[3].img.hmin).to.equal(50); - expect(nativeRequest.assets[3].img.type).to.equal(1); - expect(nativeRequest.assets[4].img).to.not.equal(null); - expect(nativeRequest.assets[4].img.wmin).to.equal(100); - expect(nativeRequest.assets[4].img.hmin).to.equal(150); - expect(nativeRequest.assets[4].img.type).to.equal(3); - }); - - it('Verify Native response', function () { - const request = spec.buildRequests(nativeSlotConfig); - expect(request.url).to.equal('https://piohbdisp.hb.adx1.com/'); - expect(request.method).to.equal('POST'); - const ortbRequest = JSON.parse(request.data); - const nativeResponse = { - 'native': { - assets: [ - { id: 1, title: { text: 'Ad Title' } }, - { id: 2, data: { value: 'Test description' } }, - { id: 3, data: { value: 'Brand' } }, - { id: 4, img: { url: 'https://adx1public.s3.amazonaws.com/creatives_icon.png', w: 100, h: 100 } }, - { id: 5, img: { url: 'https://adx1public.s3.amazonaws.com/creatives_image.png', w: 300, h: 300 } } - ], - link: { url: 'https://brand.com/' } - } - }; - const ortbResponse = { - seatbid: [{ - bid: [{ - impid: ortbRequest.imp[0].id, - price: 1.25, - nurl: 'https://rtb.adx1.com/log', - adm: JSON.stringify(nativeResponse) - }] - }], - cur: 'USD', - }; - const bids = spec.interpretResponse({ body: ortbResponse }, request); - // verify bid - const bid = bids[0]; - expect(bid.cpm).to.equal(1.25); - expect(bid.adId).to.equal('bid12345'); - expect(bid.ad).to.be.undefined; - expect(bid.mediaType).to.equal('native'); - const nativeBid = bid['native']; - expect(nativeBid).to.not.equal(null); - expect(nativeBid.title).to.equal('Ad Title'); - expect(nativeBid.sponsoredBy).to.equal('Brand'); - expect(nativeBid.icon.url).to.equal('https://adx1public.s3.amazonaws.com/creatives_icon.png'); - expect(nativeBid.image.url).to.equal('https://adx1public.s3.amazonaws.com/creatives_image.png'); - expect(nativeBid.image.width).to.equal(300); - expect(nativeBid.image.height).to.equal(300); - expect(nativeBid.icon.width).to.equal(100); - expect(nativeBid.icon.height).to.equal(100); - expect(nativeBid.clickUrl).to.equal(encodeURIComponent('https://brand.com/')); - expect(nativeBid.impressionTrackers).to.have.lengthOf(1); - expect(nativeBid.impressionTrackers[0]).to.equal('https://rtb.adx1.com/log'); - }); - - it('Verify Video request', function () { - const request = spec.buildRequests(videoSlotConfig); - expect(request.url).to.equal('https://piohbdisp.hb.adx1.com/'); - expect(request.method).to.equal('POST'); - const videoRequest = JSON.parse(request.data); - // site object - expect(videoRequest.site).to.not.equal(null); - expect(videoRequest.site.publisher.id).to.equal('29521'); - expect(videoRequest.site.ref).to.equal(window.top.document.referrer); - expect(videoRequest.site.page).to.equal(window.location.href); - // device object - expect(videoRequest.device).to.not.equal(null); - expect(videoRequest.device.ua).to.equal(navigator.userAgent); - // slot 1 - expect(videoRequest.imp[0].tagid).to.equal('1234567'); - expect(videoRequest.imp[0].video).to.not.equal(null); - expect(videoRequest.imp[0].video.w).to.equal(640); - expect(videoRequest.imp[0].video.h).to.equal(480); - expect(videoRequest.imp[0].banner).to.equal(null); - expect(videoRequest.imp[0].native).to.equal(null); - }); - - it('Verify parse video response', function () { - const request = spec.buildRequests(videoSlotConfig); - const videoRequest = JSON.parse(request.data); - const videoResponse = { - seatbid: [{ - bid: [{ - impid: videoRequest.imp[0].id, - price: 1.90, - adm: 'https://vid.example.com/9876', - crid: '510511_754567308' - }] - }], - cur: 'USD' - }; - const bids = spec.interpretResponse({ body: videoResponse }, request); - expect(bids).to.have.lengthOf(1); - // verify first bid - const bid = bids[0]; - expect(bid.cpm).to.equal(1.90); - expect(bid.vastUrl).to.equal('https://vid.example.com/9876'); - expect(bid.crid).to.equal('510511_754567308'); - expect(bid.width).to.equal(640); - expect(bid.height).to.equal(480); - expect(bid.adId).to.equal('bid12345678'); - expect(bid.netRevenue).to.equal(true); - expect(bid.currency).to.equal('USD'); - expect(bid.ttl).to.equal(360); - }); - - it('Verifies bidder code', function () { - expect(spec.code).to.equal('platformio'); - }); - - it('Verifies supported media types', function () { - expect(spec.supportedMediaTypes).to.have.lengthOf(3); - expect(spec.supportedMediaTypes[0]).to.equal('banner'); - expect(spec.supportedMediaTypes[1]).to.equal('native'); - expect(spec.supportedMediaTypes[2]).to.equal('video'); - }); - - it('Verifies if bid request valid', function () { - expect(spec.isBidRequestValid(slotConfigs[0])).to.equal(true); - expect(spec.isBidRequestValid(slotConfigs[1])).to.equal(true); - expect(spec.isBidRequestValid(nativeSlotConfig[0])).to.equal(true); - expect(spec.isBidRequestValid(videoSlotConfig[0])).to.equal(true); - }); - - it('Verify app requests', function () { - const request = spec.buildRequests(appSlotConfig); - const ortbRequest = JSON.parse(request.data); - expect(ortbRequest.site).to.equal(null); - expect(ortbRequest.app).to.not.be.null; - expect(ortbRequest.app.publisher).to.not.equal(null); - expect(ortbRequest.app.publisher.id).to.equal('29521'); - expect(ortbRequest.app.id).to.equal('1111'); - expect(ortbRequest.app.name).to.equal('app name'); - expect(ortbRequest.app.bundle).to.equal('io.platform.apps'); - expect(ortbRequest.app.storeurl).to.equal('https://platform.io/apps'); - expect(ortbRequest.app.domain).to.equal('platform.io'); - }); - - it('Verify GDPR', function () { - const bidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString: 'serialized_gpdr_data' - } - }; - const request = spec.buildRequests(slotConfigs, bidderRequest); - expect(request.url).to.equal('https://piohbdisp.hb.adx1.com/'); - expect(request.method).to.equal('POST'); - const ortbRequest = JSON.parse(request.data); - expect(ortbRequest.user).to.not.equal(null); - expect(ortbRequest.user.ext).to.not.equal(null); - expect(ortbRequest.user.ext.consent).to.equal('serialized_gpdr_data'); - expect(ortbRequest.regs).to.not.equal(null); - expect(ortbRequest.regs.ext).to.not.equal(null); - expect(ortbRequest.regs.ext.gdpr).to.equal(1); - }); -}); diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js deleted file mode 100644 index 6833daf49cf..00000000000 --- a/test/spec/modules/prebidServerBidAdapter_spec.js +++ /dev/null @@ -1,2732 +0,0 @@ -import { expect } from 'chai'; -import { PrebidServer as Adapter, resetSyncedStatus, resetWurlMap } from 'modules/prebidServerBidAdapter/index.js'; -import adapterManager from 'src/adapterManager.js'; -import * as utils from 'src/utils.js'; -import { ajax } from 'src/ajax.js'; -import { config } from 'src/config.js'; -import events from 'src/events.js'; -import CONSTANTS from 'src/constants.json'; -import { server } from 'test/mocks/xhr.js'; -import { createEidsArray } from 'modules/userId/eids.js'; - -let CONFIG = { - accountId: '1', - enabled: true, - bidders: ['appnexus'], - timeout: 1000, - cacheMarkup: 2, - endpoint: { - p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction', - noP1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction' - } -}; - -const REQUEST = { - 'account_id': '1', - 'tid': '437fbbf5-33f5-487a-8e16-a7112903cfe5', - 'max_bids': 1, - 'timeout_millis': 1000, - 'secure': 0, - 'url': '', - 'prebid_version': '0.30.0-pre', - 's2sConfig': CONFIG, - 'ad_units': [ - { - 'code': 'div-gpt-ad-1460505748561-0', - 'sizes': [[300, 250], [300, 600]], - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 300]] - }, - 'native': { - 'title': { - 'required': true, - 'len': 800 - }, - 'image': { - 'required': true, - 'sizes': [989, 742], - }, - 'icon': { - 'required': true, - 'aspect_ratios': [{ - 'min_height': 10, - 'min_width': 10, - 'ratio_height': 1, - 'ratio_width': 1 - }] - }, - 'sponsoredBy': { - 'required': true - } - } - }, - 'transactionId': '4ef956ad-fd83-406d-bd35-e4bb786ab86c', - 'bids': [ - { - 'bid_id': '123', - 'bidder': 'appnexus', - 'params': { - 'placementId': '10433394', - 'member': 123 - } - } - ] - } - ] -}; - -const VIDEO_REQUEST = { - 'account_id': '1', - 'tid': '437fbbf5-33f5-487a-8e16-a7112903cfe5', - 'max_bids': 1, - 'timeout_millis': 1000, - 'secure': 0, - 'url': '', - 'prebid_version': '1.4.0-pre', - 's2sConfig': CONFIG, - 'ad_units': [ - { - 'code': 'div-gpt-ad-1460505748561-0', - 'sizes': [640, 480], - 'mediaTypes': { - 'video': { - 'playerSize': [[640, 480]], - 'mimes': ['video/mp4'] - } - }, - 'transactionId': '4ef956ad-fd83-406d-bd35-e4bb786ab86c', - 'bids': [ - { - 'bid_id': '123', - 'bidder': 'appnexus', - 'params': { 'placementId': '12349520' } - } - ] - } - ] -}; - -const OUTSTREAM_VIDEO_REQUEST = { - 'account_id': '1', - 'tid': '437fbbf5-33f5-487a-8e16-a7112903cfe5', - 'max_bids': 1, - 'timeout_millis': 1000, - 'secure': 0, - 'url': '', - 'prebid_version': '1.4.0-pre', - 's2sConfig': CONFIG, - 'ad_units': [ - { - 'code': 'div-gpt-ad-1460505748561-0', - 'sizes': [640, 480], - 'mediaTypes': { - 'video': { - playerSize: [[640, 480]], - context: 'outstream', - mimes: ['video/mp4'] - }, - banner: { sizes: [[300, 250]] } - }, - 'transactionId': '4ef956ad-fd83-406d-bd35-e4bb786ab86c', - 'bids': [ - { - 'bid_id': '123', - 'bidder': 'appnexus', - 'params': { 'placementId': '12349520' } - } - ] - }, - { - code: 'video1', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'outstream', - mimes: ['video/mp4'] - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 13232385, - video: { - skippable: true, - playback_method: ['auto_play_sound_off'] - } - } - } - ], - renderer: { - url: 'http://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', - render: function (bid) { - ANOutstreamVideo.renderAd({ - targetId: bid.adUnitCode, - adResponse: bid.adResponse, - }); - } - } - } - ], -}; - -let BID_REQUESTS; - -const RESPONSE_NO_BID_NO_UNIT = { - 'tid': '437fbbf5-33f5-487a-8e16-a7112903cfe5', - 'status': 'OK', - 'bidder_status': [{ - 'bidder': 'appnexus', - 'response_time_ms': 132, - 'no_bid': true - }] -}; - -const RESPONSE_NO_BID_UNIT_SET = { - 'tid': '437fbbf5-33f5-487a-8e16-a7112903cfe5', - 'status': 'OK', - 'bidder_status': [{ - 'bidder': 'appnexus', - 'ad_unit': 'div-gpt-ad-1460505748561-0', - 'response_time_ms': 91, - 'no_bid': true - }] -}; - -const RESPONSE_NO_COOKIE = { - 'tid': 'd6eca075-4a59-4346-bdb3-86531830ef2c', - 'status': 'OK', - 'bidder_status': [{ - 'bidder': 'pubmatic', - 'no_cookie': true, - 'usersync': { - 'url': '//ads.pubmatic.com/AdServer/js/user_sync.html?predirect=http://localhost:8000/setuid?bidder=pubmatic&uid=', - 'type': 'iframe' - } - }] -}; - -const RESPONSE_NO_PBS_COOKIE = { - 'tid': '882fe33e-2981-4257-bd44-bd3b03945f48', - 'status': 'no_cookie', - 'bidder_status': [{ - 'bidder': 'rubicon', - 'no_cookie': true, - 'usersync': { - 'url': 'https://pixel.rubiconproject.com/exchange/sync.php?p=prebid', - 'type': 'redirect' - } - }, { - 'bidder': 'pubmatic', - 'no_cookie': true, - 'usersync': { - 'url': '//ads.pubmatic.com/AdServer/js/user_sync.html?predirect=https%3A%2F%2Fprebid.adnxs.com%2Fpbs%2Fv1%2Fsetuid%3Fbidder%3Dpubmatic%26uid%3D', - 'type': 'iframe' - } - }, { - 'bidder': 'appnexus', - 'response_time_ms': 162, - 'num_bids': 1, - 'debug': [{ - 'request_uri': 'http://ib.adnxs.com/openrtb2', - 'request_body': '{"id":"882fe33e-2981-4257-bd44-bd3b03945f48","imp":[{"id":"/19968336/header-bid-tag-0","banner":{"w":300,"h":250,"format":[{"w":300,"h":250}]},"secure":1,"ext":{"appnexus":{"placement_id":5914989}}}],"site":{"domain":"nytimes.com","page":"http://www.nytimes.com"},"device":{"ua":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36","ip":"75.97.0.47"},"user":{"id":"3519479852893340159","buyeruid":"3519479852893340159"},"at":1,"tmax":1000,"source":{"fd":1,"tid":"882fe33e-2981-4257-bd44-bd3b03945f48"}}', - 'response_body': '{"id":"882fe33e-2981-4257-bd44-bd3b03945f48"}', - 'status_code': 200 - }] - }], - 'bids': [{ - 'bid_id': '123', - 'code': 'div-gpt-ad-1460505748561-0', - 'creative_id': '70928274', - 'bidder': 'appnexus', - 'price': 0.07425, - 'adm': '', - 'width': 300, - 'height': 250, - 'response_time_ms': 162 - }] -}; - -const RESPONSE_OPENRTB = { - 'id': 'c7dcf14f', - 'seatbid': [ - { - 'bid': [ - { - 'id': '8750901685062148', - 'impid': 'div-gpt-ad-1460505748561-0', - 'price': 0.5, - 'adm': '', - 'adid': '29681110', - 'adomain': ['appnexus.com'], - 'iurl': 'http://lax1-ib.adnxs.com/cr?id=2968111', - 'cid': '958', - 'crid': '2968111', - 'dealid': 'test-dealid', - 'w': 300, - 'h': 250, - 'ext': { - 'prebid': { - 'type': 'banner', - 'event': { - 'win': 'http://wurl.org?id=333' - } - }, - 'dchain': { 'ver': '1.0', 'complete': 0, 'nodes': [ { 'asi': 'magnite.com', 'bsid': '123456789', } ] }, - 'bidder': { - 'appnexus': { - 'brand_id': 1, - 'auction_id': 3, - 'bidder_id': 2 - } - } - } - } - ], - 'seat': 'appnexus' - }, - ], - 'cur': 'EUR', - 'ext': { - 'responsetimemillis': { - 'appnexus': 8, - } - } -}; - -const RESPONSE_OPENRTB_VIDEO = { - id: 'c7dcf14f', - seatbid: [ - { - bid: [ - { - id: '1987250005171537465', - impid: 'div-gpt-ad-1460505748561-0', - price: 10, - adm: 'adnxs', - adid: '81877115', - adomain: ['appnexus.com'], - iurl: 'http://lax1-ib.adnxs.com/cr?id=81877115', - cid: '3535', - crid: '81877115', - dealid: 'test-dealid', - w: 1, - h: 1, - ext: { - prebid: { - type: 'video', - bidid: '654321' - }, - bidder: { - appnexus: { - brand_id: 1, - auction_id: 6673622101799484743, - bidder_id: 2, - bid_ad_type: 1, - }, - }, - }, - }, - ], - seat: 'appnexus', - }, - ], - ext: { - responsetimemillis: { - appnexus: 81, - }, - }, -}; - -const RESPONSE_OPENRTB_NATIVE = { - 'id': 'c7dcf14f', - 'seatbid': [ - { - 'bid': [ - { - 'id': '6451317310275562039', - 'impid': 'div-gpt-ad-1460505748561-0', - 'price': 10, - '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': 2, - 'img': { - 'url': 'https://vcdn.adnxs.com/p/creative-image/1a/3e/e9/5b/1a3ee95b-06cd-4260-98c7-0258627c9197.png', - 'w': 127, - 'h': 83, - 'ext': { - 'appnexus': { - 'prevent_crop': 0 - } - } - } - }, - { - 'id': 0, - 'title': { - 'text': 'This is a Prebid Native Creative' - } - }, - { - 'id': 3, - 'data': { - 'value': 'Prebid.org' - } - } - ], - 'link': { - 'url': 'https://lax1-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQGdce2vBWudAJZpFu1er1zA7ZzddAAAAAOLoyQBtJAAAbSQAAAIAAAC8pM8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAgMCAAAAALsAuhVqdgAAAAA./cpcpm=AAAAAAAAAAA=/bcr=AAAAAAAA8D8=/pp=${AUCTION_PRICE}/cnd=%213Q5HCQj8-LwKELzJvi4YnPFbIAQoADEAAAAAAAAkQDoJTEFYMTo0MDc3QKcPSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAA/cca=OTMyNSNMQVgxOjQwNzc=/bn=84305/test=1/clickenc=http%3A%2F%2Fprebid.org%2Fdev-docs%2Fshow-native-ads.html' - }, - 'eventtrackers': [ - { - 'event': 1, - 'method': 1, - 'url': 'https://lax1-ib.adnxs.com/it?an_audit=0&test=1&referrer=http%3A%2F%2Flocalhost%3A9999%2FintegrationExamples%2Fgpt%2Fdemo_native.html&e=wqT_3QKCCKACBAAAAwDWAAUBCLvO3ekFEOe47duW2NbzQBiltJba--rq6zAqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlC8yb4uWJzxW2AAaM26dXjRkgWAAQGKAQNVU0SSAQEG8FKYAQGgAQGoAQGwAQC4AQLAAQPIAQLQAQnYAQDgAQHwAQCKAjt1ZignYScsIDI1Mjk4ODUsIDE1NjM5MTE5OTUpO3VmKCdyJywgOTc0OTQyMDQsIC4eAPQ0AZICnQIhb2pkaWlnajgtTHdLRUx6SnZpNFlBQ0NjOFZzd0FEZ0FRQVJJN1VoUTR0R25CbGdBWVAwQmFBQndBSGdBZ0FFQWlBRUFrQUVCbUFFQm9BRUJxQUVEc0FFQXVRSHpyV3FrQUFBa1FNRUI4NjFxcEFBQUpFREpBVVZpYmxDaFpRQkEyUUVBQUFBQUFBRHdQLUFCQVBVQkFBQUFBUGdCQUpnQ0FLQUNBTFVDQUFBQUFMMENBQUFBQU1BQ0FNZ0NBT0FDQU9nQ0FQZ0NBSUFEQVpBREFKZ0RBYWdEX1BpOENyb0RDVXhCV0RFNk5EQTNOLUFEcHctUUJBQ1lCQUhCQkFBQUFBQUFBQUFBeVFRQUFBQUFBQUFBQU5nRUFBLi6aAoUBITNRNUhDUWo4LUx3S0VMeiUhJG5QRmJJQVFvQUQRvVhBa1FEb0pURUZZTVRvME1EYzNRS2NQUxFUDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQz0FwHYAgDgAq2YSOoCPmh0dHA6Ly9sb2NhbGhvc3Q6OTk5OS9pbnRlZ3JhdGlvbkV4YW1wbGVzL2dwdC9kZW1vX25hdGl2ZS5odG1sgAMAiAMBkAMAmAMUoAMBqgMAwAPgqAHIAwDYAwDgAwDoAwD4AwOABACSBAkvb3BlbnJ0YjKYBACiBA0xNzMuMjQ0LjM2LjQwqATtoySyBAwIABAAGAAgADAAOAC4BADABADIBADSBA45MzI1I0xBWDE6NDA3N9oEAggB4AQA8AS8yb4uiAUBmAUAoAX___________8BqgUkZTU5YzNlYjYtNmRkNi00MmQ5LWExMWEtM2FhMTFjOTc5MGUwwAUAyQUAAAAAAADwP9IFCQkAaVh0ANgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGCSQk8D_IBgDaBhYKEAkQGQEBwTTgBgzyBgIIAIAHAYgHAA..&s=11ababa390e9f7983de260493fc5b91ec5b1b3d4&pp=${AUCTION_PRICE}' - } - ] - }, - 'adid': '97494204', - 'adomain': [ - 'http://prebid.org' - ], - 'iurl': 'https://lax1-ib.adnxs.com/cr?id=97494204', - 'cid': '9325', - 'crid': '97494204', - 'cat': [ - 'IAB3-1' - ], - 'ext': { - 'prebid': { - 'targeting': { - 'hb_bidder': 'appnexus', - 'hb_pb': '10.00' - }, - 'type': 'native', - 'video': { - 'duration': 0, - 'primary_category': '' - } - }, - 'bidder': { - 'appnexus': { - 'brand_id': 555545, - 'auction_id': 4676806524825984103, - 'bidder_id': 2, - 'bid_ad_type': 3 - } - } - } - } - ], - 'seat': 'appnexus' - } - ] -}; - -describe('S2S Adapter', function () { - let adapter, - addBidResponse = sinon.spy(), - done = sinon.spy(); - - beforeEach(function () { - config.resetConfig(); - adapter = new Adapter(); - BID_REQUESTS = [ - { - 'bidderCode': 'appnexus', - 'auctionId': '173afb6d132ba3', - 'bidderRequestId': '3d1063078dfcc8', - 'tid': '437fbbf5-33f5-487a-8e16-a7112903cfe5', - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': '10433394', - 'member': 123, - 'keywords': { - 'foo': ['bar', 'baz'], - 'fizz': ['buzz'] - } - }, - 'bid_id': '123', - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'transactionId': '4ef956ad-fd83-406d-bd35-e4bb786ab86c', - 'sizes': [300, 250], - 'bidId': '123', - 'bidderRequestId': '3d1063078dfcc8', - 'auctionId': '173afb6d132ba3', - 'storedAuctionResponse': 11111 - } - ], - 'auctionStart': 1510852447530, - 'timeout': 5000, - 'src': 's2s', - 'doneCbCallCount': 0, - 'refererInfo': { - 'referer': 'http://mytestpage.com' - } - } - ]; - }); - - afterEach(function () { - addBidResponse.resetHistory(); - done.resetHistory(); - }); - - after(function () { - config.resetConfig(); - }); - - describe('request function', function () { - beforeEach(function () { - resetSyncedStatus(); - }); - - it('should not add outstrean without renderer', function () { - config.setConfig({ s2sConfig: CONFIG }); - - adapter.callBids(OUTSTREAM_VIDEO_REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - - const requestBid = JSON.parse(server.requests[0].requestBody); - expect(requestBid.imp[0].banner).to.exist; - expect(requestBid.imp[0].video).to.not.exist; - }); - - it('should default video placement if not defined and instream', function () { - let ortb2Config = utils.deepClone(CONFIG); - ortb2Config.endpoint.p1Consent = 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction'; - - config.setConfig({ s2sConfig: ortb2Config }); - - let videoBid = utils.deepClone(VIDEO_REQUEST); - videoBid.ad_units[0].mediaTypes.video.context = 'instream'; - adapter.callBids(videoBid, BID_REQUESTS, addBidResponse, done, ajax); - - const requestBid = JSON.parse(server.requests[0].requestBody); - expect(requestBid.imp[0].banner).to.not.exist; - expect(requestBid.imp[0].video).to.exist; - expect(requestBid.imp[0].video.placement).to.equal(1); - }); - - it('converts video mediaType properties into openRTB format', function () { - let ortb2Config = utils.deepClone(CONFIG); - ortb2Config.endpoint.p1Consent = 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction'; - - config.setConfig({ s2sConfig: ortb2Config }); - - let videoBid = utils.deepClone(VIDEO_REQUEST); - videoBid.ad_units[0].mediaTypes.video.context = 'instream'; - adapter.callBids(videoBid, BID_REQUESTS, addBidResponse, done, ajax); - - const requestBid = JSON.parse(server.requests[0].requestBody); - expect(requestBid.imp[0].banner).to.not.exist; - expect(requestBid.imp[0].video).to.exist; - expect(requestBid.imp[0].video.placement).to.equal(1); - expect(requestBid.imp[0].video.w).to.equal(640); - expect(requestBid.imp[0].video.h).to.equal(480); - expect(requestBid.imp[0].video.playerSize).to.be.undefined; - expect(requestBid.imp[0].video.context).to.be.undefined; - }); - - it('exists and is a function', function () { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - - describe('gdpr tests', function () { - afterEach(function () { - $$PREBID_GLOBAL$$.requestBids.removeAll(); - }); - - it('adds gdpr consent information to ortb2 request depending on presence of module', function () { - let consentConfig = { consentManagement: { cmpApi: 'iab' }, s2sConfig: CONFIG }; - config.setConfig(consentConfig); - - let gdprBidRequest = utils.deepClone(BID_REQUESTS); - gdprBidRequest[0].gdprConsent = { - consentString: 'abc123', - gdprApplies: true - }; - - adapter.callBids(REQUEST, gdprBidRequest, addBidResponse, done, ajax); - let requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.regs.ext.gdpr).is.equal(1); - expect(requestBid.user.ext.consent).is.equal('abc123'); - - config.resetConfig(); - config.setConfig({ s2sConfig: CONFIG }); - - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - requestBid = JSON.parse(server.requests[1].requestBody); - - expect(requestBid.regs).to.not.exist; - expect(requestBid.user).to.not.exist; - }); - - it('adds additional consent information to ortb2 request depending on presence of module', function () { - let consentConfig = { consentManagement: { cmpApi: 'iab' }, s2sConfig: CONFIG }; - config.setConfig(consentConfig); - - let gdprBidRequest = utils.deepClone(BID_REQUESTS); - gdprBidRequest[0].gdprConsent = { - consentString: 'abc123', - addtlConsent: 'superduperconsent', - gdprApplies: true - }; - - adapter.callBids(REQUEST, gdprBidRequest, addBidResponse, done, ajax); - let requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.regs.ext.gdpr).is.equal(1); - expect(requestBid.user.ext.consent).is.equal('abc123'); - expect(requestBid.user.ext.ConsentedProvidersSettings.consented_providers).is.equal('superduperconsent'); - - config.resetConfig(); - config.setConfig({ s2sConfig: CONFIG }); - - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - requestBid = JSON.parse(server.requests[1].requestBody); - - expect(requestBid.regs).to.not.exist; - expect(requestBid.user).to.not.exist; - }); - - it('check gdpr info gets added into cookie_sync request: have consent data', function () { - let cookieSyncConfig = utils.deepClone(CONFIG); - cookieSyncConfig.syncEndpoint = { p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync' }; - - let consentConfig = { consentManagement: { cmpApi: 'iab' }, s2sConfig: cookieSyncConfig }; - config.setConfig(consentConfig); - - let gdprBidRequest = utils.deepClone(BID_REQUESTS); - - gdprBidRequest[0].gdprConsent = { - consentString: 'abc123def', - gdprApplies: true - }; - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = cookieSyncConfig; - - adapter.callBids(s2sBidRequest, gdprBidRequest, addBidResponse, done, ajax); - let requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.gdpr).is.equal(1); - expect(requestBid.gdpr_consent).is.equal('abc123def'); - expect(requestBid.bidders).to.contain('appnexus').and.to.have.lengthOf(1); - expect(requestBid.account).is.equal('1'); - }); - - it('check gdpr info gets added into cookie_sync request: have consent data but gdprApplies is false', function () { - let cookieSyncConfig = utils.deepClone(CONFIG); - cookieSyncConfig.syncEndpoint = { p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync' }; - - let consentConfig = { consentManagement: { cmpApi: 'iab' }, s2sConfig: cookieSyncConfig }; - config.setConfig(consentConfig); - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = cookieSyncConfig; - - let gdprBidRequest = utils.deepClone(BID_REQUESTS); - gdprBidRequest[0].gdprConsent = { - consentString: 'xyz789abcc', - gdprApplies: false - }; - - adapter.callBids(s2sBidRequest, gdprBidRequest, addBidResponse, done, ajax); - let requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.gdpr).is.equal(0); - expect(requestBid.gdpr_consent).is.undefined; - }); - - it('checks gdpr info gets added to cookie_sync request: applies is false', function () { - let cookieSyncConfig = utils.deepClone(CONFIG); - cookieSyncConfig.syncEndpoint = { p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync' }; - - let consentConfig = { consentManagement: { cmpApi: 'iab' }, s2sConfig: cookieSyncConfig }; - config.setConfig(consentConfig); - - let gdprBidRequest = utils.deepClone(BID_REQUESTS); - gdprBidRequest[0].gdprConsent = { - consentString: undefined, - gdprApplies: false - }; - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = cookieSyncConfig; - - adapter.callBids(s2sBidRequest, gdprBidRequest, addBidResponse, done, ajax); - let requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.gdpr).is.equal(0); - expect(requestBid.gdpr_consent).is.undefined; - }); - }); - - describe('us_privacy (ccpa) consent data', function () { - afterEach(function () { - $$PREBID_GLOBAL$$.requestBids.removeAll(); - }); - - it('is added to ortb2 request when in bidRequest', function () { - config.setConfig({ s2sConfig: CONFIG }); - - let uspBidRequest = utils.deepClone(BID_REQUESTS); - uspBidRequest[0].uspConsent = '1NYN'; - - adapter.callBids(REQUEST, uspBidRequest, addBidResponse, done, ajax); - let requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.regs.ext.us_privacy).is.equal('1NYN'); - - config.resetConfig(); - config.setConfig({ s2sConfig: CONFIG }); - - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - requestBid = JSON.parse(server.requests[1].requestBody); - - expect(requestBid.regs).to.not.exist; - }); - - it('is added to cookie_sync request when in bidRequest', function () { - let cookieSyncConfig = utils.deepClone(CONFIG); - cookieSyncConfig.syncEndpoint = { p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync' }; - config.setConfig({ s2sConfig: cookieSyncConfig }); - - let uspBidRequest = utils.deepClone(BID_REQUESTS); - uspBidRequest[0].uspConsent = '1YNN'; - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = cookieSyncConfig; - - adapter.callBids(s2sBidRequest, uspBidRequest, addBidResponse, done, ajax); - let requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.us_privacy).is.equal('1YNN'); - expect(requestBid.bidders).to.contain('appnexus').and.to.have.lengthOf(1); - expect(requestBid.account).is.equal('1'); - }); - }); - - describe('gdpr and us_privacy (ccpa) consent data', function () { - afterEach(function () { - $$PREBID_GLOBAL$$.requestBids.removeAll(); - }); - - it('is added to ortb2 request when in bidRequest', function () { - config.setConfig({ s2sConfig: CONFIG }); - - let consentBidRequest = utils.deepClone(BID_REQUESTS); - consentBidRequest[0].uspConsent = '1NYN'; - consentBidRequest[0].gdprConsent = { - consentString: 'abc123', - gdprApplies: true - }; - - adapter.callBids(REQUEST, consentBidRequest, addBidResponse, done, ajax); - let requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.regs.ext.us_privacy).is.equal('1NYN'); - expect(requestBid.regs.ext.gdpr).is.equal(1); - expect(requestBid.user.ext.consent).is.equal('abc123'); - - config.resetConfig(); - config.setConfig({ s2sConfig: CONFIG }); - - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - requestBid = JSON.parse(server.requests[1].requestBody); - - expect(requestBid.regs).to.not.exist; - expect(requestBid.user).to.not.exist; - }); - - it('is added to cookie_sync request when in bidRequest', function () { - let cookieSyncConfig = utils.deepClone(CONFIG); - cookieSyncConfig.syncEndpoint = { p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync' }; - config.setConfig({ s2sConfig: cookieSyncConfig }); - - let consentBidRequest = utils.deepClone(BID_REQUESTS); - consentBidRequest[0].uspConsent = '1YNN'; - consentBidRequest[0].gdprConsent = { - consentString: 'abc123def', - gdprApplies: true - }; - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = cookieSyncConfig - - adapter.callBids(s2sBidRequest, consentBidRequest, addBidResponse, done, ajax); - let requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.us_privacy).is.equal('1YNN'); - expect(requestBid.gdpr).is.equal(1); - expect(requestBid.gdpr_consent).is.equal('abc123def'); - expect(requestBid.bidders).to.contain('appnexus').and.to.have.lengthOf(1); - expect(requestBid.account).is.equal('1'); - }); - }); - - it('adds device and app objects to request', function () { - const _config = { - s2sConfig: CONFIG, - device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' }, - app: { bundle: 'com.test.app' }, - }; - - config.setConfig(_config); - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - const requestBid = JSON.parse(server.requests[0].requestBody); - expect(requestBid.device).to.deep.equal({ - ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC', - w: window.innerWidth, - h: window.innerHeight - }); - expect(requestBid.app).to.deep.equal({ - bundle: 'com.test.app', - publisher: { 'id': '1' } - }); - }); - - it('adds device and app objects to request for OpenRTB', function () { - const s2sConfig = Object.assign({}, CONFIG, { - endpoint: { - p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction' - } - }); - - const _config = { - s2sConfig: s2sConfig, - device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' }, - app: { bundle: 'com.test.app' }, - }; - - config.setConfig(_config); - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - const requestBid = JSON.parse(server.requests[0].requestBody); - expect(requestBid.device).to.deep.equal({ - ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC', - w: window.innerWidth, - h: window.innerHeight - }); - expect(requestBid.app).to.deep.equal({ - bundle: 'com.test.app', - publisher: { 'id': '1' } - }); - }); - - it('adds debugging value from storedAuctionResponse to OpenRTB', function () { - const _config = { - s2sConfig: CONFIG, - device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' }, - app: { bundle: 'com.test.app' } - }; - - config.setConfig(_config); - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - const requestBid = JSON.parse(server.requests[0].requestBody); - expect(requestBid.imp).to.exist.and.to.be.a('array'); - expect(requestBid.imp).to.have.lengthOf(1); - expect(requestBid.imp[0].ext).to.exist.and.to.be.a('object'); - expect(requestBid.imp[0].ext.prebid).to.exist.and.to.be.a('object'); - expect(requestBid.imp[0].ext.prebid.storedauctionresponse).to.exist.and.to.be.a('object'); - expect(requestBid.imp[0].ext.prebid.storedauctionresponse.id).to.equal('11111'); - }); - - describe('price floors module', function () { - function runTest(expectedFloor, expectedCur) { - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - const requestBid = JSON.parse(server.requests[requestCount].requestBody); - expect(requestBid.imp[0].bidfloor).to.equal(expectedFloor); - expect(requestBid.imp[0].bidfloorcur).to.equal(expectedCur); - requestCount += 1; - } - - let getFloorResponse, requestCount; - beforeEach(function () { - getFloorResponse = {}; - requestCount = 0; - }); - - it('should NOT pass bidfloor and bidfloorcur when getFloor not present or returns invalid response', function () { - const _config = { - s2sConfig: CONFIG, - }; - - config.setConfig(_config); - - // if no get floor - runTest(undefined, undefined); - - // if getFloor returns empty object - BID_REQUESTS[0].bids[0].getFloor = () => getFloorResponse; - sinon.spy(BID_REQUESTS[0].bids[0], 'getFloor'); - - runTest(undefined, undefined); - // make sure getFloor was called - expect( - BID_REQUESTS[0].bids[0].getFloor.calledWith({ - currency: 'USD', - }) - ).to.be.true; - - // if getFloor does not return number - getFloorResponse = {currency: 'EUR', floor: 'not a number'}; - runTest(undefined, undefined); - - // if getFloor does not return currency - getFloorResponse = {floor: 1.1}; - runTest(undefined, undefined); - }); - - it('should correctly pass bidfloor and bidfloorcur', function () { - const _config = { - s2sConfig: CONFIG, - }; - - config.setConfig(_config); - - BID_REQUESTS[0].bids[0].getFloor = () => getFloorResponse; - sinon.spy(BID_REQUESTS[0].bids[0], 'getFloor'); - - // returns USD and string floor - getFloorResponse = {currency: 'USD', floor: '1.23'}; - runTest(1.23, 'USD'); - // make sure getFloor was called - expect( - BID_REQUESTS[0].bids[0].getFloor.calledWith({ - currency: 'USD', - }) - ).to.be.true; - - // returns non USD and number floor - getFloorResponse = {currency: 'EUR', floor: 0.85}; - runTest(0.85, 'EUR'); - }); - - it('should correctly pass adServerCurrency when set to getFloor not default', function () { - config.setConfig({ - s2sConfig: CONFIG, - currency: { adServerCurrency: 'JPY' }, - }); - - // we have to start requestCount at 1 because a conversion rates fetch occurs when adServerCur is not USD! - requestCount = 1; - - BID_REQUESTS[0].bids[0].getFloor = () => getFloorResponse; - sinon.spy(BID_REQUESTS[0].bids[0], 'getFloor'); - - // returns USD and string floor - getFloorResponse = {currency: 'JPY', floor: 97.2}; - runTest(97.2, 'JPY'); - // make sure getFloor was called with JPY - expect( - BID_REQUESTS[0].bids[0].getFloor.calledWith({ - currency: 'JPY', - }) - ).to.be.true; - }); - }); - - it('adds device.w and device.h even if the config lacks a device object', function () { - const _config = { - s2sConfig: CONFIG, - app: { bundle: 'com.test.app' }, - }; - - config.setConfig(_config); - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - const requestBid = JSON.parse(server.requests[0].requestBody); - expect(requestBid.device).to.deep.equal({ - w: window.innerWidth, - h: window.innerHeight - }); - expect(requestBid.app).to.deep.equal({ - bundle: 'com.test.app', - publisher: { 'id': '1' } - }); - }); - - it('adds native request for OpenRTB', function () { - const _config = { - s2sConfig: CONFIG - }; - - config.setConfig(_config); - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - const requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.imp[0].native).to.deep.equal({ - request: JSON.stringify({ - 'context': 1, - 'plcmttype': 1, - 'eventtrackers': [{ - event: 1, - methods: [1] - }], - 'assets': [ - { - 'required': 1, - 'title': { - 'len': 800 - } - }, - { - 'required': 1, - 'img': { - 'type': 3, - 'w': 989, - 'h': 742 - } - }, - { - 'required': 1, - 'img': { - 'type': 1, - 'wmin': 10, - 'hmin': 10, - 'ext': { - 'aspectratios': ['1:1'] - } - } - }, - { - 'required': 1, - 'data': { - 'type': 1 - } - } - ] - }), - ver: '1.2' - }); - }); - - it('adds site if app is not present', function () { - const _config = { - s2sConfig: CONFIG, - site: { - publisher: { - id: '1234', - domain: 'test.com' - }, - content: { - language: 'en' - } - } - }; - - config.setConfig(_config); - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - const requestBid = JSON.parse(server.requests[0].requestBody); - expect(requestBid.site).to.exist.and.to.be.a('object'); - expect(requestBid.site.publisher).to.exist.and.to.be.a('object'); - expect(requestBid.site.publisher.id).to.exist.and.to.be.a('string'); - expect(requestBid.site.publisher.domain).to.exist.and.to.be.a('string'); - expect(requestBid.site.page).to.exist.and.to.be.a('string'); - expect(requestBid.site.content).to.exist.and.to.be.a('object'); - expect(requestBid.site.content.language).to.exist.and.to.be.a('string'); - expect(requestBid.site).to.deep.equal({ - publisher: { - id: '1234', - domain: 'test.com' - }, - content: { - language: 'en' - }, - page: 'http://mytestpage.com' - }); - }); - - it('adds appnexus aliases to request', function () { - config.setConfig({ s2sConfig: CONFIG }); - - const aliasBidder = { - bidder: 'brealtime', - params: { placementId: '123456' } - }; - - const request = utils.deepClone(REQUEST); - request.ad_units[0].bids = [aliasBidder]; - - adapter.callBids(request, BID_REQUESTS, addBidResponse, done, ajax); - - const requestBid = JSON.parse(server.requests[0].requestBody); - expect(requestBid.ext).to.haveOwnProperty('prebid'); - expect(requestBid.ext.prebid).to.deep.include({ - aliases: { - brealtime: 'appnexus' - }, - auctiontimestamp: 1510852447530, - targeting: { - includebidderkeys: false, - includewinners: true - } - }); - }); - - it('adds dynamic aliases to request', function () { - config.setConfig({ s2sConfig: CONFIG }); - - const alias = 'foobar'; - const aliasBidder = { - bidder: alias, - params: { placementId: '123456' } - }; - - const request = utils.deepClone(REQUEST); - request.ad_units[0].bids = [aliasBidder]; - - // TODO: stub this - $$PREBID_GLOBAL$$.aliasBidder('appnexus', alias); - adapter.callBids(request, BID_REQUESTS, addBidResponse, done, ajax); - - const requestBid = JSON.parse(server.requests[0].requestBody); - expect(requestBid.ext).to.haveOwnProperty('prebid'); - expect(requestBid.ext.prebid).to.deep.include({ - aliases: { - [alias]: 'appnexus' - }, - auctiontimestamp: 1510852447530, - targeting: { - includebidderkeys: false, - includewinners: true - } - }); - }); - - it('skips pbs alias when skipPbsAliasing is enabled in adapter', function() { - const s2sConfig = Object.assign({}, CONFIG, { - endpoint: { - p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction' - } - }); - config.setConfig({ s2sConfig: s2sConfig }); - - const aliasBidder = { - bidder: 'mediafuse', - params: { aid: 123 } - }; - - const request = utils.deepClone(REQUEST); - request.ad_units[0].bids = [aliasBidder]; - - adapter.callBids(request, BID_REQUESTS, addBidResponse, done, ajax); - - const requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.ext).to.deep.equal({ - prebid: { - auctiontimestamp: 1510852447530, - targeting: { - includebidderkeys: false, - includewinners: true - }, - channel: { - name: 'pbjs', - version: 'v$prebid.version$' - } - } - }); - }); - - it('skips dynamic aliases to request when skipPbsAliasing enabled', function () { - const s2sConfig = Object.assign({}, CONFIG, { - endpoint: { - p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction' - } - }); - config.setConfig({ s2sConfig: s2sConfig }); - - const alias = 'foobar_1'; - const aliasBidder = { - bidder: alias, - params: { aid: 123456 } - }; - - const request = utils.deepClone(REQUEST); - request.ad_units[0].bids = [aliasBidder]; - - // TODO: stub this - $$PREBID_GLOBAL$$.aliasBidder('appnexus', alias, { skipPbsAliasing: true }); - adapter.callBids(request, BID_REQUESTS, addBidResponse, done, ajax); - - const requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.ext).to.deep.equal({ - prebid: { - auctiontimestamp: 1510852447530, - targeting: { - includebidderkeys: false, - includewinners: true - }, - channel: { - name: 'pbjs', - version: 'v$prebid.version$' - } - } - }); - }); - - it('converts appnexus params to expected format for PBS', function () { - const s2sConfig = Object.assign({}, CONFIG, { - endpoint: { - p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction' - } - }); - config.setConfig({ s2sConfig: s2sConfig }); - - const myRequest = utils.deepClone(REQUEST); - myRequest.ad_units[0].bids[0].params.usePaymentRule = true; - myRequest.ad_units[0].bids[0].params.keywords = { - foo: ['bar', 'baz'], - fizz: ['buzz'] - }; - - adapter.callBids(myRequest, BID_REQUESTS, addBidResponse, done, ajax); - const requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.imp[0].ext.appnexus).to.exist; - expect(requestBid.imp[0].ext.appnexus.placement_id).to.exist.and.to.equal(10433394); - expect(requestBid.imp[0].ext.appnexus.use_pmt_rule).to.exist.and.to.be.true; - expect(requestBid.imp[0].ext.appnexus.member).to.exist; - expect(requestBid.imp[0].ext.appnexus.keywords).to.exist.and.to.deep.equal([{ - key: 'foo', - value: ['bar', 'baz'] - }, { - key: 'fizz', - value: ['buzz'] - }]); - }); - - it('adds limit to the cookie_sync request if userSyncLimit is greater than 0', function () { - let cookieSyncConfig = utils.deepClone(CONFIG); - cookieSyncConfig.syncEndpoint = { p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync' }; - cookieSyncConfig.userSyncLimit = 1; - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = cookieSyncConfig; - - config.setConfig({ s2sConfig: cookieSyncConfig }); - - let bidRequest = utils.deepClone(BID_REQUESTS); - adapter.callBids(s2sBidRequest, bidRequest, addBidResponse, done, ajax); - let requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.bidders).to.contain('appnexus').and.to.have.lengthOf(1); - expect(requestBid.account).is.equal('1'); - expect(requestBid.limit).is.equal(1); - }); - - it('does not add limit to cooke_sync request if userSyncLimit is missing or 0', function () { - let cookieSyncConfig = utils.deepClone(CONFIG); - cookieSyncConfig.syncEndpoint = { p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync' }; - config.setConfig({ s2sConfig: cookieSyncConfig }); - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = cookieSyncConfig; - - let bidRequest = utils.deepClone(BID_REQUESTS); - adapter.callBids(s2sBidRequest, bidRequest, addBidResponse, done, ajax); - let requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.bidders).to.contain('appnexus').and.to.have.lengthOf(1); - expect(requestBid.account).is.equal('1'); - expect(requestBid.limit).is.undefined; - - cookieSyncConfig.userSyncLimit = 0; - config.resetConfig(); - config.setConfig({ s2sConfig: cookieSyncConfig }); - - const s2sBidRequest2 = utils.deepClone(REQUEST); - s2sBidRequest2.s2sConfig = cookieSyncConfig; - - bidRequest = utils.deepClone(BID_REQUESTS); - adapter.callBids(s2sBidRequest2, bidRequest, addBidResponse, done, ajax); - requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.bidders).to.contain('appnexus').and.to.have.lengthOf(1); - expect(requestBid.account).is.equal('1'); - expect(requestBid.limit).is.undefined; - }); - - it('adds s2sConfig adapterOptions to request for ORTB', function () { - const s2sConfig = Object.assign({}, CONFIG, { - adapterOptions: { - appnexus: { - key: 'value' - } - } - }); - const _config = { - s2sConfig: s2sConfig, - device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' }, - app: { bundle: 'com.test.app' }, - }; - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = s2sConfig; - - config.setConfig(_config); - adapter.callBids(s2sBidRequest, BID_REQUESTS, addBidResponse, done, ajax); - const requestBid = JSON.parse(server.requests[0].requestBody); - expect(requestBid.imp[0].ext.appnexus).to.haveOwnProperty('key'); - expect(requestBid.imp[0].ext.appnexus.key).to.be.equal('value') - }); - - describe('config site value is added to the oRTB request', function () { - const s2sConfig = Object.assign({}, CONFIG, { - adapterOptions: { - appnexus: { - key: 'value' - } - } - }); - const device = { - ua: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36', - ip: '75.97.0.47' - }; - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = s2sConfig; - - it('and overrides publisher and page', function () { - config.setConfig({ - s2sConfig: s2sConfig, - site: { - domain: 'nytimes.com', - page: 'http://www.nytimes.com', - publisher: { id: '2' } - }, - device: device - }); - - adapter.callBids(s2sBidRequest, BID_REQUESTS, addBidResponse, done, ajax); - const requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.site).to.exist.and.to.be.a('object'); - expect(requestBid.site.domain).to.equal('nytimes.com'); - expect(requestBid.site.page).to.equal('http://www.nytimes.com'); - expect(requestBid.site.publisher).to.exist.and.to.be.a('object'); - expect(requestBid.site.publisher.id).to.equal('2'); - }); - - it('and merges domain and page with the config site value', function () { - config.setConfig({ - s2sConfig: s2sConfig, - site: { - foo: 'bar' - }, - device: device - }); - - adapter.callBids(s2sBidRequest, BID_REQUESTS, addBidResponse, done, ajax); - - const requestBid = JSON.parse(server.requests[0].requestBody); - expect(requestBid.site).to.exist.and.to.be.a('object'); - expect(requestBid.site.foo).to.equal('bar'); - expect(requestBid.site.page).to.equal('http://mytestpage.com'); - expect(requestBid.site.publisher).to.exist.and.to.be.a('object'); - expect(requestBid.site.publisher.id).to.equal('1'); - }); - }); - - it('when userId is defined on bids, it\'s properties should be copied to user.ext.tpid properties', function () { - let consentConfig = { s2sConfig: CONFIG }; - config.setConfig(consentConfig); - - let userIdBidRequest = utils.deepClone(BID_REQUESTS); - userIdBidRequest[0].bids[0].userId = { - criteoId: '44VmRDeUE3ZGJ5MzRkRVJHU3BIUlJ6TlFPQUFU', - tdid: 'abc123', - pubcid: '1234', - parrableId: { eid: '01.1563917337.test-eid' }, - lipb: { - lipbid: 'li-xyz', - segments: ['segA', 'segB'] - }, - idl_env: '0000-1111-2222-3333', - id5id: { - uid: '11111', - ext: { - linkType: 'some-link-type' - } - } - }; - userIdBidRequest[0].bids[0].userIdAsEids = createEidsArray(userIdBidRequest[0].bids[0].userId); - - adapter.callBids(REQUEST, userIdBidRequest, addBidResponse, done, ajax); - let requestBid = JSON.parse(server.requests[0].requestBody); - expect(typeof requestBid.user.ext.eids).is.equal('object'); - expect(Array.isArray(requestBid.user.ext.eids)).to.be.true; - expect(requestBid.user.ext.eids.filter(eid => eid.source === 'adserver.org')).is.not.empty; - expect(requestBid.user.ext.eids.filter(eid => eid.source === 'adserver.org')[0].uids[0].id).is.equal('abc123'); - expect(requestBid.user.ext.eids.filter(eid => eid.source === 'criteo.com')).is.not.empty; - expect(requestBid.user.ext.eids.filter(eid => eid.source === 'criteo.com')[0].uids[0].id).is.equal('44VmRDeUE3ZGJ5MzRkRVJHU3BIUlJ6TlFPQUFU'); - expect(requestBid.user.ext.eids.filter(eid => eid.source === 'pubcid.org')).is.not.empty; - expect(requestBid.user.ext.eids.filter(eid => eid.source === 'pubcid.org')[0].uids[0].id).is.equal('1234'); - expect(requestBid.user.ext.eids.filter(eid => eid.source === 'parrable.com')).is.not.empty; - expect(requestBid.user.ext.eids.filter(eid => eid.source === 'parrable.com')[0].uids[0].id).is.equal('01.1563917337.test-eid'); - expect(requestBid.user.ext.eids.filter(eid => eid.source === 'liveintent.com')).is.not.empty; - expect(requestBid.user.ext.eids.filter(eid => eid.source === 'liveintent.com')[0].uids[0].id).is.equal('li-xyz'); - expect(requestBid.user.ext.eids.filter(eid => eid.source === 'liveintent.com')[0].ext.segments.length).is.equal(2); - expect(requestBid.user.ext.eids.filter(eid => eid.source === 'liveintent.com')[0].ext.segments[0]).is.equal('segA'); - expect(requestBid.user.ext.eids.filter(eid => eid.source === 'liveintent.com')[0].ext.segments[1]).is.equal('segB'); - expect(requestBid.user.ext.eids.filter(eid => eid.source === 'id5-sync.com')).is.not.empty; - expect(requestBid.user.ext.eids.filter(eid => eid.source === 'id5-sync.com')[0].uids[0].id).is.equal('11111'); - expect(requestBid.user.ext.eids.filter(eid => eid.source === 'id5-sync.com')[0].uids[0].ext.linkType).is.equal('some-link-type'); - // LiveRamp should exist - expect(requestBid.user.ext.eids.filter(eid => eid.source === 'liveramp.com')[0].uids[0].id).is.equal('0000-1111-2222-3333'); - }); - - it('when config \'currency.adServerCurrency\' value is an array: ORTB has property \'cur\' value set to a single item array', function () { - config.setConfig({ - currency: { adServerCurrency: ['USD', 'GB', 'UK', 'AU'] }, - }); - - const bidRequests = utils.deepClone(BID_REQUESTS); - adapter.callBids(REQUEST, bidRequests, addBidResponse, done, ajax); - - const parsedRequestBody = JSON.parse(server.requests[0].requestBody); - expect(parsedRequestBody.cur).to.deep.equal(['USD']); - }); - - it('when config \'currency.adServerCurrency\' value is a string: ORTB has property \'cur\' value set to a single item array', function () { - config.setConfig({ - currency: { adServerCurrency: 'NZ' }, - }); - - const bidRequests = utils.deepClone(BID_REQUESTS); - adapter.callBids(REQUEST, bidRequests, addBidResponse, done, ajax); - - const parsedRequestBody = JSON.parse(server.requests[1].requestBody); - expect(parsedRequestBody.cur).to.deep.equal(['NZ']); - }); - - it('when config \'currency.adServerCurrency\' is unset: ORTB should not define a \'cur\' property', function () { - config.setConfig({ s2sConfig: CONFIG }); - - const bidRequests = utils.deepClone(BID_REQUESTS); - adapter.callBids(REQUEST, bidRequests, addBidResponse, done, ajax); - - const parsedRequestBody = JSON.parse(server.requests[0].requestBody); - expect(typeof parsedRequestBody.cur).to.equal('undefined'); - }); - - it('always add ext.prebid.targeting.includebidderkeys: false for ORTB', function () { - const s2sConfig = Object.assign({}, CONFIG, { - adapterOptions: { - appnexus: { - key: 'value' - } - } - }); - const _config = { - s2sConfig: s2sConfig, - device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' }, - app: { bundle: 'com.test.app' }, - }; - - config.setConfig(_config); - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = s2sConfig; - - adapter.callBids(s2sBidRequest, BID_REQUESTS, addBidResponse, done, ajax); - const requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.ext.prebid.targeting).to.haveOwnProperty('includebidderkeys'); - expect(requestBid.ext.prebid.targeting.includebidderkeys).to.equal(false); - }); - - it('always add ext.prebid.targeting.includewinners: true for ORTB', function () { - const s2sConfig = Object.assign({}, CONFIG, { - adapterOptions: { - appnexus: { - key: 'value' - } - } - }); - const _config = { - s2sConfig: s2sConfig, - device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' }, - app: { bundle: 'com.test.app' }, - }; - config.setConfig(_config); - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = s2sConfig; - - adapter.callBids(s2sBidRequest, BID_REQUESTS, addBidResponse, done, ajax); - const requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.ext.prebid.targeting).to.haveOwnProperty('includewinners'); - expect(requestBid.ext.prebid.targeting.includewinners).to.equal(true); - }); - - it('adds s2sConfig video.ext.prebid to request for ORTB', function () { - const s2sConfig = Object.assign({}, CONFIG, { - extPrebid: { - foo: 'bar' - } - }); - const _config = { - s2sConfig: s2sConfig, - device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' }, - app: { bundle: 'com.test.app' }, - }; - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = s2sConfig; - - config.setConfig(_config); - adapter.callBids(s2sBidRequest, BID_REQUESTS, addBidResponse, done, ajax); - const requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid).to.haveOwnProperty('ext'); - expect(requestBid.ext).to.haveOwnProperty('prebid'); - expect(requestBid.ext.prebid).to.deep.include({ - auctiontimestamp: 1510852447530, - foo: 'bar', - targeting: { - includewinners: true, - includebidderkeys: false - } - }); - }); - - it('overrides request.ext.prebid properties using s2sConfig video.ext.prebid values for ORTB', function () { - const s2sConfig = Object.assign({}, CONFIG, { - extPrebid: { - targeting: { - includewinners: false, - includebidderkeys: true - } - } - }); - const _config = { - s2sConfig: s2sConfig, - device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' }, - app: { bundle: 'com.test.app' }, - }; - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = s2sConfig; - - config.setConfig(_config); - adapter.callBids(s2sBidRequest, BID_REQUESTS, addBidResponse, done, ajax); - const requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid).to.haveOwnProperty('ext'); - expect(requestBid.ext).to.haveOwnProperty('prebid'); - expect(requestBid.ext.prebid).to.deep.include({ - auctiontimestamp: 1510852447530, - targeting: { - includewinners: false, - includebidderkeys: true - } - }); - }); - - it('overrides request.ext.prebid properties using s2sConfig video.ext.prebid values for ORTB', function () { - const s2sConfig = Object.assign({}, CONFIG, { - extPrebid: { - cache: { - vastxml: 'vastxml-set-though-extPrebid.cache.vastXml' - }, - targeting: { - includewinners: false, - includebidderkeys: false - } - } - }); - const _config = { - s2sConfig: s2sConfig, - device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' }, - app: { bundle: 'com.test.app' }, - }; - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = s2sConfig; - - config.setConfig(_config); - adapter.callBids(s2sBidRequest, BID_REQUESTS, addBidResponse, done, ajax); - const requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid).to.haveOwnProperty('ext'); - expect(requestBid.ext).to.haveOwnProperty('prebid'); - expect(requestBid.ext.prebid).to.deep.include({ - auctiontimestamp: 1510852447530, - cache: { - vastxml: 'vastxml-set-though-extPrebid.cache.vastXml' - }, - targeting: { - includewinners: false, - includebidderkeys: false - } - }); - }); - - it('passes schain object in request', function () { - const bidRequests = utils.deepClone(BID_REQUESTS); - const schainObject = { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'indirectseller.com', - 'sid': '00001', - 'hp': 1 - }, - - { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 2 - } - ] - }; - bidRequests[0].bids[0].schain = schainObject; - adapter.callBids(REQUEST, bidRequests, addBidResponse, done, ajax); - const parsedRequestBody = JSON.parse(server.requests[0].requestBody); - expect(parsedRequestBody.source.ext.schain).to.deep.equal(schainObject); - }); - - it('passes multibid array in request', function () { - const bidRequests = utils.deepClone(BID_REQUESTS); - const multibid = [{ - bidder: 'bidderA', - maxBids: 2 - }, { - bidder: 'bidderB', - maxBids: 2 - }]; - const expected = [{ - bidder: 'bidderA', - maxbids: 2 - }, { - bidder: 'bidderB', - maxbids: 2 - }]; - - config.setConfig({multibid: multibid}); - - adapter.callBids(REQUEST, bidRequests, addBidResponse, done, ajax); - const parsedRequestBody = JSON.parse(server.requests[0].requestBody); - expect(parsedRequestBody.ext.prebid.multibid).to.deep.equal(expected); - }); - - it('sets and passes pbjs version in request if channel does not exist in s2sConfig', () => { - const s2sBidRequest = utils.deepClone(REQUEST); - const bidRequests = utils.deepClone(BID_REQUESTS); - - adapter.callBids(s2sBidRequest, bidRequests, addBidResponse, done, ajax); - - const parsedRequestBody = JSON.parse(server.requests[0].requestBody); - expect(parsedRequestBody.ext.prebid.channel).to.deep.equal({name: 'pbjs', version: 'v$prebid.version$'}); - }); - - it('does not set pbjs version in request if channel does exist in s2sConfig', () => { - const s2sBidRequest = utils.deepClone(REQUEST); - const bidRequests = utils.deepClone(BID_REQUESTS); - - utils.deepSetValue(s2sBidRequest, 's2sConfig.extPrebid.channel', {test: 1}); - - adapter.callBids(s2sBidRequest, bidRequests, addBidResponse, done, ajax); - - const parsedRequestBody = JSON.parse(server.requests[0].requestBody); - expect(parsedRequestBody.ext.prebid.channel).to.deep.equal({test: 1}); - }); - - it('passes first party data in request', () => { - const s2sBidRequest = utils.deepClone(REQUEST); - const bidRequests = utils.deepClone(BID_REQUESTS); - - const commonContext = { - keywords: ['power tools'], - search: 'drill' - }; - const commonUser = { - keywords: ['a', 'b'], - gender: 'M' - }; - - const context = { - content: { userrating: 4 }, - data: { - pageType: 'article', - category: 'tools' - } - }; - const user = { - yob: '1984', - geo: { country: 'ca' }, - data: { - registered: true, - interests: ['cars'] - } - }; - const allowedBidders = [ 'rubicon', 'appnexus' ]; - - const expected = allowedBidders.map(bidder => ({ - bidders: [ bidder ], - config: { - ortb2: { - site: { - content: { userrating: 4 }, - ext: { - data: { - pageType: 'article', - category: 'tools' - } - } - }, - user: { - yob: '1984', - geo: { country: 'ca' }, - ext: { - data: { - registered: true, - interests: ['cars'] - } - } - } - } - } - })); - const commonContextExpected = utils.mergeDeep({'page': 'http://mytestpage.com', 'publisher': {'id': '1'}}, commonContext); - - config.setConfig({ fpd: { context: commonContext, user: commonUser } }); - config.setBidderConfig({ bidders: allowedBidders, config: { fpd: { context, user } } }); - adapter.callBids(s2sBidRequest, bidRequests, addBidResponse, done, ajax); - const parsedRequestBody = JSON.parse(server.requests[0].requestBody); - expect(parsedRequestBody.ext.prebid.bidderconfig).to.deep.equal(expected); - expect(parsedRequestBody.site).to.deep.equal(commonContextExpected); - expect(parsedRequestBody.user).to.deep.equal(commonUser); - }); - - describe('pbAdSlot config', function () { - it('should not send \"imp.ext.data.pbadslot\" if \"ortb2Imp.ext\" is undefined', function () { - const consentConfig = { s2sConfig: CONFIG }; - config.setConfig(consentConfig); - const bidRequest = utils.deepClone(REQUEST); - - adapter.callBids(bidRequest, BID_REQUESTS, addBidResponse, done, ajax); - const parsedRequestBody = JSON.parse(server.requests[0].requestBody); - - expect(parsedRequestBody.imp).to.be.a('array'); - expect(parsedRequestBody.imp[0]).to.be.a('object'); - expect(parsedRequestBody.imp[0]).to.not.have.deep.nested.property('ext.data.pbadslot'); - }); - - it('should not send \"imp.ext.data.pbadslot\" if \"ortb2Imp.ext.data.pbadslot\" is undefined', function () { - const consentConfig = { s2sConfig: CONFIG }; - config.setConfig(consentConfig); - const bidRequest = utils.deepClone(REQUEST); - bidRequest.ad_units[0].ortb2Imp = {}; - - adapter.callBids(bidRequest, BID_REQUESTS, addBidResponse, done, ajax); - const parsedRequestBody = JSON.parse(server.requests[0].requestBody); - - expect(parsedRequestBody.imp).to.be.a('array'); - expect(parsedRequestBody.imp[0]).to.be.a('object'); - expect(parsedRequestBody.imp[0]).to.not.have.deep.nested.property('ext.data.pbadslot'); - }); - - it('should not send \"imp.ext.data.pbadslot\" if \"ortb2Imp.ext.data.pbadslot\" is empty string', function () { - const consentConfig = { s2sConfig: CONFIG }; - config.setConfig(consentConfig); - const bidRequest = utils.deepClone(REQUEST); - bidRequest.ad_units[0].ortb2Imp = { - ext: { - data: { - pbadslot: '' - } - } - }; - - adapter.callBids(bidRequest, BID_REQUESTS, addBidResponse, done, ajax); - const parsedRequestBody = JSON.parse(server.requests[0].requestBody); - - expect(parsedRequestBody.imp).to.be.a('array'); - expect(parsedRequestBody.imp[0]).to.be.a('object'); - expect(parsedRequestBody.imp[0]).to.not.have.deep.nested.property('ext.data.pbadslot'); - }); - - it('should send \"imp.ext.data.pbadslot\" if \"ortb2Imp.ext.data.pbadslot\" value is a non-empty string', function () { - const consentConfig = { s2sConfig: CONFIG }; - config.setConfig(consentConfig); - const bidRequest = utils.deepClone(REQUEST); - bidRequest.ad_units[0].ortb2Imp = { - ext: { - data: { - pbadslot: '/a/b/c' - } - } - }; - - adapter.callBids(bidRequest, BID_REQUESTS, addBidResponse, done, ajax); - const parsedRequestBody = JSON.parse(server.requests[0].requestBody); - - expect(parsedRequestBody.imp).to.be.a('array'); - expect(parsedRequestBody.imp[0]).to.be.a('object'); - expect(parsedRequestBody.imp[0]).to.have.deep.nested.property('ext.data.pbadslot'); - expect(parsedRequestBody.imp[0].ext.data.pbadslot).to.equal('/a/b/c'); - }); - }); - - describe('GAM ad unit config', function () { - it('should not send \"imp.ext.data.adserver.adslot\" if \"ortb2Imp.ext\" is undefined', function () { - const consentConfig = { s2sConfig: CONFIG }; - config.setConfig(consentConfig); - const bidRequest = utils.deepClone(REQUEST); - - adapter.callBids(bidRequest, BID_REQUESTS, addBidResponse, done, ajax); - const parsedRequestBody = JSON.parse(server.requests[0].requestBody); - - expect(parsedRequestBody.imp).to.be.a('array'); - expect(parsedRequestBody.imp[0]).to.be.a('object'); - expect(parsedRequestBody.imp[0]).to.not.have.deep.nested.property('ext.data.adslot'); - }); - - it('should not send \"imp.ext.data.adserver.adslot\" if \"ortb2Imp.ext.data.adserver.adslot\" is undefined', function () { - const consentConfig = { s2sConfig: CONFIG }; - config.setConfig(consentConfig); - const bidRequest = utils.deepClone(REQUEST); - bidRequest.ad_units[0].ortb2Imp = {}; - - adapter.callBids(bidRequest, BID_REQUESTS, addBidResponse, done, ajax); - const parsedRequestBody = JSON.parse(server.requests[0].requestBody); - - expect(parsedRequestBody.imp).to.be.a('array'); - expect(parsedRequestBody.imp[0]).to.be.a('object'); - expect(parsedRequestBody.imp[0]).to.not.have.deep.nested.property('ext.data.adslot'); - }); - - it('should not send \"imp.ext.data.adserver.adslot\" if \"ortb2Imp.ext.data.adserver.adslot\" is empty string', function () { - const consentConfig = { s2sConfig: CONFIG }; - config.setConfig(consentConfig); - const bidRequest = utils.deepClone(REQUEST); - bidRequest.ad_units[0].ortb2Imp = { - ext: { - data: { - adserver: { - adslot: '' - } - } - } - }; - - adapter.callBids(bidRequest, BID_REQUESTS, addBidResponse, done, ajax); - const parsedRequestBody = JSON.parse(server.requests[0].requestBody); - - expect(parsedRequestBody.imp).to.be.a('array'); - expect(parsedRequestBody.imp[0]).to.be.a('object'); - expect(parsedRequestBody.imp[0]).to.not.have.deep.nested.property('ext.data.adslot'); - }); - - it('should send both \"adslot\" and \"name\" from \"imp.ext.data.adserver\" if \"ortb2Imp.ext.data.adserver.adslot\" and \"ortb2Imp.ext.data.adserver.name\" values are non-empty strings', function () { - const consentConfig = { s2sConfig: CONFIG }; - config.setConfig(consentConfig); - const bidRequest = utils.deepClone(REQUEST); - bidRequest.ad_units[0].ortb2Imp = { - ext: { - data: { - adserver: { - adslot: '/a/b/c', - name: 'adserverName1' - } - } - } - }; - - adapter.callBids(bidRequest, BID_REQUESTS, addBidResponse, done, ajax); - const parsedRequestBody = JSON.parse(server.requests[0].requestBody); - - expect(parsedRequestBody.imp).to.be.a('array'); - expect(parsedRequestBody.imp[0]).to.be.a('object'); - expect(parsedRequestBody.imp[0]).to.have.deep.nested.property('ext.data.adserver.adslot'); - expect(parsedRequestBody.imp[0]).to.have.deep.nested.property('ext.data.adserver.name'); - expect(parsedRequestBody.imp[0].ext.data.adserver.adslot).to.equal('/a/b/c'); - expect(parsedRequestBody.imp[0].ext.data.adserver.name).to.equal('adserverName1'); - }); - }); - }); - - describe('ext.prebid config', function () { - it('should send \"imp.ext.prebid.storedrequest.id\" if \"ortb2Imp.ext.prebid.storedrequest.id\" is set', function () { - const consentConfig = { s2sConfig: CONFIG }; - config.setConfig(consentConfig); - const bidRequest = utils.deepClone(REQUEST); - const storedRequestId = 'my-id'; - bidRequest.ad_units[0].ortb2Imp = { - ext: { - prebid: { - storedrequest: { - id: storedRequestId - } - } - } - }; - - adapter.callBids(bidRequest, BID_REQUESTS, addBidResponse, done, ajax); - const parsedRequestBody = JSON.parse(server.requests[0].requestBody); - - expect(parsedRequestBody.imp).to.be.a('array'); - expect(parsedRequestBody.imp[0]).to.be.a('object'); - expect(parsedRequestBody.imp[0]).to.have.deep.nested.property('ext.prebid.storedrequest.id'); - expect(parsedRequestBody.imp[0].ext.prebid.storedrequest.id).to.equal(storedRequestId); - }); - }); - - describe('response handler', function () { - beforeEach(function () { - sinon.stub(utils, 'triggerPixel'); - sinon.stub(utils, 'insertUserSyncIframe'); - sinon.stub(utils, 'logError'); - sinon.stub(events, 'emit'); - }); - - afterEach(function () { - utils.triggerPixel.restore(); - utils.insertUserSyncIframe.restore(); - utils.logError.restore(); - events.emit.restore(); - }); - - // TODO: test dependent on pbjs_api_spec. Needs to be isolated - it('does not call addBidResponse and calls done when ad unit not set', function () { - config.setConfig({ s2sConfig: CONFIG }); - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_NO_BID_NO_UNIT)); - - sinon.assert.notCalled(addBidResponse); - sinon.assert.calledOnce(done); - }); - - it('does not call addBidResponse and calls done when server requests cookie sync', function () { - config.setConfig({ s2sConfig: CONFIG }); - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_NO_COOKIE)); - - sinon.assert.notCalled(addBidResponse); - sinon.assert.calledOnce(done); - }); - - it('does not call addBidResponse and calls done when ad unit is set', function () { - config.setConfig({ s2sConfig: CONFIG }); - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_NO_BID_UNIT_SET)); - - sinon.assert.notCalled(addBidResponse); - sinon.assert.calledOnce(done); - }); - - it('registers successful bids and calls done when there are less bids than requests', function () { - config.setConfig({ s2sConfig: CONFIG }); - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB)); - - sinon.assert.calledOnce(addBidResponse); - sinon.assert.calledOnce(done); - - expect(addBidResponse.firstCall.args[0]).to.equal('div-gpt-ad-1460505748561-0'); - - expect(addBidResponse.firstCall.args[1]).to.have.property('requestId', '123'); - - expect(addBidResponse.firstCall.args[1]) - .to.have.property('statusMessage', 'Bid available'); - }); - - it('should have dealId in bidObject', function () { - config.setConfig({ s2sConfig: CONFIG }); - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB)); - const response = addBidResponse.firstCall.args[1]; - expect(response).to.have.property('dealId', 'test-dealid'); - }); - - it('should pass through default adserverTargeting if present in bidObject for video request', function () { - config.setConfig({s2sConfig: CONFIG}); - const cacheResponse = utils.deepClone(RESPONSE_OPENRTB); - const targetingTestData = { - hb_cache_path: '/cache', - hb_cache_host: 'prebid-cache.testurl.com' - }; - - cacheResponse.seatbid.forEach(item => { - item.bid[0].ext.prebid.targeting = targetingTestData - }); - adapter.callBids(VIDEO_REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(cacheResponse)); - - sinon.assert.calledOnce(addBidResponse); - const response = addBidResponse.firstCall.args[1]; - expect(response).to.have.property('adserverTargeting'); - expect(response.adserverTargeting).to.deep.equal({ - 'hb_cache_path': '/cache', - 'hb_cache_host': 'prebid-cache.testurl.com' - }); - }); - - it('should set the bidResponse currency to whats in the PBS response', function() { - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB)); - sinon.assert.calledOnce(addBidResponse); - const pbjsResponse = addBidResponse.firstCall.args[1]; - expect(pbjsResponse).to.have.property('currency', 'EUR'); - }); - - it('should set the default bidResponse currency when not specified in OpenRTB', function() { - let modifiedResponse = utils.deepClone(RESPONSE_OPENRTB); - modifiedResponse.cur = ''; - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(modifiedResponse)); - sinon.assert.calledOnce(addBidResponse); - const pbjsResponse = addBidResponse.firstCall.args[1]; - expect(pbjsResponse).to.have.property('currency', 'USD'); - }); - - it('should pass through default adserverTargeting if present in bidObject for banner request', function () { - const cacheResponse = utils.deepClone(RESPONSE_OPENRTB); - - const targetingTestData = { - 'foo': 'bar' - }; - - cacheResponse.seatbid.forEach(item => { - item.bid[0].ext.prebid.targeting = targetingTestData - }); - - config.setConfig({ s2sConfig: CONFIG }); - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(cacheResponse)); - sinon.assert.calledOnce(addBidResponse); - const response = addBidResponse.firstCall.args[1]; - expect(response).to.have.property('adserverTargeting').that.deep.equals({ 'foo': 'bar' }); - }); - - it('registers client user syncs when client bid adapter is present', function () { - let rubiconAdapter = { - registerSyncs: sinon.spy() - }; - sinon.stub(adapterManager, 'getBidAdapter').callsFake(() => rubiconAdapter); - - config.setConfig({ s2sConfig: CONFIG }); - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_NO_PBS_COOKIE)); - - sinon.assert.calledOnce(rubiconAdapter.registerSyncs); - - adapterManager.getBidAdapter.restore(); - }); - - it('registers client user syncs when using OpenRTB endpoint', function () { - let rubiconAdapter = { - registerSyncs: sinon.spy() - }; - sinon.stub(adapterManager, 'getBidAdapter').returns(rubiconAdapter); - - config.setConfig({ CONFIG }); - - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB)); - - sinon.assert.calledOnce(rubiconAdapter.registerSyncs); - - adapterManager.getBidAdapter.restore(); - }); - - it('handles OpenRTB responses and call BIDDER_DONE', function () { - config.setConfig({ CONFIG }); - - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB)); - - sinon.assert.calledOnce(events.emit); - const event = events.emit.firstCall.args; - expect(event[0]).to.equal(CONSTANTS.EVENTS.BIDDER_DONE); - expect(event[1].bids[0]).to.have.property('serverResponseTimeMs', 8); - - sinon.assert.calledOnce(addBidResponse); - const response = addBidResponse.firstCall.args[1]; - expect(response).to.have.property('statusMessage', 'Bid available'); - expect(response).to.have.property('bidderCode', 'appnexus'); - expect(response).to.have.property('requestId', '123'); - expect(response).to.have.property('cpm', 0.5); - expect(response).to.have.property('meta'); - expect(response.meta).to.have.property('advertiserDomains'); - expect(response.meta.advertiserDomains[0]).to.equal('appnexus.com'); - expect(response.meta).to.have.property('dchain'); - expect(response.meta.dchain.ver).to.equal('1.0'); - expect(response.meta.dchain.nodes[0].asi).to.equal('magnite.com'); - expect(response).to.not.have.property('vastUrl'); - expect(response).to.not.have.property('videoCacheKey'); - expect(response).to.have.property('ttl', 60); - }); - - it('respects defaultTtl', function () { - const s2sConfig = Object.assign({}, CONFIG, { - defaultTtl: 30 - }); - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = s2sConfig; - - adapter.callBids(s2sBidRequest, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB)); - - sinon.assert.calledOnce(events.emit); - const event = events.emit.firstCall.args; - sinon.assert.calledOnce(addBidResponse); - const response = addBidResponse.firstCall.args[1]; - expect(response).to.have.property('ttl', 30); - }); - - it('handles OpenRTB video responses', function () { - const s2sConfig = Object.assign({}, CONFIG, { - endpoint: { - p1Consent: 'https://prebidserverurl/openrtb2/auction?querystring=param' - } - }); - config.setConfig({ s2sConfig }); - - const s2sVidRequest = utils.deepClone(VIDEO_REQUEST); - s2sVidRequest.s2sConfig = s2sConfig; - - adapter.callBids(s2sVidRequest, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB_VIDEO)); - - sinon.assert.calledOnce(addBidResponse); - const response = addBidResponse.firstCall.args[1]; - expect(response).to.have.property('statusMessage', 'Bid available'); - expect(response).to.have.property('vastXml', RESPONSE_OPENRTB_VIDEO.seatbid[0].bid[0].adm); - expect(response).to.have.property('mediaType', 'video'); - expect(response).to.have.property('bidderCode', 'appnexus'); - expect(response).to.have.property('requestId', '123'); - expect(response).to.have.property('cpm', 10); - }); - - it('handles response cache from ext.prebid.cache.vastXml', function () { - const s2sConfig = Object.assign({}, CONFIG, { - endpoint: { - p1Consent: 'https://prebidserverurl/openrtb2/auction?querystring=param' - } - }); - config.setConfig({ s2sConfig }); - const cacheResponse = utils.deepClone(RESPONSE_OPENRTB_VIDEO); - cacheResponse.seatbid.forEach(item => { - item.bid[0].ext.prebid.cache = { - vastXml: { - cacheId: 'abcd1234', - url: 'https://prebid-cache.net/cache?uuid=abcd1234' - } - } - }); - - const s2sVidRequest = utils.deepClone(VIDEO_REQUEST); - s2sVidRequest.s2sConfig = s2sConfig; - - adapter.callBids(s2sVidRequest, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(cacheResponse)); - - sinon.assert.calledOnce(addBidResponse); - const response = addBidResponse.firstCall.args[1]; - - expect(response).to.have.property('statusMessage', 'Bid available'); - expect(response).to.have.property('videoCacheKey', 'abcd1234'); - expect(response).to.have.property('vastUrl', 'https://prebid-cache.net/cache?uuid=abcd1234'); - }); - - it('add adserverTargeting object to bids when ext.prebid.targeting is defined', function () { - const s2sConfig = Object.assign({}, CONFIG, { - endpoint: { - p1Consent: 'https://prebidserverurl/openrtb2/auction?querystring=param' - } - }); - config.setConfig({ s2sConfig }); - const cacheResponse = utils.deepClone(RESPONSE_OPENRTB_VIDEO); - const targetingTestData = { - hb_cache_path: '/cache', - hb_cache_host: 'prebid-cache.testurl.com' - }; - - cacheResponse.seatbid.forEach(item => { - item.bid[0].ext.prebid.targeting = targetingTestData - }); - - const s2sVidRequest = utils.deepClone(VIDEO_REQUEST); - s2sVidRequest.s2sConfig = s2sConfig; - - adapter.callBids(s2sVidRequest, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(cacheResponse)); - - sinon.assert.calledOnce(addBidResponse); - const response = addBidResponse.firstCall.args[1]; - - expect(response).to.have.property('adserverTargeting'); - expect(response.adserverTargeting).to.deep.equal({ - 'hb_cache_path': '/cache', - 'hb_cache_host': 'prebid-cache.testurl.com' - }); - }); - - it('handles response cache from ext.prebid.targeting', function () { - const s2sConfig = Object.assign({}, CONFIG, { - endpoint: { - p1Consent: 'https://prebidserverurl/openrtb2/auction?querystring=param' - } - }); - config.setConfig({ s2sConfig }); - const cacheResponse = utils.deepClone(RESPONSE_OPENRTB_VIDEO); - cacheResponse.seatbid.forEach(item => { - item.bid[0].ext.prebid.targeting = { - hb_uuid: 'a5ad3993', - hb_cache_host: 'prebid-cache.net', - hb_cache_path: '/cache' - } - }); - - const s2sVidRequest = utils.deepClone(VIDEO_REQUEST); - s2sVidRequest.s2sConfig = s2sConfig; - - adapter.callBids(s2sVidRequest, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(cacheResponse)); - - sinon.assert.calledOnce(addBidResponse); - const response = addBidResponse.firstCall.args[1]; - - expect(response).to.have.property('statusMessage', 'Bid available'); - expect(response).to.have.property('videoCacheKey', 'a5ad3993'); - expect(response).to.have.property('vastUrl', 'https://prebid-cache.net/cache?uuid=a5ad3993'); - }); - - it('handles response cache from ext.prebid.targeting with wurl', function () { - const s2sConfig = Object.assign({}, CONFIG, { - endpoint: { - p1Consent: 'https://prebidserverurl/openrtb2/auction?querystring=param' - } - }); - config.setConfig({ s2sConfig }); - const cacheResponse = utils.deepClone(RESPONSE_OPENRTB_VIDEO); - cacheResponse.seatbid.forEach(item => { - item.bid[0].ext.prebid.events = { - win: 'https://wurl.com?a=1&b=2' - }; - item.bid[0].ext.prebid.targeting = { - hb_uuid: 'a5ad3993', - hb_cache_host: 'prebid-cache.net', - hb_cache_path: '/cache' - } - }); - const s2sVidRequest = utils.deepClone(VIDEO_REQUEST); - s2sVidRequest.s2sConfig = s2sConfig; - - adapter.callBids(s2sVidRequest, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(cacheResponse)); - - sinon.assert.calledOnce(addBidResponse); - const response = addBidResponse.firstCall.args[1]; - expect(response).to.have.property('pbsBidId', '654321'); - }); - - it('handles response cache from ext.prebid.targeting with wurl and removes invalid targeting', function () { - const s2sConfig = Object.assign({}, CONFIG, { - endpoint: { - p1Consent: 'https://prebidserverurl/openrtb2/auction?querystring=param' - } - }); - config.setConfig({ s2sConfig }); - const cacheResponse = utils.deepClone(RESPONSE_OPENRTB_VIDEO); - cacheResponse.seatbid.forEach(item => { - item.bid[0].ext.prebid.events = { - win: 'https://wurl.com?a=1&b=2' - }; - item.bid[0].ext.prebid.targeting = { - hb_uuid: 'a5ad3993', - hb_cache_host: 'prebid-cache.net', - hb_cache_path: '/cache', - hb_winurl: 'https://hbwinurl.com?a=1&b=2', - hb_bidid: '1234567890', - } - }); - - const s2sVidRequest = utils.deepClone(VIDEO_REQUEST); - s2sVidRequest.s2sConfig = s2sConfig; - - adapter.callBids(s2sVidRequest, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(cacheResponse)); - - sinon.assert.calledOnce(addBidResponse); - const response = addBidResponse.firstCall.args[1]; - - expect(response.adserverTargeting).to.deep.equal({ - hb_uuid: 'a5ad3993', - hb_cache_host: 'prebid-cache.net', - hb_cache_path: '/cache' - }); - }); - - it('add request property pbsBidId with ext.prebid.bidid value', function () { - const s2sConfig = Object.assign({}, CONFIG, { - endpoint: { - p1Consent: 'https://prebidserverurl/openrtb2/auction?querystring=param' - } - }); - config.setConfig({ s2sConfig }); - const cacheResponse = utils.deepClone(RESPONSE_OPENRTB_VIDEO); - - const s2sVidRequest = utils.deepClone(VIDEO_REQUEST); - s2sVidRequest.s2sConfig = s2sConfig; - - adapter.callBids(s2sVidRequest, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(cacheResponse)); - - sinon.assert.calledOnce(addBidResponse); - const response = addBidResponse.firstCall.args[1]; - - expect(response).to.have.property('pbsBidId', '654321'); - }); - - it('handles OpenRTB native responses', function () { - sinon.stub(utils, 'getBidRequest').returns({ - adUnitCode: 'div-gpt-ad-1460505748561-0', - bidder: 'appnexus', - bidId: '123' - }); - const s2sConfig = Object.assign({}, CONFIG, { - endpoint: { - p1Consent: 'https://prebidserverurl/openrtb2/auction?querystring=param' - } - }); - config.setConfig({ s2sConfig }); - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = s2sConfig; - - adapter.callBids(s2sBidRequest, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(RESPONSE_OPENRTB_NATIVE)); - - sinon.assert.calledOnce(addBidResponse); - const response = addBidResponse.firstCall.args[1]; - expect(response).to.have.property('statusMessage', 'Bid available'); - expect(response).to.have.property('adm').deep.equal(RESPONSE_OPENRTB_NATIVE.seatbid[0].bid[0].adm); - expect(response).to.have.property('mediaType', 'native'); - expect(response).to.have.property('bidderCode', 'appnexus'); - expect(response).to.have.property('requestId', '123'); - expect(response).to.have.property('cpm', 10); - - utils.getBidRequest.restore(); - }); - }); - - describe('bid won events', function () { - let uniqueIdCount = 0; - let triggerPixelStub; - const staticUniqueIds = ['1000', '1001', '1002', '1003']; - - before(function () { - triggerPixelStub = sinon.stub(utils, 'triggerPixel'); - }); - - beforeEach(function () { - resetWurlMap(); - sinon.stub(utils, 'insertUserSyncIframe'); - sinon.stub(utils, 'logError'); - sinon.stub(utils, 'getUniqueIdentifierStr').callsFake(() => { - uniqueIdCount++; - return staticUniqueIds[uniqueIdCount - 1]; - }); - triggerPixelStub.resetHistory(); - - config.setConfig({ - s2sConfig: Object.assign({}, CONFIG, { - endpoint: { - p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction' - } - }) - }); - }); - - afterEach(function () { - utils.triggerPixel.resetHistory(); - utils.insertUserSyncIframe.restore(); - utils.logError.restore(); - utils.getUniqueIdentifierStr.restore(); - uniqueIdCount = 0; - }); - - after(function () { - triggerPixelStub.restore(); - }); - - it('should call triggerPixel if wurl is defined', function () { - const clonedResponse = utils.deepClone(RESPONSE_OPENRTB); - clonedResponse.seatbid[0].bid[0].ext.prebid.events = { - win: 'https://wurl.org' - }; - - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(clonedResponse)); - - events.emit(CONSTANTS.EVENTS.BID_WON, { - auctionId: '173afb6d132ba3', - adId: '1000' - }); - - sinon.assert.calledOnce(addBidResponse); - expect(utils.triggerPixel.called).to.be.true; - expect(utils.triggerPixel.getCall(0).args[0]).to.include('https://wurl.org'); - }); - - it('should not call triggerPixel if the wurl cache does not contain the winning bid', function () { - const clonedResponse = utils.deepClone(RESPONSE_OPENRTB); - clonedResponse.seatbid[0].bid[0].ext.prebid.events = { - win: 'https://wurl.org' - }; - - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(clonedResponse)); - - events.emit(CONSTANTS.EVENTS.BID_WON, { - auctionId: '173afb6d132ba3', - adId: 'missingAdId' - }); - - sinon.assert.calledOnce(addBidResponse) - expect(utils.triggerPixel.called).to.be.false; - }); - - it('should not call triggerPixel if wurl is undefined', function () { - const clonedResponse = utils.deepClone(RESPONSE_OPENRTB); - clonedResponse.seatbid[0].bid[0].ext.prebid.events = {}; - - adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); - server.requests[0].respond(200, {}, JSON.stringify(clonedResponse)); - - events.emit(CONSTANTS.EVENTS.BID_WON, { - auctionId: '173afb6d132ba3', - adId: '1060' - }); - - sinon.assert.calledOnce(addBidResponse) - expect(utils.triggerPixel.called).to.be.false; - }); - }) - - describe('s2sConfig', function () { - let logErrorSpy; - - beforeEach(function () { - logErrorSpy = sinon.spy(utils, 'logError'); - resetSyncedStatus(); - }); - - afterEach(function () { - utils.logError.restore(); - }); - - it('should log an error when accountId is missing', function () { - const options = { - enabled: true, - bidders: ['appnexus'], - timeout: 1000, - adapter: 'prebidServer', - endpoint: { - p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction' - } - }; - - config.setConfig({ s2sConfig: options }); - sinon.assert.calledOnce(logErrorSpy); - }); - - it('should log an error when bidders is missing', function () { - const options = { - accountId: '1', - enabled: true, - timeout: 1000, - adapter: 's2s', - endpoint: { - p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction' - } - }; - - config.setConfig({ s2sConfig: options }); - sinon.assert.calledOnce(logErrorSpy); - }); - - it('should log an error when endpoint is missing', function () { - const options = { - accountId: '1', - bidders: ['appnexus'], - timeout: 1000, - enabled: true, - adapter: 'prebidServer' - }; - - config.setConfig({ s2sConfig: options }); - sinon.assert.calledOnce(logErrorSpy); - }); - - it('should log an error when using an unknown vendor', function () { - const options = { - accountId: '1', - bidders: ['appnexus'], - defaultVendor: 'mytest' - }; - - config.setConfig({ s2sConfig: options }); - sinon.assert.calledOnce(logErrorSpy); - }); - - it('should configure the s2sConfig object with appnexus vendor defaults unless specified by user', function () { - const options = { - accountId: '123', - bidders: ['appnexus'], - defaultVendor: 'appnexus', - timeout: 750 - }; - - config.setConfig({ s2sConfig: options }); - sinon.assert.notCalled(logErrorSpy); - - let vendorConfig = config.getConfig('s2sConfig'); - expect(vendorConfig).to.have.property('accountId', '123'); - expect(vendorConfig).to.have.property('adapter', 'prebidServer'); - expect(vendorConfig.bidders).to.deep.equal(['appnexus']); - expect(vendorConfig.enabled).to.be.true; - expect(vendorConfig.endpoint).to.deep.equal({p1Consent: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction', noP1Consent: 'https://prebid.adnxs-simple.com/pbs/v1/openrtb2/auction'}); - expect(vendorConfig.syncEndpoint).to.deep.equal({p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync', noP1Consent: 'https://prebid.adnxs-simple.com/pbs/v1/cookie_sync'}); - expect(vendorConfig).to.have.property('timeout', 750); - }); - - it('should configure the s2sConfig object with rubicon vendor defaults unless specified by user', function () { - const options = { - accountId: 'abc', - bidders: ['rubicon'], - defaultVendor: 'rubicon', - timeout: 750 - }; - - config.setConfig({ s2sConfig: options }); - sinon.assert.notCalled(logErrorSpy); - - let vendorConfig = config.getConfig('s2sConfig'); - expect(vendorConfig).to.have.property('accountId', 'abc'); - expect(vendorConfig).to.have.property('adapter', 'prebidServer'); - expect(vendorConfig.bidders).to.deep.equal(['rubicon']); - expect(vendorConfig.enabled).to.be.true; - expect(vendorConfig.endpoint).to.deep.equal({p1Consent: 'https://prebid-server.rubiconproject.com/openrtb2/auction', noP1Consent: 'https://prebid-server.rubiconproject.com/openrtb2/auction'}); - expect(vendorConfig.syncEndpoint).to.deep.equal({p1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync', noP1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync'}); - expect(vendorConfig).to.have.property('timeout', 750); - }); - - it('should return proper defaults', function () { - const options = { - accountId: 'abc', - bidders: ['rubicon'], - defaultVendor: 'rubicon', - timeout: 750 - }; - - config.setConfig({ s2sConfig: options }); - expect(config.getConfig('s2sConfig')).to.deep.equal({ - 'accountId': 'abc', - 'adapter': 'prebidServer', - 'bidders': ['rubicon'], - 'defaultVendor': 'rubicon', - 'enabled': true, - 'endpoint': {p1Consent: 'https://prebid-server.rubiconproject.com/openrtb2/auction', noP1Consent: 'https://prebid-server.rubiconproject.com/openrtb2/auction'}, - 'syncEndpoint': {p1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync', noP1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync'}, - 'timeout': 750 - }) - }); - - it('should return default adapterOptions if not set', function () { - config.setConfig({ - s2sConfig: { - accountId: 'abc', - bidders: ['rubicon'], - defaultVendor: 'rubicon', - timeout: 750 - } - }); - expect(config.getConfig('s2sConfig')).to.deep.equal({ - enabled: true, - timeout: 750, - adapter: 'prebidServer', - accountId: 'abc', - bidders: ['rubicon'], - defaultVendor: 'rubicon', - endpoint: {p1Consent: 'https://prebid-server.rubiconproject.com/openrtb2/auction', noP1Consent: 'https://prebid-server.rubiconproject.com/openrtb2/auction'}, - syncEndpoint: {p1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync', noP1Consent: 'https://prebid-server.rubiconproject.com/cookie_sync'}, - }) - }); - - it('should set adapterOptions', function () { - config.setConfig({ - s2sConfig: { - adapterOptions: { - rubicon: { - singleRequest: true, - foo: 'bar' - } - } - } - }); - expect(config.getConfig('s2sConfig').adapterOptions).to.deep.equal({ - rubicon: { - singleRequest: true, - foo: 'bar' - } - }) - }); - - it('should set default s2s ttl', function () { - config.setConfig({ - s2sConfig: { - defaultTtl: 30 - } - }); - expect(config.getConfig('s2sConfig').defaultTtl).to.deep.equal(30); - }); - - it('should set syncUrlModifier', function () { - config.setConfig({ - s2sConfig: { - syncUrlModifier: { - appnexus: () => { } - } - } - }); - expect(typeof config.getConfig('s2sConfig').syncUrlModifier.appnexus).to.equal('function') - }); - - it('should set correct bidder names to bidders property when using an alias for that bidder', function () { - const s2sConfig = utils.deepClone(CONFIG); - - // 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.bidders = ['appnexus', 'rubicon-alias']; - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = s2sConfig; - - // Add another bidder, `rubicon-alias` - s2sBidRequest.ad_units[0].bids.push({ - bidder: 'rubicon-alias', - params: { - accoundId: 14062, - siteId: 70608, - zoneId: 498816 - } - }); - - // create an alias for the Rubicon Bid Adapter - adapterManager.aliasBidAdapter('rubicon', 'rubicon-alias'); - - const bidRequest = utils.deepClone(BID_REQUESTS); - bidRequest.push({ - 'bidderCode': 'rubicon-alias', - 'auctionId': '4146ab2b-9422-4040-9b1c-966fffbfe2d4', - 'bidderRequestId': '4b1a4f9c3e4546', - 'tid': 'd7fa8342-ae22-4ca1-b237-331169350f84', - 'bids': [ - { - 'bidder': 'rubicon-alias', - 'params': { - 'accountId': 14062, - 'siteId': 70608, - 'zoneId': 498816 - }, - 'bid_id': '2a9523915411c3', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': '78ddc106-b7d8-45d1-bd29-86993098e53d', - 'sizes': [ - [ - 300, - 250 - ] - ], - 'bidId': '2a9523915411c3', - 'bidderRequestId': '4b1a4f9c3e4546', - 'auctionId': '4146ab2b-9422-4040-9b1c-966fffbfe2d4' - } - ], - 'auctionStart': 1569234122602, - 'timeout': 1000, - 'src': 's2s' - }); - - adapter.callBids(s2sBidRequest, bidRequest, addBidResponse, done, ajax); - - const requestBid = JSON.parse(server.requests[0].requestBody); - expect(requestBid.bidders).to.deep.equal(['appnexus', 'rubicon']); - }); - - it('should add cooperative sync flag to cookie_sync request if property is present', function () { - let s2sConfig = utils.deepClone(CONFIG); - s2sConfig.coopSync = false; - s2sConfig.syncEndpoint = {p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync'}; - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = s2sConfig; - - let bidRequest = utils.deepClone(BID_REQUESTS); - - adapter.callBids(s2sBidRequest, bidRequest, addBidResponse, done, ajax); - let requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.coopSync).to.equal(false); - }); - - it('should not add cooperative sync flag to cookie_sync request if property is not present', function () { - let s2sConfig = utils.deepClone(CONFIG); - s2sConfig.syncEndpoint = {p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync'}; - - const s2sBidRequest = utils.deepClone(REQUEST); - s2sBidRequest.s2sConfig = s2sConfig; - - let bidRequest = utils.deepClone(BID_REQUESTS); - - adapter.callBids(s2sBidRequest, bidRequest, addBidResponse, done, ajax); - let requestBid = JSON.parse(server.requests[0].requestBody); - - expect(requestBid.coopSync).to.be.undefined; - }); - }); -}); diff --git a/test/spec/modules/prebidmanagerAnalyticsAdapter_spec.js b/test/spec/modules/prebidmanagerAnalyticsAdapter_spec.js deleted file mode 100644 index 2505af0c2a7..00000000000 --- a/test/spec/modules/prebidmanagerAnalyticsAdapter_spec.js +++ /dev/null @@ -1,160 +0,0 @@ -import prebidmanagerAnalytics, { - storage -} from 'modules/prebidmanagerAnalyticsAdapter.js'; -import {expect} from 'chai'; -import {server} from 'test/mocks/xhr.js'; -import * as utils from 'src/utils.js'; - -let events = require('src/events'); -let constants = require('src/constants.json'); - -describe('Prebid Manager Analytics Adapter', function () { - let bidWonEvent = { - 'bidderCode': 'appnexus', - 'width': 300, - 'height': 250, - 'adId': '1ebb82ec35375e', - 'mediaType': 'banner', - 'cpm': 0.5, - 'requestId': '1582271863760569973', - 'creative_id': '96846035', - 'creativeId': '96846035', - 'ttl': 60, - 'currency': 'USD', - 'netRevenue': true, - 'auctionId': '9c7b70b9-b6ab-4439-9e71-b7b382797c18', - 'responseTimestamp': 1537521629657, - 'requestTimestamp': 1537521629331, - 'bidder': 'appnexus', - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'timeToRespond': 326, - 'size': '300x250', - 'status': 'rendered', - 'eventType': 'bidWon', - 'ad': 'some ad', - 'adUrl': 'ad url' - }; - - describe('Prebid Manager Analytic tests', function () { - beforeEach(function () { - sinon.stub(events, 'getEvents').returns([]); - }); - - afterEach(function () { - prebidmanagerAnalytics.disableAnalytics(); - events.getEvents.restore(); - }); - - it('support custom endpoint', function () { - let custom_url = 'custom url'; - prebidmanagerAnalytics.enableAnalytics({ - provider: 'prebidmanager', - options: { - url: custom_url, - bundleId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' - } - }); - - expect(prebidmanagerAnalytics.getOptions().url).to.equal(custom_url); - }); - - it('bid won event', function() { - let bundleId = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'; - prebidmanagerAnalytics.enableAnalytics({ - provider: 'prebidmanager', - options: { - bundleId: bundleId - } - }); - - events.emit(constants.EVENTS.BID_WON, bidWonEvent); - prebidmanagerAnalytics.flush(); - - expect(server.requests.length).to.equal(1); - expect(server.requests[0].url).to.equal('https://endpoint.prebidmanager.com/endpoint'); - expect(server.requests[0].requestBody.substring(0, 2)).to.equal('1:'); - - const pmEvents = JSON.parse(server.requests[0].requestBody.substring(2)); - expect(pmEvents.pageViewId).to.exist; - expect(pmEvents.bundleId).to.equal(bundleId); - expect(pmEvents.ver).to.equal(1); - expect(pmEvents.events.length).to.equal(2); - expect(pmEvents.events[0].eventType).to.equal('pageView'); - expect(pmEvents.events[1].eventType).to.equal('bidWon'); - expect(pmEvents.events[1].ad).to.be.undefined; - expect(pmEvents.events[1].adUrl).to.be.undefined; - }); - - it('track event without errors', function () { - sinon.spy(prebidmanagerAnalytics, 'track'); - - prebidmanagerAnalytics.enableAnalytics({ - provider: 'prebidmanager', - options: { - bundleId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' - } - }); - - events.emit(constants.EVENTS.AUCTION_INIT, {}); - events.emit(constants.EVENTS.BID_REQUESTED, {}); - events.emit(constants.EVENTS.BID_RESPONSE, {}); - events.emit(constants.EVENTS.BID_WON, {}); - events.emit(constants.EVENTS.AUCTION_END, {}); - events.emit(constants.EVENTS.BID_TIMEOUT, {}); - - sinon.assert.callCount(prebidmanagerAnalytics.track, 6); - }); - }); - - describe('build utm tag data', function () { - let getDataFromLocalStorageStub; - beforeEach(function () { - getDataFromLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage'); - getDataFromLocalStorageStub.withArgs('pm_utm_source').returns('utm_source'); - getDataFromLocalStorageStub.withArgs('pm_utm_medium').returns('utm_medium'); - getDataFromLocalStorageStub.withArgs('pm_utm_campaign').returns('utm_camp'); - getDataFromLocalStorageStub.withArgs('pm_utm_term').returns(''); - getDataFromLocalStorageStub.withArgs('pm_utm_content').returns(''); - getDataFromLocalStorageStub.withArgs('pm_utm_source').returns('utm_source'); - }); - afterEach(function () { - getDataFromLocalStorageStub.restore(); - prebidmanagerAnalytics.disableAnalytics() - }); - it('should build utm data from local storage', function () { - prebidmanagerAnalytics.enableAnalytics({ - provider: 'prebidmanager', - options: { - bundleId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' - } - }); - - const pmEvents = JSON.parse(server.requests[0].requestBody.substring(2)); - - expect(pmEvents.utmTags.utm_source).to.equal('utm_source'); - expect(pmEvents.utmTags.utm_medium).to.equal('utm_medium'); - expect(pmEvents.utmTags.utm_campaign).to.equal('utm_camp'); - expect(pmEvents.utmTags.utm_term).to.equal(''); - expect(pmEvents.utmTags.utm_content).to.equal(''); - }); - }); - - describe('build page info', function () { - afterEach(function () { - prebidmanagerAnalytics.disableAnalytics() - }); - it('should build page info', function () { - prebidmanagerAnalytics.enableAnalytics({ - provider: 'prebidmanager', - options: { - bundleId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' - } - }); - - const pmEvents = JSON.parse(server.requests[0].requestBody.substring(2)); - - expect(pmEvents.pageInfo.domain).to.equal(window.location.hostname); - expect(pmEvents.pageInfo.referrerDomain).to.equal(utils.parseUrl(document.referrer).hostname); - }); - }); -}); diff --git a/test/spec/modules/priceFloorsSchema.json b/test/spec/modules/priceFloorsSchema.json deleted file mode 100644 index 7b524da381e..00000000000 --- a/test/spec/modules/priceFloorsSchema.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-06/schema#", - "description": "A Price Floors object which is parsed and used to enforce dynamic floors depending on the properties of the json", - "type": "object", - "title": "Price Floors Enforcement", - "required": [ - "schema", - "values" - ], - "properties": { - "schema": { - "type": "object", - "description": "Defines the schema of the rules", - "required": [ - "fields" - ], - "properties": { - "fields": { - "type": "array", - "description": "The list of fields to be used for matching criteria of a bid response with a price floor", - "minItems": 1, - "uniqueItems": true, - "additionalItems": false, - "items": { - "type": "string" - } - }, - "delimiter": { - "type": "string", - "description": "The character used to differentiate the fields inside a single rule", - "examples": [ - "|", - "^", - "~" - ] - } - } - }, - "values": { - "type": "object", - "description": "A object with key : value pairs which constitutes a rule and floor", - "additionalProperties": { - "type": "number" - }, - "minProperties": 1, - "examples": [ - { - "123456/someSlot|300x250|www.prebid.org": 1.5, - "123456/someSlot|300x600|www.prebid.org": 2.5, - "123456/someSlot|300x600|*": 1.2, - "123456/someSlot|*|*": 0.8 - } - ] - }, - "currency": { - "type": "string", - "description": "The three digit Currency Code which the floors are provided in", - "examples": [ - "USD", - "EUR", - "JPY" - ], - "pattern": "^[a-zA-Z]{3}$" - }, - "modelVersion": { - "type": "string", - "description": "The floor modeling name to be used for tracking", - "examples": [ - "Prebid-Floor-Model-1.2" - ] - }, - "skipRate": { - "type": "integer", - "description": "The skip rate as to which flooring will be 'turned off' for a given auction", - "minimum": 0, - "maximum": 100 - }, - "default": { - "type": "number", - "description": "The default floor to use if no entry in the value matches a bid response", - "examples": [ - 0.75 - ] - } - } -} \ No newline at end of file diff --git a/test/spec/modules/priceFloors_spec.js b/test/spec/modules/priceFloors_spec.js deleted file mode 100644 index 548d2789d3e..00000000000 --- a/test/spec/modules/priceFloors_spec.js +++ /dev/null @@ -1,1646 +0,0 @@ -import {expect} from 'chai'; -import * as utils from 'src/utils.js'; -import { getGlobal } from 'src/prebidGlobal.js'; -import CONSTANTS from 'src/constants.json'; -import { - _floorDataForAuction, - getFloorsDataForAuction, - getFirstMatchingFloor, - getFloor, - handleSetFloorsConfig, - requestBidsHook, - isFloorsDataValid, - addBidResponseHook, - fieldMatchingFunctions, - allowedFields -} from 'modules/priceFloors.js'; -import events from 'src/events.js'; - -describe('the price floors module', function () { - let logErrorSpy; - let logWarnSpy; - let sandbox; - let clock; - const basicFloorData = { - modelVersion: 'basic model', - modelWeight: 10, - modelTimestamp: 1606772895, - currency: 'USD', - schema: { - delimiter: '|', - fields: ['mediaType'] - }, - values: { - 'banner': 1.0, - 'video': 5.0, - '*': 2.5 - } - }; - const basicFloorDataHigh = { - floorMin: 7.0, - modelVersion: 'basic model', - modelWeight: 10, - currency: 'USD', - schema: { - delimiter: '|', - fields: ['mediaType'] - }, - values: { - 'banner': 1.0, - 'video': 5.0, - '*': 2.5 - } - }; - const basicFloorDataLow = { - floorMin: 2.3, - modelVersion: 'basic model', - modelWeight: 10, - currency: 'USD', - schema: { - delimiter: '|', - fields: ['mediaType'] - }, - values: { - 'banner': 1.0, - 'video': 5.0, - '*': 2.5 - } - }; - const basicFloorConfig = { - enabled: true, - auctionDelay: 0, - endpoint: {}, - enforcement: { - enforceJS: true, - enforcePBS: false, - floorDeals: false, - bidAdjustment: true - }, - data: basicFloorData - } - const minFloorConfigHigh = { - enabled: true, - auctionDelay: 0, - floorMin: 7, - endpoint: {}, - enforcement: { - enforceJS: true, - enforcePBS: false, - floorDeals: false, - bidAdjustment: true - }, - data: basicFloorDataHigh - } - const minFloorConfigLow = { - enabled: true, - auctionDelay: 0, - floorMin: 2.3, - endpoint: {}, - enforcement: { - enforceJS: true, - enforcePBS: false, - floorDeals: false, - bidAdjustment: true - }, - data: basicFloorDataLow - } - const basicBidRequest = { - bidder: 'rubicon', - adUnitCode: 'test_div_1', - auctionId: '1234-56-789', - }; - - function getAdUnitMock(code = 'adUnit-code') { - return { - code, - mediaTypes: {banner: { sizes: [[300, 200], [300, 600]] }, native: {}}, - bids: [{bidder: 'someBidder'}, {bidder: 'someOtherBidder'}] - }; - } - beforeEach(function() { - clock = sinon.useFakeTimers(); - sandbox = sinon.sandbox.create(); - logErrorSpy = sinon.spy(utils, 'logError'); - logWarnSpy = sinon.spy(utils, 'logWarn'); - }); - - afterEach(function() { - clock.restore(); - handleSetFloorsConfig({enabled: false}); - sandbox.restore(); - utils.logError.restore(); - utils.logWarn.restore(); - // reset global bidder settings so no weird test side effects - getGlobal().bidderSettings = {}; - }); - - describe('getFloorsDataForAuction', function () { - it('converts basic input floor data into a floorData map for the auction correctly', function () { - // basic input where nothing needs to be updated - expect(getFloorsDataForAuction(basicFloorData)).to.deep.equal(basicFloorData); - - // if cur and delim not defined then default to correct ones (usd and |) - let inputFloorData = utils.deepClone(basicFloorData); - delete inputFloorData.currency; - delete inputFloorData.schema.delimiter; - expect(getFloorsDataForAuction(inputFloorData)).to.deep.equal(basicFloorData); - - // should not use defaults if differing values - inputFloorData.currency = 'EUR' - inputFloorData.schema.delimiter = '^' - let resultingData = getFloorsDataForAuction(inputFloorData); - expect(resultingData.currency).to.equal('EUR'); - expect(resultingData.schema.delimiter).to.equal('^'); - }); - - it('converts more complex floor data correctly', function () { - let inputFloorData = { - schema: { - fields: ['mediaType', 'size', 'domain'] - }, - values: { - 'banner|300x250|prebid.org': 1.0, - 'video|640x480|prebid.org': 5.0, - 'banner|728x90|rubicon.com': 3.5, - 'video|600x300|appnexus.com': 3.5, - '*|*|prebid.org': 3.5, - } - }; - let resultingData = getFloorsDataForAuction(inputFloorData); - expect(resultingData).to.deep.equal({ - currency: 'USD', - schema: { - delimiter: '|', - fields: ['mediaType', 'size', 'domain'] - }, - values: { - 'banner|300x250|prebid.org': 1.0, - 'video|640x480|prebid.org': 5.0, - 'banner|728x90|rubicon.com': 3.5, - 'video|600x300|appnexus.com': 3.5, - '*|*|prebid.org': 3.5, - } - }); - }); - - it('adds adUnitCode to the schema if the floorData comes from adUnit level to maintain scope', function () { - let inputFloorData = utils.deepClone(basicFloorData); - let resultingData = getFloorsDataForAuction(inputFloorData, 'test_div_1'); - expect(resultingData).to.deep.equal({ - modelVersion: 'basic model', - modelWeight: 10, - modelTimestamp: 1606772895, - currency: 'USD', - schema: { - delimiter: '|', - fields: ['adUnitCode', 'mediaType'] - }, - values: { - 'test_div_1|banner': 1.0, - 'test_div_1|video': 5.0, - 'test_div_1|*': 2.5 - } - }); - - // uses the right delim if not | - inputFloorData.schema.delimiter = '^'; - resultingData = getFloorsDataForAuction(inputFloorData, 'this_is_a_div'); - expect(resultingData).to.deep.equal({ - modelVersion: 'basic model', - modelWeight: 10, - modelTimestamp: 1606772895, - currency: 'USD', - schema: { - delimiter: '^', - fields: ['adUnitCode', 'mediaType'] - }, - values: { - 'this_is_a_div^banner': 1.0, - 'this_is_a_div^video': 5.0, - 'this_is_a_div^*': 2.5 - } - }); - }); - }); - - describe('getFirstMatchingFloor', 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({ - floorMin: 0, - floorRuleValue: 1.0, - matchingFloor: 1.0, - matchingData: 'banner', - matchingRule: 'banner' - }); - // video with * size (not in rule file so does not do anything) - expect(getFirstMatchingFloor({...basicFloorData}, basicBidRequest, {mediaType: 'video', size: '*'})).to.deep.equal({ - floorMin: 0, - floorRuleValue: 5.0, - matchingFloor: 5.0, - matchingData: 'video', - 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({ - floorMin: 0, - floorRuleValue: 2.5, - matchingFloor: 2.5, - matchingData: 'native', - matchingRule: '*' - }); - // banner with floorMin higher than matching rule - handleSetFloorsConfig({ - ...minFloorConfigHigh - }); - expect(getFirstMatchingFloor({...basicFloorDataHigh}, basicBidRequest, {mediaType: 'banner', size: '*'})).to.deep.equal({ - floorMin: 7, - floorRuleValue: 1.0, - matchingFloor: 7, - matchingData: 'banner', - matchingRule: 'banner' - }); - // banner with floorMin higher than matching rule - handleSetFloorsConfig({ - ...minFloorConfigLow - }); - expect(getFirstMatchingFloor({...basicFloorDataLow}, basicBidRequest, {mediaType: 'video', size: '*'})).to.deep.equal({ - floorMin: 2.3, - floorRuleValue: 5, - matchingFloor: 5, - matchingData: 'video', - matchingRule: 'video' - }); - }); - it('does not alter cached matched input if conversion occurs', function () { - let inputData = {...basicFloorData}; - [0.2, 0.4, 0.6, 0.8].forEach(modifier => { - let result = getFirstMatchingFloor(inputData, basicBidRequest, {mediaType: 'banner', size: '*'}); - // result should always be the same - expect(result).to.deep.equal({ - floorMin: 0, - floorRuleValue: 1.0, - matchingFloor: 1.0, - matchingData: 'banner', - matchingRule: 'banner' - }); - // make sure a post retrieval adjustment does not alter the cached floor - result.matchingFloor = result.matchingFloor * modifier; - }); - }); - it('selects the right floor for different sizes', function () { - let inputFloorData = { - currency: 'USD', - schema: { - delimiter: '|', - fields: ['size'] - }, - values: { - '300x250': 1.1, - '640x480': 2.2, - '728x90': 3.3, - '600x300': 4.4, - '*': 5.5, - } - } - // banner with 300x250 size - expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'banner', size: [300, 250]})).to.deep.equal({ - floorMin: 0, - floorRuleValue: 1.1, - matchingFloor: 1.1, - matchingData: '300x250', - matchingRule: '300x250' - }); - // video with 300x250 size - expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'video', size: [300, 250]})).to.deep.equal({ - floorMin: 0, - floorRuleValue: 1.1, - matchingFloor: 1.1, - matchingData: '300x250', - matchingRule: '300x250' - }); - // native (not in the rule list) with 300x600 size - expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'native', size: [600, 300]})).to.deep.equal({ - floorMin: 0, - floorRuleValue: 4.4, - matchingFloor: 4.4, - matchingData: '600x300', - 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({ - floorMin: 0, - floorRuleValue: 5.5, - matchingFloor: 5.5, - matchingData: '1x1', - matchingRule: '*' - }); - }); - it('selects the right floor for more complex rules', function () { - let inputFloorData = { - currency: 'USD', - schema: { - delimiter: '^', - fields: ['adUnitCode', 'mediaType', 'size'] - }, - values: { - 'test_div_1^banner^300x250': 1.1, - 'test_div_1^video^640x480': 2.2, - 'test_div_2^*^*': 3.3, - '*^banner^300x250': 4.4, - 'weird_div^*^300x250': 5.5 - }, - default: 0.5 - }; - // banner with 300x250 size - expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'banner', size: [300, 250]})).to.deep.equal({ - floorMin: 0, - floorRuleValue: 1.1, - matchingFloor: 1.1, - matchingData: 'test_div_1^banner^300x250', - 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({ - floorMin: 0, - floorRuleValue: 0.5, - matchingFloor: 0.5, - matchingData: 'test_div_1^video^300x250', - matchingRule: undefined - }); - // 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({ - floorMin: 0, - floorRuleValue: 0.5, - matchingFloor: 0.5, - matchingData: 'test_div_1^video^300x250', - matchingRule: undefined - }); - // update adUnitCode to test_div_2 with weird other params - let newBidRequest = { ...basicBidRequest, adUnitCode: 'test_div_2' } - expect(getFirstMatchingFloor(inputFloorData, newBidRequest, {mediaType: 'badmediatype', size: [900, 900]})).to.deep.equal({ - floorMin: 0, - floorRuleValue: 3.3, - matchingFloor: 3.3, - matchingData: 'test_div_2^badmediatype^900x900', - matchingRule: 'test_div_2^*^*' - }); - }); - it('it does not break if floorData has bad values', function () { - let inputFloorData = {}; - expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'banner', size: '*'})).to.deep.equal({ - matchingFloor: undefined - }); - // if default is there use it - inputFloorData = { default: 5.0 }; - expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'banner', size: '*'})).to.deep.equal({ - matchingFloor: 5.0 - }); - }); - }); - describe('pre-auction tests', function () { - let exposedAdUnits; - const validateBidRequests = (getFloorExpected, FloorDataExpected) => { - exposedAdUnits.forEach(adUnit => adUnit.bids.forEach(bid => { - expect(bid.hasOwnProperty('getFloor')).to.equal(getFloorExpected); - expect(bid.floorData).to.deep.equal(FloorDataExpected); - })); - }; - const runStandardAuction = (adUnits = [getAdUnitMock('test_div_1')]) => { - requestBidsHook(config => exposedAdUnits = config.adUnits, { - auctionId: basicBidRequest.auctionId, - adUnits, - }); - }; - let fakeFloorProvider; - let actualAllowedFields = allowedFields; - let actualFieldMatchingFunctions = fieldMatchingFunctions; - const defaultAllowedFields = [...allowedFields]; - const defaultMatchingFunctions = {...fieldMatchingFunctions}; - beforeEach(function() { - fakeFloorProvider = sinon.fakeServer.create(); - }); - afterEach(function() { - fakeFloorProvider.restore(); - exposedAdUnits = undefined; - actualAllowedFields = [...defaultAllowedFields]; - actualFieldMatchingFunctions = {...defaultMatchingFunctions}; - }); - it('should not do floor stuff if no resulting floor object can be resolved for auciton', function () { - handleSetFloorsConfig({ - ...basicFloorConfig, - data: undefined - }); - runStandardAuction(); - validateBidRequests(false, { - skipped: true, - floorMin: undefined, - modelVersion: undefined, - modelWeight: undefined, - modelTimestamp: undefined, - location: 'noData', - skipRate: 0, - fetchStatus: undefined, - floorProvider: undefined - }); - }); - it('should use adUnit level data if not setConfig or fetch has occured', function () { - handleSetFloorsConfig({ - ...basicFloorConfig, - data: undefined - }); - // attach floor data onto an adUnit and run an auction - let adUnitWithFloors1 = { - ...getAdUnitMock('adUnit-Div-1'), - floors: { - ...basicFloorData, - modelVersion: 'adUnit Model Version', // change the model name - } - }; - let adUnitWithFloors2 = { - ...getAdUnitMock('adUnit-Div-2'), - floors: { - ...basicFloorData, - values: { - 'banner': 5.0, - '*': 10.4 - } - } - }; - runStandardAuction([adUnitWithFloors1, adUnitWithFloors2]); - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'adUnit Model Version', - modelWeight: 10, - modelTimestamp: 1606772895, - location: 'adUnit', - skipRate: 0, - fetchStatus: undefined, - floorProvider: undefined - }); - }); - it('should use adUnit level data and minFloor should be set', function () { - handleSetFloorsConfig({ - ...minFloorConfigHigh, - data: undefined - }); - // attach floor data onto an adUnit and run an auction - let adUnitWithFloors1 = { - ...getAdUnitMock('adUnit-Div-1'), - floors: { - ...basicFloorData, - modelVersion: 'adUnit Model Version', // change the model name - } - }; - let adUnitWithFloors2 = { - ...getAdUnitMock('adUnit-Div-2'), - floors: { - ...basicFloorData, - values: { - 'banner': 5.0, - '*': 10.4 - } - } - }; - runStandardAuction([adUnitWithFloors1, adUnitWithFloors2]); - validateBidRequests(true, { - skipped: false, - modelVersion: 'adUnit Model Version', - modelWeight: 10, - modelTimestamp: 1606772895, - location: 'adUnit', - skipRate: 0, - floorMin: 7, - fetchStatus: undefined, - floorProvider: undefined - }); - }); - it('bidRequests should have getFloor function and flooring meta data when setConfig occurs', function () { - handleSetFloorsConfig({...basicFloorConfig, floorProvider: 'floorprovider'}); - runStandardAuction(); - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'basic model', - modelWeight: 10, - modelTimestamp: 1606772895, - location: 'setConfig', - skipRate: 0, - fetchStatus: undefined, - floorProvider: 'floorprovider' - }); - }); - it('should pick the right floorProvider', function () { - let inputFloors = { - ...basicFloorConfig, - floorProvider: 'providerA', - data: { - ...basicFloorData, - floorProvider: 'providerB', - } - }; - handleSetFloorsConfig(inputFloors); - runStandardAuction(); - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'basic model', - modelWeight: 10, - modelTimestamp: 1606772895, - location: 'setConfig', - skipRate: 0, - fetchStatus: undefined, - floorProvider: 'providerB' - }); - - // if not at data level take top level - delete inputFloors.data.floorProvider; - handleSetFloorsConfig(inputFloors); - runStandardAuction(); - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'basic model', - modelWeight: 10, - modelTimestamp: 1606772895, - location: 'setConfig', - skipRate: 0, - fetchStatus: undefined, - floorProvider: 'providerA' - }); - - // if none should be undefined - delete inputFloors.floorProvider; - handleSetFloorsConfig(inputFloors); - runStandardAuction(); - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'basic model', - modelWeight: 10, - modelTimestamp: 1606772895, - location: 'setConfig', - skipRate: 0, - fetchStatus: undefined, - floorProvider: undefined - }); - }); - it('should take the right skipRate depending on input', function () { - // first priority is data object - sandbox.stub(Math, 'random').callsFake(() => 0.99); - let inputFloors = { - ...basicFloorConfig, - skipRate: 10, - data: { - ...basicFloorData, - skipRate: 50 - } - }; - handleSetFloorsConfig(inputFloors); - runStandardAuction(); - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'basic model', - modelWeight: 10, - modelTimestamp: 1606772895, - location: 'setConfig', - skipRate: 50, - fetchStatus: undefined, - floorProvider: undefined - }); - - // if that does not exist uses topLevel skipRate setting - delete inputFloors.data.skipRate; - handleSetFloorsConfig(inputFloors); - runStandardAuction(); - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'basic model', - modelWeight: 10, - modelTimestamp: 1606772895, - location: 'setConfig', - skipRate: 10, - fetchStatus: undefined, - floorProvider: undefined - }); - - // if that is not there defaults to zero - delete inputFloors.skipRate; - handleSetFloorsConfig(inputFloors); - runStandardAuction(); - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'basic model', - modelWeight: 10, - modelTimestamp: 1606772895, - location: 'setConfig', - skipRate: 0, - fetchStatus: undefined, - floorProvider: undefined - }); - }); - it('should randomly pick a model if floorsSchemaVersion is 2', function () { - let inputFloors = { - ...basicFloorConfig, - floorProvider: 'floorprovider', - data: { - floorsSchemaVersion: 2, - currency: 'USD', - modelGroups: [ - { - modelVersion: 'model-1', - modelWeight: 10, - schema: { - delimiter: '|', - fields: ['mediaType'] - }, - values: { - 'banner': 1.0, - '*': 2.5 - } - }, { - modelVersion: 'model-2', - modelWeight: 40, - schema: { - delimiter: '|', - fields: ['size'] - }, - values: { - '300x250': 1.0, - '*': 2.5 - } - }, { - modelVersion: 'model-3', - modelWeight: 50, - schema: { - delimiter: '|', - fields: ['domain'] - }, - values: { - 'www.prebid.org': 1.0, - '*': 2.5 - } - } - ] - } - }; - handleSetFloorsConfig(inputFloors); - - // stub random to give us wanted vals - let randValue; - sandbox.stub(Math, 'random').callsFake(() => randValue); - - // 0 - 10 should use first model - randValue = 0.05; - runStandardAuction(); - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'model-1', - modelWeight: 10, - modelTimestamp: undefined, - location: 'setConfig', - skipRate: 0, - fetchStatus: undefined, - floorProvider: 'floorprovider' - }); - - // 11 - 50 should use second model - randValue = 0.40; - runStandardAuction(); - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'model-2', - modelWeight: 40, - modelTimestamp: undefined, - location: 'setConfig', - skipRate: 0, - fetchStatus: undefined, - floorProvider: 'floorprovider' - }); - - // 51 - 100 should use third model - randValue = 0.75; - runStandardAuction(); - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'model-3', - modelWeight: 50, - modelTimestamp: undefined, - location: 'setConfig', - skipRate: 0, - fetchStatus: undefined, - floorProvider: 'floorprovider' - }); - }); - it('should not overwrite previous data object if the new one is bad', function () { - handleSetFloorsConfig({...basicFloorConfig}); - handleSetFloorsConfig({ - ...basicFloorConfig, - data: undefined - }); - handleSetFloorsConfig({ - ...basicFloorConfig, - data: 5 - }); - handleSetFloorsConfig({ - ...basicFloorConfig, - data: { - schema: {fields: ['thisIsNotAllowedSoShouldFail']}, - values: {'*': 1.2}, - modelVersion: 'FAIL' - } - }); - runStandardAuction(); - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'basic model', - modelWeight: 10, - modelTimestamp: 1606772895, - location: 'setConfig', - skipRate: 0, - fetchStatus: undefined, - floorProvider: undefined - }); - }); - it('should dynamically add new schema fileds and functions if added via setConfig', function () { - let deviceSpoof; - handleSetFloorsConfig({ - ...basicFloorConfig, - data: { - schema: {fields: ['deviceType']}, - values: { - 'mobile': 1.0, - 'desktop': 2.0, - 'tablet': 3.0, - '*': 4.0 - } - }, - additionalSchemaFields: { - deviceType: () => deviceSpoof - } - }); - expect(allowedFields).to.contain('deviceType'); - expect(fieldMatchingFunctions['deviceType']).to.be.a('function'); - - // run getFloor to make sure it selcts right stuff! (other params do not matter since we only are testing deviceType) - runStandardAuction(); - - // set deviceType to mobile; - deviceSpoof = 'mobile'; - exposedAdUnits[0].bids[0].auctionId = basicBidRequest.auctionId - expect(exposedAdUnits[0].bids[0].getFloor()).to.deep.equal({ - currency: 'USD', - floor: 1.0 // 'mobile': 1.0, - }); - - // set deviceType to desktop; - deviceSpoof = 'desktop'; - expect(exposedAdUnits[0].bids[0].getFloor()).to.deep.equal({ - currency: 'USD', - floor: 2.0 // 'desktop': 2.0, - }); - - // set deviceType to tablet; - deviceSpoof = 'tablet'; - expect(exposedAdUnits[0].bids[0].getFloor()).to.deep.equal({ - currency: 'USD', - floor: 3.0 // 'tablet': 3.0 - }); - - // set deviceType to unknown; - deviceSpoof = 'unknown'; - expect(exposedAdUnits[0].bids[0].getFloor()).to.deep.equal({ - currency: 'USD', - floor: 4.0 // '*': 4.0 - }); - }); - 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'}}); - - // start the auction it should delay and not immediately call `continueAuction` - runStandardAuction(); - - // exposedAdUnits should be undefined if the auction has not continued - expect(exposedAdUnits).to.be.undefined; - - // hit the delay - clock.tick(250); - - // log warn should be called and adUnits not undefined - expect(logWarnSpy.calledOnce).to.equal(true); - expect(exposedAdUnits).to.not.be.undefined; - - // the exposedAdUnits should be from the fetch not setConfig level data - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'basic model', - modelWeight: 10, - modelTimestamp: 1606772895, - location: 'setConfig', - skipRate: 0, - fetchStatus: 'timeout', - floorProvider: undefined - }); - fakeFloorProvider.respond(); - }); - it('It should fetch if config has url and bidRequests have fetch level flooring meta data', function () { - // init the fake server with response stuff - let fetchFloorData = { - ...basicFloorData, - modelVersion: 'fetch model name', // change the model name - }; - fakeFloorProvider.respondWith(JSON.stringify(fetchFloorData)); - - // run setConfig indicating fetch - handleSetFloorsConfig({...basicFloorConfig, floorProvider: 'floorprovider', auctionDelay: 250, endpoint: {url: 'http://www.fakeFloorProvider.json'}}); - - // floor provider should be called - expect(fakeFloorProvider.requests.length).to.equal(1); - expect(fakeFloorProvider.requests[0].url).to.equal('http://www.fakeFloorProvider.json'); - - // start the auction it should delay and not immediately call `continueAuction` - runStandardAuction(); - - // exposedAdUnits should be undefined if the auction has not continued - expect(exposedAdUnits).to.be.undefined; - - // make the fetch respond - fakeFloorProvider.respond(); - expect(exposedAdUnits).to.not.be.undefined; - - // the exposedAdUnits should be from the fetch not setConfig level data - // and fetchStatus is success since fetch worked - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'fetch model name', - modelWeight: 10, - modelTimestamp: 1606772895, - location: 'fetch', - skipRate: 0, - fetchStatus: 'success', - floorProvider: 'floorprovider' - }); - }); - it('it should correctly overwrite floorProvider with fetch provider', function () { - // init the fake server with response stuff - let fetchFloorData = { - ...basicFloorData, - floorProvider: 'floorProviderD', // change the floor provider - modelVersion: 'fetch model name', // change the model name - }; - fakeFloorProvider.respondWith(JSON.stringify(fetchFloorData)); - - // run setConfig indicating fetch - handleSetFloorsConfig({...basicFloorConfig, floorProvider: 'floorproviderC', auctionDelay: 250, endpoint: {url: 'http://www.fakeFloorProvider.json'}}); - - // floor provider should be called - expect(fakeFloorProvider.requests.length).to.equal(1); - expect(fakeFloorProvider.requests[0].url).to.equal('http://www.fakeFloorProvider.json'); - - // start the auction it should delay and not immediately call `continueAuction` - runStandardAuction(); - - // exposedAdUnits should be undefined if the auction has not continued - expect(exposedAdUnits).to.be.undefined; - - // make the fetch respond - fakeFloorProvider.respond(); - - // the exposedAdUnits should be from the fetch not setConfig level data - // and fetchStatus is success since fetch worked - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'fetch model name', - modelWeight: 10, - modelTimestamp: 1606772895, - location: 'fetch', - skipRate: 0, - fetchStatus: 'success', - floorProvider: 'floorProviderD' - }); - }); - it('it should correctly overwrite skipRate with fetch skipRate', function () { - // so floors does not skip - sandbox.stub(Math, 'random').callsFake(() => 0.99); - // init the fake server with response stuff - let fetchFloorData = { - ...basicFloorData, - modelVersion: 'fetch model name', // change the model name - }; - fetchFloorData.skipRate = 95; - fakeFloorProvider.respondWith(JSON.stringify(fetchFloorData)); - - // run setConfig indicating fetch - handleSetFloorsConfig({...basicFloorConfig, floorProvider: 'floorprovider', auctionDelay: 250, endpoint: {url: 'http://www.fakeFloorProvider.json'}}); - - // floor provider should be called - expect(fakeFloorProvider.requests.length).to.equal(1); - expect(fakeFloorProvider.requests[0].url).to.equal('http://www.fakeFloorProvider.json'); - - // start the auction it should delay and not immediately call `continueAuction` - runStandardAuction(); - - // exposedAdUnits should be undefined if the auction has not continued - expect(exposedAdUnits).to.be.undefined; - - // make the fetch respond - fakeFloorProvider.respond(); - expect(exposedAdUnits).to.not.be.undefined; - - // the exposedAdUnits should be from the fetch not setConfig level data - // and fetchStatus is success since fetch worked - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'fetch model name', - modelWeight: 10, - modelTimestamp: 1606772895, - location: 'fetch', - skipRate: 95, - fetchStatus: 'success', - floorProvider: 'floorprovider' - }); - }); - it('Should not break if floor provider returns 404', function () { - // run setConfig indicating fetch - handleSetFloorsConfig({...basicFloorConfig, auctionDelay: 250, endpoint: {url: 'http://www.fakeFloorProvider.json'}}); - - // run the auction and make server respond with 404 - fakeFloorProvider.respond(); - runStandardAuction(); - - // error should have been called for fetch error - expect(logErrorSpy.calledOnce).to.equal(true); - // should have caught the response error and still used setConfig data - // and fetch failed is true - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'basic model', - modelWeight: 10, - modelTimestamp: 1606772895, - location: 'setConfig', - skipRate: 0, - fetchStatus: 'error', - floorProvider: undefined - }); - }); - it('Should not break if floor provider returns non json', function () { - fakeFloorProvider.respondWith('Not valid response'); - - // run setConfig indicating fetch - handleSetFloorsConfig({...basicFloorConfig, auctionDelay: 250, endpoint: {url: 'http://www.fakeFloorProvider.json'}}); - - // run the auction and make server respond - fakeFloorProvider.respond(); - runStandardAuction(); - - // error should have been called for response floor data not being valid - expect(logErrorSpy.calledOnce).to.equal(true); - // should have caught the response error and still used setConfig data - // and fetchStatus is 'success' but location is setConfig since it had bad data - validateBidRequests(true, { - skipped: false, - floorMin: undefined, - modelVersion: 'basic model', - modelWeight: 10, - modelTimestamp: 1606772895, - location: 'setConfig', - skipRate: 0, - fetchStatus: 'success', - floorProvider: undefined - }); - }); - it('should handle not using fetch correctly', function () { - // run setConfig twice indicating fetch - fakeFloorProvider.respondWith(JSON.stringify(basicFloorData)); - 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); - expect(fakeFloorProvider.requests.length).to.equal(1); - expect(fakeFloorProvider.requests[0].url).to.equal('http://www.fakeFloorProvider.json'); - - // now we respond and then run again it should work and make another request - fakeFloorProvider.respond(); - handleSetFloorsConfig({...basicFloorConfig, auctionDelay: 250, endpoint: {url: 'http://www.fakeFloorProvider.json'}}); - fakeFloorProvider.respond(); - - // now warn still only called once and server called twice - expect(logWarnSpy.calledOnce).to.equal(true); - expect(fakeFloorProvider.requests.length).to.equal(2); - - // 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'}}); - expect(logErrorSpy.calledOnce).to.equal(true); - }); - describe('isFloorsDataValid', function () { - it('should return false if unknown floorsSchemaVersion', function () { - let inputFloorData = utils.deepClone(basicFloorData); - inputFloorData.floorsSchemaVersion = 3; - expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); - }); - it('should work correctly for fields array', function () { - let inputFloorData = utils.deepClone(basicFloorData); - expect(isFloorsDataValid(inputFloorData)).to.to.equal(true); - - // no fields array - delete inputFloorData.schema.fields; - expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); - - // Fields is not an array - inputFloorData.schema.fields = {}; - expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); - inputFloorData.schema.fields = undefined; - expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); - inputFloorData.schema.fields = 'adUnitCode'; - expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); - - // fields has a value that is not one of the "allowed" fields - inputFloorData.schema.fields = ['adUnitCode', 'notValidMapping']; - expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); - }); - it('should work correctly for values object', function () { - let inputFloorData = utils.deepClone(basicFloorData); - expect(isFloorsDataValid(inputFloorData)).to.to.equal(true); - - // no values object - delete inputFloorData.values; - expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); - - // values is not correct type - inputFloorData.values = []; - expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); - inputFloorData.values = '123455/slot'; - expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); - - // is an object but structure is wrong - inputFloorData.values = { - 'banner': 'not a floor value' - }; - expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); - inputFloorData.values = { - 'banner': undefined - }; - expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); - - // should be true if at least one rule is valid - inputFloorData.schema.fields = ['adUnitCode', 'mediaType']; - inputFloorData.values = { - 'banner': 1.0, - 'test-div-1|native': 1.0, // only valid rule should still work and delete the other rules - 'video': 1.0, - '*': 1.0 - }; - expect(isFloorsDataValid(inputFloorData)).to.to.equal(true); - expect(inputFloorData.values).to.deep.equal({ 'test-div-1|native': 1.0 }); - }); - it('should work correctly for floorsSchemaVersion 2', function () { - let inputFloorData = { - floorsSchemaVersion: 2, - currency: 'USD', - modelGroups: [ - { - modelVersion: 'model-1', - modelWeight: 10, - schema: { - delimiter: '|', - fields: ['mediaType'] - }, - values: { - 'banner': 1.0, - '*': 2.5 - } - }, { - modelVersion: 'model-2', - modelWeight: 40, - schema: { - delimiter: '|', - fields: ['size'] - }, - values: { - '300x250': 1.0, - '*': 2.5 - } - }, { - modelVersion: 'model-3', - modelWeight: 50, - schema: { - delimiter: '|', - fields: ['domain'] - }, - values: { - 'www.prebid.org': 1.0, - '*': 2.5 - } - } - ] - }; - expect(isFloorsDataValid(inputFloorData)).to.to.equal(true); - - // remove one of the modelWeight's and it should be false - delete inputFloorData.modelGroups[1].modelWeight; - expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); - inputFloorData.modelGroups[1].modelWeight = 40; - - // remove values from a model and it should not validate - const tempValues = {...inputFloorData.modelGroups[0].values}; - delete inputFloorData.modelGroups[0].values; - expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); - inputFloorData.modelGroups[0].values = tempValues; - - // modelGroups should be an array and have at least one entry - delete inputFloorData.modelGroups; - expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); - inputFloorData.modelGroups = []; - expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); - }); - }); - describe('getFloor', function () { - let bidRequest = { - ...basicBidRequest, - getFloor - }; - it('returns empty if no matching data for auction is found', function () { - expect(bidRequest.getFloor({})).to.deep.equal({}); - }); - it('picks the right rule depending on input', function () { - _floorDataForAuction[bidRequest.auctionId] = utils.deepClone(basicFloorConfig); - - // empty params into getFloor should use default of banner * FloorData Curr - let inputParams = {}; - expect(bidRequest.getFloor(inputParams)).to.deep.equal({ - currency: 'USD', - floor: 1.0 - }); - - // ask for banner - inputParams = {mediaType: 'banner'}; - expect(bidRequest.getFloor(inputParams)).to.deep.equal({ - currency: 'USD', - floor: 1.0 - }); - - // ask for video - inputParams = {mediaType: 'video'}; - expect(bidRequest.getFloor(inputParams)).to.deep.equal({ - currency: 'USD', - floor: 5.0 - }); - - // ask for * - inputParams = {mediaType: '*'}; - expect(bidRequest.getFloor(inputParams)).to.deep.equal({ - currency: 'USD', - floor: 2.5 - }); - }); - it('picks the right rule with more complex rules', function () { - _floorDataForAuction[bidRequest.auctionId] = { - ...basicFloorConfig, - data: { - currency: 'USD', - schema: { fields: ['mediaType', 'size'], delimiter: '|' }, - values: { - 'banner|300x250': 0.5, - 'banner|300x600': 1.5, - 'banner|728x90': 2.5, - 'banner|*': 3.5, - 'video|640x480': 4.5, - 'video|*': 5.5 - }, - default: 10.0 - } - }; - - // assumes banner * - let inputParams = {}; - expect(bidRequest.getFloor(inputParams)).to.deep.equal({ - currency: 'USD', - floor: 3.5 - }); - - // ask for banner with a size - 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]}; - 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]}; - 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: '*'}; - expect(bidRequest.getFloor(inputParams)).to.deep.equal({ - currency: 'USD', - floor: 10.0 - }); - }); - it('should round up to 4 decimal places', function () { - _floorDataForAuction[bidRequest.auctionId] = utils.deepClone(basicFloorConfig); - _floorDataForAuction[bidRequest.auctionId].data.values = { - 'banner': 1.777777, - 'video': 1.1111111, - }; - - // assumes banner * - let inputParams = {mediaType: 'banner'}; - expect(bidRequest.getFloor(inputParams)).to.deep.equal({ - currency: 'USD', - floor: 1.7778 - }); - - // assumes banner * - inputParams = {mediaType: 'video'}; - expect(bidRequest.getFloor(inputParams)).to.deep.equal({ - currency: 'USD', - floor: 1.1112 - }); - }); - it('should return the adjusted floor if bidder has cpm adjustment function', function () { - getGlobal().bidderSettings = { - rubicon: { - bidCpmAdjustment: function (bidCpm) { - return bidCpm * 0.5; - }, - }, - appnexus: { - bidCpmAdjustment: function (bidCpm) { - return bidCpm * 0.75; - }, - } - }; - _floorDataForAuction[bidRequest.auctionId] = utils.deepClone(basicFloorConfig); - _floorDataForAuction[bidRequest.auctionId].data.values = { '*': 1.0 }; - let appnexusBid = { - ...bidRequest, - bidder: 'appnexus' - }; - - // the conversion should be what the bidder would need to return in order to match the actual floor - // rubicon - expect(bidRequest.getFloor()).to.deep.equal({ - currency: 'USD', - floor: 2.0 // a 2.0 bid after rubicons cpm adjustment would be 1.0 and thus is the floor after adjust - }); - - // appnexus - expect(appnexusBid.getFloor()).to.deep.equal({ - currency: 'USD', - floor: 1.3334 // 1.3334 * 0.75 = 1.000005 which is the floor (we cut off getFloor at 4 decimal points) - }); - }); - - it('should use standard cpmAdjustment if no bidder cpmAdjustment', function () { - getGlobal().bidderSettings = { - rubicon: { - bidCpmAdjustment: function (bidCpm, bidResponse) { - return bidResponse.cpm * 0.5; - }, - }, - standard: { - bidCpmAdjustment: function (bidCpm, bidResponse) { - return bidResponse.cpm * 0.75; - }, - } - }; - _floorDataForAuction[bidRequest.auctionId] = utils.deepClone(basicFloorConfig); - _floorDataForAuction[bidRequest.auctionId].data.values = { '*': 1.0 }; - let appnexusBid = { - ...bidRequest, - bidder: 'appnexus' - }; - - // the conversion should be what the bidder would need to return in order to match the actual floor - // rubicon - expect(bidRequest.getFloor()).to.deep.equal({ - currency: 'USD', - floor: 2.0 // a 2.0 bid after rubicons cpm adjustment would be 1.0 and thus is the floor after adjust - }); - - // appnexus - expect(appnexusBid.getFloor()).to.deep.equal({ - currency: 'USD', - floor: 1.3334 // 1.3334 * 0.75 = 1.000005 which is the floor (we cut off getFloor at 4 decimal points) - }); - }); - - it('should work when cpmAdjust function uses bid object', function () { - getGlobal().bidderSettings = { - rubicon: { - bidCpmAdjustment: function (bidCpm, bidResponse) { - return bidResponse.cpm * 0.5; - }, - }, - appnexus: { - bidCpmAdjustment: function (bidCpm, bidResponse) { - return bidResponse.cpm * 0.75; - }, - } - }; - _floorDataForAuction[bidRequest.auctionId] = utils.deepClone(basicFloorConfig); - _floorDataForAuction[bidRequest.auctionId].data.values = { '*': 1.0 }; - let appnexusBid = { - ...bidRequest, - bidder: 'appnexus' - }; - - // the conversion should be what the bidder would need to return in order to match the actual floor - // rubicon - expect(bidRequest.getFloor()).to.deep.equal({ - currency: 'USD', - floor: 2.0 // a 2.0 bid after rubicons cpm adjustment would be 1.0 and thus is the floor after adjust - }); - - // appnexus - expect(appnexusBid.getFloor()).to.deep.equal({ - currency: 'USD', - floor: 1.3334 // 1.3334 * 0.75 = 1.000005 which is the floor (we cut off getFloor at 4 decimal points) - }); - }); - it('should correctly pick the right attributes if * is passed in and context can be assumed', function () { - let inputBidReq = { - bidder: 'rubicon', - adUnitCode: 'test_div_2', - auctionId: '987654321', - mediaTypes: { - video: {} - }, - getFloor - }; - _floorDataForAuction[inputBidReq.auctionId] = utils.deepClone(basicFloorConfig); - _floorDataForAuction[inputBidReq.auctionId].data.values = { - '*': 1.0, - 'banner': 3.0, - 'video': 5.0 - }; - - // 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({ - 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({ - 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({ - currency: 'USD', - floor: 1.0 // '*': 1.0, - }); - delete _floorDataForAuction[inputBidReq.auctionId].data.matchingInputs; - - // now if size can be inferred (meaning only one size is in the specified mediaType, it will use it) - _floorDataForAuction[inputBidReq.auctionId].data.schema.fields = ['mediaType', 'size']; - _floorDataForAuction[inputBidReq.auctionId].data.values = { - '*|*': 1.0, - 'banner|300x250': 2.0, - 'banner|728x90': 3.0, - 'banner|*': 4.0, - 'video|300x250': 5.0, - 'video|728x90': 6.0, - 'video|*': 7.0 - }; - // 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({ - 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({ - 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({ - 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({ - 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({ - 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({ - currency: 'USD', - floor: 1.0 // '*|*': 1.0, - }); - delete _floorDataForAuction[inputBidReq.auctionId].data.matchingInputs; - }); - }); - }); - describe('bidResponseHook tests', function () { - let returnedBidResponse; - let bidderRequest = { - bidderCode: 'appnexus', - auctionId: '123456', - bids: [{ - bidder: 'appnexus', - adUnitCode: 'test_div_1', - auctionId: '123456', - bidId: '1111' - }] - }; - let basicBidResponse = { - bidderCode: 'appnexus', - width: 300, - height: 250, - cpm: 0.5, - mediaType: 'banner', - requestId: '1111', - }; - beforeEach(function () { - returnedBidResponse = {}; - }); - function runBidResponse(bidResp = basicBidResponse) { - let next = (adUnitCode, bid) => { - returnedBidResponse = bid; - }; - addBidResponseHook.bind({ bidderRequest })(next, bidResp.adUnitCode, bidResp); - }; - it('continues with the auction if not floors data is present without any flooring', function () { - runBidResponse(); - expect(returnedBidResponse).to.not.haveOwnProperty('floorData'); - }); - it('if no matching rule it should not floor and should call log warn', function () { - _floorDataForAuction[bidderRequest.auctionId] = utils.deepClone(basicFloorConfig); - _floorDataForAuction[bidderRequest.auctionId].data.values = { 'video': 1.0 }; - runBidResponse(); - expect(returnedBidResponse).to.not.haveOwnProperty('floorData'); - expect(logWarnSpy.calledOnce).to.equal(true); - }); - it('if it finds a rule and floors should update the bid accordingly', function () { - _floorDataForAuction[bidderRequest.auctionId] = utils.deepClone(basicFloorConfig); - _floorDataForAuction[bidderRequest.auctionId].data.values = { 'banner': 1.0 }; - runBidResponse(); - expect(returnedBidResponse).to.haveOwnProperty('floorData'); - expect(returnedBidResponse.status).to.equal(CONSTANTS.BID_STATUS.BID_REJECTED); - expect(returnedBidResponse.cpm).to.equal(0); - }); - it('if it finds a rule and does not floor should update the bid accordingly', function () { - _floorDataForAuction[bidderRequest.auctionId] = utils.deepClone(basicFloorConfig); - _floorDataForAuction[bidderRequest.auctionId].data.values = { 'banner': 0.3 }; - runBidResponse(); - expect(returnedBidResponse).to.haveOwnProperty('floorData'); - expect(returnedBidResponse.floorData).to.deep.equal({ - floorRuleValue: 0.3, - floorValue: 0.3, - floorCurrency: 'USD', - floorRule: 'banner', - cpmAfterAdjustments: 0.5, - enforcements: { - bidAdjustment: true, - enforceJS: true, - enforcePBS: false, - floorDeals: false - }, - matchedFields: { - mediaType: 'banner' - } - }); - expect(returnedBidResponse.cpm).to.equal(0.5); - }); - it('if should work with more complex rules and update accordingly', function () { - _floorDataForAuction[bidderRequest.auctionId] = { - ...basicFloorConfig, - data: { - currency: 'USD', - schema: { fields: ['mediaType', 'size'], delimiter: '|' }, - values: { - 'banner|300x250': 0.5, - 'banner|300x600': 1.5, - 'banner|728x90': 2.5, - 'banner|*': 3.5, - 'video|640x480': 4.5, - 'video|*': 5.5 - }, - default: 10.0 - } - }; - runBidResponse(); - expect(returnedBidResponse).to.haveOwnProperty('floorData'); - expect(returnedBidResponse.floorData).to.deep.equal({ - floorValue: 0.5, - floorRuleValue: 0.5, - floorCurrency: 'USD', - floorRule: 'banner|300x250', - cpmAfterAdjustments: 0.5, - enforcements: { - bidAdjustment: true, - enforceJS: true, - enforcePBS: false, - floorDeals: false - }, - matchedFields: { - mediaType: 'banner', - size: '300x250' - } - }); - expect(returnedBidResponse.cpm).to.equal(0.5); - - // update bidResponse to have different combinations (should pick video|*) - runBidResponse({ - width: 300, - height: 250, - cpm: 7.5, - mediaType: 'video', - requestId: '1111', - }); - expect(returnedBidResponse).to.haveOwnProperty('floorData'); - expect(returnedBidResponse.floorData).to.deep.equal({ - floorRuleValue: 5.5, - floorValue: 5.5, - floorCurrency: 'USD', - floorRule: 'video|*', - cpmAfterAdjustments: 7.5, - enforcements: { - bidAdjustment: true, - enforceJS: true, - enforcePBS: false, - floorDeals: false - }, - matchedFields: { - mediaType: 'video', - size: '300x250' - } - }); - expect(returnedBidResponse.cpm).to.equal(7.5); - }); - }); - - describe('Post Auction Tests', function () { - let AUCTION_END_EVENT; - beforeEach(function () { - AUCTION_END_EVENT = { - auctionId: '123-45-6789' - }; - }); - it('should wait 3 seconds before deleting auction floor data', function () { - handleSetFloorsConfig({enabled: true}); - _floorDataForAuction[AUCTION_END_EVENT.auctionId] = utils.deepClone(basicFloorConfig); - events.emit(CONSTANTS.EVENTS.AUCTION_END, AUCTION_END_EVENT); - // should still be here - expect(_floorDataForAuction[AUCTION_END_EVENT.auctionId]).to.not.be.undefined; - // tick for 4 seconds - clock.tick(4000); - // should be undefined now - expect(_floorDataForAuction[AUCTION_END_EVENT.auctionId]).to.be.undefined; - }); - }); -}); diff --git a/test/spec/modules/projectLimeLightBidAdapter_spec.js b/test/spec/modules/projectLimeLightBidAdapter_spec.js deleted file mode 100644 index 778d8eedf7b..00000000000 --- a/test/spec/modules/projectLimeLightBidAdapter_spec.js +++ /dev/null @@ -1,259 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/projectLimeLightBidAdapter.js'; - -describe('ProjectLimeLightAdapter', function () { - const bid1 = { - bidId: '2dd581a2b6281d', - bidder: 'project-limelight', - bidderRequestId: '145e1d6a7837c9', - params: { - host: 'ads.project-limelight.com', - adUnitId: 123, - adUnitType: 'banner' - }, - placementCode: 'placement_0', - auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', - sizes: [[300, 250]], - transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e62' - } - const bid2 = { - bidId: '58ee9870c3164a', - bidder: 'project-limelight', - bidderRequestId: '209fdaf1c81649', - params: { - host: 'cpm.project-limelight.com', - adUnitId: 456, - adUnitType: 'banner' - }, - placementCode: 'placement_1', - auctionId: '482f88de-29ab-45c8-981a-d25e39454a34', - sizes: [[350, 200]], - transactionId: '068867d1-46ec-40bb-9fa0-e24611786fb4' - } - const bid3 = { - bidId: '019645c7d69460', - bidder: 'project-limelight', - bidderRequestId: 'f2b15f89e77ba6', - params: { - host: 'ads.project-limelight.com', - adUnitId: 789, - adUnitType: 'video' - }, - placementCode: 'placement_2', - auctionId: 'e4771143-6aa7-41ec-8824-ced4342c96c8', - sizes: [[800, 600]], - transactionId: '738d5915-6651-43b9-9b6b-d50517350917' - } - - describe('buildRequests', function () { - const serverRequests = spec.buildRequests([bid1, bid2, bid3]) - 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 () { - let data = serverRequest.data - expect(data).to.be.an('object') - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'secure', 'adUnits') - 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') - 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') - }) - }) - }) - it('Returns valid URL', function () { - expect(serverRequests[0].url).to.equal('https://ads.project-limelight.com/hb') - expect(serverRequests[1].url).to.equal('https://cpm.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 - }) - }) - describe('interpretBannerResponse', function () { - let resObject = { - body: [ { - requestId: '123', - mediaType: 'banner', - cpm: 0.3, - width: 320, - height: 50, - ad: '

Hello ad

', - ttl: 1000, - creativeId: '123asd', - netRevenue: true, - currency: 'USD' - } ] - }; - 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++) { - let dataItem = serverResponses[i]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'mediaType'); - 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.mediaType).to.be.a('string'); - } - 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; - }); - }); - }); - describe('interpretVideoResponse', function () { - let resObject = { - body: [ { - requestId: '123', - mediaType: 'video', - cpm: 0.3, - width: 320, - height: 50, - vastXml: '', - ttl: 1000, - creativeId: '123asd', - netRevenue: true, - currency: 'USD' - } ] - }; - 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++) { - let dataItem = serverResponses[i]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'vastXml', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'mediaType'); - 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.mediaType).to.be.a('string'); - } - 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; - }); - }); - }); - describe('isBidRequestValid', function() { - let bid = { - bidId: '2dd581a2b6281d', - bidder: 'project-limelight', - 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 true when required params found', function() { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function() { - let bidFailed = { - bidder: 'project-limelight', - 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' - }; - expect(spec.isBidRequestValid(bidFailed)).to.equal(false); - }); - }); - describe('interpretResponse', function() { - let resObject = { - requestId: '123', - mediaType: 'banner', - cpm: 0.3, - width: 320, - height: 50, - ad: '

Hello ad

', - ttl: 1000, - creativeId: '123asd', - netRevenue: true, - currency: 'USD' - }; - it('should skip responses which do not contain required params', function() { - let bidResponses = { - body: [ { - mediaType: 'banner', - cpm: 0.3, - ttl: 1000, - currency: 'USD' - }, resObject ] - } - expect(spec.interpretResponse(bidResponses)).to.deep.equal([ resObject ]); - }); - it('should skip responses which do not contain expected mediaType', function() { - let bidResponses = { - body: [ { - requestId: '123', - mediaType: 'native', - cpm: 0.3, - creativeId: '123asd', - ttl: 1000, - currency: 'USD' - }, resObject ] - } - expect(spec.interpretResponse(bidResponses)).to.deep.equal([ resObject ]); - }); - }); -}); - -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.transactionId) - expect(adUnit.sizes).to.deep.equal(bid.sizes.map(size => { - return { - width: size[0], - height: size[1] - } - })) -} diff --git a/test/spec/modules/proxistoreBidAdapter_spec.js b/test/spec/modules/proxistoreBidAdapter_spec.js deleted file mode 100644 index bdcdca06183..00000000000 --- a/test/spec/modules/proxistoreBidAdapter_spec.js +++ /dev/null @@ -1,166 +0,0 @@ -import { expect } from 'chai'; -let { spec } = require('modules/proxistoreBidAdapter'); -const BIDDER_CODE = 'proxistore'; -describe('ProxistoreBidAdapter', function () { - const consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - const bidderRequest = { - bidderCode: BIDDER_CODE, - auctionId: '1025ba77-5463-4877-b0eb-14b205cb9304', - bidderRequestId: '10edf38ec1a719', - gdprConsent: { - apiVersion: 2, - gdprApplies: true, - consentString: consentString, - vendorData: { - vendor: { - consents: { - 418: true, - }, - }, - }, - }, - }; - let bid = { - sizes: [[300, 600]], - params: { - website: 'example.fr', - language: 'fr', - }, - ortb2: { - user: { ext: { data: { segments: [], contextual_categories: {} } } }, - }, - auctionId: 442133079, - bidId: 464646969, - transactionId: 511916005, - }; - 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('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('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); - }); - }); - describe('buildRequests', function () { - const url = { - cookieBase: 'https://abs.proxistore.com/fr/v3/rtb/prebid/multi', - cookieLess: - 'https://abs.cookieless-proxistore.com/fr/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 gpdr consent - bidderRequest.gdprConsent.vendorData = null; - - request = spec.buildRequests([bid], bidderRequest); - expect(request.url).equal(url.cookieLess); - - // api v2 - bidderRequest.gdprConsent = { - gdprApplies: true, - allowAuctionWithoutConsent: true, - consentString: consentString, - vendorData: { - vendor: { - consents: { - '418': true - } - }, - }, - 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; - - // make it respond with a non USD floor should not send it - bid.getFloor = function () { - return { currency: 'EUR', floor: 1.0 }; - }; - 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 }; - }; - req = spec.buildRequests([bid], bidderRequest); - data = JSON.parse(req.data); - expect(data.bids[0].floor).to.be.null; - }); - }); - 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 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); - }); - }); -}); diff --git a/test/spec/modules/pubCommonId_spec.js b/test/spec/modules/pubCommonId_spec.js deleted file mode 100644 index a46ff26c4b8..00000000000 --- a/test/spec/modules/pubCommonId_spec.js +++ /dev/null @@ -1,370 +0,0 @@ -import { - requestBidHook, - getCookie, - setCookie, - setConfig, - isPubcidEnabled, - getExpInterval, - initPubcid, - setStorageItem, - getStorageItem, - removeStorageItem, - getPubcidConfig } from 'modules/pubCommonId.js'; -import { getAdUnits } from 'test/fixtures/fixtures.js'; -import * as auctionModule from 'src/auction.js'; -import { registerBidder } from 'src/adapters/bidderFactory.js'; -import * as utils from 'src/utils.js'; - -let events = require('src/events'); -let constants = require('src/constants.json'); - -var assert = require('chai').assert; -var expect = require('chai').expect; - -const ID_NAME = '_pubcid'; -const EXP = '_exp'; -const TIMEOUT = 2000; - -const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89a-f][0-9a-f]{3}-[0-9a-f]{12}$/; - -function cleanUp() { - window.document.cookie = ID_NAME + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;'; - localStorage.removeItem(ID_NAME); - localStorage.removeItem(ID_NAME + EXP); -} - -describe('Publisher Common ID', function () { - afterEach(function () { - $$PREBID_GLOBAL$$.requestBids.removeAll(); - }); - describe('Decorate adUnits', function () { - beforeEach(function() { - cleanUp(); - }); - afterEach(function() { - cleanUp(); - }); - - it('Check same cookie', function () { - let adUnits1 = getAdUnits(); - let adUnits2 = getAdUnits(); - let innerAdUnits1; - let innerAdUnits2; - let pubcid; - - expect(getCookie(ID_NAME)).to.be.null; // there should be no cookie initially - expect(localStorage.getItem(ID_NAME)).to.be.null; // there should be no local storage item either - - requestBidHook((config) => { innerAdUnits1 = config.adUnits }, {adUnits: adUnits1}); - pubcid = localStorage.getItem(ID_NAME); // local storage item is created after requestbidHook - - innerAdUnits1.forEach((unit) => { - unit.bids.forEach((bid) => { - expect(bid).to.have.deep.nested.property('crumbs.pubcid'); - expect(bid.crumbs.pubcid).to.equal(pubcid); - }); - }); - - // verify cookie is null - expect(getCookie(ID_NAME)).to.be.null; - - // verify same pubcid is preserved - requestBidHook((config) => { innerAdUnits2 = config.adUnits }, {adUnits: adUnits2}); - assert.deepEqual(innerAdUnits1, innerAdUnits2); - }); - - it('Check different cookies', function () { - let adUnits1 = getAdUnits(); - let adUnits2 = getAdUnits(); - let innerAdUnits1; - let innerAdUnits2; - let pubcid1; - let pubcid2; - - requestBidHook((config) => { innerAdUnits1 = config.adUnits }, {adUnits: adUnits1}); - pubcid1 = localStorage.getItem(ID_NAME); // get first pubcid - removeStorageItem(ID_NAME); // remove storage - - expect(pubcid1).to.not.be.null; - - innerAdUnits1.forEach((unit) => { - unit.bids.forEach((bid) => { - expect(bid).to.have.deep.nested.property('crumbs.pubcid'); - expect(bid.crumbs.pubcid).to.equal(pubcid1); - }); - }); - - requestBidHook((config) => { innerAdUnits2 = config.adUnits }, {adUnits: adUnits2}); - pubcid2 = localStorage.getItem(ID_NAME); // get second pubcid - - innerAdUnits2.forEach((unit) => { - unit.bids.forEach((bid) => { - expect(bid).to.have.deep.nested.property('crumbs.pubcid'); - expect(bid.crumbs.pubcid).to.equal(pubcid2); - }); - }); - - expect(pubcid2).to.not.be.null; - expect(pubcid1).to.not.equal(pubcid2); - }); - - it('Check new cookie', function () { - let adUnits = getAdUnits(); - let innerAdUnits; - let pubcid = utils.generateUUID(); - - setCookie(ID_NAME, pubcid, 600); - requestBidHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); - innerAdUnits.forEach((unit) => { - unit.bids.forEach((bid) => { - expect(bid).to.have.deep.nested.property('crumbs.pubcid'); - expect(bid.crumbs.pubcid).to.equal(pubcid); - }); - }); - }); - - it('Replicate cookie to storage', function() { - let adUnits = getAdUnits(); - let innerAdUnits; - let pubcid = utils.generateUUID(); - - setCookie(ID_NAME, pubcid, 600); - requestBidHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); - - expect(getStorageItem(ID_NAME)).to.equal(pubcid); - }); - - it('Does not replicate storage to cookie', function() { - let adUnits = getAdUnits(); - let innerAdUnits; - let pubcid = utils.generateUUID(); - - setStorageItem(ID_NAME, pubcid, 600); - requestBidHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); - - expect(getCookie(ID_NAME)).to.be.null; - }); - - it('Cookie only', function() { - setConfig({type: 'cookie'}); - let adUnits = getAdUnits(); - let innerAdUnits; - - requestBidHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); - - expect(getCookie(ID_NAME)).to.match(uuidPattern); - expect(getStorageItem(ID_NAME)).to.be.null; - }); - - it('Storage only', function() { - setConfig({type: 'html5'}); - let adUnits = getAdUnits(); - let innerAdUnits; - - requestBidHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); - - expect(getCookie(ID_NAME)).to.be.null; - expect(getStorageItem(ID_NAME)).to.match(uuidPattern); - }); - - it('Bad id recovery', function() { - let adUnits = getAdUnits(); - let innerAdUnits; - - setStorageItem(ID_NAME, 'undefined', 600); - requestBidHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); - - expect(getStorageItem(ID_NAME)).to.match(uuidPattern); - }); - }); - - describe('Configuration', function () { - beforeEach(() => { - setConfig(); - cleanUp(); - }); - afterEach(() => { - setConfig(); - cleanUp(); - }); - - it('empty config', function () { - // this should work as usual - setConfig({}); - let adUnits = getAdUnits(); - let innerAdUnits; - requestBidHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); - let pubcid = localStorage.getItem(ID_NAME); - innerAdUnits.forEach((unit) => { - unit.bids.forEach((bid) => { - expect(bid).to.have.deep.nested.property('crumbs.pubcid'); - expect(bid.crumbs.pubcid).to.equal(pubcid); - }); - }); - }); - - it('disable', function () { - setConfig({enable: false}); - let adUnits = getAdUnits(); - let unmodified = getAdUnits(); - let innerAdUnits; - expect(isPubcidEnabled()).to.be.false; - requestBidHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); - expect(getCookie(ID_NAME)).to.be.null; - assert.deepEqual(innerAdUnits, unmodified); - setConfig({enable: true}); // reset - requestBidHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); - innerAdUnits.forEach((unit) => { - unit.bids.forEach((bid) => { - expect(bid).to.have.deep.nested.property('crumbs.pubcid'); - }); - }); - }); - - it('change expiration time', function () { - setConfig({expInterval: 100}); - expect(getExpInterval()).to.equal(100); - let adUnits = getAdUnits(); - let innerAdUnits; - requestBidHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); - innerAdUnits.every((unit) => { - unit.bids.forEach((bid) => { - expect(bid).to.have.deep.nested.property('crumbs.pubcid'); - }); - }); - }); - - it.skip('disable auto create', function() { - setConfig({ - create: false - }); - - const config = getPubcidConfig(); - expect(config.create).to.be.false; - expect(config.typeEnabled).to.equal('html5'); - - let adUnits = getAdUnits(); - let innerAdUnits; - requestBidHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); - - const pubcid = localStorage.getItem(ID_NAME); - expect(pubcid).to.be.null; - }); - }); - - describe('Invoking requestBid', function () { - let createAuctionStub; - let adUnits; - let adUnitCodes; - let capturedReqs; - let sampleSpec = { - code: 'sampleBidder', - isBidRequestValid: () => {}, - buildRequest: (reqs) => {}, - interpretResponse: () => {}, - getUserSyncs: () => {} - }; - - beforeEach(function () { - adUnits = [{ - code: 'adUnit-code', - mediaTypes: { - banner: {}, - native: {}, - }, - sizes: [[300, 200], [300, 600]], - bids: [ - {bidder: 'sampleBidder', params: {placementId: 'banner-only-bidder'}} - ] - }]; - adUnitCodes = ['adUnit-code']; - let auction = auctionModule.newAuction({adUnits, adUnitCodes, callback: function() {}, cbTimeout: TIMEOUT}); - createAuctionStub = sinon.stub(auctionModule, 'newAuction'); - createAuctionStub.returns(auction); - initPubcid(); - registerBidder(sampleSpec); - }); - - afterEach(function () { - auctionModule.newAuction.restore(); - }); - - it('test hook', function() { - $$PREBID_GLOBAL$$.requestBids({adUnits}); - adUnits.forEach((unit) => { - unit.bids.forEach((bid) => { - expect(bid).to.have.deep.nested.property('crumbs.pubcid'); - }); - }); - }); - }); - - describe('Storage item functions', () => { - beforeEach(() => { cleanUp(); }); - afterEach(() => { cleanUp(); }); - - it('Test set', () => { - const key = ID_NAME; - const val = 'test-set-value'; - // Set item in localStorage - const now = Date.now(); - setStorageItem(key, val, 100); - // Check both item and expiry time are stored - const expVal = localStorage.getItem(key + EXP); - const storedVal = localStorage.getItem(key); - // Verify expiry - expect(expVal).to.not.be.null; - const expDate = new Date(expVal); - expect((expDate.getTime() - now) / 1000).to.be.closeTo(100 * 60, 5); - // Verify value - expect(storedVal).to.equal(val); - }); - - it('Test get and remove', () => { - const key = ID_NAME; - const val = 'test-get-remove'; - setStorageItem(key, val, 10); - expect(getStorageItem(key)).to.equal(val); - removeStorageItem(key); - expect(getStorageItem(key)).to.be.null; - }); - - it('Test expiry', () => { - const key = ID_NAME; - const val = 'test-expiry'; - setStorageItem(key, val, -1); - expect(localStorage.getItem(key)).to.equal(val); - expect(getStorageItem(key)).to.be.null; - expect(localStorage.getItem(key)).to.be.null; - }); - }); - - describe('event callback', () => { - beforeEach(() => { - setConfig(); - cleanUp(); - sinon.stub(events, 'getEvents').returns([]); - sinon.stub(utils, 'triggerPixel'); - }); - afterEach(() => { - setConfig(); - cleanUp(); - events.getEvents.restore(); - utils.triggerPixel.restore(); - }); - it('auction end trigger', () => { - setConfig({ - pixelUrl: '/any/url' - }); - - let adUnits = getAdUnits(); - let innerAdUnits; - requestBidHook((config) => { innerAdUnits = config.adUnits }, {adUnits}); - - expect(utils.triggerPixel.called).to.be.false; - events.emit(constants.EVENTS.AUCTION_END, {}); - expect(utils.triggerPixel.called).to.be.true; - expect(utils.triggerPixel.getCall(0).args[0]).to.include('/any/url'); - }); - }); -}); diff --git a/test/spec/modules/pubgeniusBidAdapter_spec.js b/test/spec/modules/pubgeniusBidAdapter_spec.js deleted file mode 100644 index 57b83fced06..00000000000 --- a/test/spec/modules/pubgeniusBidAdapter_spec.js +++ /dev/null @@ -1,555 +0,0 @@ -import { expect } from 'chai'; - -import { spec } from 'modules/pubgeniusBidAdapter.js'; -import { config } from 'src/config.js'; -import { VIDEO } from 'src/mediaTypes.js'; -import { deepClone, parseQueryStringParameters } from 'src/utils.js'; -import { server } from 'test/mocks/xhr.js'; - -const { - code, - supportedMediaTypes, - isBidRequestValid, - buildRequests, - interpretResponse, - getUserSyncs, - onTimeout, -} = spec; - -describe('pubGENIUS adapter', () => { - describe('code', () => { - it('should be pubgenius', () => { - expect(code).to.equal('pubgenius'); - }); - }); - - describe('supportedMediaTypes', () => { - it('should contain banner and video', () => { - expect(supportedMediaTypes).to.deep.equal(['banner', 'video']); - }); - }); - - describe('isBidRequestValid', () => { - let bid = null; - - beforeEach(() => { - bid = { - mediaTypes: { - banner: { - sizes: [[300, 600], [300, 250]], - }, - }, - params: { - adUnitId: 1112, - }, - }; - }); - - it('should return true with numeric adUnitId ', () => { - expect(isBidRequestValid(bid)).to.be.true; - }); - - it('should return true with string adUnitId ', () => { - bid.params.adUnitId = '1112'; - - expect(isBidRequestValid(bid)).to.be.true; - }); - - it('should return false without adUnitId', () => { - delete bid.params.adUnitId; - - expect(isBidRequestValid(bid)).to.be.false; - }); - - it('should return false with adUnitId of invalid type', () => { - bid.params.adUnitId = [1112]; - - expect(isBidRequestValid(bid)).to.be.false; - }); - - it('should return false with empty sizes', () => { - bid.mediaTypes.banner.sizes = []; - - expect(isBidRequestValid(bid)).to.be.false; - }); - - it('should return false with invalid size', () => { - bid.mediaTypes.banner.sizes = [[300, 600, 250]]; - - expect(isBidRequestValid(bid)).to.be.false; - }); - - it('should return false without banner or video', () => { - bid.mediaTypes = {}; - - expect(isBidRequestValid(bid)).to.be.false; - }); - - it('should return true with valid video media type', () => { - bid.mediaTypes = { - video: { - context: 'instream', - playerSize: [[100, 100]], - mimes: ['video/mp4'], - protocols: [1], - }, - }; - - expect(isBidRequestValid(bid)).to.be.true; - }); - - it('should return true with valid video params', () => { - bid.params.video = { - placement: 1, - w: 200, - h: 200, - mimes: ['video/mp4'], - protocols: [1], - }; - - expect(isBidRequestValid(bid)).to.be.true; - }); - - it('should return false without video protocols', () => { - bid.mediaTypes = { - video: { - context: 'instream', - playerSize: [[100, 100]], - }, - }; - bid.params.video = { - mimes: ['video/mp4'], - }; - - expect(isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', () => { - const origBidderTimeout = config.getConfig('bidderTimeout'); - const origPageUrl = config.getConfig('pageUrl'); - const origCoppa = config.getConfig('coppa'); - - after(() => { - config.setConfig({ - bidderTimeout: origBidderTimeout, - pageUrl: origPageUrl, - coppa: origCoppa, - }); - }); - - let bidRequest = null; - let bidderRequest = null; - let expectedRequest = null; - - beforeEach(() => { - bidRequest = { - adUnitCode: 'test-div', - auctionId: 'fake-auction-id', - bidId: 'fakebidid', - bidder: 'pubgenius', - bidderRequestId: 'fakebidderrequestid', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0, - mediaTypes: { - banner: { - sizes: [[300, 600], [300, 250]], - }, - }, - params: { - adUnitId: 1112, - }, - transactionId: 'fake-transaction-id', - }; - - bidderRequest = { - auctionId: 'fake-auction-id', - bidderCode: 'pubgenius', - bidderRequestId: 'fakebidderrequestid', - refererInfo: {}, - timeout: 1200, - }; - - expectedRequest = { - method: 'POST', - url: 'https://ortb.adpearl.io/prebid/auction', - data: { - id: 'fake-auction-id', - imp: [ - { - id: 'fakebidid', - banner: { - format: [{ w: 300, h: 600 }, { w: 300, h: 250 }], - topframe: 0, - }, - tagid: '1112', - }, - ], - tmax: 1200, - ext: { - pbadapter: { - version: '1.1.0', - }, - }, - }, - }; - - config.setConfig({ - bidderTimeout: 1000, - pageUrl: undefined, - coppa: undefined, - }); - }); - - it('should build basic requests correctly', () => { - expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); - }); - - it('should build requests with multiple ad units', () => { - const bidRequest1 = deepClone(bidRequest); - bidRequest1.adUnitCode = 'test-div-1'; - bidRequest1.bidId = 'fakebidid1'; - bidRequest1.mediaTypes.banner.sizes = [[728, 90]]; - bidRequest1.params.adUnitId = '1111'; - - expectedRequest.data.imp.push({ - id: 'fakebidid1', - banner: { - format: [{ w: 728, h: 90 }], - topframe: 0, - }, - tagid: '1111', - }); - - expect(buildRequests([bidRequest, bidRequest1], bidderRequest)).to.deep.equal(expectedRequest); - }); - - it('should take bid floor from getFloor interface', () => { - bidRequest.getFloor = () => ({ floor: 0.5, currency: 'USD' }); - expectedRequest.data.imp[0].bidfloor = 0.5; - - expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); - }); - - it('should take position in bidder params', () => { - bidRequest.params.position = 3; - expectedRequest.data.imp[0].banner.pos = 3; - - expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); - }); - - it('should take pageUrl in config over referer in refererInfo', () => { - config.setConfig({ pageUrl: 'http://pageurl.org' }); - bidderRequest.refererInfo.referer = 'http://referer.org'; - expectedRequest.data.site = { page: 'http://pageurl.org' }; - - expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); - }); - - it('should use canonical URL over referer in refererInfo', () => { - bidderRequest.refererInfo.canonicalUrl = 'http://pageurl.org'; - bidderRequest.refererInfo.referer = 'http://referer.org'; - expectedRequest.data.site = { page: 'http://pageurl.org' }; - - expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); - }); - - it('should take gdprConsent when GDPR does not apply', () => { - bidderRequest.gdprConsent = { - gdprApplies: false, - consentString: 'fakeconsent', - }; - expectedRequest.data.regs = { - ext: { gdpr: 0 }, - }; - - expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); - }); - - it('should take gdprConsent when GDPR applies', () => { - bidderRequest.gdprConsent = { - gdprApplies: true, - consentString: 'fakeconsent', - }; - expectedRequest.data.regs = { - ext: { gdpr: 1 }, - }; - expectedRequest.data.user = { - ext: { consent: 'fakeconsent' }, - }; - - expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); - }); - - it('should take uspConsent', () => { - bidderRequest.uspConsent = '1---'; - expectedRequest.data.regs = { - ext: { us_privacy: '1---' }, - }; - - expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); - }); - - it('should take schain', () => { - const schain = { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '0001', - hp: 1 - } - ] - }; - bidRequest.schain = deepClone(schain); - expectedRequest.data.source = { - ext: { schain: deepClone(schain) }, - }; - - expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); - }); - - it('should take coppa', () => { - config.setConfig({ coppa: true }); - expectedRequest.data.regs = { coppa: 1 }; - - expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); - }); - - it('should take user IDs', () => { - const eid = { - source: 'adserver.org', - uids: [ - { - id: 'fake-user-id', - atype: 1, - ext: { rtiPartner: 'TDID' }, - }, - ], - }; - bidRequest.userIdAsEids = [deepClone(eid)]; - expectedRequest.data.user = { - ext: { - eids: [deepClone(eid)], - }, - }; - - expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); - }); - - it('should not take unsupported user IDs', () => { - bidRequest.userIdAsEids = [ - { - source: 'pubcid.org', - uids: [ - { - id: 'fake-user-id', - atype: 1, - }, - ], - }, - ]; - - expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); - }); - - it('should not take empty user IDs', () => { - bidRequest.userIdAsEids = []; - - expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); - }); - - it('should build video imp', () => { - bidRequest.mediaTypes = { - video: { - context: 'instream', - playerSize: [[200, 100]], - mimes: ['video/mp4'], - protocols: [2, 3], - api: [1, 2], - playbackmethod: [3, 4], - }, - }; - bidRequest.params.video = { - minduration: 5, - maxduration: 100, - skip: 1, - skipafter: 1, - startdelay: -1, - }; - - delete expectedRequest.data.imp[0].banner; - expectedRequest.data.imp[0].video = { - mimes: ['video/mp4'], - minduration: 5, - maxduration: 100, - protocols: [2, 3], - w: 200, - h: 100, - startdelay: -1, - placement: 1, - skip: 1, - skipafter: 1, - playbackmethod: [3, 4], - api: [1, 2], - }; - - expect(buildRequests([bidRequest], bidderRequest)).to.deep.equal(expectedRequest); - }); - }); - - describe('interpretResponse', () => { - let serverResponse = null; - let expectedBidResponse = null; - - beforeEach(() => { - serverResponse = { - body: { - seatbid: [ - { - seat: 'pubgenius', - bid: [ - { - impid: 'fakebidid', - price: 0.3, - w: 300, - h: 250, - adm: 'fake_creative', - exp: 60, - crid: 'fakecreativeid', - }, - ], - }, - ], - }, - }; - expectedBidResponse = { - requestId: 'fakebidid', - cpm: 0.3, - currency: 'USD', - width: 300, - height: 250, - ad: 'fake_creative', - ttl: 60, - creativeId: 'fakecreativeid', - netRevenue: true, - }; - }); - - it('should interpret response correctly', () => { - expect(interpretResponse(serverResponse)).to.deep.equal([expectedBidResponse]); - }); - - it('should interpret response with adomain', () => { - serverResponse.body.seatbid[0].bid[0].adomain = ['fakeaddomain']; - expectedBidResponse.meta = { - advertiserDomains: ['fakeaddomain'], - }; - - expect(interpretResponse(serverResponse)).to.deep.equal([expectedBidResponse]); - }); - - it('should interpret no bids', () => { - expect(interpretResponse({ body: {} })).to.deep.equal([]); - }); - - it('should interpret video response', () => { - serverResponse.body.seatbid[0].bid[0] = { - ...serverResponse.body.seatbid[0].bid[0], - nurl: 'http://vasturl/cache?id=x', - ext: { - pbadapter: { - mediaType: 'video', - cacheKey: 'x', - }, - }, - }; - - delete expectedBidResponse.ad; - expectedBidResponse = { - ...expectedBidResponse, - vastUrl: 'http://vasturl/cache?id=x', - vastXml: 'fake_creative', - mediaType: VIDEO, - }; - - expect(interpretResponse(serverResponse)).to.deep.equal([expectedBidResponse]); - }); - }); - - describe('getUserSyncs', () => { - let syncOptions = null; - let expectedSync = null; - - beforeEach(() => { - syncOptions = { - iframeEnabled: true, - pixelEnabled: true, - }; - expectedSync = { - type: 'iframe', - url: 'https://ortb.adpearl.io/usersync/pixels.html?', - }; - }); - - it('should return iframe pixels', () => { - expect(getUserSyncs(syncOptions)).to.deep.equal([expectedSync]); - }); - - it('should return empty when iframe is not enabled', () => { - syncOptions.iframeEnabled = false; - - expect(getUserSyncs(syncOptions)).to.deep.equal([]); - }); - - it('should return sync when GDPR applies', () => { - const gdprConsent = { - gdprApplies: true, - consentString: 'fake-gdpr-consent', - }; - expectedSync.url = expectedSync.url + parseQueryStringParameters({ - gdpr: 1, - consent: 'fake-gdpr-consent', - }); - - expect(getUserSyncs(syncOptions, [], gdprConsent)).to.deep.equal([expectedSync]); - }); - - it('should return sync when GDPR does not apply', () => { - const gdprConsent = { - gdprApplies: false, - }; - expectedSync.url = expectedSync.url + parseQueryStringParameters({ gdpr: 0 }); - - expect(getUserSyncs(syncOptions, [], gdprConsent)).to.deep.equal([expectedSync]); - }); - - it('should return sync with US privacy', () => { - expectedSync.url = expectedSync.url + parseQueryStringParameters({ us_privacy: '1---' }); - - expect(getUserSyncs(syncOptions, [], undefined, '1---')).to.deep.equal([expectedSync]); - }); - }); - - describe('onTimeout', () => { - it('should send timeout data', () => { - const timeoutData = { - bidder: 'pubgenius', - bidId: 'fakebidid', - params: { - adUnitId: 1234, - }, - adUnitCode: 'fake-ad-unit-code', - timeout: 3000, - auctionId: 'fake-auction-id', - }; - onTimeout(timeoutData); - - expect(server.requests[0].method).to.equal('POST'); - expect(server.requests[0].url).to.equal('https://ortb.adpearl.io/prebid/events?type=timeout'); - expect(JSON.parse(server.requests[0].requestBody)).to.deep.equal(timeoutData); - }); - }); -}); diff --git a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js b/test/spec/modules/pubmaticAnalyticsAdapter_spec.js deleted file mode 100755 index 11de7b13208..00000000000 --- a/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +++ /dev/null @@ -1,914 +0,0 @@ -import pubmaticAnalyticsAdapter from 'modules/pubmaticAnalyticsAdapter.js'; -import CONSTANTS from 'src/constants.json'; -import { config } from 'src/config.js'; -import { - setConfig, - addBidResponseHook, -} from 'modules/currency.js'; - -// using es6 "import * as events from 'src/events'" causes the events.getEvents stub not to work... -let events = require('src/events'); -let ajax = require('src/ajax'); -let utils = require('src/utils'); - -const DEFAULT_USER_AGENT = window.navigator.userAgent; -const MOBILE_USER_AGENT = 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Mobile/15E148 Safari/604.1'; -const setUADefault = () => { window.navigator.__defineGetter__('userAgent', function () { return DEFAULT_USER_AGENT }) }; -const setUAMobile = () => { window.navigator.__defineGetter__('userAgent', function () { return MOBILE_USER_AGENT }) }; -const setUANull = () => { window.navigator.__defineGetter__('userAgent', function () { return null }) }; - -const { - EVENTS: { - AUCTION_INIT, - AUCTION_END, - BID_REQUESTED, - BID_RESPONSE, - BIDDER_DONE, - BID_WON, - BID_TIMEOUT, - SET_TARGETING - } -} = CONSTANTS; - -const BID = { - 'bidder': 'pubmatic', - 'width': 640, - 'height': 480, - 'mediaType': 'video', - 'statusMessage': 'Bid available', - 'bidId': '2ecff0db240757', - 'partnerImpId': 'partnerImpressionID-1', - 'adId': 'fake_ad_id', - 'source': 's2s', - 'requestId': '2ecff0db240757', - 'currency': 'USD', - 'creativeId': '3571560', - 'cpm': 1.22752, - 'originalCpm': 1.22752, - 'originalCurrency': 'USD', - 'ttl': 300, - 'netRevenue': false, - 'ad': '', - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa', - 'responseTimestamp': 1519149629415, - 'requestTimestamp': 1519149628471, - 'adUnitCode': '/19968336/header-bid-tag-0', - 'timeToRespond': 944, - 'pbLg': '1.00', - 'pbMg': '1.20', - 'pbHg': '1.22', - 'pbAg': '1.20', - 'pbDg': '1.22', - 'pbCg': '', - 'size': '640x480', - 'adserverTargeting': { - 'hb_bidder': 'pubmatic', - 'hb_adid': '2ecff0db240757', - 'hb_pb': 1.20, - 'hb_size': '640x480', - 'hb_source': 'server' - }, - getStatusCode() { - return 1; - } -}; - -const BID2 = Object.assign({}, BID, { - adUnitCode: '/19968336/header-bid-tag-1', - bidId: '3bd4ebb1c900e2', - partnerImpId: 'partnerImpressionID-2', - adId: 'fake_ad_id_2', - requestId: '3bd4ebb1c900e2', - width: 728, - height: 90, - mediaType: 'banner', - cpm: 1.52, - originalCpm: 1.52, - dealId: 'the-deal-id', - dealChannel: 'PMP', - mi: 'matched-impression', - seatBidId: 'aaaa-bbbb-cccc-dddd', - adserverTargeting: { - 'hb_bidder': 'pubmatic', - 'hb_adid': '3bd4ebb1c900e2', - 'hb_pb': '1.500', - 'hb_size': '728x90', - 'hb_source': 'server' - } -}); - -const MOCK = { - SET_TARGETING: { - [BID.adUnitCode]: BID.adserverTargeting, - [BID2.adUnitCode]: BID2.adserverTargeting - }, - AUCTION_INIT: { - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa', - 'timestamp': 1519767010567, - 'auctionStatus': 'inProgress', - 'adUnits': [ { - 'code': '/19968336/header-bid-tag-1', - 'sizes': [[640, 480]], - 'bids': [ { - 'bidder': 'pubmatic', - 'params': { - 'publisherId': '1001' - } - } ], - 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014' - } - ], - 'adUnitCodes': ['/19968336/header-bid-tag-1'], - 'bidderRequests': [ { - 'bidderCode': 'pubmatic', - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa', - 'bidderRequestId': '1be65d7958826a', - 'bids': [ { - 'bidder': 'pubmatic', - 'params': { - 'publisherId': '1001', - 'kgpv': 'this-is-a-kgpv' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[640, 480]] - } - }, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014', - 'sizes': [[640, 480]], - 'bidId': '2ecff0db240757', - 'bidderRequestId': '1be65d7958826a', - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa', - 'src': 'client', - 'bidRequestsCount': 1 - } - ], - 'timeout': 3000, - 'refererInfo': { - 'referer': 'http://www.test.com/page.html', 'reachedTop': true, 'numIframes': 0, 'stack': ['http://www.test.com/page.html'] - } - } - ], - 'bidsReceived': [], - 'winningBids': [], - 'timeout': 3000 - }, - BID_REQUESTED: { - 'bidder': 'pubmatic', - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa', - 'bidderRequestId': '1be65d7958826a', - 'bids': [ - { - 'bidder': 'pubmatic', - 'params': { - 'publisherId': '1001', - 'video': { - 'minduration': 30, - 'skippable': true - } - }, - 'mediaType': 'video', - 'adUnitCode': '/19968336/header-bid-tag-0', - 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014', - 'sizes': [[640, 480]], - 'bidId': '2ecff0db240757', - 'bidderRequestId': '1be65d7958826a', - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa' - }, - { - 'bidder': 'pubmatic', - 'params': { - 'publisherId': '1001', - 'kgpv': 'this-is-a-kgpv' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[1000, 300], [970, 250], [728, 90]] - } - }, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'transactionId': 'c116413c-9e3f-401a-bee1-d56aec29a1d4', - 'sizes': [[1000, 300], [970, 250], [728, 90]], - 'bidId': '3bd4ebb1c900e2', - 'seatBidId': 'aaaa-bbbb-cccc-dddd', - 'bidderRequestId': '1be65d7958826a', - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa' - } - ], - 'auctionStart': 1519149536560, - 'timeout': 5000, - 'start': 1519149562216, - 'refererInfo': { - 'referer': 'http://www.test.com/page.html', 'reachedTop': true, 'numIframes': 0, 'stack': ['http://www.test.com/page.html'] - }, - 'gdprConsent': { - 'consentString': 'here-goes-gdpr-consent-string', - 'gdprApplies': true - } - }, - BID_RESPONSE: [ - BID, - BID2 - ], - AUCTION_END: { - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa' - }, - BID_WON: [ - Object.assign({}, BID, { - 'status': 'rendered' - }), - Object.assign({}, BID2, { - 'status': 'rendered' - }) - ], - BIDDER_DONE: { - 'bidderCode': 'pubmatic', - 'bids': [ - BID, - Object.assign({}, BID2, { - 'serverResponseTimeMs': 42, - }) - ] - }, - BID_TIMEOUT: [ - { - 'bidId': '3bd4ebb1c900e2', - 'bidder': 'pubmatic', - 'adUnitCode': '/19968336/header-bid-tag-1', - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa' - } - ] -}; - -function getLoggerJsonFromRequest(requestBody) { - return JSON.parse(decodeURIComponent(requestBody.split('json=')[1])); -} - -describe('pubmatic analytics adapter', function () { - let sandbox; - let xhr; - let requests; - let oldScreen; - let clock; - - beforeEach(function () { - setUADefault(); - sandbox = sinon.sandbox.create(); - - xhr = sandbox.useFakeXMLHttpRequest(); - requests = []; - xhr.onCreate = request => requests.push(request); - - sandbox.stub(events, 'getEvents').returns([]); - - clock = sandbox.useFakeTimers(1519767013781); - - config.setConfig({ - s2sConfig: { - timeout: 1000, - accountId: 10000, - bidders: ['pubmatic'] - } - }) - }); - - afterEach(function () { - sandbox.restore(); - config.resetConfig(); - }); - - it('should require publisherId', function () { - sandbox.stub(utils, 'logError'); - pubmaticAnalyticsAdapter.enableAnalytics({ - options: {} - }); - expect(utils.logError.called).to.equal(true); - }); - - describe('when handling events', function() { - beforeEach(function () { - pubmaticAnalyticsAdapter.enableAnalytics({ - options: { - publisherId: 9999, - profileId: 1111, - profileVersionId: 20 - } - }); - }); - - afterEach(function () { - pubmaticAnalyticsAdapter.disableAnalytics(); - }); - - it('Logger: best case + win tracker', function() { - sandbox.stub($$PREBID_GLOBAL$$, 'getHighestCpmBids').callsFake((key) => { - return [MOCK.BID_RESPONSE[0], MOCK.BID_RESPONSE[1]] - }); - - config.setConfig({ - testGroupId: 15 - }); - - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[1]); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON[0]); - events.emit(BID_WON, MOCK.BID_WON[1]); - - clock.tick(2000 + 1000); - expect(requests.length).to.equal(3); // 1 logger and 2 win-tracker - let request = requests[2]; // logger is executed late, trackers execute first - expect(request.url).to.equal('https://t.pubmatic.com/wl?pubid=9999'); - let data = getLoggerJsonFromRequest(request.requestBody); - expect(data.pubid).to.equal('9999'); - expect(data.pid).to.equal('1111'); - expect(data.pdvid).to.equal('20'); - expect(data.iid).to.equal('25c6d7f5-699a-4bfc-87c9-996f915341fa'); - expect(data.to).to.equal('3000'); - expect(data.purl).to.equal('http://www.test.com/page.html'); - expect(data.orig).to.equal('www.test.com'); - expect(data.tst).to.equal(1519767016); - expect(data.tgid).to.equal(15); - expect(data.s).to.be.an('array'); - expect(data.s.length).to.equal(2); - // slot 1 - expect(data.s[0].sn).to.equal('/19968336/header-bid-tag-0'); - expect(data.s[0].sz).to.deep.equal(['640x480']); - expect(data.s[0].ps).to.be.an('array'); - expect(data.s[0].ps.length).to.equal(1); - expect(data.s[0].ps[0].pn).to.equal('pubmatic'); - expect(data.s[0].ps[0].bidid).to.equal('2ecff0db240757'); - expect(data.s[0].ps[0].piid).to.equal('partnerImpressionID-1'); - expect(data.s[0].ps[0].db).to.equal(0); - expect(data.s[0].ps[0].kgpv).to.equal('/19968336/header-bid-tag-0'); - expect(data.s[0].ps[0].kgpsv).to.equal('/19968336/header-bid-tag-0'); - expect(data.s[0].ps[0].psz).to.equal('640x480'); - expect(data.s[0].ps[0].eg).to.equal(1.23); - expect(data.s[0].ps[0].en).to.equal(1.23); - expect(data.s[0].ps[0].di).to.equal(''); - expect(data.s[0].ps[0].dc).to.equal(''); - expect(data.s[0].ps[0].l1).to.equal(3214); - expect(data.s[0].ps[0].l2).to.equal(0); - expect(data.s[0].ps[0].ss).to.equal(1); - expect(data.s[0].ps[0].t).to.equal(0); - expect(data.s[0].ps[0].wb).to.equal(1); - expect(data.s[0].ps[0].af).to.equal('video'); - expect(data.s[0].ps[0].ocpm).to.equal(1.23); - expect(data.s[0].ps[0].ocry).to.equal('USD'); - // slot 2 - expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); - expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); - expect(data.s[1].ps).to.be.an('array'); - expect(data.s[1].ps.length).to.equal(1); - expect(data.s[1].ps[0].pn).to.equal('pubmatic'); - expect(data.s[1].ps[0].bidid).to.equal('3bd4ebb1c900e2'); - expect(data.s[1].ps[0].piid).to.equal('partnerImpressionID-2'); - expect(data.s[1].ps[0].db).to.equal(0); - expect(data.s[1].ps[0].kgpv).to.equal('this-is-a-kgpv'); - expect(data.s[1].ps[0].kgpsv).to.equal('this-is-a-kgpv'); - expect(data.s[1].ps[0].psz).to.equal('728x90'); - expect(data.s[1].ps[0].eg).to.equal(1.52); - expect(data.s[1].ps[0].en).to.equal(1.52); - expect(data.s[1].ps[0].di).to.equal('the-deal-id'); - expect(data.s[1].ps[0].dc).to.equal('PMP'); - expect(data.s[1].ps[0].mi).to.equal('matched-impression'); - expect(data.s[1].ps[0].l1).to.equal(3214); - expect(data.s[1].ps[0].l2).to.equal(0); - expect(data.s[1].ps[0].ss).to.equal(1); - expect(data.s[1].ps[0].t).to.equal(0); - expect(data.s[1].ps[0].wb).to.equal(1); - expect(data.s[1].ps[0].af).to.equal('banner'); - expect(data.s[1].ps[0].ocpm).to.equal(1.52); - expect(data.s[1].ps[0].ocry).to.equal('USD'); - - // tracker slot1 - let firstTracker = requests[0].url; - expect(firstTracker.split('?')[0]).to.equal('https://t.pubmatic.com/wt'); - data = {}; - firstTracker.split('?')[1].split('&').map(e => e.split('=')).forEach(e => data[e[0]] = e[1]); - expect(data.pubid).to.equal('9999'); - expect(decodeURIComponent(data.purl)).to.equal('http://www.test.com/page.html'); - expect(data.tst).to.equal('1519767014'); - expect(data.iid).to.equal('25c6d7f5-699a-4bfc-87c9-996f915341fa'); - expect(data.bidid).to.equal('2ecff0db240757'); - expect(data.pid).to.equal('1111'); - expect(data.pdvid).to.equal('20'); - expect(decodeURIComponent(data.slot)).to.equal('/19968336/header-bid-tag-0'); - expect(decodeURIComponent(data.kgpv)).to.equal('/19968336/header-bid-tag-0'); - expect(data.pn).to.equal('pubmatic'); - expect(data.eg).to.equal('1.23'); - expect(data.en).to.equal('1.23'); - expect(data.piid).to.equal('partnerImpressionID-1'); - }); - - it('bidCpmAdjustment: USD: Logger: best case + win tracker', function() { - const bidCopy = utils.deepClone(BID); - bidCopy.cpm = bidCopy.originalCpm * 2; // bidCpmAdjustment => bidCpm * 2 - - sandbox.stub($$PREBID_GLOBAL$$, 'getHighestCpmBids').callsFake((key) => { - return [bidCopy, MOCK.BID_RESPONSE[1]] - }); - - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(BID_RESPONSE, bidCopy); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[1]); - events.emit(BID_RESPONSE, bidCopy); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON[0]); - events.emit(BID_WON, MOCK.BID_WON[1]); - - clock.tick(2000 + 1000); - expect(requests.length).to.equal(3); // 1 logger and 2 win-tracker - let request = requests[2]; // logger is executed late, trackers execute first - expect(request.url).to.equal('https://t.pubmatic.com/wl?pubid=9999'); - let data = getLoggerJsonFromRequest(request.requestBody); - expect(data.pubid).to.equal('9999'); - expect(data.pid).to.equal('1111'); - expect(data.s).to.be.an('array'); - expect(data.s.length).to.equal(2); - expect(data.tgid).to.equal(0); - // slot 1 - expect(data.s[0].sn).to.equal('/19968336/header-bid-tag-0'); - expect(data.s[0].sz).to.deep.equal(['640x480']); - expect(data.s[0].ps).to.be.an('array'); - expect(data.s[0].ps.length).to.equal(1); - expect(data.s[0].ps[0].pn).to.equal('pubmatic'); - expect(data.s[0].ps[0].bidid).to.equal('2ecff0db240757'); - expect(data.s[0].ps[0].kgpv).to.equal('/19968336/header-bid-tag-0'); - expect(data.s[0].ps[0].eg).to.equal(1.23); - expect(data.s[0].ps[0].en).to.equal(2.46); - expect(data.s[0].ps[0].wb).to.equal(1); - expect(data.s[0].ps[0].af).to.equal('video'); - expect(data.s[0].ps[0].ocpm).to.equal(1.23); - expect(data.s[0].ps[0].ocry).to.equal('USD'); - // tracker slot1 - let firstTracker = requests[0].url; - expect(firstTracker.split('?')[0]).to.equal('https://t.pubmatic.com/wt'); - data = {}; - firstTracker.split('?')[1].split('&').map(e => e.split('=')).forEach(e => data[e[0]] = e[1]); - expect(data.pubid).to.equal('9999'); - expect(data.tst).to.equal('1519767014'); - expect(data.iid).to.equal('25c6d7f5-699a-4bfc-87c9-996f915341fa'); - expect(data.eg).to.equal('1.23'); - expect(data.en).to.equal('2.46'); - }); - - it('bidCpmAdjustment: JPY: Logger: best case + win tracker', function() { - config.setConfig({ - testGroupId: 25 - }); - - setConfig({ - adServerCurrency: 'JPY', - rates: { - USD: { - JPY: 100 - } - } - }); - const bidCopy = utils.deepClone(BID); - bidCopy.originalCpm = 100; - bidCopy.originalCurrency = 'JPY'; - bidCopy.currency = 'JPY'; - bidCopy.cpm = bidCopy.originalCpm * 2; // bidCpmAdjustment => bidCpm * 2 - - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - // events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); - events.emit(BID_RESPONSE, bidCopy); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[1]); - events.emit(BID_RESPONSE, bidCopy); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON[0]); - events.emit(BID_WON, MOCK.BID_WON[1]); - - clock.tick(2000 + 1000); - expect(requests.length).to.equal(3); // 1 logger and 2 win-tracker - let request = requests[2]; // logger is executed late, trackers execute first - expect(request.url).to.equal('https://t.pubmatic.com/wl?pubid=9999'); - let data = getLoggerJsonFromRequest(request.requestBody); - expect(data.pubid).to.equal('9999'); - expect(data.pid).to.equal('1111'); - expect(data.tgid).to.equal(0);// test group id should be between 0-15 else set to 0 - expect(data.s).to.be.an('array'); - expect(data.s.length).to.equal(2); - // slot 1 - expect(data.s[0].sn).to.equal('/19968336/header-bid-tag-0'); - expect(data.s[0].sz).to.deep.equal(['640x480']); - expect(data.s[0].ps).to.be.an('array'); - expect(data.s[0].ps.length).to.equal(1); - expect(data.s[0].ps[0].pn).to.equal('pubmatic'); - expect(data.s[0].ps[0].bidid).to.equal('2ecff0db240757'); - expect(data.s[0].ps[0].kgpv).to.equal('/19968336/header-bid-tag-0'); - expect(data.s[0].ps[0].eg).to.equal(1); - expect(data.s[0].ps[0].en).to.equal(200); - expect(data.s[0].ps[0].wb).to.equal(0); // bidPriceUSD is not getting set as currency module is not added, so unable to set wb to 1 - expect(data.s[0].ps[0].af).to.equal('video'); - expect(data.s[0].ps[0].ocpm).to.equal(100); - expect(data.s[0].ps[0].ocry).to.equal('JPY'); - // tracker slot1 - let firstTracker = requests[0].url; - expect(firstTracker.split('?')[0]).to.equal('https://t.pubmatic.com/wt'); - data = {}; - firstTracker.split('?')[1].split('&').map(e => e.split('=')).forEach(e => data[e[0]] = e[1]); - expect(data.pubid).to.equal('9999'); - expect(data.tst).to.equal('1519767014'); - expect(data.iid).to.equal('25c6d7f5-699a-4bfc-87c9-996f915341fa'); - expect(data.eg).to.equal('1'); - expect(data.en).to.equal('200'); // bidPriceUSD is not getting set as currency module is not added - }); - - it('Logger: when bid is not submitted, default bid status 1 check: pubmatic set as s2s', function() { - config.setConfig({ - testGroupId: '25' - }); - - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON[0]); - - clock.tick(2000 + 1000); - expect(requests.length).to.equal(2); // 1 logger and 1 win-tracker - let request = requests[1]; // logger is executed late, trackers execute first - let data = getLoggerJsonFromRequest(request.requestBody); - expect(data.tgid).to.equal(0);// test group id should be an INT between 0-15 else set to 0 - expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); - expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); - expect(data.s[1].ps).to.be.an('array'); - expect(data.s[1].ps.length).to.equal(1); - expect(data.s[1].ps[0].pn).to.equal('pubmatic'); - expect(data.s[1].ps[0].bidid).to.equal('3bd4ebb1c900e2'); - expect(data.s[1].ps[0].db).to.equal(1); - expect(data.s[1].ps[0].kgpv).to.equal('this-is-a-kgpv'); - expect(data.s[1].ps[0].kgpsv).to.equal('this-is-a-kgpv'); - expect(data.s[1].ps[0].psz).to.equal('0x0'); - expect(data.s[1].ps[0].eg).to.equal(0); - expect(data.s[1].ps[0].en).to.equal(0); - expect(data.s[1].ps[0].di).to.equal(''); - expect(data.s[1].ps[0].dc).to.equal(''); - expect(data.s[1].ps[0].mi).to.equal(undefined); - expect(data.s[1].ps[0].l1).to.equal(0); - expect(data.s[1].ps[0].l2).to.equal(0); - expect(data.s[1].ps[0].ss).to.equal(1); - expect(data.s[1].ps[0].t).to.equal(0); - expect(data.s[1].ps[0].wb).to.equal(0); - expect(data.s[1].ps[0].af).to.equal(undefined); - expect(data.s[1].ps[0].ocpm).to.equal(0); - expect(data.s[1].ps[0].ocry).to.equal('USD'); - }); - - it('Logger: post-timeout check without bid response', function() { - // db = 1 and t = 1 means bidder did NOT respond with a bid but we got a timeout notification - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(BID_TIMEOUT, MOCK.BID_TIMEOUT); - events.emit(AUCTION_END, MOCK.AUCTION_END); - clock.tick(2000 + 1000); - - expect(requests.length).to.equal(1); // 1 logger and 0 win-tracker - let request = requests[0]; - let data = getLoggerJsonFromRequest(request.requestBody); - expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); - expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); - expect(data.s[1].ps).to.be.an('array'); - expect(data.s[1].ps.length).to.equal(1); - expect(data.s[1].ps[0].pn).to.equal('pubmatic'); - expect(data.s[1].ps[0].bidid).to.equal('3bd4ebb1c900e2'); - expect(data.s[1].ps[0].db).to.equal(1); - expect(data.s[1].ps[0].kgpv).to.equal('this-is-a-kgpv'); - expect(data.s[1].ps[0].kgpsv).to.equal('this-is-a-kgpv'); - expect(data.s[1].ps[0].psz).to.equal('0x0'); - expect(data.s[1].ps[0].eg).to.equal(0); - expect(data.s[1].ps[0].en).to.equal(0); - expect(data.s[1].ps[0].di).to.equal(''); - expect(data.s[1].ps[0].dc).to.equal(''); - expect(data.s[1].ps[0].mi).to.equal(undefined); - expect(data.s[1].ps[0].l1).to.equal(0); - expect(data.s[1].ps[0].l2).to.equal(0); - expect(data.s[1].ps[0].ss).to.equal(1); - expect(data.s[1].ps[0].t).to.equal(1); - expect(data.s[1].ps[0].wb).to.equal(0); - expect(data.s[1].ps[0].af).to.equal(undefined); - expect(data.s[1].ps[0].ocpm).to.equal(0); - expect(data.s[1].ps[0].ocry).to.equal('USD'); - }); - - it('Logger: post-timeout check with bid response', function() { - // db = 1 and t = 1 means bidder did NOT respond with a bid but we got a timeout notification - - sandbox.stub($$PREBID_GLOBAL$$, 'getHighestCpmBids').callsFake((key) => { - return [MOCK.BID_RESPONSE[1]] - }); - - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[1]); - events.emit(BID_TIMEOUT, MOCK.BID_TIMEOUT); - events.emit(AUCTION_END, MOCK.AUCTION_END); - clock.tick(2000 + 1000); - - expect(requests.length).to.equal(1); // 1 logger and 0 win-tracker - let request = requests[0]; - let data = getLoggerJsonFromRequest(request.requestBody); - expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); - expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); - expect(data.s[1].ps).to.be.an('array'); - expect(data.s[1].ps.length).to.equal(1); - expect(data.s[1].ps[0].pn).to.equal('pubmatic'); - expect(data.s[1].ps[0].bidid).to.equal('3bd4ebb1c900e2'); - expect(data.s[1].ps[0].db).to.equal(0); - expect(data.s[1].ps[0].kgpv).to.equal('this-is-a-kgpv'); - expect(data.s[1].ps[0].kgpsv).to.equal('this-is-a-kgpv'); - expect(data.s[1].ps[0].psz).to.equal('728x90'); - expect(data.s[1].ps[0].eg).to.equal(1.52); - expect(data.s[1].ps[0].en).to.equal(1.52); - expect(data.s[1].ps[0].di).to.equal('the-deal-id'); - expect(data.s[1].ps[0].dc).to.equal('PMP'); - expect(data.s[1].ps[0].mi).to.equal('matched-impression'); - expect(data.s[1].ps[0].l1).to.equal(3214); - expect(data.s[1].ps[0].l2).to.equal(0); - expect(data.s[1].ps[0].ss).to.equal(1); - expect(data.s[1].ps[0].t).to.equal(1); - expect(data.s[1].ps[0].wb).to.equal(1); // todo - expect(data.s[1].ps[0].af).to.equal('banner'); - expect(data.s[1].ps[0].ocpm).to.equal(1.52); - expect(data.s[1].ps[0].ocry).to.equal('USD'); - }); - - it('Logger: currency conversion check', function() { - setUANull(); - setConfig({ - adServerCurrency: 'JPY', - rates: { - USD: { - JPY: 100 - } - } - }); - const bidCopy = utils.deepClone(BID2); - bidCopy.currency = 'JPY'; - bidCopy.cpm = 100; - bidCopy.originalCpm = 100; - bidCopy.originalCurrency = 'JPY'; - - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); - events.emit(BID_RESPONSE, bidCopy); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON[0]); - events.emit(BID_WON, MOCK.BID_WON[1]); - - clock.tick(2000 + 1000); - expect(requests.length).to.equal(3); // 1 logger and 2 win-tracker - let request = requests[2]; // logger is executed late, trackers execute first - expect(request.url).to.equal('https://t.pubmatic.com/wl?pubid=9999'); - let data = getLoggerJsonFromRequest(request.requestBody); - expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); - expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); - expect(data.s[1].ps).to.be.an('array'); - expect(data.s[1].ps.length).to.equal(1); - expect(data.s[1].ps[0].pn).to.equal('pubmatic'); - expect(data.s[1].ps[0].bidid).to.equal('3bd4ebb1c900e2'); - expect(data.s[1].ps[0].db).to.equal(0); - expect(data.s[1].ps[0].kgpv).to.equal('this-is-a-kgpv'); - expect(data.s[1].ps[0].kgpsv).to.equal('this-is-a-kgpv'); - expect(data.s[1].ps[0].psz).to.equal('728x90'); - expect(data.s[1].ps[0].eg).to.equal(1); - expect(data.s[1].ps[0].en).to.equal(100); - expect(data.s[1].ps[0].di).to.equal('the-deal-id'); - expect(data.s[1].ps[0].dc).to.equal('PMP'); - expect(data.s[1].ps[0].mi).to.equal('matched-impression'); - expect(data.s[1].ps[0].l1).to.equal(3214); - expect(data.s[1].ps[0].l2).to.equal(0); - expect(data.s[1].ps[0].ss).to.equal(1); - expect(data.s[1].ps[0].t).to.equal(0); - expect(data.s[1].ps[0].wb).to.equal(0); // bidPriceUSD is not getting set as currency module is not added, so unable to set wb to 1 - expect(data.s[1].ps[0].af).to.equal('banner'); - expect(data.s[1].ps[0].ocpm).to.equal(100); - expect(data.s[1].ps[0].ocry).to.equal('JPY'); - expect(data.dvc).to.deep.equal({'plt': 3}); - }); - - it('Logger: regexPattern in bid.params', function() { - setUAMobile(); - const BID_REQUESTED_COPY = utils.deepClone(MOCK.BID_REQUESTED); - BID_REQUESTED_COPY.bids[1].params.regexPattern = '*'; - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, BID_REQUESTED_COPY); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); - events.emit(BID_RESPONSE, BID2); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON[0]); - events.emit(BID_WON, MOCK.BID_WON[1]); - - clock.tick(2000 + 1000); - expect(requests.length).to.equal(3); // 1 logger and 2 win-tracker - let request = requests[2]; // logger is executed late, trackers execute first - expect(request.url).to.equal('https://t.pubmatic.com/wl?pubid=9999'); - let data = getLoggerJsonFromRequest(request.requestBody); - expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); - expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); - expect(data.s[1].ps).to.be.an('array'); - expect(data.s[1].ps.length).to.equal(1); - expect(data.s[1].ps[0].pn).to.equal('pubmatic'); - expect(data.s[1].ps[0].bidid).to.equal('3bd4ebb1c900e2'); - expect(data.s[1].ps[0].db).to.equal(0); - expect(data.s[1].ps[0].kgpv).to.equal('*'); - expect(data.s[1].ps[0].kgpsv).to.equal('this-is-a-kgpv'); - expect(data.s[1].ps[0].psz).to.equal('728x90'); - expect(data.s[1].ps[0].eg).to.equal(1.52); - expect(data.s[1].ps[0].en).to.equal(1.52); - expect(data.s[1].ps[0].di).to.equal('the-deal-id'); - expect(data.s[1].ps[0].dc).to.equal('PMP'); - expect(data.s[1].ps[0].mi).to.equal('matched-impression'); - expect(data.s[1].ps[0].l1).to.equal(3214); - expect(data.s[1].ps[0].l2).to.equal(0); - expect(data.s[1].ps[0].ss).to.equal(1); - expect(data.s[1].ps[0].t).to.equal(0); - expect(data.s[1].ps[0].wb).to.equal(0); // bidPriceUSD is not getting set as currency module is not added, so unable to set wb to 1 - expect(data.s[1].ps[0].af).to.equal('banner'); - expect(data.s[1].ps[0].ocpm).to.equal(1.52); - expect(data.s[1].ps[0].ocry).to.equal('USD'); - expect(data.dvc).to.deep.equal({'plt': 2}); - // respective tracker slot - let firstTracker = requests[1].url; - expect(firstTracker.split('?')[0]).to.equal('https://t.pubmatic.com/wt'); - data = {}; - firstTracker.split('?')[1].split('&').map(e => e.split('=')).forEach(e => data[e[0]] = e[1]); - expect(data.kgpv).to.equal('*'); - }); - - it('Logger: regexPattern in bid.bidResponse', function() { - const BID2_COPY = utils.deepClone(BID2); - BID2_COPY.regexPattern = '*'; - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); - events.emit(BID_RESPONSE, BID2_COPY); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON[0]); - events.emit(BID_WON, Object.assign({}, BID2_COPY, { - 'status': 'rendered' - })); - - clock.tick(2000 + 1000); - expect(requests.length).to.equal(3); // 1 logger and 2 win-tracker - let request = requests[2]; // logger is executed late, trackers execute first - expect(request.url).to.equal('https://t.pubmatic.com/wl?pubid=9999'); - let data = getLoggerJsonFromRequest(request.requestBody); - expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); - expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); - expect(data.s[1].ps).to.be.an('array'); - expect(data.s[1].ps.length).to.equal(1); - expect(data.s[1].ps[0].pn).to.equal('pubmatic'); - expect(data.s[1].ps[0].bidid).to.equal('3bd4ebb1c900e2'); - expect(data.s[1].ps[0].db).to.equal(0); - expect(data.s[1].ps[0].kgpv).to.equal('*'); - expect(data.s[1].ps[0].kgpsv).to.equal('this-is-a-kgpv'); - expect(data.s[1].ps[0].psz).to.equal('728x90'); - expect(data.s[1].ps[0].eg).to.equal(1.52); - expect(data.s[1].ps[0].en).to.equal(1.52); - expect(data.s[1].ps[0].di).to.equal('the-deal-id'); - expect(data.s[1].ps[0].dc).to.equal('PMP'); - expect(data.s[1].ps[0].mi).to.equal('matched-impression'); - expect(data.s[1].ps[0].l1).to.equal(3214); - expect(data.s[1].ps[0].l2).to.equal(0); - expect(data.s[1].ps[0].ss).to.equal(1); - expect(data.s[1].ps[0].t).to.equal(0); - expect(data.s[1].ps[0].wb).to.equal(0); // bidPriceUSD is not getting set as currency module is not added, so unable to set wb to 1 - expect(data.s[1].ps[0].af).to.equal('banner'); - expect(data.s[1].ps[0].ocpm).to.equal(1.52); - expect(data.s[1].ps[0].ocry).to.equal('USD'); - expect(data.dvc).to.deep.equal({'plt': 1}); - // respective tracker slot - let firstTracker = requests[1].url; - expect(firstTracker.split('?')[0]).to.equal('https://t.pubmatic.com/wt'); - data = {}; - firstTracker.split('?')[1].split('&').map(e => e.split('=')).forEach(e => data[e[0]] = e[1]); - expect(data.kgpv).to.equal('*'); - }); - - it('Logger: regexPattern in bid.params', function() { - const BID_REQUESTED_COPY = utils.deepClone(MOCK.BID_REQUESTED); - BID_REQUESTED_COPY.bids[1].params.regexPattern = '*'; - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, BID_REQUESTED_COPY); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); - events.emit(BID_RESPONSE, BID2); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON[0]); - events.emit(BID_WON, MOCK.BID_WON[1]); - - clock.tick(2000 + 1000); - expect(requests.length).to.equal(3); // 1 logger and 2 win-tracker - let request = requests[2]; // logger is executed late, trackers execute first - expect(request.url).to.equal('https://t.pubmatic.com/wl?pubid=9999'); - let data = getLoggerJsonFromRequest(request.requestBody); - expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); - expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); - expect(data.s[1].ps).to.be.an('array'); - expect(data.s[1].ps.length).to.equal(1); - expect(data.s[1].ps[0].pn).to.equal('pubmatic'); - expect(data.s[1].ps[0].bidid).to.equal('3bd4ebb1c900e2'); - expect(data.s[1].ps[0].db).to.equal(0); - expect(data.s[1].ps[0].kgpv).to.equal('*'); - expect(data.s[1].ps[0].kgpsv).to.equal('this-is-a-kgpv'); - expect(data.s[1].ps[0].psz).to.equal('728x90'); - expect(data.s[1].ps[0].eg).to.equal(1.52); - expect(data.s[1].ps[0].en).to.equal(1.52); - expect(data.s[1].ps[0].di).to.equal('the-deal-id'); - expect(data.s[1].ps[0].dc).to.equal('PMP'); - expect(data.s[1].ps[0].mi).to.equal('matched-impression'); - expect(data.s[1].ps[0].l1).to.equal(3214); - expect(data.s[1].ps[0].l2).to.equal(0); - expect(data.s[1].ps[0].ss).to.equal(1); - expect(data.s[1].ps[0].t).to.equal(0); - expect(data.s[1].ps[0].wb).to.equal(0); // bidPriceUSD is not getting set as currency module is not added, so unable to set wb to 1 - expect(data.s[1].ps[0].af).to.equal('banner'); - expect(data.s[1].ps[0].ocpm).to.equal(1.52); - expect(data.s[1].ps[0].ocry).to.equal('USD'); - // respective tracker slot - let firstTracker = requests[1].url; - expect(firstTracker.split('?')[0]).to.equal('https://t.pubmatic.com/wt'); - data = {}; - firstTracker.split('?')[1].split('&').map(e => e.split('=')).forEach(e => data[e[0]] = e[1]); - expect(data.kgpv).to.equal('*'); - }); - - it('Logger: regexPattern in bid.bidResponse', function() { - const BID2_COPY = utils.deepClone(BID2); - BID2_COPY.regexPattern = '*'; - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); - events.emit(BID_RESPONSE, BID2_COPY); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON[0]); - events.emit(BID_WON, Object.assign({}, BID2_COPY, { - 'status': 'rendered' - })); - - clock.tick(2000 + 1000); - expect(requests.length).to.equal(3); // 1 logger and 2 win-tracker - let request = requests[2]; // logger is executed late, trackers execute first - expect(request.url).to.equal('https://t.pubmatic.com/wl?pubid=9999'); - let data = getLoggerJsonFromRequest(request.requestBody); - expect(data.s[1].sn).to.equal('/19968336/header-bid-tag-1'); - expect(data.s[1].sz).to.deep.equal(['1000x300', '970x250', '728x90']); - expect(data.s[1].ps).to.be.an('array'); - expect(data.s[1].ps.length).to.equal(1); - expect(data.s[1].ps[0].pn).to.equal('pubmatic'); - expect(data.s[1].ps[0].bidid).to.equal('3bd4ebb1c900e2'); - expect(data.s[1].ps[0].db).to.equal(0); - expect(data.s[1].ps[0].kgpv).to.equal('*'); - expect(data.s[1].ps[0].kgpsv).to.equal('this-is-a-kgpv'); - expect(data.s[1].ps[0].psz).to.equal('728x90'); - expect(data.s[1].ps[0].eg).to.equal(1.52); - expect(data.s[1].ps[0].en).to.equal(1.52); - expect(data.s[1].ps[0].di).to.equal('the-deal-id'); - expect(data.s[1].ps[0].dc).to.equal('PMP'); - expect(data.s[1].ps[0].mi).to.equal('matched-impression'); - expect(data.s[1].ps[0].l1).to.equal(3214); - expect(data.s[1].ps[0].l2).to.equal(0); - expect(data.s[1].ps[0].ss).to.equal(1); - expect(data.s[1].ps[0].t).to.equal(0); - expect(data.s[1].ps[0].wb).to.equal(0); // bidPriceUSD is not getting set as currency module is not added, so unable to set wb to 1 - expect(data.s[1].ps[0].af).to.equal('banner'); - expect(data.s[1].ps[0].ocpm).to.equal(1.52); - expect(data.s[1].ps[0].ocry).to.equal('USD'); - // respective tracker slot - let firstTracker = requests[1].url; - expect(firstTracker.split('?')[0]).to.equal('https://t.pubmatic.com/wt'); - data = {}; - firstTracker.split('?')[1].split('&').map(e => e.split('=')).forEach(e => data[e[0]] = e[1]); - expect(data.kgpv).to.equal('*'); - }); - }); -}); diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js deleted file mode 100644 index e8948fdc2d3..00000000000 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ /dev/null @@ -1,3130 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/pubmaticBidAdapter.js'; -import * as utils from 'src/utils.js'; -import {config} from 'src/config.js'; -import { createEidsArray } from 'modules/userId/eids.js'; -const constants = require('src/constants.json'); - -describe('PubMatic adapter', function () { - let bidRequests; - let videoBidRequests; - let multipleMediaRequests; - let bidResponses; - let nativeBidRequests; - let nativeBidRequestsWithAllParams; - let nativeBidRequestsWithoutAsset; - let nativeBidRequestsWithRequiredParam; - let nativeBidResponse; - let validnativeBidImpression; - let validnativeBidImpressionWithRequiredParam; - let nativeBidImpressionWithoutRequiredParams; - let validnativeBidImpressionWithAllParams; - let bannerAndVideoBidRequests; - let bannerAndNativeBidRequests; - let videoAndNativeBidRequests; - let bannerVideoAndNativeBidRequests; - let bannerBidResponse; - let videoBidResponse; - let schainConfig; - let outstreamBidRequest; - let validOutstreamBidRequest; - let outstreamVideoBidResponse; - - beforeEach(function () { - schainConfig = { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'indirectseller.com', - 'sid': '00001', - 'hp': 1 - }, - - { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 2 - } - ] - }; - - bidRequests = [ - { - bidder: 'pubmatic', - mediaTypes: { - banner: { - sizes: [[728, 90], [160, 600]] - } - }, - params: { - publisherId: '5670', - adSlot: '/15671365/DMDemo@300x250:0', - kadfloor: '1.2', - pmzoneid: 'aabc, ddef', - kadpageurl: 'www.publisher.com', - yob: '1986', - gender: 'M', - lat: '12.3', - lon: '23.7', - wiid: '1234567890', - profId: '100', - verId: '200', - currency: 'AUD', - dctr: 'key1:val1,val2|key2:val1' - }, - placementCode: '/19968336/header-bid-tag-1', - sizes: [[300, 250], [300, 600]], - bidId: '23acc48ad47af5', - requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729', - schain: schainConfig - } - ]; - - videoBidRequests = - [ - { - code: 'video1', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'instream' - } - }, - bidder: 'pubmatic', - bidId: '22bddb28db77d', - params: { - publisherId: '5890', - adSlot: 'Div1@0x0', // ad_id or tagid - video: { - mimes: ['video/mp4', 'video/x-flv'], - skippable: true, - minduration: 5, - maxduration: 30, - startdelay: 5, - playbackmethod: [1, 3], - api: [1, 2], - protocols: [2, 3], - battr: [13, 14], - linearity: 1, - placement: 2, - minbitrate: 10, - maxbitrate: 10 - } - } - } - ]; - - multipleMediaRequests = [ - { - bidder: 'pubmatic', - params: { - publisherId: '301', - adSlot: '/15671365/DMDemo@300x250:0', - kadfloor: '1.2', - pmzoneid: 'aabc, ddef', - kadpageurl: 'www.publisher.com', - yob: '1986', - gender: 'M', - lat: '12.3', - lon: '23.7', - wiid: '1234567890', - profId: '100', - verId: '200' - } - }, - { - code: 'div-instream', - mediaTypes: { - video: { - context: 'instream', - playerSize: [300, 250] - }, - }, - bidder: 'pubmatic', - params: { - publisherId: '5890', - adSlot: 'Div1@640x480', // ad_id or tagid - video: { - mimes: ['video/mp4', 'video/x-flv'], - skippable: true, - minduration: 5, - maxduration: 30, - startdelay: 15, - playbackmethod: [1, 3], - api: [1, 2], - protocols: [2, 3], - w: 640, - h: 480, - battr: [13, 14], - linearity: 1, - placement: 2, - minbitrate: 100, - maxbitrate: 4096 - } - } - } - ]; - - nativeBidRequests = [{ - code: '/19968336/prebid_native_example_1', - sizes: [ - [300, 250] - ], - mediaTypes: { - native: { - title: { - required: true, - length: 80 - }, - image: { - required: true, - sizes: [300, 250] - }, - sponsoredBy: { - required: true - } - } - }, - nativeParams: { - title: { required: true, length: 80 }, - image: { required: true, sizes: [300, 250] }, - sponsoredBy: { required: true } - }, - bidder: 'pubmatic', - params: { - publisherId: '5670', - adSlot: '/43743431/NativeAutomationPrebid@1x1', - }, - bidId: '2a5571261281d4', - requestId: 'B68287E1-DC39-4B38-9790-FE4F179739D6', - bidderRequestId: '1c56ad30b9b8ca8', - }]; - - nativeBidRequestsWithAllParams = [{ - code: '/19968336/prebid_native_example_1', - sizes: [ - [300, 250] - ], - mediaTypes: { - native: { - title: {required: true, len: 80, ext: {'title1': 'title2'}}, - icon: {required: true, sizes: [50, 50], ext: {'icon1': 'icon2'}}, - image: {required: true, sizes: [728, 90], ext: {'image1': 'image2'}, 'mimes': ['image/png', 'image/gif']}, - sponsoredBy: {required: true, len: 10, ext: {'sponsor1': 'sponsor2'}}, - body: {required: true, len: 10, ext: {'body1': 'body2'}}, - rating: {required: true, len: 10, ext: {'rating1': 'rating2'}}, - likes: {required: true, len: 10, ext: {'likes1': 'likes2'}}, - downloads: {required: true, len: 10, ext: {'downloads1': 'downloads2'}}, - price: {required: true, len: 10, ext: {'price1': 'price2'}}, - saleprice: {required: true, len: 10, ext: {'saleprice1': 'saleprice2'}}, - phone: {required: true, len: 10, ext: {'phone1': 'phone2'}}, - address: {required: true, len: 10, ext: {'address1': 'address2'}}, - desc2: {required: true, len: 10, ext: {'desc21': 'desc22'}}, - displayurl: {required: true, len: 10, ext: {'displayurl1': 'displayurl2'}} - } - }, - nativeParams: { - title: {required: true, len: 80, ext: {'title1': 'title2'}}, - icon: {required: true, sizes: [50, 50], ext: {'icon1': 'icon2'}}, - image: {required: true, sizes: [728, 90], ext: {'image1': 'image2'}, 'mimes': ['image/png', 'image/gif']}, - sponsoredBy: {required: true, len: 10, ext: {'sponsor1': 'sponsor2'}}, - body: {required: true, len: 10, ext: {'body1': 'body2'}}, - rating: {required: true, len: 10, ext: {'rating1': 'rating2'}}, - likes: {required: true, len: 10, ext: {'likes1': 'likes2'}}, - downloads: {required: true, len: 10, ext: {'downloads1': 'downloads2'}}, - price: {required: true, len: 10, ext: {'price1': 'price2'}}, - saleprice: {required: true, len: 10, ext: {'saleprice1': 'saleprice2'}}, - phone: {required: true, len: 10, ext: {'phone1': 'phone2'}}, - address: {required: true, len: 10, ext: {'address1': 'address2'}}, - desc2: {required: true, len: 10, ext: {'desc21': 'desc22'}}, - displayurl: {required: true, len: 10, ext: {'displayurl1': 'displayurl2'}} - }, - bidder: 'pubmatic', - params: { - publisherId: '5670', - adSlot: '/43743431/NativeAutomationPrebid@1x1', - }, - bidId: '2a5571261281d4', - requestId: 'B68287E1-DC39-4B38-9790-FE4F179739D6', - bidderRequestId: '1c56ad30b9b8ca8', - }]; - - nativeBidRequestsWithoutAsset = [{ - code: '/19968336/prebid_native_example_1', - sizes: [ - [300, 250] - ], - mediaTypes: { - native: { - type: 'image' - } - }, - nativeParams: { - title: { required: true }, - image: { required: true }, - sponsoredBy: { required: true }, - clickUrl: { required: true } - }, - bidder: 'pubmatic', - params: { - publisherId: '5670', - adSlot: '/43743431/NativeAutomationPrebid@1x1', - } - }]; - - nativeBidRequestsWithRequiredParam = [{ - code: '/19968336/prebid_native_example_1', - sizes: [ - [300, 250] - ], - mediaTypes: { - native: { - title: { - required: false, - length: 80 - }, - image: { - required: false, - sizes: [300, 250] - }, - sponsoredBy: { - required: true - } - } - }, - nativeParams: { - title: { required: false, length: 80 }, - image: { required: false, sizes: [300, 250] }, - sponsoredBy: { required: true } - }, - bidder: 'pubmatic', - params: { - publisherId: '5670', - adSlot: '/43743431/NativeAutomationPrebid@1x1', - } - }]; - - bannerAndVideoBidRequests = [ - { - code: 'div-banner-video', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'instream' - }, - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - bidder: 'pubmatic', - params: { - publisherId: '301', - adSlot: '/15671365/DMDemo@300x250:0', - kadfloor: '1.2', - pmzoneid: 'aabc, ddef', - kadpageurl: 'www.publisher.com', - yob: '1986', - gender: 'M', - lat: '12.3', - lon: '23.7', - wiid: '1234567890', - profId: '100', - verId: '200', - currency: 'AUD', - dctr: 'key1:val1,val2|key2:val1', - video: { - mimes: ['video/mp4', 'video/x-flv'], - skippable: true, - minduration: 5, - maxduration: 30, - startdelay: 15, - playbackmethod: [1, 3], - api: [1, 2], - protocols: [2, 3], - w: 640, - h: 480, - battr: [13, 14], - linearity: 1, - placement: 2, - minbitrate: 100, - maxbitrate: 4096 - } - }, - placementCode: '/19968336/header-bid-tag-1', - sizes: [[728, 90]], - bidId: '23acc48ad47af5', - requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - } - ]; - - bannerAndNativeBidRequests = [ - { - code: 'div-banner-native', - mediaTypes: { - native: { - title: { - required: true, - length: 80 - }, - image: { - required: true, - sizes: [300, 250] - }, - sponsoredBy: { - required: true - } - }, - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - nativeParams: { - title: { required: true, length: 80 }, - image: { required: true, sizes: [300, 250] }, - sponsoredBy: { required: true } - }, - bidder: 'pubmatic', - params: { - publisherId: '301', - adSlot: '/15671365/DMDemo@300x250:0', - kadfloor: '1.2', - pmzoneid: 'aabc, ddef', - kadpageurl: 'www.publisher.com', - yob: '1986', - gender: 'M', - lat: '12.3', - lon: '23.7', - wiid: '1234567890', - profId: '100', - verId: '200', - currency: 'AUD', - dctr: 'key1:val1,val2|key2:val1' - }, - placementCode: '/19968336/header-bid-tag-1', - sizes: [[728, 90]], - bidId: '23acc48ad47af5', - requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - } - ]; - - videoAndNativeBidRequests = [ - { - code: 'div-video-native', - mediaTypes: { - native: { - title: { - required: true, - length: 80 - }, - image: { - required: true, - sizes: [300, 250] - }, - sponsoredBy: { - required: true - } - }, - video: { - playerSize: [640, 480], - context: 'instream' - } - }, - nativeParams: { - title: { required: true, length: 80 }, - image: { required: true, sizes: [300, 250] }, - sponsoredBy: { required: true } - }, - bidder: 'pubmatic', - params: { - publisherId: '301', - adSlot: '/15671365/DMDemo@300x250:0', - video: { - mimes: ['video/mp4', 'video/x-flv'], - skippable: true, - minduration: 5, - maxduration: 30, - startdelay: 15, - playbackmethod: [1, 3], - api: [1, 2], - protocols: [2, 3], - w: 640, - h: 480, - battr: [13, 14], - linearity: 1, - placement: 2, - minbitrate: 100, - maxbitrate: 4096 - } - }, - placementCode: '/19968336/header-bid-tag-1', - sizes: [[728, 90]], - bidId: '23acc48ad47af5', - requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - } - ]; - - bannerVideoAndNativeBidRequests = [ - { - code: 'div-video-native', - mediaTypes: { - native: { - title: { - required: true, - length: 80 - }, - image: { - required: true, - sizes: [300, 250] - }, - sponsoredBy: { - required: true - } - }, - video: { - playerSize: [640, 480], - context: 'instream' - }, - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - nativeParams: { - title: { required: true, length: 80 }, - image: { required: true, sizes: [300, 250] }, - sponsoredBy: { required: true } - }, - bidder: 'pubmatic', - params: { - publisherId: '301', - adSlot: '/15671365/DMDemo@300x250:0', - video: { - mimes: ['video/mp4', 'video/x-flv'], - skippable: true, - minduration: 5, - maxduration: 30, - startdelay: 15, - playbackmethod: [1, 3], - api: [1, 2], - protocols: [2, 3], - w: 640, - h: 480, - battr: [13, 14], - linearity: 1, - placement: 2, - minbitrate: 100, - maxbitrate: 4096 - } - }, - placementCode: '/19968336/header-bid-tag-1', - sizes: [[728, 90]], - bidId: '23acc48ad47af5', - requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - } - ]; - - bidResponses = { - 'body': { - 'id': '93D3BAD6-E2E2-49FB-9D89-920B1761C865', - 'seatbid': [{ - 'seat': 'seat-id', - 'ext': { - 'buyid': 'BUYER-ID-987' - }, - 'bid': [{ - 'id': '74858439-49D7-4169-BA5D-44A046315B2F', - 'impid': '22bddb28db77d', - 'price': 1.3, - 'adm': 'image3.pubmatic.com Layer based creative', - 'adomain': ['blackrock.com'], - 'h': 250, - 'w': 300, - 'ext': { - 'deal_channel': 6, - 'advid': 976, - 'dspid': 123 - } - }] - }, { - 'ext': { - 'buyid': 'BUYER-ID-789' - }, - 'bid': [{ - 'id': '74858439-49D7-4169-BA5D-44A046315BEF', - 'impid': '22bddb28db77e', - 'price': 1.7, - 'adm': 'image3.pubmatic.com Layer based creative', - 'adomain': ['hivehome.com'], - 'h': 250, - 'w': 300, - 'ext': { - 'deal_channel': 5, - 'advid': 832, - 'dspid': 422 - } - }] - }] - } - }; - - nativeBidResponse = { - 'body': { - 'id': '1544691825939', - 'seatbid': [{ - 'bid': [{ - 'id': 'B68287E1-DC39-4B38-9790-FE4F179739D6', - 'impid': '2a5571261281d4', - 'price': 0.01, - 'adm': "{\"native\":{\"assets\":[{\"id\":1,\"title\":{\"text\":\"Native Test Title\"}},{\"id\":2,\"img\":{\"h\":627,\"url\":\"http://stagingpub.net/native_ads/PM-Native-Ad-1200x627.png\",\"w\":1200}},{\"data\":{\"value\":\"Sponsored By PubMatic\"},\"id\":4}],\"imptrackers\":[\"http://imptracker.com/main/9bde02d0-6017-11e4-9df7-005056967c35\",\"http://172.16.4.213/AdServer/AdDisplayTrackerServlet?operId=1&pubId=5890&siteId=5892&adId=6016&adType=12&adServerId=243&kefact=0.010000&kaxefact=0.010000&kadNetFrequecy=0&kadwidth=0&kadheight=0&kadsizeid=7&kltstamp=1544692761&indirectAdId=0&adServerOptimizerId=2&ranreq=0.1&kpbmtpfact=1.000000&dcId=1&tldId=0&passback=0&svr=MADS1107&ekefact=GSQSXOLKDgBAvRnoiNj0LxtpAnNEO30u1ZI5sITloOsP7gzh&ekaxefact=GSQSXAXLDgD0fOZLCjgbnVJiyS3D65dqDkxfs2ArpC3iugXw&ekpbmtpfact=GSQSXCDLDgB5mcooOvXtCKmx7TnNDJDY2YuHFOL3o9ceoU4H&crID=campaign111&lpu=advertiserdomain.com&ucrid=273354366805642829&campaignId=16981&creativeId=0&pctr=0.000000&wDSPByrId=511&wDspId=6&wbId=0&wrId=0&wAdvID=1&isRTB=1&rtbId=C09BB577-B8C1-4C3E-A0FF-73F6F631C80A&imprId=B68287E1-DC39-4B38-9790-FE4F179739D6&oid=B68287E1-DC39-4B38-9790-FE4F179739D6&pageURL=http%3A%2F%2Ftest.com%2FTestPages%2Fnativead.html\"],\"jstracker\":\" ', - 'h': 250, - 'w': 300, - 'ext': { - 'deal_channel': 6 - } - }] - }] - } - }; - - videoBidResponse = { - 'body': { - 'id': '93D3BAD6-E2E2-49FB-9D89-920B1761C865', - 'seatbid': [{ - 'bid': [{ - 'id': '74858439-49D7-4169-BA5D-44A046315B2F', - 'impid': '22bddb28db77d', - 'price': 1.3, - 'adm': 'Acudeo CompatibleVAST 2.0 Instream Test 1VAST 2.0 Instream Test 1https://dsptracker.com/{PSPM}00:00:04https://www.pubmatic.com', - 'h': 250, - 'w': 300, - 'ext': { - 'deal_channel': 6 - } - }] - }] - } - }; - outstreamBidRequest = - [ - { - code: 'video1', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'outstream' - } - }, - bidder: 'pubmatic', - bidId: '47acc48ad47af5', - requestId: '0fb4905b-1234-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729', - params: { - publisherId: '5670', - outstreamAU: 'pubmatic-test', - adSlot: 'Div1@0x0', // ad_id or tagid - video: { - mimes: ['video/mp4', 'video/x-flv'], - skippable: true, - minduration: 5, - maxduration: 30 - } - } - } - ]; - - validOutstreamBidRequest = { - auctionId: '92489f71-1bf2-49a0-adf9-000cea934729', - auctionStart: 1585918458868, - bidderCode: 'pubmatic', - bidderRequestId: '47acc48ad47af5', - bids: [{ - adUnitCode: 'video1', - auctionId: '92489f71-1bf2-49a0-adf9-000cea934729', - bidId: '47acc48ad47af5', - bidRequestsCount: 1, - bidder: 'pubmatic', - bidderRequestId: '47acc48ad47af5', - mediaTypes: { - video: { - context: 'outstream' - } - }, - params: { - publisherId: '5670', - outstreamAU: 'pubmatic-test', - adSlot: 'Div1@0x0', // ad_id or tagid - video: { - mimes: ['video/mp4', 'video/x-flv'], - skippable: true, - minduration: 5, - maxduration: 30 - } - }, - sizes: [[768, 432], [640, 480], [630, 360]], - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - }], - start: 11585918458869, - timeout: 3000 - }; - - outstreamVideoBidResponse = { - 'body': { - 'id': '93D3BAD6-E2E2-49FB-9D89-920B1761C865', - 'seatbid': [{ - 'bid': [{ - 'id': '0fb4905b-1234-4152-86be-c6f6d259ba99', - 'impid': '47acc48ad47af5', - 'price': 1.3, - 'adm': 'Acudeo CompatibleVAST 2.0 Instream Test 1VAST 2.0 Instream Test 1https://dsptracker.com/{PSPM}00:00:04https://www.pubmatic.com', - 'h': 250, - 'w': 300, - 'ext': { - 'deal_channel': 6 - } - }] - }] - } - }; - }); - - describe('implementation', function () { - describe('Bid validations', function () { - it('valid bid case', function () { - let validBid = { - bidder: 'pubmatic', - params: { - publisherId: '301', - adSlot: '/15671365/DMDemo@300x250:0' - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(true); - }); - - it('invalid bid case: publisherId not passed', function () { - let validBid = { - bidder: 'pubmatic', - params: { - adSlot: '/15671365/DMDemo@300x250:0' - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(false); - }); - - it('invalid bid case: publisherId is not string', function () { - let validBid = { - bidder: 'pubmatic', - params: { - publisherId: 301, - adSlot: '/15671365/DMDemo@300x250:0' - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(false); - }); - - it('valid bid case: adSlot is not passed', function () { - let validBid = { - bidder: 'pubmatic', - params: { - publisherId: '301' - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(true); - }); - }); - - describe('Request formation', function () { - it('buildRequests function should not modify original bidRequests object', function () { - let originalBidRequests = utils.deepClone(bidRequests); - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - expect(bidRequests).to.deep.equal(originalBidRequests); - }); - - it('buildRequests function should not modify original nativebidRequests object', function () { - let originalBidRequests = utils.deepClone(nativeBidRequests); - let request = spec.buildRequests(nativeBidRequests, { - auctionId: 'new-auction-id' - }); - expect(nativeBidRequests).to.deep.equal(originalBidRequests); - }); - - it('Endpoint checking', function () { - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - expect(request.url).to.equal('https://hbopenbid.pubmatic.com/translator?source=prebid-client'); - expect(request.method).to.equal('POST'); - }); - - it('should return bidderRequest property', function() { - let request = spec.buildRequests(bidRequests, validOutstreamBidRequest); - expect(request.bidderRequest).to.equal(validOutstreamBidRequest); - }); - - it('bidderRequest should be undefined if bidderRequest is not present', function() { - let request = spec.buildRequests(bidRequests); - expect(request.bidderRequest).to.be.undefined; - }); - - it('test flag not sent when pubmaticTest=true is absent in page url', function() { - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.test).to.equal(undefined); - }); - - // disabled this test case as it refreshes the whole suite when in karma watch mode - // todo: needs a fix - xit('test flag set to 1 when pubmaticTest=true is present in page url', function() { - window.location.href += '#pubmaticTest=true'; - // now all the test cases below will have window.location.href with #pubmaticTest=true - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.test).to.equal(1); - }); - - it('Request params check', function () { - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.at).to.equal(1); // auction type - expect(data.cur[0]).to.equal('USD'); // currency - expect(data.site.domain).to.be.a('string'); // domain should be set - expect(data.site.page).to.equal(bidRequests[0].params.kadpageurl); // forced pageURL - expect(data.site.publisher.id).to.equal(bidRequests[0].params.publisherId); // publisher Id - expect(data.site.ext).to.exist.and.to.be.an('object'); // dctr parameter - expect(data.site.ext.key_val).to.exist.and.to.equal(bidRequests[0].params.dctr); - expect(data.user.yob).to.equal(parseInt(bidRequests[0].params.yob)); // YOB - expect(data.user.gender).to.equal(bidRequests[0].params.gender); // Gender - expect(data.device.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude - expect(data.device.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude - expect(data.user.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude - expect(data.user.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude - expect(data.ext.wrapper.wv).to.equal($$REPO_AND_VERSION$$); // Wrapper Version - expect(data.ext.wrapper.transactionId).to.equal(bidRequests[0].transactionId); // Prebid TransactionId - expect(data.source.tid).to.equal(bidRequests[0].transactionId); // Prebid TransactionId - expect(data.ext.wrapper.wiid).to.equal(bidRequests[0].params.wiid); // OpenWrap: Wrapper Impression ID - expect(data.ext.wrapper.profile).to.equal(parseInt(bidRequests[0].params.profId)); // OpenWrap: Wrapper Profile ID - expect(data.ext.wrapper.version).to.equal(parseInt(bidRequests[0].params.verId)); // OpenWrap: Wrapper Profile Version ID - - expect(data.imp[0].id).to.equal(bidRequests[0].bidId); // Prebid bid id is passed as id - expect(data.imp[0].bidfloor).to.equal(parseFloat(bidRequests[0].params.kadfloor)); // kadfloor - expect(data.imp[0].tagid).to.equal('/15671365/DMDemo'); // tagid - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(250); // height - expect(data.imp[0].ext.pmZoneId).to.equal(bidRequests[0].params.pmzoneid.split(',').slice(0, 50).map(id => id.trim()).join()); // pmzoneid - expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency); - expect(data.source.ext.schain).to.deep.equal(bidRequests[0].schain); - }); - - it('Set content from config, set site.content', function() { - let sandbox = sinon.sandbox.create(); - const content = { - 'id': 'alpha-numeric-id' - }; - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - content: content - }; - return config[key]; - }); - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.site.content).to.deep.equal(content); - sandbox.restore(); - }); - - it('Merge the device info from config', function() { - let sandbox = sinon.sandbox.create(); - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - device: { - 'newkey': 'new-device-data' - } - }; - return config[key]; - }); - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.device.js).to.equal(1); - expect(data.device.dnt).to.equal((navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0); - expect(data.device.h).to.equal(screen.height); - expect(data.device.w).to.equal(screen.width); - expect(data.device.language).to.equal(navigator.language); - expect(data.device.newkey).to.equal('new-device-data');// additional data from config - sandbox.restore(); - }); - - it('Merge the device info from config; data from config overrides the info we have gathered', function() { - let sandbox = sinon.sandbox.create(); - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - device: { - newkey: 'new-device-data', - language: 'MARATHI' - } - }; - return config[key]; - }); - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.device.js).to.equal(1); - expect(data.device.dnt).to.equal((navigator.doNotTrack == 'yes' || navigator.doNotTrack == '1' || navigator.msDoNotTrack == '1') ? 1 : 0); - expect(data.device.h).to.equal(screen.height); - expect(data.device.w).to.equal(screen.width); - expect(data.device.language).to.equal('MARATHI');// // data overriding from config - expect(data.device.newkey).to.equal('new-device-data');// additional data from config - sandbox.restore(); - }); - - it('Set app from config, copy publisher and ext from site, unset site', function() { - let sandbox = sinon.sandbox.create(); - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - app: { - bundle: 'org.prebid.mobile.demoapp', - domain: 'prebid.org' - } - }; - return config[key]; - }); - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.app.bundle).to.equal('org.prebid.mobile.demoapp'); - expect(data.app.domain).to.equal('prebid.org'); - expect(data.app.publisher.id).to.equal(bidRequests[0].params.publisherId); - expect(data.app.ext.key_val).to.exist.and.to.equal(bidRequests[0].params.dctr); - expect(data.site).to.not.exist; - sandbox.restore(); - }); - - it('Set app, content from config, copy publisher and ext from site, unset site, config.content in app.content', function() { - let sandbox = sinon.sandbox.create(); - const content = { - 'id': 'alpha-numeric-id' - }; - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - content: content, - app: { - bundle: 'org.prebid.mobile.demoapp', - domain: 'prebid.org' - } - }; - return config[key]; - }); - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.app.bundle).to.equal('org.prebid.mobile.demoapp'); - expect(data.app.domain).to.equal('prebid.org'); - expect(data.app.publisher.id).to.equal(bidRequests[0].params.publisherId); - expect(data.app.ext.key_val).to.exist.and.to.equal(bidRequests[0].params.dctr); - expect(data.app.content).to.deep.equal(content); - expect(data.site).to.not.exist; - sandbox.restore(); - }); - - it('Set app.content, content from config, copy publisher and ext from site, unset site, config.app.content in app.content', function() { - let sandbox = sinon.sandbox.create(); - const content = { - 'id': 'alpha-numeric-id' - }; - const appContent = { - id: 'app-content-id-2' - }; - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - content: content, - app: { - bundle: 'org.prebid.mobile.demoapp', - domain: 'prebid.org', - content: appContent - } - }; - return config[key]; - }); - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.app.bundle).to.equal('org.prebid.mobile.demoapp'); - expect(data.app.domain).to.equal('prebid.org'); - expect(data.app.publisher.id).to.equal(bidRequests[0].params.publisherId); - expect(data.app.ext.key_val).to.exist.and.to.equal(bidRequests[0].params.dctr); - expect(data.app.content).to.deep.equal(appContent); - expect(data.site).to.not.exist; - sandbox.restore(); - }); - - it('Request params check: without adSlot', function () { - delete bidRequests[0].params.adSlot; - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.at).to.equal(1); // auction type - expect(data.cur[0]).to.equal('USD'); // currency - expect(data.site.domain).to.be.a('string'); // domain should be set - expect(data.site.page).to.equal(bidRequests[0].params.kadpageurl); // forced pageURL - expect(data.site.publisher.id).to.equal(bidRequests[0].params.publisherId); // publisher Id - expect(data.site.ext).to.exist.and.to.be.an('object'); // dctr parameter - expect(data.site.ext.key_val).to.exist.and.to.equal(bidRequests[0].params.dctr); - expect(data.user.yob).to.equal(parseInt(bidRequests[0].params.yob)); // YOB - expect(data.user.gender).to.equal(bidRequests[0].params.gender); // Gender - expect(data.device.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude - expect(data.device.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude - expect(data.user.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude - expect(data.user.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude - expect(data.ext.wrapper.wv).to.equal($$REPO_AND_VERSION$$); // Wrapper Version - expect(data.ext.wrapper.transactionId).to.equal(bidRequests[0].transactionId); // Prebid TransactionId - expect(data.ext.wrapper.wiid).to.equal(bidRequests[0].params.wiid); // OpenWrap: Wrapper Impression ID - expect(data.ext.wrapper.profile).to.equal(parseInt(bidRequests[0].params.profId)); // OpenWrap: Wrapper Profile ID - expect(data.ext.wrapper.version).to.equal(parseInt(bidRequests[0].params.verId)); // OpenWrap: Wrapper Profile Version ID - - expect(data.imp[0].id).to.equal(bidRequests[0].bidId); // Prebid bid id is passed as id - expect(data.imp[0].bidfloor).to.equal(parseFloat(bidRequests[0].params.kadfloor)); // kadfloor - expect(data.imp[0].tagid).to.deep.equal(undefined); // tagid - expect(data.imp[0].banner.w).to.equal(728); // width - expect(data.imp[0].banner.h).to.equal(90); // height - expect(data.imp[0].banner.format).to.deep.equal([{w: 160, h: 600}]); - expect(data.imp[0].ext.pmZoneId).to.equal(bidRequests[0].params.pmzoneid.split(',').slice(0, 50).map(id => id.trim()).join()); // pmzoneid - expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency); - }); - - it('Request params multi size format object check', function () { - let bidRequests = [ - { - bidder: 'pubmatic', - params: { - publisherId: '301', - adSlot: '/15671365/DMDemo@300x250:0', - kadfloor: '1.2', - pmzoneid: 'aabc, ddef', - kadpageurl: 'www.publisher.com', - yob: '1986', - gender: 'M', - lat: '12.3', - lon: '23.7', - wiid: '1234567890', - profId: '100', - verId: '200', - currency: 'AUD' - }, - placementCode: '/19968336/header-bid-tag-1', - bidId: '23acc48ad47af5', - requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - } - ]; - /* case 1 - size passed in adslot */ - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(250); // height - - /* case 2 - size passed in adslot as well as in sizes array */ - bidRequests[0].sizes = [[300, 600], [300, 250]]; - bidRequests[0].mediaTypes = { - banner: { - sizes: [[300, 600], [300, 250]] - } - }; - request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - data = JSON.parse(request.data); - - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(250); // height - - /* case 3 - size passed in sizes but not in adslot */ - bidRequests[0].params.adSlot = '/15671365/DMDemo'; - bidRequests[0].sizes = [[300, 250], [300, 600]]; - bidRequests[0].mediaTypes = { - banner: { - sizes: [[300, 250], [300, 600]] - } - }; - request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - data = JSON.parse(request.data); - - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(250); // height - expect(data.imp[0].banner.format).exist.and.to.be.an('array'); - expect(data.imp[0].banner.format[0]).exist.and.to.be.an('object'); - expect(data.imp[0].banner.format[0].w).to.equal(300); // width - expect(data.imp[0].banner.format[0].h).to.equal(600); // height - }); - - it('Request params currency check', function () { - let multipleBidRequests = [ - { - bidder: 'pubmatic', - params: { - publisherId: '301', - adSlot: '/15671365/DMDemo@300x250:0', - kadfloor: '1.2', - pmzoneid: 'aabc, ddef', - kadpageurl: 'www.publisher.com', - yob: '1986', - gender: 'M', - lat: '12.3', - lon: '23.7', - wiid: '1234567890', - profId: '100', - verId: '200', - currency: 'AUD' - }, - placementCode: '/19968336/header-bid-tag-1', - sizes: [[300, 250], [300, 600]], - bidId: '23acc48ad47af5', - requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - }, - { - bidder: 'pubmatic', - params: { - publisherId: '301', - adSlot: '/15671365/DMDemo@300x250:0', - kadfloor: '1.2', - pmzoneid: 'aabc, ddef', - kadpageurl: 'www.publisher.com', - yob: '1986', - gender: 'M', - lat: '12.3', - lon: '23.7', - wiid: '1234567890', - profId: '100', - verId: '200', - currency: 'GBP' - }, - placementCode: '/19968336/header-bid-tag-1', - sizes: [[300, 250], [300, 600]], - bidId: '23acc48ad47af5', - requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - } - ]; - - /* case 1 - - currency specified in both adunits - output: imp[0] and imp[1] both use currency specified in bidRequests[0].params.currency - - */ - let request = spec.buildRequests(multipleBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - - expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency); - expect(data.imp[1].bidfloorcur).to.equal(bidRequests[0].params.currency); - - /* case 2 - - currency specified in only 1st adunit - output: imp[0] and imp[1] both use currency specified in bidRequests[0].params.currency - - */ - delete multipleBidRequests[1].params.currency; - request = spec.buildRequests(multipleBidRequests, { - auctionId: 'new-auction-id' - }); - data = JSON.parse(request.data); - expect(data.imp[0].bidfloorcur).to.equal(bidRequests[0].params.currency); - expect(data.imp[1].bidfloorcur).to.equal(bidRequests[0].params.currency); - - /* case 3 - - currency specified in only 1st adunit - output: imp[0] and imp[1] both use default currency - USD - - */ - delete multipleBidRequests[0].params.currency; - request = spec.buildRequests(multipleBidRequests, { - auctionId: 'new-auction-id' - }); - data = JSON.parse(request.data); - expect(data.imp[0].bidfloorcur).to.equal('USD'); - expect(data.imp[1].bidfloorcur).to.equal('USD'); - - /* case 4 - - currency not specified in 1st adunit but specified in 2nd adunit - output: imp[0] and imp[1] both use default currency - USD - - */ - multipleBidRequests[1].params.currency = 'AUD'; - request = spec.buildRequests(multipleBidRequests, { - auctionId: 'new-auction-id' - }); - data = JSON.parse(request.data); - expect(data.imp[0].bidfloorcur).to.equal('USD'); - expect(data.imp[1].bidfloorcur).to.equal('USD'); - }); - - it('Pass auctiondId as wiid if wiid is not passed in params', function () { - let bidRequest = { - auctionId: 'new-auction-id' - }; - delete bidRequests[0].params.wiid; - let request = spec.buildRequests(bidRequests, bidRequest); - let data = JSON.parse(request.data); - expect(data.at).to.equal(1); // auction type - expect(data.cur[0]).to.equal('USD'); // currency - expect(data.site.domain).to.be.a('string'); // domain should be set - expect(data.site.page).to.equal(bidRequests[0].params.kadpageurl); // forced pageURL - expect(data.site.publisher.id).to.equal(bidRequests[0].params.publisherId); // publisher Id - expect(data.user.yob).to.equal(parseInt(bidRequests[0].params.yob)); // YOB - expect(data.user.gender).to.equal(bidRequests[0].params.gender); // Gender - expect(data.device.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude - expect(data.device.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude - expect(data.user.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude - expect(data.user.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude - expect(data.ext.wrapper.wv).to.equal($$REPO_AND_VERSION$$); // Wrapper Version - expect(data.ext.wrapper.transactionId).to.equal(bidRequests[0].transactionId); // Prebid TransactionId - expect(data.ext.wrapper.wiid).to.equal('new-auction-id'); // OpenWrap: Wrapper Impression ID - expect(data.ext.wrapper.profile).to.equal(parseInt(bidRequests[0].params.profId)); // OpenWrap: Wrapper Profile ID - expect(data.ext.wrapper.version).to.equal(parseInt(bidRequests[0].params.verId)); // OpenWrap: Wrapper Profile Version ID - - expect(data.imp[0].id).to.equal(bidRequests[0].bidId); // Prebid bid id is passed as id - expect(data.imp[0].bidfloor).to.equal(parseFloat(bidRequests[0].params.kadfloor)); // kadfloor - expect(data.imp[0].tagid).to.equal('/15671365/DMDemo'); // tagid - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(250); // height - expect(data.imp[0].ext.pmZoneId).to.equal(bidRequests[0].params.pmzoneid.split(',').slice(0, 50).map(id => id.trim()).join()); // pmzoneid - }); - - it('Request params check with GDPR Consent', function () { - let bidRequest = { - gdprConsent: { - consentString: 'kjfdniwjnifwenrif3', - gdprApplies: true - } - }; - let request = spec.buildRequests(bidRequests, bidRequest); - let data = JSON.parse(request.data); - expect(data.user.ext.consent).to.equal('kjfdniwjnifwenrif3'); - expect(data.regs.ext.gdpr).to.equal(1); - expect(data.at).to.equal(1); // auction type - expect(data.cur[0]).to.equal('USD'); // currency - expect(data.site.domain).to.be.a('string'); // domain should be set - expect(data.site.page).to.equal(bidRequests[0].params.kadpageurl); // forced pageURL - expect(data.site.publisher.id).to.equal(bidRequests[0].params.publisherId); // publisher Id - expect(data.user.yob).to.equal(parseInt(bidRequests[0].params.yob)); // YOB - expect(data.user.gender).to.equal(bidRequests[0].params.gender); // Gender - expect(data.device.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude - expect(data.device.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude - expect(data.user.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude - expect(data.user.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude - expect(data.ext.wrapper.wv).to.equal($$REPO_AND_VERSION$$); // Wrapper Version - expect(data.ext.wrapper.transactionId).to.equal(bidRequests[0].transactionId); // Prebid TransactionId - expect(data.ext.wrapper.wiid).to.equal(bidRequests[0].params.wiid); // OpenWrap: Wrapper Impression ID - expect(data.ext.wrapper.profile).to.equal(parseInt(bidRequests[0].params.profId)); // OpenWrap: Wrapper Profile ID - expect(data.ext.wrapper.version).to.equal(parseInt(bidRequests[0].params.verId)); // OpenWrap: Wrapper Profile Version ID - - expect(data.imp[0].id).to.equal(bidRequests[0].bidId); // Prebid bid id is passed as id - expect(data.imp[0].bidfloor).to.equal(parseFloat(bidRequests[0].params.kadfloor)); // kadfloor - expect(data.imp[0].tagid).to.equal('/15671365/DMDemo'); // tagid - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(250); // height - expect(data.imp[0].ext.pmZoneId).to.equal(bidRequests[0].params.pmzoneid.split(',').slice(0, 50).map(id => id.trim()).join()); // pmzoneid - }); - - it('Request params check with USP/CCPA Consent', function () { - let bidRequest = { - uspConsent: '1NYN' - }; - let request = spec.buildRequests(bidRequests, bidRequest); - let data = JSON.parse(request.data); - expect(data.regs.ext.us_privacy).to.equal('1NYN');// USP/CCPAs - expect(data.at).to.equal(1); // auction type - expect(data.cur[0]).to.equal('USD'); // currency - expect(data.site.domain).to.be.a('string'); // domain should be set - expect(data.site.page).to.equal(bidRequests[0].params.kadpageurl); // forced pageURL - expect(data.site.publisher.id).to.equal(bidRequests[0].params.publisherId); // publisher Id - expect(data.user.yob).to.equal(parseInt(bidRequests[0].params.yob)); // YOB - expect(data.user.gender).to.equal(bidRequests[0].params.gender); // Gender - expect(data.device.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude - expect(data.device.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude - expect(data.user.geo.lat).to.equal(parseFloat(bidRequests[0].params.lat)); // Latitude - expect(data.user.geo.lon).to.equal(parseFloat(bidRequests[0].params.lon)); // Lognitude - expect(data.ext.wrapper.wv).to.equal($$REPO_AND_VERSION$$); // Wrapper Version - expect(data.ext.wrapper.transactionId).to.equal(bidRequests[0].transactionId); // Prebid TransactionId - expect(data.ext.wrapper.wiid).to.equal(bidRequests[0].params.wiid); // OpenWrap: Wrapper Impression ID - expect(data.ext.wrapper.profile).to.equal(parseInt(bidRequests[0].params.profId)); // OpenWrap: Wrapper Profile ID - expect(data.ext.wrapper.version).to.equal(parseInt(bidRequests[0].params.verId)); // OpenWrap: Wrapper Profile Version ID - - expect(data.imp[0].id).to.equal(bidRequests[0].bidId); // Prebid bid id is passed as id - expect(data.imp[0].bidfloor).to.equal(parseFloat(bidRequests[0].params.kadfloor)); // kadfloor - expect(data.imp[0].tagid).to.equal('/15671365/DMDemo'); // tagid - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(250); // height - expect(data.imp[0].ext.pmZoneId).to.equal(bidRequests[0].params.pmzoneid.split(',').slice(0, 50).map(id => id.trim()).join()); // pmzoneid - - // second request without USP/CCPA - let request2 = spec.buildRequests(bidRequests, {}); - let data2 = JSON.parse(request2.data); - expect(data2.regs).to.equal(undefined);// USP/CCPAs - }); - - describe('FPD', function() { - let newRequest; - - it('ortb2.site should be merged in the request', function() { - let sandbox = sinon.sandbox.create(); - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - 'ortb2': { - site: { - domain: 'page.example.com', - cat: ['IAB2'], - sectioncat: ['IAB2-2'] - } - } - }; - return config[key]; - }); - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.site.domain).to.equal('page.example.com'); - expect(data.site.cat).to.deep.equal(['IAB2']); - expect(data.site.sectioncat).to.deep.equal(['IAB2-2']); - sandbox.restore(); - }); - - it('ortb2.user should be merged in the request', function() { - let sandbox = sinon.sandbox.create(); - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - 'ortb2': { - user: { - yob: 1985 - } - } - }; - return config[key]; - }); - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.yob).to.equal(1985); - sandbox.restore(); - }); - - describe('ortb2Imp', function() { - describe('ortb2Imp.ext.data.pbadslot', function() { - beforeEach(function () { - if (bidRequests[0].hasOwnProperty('ortb2Imp')) { - delete bidRequests[0].ortb2Imp; - } - }); - - it('should not send if imp[].ext.data object is invalid', function() { - bidRequests[0].ortb2Imp = { - ext: {} - }; - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.imp[0].ext).to.not.have.property('data'); - }); - - it('should not send if imp[].ext.data.pbadslot is undefined', function() { - bidRequests[0].ortb2Imp = { - ext: { - data: { - } - } - }; - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - if (data.imp[0].ext.data) { - expect(data.imp[0].ext.data).to.not.have.property('pbadslot'); - } else { - expect(data.imp[0].ext).to.not.have.property('data'); - } - }); - - it('should not send if imp[].ext.data.pbadslot is empty string', function() { - bidRequests[0].ortb2Imp = { - ext: { - data: { - pbadslot: '' - } - } - }; - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - if (data.imp[0].ext.data) { - expect(data.imp[0].ext.data).to.not.have.property('pbadslot'); - } else { - expect(data.imp[0].ext).to.not.have.property('data'); - } - }); - - it('should send if imp[].ext.data.pbadslot is string', function() { - bidRequests[0].ortb2Imp = { - ext: { - data: { - pbadslot: 'abcd' - } - } - }; - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.imp[0].ext.data).to.have.property('pbadslot'); - expect(data.imp[0].ext.data.pbadslot).to.equal('abcd'); - }); - }); - - describe('ortb2Imp.ext.data.adserver', function() { - beforeEach(function () { - if (bidRequests[0].hasOwnProperty('ortb2Imp')) { - delete bidRequests[0].ortb2Imp; - } - }); - - it('should not send if imp[].ext.data object is invalid', function() { - bidRequests[0].ortb2Imp = { - ext: {} - }; - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.imp[0].ext).to.not.have.property('data'); - }); - - it('should not send if imp[].ext.data.adserver is undefined', function() { - bidRequests[0].ortb2Imp = { - ext: { - data: { - } - } - }; - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - if (data.imp[0].ext.data) { - expect(data.imp[0].ext.data).to.not.have.property('adserver'); - } else { - expect(data.imp[0].ext).to.not.have.property('data'); - } - }); - - it('should send', function() { - let adSlotValue = 'abc'; - bidRequests[0].ortb2Imp = { - ext: { - data: { - adserver: { - name: 'GAM', - adslot: adSlotValue - } - } - } - }; - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.imp[0].ext.data.adserver.name).to.equal('GAM'); - expect(data.imp[0].ext.data.adserver.adslot).to.equal(adSlotValue); - expect(data.imp[0].ext.dfp_ad_unit_code).to.equal(adSlotValue); - }); - }); - - describe('ortb2Imp.ext.data.other', function() { - beforeEach(function () { - if (bidRequests[0].hasOwnProperty('ortb2Imp')) { - delete bidRequests[0].ortb2Imp; - } - }); - - it('should not send if imp[].ext.data object is invalid', function() { - bidRequests[0].ortb2Imp = { - ext: {} - }; - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.imp[0].ext).to.not.have.property('data'); - }); - - it('should not send if imp[].ext.data.other is undefined', function() { - bidRequests[0].ortb2Imp = { - ext: { - data: { - } - } - }; - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - if (data.imp[0].ext.data) { - expect(data.imp[0].ext.data).to.not.have.property('other'); - } else { - expect(data.imp[0].ext).to.not.have.property('data'); - } - }); - - it('ortb2Imp.ext.data.other', function() { - bidRequests[0].ortb2Imp = { - ext: { - data: { - other: 1234 - } - } - }; - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.imp[0].ext.data.other).to.equal(1234); - }); - }); - }); - }); - - describe('setting imp.floor using floorModule', function() { - /* - Use the minimum value among floor from floorModule per mediaType - If params.adfloor is set then take max(kadfloor, min(floors from floorModule)) - set imp.bidfloor only if it is more than 0 - */ - - let newRequest; - let floorModuleTestData; - let getFloor = function(req) { - return floorModuleTestData[req.mediaType]; - }; - - beforeEach(() => { - floorModuleTestData = { - 'banner': { - 'currency': 'USD', - 'floor': 1.50 - }, - 'video': { - 'currency': 'USD', - 'floor': 2.50 - }, - 'native': { - 'currency': 'USD', - 'floor': 3.50 - } - }; - newRequest = utils.deepClone(bannerVideoAndNativeBidRequests); - newRequest[0].getFloor = getFloor; - }); - - it('bidfloor should be undefined if calculation is <= 0', function() { - floorModuleTestData.banner.floor = 0; // lowest of them all - newRequest[0].params.kadfloor = undefined; - let request = spec.buildRequests(newRequest, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - data = data.imp[0]; - expect(data.bidfloor).to.equal(undefined); - }); - - it('ignore floormodule o/p if floor is not number', function() { - floorModuleTestData.banner.floor = 'INR'; - newRequest[0].params.kadfloor = undefined; - let request = spec.buildRequests(newRequest, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - data = data.imp[0]; - expect(data.bidfloor).to.equal(2.5); // video will be lowest now - }); - - it('ignore floormodule o/p if currency is not matched', function() { - floorModuleTestData.banner.currency = 'INR'; - newRequest[0].params.kadfloor = undefined; - let request = spec.buildRequests(newRequest, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - data = data.imp[0]; - expect(data.bidfloor).to.equal(2.5); // video will be lowest now - }); - - it('kadfloor is not passed, use minimum from floorModule', function() { - newRequest[0].params.kadfloor = undefined; - let request = spec.buildRequests(newRequest, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - data = data.imp[0]; - expect(data.bidfloor).to.equal(1.5); - }); - - it('kadfloor is passed as 3, use kadfloor as it is highest', function() { - newRequest[0].params.kadfloor = '3.0';// yes, we want it as a string - let request = spec.buildRequests(newRequest, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - data = data.imp[0]; - expect(data.bidfloor).to.equal(3); - }); - - it('kadfloor is passed as 1, use min of fllorModule as it is highest', function() { - newRequest[0].params.kadfloor = '1.0';// yes, we want it as a string - let request = spec.buildRequests(newRequest, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - data = data.imp[0]; - expect(data.bidfloor).to.equal(1.5); - }); - }); - - it('should NOT include coppa flag in bid request if coppa config is not present', () => { - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - if (data.regs) { - // in case GDPR is set then data.regs will exist - expect(data.regs.coppa).to.equal(undefined); - } else { - expect(data.regs).to.equal(undefined); - } - }); - - it('should include coppa flag in bid request if coppa is set to true', () => { - let sandbox = sinon.sandbox.create(); - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - 'coppa': true - }; - return config[key]; - }); - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.regs.coppa).to.equal(1); - sandbox.restore(); - }); - - it('should NOT include coppa flag in bid request if coppa is set to false', () => { - let sandbox = sinon.sandbox.create(); - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - 'coppa': false - }; - return config[key]; - }); - const request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - if (data.regs) { - // in case GDPR is set then data.regs will exist - expect(data.regs.coppa).to.equal(undefined); - } else { - expect(data.regs).to.equal(undefined); - } - sandbox.restore(); - }); - - describe('AdsrvrOrgId from userId module', function() { - let sandbox; - beforeEach(() => { - sandbox = sinon.sandbox.create(); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('Request should have AdsrvrOrgId config params', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.tdid = 'TTD_ID_FROM_USER_ID_MODULE'; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'adserver.org', - 'uids': [{ - 'id': 'TTD_ID_FROM_USER_ID_MODULE', - 'atype': 1, - 'ext': { - 'rtiPartner': 'TDID' - } - }] - }]); - }); - - it('Request should have adsrvrOrgId from UserId Module if config and userId module both have TTD ID', function() { - sandbox.stub(config, 'getConfig').callsFake((key) => { - var config = { - adsrvrOrgId: { - 'TDID': 'TTD_ID_FROM_CONFIG', - 'TDID_LOOKUP': 'TRUE', - 'TDID_CREATED_AT': '2018-10-01T07:05:40' - } - }; - return config[key]; - }); - bidRequests[0].userId = {}; - bidRequests[0].userId.tdid = 'TTD_ID_FROM_USER_ID_MODULE'; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'adserver.org', - 'uids': [{ - 'id': 'TTD_ID_FROM_USER_ID_MODULE', - 'atype': 1, - 'ext': { - 'rtiPartner': 'TDID' - } - }] - }]); - }); - - it('Request should NOT have adsrvrOrgId params if userId is NOT object', function() { - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal(undefined); - }); - - it('Request should NOT have adsrvrOrgId params if userId.tdid is NOT string', function() { - bidRequests[0].userId = { - tdid: 1234 - }; - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal(undefined); - }); - }); - - describe('UserIds from request', function() { - describe('pubcommon Id', function() { - it('send the pubcommon id if it is present', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.pubcid = 'pub_common_user_id'; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'pubcid.org', - 'uids': [{ - 'id': 'pub_common_user_id', - 'atype': 1 - }] - }]); - }); - - it('do not pass if not string', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.pubcid = 1; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.pubcid = []; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.pubcid = null; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.pubcid = {}; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - }); - }); - - describe('ID5 Id', function() { - it('send the id5 id if it is present', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.id5id = { uid: 'id5-user-id' }; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'id5-sync.com', - 'uids': [{ - 'id': 'id5-user-id', - 'atype': 1 - }] - }]); - }); - - it('do not pass if not string', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.id5id = { uid: 1 }; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.id5id = { uid: [] }; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.id5id = { uid: null }; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.id5id = { uid: {} }; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - }); - }); - - describe('Criteo Id', function() { - it('send the criteo id if it is present', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.criteoId = 'criteo-user-id'; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'criteo.com', - 'uids': [{ - 'id': 'criteo-user-id', - 'atype': 1 - }] - }]); - }); - - it('do not pass if not string', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.criteoId = 1; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.criteoId = []; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.criteoId = null; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.criteoId = {}; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - }); - }); - - describe('IdentityLink Id', function() { - it('send the identity-link id if it is present', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.idl_env = 'identity-link-user-id'; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'liveramp.com', - 'uids': [{ - 'id': 'identity-link-user-id', - 'atype': 3 - }] - }]); - }); - - it('do not pass if not string', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.idl_env = 1; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.idl_env = []; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.idl_env = null; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.idl_env = {}; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - }); - }); - - describe('LiveIntent Id', function() { - it('send the LiveIntent id if it is present', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.lipb = { lipbid: 'live-intent-user-id' }; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'liveintent.com', - 'uids': [{ - 'id': 'live-intent-user-id', - 'atype': 3 - }] - }]); - }); - - it('do not pass if not string', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.lipb = { lipbid: 1 }; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.lipb.lipbid = []; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.lipb.lipbid = null; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.lipb.lipbid = {}; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - }); - }); - - describe('Parrable Id', function() { - it('send the Parrable id if it is present', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.parrableId = { eid: 'parrable-user-id' }; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'parrable.com', - 'uids': [{ - 'id': 'parrable-user-id', - 'atype': 1 - }] - }]); - }); - - it('do not pass if not object with eid key', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.parrableid = 1; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.parrableid = []; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.parrableid = null; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.parrableid = {}; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - }); - }); - - describe('Britepool Id', function() { - it('send the Britepool id if it is present', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.britepoolid = 'britepool-user-id'; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'britepool.com', - 'uids': [{ - 'id': 'britepool-user-id', - 'atype': 3 - }] - }]); - }); - - it('do not pass if not string', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.britepoolid = 1; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.britepoolid = []; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.britepoolid = null; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.britepoolid = {}; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - }); - }); - - describe('NetId', function() { - it('send the NetId if it is present', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.netId = 'netid-user-id'; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'netid.de', - 'uids': [{ - 'id': 'netid-user-id', - 'atype': 1 - }] - }]); - }); - - it('do not pass if not string', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.netId = 1; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.netId = []; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.netId = null; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - bidRequests[0].userId.netId = {}; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - request = spec.buildRequests(bidRequests, {}); - data = JSON.parse(request.data); - expect(data.user.eids).to.equal(undefined); - }); - }); - - describe('FlocId', function() { - it('send the FlocId if it is present', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.flocId = { - id: '1234', - version: 'chrome1.1' - } - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'chrome.com', - 'uids': [{ - 'id': '1234', - 'atype': 1, - 'ext': { - 'ver': 'chrome1.1' - } - }] - }]); - expect(data.user.data).to.deep.equal([{ - id: 'FLOC', - name: 'FLOC', - ext: { - ver: 'chrome1.1' - }, - segment: [{ - id: '1234', - name: 'chrome.com', - value: '1234' - }] - }]); - }); - - it('appnend the flocId if userIds are present', function() { - bidRequests[0].userId = {}; - bidRequests[0].userId.netId = 'netid-user-id'; - bidRequests[0].userIdAsEids = createEidsArray(bidRequests[0].userId); - bidRequests[0].userId.flocId = { - id: '1234', - version: 'chrome1.1' - } - let request = spec.buildRequests(bidRequests, {}); - let data = JSON.parse(request.data); - expect(data.user.eids).to.deep.equal([{ - 'source': 'netid.de', - 'uids': [{ - 'id': 'netid-user-id', - 'atype': 1 - }] - }, { - 'source': 'chrome.com', - 'uids': [{ - 'id': '1234', - 'atype': 1, - 'ext': { - 'ver': 'chrome1.1' - } - }] - }]); - }); - }); - }); - - it('Request params check for video ad', function () { - let request = spec.buildRequests(videoBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.imp[0].video).to.exist; - expect(data.imp[0].tagid).to.equal('Div1'); - expect(data.imp[0].video.ext['video_skippable']).to.equal(videoBidRequests[0].params.video.skippable ? 1 : 0); - expect(data.imp[0]['video']['mimes']).to.exist.and.to.be.an('array'); - expect(data.imp[0]['video']['mimes'][0]).to.equal(videoBidRequests[0].params.video['mimes'][0]); - expect(data.imp[0]['video']['mimes'][1]).to.equal(videoBidRequests[0].params.video['mimes'][1]); - expect(data.imp[0]['video']['minduration']).to.equal(videoBidRequests[0].params.video['minduration']); - expect(data.imp[0]['video']['maxduration']).to.equal(videoBidRequests[0].params.video['maxduration']); - expect(data.imp[0]['video']['startdelay']).to.equal(videoBidRequests[0].params.video['startdelay']); - - expect(data.imp[0]['video']['playbackmethod']).to.exist.and.to.be.an('array'); - expect(data.imp[0]['video']['playbackmethod'][0]).to.equal(videoBidRequests[0].params.video['playbackmethod'][0]); - expect(data.imp[0]['video']['playbackmethod'][1]).to.equal(videoBidRequests[0].params.video['playbackmethod'][1]); - - expect(data.imp[0]['video']['api']).to.exist.and.to.be.an('array'); - expect(data.imp[0]['video']['api'][0]).to.equal(videoBidRequests[0].params.video['api'][0]); - expect(data.imp[0]['video']['api'][1]).to.equal(videoBidRequests[0].params.video['api'][1]); - - expect(data.imp[0]['video']['protocols']).to.exist.and.to.be.an('array'); - expect(data.imp[0]['video']['protocols'][0]).to.equal(videoBidRequests[0].params.video['protocols'][0]); - expect(data.imp[0]['video']['protocols'][1]).to.equal(videoBidRequests[0].params.video['protocols'][1]); - - expect(data.imp[0]['video']['battr']).to.exist.and.to.be.an('array'); - expect(data.imp[0]['video']['battr'][0]).to.equal(videoBidRequests[0].params.video['battr'][0]); - expect(data.imp[0]['video']['battr'][1]).to.equal(videoBidRequests[0].params.video['battr'][1]); - - expect(data.imp[0]['video']['linearity']).to.equal(videoBidRequests[0].params.video['linearity']); - expect(data.imp[0]['video']['placement']).to.equal(videoBidRequests[0].params.video['placement']); - expect(data.imp[0]['video']['minbitrate']).to.equal(videoBidRequests[0].params.video['minbitrate']); - expect(data.imp[0]['video']['maxbitrate']).to.equal(videoBidRequests[0].params.video['maxbitrate']); - - expect(data.imp[0]['video']['w']).to.equal(videoBidRequests[0].mediaTypes.video.playerSize[0]); - expect(data.imp[0]['video']['h']).to.equal(videoBidRequests[0].mediaTypes.video.playerSize[1]); - }); - - it('Request params check for 1 banner and 1 video ad', function () { - let request = spec.buildRequests(multipleMediaRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - - expect(data.imp).to.be.an('array') - expect(data.imp).with.length.above(1); - - expect(data.at).to.equal(1); // auction type - expect(data.cur[0]).to.equal('USD'); // currency - expect(data.site.domain).to.be.a('string'); // domain should be set - expect(data.site.page).to.equal(multipleMediaRequests[0].params.kadpageurl); // forced pageURL - expect(data.site.publisher.id).to.equal(multipleMediaRequests[0].params.publisherId); // publisher Id - expect(data.user.yob).to.equal(parseInt(multipleMediaRequests[0].params.yob)); // YOB - expect(data.user.gender).to.equal(multipleMediaRequests[0].params.gender); // Gender - expect(data.device.geo.lat).to.equal(parseFloat(multipleMediaRequests[0].params.lat)); // Latitude - expect(data.device.geo.lon).to.equal(parseFloat(multipleMediaRequests[0].params.lon)); // Lognitude - expect(data.user.geo.lat).to.equal(parseFloat(multipleMediaRequests[0].params.lat)); // Latitude - expect(data.user.geo.lon).to.equal(parseFloat(multipleMediaRequests[0].params.lon)); // Lognitude - expect(data.ext.wrapper.wv).to.equal($$REPO_AND_VERSION$$); // Wrapper Version - expect(data.ext.wrapper.transactionId).to.equal(multipleMediaRequests[0].transactionId); // Prebid TransactionId - expect(data.ext.wrapper.wiid).to.equal(multipleMediaRequests[0].params.wiid); // OpenWrap: Wrapper Impression ID - expect(data.ext.wrapper.profile).to.equal(parseInt(multipleMediaRequests[0].params.profId)); // OpenWrap: Wrapper Profile ID - expect(data.ext.wrapper.version).to.equal(parseInt(multipleMediaRequests[0].params.verId)); // OpenWrap: Wrapper Profile Version ID - - // banner imp object check - expect(data.imp[0].id).to.equal(multipleMediaRequests[0].bidId); // Prebid bid id is passed as id - expect(data.imp[0].bidfloor).to.equal(parseFloat(multipleMediaRequests[0].params.kadfloor)); // kadfloor - expect(data.imp[0].tagid).to.equal('/15671365/DMDemo'); // tagid - expect(data.imp[0].banner.w).to.equal(300); // width - expect(data.imp[0].banner.h).to.equal(250); // height - expect(data.imp[0].ext.pmZoneId).to.equal(multipleMediaRequests[0].params.pmzoneid.split(',').slice(0, 50).map(id => id.trim()).join()); // pmzoneid - - // video imp object check - expect(data.imp[1].video).to.exist; - expect(data.imp[1].tagid).to.equal('Div1'); - expect(data.imp[1].video.ext['video_skippable']).to.equal(multipleMediaRequests[1].params.video.skippable ? 1 : 0); - expect(data.imp[1]['video']['mimes']).to.exist.and.to.be.an('array'); - expect(data.imp[1]['video']['mimes'][0]).to.equal(multipleMediaRequests[1].params.video['mimes'][0]); - expect(data.imp[1]['video']['mimes'][1]).to.equal(multipleMediaRequests[1].params.video['mimes'][1]); - expect(data.imp[1]['video']['minduration']).to.equal(multipleMediaRequests[1].params.video['minduration']); - expect(data.imp[1]['video']['maxduration']).to.equal(multipleMediaRequests[1].params.video['maxduration']); - expect(data.imp[1]['video']['startdelay']).to.equal(multipleMediaRequests[1].params.video['startdelay']); - - expect(data.imp[1]['video']['playbackmethod']).to.exist.and.to.be.an('array'); - expect(data.imp[1]['video']['playbackmethod'][0]).to.equal(multipleMediaRequests[1].params.video['playbackmethod'][0]); - expect(data.imp[1]['video']['playbackmethod'][1]).to.equal(multipleMediaRequests[1].params.video['playbackmethod'][1]); - - expect(data.imp[1]['video']['api']).to.exist.and.to.be.an('array'); - expect(data.imp[1]['video']['api'][0]).to.equal(multipleMediaRequests[1].params.video['api'][0]); - expect(data.imp[1]['video']['api'][1]).to.equal(multipleMediaRequests[1].params.video['api'][1]); - - expect(data.imp[1]['video']['protocols']).to.exist.and.to.be.an('array'); - expect(data.imp[1]['video']['protocols'][0]).to.equal(multipleMediaRequests[1].params.video['protocols'][0]); - expect(data.imp[1]['video']['protocols'][1]).to.equal(multipleMediaRequests[1].params.video['protocols'][1]); - - expect(data.imp[1]['video']['battr']).to.exist.and.to.be.an('array'); - expect(data.imp[1]['video']['battr'][0]).to.equal(multipleMediaRequests[1].params.video['battr'][0]); - expect(data.imp[1]['video']['battr'][1]).to.equal(multipleMediaRequests[1].params.video['battr'][1]); - - expect(data.imp[1]['video']['linearity']).to.equal(multipleMediaRequests[1].params.video['linearity']); - expect(data.imp[1]['video']['placement']).to.equal(multipleMediaRequests[1].params.video['placement']); - expect(data.imp[1]['video']['minbitrate']).to.equal(multipleMediaRequests[1].params.video['minbitrate']); - expect(data.imp[1]['video']['maxbitrate']).to.equal(multipleMediaRequests[1].params.video['maxbitrate']); - - expect(data.imp[1]['video']['w']).to.equal(multipleMediaRequests[1].mediaTypes.video.playerSize[0]); - expect(data.imp[1]['video']['h']).to.equal(multipleMediaRequests[1].mediaTypes.video.playerSize[1]); - }); - - it('Request params should have valid native bid request for all valid params', function () { - let request = spec.buildRequests(nativeBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.imp[0].native).to.exist; - expect(data.imp[0].native['request']).to.exist; - expect(data.imp[0].tagid).to.equal('/43743431/NativeAutomationPrebid'); - expect(data.imp[0]['native']['request']).to.exist.and.to.be.an('string'); - expect(data.imp[0]['native']['request']).to.exist.and.to.equal(validnativeBidImpression.native.request); - }); - - it('Request params should not have valid native bid request for non native request', function () { - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.imp[0].native).to.not.exist; - }); - - it('Request params should have valid native bid request with valid required param values for all valid params', function () { - let request = spec.buildRequests(nativeBidRequestsWithRequiredParam, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.imp[0].native).to.exist; - expect(data.imp[0].native['request']).to.exist; - expect(data.imp[0].tagid).to.equal('/43743431/NativeAutomationPrebid'); - expect(data.imp[0]['native']['request']).to.exist.and.to.be.an('string'); - expect(data.imp[0]['native']['request']).to.exist.and.to.equal(validnativeBidImpressionWithRequiredParam.native.request); - }); - - it('should not have valid native request if assets are not defined with minimum required params and only native is the slot', function () { - let request = spec.buildRequests(nativeBidRequestsWithoutAsset, { - auctionId: 'new-auction-id' - }); - expect(request).to.deep.equal(undefined); - }); - - it('Request params should have valid native bid request for all native params', function () { - let request = spec.buildRequests(nativeBidRequestsWithAllParams, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.imp[0].native).to.exist; - expect(data.imp[0].native['request']).to.exist; - expect(data.imp[0].tagid).to.equal('/43743431/NativeAutomationPrebid'); - expect(data.imp[0]['native']['request']).to.exist.and.to.be.an('string'); - expect(data.imp[0]['native']['request']).to.exist.and.to.equal(validnativeBidImpressionWithAllParams.native.request); - }); - - it('Request params - should handle banner and video format in single adunit', function() { - let request = spec.buildRequests(bannerAndVideoBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - data = data.imp[0]; - expect(data.banner).to.exist; - expect(data.banner.w).to.equal(300); - expect(data.banner.h).to.equal(250); - expect(data.banner.format).to.exist; - expect(data.banner.format.length).to.equal(bannerAndVideoBidRequests[0].mediaTypes.banner.sizes.length); - - // Case: when size is not present in adslo - bannerAndVideoBidRequests[0].params.adSlot = '/15671365/DMDemo'; - request = spec.buildRequests(bannerAndVideoBidRequests, { - auctionId: 'new-auction-id' - }); - data = JSON.parse(request.data); - data = data.imp[0]; - expect(data.banner).to.exist; - expect(data.banner.w).to.equal(bannerAndVideoBidRequests[0].mediaTypes.banner.sizes[0][0]); - expect(data.banner.h).to.equal(bannerAndVideoBidRequests[0].mediaTypes.banner.sizes[0][1]); - expect(data.banner.format).to.exist; - expect(data.banner.format.length).to.equal(bannerAndVideoBidRequests[0].mediaTypes.banner.sizes.length - 1); - - expect(data.video).to.exist; - expect(data.video.w).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[0]); - expect(data.video.h).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[1]); - }); - - it('Request params - banner and video req in single adslot - should ignore banner imp if banner size is set to fluid and send video imp object', function () { - /* Adslot configured for banner and video. - banner size is set to [['fluid'], [300, 250]] - adslot specifies a size as 300x250 - => banner imp object should have primary w and h set to 300 and 250. fluid is ignored - */ - bannerAndVideoBidRequests[0].mediaTypes.banner.sizes = [['fluid'], [160, 600]]; - - let request = spec.buildRequests(bannerAndVideoBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - data = data.imp[0]; - - expect(data.banner).to.exist; - expect(data.banner.w).to.equal(300); - expect(data.banner.h).to.equal(250); - expect(data.banner.format).to.exist; - expect(data.banner.format[0].w).to.equal(160); - expect(data.banner.format[0].h).to.equal(600); - - /* Adslot configured for banner and video. - banner size is set to [['fluid'], [300, 250]] - adslot does not specify any size - => banner imp object should have primary w and h set to 300 and 250. fluid is ignored - */ - bannerAndVideoBidRequests[0].mediaTypes.banner.sizes = [['fluid'], [160, 600]]; - bannerAndVideoBidRequests[0].params.adSlot = '/15671365/DMDemo'; - - request = spec.buildRequests(bannerAndVideoBidRequests, { - auctionId: 'new-auction-id' - }); - data = JSON.parse(request.data); - data = data.imp[0]; - - expect(data.banner).to.exist; - expect(data.banner.w).to.equal(160); - expect(data.banner.h).to.equal(600); - expect(data.banner.format).to.not.exist; - - /* Adslot configured for banner and video. - banner size is set to [[728 90], ['fluid'], [300, 250]] - adslot does not specify any size - => banner imp object should have primary w and h set to 728 and 90. - banner.format should have 300, 250 set in it - fluid is ignore - */ - - bannerAndVideoBidRequests[0].mediaTypes.banner.sizes = [[728, 90], ['fluid'], [300, 250]]; - request = spec.buildRequests(bannerAndVideoBidRequests, { - auctionId: 'new-auction-id' - }); - data = JSON.parse(request.data); - data = data.imp[0]; - - expect(data.banner).to.exist; - expect(data.banner.w).to.equal(728); - expect(data.banner.h).to.equal(90); - expect(data.banner.format).to.exist; - expect(data.banner.format[0].w).to.equal(300); - expect(data.banner.format[0].h).to.equal(250); - - /* Adslot configured for banner and video. - banner size is set to [['fluid']] - adslot does not specify any size - => banner object should not be sent in the request. only video should be sent. - */ - - bannerAndVideoBidRequests[0].mediaTypes.banner.sizes = [['fluid']]; - request = spec.buildRequests(bannerAndVideoBidRequests, { - auctionId: 'new-auction-id' - }); - data = JSON.parse(request.data); - data = data.imp[0]; - - expect(data.banner).to.not.exist; - expect(data.video).to.exist; - }); - - it('Request params - should not contain banner imp if mediaTypes.banner is not present and sizes is specified in bid.sizes', function() { - delete bannerAndVideoBidRequests[0].mediaTypes.banner; - bannerAndVideoBidRequests[0].params.sizes = [300, 250]; - - let request = spec.buildRequests(bannerAndVideoBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - data = data.imp[0]; - expect(data.banner).to.not.exist; - }); - - it('Request params - should handle banner and native format in single adunit', function() { - let request = spec.buildRequests(bannerAndNativeBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - data = data.imp[0]; - - expect(data.banner).to.exist; - expect(data.banner.w).to.equal(300); - expect(data.banner.h).to.equal(250); - expect(data.banner.format).to.exist; - expect(data.banner.format.length).to.equal(bannerAndNativeBidRequests[0].mediaTypes.banner.sizes.length); - - expect(data.native).to.exist; - expect(data.native.request).to.exist; - }); - - it('Request params - should handle video and native format in single adunit', function() { - let request = spec.buildRequests(videoAndNativeBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - data = data.imp[0]; - - expect(data.video).to.exist; - expect(data.video.w).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[0]); - expect(data.video.h).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[1]); - - expect(data.native).to.exist; - expect(data.native.request).to.exist; - }); - - it('Request params - should handle banner, video and native format in single adunit', function() { - let request = spec.buildRequests(bannerVideoAndNativeBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - data = data.imp[0]; - - expect(data.banner).to.exist; - expect(data.banner.w).to.equal(300); - expect(data.banner.h).to.equal(250); - expect(data.banner.format).to.exist; - expect(data.banner.format.length).to.equal(bannerAndNativeBidRequests[0].mediaTypes.banner.sizes.length); - - expect(data.video).to.exist; - expect(data.video.w).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[0]); - expect(data.video.h).to.equal(bannerAndVideoBidRequests[0].mediaTypes.video.playerSize[1]); - - expect(data.native).to.exist; - expect(data.native.request).to.exist; - }); - - it('Request params - should not add banner object if mediaTypes.banner is missing, but adunits.sizes is present', function() { - delete bannerAndNativeBidRequests[0].mediaTypes.banner; - bannerAndNativeBidRequests[0].sizes = [729, 90]; - - let request = spec.buildRequests(bannerAndNativeBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - data = data.imp[0]; - - expect(data.banner).to.not.exist; - - expect(data.native).to.exist; - expect(data.native.request).to.exist; - }); - - it('Request params - banner and native multiformat request - should not have native object incase of invalid config present', function() { - bannerAndNativeBidRequests[0].mediaTypes.native = { - title: { required: true }, - image: { required: true }, - sponsoredBy: { required: true }, - clickUrl: { required: true } - }; - bannerAndNativeBidRequests[0].nativeParams = { - title: { required: true }, - image: { required: true }, - sponsoredBy: { required: true }, - clickUrl: { required: true } - } - let request = spec.buildRequests(bannerAndNativeBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - data = data.imp[0]; - - expect(data.banner).to.exist; - expect(data.native).to.not.exist; - }); - - it('Request params - video and native multiformat request - should not have native object incase of invalid config present', function() { - videoAndNativeBidRequests[0].mediaTypes.native = { - title: { required: true }, - image: { required: true }, - sponsoredBy: { required: true }, - clickUrl: { required: true } - }; - videoAndNativeBidRequests[0].nativeParams = { - title: { required: true }, - image: { required: true }, - sponsoredBy: { required: true }, - clickUrl: { required: true } - } - let request = spec.buildRequests(videoAndNativeBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - data = data.imp[0]; - - expect(data.video).to.exist; - expect(data.native).to.not.exist; - }); - }); - - it('Request params dctr check', function () { - let multipleBidRequests = [ - { - bidder: 'pubmatic', - params: { - publisherId: '301', - adSlot: '/15671365/DMDemo@300x250:0', - kadfloor: '1.2', - pmzoneid: 'aabc, ddef', - kadpageurl: 'www.publisher.com', - yob: '1986', - gender: 'M', - lat: '12.3', - lon: '23.7', - wiid: '1234567890', - profId: '100', - verId: '200', - currency: 'AUD', - dctr: 'key1=val1|key2=val2,!val3' - }, - placementCode: '/19968336/header-bid-tag-1', - sizes: [[300, 250], [300, 600]], - bidId: '23acc48ad47af5', - requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - }, - { - bidder: 'pubmatic', - params: { - publisherId: '301', - adSlot: '/15671365/DMDemo@300x250:0', - kadfloor: '1.2', - pmzoneid: 'aabc, ddef', - kadpageurl: 'www.publisher.com', - yob: '1986', - gender: 'M', - lat: '12.3', - lon: '23.7', - wiid: '1234567890', - profId: '100', - verId: '200', - currency: 'GBP', - dctr: 'key1=val3|key2=val1,!val3|key3=val123' - }, - placementCode: '/19968336/header-bid-tag-1', - sizes: [[300, 250], [300, 600]], - bidId: '23acc48ad47af5', - requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - } - ]; - - let request = spec.buildRequests(multipleBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - - /* case 1 - - dctr is found in adunit[0] - */ - - expect(data.site.ext).to.exist.and.to.be.an('object'); // dctr parameter - expect(data.site.ext.key_val).to.exist.and.to.equal(multipleBidRequests[0].params.dctr); - - /* case 2 - - dctr not present in adunit[0] - */ - delete multipleBidRequests[0].params.dctr; - request = spec.buildRequests(multipleBidRequests, { - auctionId: 'new-auction-id' - }); - data = JSON.parse(request.data); - - expect(data.site.ext).to.not.exist; - - /* case 3 - - dctr is present in adunit[0], but is not a string value - */ - multipleBidRequests[0].params.dctr = 123; - request = spec.buildRequests(multipleBidRequests, { - auctionId: 'new-auction-id' - }); - data = JSON.parse(request.data); - - expect(data.site.ext).to.not.exist; - }); - - it('Request params deals check', function () { - let multipleBidRequests = [ - { - bidder: 'pubmatic', - params: { - publisherId: '301', - adSlot: '/15671365/DMDemo@300x250:0', - kadfloor: '1.2', - pmzoneid: 'aabc, ddef', - kadpageurl: 'www.publisher.com', - yob: '1986', - gender: 'M', - lat: '12.3', - lon: '23.7', - wiid: '1234567890', - profId: '100', - verId: '200', - currency: 'AUD', - deals: ['deal-id-1', 'deal-id-2', 'dea'] // "dea" will not be passed as more than 3 characters needed - }, - placementCode: '/19968336/header-bid-tag-1', - sizes: [[300, 250], [300, 600]], - bidId: '23acc48ad47af5', - requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - }, - { - bidder: 'pubmatic', - params: { - publisherId: '301', - adSlot: '/15671365/DMDemo@300x250:0', - kadfloor: '1.2', - pmzoneid: 'aabc, ddef', - kadpageurl: 'www.publisher.com', - yob: '1986', - gender: 'M', - lat: '12.3', - lon: '23.7', - wiid: '1234567890', - profId: '100', - verId: '200', - currency: 'GBP', - deals: ['deal-id-100', 'deal-id-200'] - }, - placementCode: '/19968336/header-bid-tag-1', - sizes: [[300, 250], [300, 600]], - bidId: '23acc48ad47af5', - requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - } - ]; - - let request = spec.buildRequests(multipleBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - // case 1 - deals are passed as expected, ['', ''] , in both adUnits - expect(data.imp[0].pmp).to.deep.equal({ - 'private_auction': 0, - 'deals': [ - { - 'id': 'deal-id-1' - }, - { - 'id': 'deal-id-2' - } - ] - }); - expect(data.imp[1].pmp).to.deep.equal({ - 'private_auction': 0, - 'deals': [ - { - 'id': 'deal-id-100' - }, - { - 'id': 'deal-id-200' - } - ] - }); - - // case 2 - deals not present in adunit[0] - delete multipleBidRequests[0].params.deals; - request = spec.buildRequests(multipleBidRequests, { - auctionId: 'new-auction-id' - }); - data = JSON.parse(request.data); - expect(data.imp[0].pmp).to.not.exist; - - // case 3 - deals is present in adunit[0], but is not an array - multipleBidRequests[0].params.deals = 123; - request = spec.buildRequests(multipleBidRequests, { - auctionId: 'new-auction-id' - }); - data = JSON.parse(request.data); - expect(data.imp[0].pmp).to.not.exist; - - // case 4 - deals is present in adunit[0] as an array but one of the value is not a string - multipleBidRequests[0].params.deals = [123, 'deal-id-1']; - request = spec.buildRequests(multipleBidRequests, { - auctionId: 'new-auction-id' - }); - data = JSON.parse(request.data); - expect(data.imp[0].pmp).to.deep.equal({ - 'private_auction': 0, - 'deals': [ - { - 'id': 'deal-id-1' - } - ] - }); - }); - - describe('Request param bcat checking', function() { - let multipleBidRequests = [ - { - bidder: 'pubmatic', - params: { - publisherId: '301', - adSlot: '/15671365/DMDemo@300x250:0', - kadfloor: '1.2', - pmzoneid: 'aabc, ddef', - kadpageurl: 'www.publisher.com', - yob: '1986', - gender: 'M', - lat: '12.3', - lon: '23.7', - wiid: '1234567890', - profId: '100', - verId: '200', - currency: 'AUD', - dctr: 'key1=val1|key2=val2,!val3' - }, - placementCode: '/19968336/header-bid-tag-1', - sizes: [[300, 250], [300, 600]], - bidId: '23acc48ad47af5', - requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - }, - { - bidder: 'pubmatic', - params: { - publisherId: '301', - adSlot: '/15671365/DMDemo@300x250:0', - kadfloor: '1.2', - pmzoneid: 'aabc, ddef', - kadpageurl: 'www.publisher.com', - yob: '1986', - gender: 'M', - lat: '12.3', - lon: '23.7', - wiid: '1234567890', - profId: '100', - verId: '200', - currency: 'GBP', - dctr: 'key1=val3|key2=val1,!val3|key3=val123' - }, - placementCode: '/19968336/header-bid-tag-1', - sizes: [[300, 250], [300, 600]], - bidId: '23acc48ad47af5', - requestId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - } - ]; - - it('bcat: pass only strings', function() { - multipleBidRequests[0].params.bcat = [1, 2, 3, 'IAB1', 'IAB2']; - let request = spec.buildRequests(multipleBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.bcat).to.exist.and.to.deep.equal(['IAB1', 'IAB2']); - }); - - it('bcat: pass strings with length greater than 3', function() { - multipleBidRequests[0].params.bcat = ['AB', 'CD', 'IAB1', 'IAB2']; - let request = spec.buildRequests(multipleBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.bcat).to.exist.and.to.deep.equal(['IAB1', 'IAB2']); - }); - - it('bcat: trim the strings', function() { - multipleBidRequests[0].params.bcat = [' IAB1 ', ' IAB2 ']; - let request = spec.buildRequests(multipleBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.bcat).to.exist.and.to.deep.equal(['IAB1', 'IAB2']); - }); - - it('bcat: pass only unique strings', function() { - // multi slot - multipleBidRequests[0].params.bcat = ['IAB1', 'IAB2', 'IAB1', 'IAB2', 'IAB1', 'IAB2']; - multipleBidRequests[1].params.bcat = ['IAB1', 'IAB2', 'IAB1', 'IAB2', 'IAB1', 'IAB3']; - let request = spec.buildRequests(multipleBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.bcat).to.exist.and.to.deep.equal(['IAB1', 'IAB2', 'IAB3']); - }); - - it('bcat: do not pass bcat if all entries are invalid', function() { - // multi slot - multipleBidRequests[0].params.bcat = ['', 'IAB', 'IAB']; - multipleBidRequests[1].params.bcat = [' ', 22, 99999, 'IA']; - let request = spec.buildRequests(multipleBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - expect(data.bcat).to.deep.equal(undefined); - }); - }); - - describe('Response checking', function () { - it('should check for valid response values', function () { - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - let response = spec.interpretResponse(bidResponses, request); - expect(response).to.be.an('array').with.length.above(0); - expect(response[0].requestId).to.equal(bidResponses.body.seatbid[0].bid[0].impid); - expect(response[0].cpm).to.equal((bidResponses.body.seatbid[0].bid[0].price).toFixed(2)); - expect(response[0].width).to.equal(bidResponses.body.seatbid[0].bid[0].w); - expect(response[0].height).to.equal(bidResponses.body.seatbid[0].bid[0].h); - if (bidResponses.body.seatbid[0].bid[0].crid) { - expect(response[0].creativeId).to.equal(bidResponses.body.seatbid[0].bid[0].crid); - } else { - expect(response[0].creativeId).to.equal(bidResponses.body.seatbid[0].bid[0].id); - } - expect(response[0].dealId).to.equal(bidResponses.body.seatbid[0].bid[0].dealid); - expect(response[0].currency).to.equal('USD'); - expect(response[0].netRevenue).to.equal(true); - expect(response[0].ttl).to.equal(300); - expect(response[0].meta.networkId).to.equal(123); - expect(response[0].adserverTargeting.hb_buyid_pubmatic).to.equal('BUYER-ID-987'); - expect(response[0].meta.buyerId).to.equal(976); - expect(response[0].meta.clickUrl).to.equal('blackrock.com'); - expect(response[0].meta.advertiserDomains[0]).to.equal('blackrock.com'); - expect(response[0].referrer).to.include(data.site.ref); - expect(response[0].ad).to.equal(bidResponses.body.seatbid[0].bid[0].adm); - expect(response[0].pm_seat).to.equal(bidResponses.body.seatbid[0].seat); - expect(response[0].pm_dspid).to.equal(bidResponses.body.seatbid[0].bid[0].ext.dspid); - expect(response[0].partnerImpId).to.equal(bidResponses.body.seatbid[0].bid[0].id); - - expect(response[1].requestId).to.equal(bidResponses.body.seatbid[1].bid[0].impid); - expect(response[1].cpm).to.equal((bidResponses.body.seatbid[1].bid[0].price).toFixed(2)); - expect(response[1].width).to.equal(bidResponses.body.seatbid[1].bid[0].w); - expect(response[1].height).to.equal(bidResponses.body.seatbid[1].bid[0].h); - if (bidResponses.body.seatbid[1].bid[0].crid) { - expect(response[1].creativeId).to.equal(bidResponses.body.seatbid[1].bid[0].crid); - } else { - expect(response[1].creativeId).to.equal(bidResponses.body.seatbid[1].bid[0].id); - } - expect(response[1].dealId).to.equal(bidResponses.body.seatbid[1].bid[0].dealid); - expect(response[1].currency).to.equal('USD'); - expect(response[1].netRevenue).to.equal(true); - expect(response[1].ttl).to.equal(300); - expect(response[1].meta.networkId).to.equal(422); - expect(response[1].adserverTargeting.hb_buyid_pubmatic).to.equal('BUYER-ID-789'); - expect(response[1].meta.buyerId).to.equal(832); - expect(response[1].meta.clickUrl).to.equal('hivehome.com'); - expect(response[1].meta.advertiserDomains[0]).to.equal('hivehome.com'); - expect(response[1].referrer).to.include(data.site.ref); - expect(response[1].ad).to.equal(bidResponses.body.seatbid[1].bid[0].adm); - expect(response[1].pm_seat).to.equal(bidResponses.body.seatbid[1].seat || null); - expect(response[1].pm_dspid).to.equal(bidResponses.body.seatbid[1].bid[0].ext.dspid); - expect(response[0].partnerImpId).to.equal(bidResponses.body.seatbid[0].bid[0].id); - }); - - it('should check for dealChannel value selection', function () { - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let response = spec.interpretResponse(bidResponses, request); - expect(response).to.be.an('array').with.length.above(0); - expect(response[0].dealChannel).to.equal('PMPG'); - expect(response[1].dealChannel).to.equal('PREF'); - }); - - it('should check for unexpected dealChannel value selection', function () { - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let updateBiResponse = bidResponses; - updateBiResponse.body.seatbid[0].bid[0].ext.deal_channel = 11; - - let response = spec.interpretResponse(updateBiResponse, request); - - expect(response).to.be.an('array').with.length.above(0); - expect(response[0].dealChannel).to.equal(null); - }); - - it('should have a valid native bid response', function() { - let request = spec.buildRequests(nativeBidRequests, { - auctionId: 'new-auction-id' - }); - let data = JSON.parse(request.data); - data.imp[0].id = '2a5571261281d4'; - request.data = JSON.stringify(data); - let response = spec.interpretResponse(nativeBidResponse, request); - expect(response).to.be.an('array').with.length.above(0); - expect(response[0].native).to.exist.and.to.be.an('object'); - expect(response[0].mediaType).to.exist.and.to.equal('native'); - expect(response[0].native.title).to.exist.and.to.be.an('string'); - expect(response[0].native.image).to.exist.and.to.be.an('object'); - expect(response[0].native.image.url).to.exist.and.to.be.an('string'); - expect(response[0].native.image.height).to.exist; - expect(response[0].native.image.width).to.exist; - expect(response[0].native.sponsoredBy).to.exist.and.to.be.an('string'); - expect(response[0].native.clickUrl).to.exist.and.to.be.an('string'); - }); - - it('should check for valid banner mediaType in case of multiformat request', function() { - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let response = spec.interpretResponse(bannerBidResponse, request); - - expect(response[0].mediaType).to.equal('banner'); - }); - - it('should check for valid video mediaType in case of multiformat request', function() { - let request = spec.buildRequests(videoBidRequests, { - auctionId: 'new-auction-id' - }); - let response = spec.interpretResponse(videoBidResponse, request); - expect(response[0].mediaType).to.equal('video'); - }); - - it('should check for valid native mediaType in case of multiformat request', function() { - let request = spec.buildRequests(nativeBidRequests, { - auctionId: 'new-auction-id' - }); - let response = spec.interpretResponse(nativeBidResponse, request); - - expect(response[0].mediaType).to.equal('native'); - }); - - it('should assign renderer if bid is video and request is for outstream', function() { - let request = spec.buildRequests(outstreamBidRequest, validOutstreamBidRequest); - let response = spec.interpretResponse(outstreamVideoBidResponse, request); - expect(response[0].renderer).to.exist; - }); - - it('should not assign renderer if bidderRequest is not present', function() { - let request = spec.buildRequests(outstreamBidRequest, { - auctionId: 'new-auction-id' - }); - let response = spec.interpretResponse(outstreamVideoBidResponse, request); - expect(response[0].renderer).to.not.exist; - }); - - it('should not assign renderer if bid is video and request is for instream', function() { - let request = spec.buildRequests(videoBidRequests, { - auctionId: 'new-auction-id' - }); - let response = spec.interpretResponse(videoBidResponse, request); - expect(response[0].renderer).to.not.exist; - }); - - it('should not assign renderer if bid is native', function() { - let request = spec.buildRequests(nativeBidRequests, { - auctionId: 'new-auction-id' - }); - let response = spec.interpretResponse(nativeBidResponse, request); - expect(response[0].renderer).to.not.exist; - }); - - it('should not assign renderer if bid is of banner', function() { - let request = spec.buildRequests(bidRequests, { - auctionId: 'new-auction-id' - }); - let response = spec.interpretResponse(bidResponses, request); - expect(response[0].renderer).to.not.exist; - }); - }); - - describe('getUserSyncs', function() { - const syncurl_iframe = 'https://ads.pubmatic.com/AdServer/js/showad.js#PIX&kdntuid=1&p=5670'; - const syncurl_image = 'https://image8.pubmatic.com/AdServer/ImgSync?p=5670'; - let sandbox; - beforeEach(function () { - sandbox = sinon.sandbox.create(); - }); - afterEach(function() { - sandbox.restore(); - }); - - it('execute as per config', function() { - expect(spec.getUserSyncs({ iframeEnabled: true }, {}, undefined, undefined)).to.deep.equal([{ - type: 'iframe', url: syncurl_iframe - }]); - expect(spec.getUserSyncs({ iframeEnabled: false }, {}, undefined, undefined)).to.deep.equal([{ - type: 'image', url: syncurl_image - }]); - }); - - it('CCPA/USP', function() { - expect(spec.getUserSyncs({ iframeEnabled: true }, {}, undefined, '1NYN')).to.deep.equal([{ - type: 'iframe', url: `${syncurl_iframe}&us_privacy=1NYN` - }]); - expect(spec.getUserSyncs({ iframeEnabled: false }, {}, undefined, '1NYN')).to.deep.equal([{ - type: 'image', url: `${syncurl_image}&us_privacy=1NYN` - }]); - }); - - it('GDPR', function() { - expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {gdprApplies: true, consentString: 'foo'}, undefined)).to.deep.equal([{ - type: 'iframe', url: `${syncurl_iframe}&gdpr=1&gdpr_consent=foo` - }]); - expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {gdprApplies: false, consentString: 'foo'}, undefined)).to.deep.equal([{ - type: 'iframe', url: `${syncurl_iframe}&gdpr=0&gdpr_consent=foo` - }]); - expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {gdprApplies: true, consentString: undefined}, undefined)).to.deep.equal([{ - type: 'iframe', url: `${syncurl_iframe}&gdpr=1&gdpr_consent=` - }]); - - expect(spec.getUserSyncs({ iframeEnabled: false }, {}, {gdprApplies: true, consentString: 'foo'}, undefined)).to.deep.equal([{ - type: 'image', url: `${syncurl_image}&gdpr=1&gdpr_consent=foo` - }]); - expect(spec.getUserSyncs({ iframeEnabled: false }, {}, {gdprApplies: false, consentString: 'foo'}, undefined)).to.deep.equal([{ - type: 'image', url: `${syncurl_image}&gdpr=0&gdpr_consent=foo` - }]); - expect(spec.getUserSyncs({ iframeEnabled: false }, {}, {gdprApplies: true, consentString: undefined}, undefined)).to.deep.equal([{ - type: 'image', url: `${syncurl_image}&gdpr=1&gdpr_consent=` - }]); - }); - - it('COPPA: true', function() { - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - 'coppa': true - }; - return config[key]; - }); - expect(spec.getUserSyncs({ iframeEnabled: true }, {}, undefined, undefined)).to.deep.equal([{ - type: 'iframe', url: `${syncurl_iframe}&coppa=1` - }]); - expect(spec.getUserSyncs({ iframeEnabled: false }, {}, undefined, undefined)).to.deep.equal([{ - type: 'image', url: `${syncurl_image}&coppa=1` - }]); - }); - - it('COPPA: false', function() { - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - 'coppa': false - }; - return config[key]; - }); - expect(spec.getUserSyncs({ iframeEnabled: true }, {}, undefined, undefined)).to.deep.equal([{ - type: 'iframe', url: `${syncurl_iframe}` - }]); - expect(spec.getUserSyncs({ iframeEnabled: false }, {}, undefined, undefined)).to.deep.equal([{ - type: 'image', url: `${syncurl_image}` - }]); - }); - - it('GDPR + COPPA:true + CCPA/USP', function() { - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - 'coppa': true - }; - return config[key]; - }); - expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {gdprApplies: true, consentString: 'foo'}, '1NYN')).to.deep.equal([{ - type: 'iframe', url: `${syncurl_iframe}&gdpr=1&gdpr_consent=foo&us_privacy=1NYN&coppa=1` - }]); - expect(spec.getUserSyncs({ iframeEnabled: false }, {}, {gdprApplies: true, consentString: 'foo'}, '1NYN')).to.deep.equal([{ - type: 'image', url: `${syncurl_image}&gdpr=1&gdpr_consent=foo&us_privacy=1NYN&coppa=1` - }]); - }); - }); - }); -}); diff --git a/test/spec/modules/pubperfAnalyticsAdapter_spec.js b/test/spec/modules/pubperfAnalyticsAdapter_spec.js deleted file mode 100644 index b316b44617a..00000000000 --- a/test/spec/modules/pubperfAnalyticsAdapter_spec.js +++ /dev/null @@ -1,55 +0,0 @@ -import pubperfAnalytics from 'modules/pubperfAnalyticsAdapter.js'; -import { expect } from 'chai'; -import { server } from 'test/mocks/xhr.js'; -let events = require('src/events'); -let utils = require('src/utils.js'); -let constants = require('src/constants.json'); - -describe('Pubperf Analytics Adapter', function() { - describe('Prebid Manager Analytic tests', function() { - beforeEach(function() { - sinon.stub(events, 'getEvents').returns([]); - sinon.stub(utils, 'logError'); - }); - - afterEach(function() { - events.getEvents.restore(); - utils.logError.restore(); - }); - - it('should throw error, when pubperf_pbjs is not defined', function() { - pubperfAnalytics.enableAnalytics({ - provider: 'pubperf' - }); - - events.emit(constants.EVENTS.AUCTION_INIT, {}); - events.emit(constants.EVENTS.BID_REQUESTED, {}); - events.emit(constants.EVENTS.BID_RESPONSE, {}); - events.emit(constants.EVENTS.BID_WON, {}); - events.emit(constants.EVENTS.AUCTION_END, {}); - events.emit(constants.EVENTS.BID_TIMEOUT, {}); - - expect(server.requests.length).to.equal(0); - expect(utils.logError.called).to.equal(true); - }); - - it('track event without errors', function() { - sinon.spy(pubperfAnalytics, 'track'); - - window['pubperf_pbjs'] = function() {}; - - pubperfAnalytics.enableAnalytics({ - provider: 'pubperf' - }); - - events.emit(constants.EVENTS.AUCTION_INIT, {}); - events.emit(constants.EVENTS.BID_REQUESTED, {}); - events.emit(constants.EVENTS.BID_RESPONSE, {}); - events.emit(constants.EVENTS.BID_WON, {}); - events.emit(constants.EVENTS.AUCTION_END, {}); - events.emit(constants.EVENTS.BID_TIMEOUT, {}); - - sinon.assert.callCount(pubperfAnalytics.track, 6); - }); - }); -}); diff --git a/test/spec/modules/pubstackAnalyticsAdapter_spec.js b/test/spec/modules/pubstackAnalyticsAdapter_spec.js deleted file mode 100644 index e3db334c888..00000000000 --- a/test/spec/modules/pubstackAnalyticsAdapter_spec.js +++ /dev/null @@ -1,38 +0,0 @@ -import * as utils from 'src/utils.js'; -import pubstackAnalytics from '../../../modules/pubstackAnalyticsAdapter.js'; -import adapterManager from 'src/adapterManager'; -import events from 'src/events'; -import constants from 'src/constants.json' - -describe('Pubstack Analytics Adapter', () => { - const scope = utils.getWindowSelf(); - let queue = []; - - beforeEach(() => { - scope.PubstackAnalytics = (...args) => queue.push(args); - adapterManager.enableAnalytics({ - provider: 'pubstack' - }); - queue = [] - }); - - afterEach(() => { - pubstackAnalytics.disableAnalytics(); - }); - - it('should forward all events to the queue', () => { - // Given - const args = 'any-args' - - // When - events.emit(constants.EVENTS.AUCTION_END, args) - events.emit(constants.EVENTS.BID_REQUESTED, args) - events.emit(constants.EVENTS.BID_ADJUSTMENT, args) - events.emit(constants.EVENTS.BID_RESPONSE, args) - events.emit(constants.EVENTS.BID_WON, args) - events.emit(constants.EVENTS.NO_BID, args) - - // Then - expect(queue.length).to.eql(6); - }); -}); diff --git a/test/spec/modules/pubwiseAnalyticsAdapter_spec.js b/test/spec/modules/pubwiseAnalyticsAdapter_spec.js deleted file mode 100644 index 3be4ea3d69c..00000000000 --- a/test/spec/modules/pubwiseAnalyticsAdapter_spec.js +++ /dev/null @@ -1,164 +0,0 @@ -import { expect } from 'chai'; -import pubwiseAnalytics from 'modules/pubwiseAnalyticsAdapter.js'; -import {server} from 'test/mocks/xhr.js'; -let events = require('src/events'); -let adapterManager = require('src/adapterManager').default; -let constants = require('src/constants.json'); - -describe('PubWise Prebid Analytics', function () { - let requests; - let sandbox; - let xhr; - let clock; - let mock = {}; - - mock.DEFAULT_PW_CONFIG = { - 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'} - } - }; - 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'}, - noBids: 'no bids today', - winningBids: 'winning bids', - extraProp: 'extraProp retained' - }; - - beforeEach(function() { - sandbox = sinon.sandbox.create(); - clock = sandbox.useFakeTimers(); - sandbox.stub(events, 'getEvents').returns([]); - - xhr = sandbox.useFakeXMLHttpRequest(); - requests = []; - xhr.onCreate = request => requests.push(request); - }); - - afterEach(function () { - sandbox.restore(); - clock.restore(); - pubwiseAnalytics.disableAnalytics(); - }); - - describe('enableAnalytics', function () { - beforeEach(function () { - requests = []; - }); - - it('should catch all events', function () { - pubwiseAnalytics.enableAnalytics(mock.DEFAULT_PW_CONFIG); - - sandbox.spy(pubwiseAnalytics, 'track'); - - // sent - events.emit(constants.EVENTS.AUCTION_INIT, mock.AUCTION_INIT); - events.emit(constants.EVENTS.BID_REQUESTED, {}); - events.emit(constants.EVENTS.BID_RESPONSE, {}); - events.emit(constants.EVENTS.BID_WON, {}); - events.emit(constants.EVENTS.AD_RENDER_FAILED, {}); - events.emit(constants.EVENTS.TCF2_ENFORCEMENT, {}); - events.emit(constants.EVENTS.BID_TIMEOUT, {}); - - // forces flush - events.emit(constants.EVENTS.AUCTION_END, {}); - - // eslint-disable-next-line - //console.log(requests); - - /* testing for 6 calls, including the 2 we're not currently tracking */ - sandbox.assert.callCount(pubwiseAnalytics.track, 7); - }); - - it('should initialize the auction properly', function () { - pubwiseAnalytics.enableAnalytics(mock.DEFAULT_PW_CONFIG); - - // sent - events.emit(constants.EVENTS.AUCTION_INIT, mock.AUCTION_INIT); - events.emit(constants.EVENTS.BID_REQUESTED, {}); - events.emit(constants.EVENTS.BID_RESPONSE, {}); - events.emit(constants.EVENTS.BID_WON, {}); - // force flush - clock.tick(500); - - /* check for critical values */ - let request = requests[0]; - let data = JSON.parse(request.requestBody); - // eslint-disable-next-line - // console.log(data.metaData); - expect(data.metaData, 'metaData property').to.exist; - expect(data.metaData.pbjs_version, 'pbjs version').to.equal('$prebid.version$') - expect(data.metaData.session_id, 'session id').not.to.be.empty - expect(data.metaData.activation_id, 'activation id').not.to.be.empty - - // check custom metadata slots - expect(data.metaData.c_script_type, 'c_script_type property').to.exist; - expect(data.metaData.c_script_type, 'c_script_type').not.to.be.empty - expect(data.metaData.c_script_type).to.equal('test-script-type'); - - expect(data.metaData.c_host, 'c_host property').to.exist; - expect(data.metaData.c_host, 'c_host').not.to.be.empty - expect(data.metaData.c_host).to.equal('test-host'); - - expect(data.metaData.c_slot1, 'c_slot1 property').to.exist; - expect(data.metaData.c_slot1, 'c_slot1').not.to.be.empty - expect(data.metaData.c_slot1).to.equal('test-slot1'); - - expect(data.metaData.c_slot2, 'c_slot1 property').to.exist; - expect(data.metaData.c_slot2, 'c_slot1').not.to.be.empty - expect(data.metaData.c_slot2).to.equal('test-slot2'); - - expect(data.metaData.c_slot3, 'c_slot1 property').to.exist; - expect(data.metaData.c_slot3, 'c_slot1').not.to.be.empty - expect(data.metaData.c_slot3).to.equal('test-slot3'); - - expect(data.metaData.c_slot4, 'c_slot1 property').to.exist; - expect(data.metaData.c_slot4, 'c_slot1').not.to.be.empty - expect(data.metaData.c_slot4).to.equal('test-slot4'); - - // check for version info too - expect(data.metaData.pw_version, 'pw_version property').to.exist; - expect(data.metaData.pbjs_version, 'pbjs_version property').to.exist; - }); - - it('should remove extra data on init', function () { - pubwiseAnalytics.enableAnalytics(mock.DEFAULT_PW_CONFIG); - - // sent - events.emit(constants.EVENTS.AUCTION_INIT, mock.AUCTION_INIT_EXTRAS); - // force flush - clock.tick(500); - - /* check for critical values */ - let request = requests[0]; - let data = JSON.parse(request.requestBody); - - // check the basics - expect(data.eventList, 'eventList property').to.exist; - expect(data.eventList[0], 'eventList property').to.exist; - expect(data.eventList[0].args, 'eventList property').to.exist; - - // eslint-disable-next-line - // console.log(data.eventList[0].args); - - let eventArgs = data.eventList[0].args; - // the props we want removed should go away - expect(eventArgs.adUnitCodes, 'adUnitCodes property').not.to.exist; - expect(eventArgs.bidderRequests, 'adUnitCodes property').not.to.exist; - expect(eventArgs.bidsReceived, 'adUnitCodes property').not.to.exist; - expect(eventArgs.config, 'adUnitCodes property').not.to.exist; - expect(eventArgs.noBids, 'adUnitCodes property').not.to.exist; - expect(eventArgs.winningBids, 'adUnitCodes property').not.to.exist; - - // the extra prop should still exist - expect(eventArgs.extraProp, 'adUnitCodes property').to.exist; - }); - }); -}); diff --git a/test/spec/modules/pubwiseBidAdapter_spec.js b/test/spec/modules/pubwiseBidAdapter_spec.js deleted file mode 100644 index 450b028f6c7..00000000000 --- a/test/spec/modules/pubwiseBidAdapter_spec.js +++ /dev/null @@ -1,575 +0,0 @@ -// import or require modules necessary for the test, e.g.: - -import {expect} from 'chai'; -import {spec} from 'modules/pubwiseBidAdapter.js'; -import {_checkMediaType} from 'modules/pubwiseBidAdapter.js'; // this is exported only for testing so maintaining the JS convention of _ to indicate the intent -import {_parseAdSlot} from 'modules/pubwiseBidAdapter.js'; // this is exported only for testing so maintaining the JS convention of _ to indicate the intent -import * as utils from 'src/utils.js'; - -const sampleRequestBanner = { - 'id': '6c148795eb836a', - 'tagid': 'div-gpt-ad-1460505748561-0', - 'bidfloor': 1, - 'secure': 1, - 'bidfloorcur': 'USD', - 'banner': { - 'w': 300, - 'h': 250, - 'format': [ - { - 'w': 300, - 'h': 600 - } - ], - 'pos': 0, - 'topframe': 1 - } -}; - -const sampleRequest = { - 'at': 1, - 'cur': [ - 'USD' - ], - 'imp': [ - sampleRequestBanner, - { - 'id': '7329ddc1d84eb3', - 'tagid': 'div-gpt-ad-1460505748561-1', - 'secure': 1, - 'bidfloorcur': 'USD', - 'native': { - 'request': '{"assets":[{"id":1,"required":1,"title":{"len":80}},{"id":5,"required":1,"data":{"type":2}},{"id":2,"required":1,"img":{"type":{"ID":2,"KEY":"image","TYPE":0},"w":150,"h":50}},{"id":4,"required":1,"data":{"type":1}}]}' - } - } - ], - 'site': { - 'page': 'http://localhost:9999/integrationExamples/gpt/hello_world.html?pbjs_debug=true', - 'ref': 'http://localhost:9999/integrationExamples/gpt/hello_world.html?pbjs_debug=true', - 'publisher': { - 'id': 'xxxxxx' - } - }, - 'device': { - 'ua': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/86.0.4240.198 Safari/537.36', - 'js': 1, - 'dnt': 0, - 'h': 600, - 'w': 800, - 'language': 'en-US', - 'geo': { - 'lat': 33.91989876432274, - 'lon': -84.38897708175764 - } - }, - 'user': { - 'gender': 'M', - 'geo': { - 'lat': 33.91989876432274, - 'lon': -84.38897708175764 - }, - 'yob': 2000 - }, - 'test': 0, - 'ext': { - 'version': '0.0.1' - }, - 'source': { - 'tid': '2c8cd034-f068-4419-8c30-f07292c0d17b' - } -}; - -const sampleValidBannerBidRequest = { - 'bidder': 'pubwise', - 'params': { - 'siteId': 'xxxxxx', - 'bidFloor': '1.00', - 'currency': 'USD', - 'gender': 'M', - 'lat': '33.91989876432274', - 'lon': '-84.38897708175764', - 'yob': '2000', - 'bcat': ['IAB25-3', 'IAB26-1', 'IAB26-2', 'IAB26-3', 'IAB26-4'], - }, - 'gdprConsent': { - 'consentString': 'BOEFEAyOEFEAyAHABDENAI4AAAB9vABAASA', - 'gdprApplies': 1, - }, - 'uspConsent': 1, - 'crumbs': { - 'pubcid': '9a62f261-3c0b-4cc8-8db3-a72ae86ec6ba' - }, - 'fpd': { - 'context': { - 'adServer': { - 'name': 'gam', - 'adSlot': '/19968336/header-bid-tag-0' - }, - 'pbAdSlot': '/19968336/header-bid-tag-0' - } - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': '2001a8b2-3bcf-417d-b64f-92641dae21e0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '6c148795eb836a', - 'bidderRequestId': '18a45bff5ff705', - 'auctionId': '9f20663c-4629-4b5c-bff6-ff3aa8319358', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 -}; - -const sampleValidBidRequests = [ - sampleValidBannerBidRequest, - { - 'bidder': 'pubwise', - 'params': { - 'siteId': 'xxxxxx' - }, - 'crumbs': { - 'pubcid': '9a62f261-3c0b-4cc8-8db3-a72ae86ec6ba' - }, - 'nativeParams': { - 'title': { - 'required': true, - 'len': 80 - }, - 'body': { - 'required': true - }, - 'image': { - 'required': true, - 'sizes': [ - 150, - 50 - ] - }, - 'sponsoredBy': { - 'required': true - }, - 'icon': { - 'required': false - } - }, - 'fpd': { - 'context': { - 'adServer': { - 'name': 'gam', - 'adSlot': '/19968336/header-bid-tag-0' - }, - 'pbAdSlot': '/19968336/header-bid-tag-0' - } - }, - 'mediaTypes': { - 'native': { - 'title': { - 'required': true, - 'len': 80 - }, - 'body': { - 'required': true - }, - 'image': { - 'required': true, - 'sizes': [ - 150, - 50 - ] - }, - 'sponsoredBy': { - 'required': true - }, - 'icon': { - 'required': false - } - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-1', - 'transactionId': '2c8cd034-f068-4419-8c30-f07292c0d17b', - 'sizes': [], - 'bidId': '30ab7516a51a7c', - 'bidderRequestId': '18a45bff5ff705', - 'auctionId': '9f20663c-4629-4b5c-bff6-ff3aa8319358', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - } -] - -const sampleBidderBannerRequest = { - 'bidder': 'pubwise', - 'params': { - 'siteId': 'xxxxxx', - 'height': 250, - 'width': 300, - 'gender': 'M', - 'yob': '2000', - 'lat': '33.91989876432274', - 'lon': '-84.38897708175764', - 'bidFloor': '1.00', - 'currency': 'USD', - 'adSlot': '', - 'adUnit': '', - 'bcat': [ - 'IAB25-3', - 'IAB26-1', - 'IAB26-2', - 'IAB26-3', - 'IAB26-4', - ], - }, - 'crumbs': { - 'pubcid': '9a62f261-3c0b-4cc8-8db3-a72ae86ec6ba' - }, - 'fpd': { - 'context': { - 'adServer': { - 'name': 'gam', - 'adSlot': '/19968336/header-bid-tag-0' - }, - 'pbAdSlot': '/19968336/header-bid-tag-0' - } - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 600 - ] - ] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': '2001a8b2-3bcf-417d-b64f-92641dae21e0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '6c148795eb836a', - 'bidderRequestId': '18a45bff5ff705', - 'auctionId': '9f20663c-4629-4b5c-bff6-ff3aa8319358', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0, - 'gdprConsent': { - 'consentString': 'BOEFEAyOEFEAyAHABDENAI4AAAB9vABAASA', - 'gdprApplies': 1, - }, - 'uspConsent': 1, -}; - -const sampleBidderRequest = { - 'bidderCode': 'pubwise', - 'auctionId': '9f20663c-4629-4b5c-bff6-ff3aa8319358', - 'bidderRequestId': '18a45bff5ff705', - 'bids': [ - sampleBidderBannerRequest, - { - 'bidder': 'pubwise', - 'params': { - 'siteId': 'xxxxxx' - }, - 'crumbs': { - 'pubcid': '9a62f261-3c0b-4cc8-8db3-a72ae86ec6ba' - }, - 'nativeParams': { - 'title': { - 'required': true, - 'len': 80 - }, - 'body': { - 'required': true - }, - 'image': { - 'required': true, - 'sizes': [ - 150, - 50 - ] - }, - 'sponsoredBy': { - 'required': true - }, - 'icon': { - 'required': false - } - }, - 'fpd': { - 'context': { - 'adServer': { - 'name': 'gam', - 'adSlot': '/19968336/header-bid-tag-0' - }, - 'pbAdSlot': '/19968336/header-bid-tag-0' - } - }, - 'mediaTypes': { - 'native': { - 'title': { - 'required': true, - 'len': 80 - }, - 'body': { - 'required': true - }, - 'image': { - 'required': true, - 'sizes': [ - 150, - 50 - ] - }, - 'sponsoredBy': { - 'required': true - }, - 'icon': { - 'required': false - } - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-1', - 'transactionId': '2c8cd034-f068-4419-8c30-f07292c0d17b', - 'sizes': [], - 'bidId': '30ab7516a51a7c', - 'bidderRequestId': '18a45bff5ff705', - 'auctionId': '9f20663c-4629-4b5c-bff6-ff3aa8319358', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - } - ], - 'auctionStart': 1606269202001, - 'timeout': 1000, - 'gdprConsent': { - 'consentString': 'BOEFEAyOEFEAyAHABDENAI4AAAB9vABAASA', - 'gdprApplies': 1, - }, - 'uspConsent': 1, - 'refererInfo': { - 'referer': 'http://localhost:9999/integrationExamples/gpt/hello_world.html?pbjs_debug=true', - 'reachedTop': true, - 'isAmp': false, - 'numIframes': 0, - 'stack': [ - 'http://localhost:9999/integrationExamples/gpt/hello_world.html?pbjs_debug=true' - ], - 'canonicalUrl': null - }, - 'start': 1606269202004 -}; - -const sampleRTBResponse = { - 'body': { - 'id': '1606251348404', - 'seatbid': [ - { - 'bid': [ - { - 'id': '1606579704052', - 'impid': '6c148795eb836a', - 'price': 1.23, - 'adm': '\u003cdiv style="box-sizing: border-box;width:298px;height:248px;border: 1px solid rgba(0,0,0,.25);border-radius:10px;"\u003e\n\t\u003ch3 style="margin-top:80px;text-align: center;"\u003ePubWise Test Bid\u003c/h3\u003e\n\u003c/div\u003e', - 'crid': 'test', - 'w': 300, - 'h': 250 - }, - { - 'id': '1606579704052', - 'impid': '7329ddc1d84eb3', - 'price': 1.23, - 'adm': '{"ver":"1.2","assets":[{"id":1,"title":{"text":"PubWise Test"}},{"id":2,"img":{"type":3,"url":"http://www.pubwise.io","w":300,"h":250}},{"id":3,"img":{"type":1,"url":"http://www.pubwise.io","w":150,"h":125}},{"id":5,"data":{"type":2,"value":"PubWise Test Desc"}},{"id":4,"data":{"type":1,"value":"PubWise.io"}}],"link":{"url":"http://www.pubwise.io"}}', - 'crid': 'test', - 'w': 300, - 'h': 250 - } - ] - } - ], - 'bidid': 'testtesttest' - } -}; - -const samplePBBidObjects = [ - { - 'requestId': '6c148795eb836a', - 'cpm': '1.23', - 'width': 300, - 'height': 250, - 'creativeId': 'test', - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'ad': '
\n\t

PubWise Test Bid

\n
', - 'pw_seat': null, - 'pw_dspid': null, - 'partnerImpId': '1606579704052', - 'meta': {}, - 'mediaType': 'banner', - }, - { - 'requestId': '7329ddc1d84eb3', - 'cpm': '1.23', - 'width': 300, - 'height': 250, - 'creativeId': 'test', - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'ad': '{\"ver\":\"1.2\",\"assets\":[{\"id\":1,\"title\":{\"text\":\"PubWise Test\"}},{\"id\":2,\"img\":{\"type\":3,\"url\":\"http://www.pubwise.io\",\"w\":300,\"h\":250}},{\"id\":3,\"img\":{\"type\":1,\"url\":\"http://www.pubwise.io\",\"w\":150,\"h\":125}},{\"id\":5,\"data\":{\"type\":2,\"value\":\"PubWise Test Desc\"}},{\"id\":4,\"data\":{\"type\":1,\"value\":\"PubWise.io\"}}],\"link\":{\"url\":\"http://www.pubwise.io\"}}', - 'pw_seat': null, - 'pw_dspid': null, - 'partnerImpId': '1606579704052', - 'mediaType': 'native', - 'native': { - 'body': 'PubWise Test Desc', - 'icon': { - 'height': 125, - 'url': 'http://www.pubwise.io', - 'width': 150, - }, - 'image': { - 'height': 250, - 'url': 'http://www.pubwise.io', - 'width': 300, - }, - 'sponsoredBy': 'PubWise.io', - 'title': 'PubWise Test' - }, - 'meta': {}, - 'impressionTrackers': [], - 'jstracker': [], - 'clickTrackers': [], - 'clickUrl': 'http://www.pubwise.io' - } -]; - -describe('PubWiseAdapter', function () { - describe('Properly Validates Bids', function () { - it('valid bid', function () { - let validBid = { - bidder: 'pubwise', - params: { - siteId: 'xxxxxx' - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(true); - }); - - it('valid bid: extra fields are ok', function () { - let validBid = { - bidder: 'pubwise', - params: { - siteId: 'xxxxxx', - gender: 'M', - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(true); - }); - - it('invalid bid: no siteId', function () { - let inValidBid = { - bidder: 'pubwise', - params: { - gender: 'M', - } - }, - isValid = spec.isBidRequestValid(inValidBid); - expect(isValid).to.equal(false); - }); - - it('invalid bid: siteId should be a string', function () { - let validBid = { - bidder: 'pubwise', - params: { - siteId: 123456 - } - }, - isValid = spec.isBidRequestValid(validBid); - expect(isValid).to.equal(false); - }); - }); - - describe('Handling Request Construction', function () { - it('bid requests are not mutable', function() { - let sourceBidRequest = utils.deepClone(sampleValidBidRequests) - spec.buildRequests(sampleValidBidRequests, {auctinId: 'placeholder'}); - expect(sampleValidBidRequests).to.deep.equal(sourceBidRequest, 'Should be unedited as they are used elsewhere'); - }); - it('should handle complex bidRequest', function() { - let request = spec.buildRequests(sampleValidBidRequests, sampleBidderRequest); - expect(request.bidderRequest).to.equal(sampleBidderRequest); - }); - it('must conform to API for buildRequests', function() { - let request = spec.buildRequests(sampleValidBidRequests); - expect(request.bidderRequest).to.be.undefined; - }); - }); - - describe('Identifies Media Types', function () { - it('identifies native adm type', function() { - let 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":""}}'; - let 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); - expect(newBid.mediaType).to.equal('banner', adm + ' Is a Banner adm'); - }); - }); - - describe('Properly Parses AdSlot Data', function () { - it('parses banner', function() { - let testBid = utils.deepClone(sampleValidBannerBidRequest) - _parseAdSlot(testBid) - expect(testBid).to.deep.equal(sampleBidderBannerRequest); - }); - }); - - describe('Properly Handles Response', function () { - it('handles response with muiltiple responses', function() { - // the request when it comes back is on the data object - let pbResponse = spec.interpretResponse(sampleRTBResponse, {'data': sampleRequest}) - expect(pbResponse).to.deep.equal(samplePBBidObjects); - }); - }); -}); diff --git a/test/spec/modules/pubxBidAdapter_spec.js b/test/spec/modules/pubxBidAdapter_spec.js deleted file mode 100644 index 6cea8787845..00000000000 --- a/test/spec/modules/pubxBidAdapter_spec.js +++ /dev/null @@ -1,189 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/pubxBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; - -describe('pubxAdapter', function () { - const adapter = newBidder(spec); - const ENDPOINT = 'https://api.primecaster.net/adlogue/api/slot/bid'; - - 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 bid = { - bidder: 'pubx', - params: { - sid: '12345abc' - } - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const bidRequests = [ - { - id: '26c1ee0038ac11', - params: { - sid: '12345abc' - } - } - ]; - - const data = { - banner: { - sid: '12345abc' - } - }; - - it('sends bid request to ENDPOINT via GET', function () { - const request = spec.buildRequests(bidRequests)[0]; - expect(request.url).to.equal(ENDPOINT); - expect(request.method).to.equal('GET'); - }); - - it('should attach params to the banner request', function () { - const request = spec.buildRequests(bidRequests)[0]; - expect(request.data).to.deep.equal(data.banner); - }); - }); - - describe('getUserSyncs', function () { - const sandbox = sinon.sandbox.create(); - - const keywordsText = 'meta1,meta2,meta3,meta4,meta5'; - const descriptionText = 'description1description2description3description4description5description'; - - let documentStubMeta; - - beforeEach(function () { - documentStubMeta = sandbox.stub(document, 'getElementsByName'); - const metaElKeywords = document.createElement('meta'); - metaElKeywords.setAttribute('name', 'keywords'); - metaElKeywords.setAttribute('content', keywordsText); - documentStubMeta.withArgs('keywords').returns([metaElKeywords]); - - const metaElDescription = document.createElement('meta'); - metaElDescription.setAttribute('name', 'description'); - metaElDescription.setAttribute('content', descriptionText); - documentStubMeta.withArgs('description').returns([metaElDescription]); - }); - - afterEach(function () { - documentStubMeta.restore(); - }); - - let kwString = ''; - let kwEnc = ''; - let descContent = ''; - let descEnc = ''; - - it('returns empty sync array when iframe is not enabled', function () { - const syncOptions = {}; - expect(spec.getUserSyncs(syncOptions)).to.deep.equal([]); - }); - - it('returns kwEnc when there is kwTag with more than 20 length', function () { - const kwArray = keywordsText.substr(0, 20).split(','); - kwArray.pop(); - kwString = kwArray.join(); - kwEnc = encodeURIComponent(kwString); - const syncs = spec.getUserSyncs({ iframeEnabled: true }); - expect(syncs[0].url).to.include(`pkw=${kwEnc}`); - }); - - it('returns kwEnc when there is kwTag with more than 60 length', function () { - descContent = descContent.substr(0, 60); - descEnc = encodeURIComponent(descContent); - const syncs = spec.getUserSyncs({ iframeEnabled: true }); - expect(syncs[0].url).to.include(`pkw=${descEnc}`); - }); - - it('returns titleEnc when there is titleContent with more than 30 length', function () { - let titleText = 'title1title2title3title4title5title'; - const documentStubTitle = sandbox.stub(document, 'title').value(titleText); - - if (titleText.length > 30) { - titleText = titleText.substr(0, 30); - } - - const syncs = spec.getUserSyncs({ iframeEnabled: true }); - expect(syncs[0].url).to.include(`pt=${encodeURIComponent(titleText)}`); - }); - }); - - describe('interpretResponse', function () { - const serverResponse = { - body: { - TTL: 300, - adm: '
some creative
', - cid: 'TKmB', - cpm: 500, - currency: 'JPY', - height: 250, - width: 300, - } - } - - const bidRequests = [ - { - id: '26c1ee0038ac11', - params: { - sid: '12345abc' - } - } - ]; - - const bidResponses = [ - { - requestId: '26c1ee0038ac11', - cpm: 500, - currency: 'JPY', - width: 300, - height: 250, - creativeId: 'TKmB', - netRevenue: true, - ttl: 300, - ad: '
some creative
' - } - ]; - it('should return empty array when required param is empty', function () { - const serverResponseWithCidEmpty = { - body: { - TTL: 300, - adm: '
some creative
', - cid: '', - cpm: '', - currency: 'JPY', - height: 250, - width: 300, - } - } - const result = spec.interpretResponse(serverResponseWithCidEmpty, bidRequests[0]); - expect(result).to.be.empty; - }); - it('handles banner responses', function () { - const result = spec.interpretResponse(serverResponse, bidRequests[0])[0]; - expect(result.requestId).to.equal(bidResponses[0].requestId); - expect(result.width).to.equal(bidResponses[0].width); - expect(result.height).to.equal(bidResponses[0].height); - expect(result.creativeId).to.equal(bidResponses[0].creativeId); - expect(result.currency).to.equal(bidResponses[0].currency); - expect(result.netRevenue).to.equal(bidResponses[0].netRevenue); - expect(result.ttl).to.equal(bidResponses[0].ttl); - expect(result.ad).to.equal(bidResponses[0].ad); - }); - }); -}); diff --git a/test/spec/modules/pubxaiAnalyticsAdapter_spec.js b/test/spec/modules/pubxaiAnalyticsAdapter_spec.js deleted file mode 100644 index 40f7afeeb6a..00000000000 --- a/test/spec/modules/pubxaiAnalyticsAdapter_spec.js +++ /dev/null @@ -1,683 +0,0 @@ -import pubxaiAnalyticsAdapter from 'modules/pubxaiAnalyticsAdapter.js'; -import { getDeviceType, getBrowser, getOS } from 'modules/pubxaiAnalyticsAdapter.js'; -import { - expect -} from 'chai'; -import adapterManager from 'src/adapterManager.js'; -import * as utils from 'src/utils.js'; -import { - server -} from 'test/mocks/xhr.js'; - -let events = require('src/events'); -let constants = require('src/constants.json'); - -describe('pubxai analytics adapter', function() { - beforeEach(function() { - sinon.stub(events, 'getEvents').returns([]); - }); - - afterEach(function() { - events.getEvents.restore(); - }); - - describe('track', function() { - let initOptions = { - samplingRate: '1', - pubxId: '6c415fc0-8b0e-4cf5-be73-01526a4db625' - }; - - let location = utils.getWindowLocation(); - - let prebidEvent = { - 'auctionInit': { - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'timestamp': 1603865707180, - 'auctionStatus': 'inProgress', - 'adUnits': [{ - 'code': '/19968336/header-bid-tag-1', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } - }, - 'bids': [{ - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 - }, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'floorData': { - 'skipped': false, - 'skipRate': 0, - 'modelVersion': 'test model 1.0', - 'location': 'fetch', - 'floorProvider': 'PubXFloorProvider', - 'fetchStatus': 'success' - } - }], - 'sizes': [ - [ - 300, - 250 - ] - ], - 'transactionId': '41ec8eaf-3e7c-4a8b-8344-ab796ff6e294' - }], - 'adUnitCodes': [ - '/19968336/header-bid-tag-1' - ], - 'bidderRequests': [{ - 'bidderCode': 'appnexus', - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'bidderRequestId': '184cbc05bb90ba', - 'bids': [{ - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 - }, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'floorData': { - 'skipped': false, - 'skipRate': 0, - 'modelVersion': 'test model 1.0', - 'location': 'fetch', - 'floorProvider': 'PubXFloorProvider', - 'fetchStatus': 'success' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } - }, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'transactionId': '41ec8eaf-3e7c-4a8b-8344-ab796ff6e294', - 'sizes': [ - [ - 300, - 250 - ] - ], - 'bidId': '248f9a4489835e', - 'bidderRequestId': '184cbc05bb90ba', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - }], - 'auctionStart': 1603865707180, - 'timeout': 1000, - 'refererInfo': { - 'referer': 'http://local-pnh.net:8080/stream/', - 'reachedTop': true, - 'isAmp': false, - 'numIframes': 0, - 'stack': [ - 'http://local-pnh.net:8080/stream/' - ], - 'canonicalUrl': null - }, - 'start': 1603865707182 - }], - 'noBids': [], - 'bidsReceived': [], - 'winningBids': [], - 'timeout': 1000, - 'config': { - 'samplingRate': '1', - 'pubxId': '6c415fc0-8b0e-4cf5-be73-01526a4db625' - } - }, - 'bidRequested': { - 'bidderCode': 'appnexus', - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'bidderRequestId': '184cbc05bb90ba', - 'bids': [{ - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 - }, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'floorData': { - 'skipped': false, - 'skipRate': 0, - 'modelVersion': 'test model 1.0', - 'location': 'fetch', - 'floorProvider': 'PubXFloorProvider', - 'fetchStatus': 'success' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } - }, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'transactionId': '41ec8eaf-3e7c-4a8b-8344-ab796ff6e294', - 'sizes': [ - [ - 300, - 250 - ] - ], - 'bidId': '248f9a4489835e', - 'bidderRequestId': '184cbc05bb90ba', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - }], - 'auctionStart': 1603865707180, - 'timeout': 1000, - 'refererInfo': { - 'referer': 'http://local-pnh.net:8080/stream/', - 'reachedTop': true, - 'isAmp': false, - 'numIframes': 0, - 'stack': [ - 'http://local-pnh.net:8080/stream/' - ], - 'canonicalUrl': null - }, - 'start': 1603865707182 - }, - 'bidTimeout': [], - 'bidResponse': { - 'bidderCode': 'appnexus', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '32780c4bc382cb', - 'requestId': '248f9a4489835e', - 'mediaType': 'banner', - 'source': 'client', - 'cpm': 0.5, - 'creativeId': 96846035, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'appnexus': { - 'buyerMemberId': 9325 - }, - 'meta': { - 'advertiserId': 2529885 - }, - 'ad': '', - 'originalCpm': 0.5, - 'originalCurrency': 'USD', - 'floorData': { - 'fetchStatus': 'success', - 'floorProvider': 'PubXFloorProvider', - 'location': 'fetch', - 'modelVersion': 'test model 1.0', - 'skipRate': 0, - 'skipped': false, - 'floorValue': 0.4, - 'floorRule': '/19968336/header-bid-tag-1|banner', - 'floorCurrency': 'USD', - 'cpmAfterAdjustments': 0.5, - 'enforcements': { - 'enforceJS': true, - 'enforcePBS': false, - 'floorDeals': true, - 'bidAdjustment': true - }, - 'matchedFields': { - 'gptSlot': '/19968336/header-bid-tag-1', - 'mediaType': 'banner' - } - }, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'responseTimestamp': 1616654313071, - 'requestTimestamp': 1616654312804, - 'bidder': 'appnexus', - 'timeToRespond': 267, - 'pbLg': '0.50', - 'pbMg': '0.50', - 'pbHg': '0.50', - 'pbAg': '0.50', - 'pbDg': '0.50', - 'pbCg': '0.50', - 'size': '300x250', - 'adserverTargeting': { - 'hb_bidder': 'appnexus', - 'hb_adid': '32780c4bc382cb', - 'hb_pb': '0.50', - 'hb_size': '300x250', - 'hb_source': 'client', - 'hb_format': 'banner' - }, - }, - 'auctionEnd': { - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'timestamp': 1616654312804, - 'auctionEnd': 1616654313090, - 'auctionStatus': 'completed', - 'adUnits': [{ - 'code': '/19968336/header-bid-tag-1', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } - }, - 'bids': [{ - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 - }, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'floorData': { - 'skipped': false, - 'skipRate': 0, - 'modelVersion': 'test model 1.0', - 'location': 'fetch', - 'floorProvider': 'PubXFloorProvider', - 'fetchStatus': 'success' - } - }], - 'sizes': [ - [ - 300, - 250 - ] - ], - 'transactionId': '41ec8eaf-3e7c-4a8b-8344-ab796ff6e294' - }], - 'adUnitCodes': [ - '/19968336/header-bid-tag-1' - ], - 'bidderRequests': [{ - 'bidderCode': 'appnexus', - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'bidderRequestId': '184cbc05bb90ba', - 'bids': [{ - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 - }, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'floorData': { - 'skipped': false, - 'skipRate': 0, - 'modelVersion': 'test model 1.0', - 'location': 'fetch', - 'floorProvider': 'PubXFloorProvider', - 'fetchStatus': 'success' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } - }, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'transactionId': '41ec8eaf-3e7c-4a8b-8344-ab796ff6e294', - 'sizes': [ - [ - 300, - 250 - ] - ], - 'bidId': '248f9a4489835e', - 'bidderRequestId': '184cbc05bb90ba', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - }], - 'auctionStart': 1603865707180, - 'timeout': 1000, - 'refererInfo': { - 'referer': 'http://local-pnh.net:8080/stream/', - 'reachedTop': true, - 'isAmp': false, - 'numIframes': 0, - 'stack': [ - 'http://local-pnh.net:8080/stream/' - ], - 'canonicalUrl': null - }, - 'start': 1603865707182 - }], - 'noBids': [], - 'bidsReceived': [{ - 'bidderCode': 'appnexus', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '32780c4bc382cb', - 'requestId': '248f9a4489835e', - 'mediaType': 'banner', - 'source': 'client', - 'cpm': 0.5, - 'creativeId': 96846035, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'appnexus': { - 'buyerMemberId': 9325 - }, - 'meta': { - 'advertiserId': 2529885 - }, - 'ad': '', - 'originalCpm': 0.5, - 'originalCurrency': 'USD', - 'floorData': { - 'fetchStatus': 'success', - 'floorProvider': 'PubXFloorProvider', - 'location': 'fetch', - 'modelVersion': 'test model 1.0', - 'skipRate': 0, - 'skipped': false, - 'floorValue': 0.4, - 'floorRule': '/19968336/header-bid-tag-1|banner', - 'floorCurrency': 'USD', - 'cpmAfterAdjustments': 0.5, - 'enforcements': { - 'enforceJS': true, - 'enforcePBS': false, - 'floorDeals': true, - 'bidAdjustment': true - }, - 'matchedFields': { - 'gptSlot': '/19968336/header-bid-tag-1', - 'mediaType': 'banner' - } - }, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'responseTimestamp': 1616654313071, - 'requestTimestamp': 1616654312804, - 'bidder': 'appnexus', - 'timeToRespond': 267, - 'pbLg': '0.50', - 'pbMg': '0.50', - 'pbHg': '0.50', - 'pbAg': '0.50', - 'pbDg': '0.50', - 'pbCg': '0.50', - 'size': '300x250', - 'adserverTargeting': { - 'hb_bidder': 'appnexus', - 'hb_adid': '32780c4bc382cb', - 'hb_pb': '0.50', - 'hb_size': '300x250', - 'hb_source': 'client', - 'hb_format': 'banner' - }, - 'status': 'rendered', - 'params': [{ - 'placementId': 13144370 - }] - }], - 'winningBids': [], - 'timeout': 1000 - }, - 'bidWon': { - 'bidderCode': 'appnexus', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '32780c4bc382cb', - 'requestId': '248f9a4489835e', - 'mediaType': 'banner', - 'source': 'client', - 'cpm': 0.5, - 'creativeId': 96846035, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'adUnitCode': '/19968336/header-bid-tag-1', - 'appnexus': { - 'buyerMemberId': 9325 - }, - 'meta': { - 'advertiserId': 2529885 - }, - 'ad': '', - 'originalCpm': 0.5, - 'originalCurrency': 'USD', - 'floorData': { - 'fetchStatus': 'success', - 'floorProvider': 'PubXFloorProvider', - 'location': 'fetch', - 'modelVersion': 'test model 1.0', - 'skipRate': 0, - 'skipped': false, - 'floorValue': 0.4, - 'floorRule': '/19968336/header-bid-tag-1|banner', - 'floorCurrency': 'USD', - 'cpmAfterAdjustments': 0.5, - 'enforcements': { - 'enforceJS': true, - 'enforcePBS': false, - 'floorDeals': true, - 'bidAdjustment': true - }, - 'matchedFields': { - 'gptSlot': '/19968336/header-bid-tag-1', - 'mediaType': 'banner' - } - }, - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'responseTimestamp': 1616654313071, - 'requestTimestamp': 1616654312804, - 'bidder': 'appnexus', - 'timeToRespond': 267, - 'pbLg': '0.50', - 'pbMg': '0.50', - 'pbHg': '0.50', - 'pbAg': '0.50', - 'pbDg': '0.50', - 'pbCg': '0.50', - 'size': '300x250', - 'adserverTargeting': { - 'hb_bidder': 'appnexus', - 'hb_adid': '32780c4bc382cb', - 'hb_pb': '0.50', - 'hb_size': '300x250', - 'hb_source': 'client', - 'hb_format': 'banner' - }, - 'status': 'rendered', - 'params': [{ - 'placementId': 13144370 - }] - }, - 'pageDetail': { - 'host': location.host, - 'path': location.pathname, - 'search': location.search - }, - }; - - let expectedAfterBid = { - 'bids': [{ - 'bidderCode': 'appnexus', - 'bidId': '248f9a4489835e', - 'adUnitCode': '/19968336/header-bid-tag-1', - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'sizes': '300x250', - 'renderStatus': 2, - 'requestTimestamp': 1616654312804, - 'creativeId': 96846035, - 'currency': 'USD', - 'cpm': 0.5, - 'netRevenue': true, - 'mediaType': 'banner', - 'statusMessage': 'Bid available', - 'floorData': { - 'fetchStatus': 'success', - 'floorProvider': 'PubXFloorProvider', - 'location': 'fetch', - 'modelVersion': 'test model 1.0', - 'skipRate': 0, - 'skipped': false, - 'floorValue': 0.4, - 'floorRule': '/19968336/header-bid-tag-1|banner', - 'floorCurrency': 'USD', - 'cpmAfterAdjustments': 0.5, - 'enforcements': { - 'enforceJS': true, - 'enforcePBS': false, - 'floorDeals': true, - 'bidAdjustment': true - }, - 'matchedFields': { - 'gptSlot': '/19968336/header-bid-tag-1', - 'mediaType': 'banner' - } - }, - 'timeToRespond': 267, - 'responseTimestamp': 1616654313071 - }], - 'pageDetail': { - 'host': location.host, - 'path': location.pathname, - 'search': location.search, - 'adUnitCount': 1 - }, - 'floorDetail': { - 'fetchStatus': 'success', - 'floorProvider': 'PubXFloorProvider', - 'location': 'fetch', - 'modelVersion': 'test model 1.0', - 'skipRate': 0, - 'skipped': false - }, - 'deviceDetail': { - 'platform': navigator.platform, - 'deviceType': getDeviceType(), - 'deviceOS': getOS(), - 'browser': getBrowser() - }, - 'initOptions': initOptions - }; - - let expectedAfterBidWon = { - 'winningBid': { - 'adUnitCode': '/19968336/header-bid-tag-1', - 'auctionId': 'bc3806e4-873e-453c-8ae5-204f35e923b4', - 'bidderCode': 'appnexus', - 'bidId': '248f9a4489835e', - 'cpm': 0.5, - 'creativeId': 96846035, - 'currency': 'USD', - 'floorData': { - 'fetchStatus': 'success', - 'floorProvider': 'PubXFloorProvider', - 'location': 'fetch', - 'modelVersion': 'test model 1.0', - 'skipRate': 0, - 'skipped': false, - 'floorValue': 0.4, - 'floorRule': '/19968336/header-bid-tag-1|banner', - 'floorCurrency': 'USD', - 'cpmAfterAdjustments': 0.5, - 'enforcements': { - 'enforceJS': true, - 'enforcePBS': false, - 'floorDeals': true, - 'bidAdjustment': true - }, - 'matchedFields': { - 'gptSlot': '/19968336/header-bid-tag-1', - 'mediaType': 'banner' - } - }, - 'floorProvider': 'PubXFloorProvider', - 'isWinningBid': true, - 'mediaType': 'banner', - 'netRevenue': true, - 'placementId': 13144370, - 'renderedSize': '300x250', - 'renderStatus': 4, - 'responseTimestamp': 1616654313071, - 'requestTimestamp': 1616654312804, - 'status': 'rendered', - 'statusMessage': 'Bid available', - 'timeToRespond': 267 - }, - 'deviceDetail': { - 'platform': navigator.platform, - 'deviceType': getDeviceType(), - 'deviceOS': getOS(), - 'browser': getBrowser() - }, - 'initOptions': initOptions - } - - adapterManager.registerAnalyticsAdapter({ - code: 'pubxai', - adapter: pubxaiAnalyticsAdapter - }); - - beforeEach(function() { - adapterManager.enableAnalytics({ - provider: 'pubxai', - options: initOptions - }); - }); - - afterEach(function() { - pubxaiAnalyticsAdapter.disableAnalytics(); - }); - - it('builds and sends auction data', function() { - // Step 1: Send auction init event - events.emit(constants.EVENTS.AUCTION_INIT, prebidEvent['auctionInit']); - - // Step 2: Send bid requested event - events.emit(constants.EVENTS.BID_REQUESTED, prebidEvent['bidRequested']); - - // Step 3: Send bid response event - events.emit(constants.EVENTS.BID_RESPONSE, prebidEvent['bidResponse']); - - // Step 4: Send bid time out event - events.emit(constants.EVENTS.BID_TIMEOUT, prebidEvent['bidTimeout']); - - // Step 5: Send auction end event - events.emit(constants.EVENTS.AUCTION_END, prebidEvent['auctionEnd']); - - expect(server.requests.length).to.equal(1); - - let realAfterBid = JSON.parse(server.requests[0].requestBody); - - expect(realAfterBid).to.deep.equal(expectedAfterBid); - - // Step 6: Send auction bid won event - events.emit(constants.EVENTS.BID_WON, prebidEvent['bidWon']); - - expect(server.requests.length).to.equal(2); - - let winEventData = JSON.parse(server.requests[1].requestBody); - - expect(winEventData).to.deep.equal(expectedAfterBidWon); - }); - }); -}); diff --git a/test/spec/modules/pulsepointBidAdapter_spec.js b/test/spec/modules/pulsepointBidAdapter_spec.js deleted file mode 100644 index c3830d5cb46..00000000000 --- a/test/spec/modules/pulsepointBidAdapter_spec.js +++ /dev/null @@ -1,781 +0,0 @@ -/* eslint dot-notation:0, quote-props:0 */ -import {expect} from 'chai'; -import {spec} from 'modules/pulsepointBidAdapter.js'; -import {deepClone} from 'src/utils.js'; - -describe('PulsePoint Adapter Tests', function () { - const slotConfigs = [{ - placementCode: '/DfpAccount1/slot1', - mediaTypes: { - banner: { - sizes: [[728, 90], [160, 600]] - } - }, - bidId: 'bid12345', - params: { - cp: 'p10000', - ct: 't10000', - cf: '300x250' - } - }, { - placementCode: '/DfpAccount2/slot2', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - }, - bidId: 'bid23456', - params: { - cp: 'p10000', - ct: 't20000', - cf: '728x90' - } - }]; - const nativeSlotConfig = [{ - placementCode: '/DfpAccount1/slot3', - bidId: 'bid12345', - nativeParams: { - title: { required: true, len: 200 }, - image: { wmin: 100 }, - sponsoredBy: { } - }, - params: { - cp: 'p10000', - ct: 't10000' - } - }]; - const appSlotConfig = [{ - placementCode: '/DfpAccount1/slot3', - bidId: 'bid12345', - params: { - cp: 'p10000', - ct: 't10000', - app: { - bundle: 'com.pulsepoint.apps', - storeUrl: 'https://pulsepoint.com/apps', - domain: 'pulsepoint.com', - } - } - }]; - const videoSlotConfig = [{ - placementCode: '/DfpAccount1/slotVideo', - bidId: 'bid12345', - params: { - cp: 'p10000', - ct: 't10000', - video: { - w: 400, - h: 300, - minduration: 5, - maxduration: 10, - startdelay: 0, - skip: 1, - minbitrate: 200, - protocols: [1, 2, 4] - } - } - }]; - const additionalParamsConfig = [{ - placementCode: '/DfpAccount1/slot1', - mediaTypes: { - banner: { - sizes: [[1, 1]] - } - }, - bidId: 'bid12345', - params: { - cp: 'p10000', - ct: 't10000', - cf: '1x1', - extra_key1: 'extra_val1', - extra_key2: 12345, - extra_key3: { - key1: 'val1', - key2: 23456, - }, - extra_key4: [1, 2, 3] - } - }]; - - const ortbParamsSlotConfig = [{ - placementCode: '/DfpAccount1/slot1', - mediaTypes: { - banner: { - sizes: [[1, 1]] - } - }, - bidId: 'bid12345', - params: { - cp: 'p10000', - ct: 't10000', - cf: '1x1', - bcat: ['IAB-1', 'IAB-20'], - battr: [1, 2, 3], - bidfloor: 1.5, - badv: ['cocacola.com', 'lays.com'] - } - }, { - placementCode: '/DfpAccount1/slotVideo', - bidId: 'bid12345', - params: { - cp: 'p10000', - ct: 't10000', - video: { - w: 400, - h: 300, - minduration: 5, - maxduration: 10, - }, - battr: [2, 3, 4], - bidfloor: 2.5, - } - }]; - - const outstreamSlotConfig = [{ - placementCode: '/DfpAccount1/slot1', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'outstream' - } - }, - bidId: 'bid12345', - params: { - cp: 'p10000', - ct: 't10000', - cf: '1x1', - video: { - h: 300, - w: 400, - minduration: 1, - maxduration: 210, - linearity: 1, - } - }, - renderer: { - options: { - text: 'PulsePoint Outstream' - } - } - }]; - - const schainParamsSlotConfig = [{ - placementCode: '/DfpAccount1/slot1', - mediaTypes: { - banner: { - sizes: [[1, 1]] - } - }, - bidId: 'bid12345', - params: { - cp: 'p10000', - ct: 't10000', - cf: '1x1', - bcat: ['IAB-1', 'IAB-20'], - battr: [1, 2, 3], - bidfloor: 1.5, - badv: ['cocacola.com', 'lays.com'] - }, - 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 = { - refererInfo: { - referer: 'https://publisher.com/home' - } - }; - - it('Verify build request', function () { - const request = spec.buildRequests(slotConfigs, bidderRequest); - expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid'); - expect(request.method).to.equal('POST'); - const ortbRequest = request.data; - // site object - expect(ortbRequest.site).to.not.equal(null); - expect(ortbRequest.site.publisher).to.not.equal(null); - expect(ortbRequest.site.publisher.id).to.equal('p10000'); - expect(ortbRequest.site.ref).to.equal(window.top.document.referrer); - expect(ortbRequest.site.page).to.equal('https://publisher.com/home'); - expect(ortbRequest.imp).to.have.lengthOf(2); - // device object - expect(ortbRequest.device).to.not.equal(null); - expect(ortbRequest.device.ua).to.equal(navigator.userAgent); - // slot 1 - expect(ortbRequest.imp[0].tagid).to.equal('t10000'); - expect(ortbRequest.imp[0].banner).to.not.equal(null); - expect(ortbRequest.imp[0].banner.w).to.equal(300); - expect(ortbRequest.imp[0].banner.h).to.equal(250); - // slot 2 - expect(ortbRequest.imp[1].tagid).to.equal('t20000'); - expect(ortbRequest.imp[1].banner).to.not.equal(null); - expect(ortbRequest.imp[1].banner.w).to.equal(728); - expect(ortbRequest.imp[1].banner.h).to.equal(90); - }); - - it('Verify parse response', function () { - const request = spec.buildRequests(slotConfigs, bidderRequest); - const ortbRequest = request.data; - const ortbResponse = { - seatbid: [{ - bid: [{ - impid: ortbRequest.imp[0].id, - price: 1.25, - adm: 'This is an Ad', - crid: 'Creative#123' - }] - }] - }; - const bids = spec.interpretResponse({ body: ortbResponse }, request); - expect(bids).to.have.lengthOf(1); - // verify first bid - const bid = bids[0]; - expect(bid.cpm).to.equal(1.25); - expect(bid.ad).to.equal('This is an Ad'); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.adId).to.equal('bid12345'); - expect(bid.creative_id).to.equal('Creative#123'); - expect(bid.creativeId).to.equal('Creative#123'); - expect(bid.netRevenue).to.equal(true); - expect(bid.currency).to.equal('USD'); - expect(bid.ttl).to.equal(20); - }); - - it('Verify ttl/currency applied to bid', function () { - const request = spec.buildRequests(slotConfigs, bidderRequest); - const ortbRequest = request.data; - const ortbResponse = { - seatbid: [{ - bid: [{ - impid: ortbRequest.imp[0].id, - price: 1.25, - adm: 'This is an Ad#1', - crid: 'Creative#123', - exp: 50 - }, { - impid: ortbRequest.imp[1].id, - price: 1.25, - adm: 'This is an Ad#2', - crid: 'Creative#123' - }] - }], - cur: 'GBP' - }; - const bids = spec.interpretResponse({ body: ortbResponse }, request); - expect(bids).to.have.lengthOf(2); - // verify first bid - const bid = bids[0]; - expect(bid.cpm).to.equal(1.25); - expect(bid.ad).to.equal('This is an Ad#1'); - expect(bid.ttl).to.equal(50); - expect(bid.currency).to.equal('GBP'); - const secondBid = bids[1]; - expect(secondBid.cpm).to.equal(1.25); - expect(secondBid.ad).to.equal('This is an Ad#2'); - expect(secondBid.ttl).to.equal(20); - expect(secondBid.currency).to.equal('GBP'); - }); - - it('Verify full passback', function () { - const request = spec.buildRequests(slotConfigs, bidderRequest); - const bids = spec.interpretResponse({ body: null }, request) - expect(bids).to.have.lengthOf(0); - }); - - it('Verify Native request', function () { - const request = spec.buildRequests(nativeSlotConfig, bidderRequest); - expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid'); - expect(request.method).to.equal('POST'); - const ortbRequest = request.data; - // native impression - expect(ortbRequest.imp[0].tagid).to.equal('t10000'); - expect(ortbRequest.imp[0].banner).to.equal(null); - const nativePart = ortbRequest.imp[0]['native']; - expect(nativePart).to.not.equal(null); - expect(nativePart.ver).to.equal('1.1'); - expect(nativePart.request).to.not.equal(null); - // native request assets - const nativeRequest = JSON.parse(ortbRequest.imp[0]['native'].request); - expect(nativeRequest).to.not.equal(null); - expect(nativeRequest.assets).to.have.lengthOf(3); - // title asset - expect(nativeRequest.assets[0].id).to.equal(1); - expect(nativeRequest.assets[0].required).to.equal(1); - expect(nativeRequest.assets[0].title).to.not.equal(null); - expect(nativeRequest.assets[0].title.len).to.equal(200); - // data asset - expect(nativeRequest.assets[1].id).to.equal(2); - expect(nativeRequest.assets[1].required).to.equal(0); - expect(nativeRequest.assets[1].title).to.be.undefined; - expect(nativeRequest.assets[1].data).to.not.equal(null); - expect(nativeRequest.assets[1].data.type).to.equal(1); - expect(nativeRequest.assets[1].data.len).to.equal(50); - // image asset - expect(nativeRequest.assets[2].id).to.equal(3); - expect(nativeRequest.assets[2].required).to.equal(0); - expect(nativeRequest.assets[2].title).to.be.undefined; - expect(nativeRequest.assets[2].img).to.not.equal(null); - expect(nativeRequest.assets[2].img.wmin).to.equal(100); - expect(nativeRequest.assets[2].img.hmin).to.equal(150); - expect(nativeRequest.assets[2].img.type).to.equal(3); - }); - - it('Verify Native response', function () { - const request = spec.buildRequests(nativeSlotConfig, bidderRequest); - expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid'); - expect(request.method).to.equal('POST'); - const ortbRequest = request.data; - const nativeResponse = { - 'native': { - assets: [ - { title: { text: 'Ad Title' } }, - { data: { type: 1, value: 'Sponsored By: Brand' } }, - { img: { type: 3, url: 'https://images.cdn.brand.com/123' } } - ], - link: { url: 'https://brand.clickme.com/' }, - imptrackers: ['https://imp1.trackme.com/', 'https://imp1.contextweb.com/'] - } - }; - const ortbResponse = { - seatbid: [{ - bid: [{ - impid: ortbRequest.imp[0].id, - price: 1.25, - adm: JSON.stringify(nativeResponse) - }] - }] - }; - const bids = spec.interpretResponse({ body: ortbResponse }, request); - // verify bid - const bid = bids[0]; - expect(bid.cpm).to.equal(1.25); - expect(bid.adId).to.equal('bid12345'); - expect(bid.ad).to.be.undefined; - expect(bid.mediaType).to.equal('native'); - const nativeBid = bid['native']; - expect(nativeBid).to.not.equal(null); - expect(nativeBid.title).to.equal('Ad Title'); - expect(nativeBid.sponsoredBy).to.equal('Sponsored By: Brand'); - expect(nativeBid.image).to.equal('https://images.cdn.brand.com/123'); - expect(nativeBid.clickUrl).to.equal(encodeURIComponent('https://brand.clickme.com/')); - expect(nativeBid.impressionTrackers).to.have.lengthOf(2); - expect(nativeBid.impressionTrackers[0]).to.equal('https://imp1.trackme.com/'); - expect(nativeBid.impressionTrackers[1]).to.equal('https://imp1.contextweb.com/'); - }); - - it('Verifies bidder code', function () { - expect(spec.code).to.equal('pulsepoint'); - }); - - it('Verifies bidder aliases', function () { - expect(spec.aliases).to.have.lengthOf(2); - expect(spec.aliases[0]).to.equal('pulseLite'); - expect(spec.aliases[1]).to.equal('pulsepointLite'); - }); - - it('Verifies supported media types', function () { - expect(spec.supportedMediaTypes).to.have.lengthOf(3); - expect(spec.supportedMediaTypes[0]).to.equal('banner'); - expect(spec.supportedMediaTypes[1]).to.equal('native'); - expect(spec.supportedMediaTypes[2]).to.equal('video'); - }); - - it('Verifies if bid request valid', function () { - expect(spec.isBidRequestValid(slotConfigs[0])).to.equal(true); - expect(spec.isBidRequestValid(slotConfigs[1])).to.equal(true); - expect(spec.isBidRequestValid(nativeSlotConfig[0])).to.equal(true); - expect(spec.isBidRequestValid({})).to.equal(false); - expect(spec.isBidRequestValid({ params: {} })).to.equal(false); - expect(spec.isBidRequestValid({ params: { ct: 123 } })).to.equal(false); - expect(spec.isBidRequestValid({ params: { cp: 123 } })).to.equal(false); - expect(spec.isBidRequestValid({ params: { ct: 123, cp: 234 } })).to.equal(true); - }); - - it('Verifies sync options', function () { - expect(spec.getUserSyncs({})).to.be.undefined; - expect(spec.getUserSyncs({ iframeEnabled: false })).to.be.undefined; - const options = spec.getUserSyncs({ iframeEnabled: true }); - expect(options).to.not.be.undefined; - expect(options).to.have.lengthOf(1); - expect(options[0].type).to.equal('iframe'); - expect(options[0].url).to.equal('https://bh.contextweb.com/visitormatch'); - }); - - it('Verifies image pixel sync', function () { - const options = spec.getUserSyncs({ pixelEnabled: true }); - expect(options).to.not.be.undefined; - expect(options).to.have.lengthOf(1); - expect(options[0].type).to.equal('image'); - expect(options[0].url).to.equal('https://bh.contextweb.com/visitormatch/prebid'); - }); - - it('Verify app requests', function () { - const request = spec.buildRequests(appSlotConfig, bidderRequest); - const ortbRequest = request.data; - // site object - expect(ortbRequest.site).to.equal(null); - expect(ortbRequest.app).to.not.be.null; - expect(ortbRequest.app.publisher).to.not.equal(null); - expect(ortbRequest.app.publisher.id).to.equal('p10000'); - expect(ortbRequest.app.bundle).to.equal('com.pulsepoint.apps'); - expect(ortbRequest.app.storeurl).to.equal('https://pulsepoint.com/apps'); - expect(ortbRequest.app.domain).to.equal('pulsepoint.com'); - }); - - it('Verify GDPR', function () { - const bidderRequestGdpr = { - gdprConsent: { - gdprApplies: true, - consentString: 'serialized_gpdr_data' - } - }; - const request = spec.buildRequests(slotConfigs, Object.assign({}, bidderRequest, bidderRequestGdpr)); - expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid'); - expect(request.method).to.equal('POST'); - const ortbRequest = request.data; - // user object - expect(ortbRequest.user).to.not.equal(null); - expect(ortbRequest.user.ext).to.not.equal(null); - expect(ortbRequest.user.ext.consent).to.equal('serialized_gpdr_data'); - // regs object - expect(ortbRequest.regs).to.not.equal(null); - expect(ortbRequest.regs.ext).to.not.equal(null); - expect(ortbRequest.regs.ext.gdpr).to.equal(1); - }); - - it('Verify CCPA', function () { - const bidderRequestUSPrivacy = { - uspConsent: '1YYY' - }; - const request = spec.buildRequests(slotConfigs, Object.assign({}, bidderRequest, bidderRequestUSPrivacy)); - expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid'); - expect(request.method).to.equal('POST'); - const ortbRequest = request.data; - // regs object - expect(ortbRequest.regs).to.not.equal(null); - expect(ortbRequest.regs.ext).to.not.equal(null); - expect(ortbRequest.regs.ext.us_privacy).to.equal('1YYY'); - }); - - it('Verify Video request', function () { - const request = spec.buildRequests(videoSlotConfig, bidderRequest); - expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid'); - expect(request.method).to.equal('POST'); - const ortbRequest = request.data; - expect(ortbRequest).to.not.equal(null); - expect(ortbRequest.imp).to.have.lengthOf(1); - expect(ortbRequest.imp[0].video).to.not.be.null; - expect(ortbRequest.imp[0].native).to.be.null; - expect(ortbRequest.imp[0].banner).to.be.null; - expect(ortbRequest.imp[0].video.w).to.equal(400); - expect(ortbRequest.imp[0].video.h).to.equal(300); - expect(ortbRequest.imp[0].video.minduration).to.equal(5); - expect(ortbRequest.imp[0].video.maxduration).to.equal(10); - expect(ortbRequest.imp[0].video.startdelay).to.equal(0); - expect(ortbRequest.imp[0].video.skip).to.equal(1); - expect(ortbRequest.imp[0].video.minbitrate).to.equal(200); - expect(ortbRequest.imp[0].video.protocols).to.eql([1, 2, 4]); - }); - - it('Verify Video response', function () { - const request = spec.buildRequests(videoSlotConfig, bidderRequest); - expect(request.url).to.equal('https://bid.contextweb.com/header/ortb?src=prebid'); - expect(request.method).to.equal('POST'); - const ortbRequest = request.data; - const ortbResponse = { - seatbid: [{ - bid: [{ - impid: ortbRequest.imp[0].id, - price: 1.25, - adm: 'https//pulsepoint.video.mp4' - }] - }] - }; - const bids = spec.interpretResponse({ body: ortbResponse }, request); - const bid = bids[0]; - expect(bid.cpm).to.equal(1.25); - expect(bid.adId).to.equal('bid12345'); - expect(bid.ad).to.be.undefined; - expect(bid['native']).to.be.undefined; - expect(bid.mediaType).to.equal('video'); - expect(bid.vastXml).to.equal(ortbResponse.seatbid[0].bid[0].adm); - }); - - it('Verify extra parameters', function () { - let request = spec.buildRequests(additionalParamsConfig, bidderRequest); - let ortbRequest = request.data; - expect(ortbRequest).to.not.equal(null); - expect(ortbRequest.imp).to.have.lengthOf(1); - expect(ortbRequest.imp[0].ext).to.not.equal(null); - expect(ortbRequest.imp[0].ext.prebid).to.not.equal(null); - expect(ortbRequest.imp[0].ext.prebid).to.not.be.null; - expect(ortbRequest.imp[0].ext.prebid.extra_key1).to.equal('extra_val1'); - expect(ortbRequest.imp[0].ext.prebid.extra_key2).to.equal(12345); - expect(ortbRequest.imp[0].ext.prebid.extra_key3).to.not.be.null; - expect(ortbRequest.imp[0].ext.prebid.extra_key3.key1).to.equal('val1'); - expect(ortbRequest.imp[0].ext.prebid.extra_key3.key2).to.equal(23456); - expect(ortbRequest.imp[0].ext.prebid.extra_key4).to.eql([1, 2, 3]); - expect(Object.keys(ortbRequest.imp[0].ext.prebid)).to.eql(['extra_key1', 'extra_key2', 'extra_key3', 'extra_key4']); - // attempting with a configuration with no unknown params. - request = spec.buildRequests(outstreamSlotConfig, bidderRequest); - ortbRequest = request.data; - expect(ortbRequest).to.not.equal(null); - expect(ortbRequest.imp).to.have.lengthOf(1); - expect(ortbRequest.imp[0].ext).to.equal(null); - }); - - it('Verify ortb parameters', function () { - const request = spec.buildRequests(ortbParamsSlotConfig, bidderRequest); - const ortbRequest = request.data; - expect(ortbRequest).to.not.equal(null); - expect(ortbRequest.bcat).to.eql(['IAB-1', 'IAB-20']); - expect(ortbRequest.badv).to.eql(['cocacola.com', 'lays.com']); - expect(ortbRequest.imp).to.have.lengthOf(2); - expect(ortbRequest.imp[0].bidfloor).to.equal(1.5); - expect(ortbRequest.imp[0].banner.battr).to.eql([1, 2, 3]); - expect(ortbRequest.imp[0].ext).to.be.null; - // slot 2 - expect(ortbRequest.imp[1].bidfloor).to.equal(2.5); - expect(ortbRequest.imp[1].video.battr).to.eql([2, 3, 4]); - expect(ortbRequest.imp[1].ext).to.be.null; - }); - - it('Verify schain parameters', function () { - const request = spec.buildRequests(schainParamsSlotConfig, bidderRequest); - const ortbRequest = request.data; - expect(ortbRequest).to.not.equal(null); - expect(ortbRequest.source).to.not.equal(null); - expect(ortbRequest.source.ext).to.not.equal(null); - expect(ortbRequest.source.ext.schain).to.not.equal(null); - expect(ortbRequest.source.ext.schain.complete).to.equal(1); - expect(ortbRequest.source.ext.schain.ver).to.equal('1.0'); - expect(ortbRequest.source.ext.schain.nodes).to.not.equal(null); - expect(ortbRequest.source.ext.schain.nodes).to.lengthOf(1); - expect(ortbRequest.source.ext.schain.nodes[0].asi).to.equal('exchange1.com'); - expect(ortbRequest.source.ext.schain.nodes[0].sid).to.equal('1234'); - expect(ortbRequest.source.ext.schain.nodes[0].hp).to.equal(1); - expect(ortbRequest.source.ext.schain.nodes[0].rid).to.equal('bid-request-1'); - expect(ortbRequest.source.ext.schain.nodes[0].name).to.equal('publisher'); - expect(ortbRequest.source.ext.schain.nodes[0].domain).to.equal('publisher.com'); - }); - - it('Verify outstream renderer', function () { - const bidderRequestOutstream = Object.assign({}, bidderRequest, {bids: [outstreamSlotConfig[0]]}); - const request = spec.buildRequests(outstreamSlotConfig, bidderRequestOutstream); - const ortbRequest = request.data; - expect(ortbRequest).to.not.be.null; - expect(ortbRequest.imp[0]).to.not.be.null; - expect(ortbRequest.imp[0].video).to.not.be.null; - const ortbResponse = { - seatbid: [{ - bid: [{ - impid: ortbRequest.imp[0].id, - price: 1.25, - adm: 'https//pulsepoint.video.mp4', - ext: { - outstream: { - type: 'Inline', - config: { - text: 'ADVERTISEMENT', - skipaftersec: 5 - }, - rendererUrl: 'https://tag.contextweb.com/hb-outstr-renderer.js' - } - } - }] - }] - }; - const bids = spec.interpretResponse({ body: ortbResponse }, request); - const bid = bids[0]; - expect(bid.cpm).to.equal(1.25); - expect(bid.renderer).to.not.be.null; - expect(bid.renderer.url).to.equal('https://tag.contextweb.com/hb-outstr-renderer.js'); - expect(bid.renderer.getConfig()).to.not.be.null; - expect(bid.renderer.getConfig().defaultOptions).to.eql(ortbResponse.seatbid[0].bid[0].ext.outstream.config); - expect(bid.renderer.getConfig().rendererOptions).to.eql(outstreamSlotConfig[0].renderer.options); - expect(bid.renderer.getConfig().type).to.equal('Inline'); - }); - it('Verify common id parameters', function () { - const bidRequests = deepClone(slotConfigs); - bidRequests[0].userId = { - pubcid: 'userid_pubcid', - tdid: 'userid_ttd', - digitrustid: { - data: { - id: 'userid_digitrust', - keyv: 4, - privacy: {optout: false}, - producer: 'ABC', - version: 2 - } - } - }; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request).to.be.not.null; - const ortbRequest = request.data; - expect(request.data).to.be.not.null; - // user object - expect(ortbRequest.user).to.not.be.undefined; - expect(ortbRequest.user.ext).to.not.be.undefined; - expect(ortbRequest.user.ext.eids).to.not.be.undefined; - expect(ortbRequest.user.ext.eids).to.have.lengthOf(2); - expect(ortbRequest.user.ext.eids[0].source).to.equal('pubcommon'); - expect(ortbRequest.user.ext.eids[0].uids).to.have.lengthOf(1); - expect(ortbRequest.user.ext.eids[0].uids[0].id).to.equal('userid_pubcid'); - expect(ortbRequest.user.ext.eids[1].source).to.equal('adserver.org'); - expect(ortbRequest.user.ext.eids[1].uids).to.have.lengthOf(1); - expect(ortbRequest.user.ext.eids[1].uids[0].id).to.equal('userid_ttd'); - expect(ortbRequest.user.ext.eids[1].uids[0].ext).to.not.be.null; - expect(ortbRequest.user.ext.eids[1].uids[0].ext.rtiPartner).to.equal('TDID'); - expect(ortbRequest.user.ext.digitrust).to.not.be.null; - expect(ortbRequest.user.ext.digitrust.id).to.equal('userid_digitrust'); - expect(ortbRequest.user.ext.digitrust.keyv).to.equal(4); - }); - it('Verify new external user id partners', function () { - const bidRequests = deepClone(slotConfigs); - bidRequests[0].userId = { - britepoolid: 'britepool_id123', - criteoId: 'criteo_id234', - idl_env: 'idl_id123', - id5id: { uid: 'id5id_234' }, - parrableId: { eid: 'parrable_id234' }, - lipb: { - lipbid: 'liveintent_id123' - } - }; - const userVerify = function(obj, source, id) { - expect(obj).to.deep.equal({ - source, - uids: [{ - id - }] - }); - }; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request).to.be.not.null; - const ortbRequest = request.data; - expect(request.data).to.be.not.null; - // user object - expect(ortbRequest.user).to.not.be.undefined; - expect(ortbRequest.user.ext).to.not.be.undefined; - expect(ortbRequest.user.ext.eids).to.not.be.undefined; - expect(ortbRequest.user.ext.eids).to.have.lengthOf(6); - userVerify(ortbRequest.user.ext.eids[0], 'britepool.com', 'britepool_id123'); - userVerify(ortbRequest.user.ext.eids[1], 'criteo', 'criteo_id234'); - userVerify(ortbRequest.user.ext.eids[2], 'identityLink', 'idl_id123'); - userVerify(ortbRequest.user.ext.eids[3], 'id5-sync.com', 'id5id_234'); - userVerify(ortbRequest.user.ext.eids[4], 'parrable.com', 'parrable_id234'); - userVerify(ortbRequest.user.ext.eids[5], 'liveintent.com', 'liveintent_id123'); - }); - it('Verify multiple adsizes', function () { - const bidRequests = deepClone(slotConfigs); - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request).to.be.not.null; - expect(request.data).to.be.not.null; - const ortbRequest = request.data; - expect(ortbRequest.imp).to.have.lengthOf(2); - // first impression has multi sizes - expect(ortbRequest.imp[0].banner).to.not.be.null; - expect(ortbRequest.imp[0].banner.w).to.equal(300); - expect(ortbRequest.imp[0].banner.h).to.equal(250); - expect(ortbRequest.imp[0].banner.format).to.not.be.null; - expect(ortbRequest.imp[0].banner.format).to.have.lengthOf(2); - expect(ortbRequest.imp[0].banner.format[0].w).to.equal(728); - expect(ortbRequest.imp[0].banner.format[0].h).to.equal(90); - expect(ortbRequest.imp[0].banner.format[1].w).to.equal(160); - expect(ortbRequest.imp[0].banner.format[1].h).to.equal(600); - // slot 2 - expect(ortbRequest.imp[1].banner).to.not.be.null; - expect(ortbRequest.imp[1].banner.w).to.equal(728); - expect(ortbRequest.imp[1].banner.h).to.equal(90); - expect(ortbRequest.imp[1].banner.format).to.not.be.null; - expect(ortbRequest.imp[1].banner.format).to.have.lengthOf(1); - expect(ortbRequest.imp[1].banner.format[0].w).to.equal(728); - expect(ortbRequest.imp[1].banner.format[0].h).to.equal(90); - // adsize on response - const ortbResponse = { - seatbid: [{ - bid: [{ - impid: ortbRequest.imp[0].id, - price: 1.25, - adm: 'This is an Ad', - crid: 'Creative#123', - w: 728, - h: 90 - }] - }] - }; - const bids = spec.interpretResponse({ body: ortbResponse }, request); - expect(bids).to.have.lengthOf(1); - const bid = bids[0]; - expect(bid.width).to.equal(728); - expect(bid.height).to.equal(90); - }); - it('Verify multi-format response', function () { - const bidRequests = deepClone(slotConfigs); - bidRequests[0].mediaTypes['native'] = { - title: { - required: true - }, - image: { - required: true - }, - sponsoredBy: { - required: true - } - }; - bidRequests[1].params.video = { - w: 400, - h: 300, - minduration: 5, - maxduration: 10, - }; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request).to.be.not.null; - expect(request.data).to.be.not.null; - const ortbRequest = request.data; - expect(ortbRequest.imp).to.have.lengthOf(2); - // adsize on response - const ortbResponse = { - seatbid: [{ - bid: [{ - impid: ortbRequest.imp[0].id, - price: 1.25, - adm: 'This is an Ad', - crid: 'Creative#123', - w: 728, - h: 90 - }, { - impid: ortbRequest.imp[1].id, - price: 2.5, - adm: '', - crid: 'Creative#234', - w: 728, - h: 90 - }] - }] - }; - // request has both types - banner and native, response is parsed as banner. - // for impression#2, response is parsed as video - const bids = spec.interpretResponse({ body: ortbResponse }, request); - expect(bids).to.have.lengthOf(2); - const bid = bids[0]; - expect(bid.width).to.equal(728); - expect(bid.height).to.equal(90); - const secondBid = bids[1]; - expect(secondBid.vastXml).to.equal(''); - }); -}); diff --git a/test/spec/modules/pxyzBidAdapter_spec.js b/test/spec/modules/pxyzBidAdapter_spec.js deleted file mode 100644 index 6d8c6056076..00000000000 --- a/test/spec/modules/pxyzBidAdapter_spec.js +++ /dev/null @@ -1,235 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/pxyzBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import { deepClone } from 'src/utils.js'; - -const URL = 'https://ads.playground.xyz/host-config/prebid?v=2'; -const GDPR_CONSENT = 'XYZ-CONSENT'; - -const BIDDER_REQUEST = { - refererInfo: { - referer: 'https://example.com' - } -}; - -describe('pxyzBidAdapter', 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 () { - let bid = { - 'bidder': 'pxyz', - 'params': { - 'placementId': '10433394' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [320, 50]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'placementId': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [ - { - 'bidder': 'pxyz', - 'params': { - 'placementId': '10433394' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - it('sends bid request to ENDPOINT via POST', function () { - const request = spec.buildRequests(bidRequests, BIDDER_REQUEST); - const data = JSON.parse(request.data); - const banner = data.imp[0].banner; - - 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(request.url).to.equal(URL); - expect(request.method).to.equal('POST'); - }); - - describe('CCPA', function () { - describe('when USP consent object is NOT present in bidder request', function () { - const request = spec.buildRequests(bidRequests, BIDDER_REQUEST); - const data = JSON.parse(request.data); - it('should not populate ext.gdpr or ext.consent', function () { - expect(data).to.not.have.property('Regs.ext.us_privacy'); - }); - }); - - describe('when USP consent object is present in bidder request', function () { - describe('when GDPR is applicable', function () { - const request = spec.buildRequests( - bidRequests, - Object.assign({}, BIDDER_REQUEST, { uspConsent: '1YYY' }) - ); - const data = JSON.parse(request.data); - it('should set Regs.ext.us_privacy with the correct value', function () { - expect(data.Regs.ext['us_privacy']).to.equal('1YYY'); - }); - }); - }); - }); - - describe('GDPR', function () { - describe('when no GDPR consent object is present in bidder request', function () { - const request = spec.buildRequests(bidRequests, BIDDER_REQUEST); - const data = JSON.parse(request.data); - it('should not populate ext.gdpr or ext.consent', function () { - expect(data).to.not.have.property('Regs.ext.consent'); - }); - }); - - describe('when GDPR consent object is present in bidder request', function () { - describe('when GDPR is applicable', function () { - const request = spec.buildRequests( - bidRequests, - Object.assign({}, BIDDER_REQUEST, { - gdprConsent: { gdprApplies: true, consentString: GDPR_CONSENT } - }) - ); - const data = JSON.parse(request.data); - it('should set ext.gdpr with 1', function () { - expect(data.Regs.ext.gdpr).to.equal(1); - }); - it('should set ext.consent', function () { - expect(data.User.ext.consent).to.equal('XYZ-CONSENT'); - }); - }); - describe('when GDPR is NOT applicable', function () { - const request = spec.buildRequests( - bidRequests, - Object.assign({}, BIDDER_REQUEST, { - gdprConsent: { gdprApplies: false, consentString: GDPR_CONSENT } - }) - ); - const data = JSON.parse(request.data); - it('should set ext.gdpr to 0', function () { - expect(data.Regs.ext.gdpr).to.equal(0); - }); - it('should populate ext.consent', function () { - expect(data.User.ext.consent).to.equal('XYZ-CONSENT'); - }); - }); - }); - }); - }) - - describe('interpretResponse', function () { - let response = { - 'id': 'bidd_id', - 'seatbid': [ { - 'bid': [ - { - 'id': '4434762738980910431', - 'impid': '221f2bdc1fbc31', - 'price': 1, - 'adid': '91673066', - 'adm': '', - 'adomain': [ 'pg.xyz' ], - 'iurl': 'http://pgxyz.com/cr?id=91673066', - 'cid': 'c_id', - 'crid': 'c_rid', - 'h': 50, - 'w': 320, - 'ext': { - 'appnexus': { - 'brand_id': 1, - 'auction_id': 1087655594852566000, - 'bidder_id': 2, - 'bid_ad_type': 0 - } - } - } - ], - 'seat': '4321' - }], - 'bidid': '6894227111893743356', - 'cur': 'AUD' - }; - - let bidderRequest = { - 'bidderCode': 'pxyz' - }; - - it('should get correct bid response', function () { - let expectedResponse = [ - { - 'requestId': '221f2bdc1fbc31', - 'cpm': 1, - 'creativeId': 91673066, - 'width': 300, - 'height': 50, - 'ad': '', - 'mediaType': 'banner', - 'currency': 'AUD', - 'ttl': 300, - 'netRevenue': true - } - ]; - let result = spec.interpretResponse({ body: response }, {bidderRequest}); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('handles nobid response', function () { - const response = undefined; - let result = spec.interpretResponse({ body: response }, {bidderRequest}); - expect(result.length).to.equal(0); - }); - }); - - describe('getUserSyncs', function () { - const syncUrl = '//ib.adnxs.com/getuidnb?https://ads.playground.xyz/usersync?partner=appnexus&uid=$UID'; - - describe('when iframeEnabled is true', function () { - const syncOptions = { - 'iframeEnabled': true - } - it('should return one image type user sync pixel', function () { - let result = spec.getUserSyncs(syncOptions); - expect(result.length).to.equal(1); - expect(result[0].type).to.equal('image') - expect(result[0].url).to.equal(syncUrl); - }); - }); - - describe('when iframeEnabled is false', function () { - const syncOptions = { - 'iframeEnabled': false - } - it('should return one image type user sync pixel', function () { - let result = spec.getUserSyncs(syncOptions); - expect(result.length).to.equal(1); - expect(result[0].type).to.equal('image') - expect(result[0].url).to.equal(syncUrl); - }); - }); - }) -}); diff --git a/test/spec/modules/quantcastBidAdapter_spec.js b/test/spec/modules/quantcastBidAdapter_spec.js deleted file mode 100644 index 5b4e7963e60..00000000000 --- a/test/spec/modules/quantcastBidAdapter_spec.js +++ /dev/null @@ -1,844 +0,0 @@ -import { expect } from 'chai'; -import { - QUANTCAST_DOMAIN, - QUANTCAST_TEST_DOMAIN, - QUANTCAST_NET_REVENUE, - QUANTCAST_TTL, - QUANTCAST_TEST_PUBLISHER, - QUANTCAST_PROTOCOL, - QUANTCAST_PORT, - spec as qcSpec, - storage -} from '../../../modules/quantcastBidAdapter.js'; -import { newBidder } from '../../../src/adapters/bidderFactory.js'; -import { parseUrl } from 'src/utils.js'; -import { config } from 'src/config.js'; - -describe('Quantcast adapter', function () { - const quantcastAdapter = newBidder(qcSpec); - let bidRequest; - let bidderRequest; - - beforeEach(function () { - bidRequest = { - bidder: 'quantcast', - bidId: '2f7b179d443f14', - auctionId: '595ffa73-d78a-46c9-b18e-f99548a5be6b', - bidderRequestId: '1cc026909c24c8', - placementCode: 'div-gpt-ad-1438287399331-0', - params: { - publisherId: QUANTCAST_TEST_PUBLISHER, // REQUIRED - Publisher ID provided by Quantcast - battr: [1, 2] // OPTIONAL - Array of blocked creative attributes as per OpenRTB Spec List 5.3 - }, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - } - }; - - bidderRequest = { - refererInfo: { - referer: 'http://example.com/hello.html', - canonicalUrl: 'http://example.com/hello.html' - } - }; - - storage.setCookie('__qca', '', 'Thu, 01 Jan 1970 00:00:00 GMT'); - }); - - function setupVideoBidRequest(videoParams) { - bidRequest.params = { - publisherId: 'test-publisher', // REQUIRED - Publisher ID provided by Quantcast - // Video object as specified in OpenRTB 2.5 - video: videoParams - }; - bidRequest['mediaTypes'] = { - video: { - context: 'instream', - playerSize: [600, 300] - } - } - }; - - describe('inherited functions', function () { - it('exists and is a function', function () { - expect(quantcastAdapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('`isBidRequestValid`', function () { - it('should return `true` when bid has publisherId', function () { - const bidRequest = { - bidder: 'quantcast', - params: { - publisherId: 'my_publisher_id' - } - }; - - expect(qcSpec.isBidRequestValid(bidRequest)).to.equal(true); - }); - - it('should return `false` when bid has no publisherId', function () { - const bidRequest = { - bidder: 'quantcast', - params: { - } - }; - - expect(qcSpec.isBidRequestValid(bidRequest)).to.equal(false); - }); - }); - - describe('`buildRequests`', function () { - it('sends secure bid requests', function () { - const requests = qcSpec.buildRequests([bidRequest]); - const url = parseUrl(requests[0]['url']); - expect(url.protocol).to.equal('https'); - }); - - it('sends bid requests to Quantcast Canary Endpoint if `publisherId` is `test-publisher`', function () { - const requests = qcSpec.buildRequests([bidRequest]); - const url = parseUrl(requests[0]['url']); - expect(url.hostname).to.equal(QUANTCAST_TEST_DOMAIN); - }); - - it('sends bid requests to default endpoint for non standard publisher IDs', function () { - const modifiedBidRequest = Object.assign({}, bidRequest, { - params: Object.assign({}, bidRequest.params, { - publisherId: 'foo-bar', - }), - }); - const requests = qcSpec.buildRequests([modifiedBidRequest]); - expect(requests[0]['url']).to.equal( - `${QUANTCAST_PROTOCOL}://${QUANTCAST_DOMAIN}:${QUANTCAST_PORT}/qchb` - ); - }); - - it('sends bid requests to Quantcast Header Bidding Endpoints via POST', function () { - const requests = qcSpec.buildRequests([bidRequest]); - - expect(requests[0].method).to.equal('POST'); - }); - - const expectedBannerBidRequest = { - publisherId: QUANTCAST_TEST_PUBLISHER, - requestId: '2f7b179d443f14', - imp: [ - { - banner: { - battr: [1, 2], - sizes: [{ width: 300, height: 250 }] - }, - placementCode: 'div-gpt-ad-1438287399331-0', - bidFloor: 1e-10 - } - ], - site: { - page: 'http://example.com/hello.html', - referrer: 'http://example.com/hello.html', - domain: 'example.com' - }, - bidId: '2f7b179d443f14', - gdprSignal: 0, - uspSignal: 0, - coppa: 0, - prebidJsVersion: '$prebid.version$', - fpa: '' - }; - - it('sends banner bid requests contains all the required parameters', function () { - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - - expect(requests[0].data).to.equal(JSON.stringify(expectedBannerBidRequest)); - }); - - it('supports deprecated banner format', function () { - bidRequest.sizes = bidRequest.mediaTypes.banner.sizes; - delete bidRequest.mediaTypes; - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - - expect(requests[0].data).to.equal(JSON.stringify(expectedBannerBidRequest)); - }); - - it('sends video bid requests containing all the required parameters', function () { - setupVideoBidRequest({ - mimes: ['video/mp4'], // required - minduration: 3, // optional - maxduration: 5, // optional - protocols: [3], // optional - startdelay: 1, // optional - linearity: 1, // optinal - battr: [1, 2], // optional - maxbitrate: 10, // optional - playbackmethod: [1], // optional - delivery: [1], // optional - placement: 1, // optional - api: [2, 3] // optional - }); - - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - const expectedVideoBidRequest = { - publisherId: QUANTCAST_TEST_PUBLISHER, - requestId: '2f7b179d443f14', - imp: [ - { - video: { - mimes: ['video/mp4'], - minduration: 3, - maxduration: 5, - protocols: [3], - startdelay: 1, - linearity: 1, - battr: [1, 2], - maxbitrate: 10, - playbackmethod: [1], - delivery: [1], - placement: 1, - api: [2, 3], - w: 600, - h: 300 - }, - placementCode: 'div-gpt-ad-1438287399331-0', - bidFloor: 1e-10 - } - ], - site: { - page: 'http://example.com/hello.html', - referrer: 'http://example.com/hello.html', - domain: 'example.com' - }, - bidId: '2f7b179d443f14', - gdprSignal: 0, - uspSignal: 0, - coppa: 0, - prebidJsVersion: '$prebid.version$', - fpa: '' - }; - - expect(requests[0].data).to.equal(JSON.stringify(expectedVideoBidRequest)); - }); - - it('overrides video parameters with parameters from adunit', function() { - setupVideoBidRequest({ - mimes: ['video/mp4'] - }); - bidRequest.mediaTypes.video.mimes = ['video/webm']; - - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - const expectedVideoBidRequest = { - publisherId: QUANTCAST_TEST_PUBLISHER, - requestId: '2f7b179d443f14', - imp: [ - { - video: { - mimes: ['video/webm'], - w: 600, - h: 300 - }, - placementCode: 'div-gpt-ad-1438287399331-0', - bidFloor: 1e-10 - } - ], - site: { - page: 'http://example.com/hello.html', - referrer: 'http://example.com/hello.html', - domain: 'example.com' - }, - bidId: '2f7b179d443f14', - gdprSignal: 0, - uspSignal: 0, - coppa: 0, - prebidJsVersion: '$prebid.version$', - fpa: '' - }; - - expect(requests[0].data).to.equal(JSON.stringify(expectedVideoBidRequest)); - }); - - it('sends video bid request when no video parameters are given', function () { - setupVideoBidRequest(null); - - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - const expectedVideoBidRequest = { - publisherId: QUANTCAST_TEST_PUBLISHER, - requestId: '2f7b179d443f14', - imp: [ - { - video: { - w: 600, - h: 300 - }, - placementCode: 'div-gpt-ad-1438287399331-0', - bidFloor: 1e-10 - } - ], - site: { - page: 'http://example.com/hello.html', - referrer: 'http://example.com/hello.html', - domain: 'example.com' - }, - bidId: '2f7b179d443f14', - gdprSignal: 0, - uspSignal: 0, - coppa: 0, - prebidJsVersion: '$prebid.version$', - fpa: '' - }; - - expect(requests[0].data).to.equal(JSON.stringify(expectedVideoBidRequest)); - }); - - it('ignores unsupported video bid requests', function () { - bidRequest.mediaTypes = { - video: { - context: 'outstream', - playerSize: [[550, 310]] - } - }; - - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - - expect(requests).to.be.empty; - }); - - it('parses multi-format bid request', function () { - bidRequest.mediaTypes = { - 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]} - }, - video: { - context: 'outstream', - playerSize: [[550, 310]] - } - }; - - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - const expectedBidRequest = { - publisherId: QUANTCAST_TEST_PUBLISHER, - requestId: '2f7b179d443f14', - imp: [{ - 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} - ] - }, - placementCode: 'div-gpt-ad-1438287399331-0', - bidFloor: 1e-10 - }], - site: { - page: 'http://example.com/hello.html', - referrer: 'http://example.com/hello.html', - domain: 'example.com' - }, - bidId: '2f7b179d443f14', - gdprSignal: 0, - uspSignal: 0, - coppa: 0, - prebidJsVersion: '$prebid.version$', - fpa: '' - }; - - expect(requests[0].data).to.equal(JSON.stringify(expectedBidRequest)); - }); - }); - - it('propagates GDPR consent string and signal', function () { - const bidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString: 'consentString' - } - }; - - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - const parsed = JSON.parse(requests[0].data); - - expect(parsed.gdprSignal).to.equal(1); - expect(parsed.gdprConsent).to.equal('consentString'); - }); - - it('allows TCF v1 request with consent for purpose 1', function () { - const bidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString: 'consentString', - vendorData: { - vendorConsents: { - '11': true - }, - purposeConsents: { - '1': true - } - }, - apiVersion: 1 - } - }; - - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - const parsed = JSON.parse(requests[0].data); - - expect(parsed.gdprSignal).to.equal(1); - expect(parsed.gdprConsent).to.equal('consentString'); - }); - - it('blocks TCF v1 request without vendor consent', function () { - const bidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString: 'consentString', - vendorData: { - vendorConsents: { - '11': false - }, - purposeConsents: { - '1': true - } - }, - apiVersion: 1 - } - }; - - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - - expect(requests).to.equal(undefined); - }); - - it('blocks TCF v1 request without consent for purpose 1', function () { - const bidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString: 'consentString', - vendorData: { - vendorConsents: { - '11': true - }, - purposeConsents: { - '1': false - } - }, - apiVersion: 1 - } - }; - - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - - expect(requests).to.equal(undefined); - }); - - it('allows TCF v2 request when Quantcast has consent for purpose 1', function() { - const bidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString: 'consentString', - vendorData: { - vendor: { - consents: { - '11': true - } - }, - purpose: { - consents: { - '1': true - } - } - }, - apiVersion: 2 - } - }; - - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - const parsed = JSON.parse(requests[0].data); - - expect(parsed.gdprSignal).to.equal(1); - expect(parsed.gdprConsent).to.equal('consentString'); - }); - - it('blocks TCF v2 request when no consent for Quantcast', function() { - const bidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString: 'consentString', - vendorData: { - vendor: { - consents: { - '11': false - } - }, - purpose: { - consents: { - '1': true - } - } - }, - apiVersion: 2 - } - }; - - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - - expect(requests).to.equal(undefined); - }); - - it('blocks TCF v2 request when no consent for purpose 1', function() { - const bidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString: 'consentString', - vendorData: { - vendor: { - consents: { - '11': true - } - }, - purpose: { - consents: { - '1': false - } - } - }, - apiVersion: 2 - } - }; - - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - - expect(requests).to.equal(undefined); - }); - - it('blocks TCF v2 request when Quantcast not allowed by publisher', function () { - const bidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString: 'consentString', - vendorData: { - vendor: { - consents: { - '11': true - } - }, - purpose: { - consents: { - '1': true - } - }, - publisher: { - restrictions: { - '1': { - '11': 0 - } - } - } - }, - apiVersion: 2 - } - }; - - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - - expect(requests).to.equal(undefined); - }); - - it('blocks TCF v2 request when legitimate interest required', function () { - const bidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString: 'consentString', - vendorData: { - vendor: { - consents: { - '11': true - } - }, - purpose: { - consents: { - '1': true - } - }, - publisher: { - restrictions: { - '1': { - '11': 2 - } - } - } - }, - apiVersion: 2 - } - }; - - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - - expect(requests).to.equal(undefined); - }); - - it('propagates US Privacy/CCPA consent information', function () { - const bidderRequest = { uspConsent: 'consentString' } - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - const parsed = JSON.parse(requests[0].data); - expect(parsed.uspSignal).to.equal(1); - expect(parsed.uspConsent).to.equal('consentString'); - }); - - it('propagates Quantcast first-party cookie (fpa)', function() { - storage.setCookie('__qca', 'P0-TestFPA'); - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - const parsed = JSON.parse(requests[0].data); - expect(parsed.fpa).to.equal('P0-TestFPA'); - }); - - describe('propagates coppa', function() { - let sandbox; - beforeEach(() => { - sandbox = sinon.sandbox.create(); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('propagates coppa as 1 if coppa param is set to true in the bid request', function () { - bidRequest.params = { - publisherId: 'test_publisher_id', - coppa: true - }; - sandbox.stub(config, 'getConfig').callsFake((key) => { - const config = { - 'coppa': true - }; - return config[key]; - }); - const requests = qcSpec.buildRequests([bidRequest], bidderRequest); - expect(JSON.parse(requests[0].data).coppa).to.equal(1); - }); - - it('propagates coppa as 0 if there is no coppa param or coppa is set to false in the bid request', function () { - const requestsWithoutCoppa = qcSpec.buildRequests([bidRequest], bidderRequest); - expect(JSON.parse(requestsWithoutCoppa[0].data).coppa).to.equal(0); - - bidRequest.params = { - publisherId: 'test_publisher_id', - coppa: false - }; - sandbox.stub(config, 'getConfig').callsFake((key) => { - const config = { - 'coppa': false - }; - return config[key]; - }); - const requestsWithFalseCoppa = qcSpec.buildRequests([bidRequest], bidderRequest); - expect(JSON.parse(requestsWithFalseCoppa[0].data).coppa).to.equal(0); - }); - }); - - describe('`interpretResponse`', function () { - // The sample response is from https://wiki.corp.qc/display/adinf/QCX - const body = { - bidderCode: 'qcx', // Renaming it to use CamelCase since that is what is used in the Prebid.js variable name - requestId: 'erlangcluster@qa-rtb002.us-ec.adtech.com-11417780270886458', // Added this field. This is not used now but could be useful in troubleshooting later on. Specially for sites using iFrames - bids: [ - { - statusCode: 1, - placementCode: 'imp1', // Changing this to placementCode to be reflective - cpm: 4.5, - currency: 'USD', - ad: - '
Quantcast
', - creativeId: 1001, - width: 300, - height: 250 - } - ] - }; - - const response = { - body, - headers: {} - }; - - const videoBody = { - bidderCode: 'qcx', - requestId: 'erlangcluster@qa-rtb002.us-ec.adtech.com-11417780270886458', - bids: [ - { - statusCode: 1, - placementCode: 'video1', - cpm: 4.5, - currency: 'USD', - videoUrl: 'https://vast.quantserve.com/vast?p=&r=&gdpr=&gdpr_consent=&rand=1337&d=H4sIAAAAAAAAAONi4mIQcrzFqGLi5OzibOzmpGtm4eyia-LoaqDraGRupOtobGJhYuni6GRiYLmLiYWrp5f_BBPDDybGScxcPs7-aRYmpmVVoVJgCSXBkozMYl0gKslI1S1Izk9JBQALkFy_YAAAAA&h=uRnsTjyXbOrXJtBQiaMn239i9GI', - width: 600, - height: 300 - } - ] - }; - - const videoResponse = { - body: videoBody, - headers: {} - }; - - it('should return an empty array if `serverResponse` is `undefined`', function () { - const interpretedResponse = qcSpec.interpretResponse(); - - expect(interpretedResponse.length).to.equal(0); - }); - - it('should return an empty array if the parsed response does NOT include `bids`', function () { - const interpretedResponse = qcSpec.interpretResponse({}); - - expect(interpretedResponse.length).to.equal(0); - }); - - it('should return an empty array if the parsed response has an empty `bids`', function () { - const interpretedResponse = qcSpec.interpretResponse({ bids: [] }); - - expect(interpretedResponse.length).to.equal(0); - }); - - it('should get correct bid response', function () { - const expectedResponse = { - requestId: 'erlangcluster@qa-rtb002.us-ec.adtech.com-11417780270886458', - cpm: 4.5, - width: 300, - height: 250, - ad: - '
Quantcast
', - ttl: QUANTCAST_TTL, - creativeId: 1001, - netRevenue: QUANTCAST_NET_REVENUE, - currency: 'USD' - }; - const interpretedResponse = qcSpec.interpretResponse(response); - - expect(interpretedResponse[0]).to.deep.equal(expectedResponse); - }); - - it('should include dealId in bid response', function () { - response.body.bids[0].dealId = 'test-dealid'; - const expectedResponse = { - requestId: 'erlangcluster@qa-rtb002.us-ec.adtech.com-11417780270886458', - cpm: 4.5, - width: 300, - height: 250, - ad: - '
Quantcast
', - ttl: QUANTCAST_TTL, - creativeId: 1001, - netRevenue: QUANTCAST_NET_REVENUE, - currency: 'USD', - dealId: 'test-dealid' - }; - const interpretedResponse = qcSpec.interpretResponse(response); - - expect(interpretedResponse[0]).to.deep.equal(expectedResponse); - }); - - it('should get correct bid response for instream video', function() { - const expectedResponse = { - requestId: 'erlangcluster@qa-rtb002.us-ec.adtech.com-11417780270886458', - cpm: 4.5, - width: 600, - height: 300, - vastUrl: 'https://vast.quantserve.com/vast?p=&r=&gdpr=&gdpr_consent=&rand=1337&d=H4sIAAAAAAAAAONi4mIQcrzFqGLi5OzibOzmpGtm4eyia-LoaqDraGRupOtobGJhYuni6GRiYLmLiYWrp5f_BBPDDybGScxcPs7-aRYmpmVVoVJgCSXBkozMYl0gKslI1S1Izk9JBQALkFy_YAAAAA&h=uRnsTjyXbOrXJtBQiaMn239i9GI', - mediaType: 'video', - ttl: QUANTCAST_TTL, - creativeId: undefined, - ad: undefined, - netRevenue: QUANTCAST_NET_REVENUE, - currency: 'USD' - }; - const interpretedResponse = qcSpec.interpretResponse(videoResponse); - - expect(interpretedResponse[0]).to.deep.equal(expectedResponse); - }); - - it('handles no bid response', function () { - const body = { - bidderCode: 'qcx', // Renaming it to use CamelCase since that is what is used in the Prebid.js variable name - requestId: 'erlangcluster@qa-rtb002.us-ec.adtech.com-11417780270886458', // Added this field. This is not used now but could be useful in troubleshooting later on. Specially for sites using iFrames - bids: [] - }; - const response = { - body, - headers: {} - }; - const interpretedResponse = qcSpec.interpretResponse(response); - - expect(interpretedResponse.length).to.equal(0); - }); - - it('should return pixel url when available userSync available', function () { - const syncOptions = { - pixelEnabled: true - }; - const serverResponses = [ - { - body: { - userSync: { - url: 'http://quantcast.com/pixelUrl' - } - } - }, - { - body: { - - } - } - ]; - - const actualSyncs = qcSpec.getUserSyncs(syncOptions, serverResponses); - const expectedSync = { - type: 'image', - url: 'http://quantcast.com/pixelUrl' - }; - expect(actualSyncs.length).to.equal(1); - expect(actualSyncs[0]).to.deep.equal(expectedSync); - qcSpec.resetUserSync(); - }); - - it('should not return user syncs if done already', function () { - const syncOptions = { - pixelEnabled: true - }; - const serverResponses = [ - { - body: { - userSync: { - url: 'http://quantcast.com/pixelUrl' - } - } - }, - { - body: { - - } - } - ]; - - let actualSyncs = qcSpec.getUserSyncs(syncOptions, serverResponses); - const expectedSync = { - type: 'image', - url: 'http://quantcast.com/pixelUrl' - }; - expect(actualSyncs.length).to.equal(1); - expect(actualSyncs[0]).to.deep.equal(expectedSync); - - actualSyncs = qcSpec.getUserSyncs(syncOptions, serverResponses); - expect(actualSyncs.length).to.equal(0); - - qcSpec.resetUserSync(); - }); - }); -}); diff --git a/test/spec/modules/quantcastIdSystem_spec.js b/test/spec/modules/quantcastIdSystem_spec.js deleted file mode 100644 index 12c8689fd3f..00000000000 --- a/test/spec/modules/quantcastIdSystem_spec.js +++ /dev/null @@ -1,19 +0,0 @@ -import { quantcastIdSubmodule, storage } from 'modules/quantcastIdSystem.js'; - -describe('QuantcastId module', function () { - beforeEach(function() { - storage.setCookie('__qca', '', 'Thu, 01 Jan 1970 00:00:00 GMT'); - }); - - it('getId() should return a quantcast id when the Quantcast first party cookie exists', function () { - storage.setCookie('__qca', 'P0-TestFPA'); - - const id = quantcastIdSubmodule.getId(); - expect(id).to.be.deep.equal({id: {quantcastId: 'P0-TestFPA'}}); - }); - - 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}); - }); -}); diff --git a/test/spec/modules/qwarryBidAdapter_spec.js b/test/spec/modules/qwarryBidAdapter_spec.js deleted file mode 100644 index 06d4af0756c..00000000000 --- a/test/spec/modules/qwarryBidAdapter_spec.js +++ /dev/null @@ -1,148 +0,0 @@ -import { expect } from 'chai' -import { ENDPOINT, spec } from 'modules/qwarryBidAdapter.js' -import { newBidder } from 'src/adapters/bidderFactory.js' - -const REQUEST = { - 'bidId': '456', - 'bidder': 'qwarry', - 'sizes': [[100, 200], [300, 400]], - 'params': { - zoneToken: 'e64782a4-8e68-4c38-965b-80ccf115d46f', - pos: 7 - } -} - -const BIDDER_BANNER_RESPONSE = { - 'prebidResponse': [{ - 'ad': '
test
', - 'requestId': 'e64782a4-8e68-4c38-965b-80ccf115d46d', - 'cpm': 900.5, - 'currency': 'USD', - 'width': 640, - 'height': 480, - 'ttl': 300, - 'creativeId': 1, - 'netRevenue': true, - 'winUrl': 'http://test.com', - 'format': 'banner' - }] -} - -const BIDDER_VIDEO_RESPONSE = { - 'prebidResponse': [{ - 'ad': 'vast', - 'requestId': 'e64782a4-8e68-4c38-965b-80ccf115d46z', - 'cpm': 800.4, - 'currency': 'USD', - 'width': 1024, - 'height': 768, - 'ttl': 200, - 'creativeId': 2, - 'netRevenue': true, - 'winUrl': 'http://test.com', - 'format': 'video' - }] -} - -const BIDDER_NO_BID_RESPONSE = '' - -describe('qwarryBidAdapter', 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 () { - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(REQUEST)).to.equal(true) - }) - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, REQUEST) - delete bid.params.zoneToken - expect(spec.isBidRequestValid(bid)).to.equal(false) - delete bid.params - expect(spec.isBidRequestValid(bid)).to.equal(false) - }) - }) - - describe('buildRequests', function () { - let bidRequests = [REQUEST] - const bidderRequest = spec.buildRequests(bidRequests, { - bidderRequestId: '123', - gdprConsent: { - gdprApplies: true, - consentString: 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==' - }, - refererInfo: { - referer: 'http://test.com/path.html' - } - }) - - it('sends bid request to ENDPOINT via POST', 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.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 }) - expect(bidderRequest.options.contentType).to.equal('application/json') - expect(bidderRequest.url).to.equal(ENDPOINT) - }) - }) - - describe('interpretResponse', function () { - it('handles banner request : should get correct bid response', function () { - const result = spec.interpretResponse({ body: BIDDER_BANNER_RESPONSE }, {}) - - expect(result[0]).to.have.property('ad').equal('
test
') - expect(result[0]).to.have.property('requestId').equal('e64782a4-8e68-4c38-965b-80ccf115d46d') - expect(result[0]).to.have.property('cpm').equal(900.5) - expect(result[0]).to.have.property('currency').equal('USD') - expect(result[0]).to.have.property('width').equal(640) - expect(result[0]).to.have.property('height').equal(480) - expect(result[0]).to.have.property('ttl').equal(300) - expect(result[0]).to.have.property('creativeId').equal(1) - expect(result[0]).to.have.property('netRevenue').equal(true) - expect(result[0]).to.have.property('winUrl').equal('http://test.com') - expect(result[0]).to.have.property('format').equal('banner') - }) - - it('handles video request : should get correct bid response', function () { - const result = spec.interpretResponse({ body: BIDDER_VIDEO_RESPONSE }, {}) - - expect(result[0]).to.have.property('ad').equal('vast') - expect(result[0]).to.have.property('requestId').equal('e64782a4-8e68-4c38-965b-80ccf115d46z') - expect(result[0]).to.have.property('cpm').equal(800.4) - expect(result[0]).to.have.property('currency').equal('USD') - expect(result[0]).to.have.property('width').equal(1024) - expect(result[0]).to.have.property('height').equal(768) - expect(result[0]).to.have.property('ttl').equal(200) - expect(result[0]).to.have.property('creativeId').equal(2) - expect(result[0]).to.have.property('netRevenue').equal(true) - expect(result[0]).to.have.property('winUrl').equal('http://test.com') - expect(result[0]).to.have.property('format').equal('video') - expect(result[0]).to.have.property('vastXml').equal('vast') - }) - - it('handles no bid response : should get empty array', function () { - let result = spec.interpretResponse({ body: undefined }, {}) - expect(result).to.deep.equal([]) - - result = spec.interpretResponse({ body: BIDDER_NO_BID_RESPONSE }, {}) - expect(result).to.deep.equal([]) - }) - }) - - describe('onBidWon', function () { - it('handles banner win: should get true', function () { - const win = BIDDER_BANNER_RESPONSE.prebidResponse[0] - const bidWonResult = spec.onBidWon(win) - - expect(bidWonResult).to.equal(true) - }) - }) -}) diff --git a/test/spec/modules/radsBidAdapter_spec.js b/test/spec/modules/radsBidAdapter_spec.js deleted file mode 100644 index c3c3b4b2746..00000000000 --- a/test/spec/modules/radsBidAdapter_spec.js +++ /dev/null @@ -1,289 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/radsBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -const RADS_ENDPOINT_URL = 'https://rads.recognified.net/md.request.php'; - -describe('radsAdapter', function () { - const adapter = newBidder(spec); - - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'rads', - 'params': { - 'placement': '6682', - 'pfilter': { - 'floorprice': 1000000 - }, - 'bcat': 'IAB2,IAB4', - 'dvt': 'desktop', - 'ip': '1.1.1.1' - }, - 'sizes': [ - [300, 250] - ], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'someIncorrectParam': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [{ - 'bidder': 'rads', - 'params': { - 'placement': '6682', - 'pfilter': { - 'floorprice': 1000000, - 'geo': { - 'country': 'DE' - } - }, - 'bcat': 'IAB2,IAB4', - 'dvt': 'desktop', - 'ip': '1.1.1.1' - }, - 'sizes': [ - [300, 250] - ], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }, { - 'bidder': 'rads', - 'params': { - 'placement': '6682', - 'pfilter': { - 'floorprice': 1000000, - 'geo': { - 'country': 'DE', - 'region': 'DE-BE' - }, - }, - 'bcat': 'IAB2,IAB4', - 'dvt': 'desktop' - }, - 'mediaTypes': { - 'video': { - 'playerSize': [640, 480], - 'context': 'instream' - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }]; - - // Without gdprConsent - let bidderRequest = { - refererInfo: { - referer: 'some_referrer.net' - } - } - // With gdprConsent - var bidderRequestGdprConsent = { - refererInfo: { - referer: 'some_referrer.net' - }, - gdprConsent: { - consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', - vendorData: {someData: 'value'}, - gdprApplies: true - } - }; - - // without gdprConsent - const request = spec.buildRequests(bidRequests, bidderRequest); - it('sends bid request to our endpoint via GET', function () { - expect(request[0].method).to.equal('GET'); - let data = request[0].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('rt=bid-response&_f=prebid_js&_ps=6682&srw=300&srh=250&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&bcat=IAB2%2CIAB4&dvt=desktop&i=1.1.1.1'); - }); - - it('sends bid video request to our rads endpoint via GET', function () { - expect(request[1].method).to.equal('GET'); - let data = request[1].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('rt=vast2&_f=prebid_js&_ps=6682&srw=640&srh=480&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgeo%5D%5Bregion%5D=DE-BE&bcat=IAB2%2CIAB4&dvt=desktop'); - }); - - // with gdprConsent - const request2 = spec.buildRequests(bidRequests, bidderRequestGdprConsent); - it('sends bid request to our endpoint via GET', function () { - expect(request2[0].method).to.equal('GET'); - let data = request2[0].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('rt=bid-response&_f=prebid_js&_ps=6682&srw=300&srh=250&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&bcat=IAB2%2CIAB4&dvt=desktop&i=1.1.1.1'); - }); - - it('sends bid video request to our rads endpoint via GET', function () { - expect(request2[1].method).to.equal('GET'); - let data = request2[1].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('rt=vast2&_f=prebid_js&_ps=6682&srw=640&srh=480&idt=100&p=some_referrer.net&bid_id=30b31c1838de1e&pfilter%5Bfloorprice%5D=1000000&pfilter%5Bgeo%5D%5Bcountry%5D=DE&pfilter%5Bgeo%5D%5Bregion%5D=DE-BE&pfilter%5Bgdpr_consent%5D=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D&pfilter%5Bgdpr%5D=true&bcat=IAB2%2CIAB4&dvt=desktop'); - }); - }); - - describe('interpretResponse', function () { - let serverBannerResponse = { - 'body': { - 'cpm': 5000000, - 'crid': 100500, - 'width': '300', - 'height': '250', - 'adTag': '', - 'requestId': '220ed41385952a', - 'currency': 'EUR', - 'ttl': 60, - 'netRevenue': true, - 'zone': '6682' - } - }; - let serverVideoResponse = { - 'body': { - 'cpm': 5000000, - 'crid': 100500, - 'width': '300', - 'height': '250', - 'vastXml': '{"reason":7001,"status":"accepted"}', - 'requestId': '220ed41385952a', - 'currency': 'EUR', - 'ttl': 60, - 'netRevenue': true, - 'zone': '6682' - } - }; - - let expectedResponse = [{ - requestId: '23beaa6af6cdde', - cpm: 0.5, - width: 0, - height: 0, - creativeId: 100500, - dealId: '', - currency: 'EUR', - netRevenue: true, - ttl: 300, - ad: '' - }, { - requestId: '23beaa6af6cdde', - cpm: 0.5, - width: 0, - height: 0, - creativeId: 100500, - dealId: '', - currency: 'EUR', - netRevenue: true, - ttl: 300, - vastXml: '{"reason":7001,"status":"accepted"}', - mediaType: 'video' - }]; - - it('should get the correct bid response by display ad', function () { - let bidRequest = [{ - 'method': 'GET', - 'url': RADS_ENDPOINT_URL, - 'refererInfo': { - 'referer': '' - }, - 'data': { - 'bid_id': '30b31c1838de1e' - } - }]; - let result = spec.interpretResponse(serverBannerResponse, bidRequest[0]); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('should get the correct rads video bid response by display ad', function () { - let bidRequest = [{ - 'method': 'GET', - 'url': RADS_ENDPOINT_URL, - 'mediaTypes': { - 'video': { - 'playerSize': [640, 480], - 'context': 'instream' - } - }, - 'data': { - 'bid_id': '30b31c1838de1e' - } - }]; - let result = spec.interpretResponse(serverVideoResponse, bidRequest[0]); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[1])); - }); - - it('handles empty bid response', function () { - let response = { - body: {} - }; - let result = spec.interpretResponse(response); - expect(result.length).to.equal(0); - }); - }); - - describe(`getUserSyncs test usage`, function () { - let serverResponses; - - beforeEach(function () { - serverResponses = [{ - body: { - requestId: '23beaa6af6cdde', - cpm: 0.5, - width: 0, - height: 0, - creativeId: 100500, - dealId: '', - currency: 'EUR', - netRevenue: true, - ttl: 300, - type: 'sspHTML', - ad: '', - userSync: { - iframeUrl: ['anyIframeUrl?a=1'], - imageUrl: ['anyImageUrl', 'anyImageUrl2'] - } - } - }]; - }); - - it(`return value should be an array`, function () { - expect(spec.getUserSyncs({ iframeEnabled: true })).to.be.an('array'); - }); - it(`array should have only one object and it should have a property type = 'iframe'`, function () { - expect(spec.getUserSyncs({ iframeEnabled: true }, serverResponses).length).to.be.equal(1); - let [userSync] = spec.getUserSyncs({ iframeEnabled: true }, serverResponses); - expect(userSync).to.have.property('type'); - expect(userSync.type).to.be.equal('iframe'); - }); - it(`we have valid sync url for iframe`, function () { - let [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 () { - let [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 () { - let 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'); - expect(userSync[1].url).to.be.equal('anyImageUrl?gdpr=1&gdpr_consent=anyString') - expect(userSync[1].type).to.be.equal('image'); - expect(userSync[2].url).to.be.equal('anyImageUrl2?gdpr=1&gdpr_consent=anyString') - expect(userSync[2].type).to.be.equal('image'); - }); - }); -}); diff --git a/test/spec/modules/rakutenBidAdapter_spec.js b/test/spec/modules/rakutenBidAdapter_spec.js deleted file mode 100644 index 15b22afbe29..00000000000 --- a/test/spec/modules/rakutenBidAdapter_spec.js +++ /dev/null @@ -1,171 +0,0 @@ -import { expect } from 'chai' -import { spec } from 'modules/rakutenBidAdapter/index.js' -import { newBidder } from 'src/adapters/bidderFactory.js' -import {config} from '../../../src/config.js'; - -describe('rakutenBidAdapter', function() { - const adapter = newBidder(spec); - const ENDPOINT = 'https://s-bid.rmp.rakuten.com/h'; - let sandbox; - - beforeEach(function() { - config.resetConfig(); - }); - - afterEach(function () { - config.resetConfig(); - }); - - describe('inherited functions', () => { - it('exists and is a function', () => { - expect(adapter.callBids).to.exist.and.to.be.a('function') - }) - }); - - describe('isBidRequestValid', () => { - let bid = { - bidder: 'rakuten', - params: { - adSpotId: '56789' - } - }; - - it('should return true when required params found', () => { - expect(spec.isBidRequestValid(bid)).to.equal(true) - }); - - it('should return false when required params are not passed', () => { - bid.params.adSpotId = ''; - expect(spec.isBidRequestValid(bid)).to.equal(false) - }); - - it('should return false when required params are not passed', () => { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false) - }) - }); - - describe('buildRequests', () => { - const bidRequests = [ - { - // banner - params: { - adSpotId: '58278' - } - } - ]; - - const bidderRequest = { - bids: bidRequests, - refererInfo: { - referer: 'http://test.com', - stack: ['http://test.com'] - }, - gdprConsent: { - consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', - vendorData: {}, - gdprApplies: true - }, - uspConsent: '1YN-' - }; - - it('sends bid request to ENDPOINT via GET', () => { - const request = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(request.url).to.equal(ENDPOINT); - expect(request.method).to.equal('GET') - expect(request.data.gdpr).to.equal(1); - expect(request.data.cd).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A=='); - expect(request.data.ccpa).to.equal('1YN-'); - }); - - it('allows url override', () => { - config.setConfig({ - rakuten: { - endpoint: '//test.rakuten.com' - } - }); - const request = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(request.url).to.equal('//test.rakuten.com'); - }) - }); - - describe('interpretResponse', () => { - const bidRequests = { - banner: { - method: 'GET', - url: '', - data: { - t: '56789', - s: 'https', - ua: - 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Mobile Safari/537.36', - l: 'ja', - d: 'examples.com', - tp: 'https://examples.com/foo/fuga', - pp: 'https://examples.com/hoge/muga' - } - } - }; - - const serverResponse = { - noAd: [], - noAd2: { - requestId: 'biequa9oaph4we' - }, - banner: { - requestId: 'biequa9oaph4we', - cpm: 37.66, - width: 300, - height: 250, - creativeId: 140281, - dealId: 'phoh3pad-ai4ah-xoh7x-ahk7cheasae3oh', - currency: 'USD', - netRevenue: 300, - ttl: 3000, - ad: '' - } - }; - - it('handles nobid responses', () => { - const result = spec.interpretResponse( - { body: serverResponse.noAd }, - bidRequests.banner - ); - expect(result.length).to.equal(0); - - const result2 = spec.interpretResponse( - { body: serverResponse.noAd2 }, - bidRequests.banner - ); - expect(result2.length).to.equal(0); - }) - }); - describe('spec.getUserSyncs', function () { - const syncResponse = [{ - body: { - request_id: 'biequa9oaph4we', - sync_urls: ['https://rdn1.test/sync?uid=9876543210', 'https://rdn2.test/sync?uid=9876543210'] - } - }]; - const nosyncResponse = [{ - body: { - request_id: 'biequa9oaph4we', - sync_urls: [] - } - }]; - let syncOptions - beforeEach(function () { - syncOptions = { - pixelEnabled: true - } - }); - it('sucess 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'}); - expect(spec.getUserSyncs(syncOptions, syncResponse)).to.deep.equal(result); - }); - }); -}); diff --git a/test/spec/modules/readpeakBidAdapter_spec.js b/test/spec/modules/readpeakBidAdapter_spec.js deleted file mode 100644 index eefd7792a7c..00000000000 --- a/test/spec/modules/readpeakBidAdapter_spec.js +++ /dev/null @@ -1,301 +0,0 @@ -import { expect } from 'chai'; -import { spec, ENDPOINT } from 'modules/readpeakBidAdapter.js'; -import { config } from 'src/config.js'; -import { parseUrl } from 'src/utils.js'; - -describe('ReadPeakAdapter', function() { - let bidRequest; - let serverResponse; - let serverRequest; - let bidderRequest; - - beforeEach(function() { - bidderRequest = { - refererInfo: { - referer: 'https://publisher.com/home' - } - }; - - bidRequest = { - bidder: 'readpeak', - nativeParams: { - title: { required: true, len: 200 }, - image: { wmin: 100 }, - sponsoredBy: {}, - body: { required: false }, - cta: { required: false } - }, - params: { - bidfloor: 5.0, - publisherId: '11bc5dd5-7421-4dd8-c926-40fa653bec76', - siteId: '11bc5dd5-7421-4dd8-c926-40fa653bec77', - tagId: 'test-tag-1' - }, - bidId: '2ffb201a808da7', - bidderRequestId: '178e34bad3658f', - auctionId: 'c45dd708-a418-42ec-b8a7-b70a6c6fab0a', - transactionId: 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b' - }; - serverResponse = { - id: bidRequest.bidderRequestId, - cur: 'USD', - seatbid: [ - { - bid: [ - { - id: 'bidRequest.bidId', - impid: bidRequest.bidId, - price: 0.12, - cid: '12', - crid: '123', - adomain: ['readpeak.com'], - adm: { - assets: [ - { - id: 1, - title: { - text: 'Title' - } - }, - { - id: 3, - data: { - type: 1, - value: 'Brand Name' - } - }, - { - id: 4, - data: { - type: 2, - value: 'Description' - } - }, - { - id: 2, - img: { - type: 3, - url: 'http://url.to/image', - w: 750, - h: 500 - } - } - ], - link: { - url: 'http://url.to/target' - }, - imptrackers: ['http://url.to/pixeltracker'] - } - } - ] - } - ] - }; - serverRequest = { - method: 'POST', - url: 'http://localhost:60080/header/prebid', - data: JSON.stringify({ - id: '178e34bad3658f', - imp: [ - { - id: '2ffb201a808da7', - native: { - request: - '{"assets":[{"id":1,"required":1,"title":{"len":200}},{"id":2,"required":0,"data":{"type":1,"len":50}},{"id":3,"required":0,"img":{"type":3,"wmin":100,"hmin":150}}]}', - ver: '1.1' - }, - bidfloor: 5, - bidfloorcur: 'USD', - tagId: 'test-tag-1' - } - ], - site: { - publisher: { - id: '11bc5dd5-7421-4dd8-c926-40fa653bec76' - }, - id: '11bc5dd5-7421-4dd8-c926-40fa653bec77', - ref: '', - page: 'http://localhost', - domain: 'localhost' - }, - app: null, - device: { - ua: - 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/61.0.3163.100 Safari/537.36', - language: 'en-US' - }, - isPrebid: true - }) - }; - }); - - describe('spec.isBidRequestValid', function() { - it('should return true when the required params are passed', function() { - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }); - - it('should return false when the native params are missing', function() { - bidRequest.nativeParams = undefined; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when the "publisherId" param is missing', function() { - bidRequest.params = { - bidfloor: 5.0 - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when no bid params are passed', function() { - bidRequest.params = {}; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when a bid request is not passed', function() { - expect(spec.isBidRequestValid()).to.equal(false); - expect(spec.isBidRequestValid({})).to.equal(false); - }); - }); - - describe('spec.buildRequests', function() { - it('should create a POST request for every bid', function() { - const request = spec.buildRequests([bidRequest], bidderRequest); - expect(request.method).to.equal('POST'); - expect(request.url).to.equal(ENDPOINT); - }); - - it('should attach request data', function() { - config.setConfig({ - currency: { - adServerCurrency: 'EUR' - } - }); - - const request = spec.buildRequests([bidRequest], bidderRequest); - - const data = JSON.parse(request.data); - - expect(data.source.ext.prebid).to.equal('$prebid.version$'); - expect(data.id).to.equal(bidRequest.bidderRequestId); - expect(data.imp[0].bidfloor).to.equal(bidRequest.params.bidfloor); - expect(data.imp[0].bidfloorcur).to.equal('USD'); - expect(data.imp[0].tagId).to.equal('test-tag-1'); - expect(data.site.publisher.id).to.equal(bidRequest.params.publisherId); - expect(data.site.id).to.equal(bidRequest.params.siteId); - expect(data.site.page).to.equal(bidderRequest.refererInfo.referer); - expect(data.site.domain).to.equal(parseUrl(bidderRequest.refererInfo.referer).hostname); - expect(data.device).to.deep.contain({ - ua: navigator.userAgent, - language: navigator.language - }); - expect(data.cur).to.deep.equal(['EUR']); - expect(data.user).to.be.undefined; - expect(data.regs).to.be.undefined; - }); - - it('should get bid floor from module', function() { - const floorModuleData = { - currency: 'USD', - floor: 3.2, - } - bidRequest.getFloor = function () { - return floorModuleData - } - const request = spec.buildRequests([bidRequest], bidderRequest); - - const data = JSON.parse(request.data); - - expect(data.source.ext.prebid).to.equal('$prebid.version$'); - expect(data.id).to.equal(bidRequest.bidderRequestId); - expect(data.imp[0].bidfloor).to.equal(floorModuleData.floor); - expect(data.imp[0].bidfloorcur).to.equal(floorModuleData.currency); - }); - - it('should send gdpr data when gdpr does not apply', function() { - const gdprData = { - gdprConsent: { - gdprApplies: false, - consentString: undefined, - } - } - const request = spec.buildRequests([bidRequest], {...bidderRequest, ...gdprData}); - - const data = JSON.parse(request.data); - - expect(data.user).to.deep.equal({ - ext: { - consent: '' - } - }); - expect(data.regs).to.deep.equal({ - ext: { - gdpr: false - } - }); - }); - - it('should send gdpr data when gdpr applies', function() { - const tcString = 'sometcstring'; - const gdprData = { - gdprConsent: { - gdprApplies: true, - consentString: tcString - } - } - const request = spec.buildRequests([bidRequest], {...bidderRequest, ...gdprData}); - - const data = JSON.parse(request.data); - - expect(data.user).to.deep.equal({ - ext: { - consent: tcString - } - }); - expect(data.regs).to.deep.equal({ - ext: { - gdpr: true - } - }); - }); - }); - - describe('spec.interpretResponse', function() { - it('should return no bids if the response is not valid', function() { - const bidResponse = spec.interpretResponse({ body: null }, serverRequest); - expect(bidResponse.length).to.equal(0); - }); - - it('should return a valid bid response', function() { - const bidResponse = spec.interpretResponse( - { body: serverResponse }, - serverRequest - )[0]; - expect(bidResponse).to.contain({ - requestId: bidRequest.bidId, - cpm: serverResponse.seatbid[0].bid[0].price, - creativeId: serverResponse.seatbid[0].bid[0].crid, - ttl: 300, - netRevenue: true, - mediaType: 'native', - currency: serverResponse.cur - }); - - expect(bidResponse.meta).to.deep.equal({ - advertiserDomains: ['readpeak.com'], - }) - expect(bidResponse.native.title).to.equal('Title'); - expect(bidResponse.native.body).to.equal('Description'); - expect(bidResponse.native.image).to.deep.equal({ - url: 'http://url.to/image', - width: 750, - height: 500 - }); - expect(bidResponse.native.clickUrl).to.equal( - 'http%3A%2F%2Furl.to%2Ftarget' - ); - expect(bidResponse.native.impressionTrackers).to.contain( - 'http://url.to/pixeltracker' - ); - }); - }); -}); diff --git a/test/spec/modules/realTimeDataModule_spec.js b/test/spec/modules/realTimeDataModule_spec.js deleted file mode 100644 index b84aef15feb..00000000000 --- a/test/spec/modules/realTimeDataModule_spec.js +++ /dev/null @@ -1,160 +0,0 @@ -import * as rtdModule from 'modules/rtdModule/index.js'; -import { config } from 'src/config.js'; -import * as sinon from 'sinon'; - -const getBidRequestDataSpy = sinon.spy(); - -const validSM = { - name: 'validSM', - init: () => { return true }, - getTargetingData: (adUnitsCodes) => { - return {'ad2': {'key': 'validSM'}} - }, - getBidRequestData: getBidRequestDataSpy -}; - -const validSMWait = { - name: 'validSMWait', - init: () => { return true }, - getTargetingData: (adUnitsCodes) => { - return {'ad1': {'key': 'validSMWait'}} - }, - getBidRequestData: getBidRequestDataSpy -}; - -const invalidSM = { - name: 'invalidSM' -}; - -const failureSM = { - name: 'failureSM', - init: () => { return false } -}; - -const nonConfSM = { - name: 'nonConfSM', - init: () => { return true } -}; - -const conf = { - 'realTimeData': { - 'auctionDelay': 100, - dataProviders: [ - { - 'name': 'validSMWait', - 'waitForIt': true, - }, - { - 'name': 'validSM', - 'waitForIt': false, - }, - { - 'name': 'invalidSM' - }, - { - 'name': 'failureSM' - }] - } -}; - -describe('Real time module', function () { - before(function () { - rtdModule.attachRealTimeDataProvider(validSM); - rtdModule.attachRealTimeDataProvider(invalidSM); - rtdModule.attachRealTimeDataProvider(failureSM); - rtdModule.attachRealTimeDataProvider(nonConfSM); - rtdModule.attachRealTimeDataProvider(validSMWait); - }); - - after(function () { - config.resetConfig(); - }); - - beforeEach(function () { - config.setConfig(conf); - }); - - it('should use only valid modules', function () { - rtdModule.init(config); - expect(rtdModule.subModules).to.eql([validSMWait, validSM]); - }); - - it('should be able to modify bid request', function (done) { - rtdModule.setBidRequestsData(() => { - assert(getBidRequestDataSpy.calledTwice); - assert(getBidRequestDataSpy.calledWith({bidRequest: {}})); - done(); - }, {bidRequest: {}}) - }); - - it('deep merge object', function () { - const obj1 = { - id1: { - key: 'value', - key2: 'value2' - }, - id2: { - k: 'v' - } - }; - const obj2 = { - id1: { - key3: 'value3' - } - }; - const obj3 = { - id3: { - key: 'value' - } - }; - const expected = { - id1: { - key: 'value', - key2: 'value2', - key3: 'value3' - }, - id2: { - k: 'v' - }, - id3: { - key: 'value' - } - }; - - const merged = rtdModule.deepMerge([obj1, obj2, obj3]); - assert.deepEqual(expected, merged); - }); - - it('sould place targeting on adUnits', function (done) { - const auction = { - adUnitCodes: ['ad1', 'ad2'], - adUnits: [ - { - code: 'ad1' - }, - { - code: 'ad2', - adserverTargeting: {preKey: 'preValue'} - } - ] - }; - - const expectedAdUnits = [ - { - code: 'ad1', - adserverTargeting: {key: 'validSMWait'} - }, - { - code: 'ad2', - adserverTargeting: { - preKey: 'preValue', - key: 'validSM' - } - } - ]; - - const adUnits = rtdModule.getAdUnitTargeting(auction); - assert.deepEqual(expectedAdUnits, adUnits) - done(); - }) -}); diff --git a/test/spec/modules/realvuAnalyticsAdapter_spec.js b/test/spec/modules/realvuAnalyticsAdapter_spec.js deleted file mode 100644 index e51a4e2e3a2..00000000000 --- a/test/spec/modules/realvuAnalyticsAdapter_spec.js +++ /dev/null @@ -1,194 +0,0 @@ -import { expect } from 'chai'; -import realvuAnalyticsAdapter, { lib } from 'modules/realvuAnalyticsAdapter.js'; -import CONSTANTS from 'src/constants.json'; - -function addDiv(id) { - let dv = document.createElement('div'); - dv.id = id; - dv.style.width = '728px'; - dv.style.height = '90px'; - dv.style.display = 'block'; - document.body.appendChild(dv); - let f = document.createElement('iframe'); - f.width = 728; - f.height = 90; - dv.appendChild(f); - let d = null; - if (f.contentDocument) d = f.contentDocument; // DOM - else if (f.contentWindow) d = f.contentWindow.document; // IE - d.open() - d.write(''); - d.close(); - return dv; -} - -describe('RealVu', function() { - let sandbox; - beforeEach(function () { - sandbox = sinon.sandbox.create(); - addDiv('ad1'); - addDiv('ad2'); - sandbox.stub(lib, 'scr'); - }); - - afterEach(function () { - let a1 = document.getElementById('ad1'); - document.body.removeChild(a1); - let a2 = document.getElementById('ad2'); - document.body.removeChild(a2); - sandbox.restore(); - realvuAnalyticsAdapter.disableAnalytics(); - }); - - after(function () { - delete window.top1; - delete window.realvu_aa_fifo; - delete window.realvu_aa; - clearInterval(window.boost_poll); - delete window.boost_poll; - }); - - describe('Analytics Adapter.', function () { - it('enableAnalytics', function () { - const config = { - options: { - partnerId: '1Y', - regAllUnits: true - // unitIds: ['ad1', 'ad2'] - } - }; - let p = realvuAnalyticsAdapter.enableAnalytics(config); - expect(p).to.equal('1Y'); - }); - - it('checkIn', function () { - const bid = { - adUnitCode: 'ad1', - sizes: [ - [728, 90], - [970, 250], - [970, 90] - ] - }; - let result = realvuAnalyticsAdapter.checkIn(bid, '1Y'); - const b = Object.assign({}, window.top1.realvu_aa); - let a = b.ads[0]; - // console.log('a: ' + a.x + ', ' + a.y + ', ' + a.w + ', ' + a.h); - // console.log('b: ' + b.x1 + ', ' + b.y1 + ', ' + b.x2 + ', ' + b.y2); - expect(result).to.equal('yes'); - - result = realvuAnalyticsAdapter.checkIn(bid); // test invalid partnerId 'undefined' - result = realvuAnalyticsAdapter.checkIn(bid, ''); // test invalid partnerId '' - }); - - it.skip('isInView returns "yes"', () => { - let inview = realvuAnalyticsAdapter.isInView('ad1'); - expect(inview).to.equal('yes'); - }); - - it('isInView return "NA"', function () { - const adUnitCode = '1234'; - let result = realvuAnalyticsAdapter.isInView(adUnitCode); - expect(result).to.equal('NA'); - }); - - it('bid response event', function () { - const config = { - options: { - partnerId: '1Y', - regAllUnits: true - // unitIds: ['ad1', 'ad2'] - } - }; - realvuAnalyticsAdapter.enableAnalytics(config); - const args = { - 'biddercode': 'realvu', - 'adUnitCode': 'ad1', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '7ba299eba818c1', - 'mediaType': 'banner', - 'creative_id': 85792851, - 'cpm': 0.4308 - }; - realvuAnalyticsAdapter.track({ - eventType: CONSTANTS.EVENTS.BID_RESPONSE, - args: args - }); - const boost = Object.assign({}, window.top1.realvu_aa); - expect(boost.ads[boost.len - 1].bids.length).to.equal(1); - - realvuAnalyticsAdapter.track({ - eventType: CONSTANTS.EVENTS.BID_WON, - args: args - }); - expect(boost.ads[boost.len - 1].bids[0].winner).to.equal(1); - }); - }); - - describe('Boost.', function () { - // const boost = window.top1.realvu_aa; - let boost; - beforeEach(function() { - boost = Object.assign({}, window.top1.realvu_aa); - }); - it('brd', function () { - let a1 = document.getElementById('ad1'); - let p = boost.brd(a1, 'Left'); - expect(typeof p).to.not.equal('undefined'); - }); - - it('addUnitById', function () { - let a1 = document.getElementById('ad1'); - let p = boost.addUnitById('1Y', 'ad1'); - expect(typeof p).to.not.equal('undefined'); - }); - - it('questA', function () { - const dv = document.getElementById('ad1'); - let q = boost.questA(dv); - expect(q).to.not.equal(null); - }); - - it('render', function () { - let dv = document.getElementById('ad1'); - // dv.style.width = '728px'; - // dv.style.height = '90px'; - // dv.style.display = 'block'; - dv.getBoundingClientRect = false; - // document.body.appendChild(dv); - let q = boost.findPosG(dv); - expect(q).to.not.equal(null); - }); - - it('readPos', function () { - const a = boost.ads[boost.len - 1]; - let r = boost.readPos(a); - expect(r).to.equal(true); - }); - - it('send_track', function () { - const a = boost.ads[boost.len - 1]; - boost.track(a, 'show', ''); - boost.sr = 'a'; - boost.send_track(); - expect(boost.beacons.length).to.equal(0); - }); - - it('questA text', function () { - let p = document.createElement('p'); - p.innerHTML = 'ABC'; - document.body.appendChild(p); - let r = boost.questA(p.firstChild); - document.body.removeChild(p); - expect(r).to.not.equal(null); - }); - - it('_f=conf', function () { - const a = boost.ads[boost.len - 1]; - let r = boost.tru(a, 'conf'); - expect(r).to.not.include('_ps='); - }); - }); -}); diff --git a/test/spec/modules/reconciliationRtdProvider_spec.js b/test/spec/modules/reconciliationRtdProvider_spec.js deleted file mode 100644 index 6efe55ddf46..00000000000 --- a/test/spec/modules/reconciliationRtdProvider_spec.js +++ /dev/null @@ -1,221 +0,0 @@ -import { - reconciliationSubmodule, - track, - getTopIFrameWin, - getSlotByWin -} from 'modules/reconciliationRtdProvider.js'; -import { makeSlot } from '../integration/faker/googletag.js'; -import * as utils from 'src/utils.js'; - -describe('Reconciliation Real time data submodule', function () { - const conf = { - dataProviders: [{ - 'name': 'reconciliation', - 'params': { - 'publisherMemberId': 'test_prebid_publisher' - }, - }] - }; - - let trackPostStub; - - beforeEach(function () { - trackPostStub = sinon.stub(track, 'trackPost'); - }); - - afterEach(function () { - trackPostStub.restore(); - }); - - describe('reconciliationSubmodule', function () { - describe('initialization', function () { - let utilsLogErrorSpy; - - before(function () { - utilsLogErrorSpy = sinon.spy(utils, 'logError'); - }); - - after(function () { - utils.logError.restore(); - }); - - it('successfully instantiates', function () { - expect(reconciliationSubmodule.init(conf.dataProviders[0])).to.equal(true); - }); - - it('should log error if initializied without parameters', function () { - 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'}); - - const targetingData = reconciliationSubmodule.getTargetingData(['/reconciliationAdunit1']); - expect(targetingData['/reconciliationAdunit1'].RSDK_AUID).to.eql('/reconciliationAdunit1'); - expect(targetingData['/reconciliationAdunit1'].RSDK_ADID).to.be.a('string'); - }); - - it('should return unit path if called with divId', function () { - makeSlot({code: '/reconciliationAdunit2', divId: 'reconciliationAd2'}); - - const targetingData = reconciliationSubmodule.getTargetingData(['reconciliationAd2']); - expect(targetingData['reconciliationAd2'].RSDK_AUID).to.eql('/reconciliationAdunit2'); - expect(targetingData['reconciliationAd2'].RSDK_ADID).to.be.a('string'); - }); - - it('should skip empty adUnit id', function () { - makeSlot({code: '/reconciliationAdunit3', divId: 'reconciliationAd3'}); - - const targetingData = reconciliationSubmodule.getTargetingData(['reconciliationAd3', '']); - expect(targetingData).to.have.all.keys('reconciliationAd3'); - }); - }); - - describe('track events', function () { - it('should track init event with data', function () { - const adUnit = { - code: '/adunit' - }; - - reconciliationSubmodule.getTargetingData([adUnit.code]); - - expect(trackPostStub.calledOnce).to.be.true; - expect(trackPostStub.getCalls()[0].args[0]).to.eql('https://confirm.fiduciadlt.com/init'); - expect(trackPostStub.getCalls()[0].args[1].adUnits[0].adUnitId).to.eql(adUnit.code); - expect(trackPostStub.getCalls()[0].args[1].adUnits[0].adDeliveryId).be.a('string'); - expect(trackPostStub.getCalls()[0].args[1].publisherMemberId).to.eql('test_prebid_publisher'); - }); - }); - - describe('get topmost iframe', function () { - /** - * - top - * -- iframe.window <-- top iframe window - * --- iframe.window - * ---- iframe.window <-- win - */ - const mockFrameWin = (topWin, parentWin) => { - return { - top: topWin, - parent: parentWin - } - } - - it('should return null if called with null', function() { - expect(getTopIFrameWin(null)).to.be.null; - }); - - it('should return null if there is an error in frames chain', function() { - const topWin = {}; - const iframe1Win = mockFrameWin(topWin, null); // break chain - const iframe2Win = mockFrameWin(topWin, iframe1Win); - - expect(getTopIFrameWin(iframe1Win, topWin)).to.be.null; - }); - - it('should get the topmost iframe', function () { - const topWin = {}; - const iframe1Win = mockFrameWin(topWin, topWin); - const iframe2Win = mockFrameWin(topWin, iframe1Win); - - expect(getTopIFrameWin(iframe2Win, topWin)).to.eql(iframe1Win); - }); - }); - - describe('get slot by nested iframe window', function () { - it('should return the slot', function () { - const adSlotElement = document.createElement('div'); - const adSlotIframe = document.createElement('iframe'); - - adSlotElement.id = 'reconciliationAd'; - adSlotElement.appendChild(adSlotIframe); - document.body.appendChild(adSlotElement); - - const adSlot = makeSlot({code: '/reconciliationAdunit', divId: adSlotElement.id}); - - expect(getSlotByWin(adSlotIframe.contentWindow)).to.eql(adSlot); - }); - - it('should return null if the slot is not found', function () { - const adSlotElement = document.createElement('div'); - const adSlotIframe = document.createElement('iframe'); - - adSlotElement.id = 'reconciliationAd'; - document.body.appendChild(adSlotElement); - document.body.appendChild(adSlotIframe); // iframe is not in ad slot - - const adSlot = makeSlot({code: '/reconciliationAdunit', divId: adSlotElement.id}); - - expect(getSlotByWin(adSlotIframe.contentWindow)).to.be.null; - }); - }); - - describe('handle postMessage from Reconciliation Tag in ad iframe', function () { - it('should track impression pixel with parameters', function (done) { - const adSlotElement = document.createElement('div'); - const adSlotIframe = document.createElement('iframe'); - - adSlotElement.id = 'reconciliationAdMessage'; - adSlotElement.appendChild(adSlotIframe); - document.body.appendChild(adSlotElement); - - const adSlot = makeSlot({code: '/reconciliationAdunit', divId: adSlotElement.id}); - // Fix targeting methods - adSlot.targeting = {}; - adSlot.setTargeting = function(key, value) { - this.targeting[key] = [value]; - }; - adSlot.getTargeting = function(key) { - return this.targeting[key]; - }; - - adSlot.setTargeting('RSDK_AUID', '/reconciliationAdunit'); - adSlot.setTargeting('RSDK_ADID', '12345'); - adSlotIframe.contentDocument.open(); - adSlotIframe.contentDocument.write(``); - adSlotIframe.contentDocument.close(); - - setTimeout(() => { - expect(trackPostStub.calledOnce).to.be.true; - expect(trackPostStub.getCalls()[0].args[0]).to.eql('https://confirm.fiduciadlt.com/pimp'); - expect(trackPostStub.getCalls()[0].args[1].adUnitId).to.eql('/reconciliationAdunit'); - expect(trackPostStub.getCalls()[0].args[1].adDeliveryId).to.eql('12345'); - expect(trackPostStub.getCalls()[0].args[1].tagOwnerMemberId).to.eql('test_member_id'); ; - expect(trackPostStub.getCalls()[0].args[1].dataSources.length).to.eql(1); - expect(trackPostStub.getCalls()[0].args[1].dataRecipients.length).to.eql(2); - expect(trackPostStub.getCalls()[0].args[1].publisherMemberId).to.eql('test_prebid_publisher'); - done(); - }, 100); - }); - }); - }); -}); diff --git a/test/spec/modules/reklamstoreBidAdapter_spec.js b/test/spec/modules/reklamstoreBidAdapter_spec.js deleted file mode 100644 index 1dcd6c17ca4..00000000000 --- a/test/spec/modules/reklamstoreBidAdapter_spec.js +++ /dev/null @@ -1,85 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/reklamstoreBidAdapter.js'; - -describe('reklamstoreBidAdapterTests', function() { - let bidRequestData = { - bids: [ - { - bidder: 'reklamstore', - params: { - regionId: 532211 - }, - sizes: [[300, 250]] - } - ] - }; - let request = []; - - it('validate_params', function() { - expect( - spec.isBidRequestValid({ - bidder: 'reklamstore', - params: { - regionId: 532211 - } - }) - ).to.equal(true); - }); - - it('validate_generated_params', function() { - let bidderRequest = { - refererInfo: { - referer: 'https://reklamstore.com' - } - }; - request = spec.buildRequests(bidRequestData.bids, bidderRequest); - let req_data = request[0].data; - - expect(req_data.regionId).to.equal(532211); - }); - - const serverResponse = { - body: - { - cpm: 1.2, - ad: 'Ad html', - w: 300, - h: 250, - syncs: [{ - type: 'image', - url: 'https://link1' - }, - { - type: 'iframe', - url: 'https://link2' - } - ] - } - }; - - it('validate_response_params', function() { - let bids = spec.interpretResponse(serverResponse, bidRequestData.bids[0]); - expect(bids).to.have.lengthOf(1); - - let bid = bids[0]; - expect(bid.ad).to.equal('Ad html'); - expect(bid.cpm).to.equal(1.2); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.currency).to.equal('USD'); - }); - - it('should return no syncs when pixel syncing is disabled', function () { - const syncs = spec.getUserSyncs({ pixelEnabled: false }, [serverResponse]); - expect(syncs).to.deep.equal([]); - }); - - it('should return user syncs', function () { - const syncs = spec.getUserSyncs({pixelEnabled: true, iframeEnabled: true}, [serverResponse]); - const expected = [ - { type: 'image', url: 'https://link1' }, - { type: 'iframe', url: 'https://link2' }, - ]; - expect(syncs).to.deep.equal(expected); - }); -}); diff --git a/test/spec/modules/relaidoBidAdapter_spec.js b/test/spec/modules/relaidoBidAdapter_spec.js deleted file mode 100644 index 91aa6b05e6e..00000000000 --- a/test/spec/modules/relaidoBidAdapter_spec.js +++ /dev/null @@ -1,416 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/relaidoBidAdapter.js'; -import * as utils from 'src/utils.js'; -import { getStorageManager } from '../../../src/storageManager.js'; - -const UUID_KEY = 'relaido_uuid'; -const DEFAULT_USER_AGENT = window.navigator.userAgent; -const MOBILE_USER_AGENT = 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.5 Mobile/15E148 Safari/604.1'; -const relaido_uuid = 'hogehoge'; - -const setUADefault = () => { window.navigator.__defineGetter__('userAgent', function () { return DEFAULT_USER_AGENT }) }; -const setUAMobile = () => { window.navigator.__defineGetter__('userAgent', function () { return MOBILE_USER_AGENT }) }; - -const storage = getStorageManager(); -storage.setCookie(UUID_KEY, relaido_uuid); - -describe('RelaidoAdapter', function () { - let bidRequest; - let bidderRequest; - let serverResponse; - let serverRequest; - - beforeEach(function () { - bidRequest = { - bidder: 'relaido', - params: { - placementId: '100000', - }, - mediaTypes: { - video: { - context: 'outstream', - playerSize: [ - [640, 360] - ] - } - }, - adUnitCode: 'test', - bidId: '2ed93003f7bb99', - bidderRequestId: '1c50443387a1f2', - auctionId: '413ed000-8c7a-4ba1-a1fa-9732e006f8c3', - transactionId: '5c2d064c-7b76-42e8-a383-983603afdc45', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 - }; - bidderRequest = { - timeout: 1000, - refererInfo: { - referer: 'https://publisher.com/home' - } - }; - serverResponse = { - body: { - status: 'ok', - price: 500, - model: 'vcpm', - currency: 'JPY', - creativeId: 1000, - uuid: relaido_uuid, - vast: '', - playerUrl: 'https://relaido/player.js', - syncUrl: 'https://relaido/sync.html' - } - }; - serverRequest = { - method: 'GET', - bidId: bidRequest.bidId, - width: bidRequest.mediaTypes.video.playerSize[0][0], - height: bidRequest.mediaTypes.video.playerSize[0][1], - mediaType: 'video', - }; - }); - - describe('spec.isBidRequestValid', function () { - it('should return true when the required params are passed by video', function () { - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }); - - it('should return true when the required params are passed by banner', function () { - setUAMobile(); - bidRequest.mediaTypes = { - banner: { - sizes: [ - [300, 250] - ] - } - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - setUADefault(); - }); - - it('should return false when missing 300x250 over and 1x1 by banner', function () { - setUAMobile(); - bidRequest.mediaTypes = { - banner: { - sizes: [ - [100, 100], - [300, 100] - ] - } - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - setUADefault(); - }); - - it('should return true when 300x250 by banner', function () { - setUAMobile(); - bidRequest.mediaTypes = { - banner: { - sizes: [ - [300, 250] - ] - } - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - setUADefault(); - }); - - it('should return true when 1x1 by banner', function () { - setUAMobile(); - bidRequest.mediaTypes = { - banner: { - sizes: [ - [1, 1] - ] - } - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - setUADefault(); - }); - - it('should return true when 300x250 over by banner', function () { - setUAMobile(); - bidRequest.mediaTypes = { - banner: { - sizes: [ - [100, 100], - [300, 250] - ] - } - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - setUADefault(); - }); - - it('should return false when the placementId params are missing', function () { - bidRequest.params.placementId = undefined; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when the mediaType video params are missing', function () { - bidRequest.mediaTypes = { - video: {} - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when the mediaType banner params are missing', function () { - setUAMobile(); - bidRequest.mediaTypes = { - banner: {} - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - setUADefault(); - }); - - it('should return false when the non-mobile', function () { - bidRequest.mediaTypes = { - banner: { - sizes: [ - [300, 250] - ] - } - }; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when the mediaTypes params are missing', function () { - bidRequest.mediaTypes = {}; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - }); - - describe('spec.buildRequests', function () { - it('should build bid requests by video', function () { - const bidRequests = spec.buildRequests([bidRequest], bidderRequest); - expect(bidRequests).to.have.lengthOf(1); - const request = bidRequests[0]; - expect(request.method).to.equal('GET'); - expect(request.url).to.equal('https://api.relaido.jp/bid/v1/prebid/100000'); - expect(request.bidId).to.equal(bidRequest.bidId); - expect(request.width).to.equal(bidRequest.mediaTypes.video.playerSize[0][0]); - expect(request.height).to.equal(bidRequest.mediaTypes.video.playerSize[0][1]); - expect(request.mediaType).to.equal('video'); - expect(request.data.ref).to.equal(bidderRequest.refererInfo.referer); - expect(request.data.timeout_ms).to.equal(bidderRequest.timeout); - expect(request.data.ad_unit_code).to.equal(bidRequest.adUnitCode); - expect(request.data.auction_id).to.equal(bidRequest.auctionId); - expect(request.data.bidder).to.equal(bidRequest.bidder); - expect(request.data.bidder_request_id).to.equal(bidRequest.bidderRequestId); - expect(request.data.bid_requests_count).to.equal(bidRequest.bidRequestsCount); - expect(request.data.bid_id).to.equal(bidRequest.bidId); - expect(request.data.transaction_id).to.equal(bidRequest.transactionId); - expect(request.data.media_type).to.equal('video'); - expect(request.data.uuid).to.equal(relaido_uuid); - expect(request.data.width).to.equal(bidRequest.mediaTypes.video.playerSize[0][0]); - expect(request.data.height).to.equal(bidRequest.mediaTypes.video.playerSize[0][1]); - }); - - it('should build bid requests by banner', function () { - setUAMobile(); - bidRequest.mediaTypes = { - video: { - context: 'outstream', - playerSize: [ - [320, 180] - ] - }, - banner: { - sizes: [ - [640, 360], - [1, 1] - ] - } - }; - const bidRequests = spec.buildRequests([bidRequest], bidderRequest); - expect(bidRequests).to.have.lengthOf(1); - const request = bidRequests[0]; - expect(request.mediaType).to.equal('banner'); - }); - - it('should take 1x1 size', function () { - setUAMobile(); - bidRequest.mediaTypes = { - video: { - context: 'outstream', - playerSize: [ - [320, 180] - ] - }, - banner: { - sizes: [ - [640, 360], - [1, 1] - ] - } - }; - const bidRequests = spec.buildRequests([bidRequest], bidderRequest); - expect(bidRequests).to.have.lengthOf(1); - const request = bidRequests[0]; - - // eslint-disable-next-line no-console - console.log(bidRequests); - expect(request.width).to.equal(1); - }); - - it('The referrer should be the last', function () { - const bidRequests = spec.buildRequests([bidRequest], bidderRequest); - expect(bidRequests).to.have.lengthOf(1); - const request = bidRequests[0]; - const keys = Object.keys(request.data); - expect(keys[0]).to.equal('version'); - expect(keys[keys.length - 1]).to.equal('ref'); - }); - }); - - describe('spec.interpretResponse', function () { - it('should build bid response by video', function () { - const bidResponses = spec.interpretResponse(serverResponse, serverRequest); - expect(bidResponses).to.have.lengthOf(1); - const response = bidResponses[0]; - expect(response.requestId).to.equal(serverRequest.bidId); - expect(response.width).to.equal(serverRequest.width); - expect(response.height).to.equal(serverRequest.height); - expect(response.cpm).to.equal(serverResponse.body.price); - expect(response.currency).to.equal(serverResponse.body.currency); - expect(response.creativeId).to.equal(serverResponse.body.creativeId); - expect(response.vastXml).to.equal(serverResponse.body.vast); - expect(response.ad).to.be.undefined; - }); - - it('should build bid response by banner', function () { - serverRequest.mediaType = 'banner'; - const bidResponses = spec.interpretResponse(serverResponse, serverRequest); - expect(bidResponses).to.have.lengthOf(1); - const response = bidResponses[0]; - expect(response.requestId).to.equal(serverRequest.bidId); - expect(response.width).to.equal(serverRequest.width); - expect(response.height).to.equal(serverRequest.height); - expect(response.cpm).to.equal(serverResponse.body.price); - expect(response.currency).to.equal(serverResponse.body.currency); - expect(response.creativeId).to.equal(serverResponse.body.creativeId); - expect(response.vastXml).to.be.undefined; - expect(response.ad).to.include(`
`); - expect(response.ad).to.include(``); - expect(response.ad).to.include(`window.RelaidoPlayer.renderAd`); - }); - - it('should not build bid response', function () { - serverResponse = {}; - const bidResponses = spec.interpretResponse(serverResponse, serverRequest); - expect(bidResponses).to.have.lengthOf(0); - }); - - it('should not build bid response', function () { - serverResponse = { - body: { - status: 'no_ad', - } - }; - const bidResponses = spec.interpretResponse(serverResponse, serverRequest); - expect(bidResponses).to.have.lengthOf(0); - }); - }); - - describe('spec.getUserSyncs', function () { - it('should choose iframe sync urls', function () { - let userSyncs = spec.getUserSyncs({iframeEnabled: true}, [serverResponse]); - expect(userSyncs).to.deep.equal([{ - type: 'iframe', - url: serverResponse.body.syncUrl - }]); - }); - - it('should choose iframe sync urls if serverResponse are empty', function () { - let userSyncs = spec.getUserSyncs({iframeEnabled: true}, []); - expect(userSyncs).to.deep.equal([{ - type: 'iframe', - url: 'https://api.relaido.jp/tr/v1/prebid/sync.html' - }]); - }); - - it('should choose iframe sync urls if syncUrl are undefined', function () { - serverResponse.body.syncUrl = undefined; - let userSyncs = spec.getUserSyncs({iframeEnabled: true}, [serverResponse]); - expect(userSyncs).to.deep.equal([{ - type: 'iframe', - url: 'https://api.relaido.jp/tr/v1/prebid/sync.html' - }]); - }); - - it('should return empty if iframeEnabled are false', function () { - let userSyncs = spec.getUserSyncs({iframeEnabled: false}, [serverResponse]); - expect(userSyncs).to.have.lengthOf(0); - }); - }); - - describe('spec.onBidWon', function () { - let stub; - beforeEach(() => { - stub = sinon.stub(utils, 'triggerPixel'); - }); - afterEach(() => { - stub.restore(); - }); - - it('Should create nurl pixel if bid nurl', function () { - let bid = { - bidder: bidRequest.bidder, - creativeId: serverResponse.body.creativeId, - cpm: serverResponse.body.price, - params: [bidRequest.params], - auctionId: bidRequest.auctionId, - requestId: bidRequest.bidId, - adId: '3b286a4db7031f', - adUnitCode: bidRequest.adUnitCode, - ref: window.location.href, - } - spec.onBidWon(bid); - const parser = utils.parseUrl(stub.getCall(0).args[0]); - const query = parser.search; - expect(parser.hostname).to.equal('api.relaido.jp'); - expect(parser.pathname).to.equal('/tr/v1/prebid/win.gif'); - expect(query.placement_id).to.equal('100000'); - expect(query.creative_id).to.equal('1000'); - expect(query.price).to.equal('500'); - expect(query.auction_id).to.equal('413ed000-8c7a-4ba1-a1fa-9732e006f8c3'); - expect(query.bid_id).to.equal('2ed93003f7bb99'); - expect(query.ad_id).to.equal('3b286a4db7031f'); - expect(query.ad_unit_code).to.equal('test'); - expect(query.ref).to.include(window.location.href); - }); - }); - - describe('spec.onTimeout', function () { - let stub; - beforeEach(() => { - stub = sinon.stub(utils, 'triggerPixel'); - }); - afterEach(() => { - stub.restore(); - }); - - it('Should create nurl pixel if bid nurl', function () { - const data = [{ - bidder: bidRequest.bidder, - bidId: bidRequest.bidId, - adUnitCode: bidRequest.adUnitCode, - auctionId: bidRequest.auctionId, - params: [bidRequest.params], - timeout: bidderRequest.timeout, - }]; - spec.onTimeout(data); - const parser = utils.parseUrl(stub.getCall(0).args[0]); - const query = parser.search; - expect(parser.hostname).to.equal('api.relaido.jp'); - expect(parser.pathname).to.equal('/tr/v1/prebid/timeout.gif'); - expect(query.placement_id).to.equal('100000'); - expect(query.timeout).to.equal('1000'); - expect(query.auction_id).to.equal('413ed000-8c7a-4ba1-a1fa-9732e006f8c3'); - expect(query.bid_id).to.equal('2ed93003f7bb99'); - expect(query.ad_unit_code).to.equal('test'); - expect(query.ref).to.include(window.location.href); - }); - }); -}); diff --git a/test/spec/modules/relevantAnalyticsAdapter_spec.js b/test/spec/modules/relevantAnalyticsAdapter_spec.js deleted file mode 100644 index 3e31db2d7dc..00000000000 --- a/test/spec/modules/relevantAnalyticsAdapter_spec.js +++ /dev/null @@ -1,43 +0,0 @@ -import relevantAnalytics from '../../../modules/relevantAnalyticsAdapter.js'; -import adapterManager from 'src/adapterManager'; -import events from 'src/events'; -import constants from 'src/constants.json' -import { expect } from 'chai'; - -describe('Relevant Analytics Adapter', () => { - beforeEach(() => { - adapterManager.enableAnalytics({ - provider: 'relevant' - }); - }); - - afterEach(() => { - relevantAnalytics.disableAnalytics(); - }); - - it('should pass all events to the global array', () => { - // Given - const testEvents = [ - { ev: constants.EVENTS.AUCTION_INIT, args: { test: 1 } }, - { ev: constants.EVENTS.BID_REQUESTED, args: { test: 2 } }, - ]; - - // When - testEvents.forEach(({ ev, args }) => ( - events.emit(ev, args) - )); - - // Then - const eventQueue = (window.relevantDigital || {}).pbEventLog; - expect(eventQueue).to.be.an('array'); - expect(eventQueue.length).to.be.at.least(testEvents.length); - - // The last events should be our test events - const myEvents = eventQueue.slice(-testEvents.length); - testEvents.forEach(({ ev, args }, idx) => { - const actualEvent = myEvents[idx]; - expect(actualEvent.ev).to.eql(ev); - expect(actualEvent.args).to.eql(args); - }); - }); -}); diff --git a/test/spec/modules/reloadBidAdapter_spec.js b/test/spec/modules/reloadBidAdapter_spec.js deleted file mode 100644 index b22dd9e7b92..00000000000 --- a/test/spec/modules/reloadBidAdapter_spec.js +++ /dev/null @@ -1,295 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/reloadBidAdapter.js'; - -let getParams = () => { - return JSON.parse(JSON.stringify({ - 'plcmID': 'placement_01', - 'partID': 'part00', - 'opdomID': 1, - 'bsrvID': 1, - 'type': 'pcm' - })); -}; - -let getBidderRequest = () => { - return JSON.parse(JSON.stringify({ - bidderCode: 'reload', - auctionId: 'd3e07445-ab06-44c8-a9dd-5ef9af06d2a6', - bidderRequestId: '7101db09af0db2', - start: new Date().getTime(), - bids: [{ - bidder: 'reload', - bidId: '84ab500420319d', - bidderRequestId: '7101db09af0db2', - auctionId: 'd3e07445-ab06-44c8-a9dd-5ef9af06d2a6', - params: getParams() - }] - })); -}; - -let getValidBidRequests = () => { - return JSON.parse(JSON.stringify([ - { - 'bidder': 'reload', - 'params': getParams(), - 'mediaTypes': { - 'banner': { - 'sizes': [[160, 600]] - } - }, - 'adUnitCode': '1b243858-3c53-43dc-9fdf-89f839ea4a0f', - 'transactionId': '8cbafa10-123d-4673-a1a5-04a1c7d62ded', - 'sizes': [[160, 600]], - 'bidId': '2236e11dc09931', - 'bidderRequestId': '1266bb886c2267', - 'auctionId': '4fb72c4d-94dc-4db1-8fac-3c2090ceeec0', - 'src': 'client', - 'bidRequestsCount': 1 - } - ])); -} - -let getExt1ServerResponse = () => { - return JSON.parse(JSON.stringify({ - 'pcmdata': { - 'thisVer': '100', - 'plcmSett': { - 'name': 'zz_test_mariano_adapter', - 'Version': '210', - 'lifeSpan': '100', - 'versionFolder': 'v4.14q', - 'versionFolderA': 'v4.14q', - 'versionFolderB': '', - 'stage': 'zz_test_mariano_adapter', - 'synchro': 1556916507000, - 'localCache': 'true', - 'testCase': 'A:00_B:100', - 'opdomain': '1', - 'checksum': '6378', - 'cpm': '0', - 'bstfct': '100', - 'totstop': 'false', - 'pcmurl': 'bidsrv01.reload.net' - }, - 'srvUrl': 'bidsrv01.reload.net', - 'instr': {'go': true, 'prc': 32, 'cur': 'USD'}, - 'statStr': 'eyN4aHYnQCk5OTotOC', - 'status': 'ok', - 'message': '', - 'log': '---- LOG ----' - }, - 'plcmID': 'zz_test_mariano_adapter', - 'partID': 'prx_part', - 'opdomID': '0', - 'bsrvID': 1, - 'adUnitCode': '1b243858-3c53-43dc-9fdf-89f839ea4a0f', - 'banner': {'w': 300, 'h': 250} - })); -} - -let getExt2ServerResponse = () => { - return JSON.parse(JSON.stringify({ - 'pcmdata': { - 'thisVer': '100', - 'plcmSett': { - 'name': 'placement_01', - 'Version': '210', - 'lifeSpan': '100', - 'versionFolder': 'v4.14q', - 'versionFolderA': 'v4.14q', - 'versionFolderB': '', - 'stage': 'placement_01', - 'synchro': 1556574760000, - 'localCache': 'true', - 'testCase': 'A:00_B:100', - 'opdomain': '1', - 'checksum': '6378', - 'cpm': '0', - 'bstfct': '100', - 'totstop': 'false', - 'pcmurl': 'bidsrv00.reload.net' - }, - 'srvUrl': 'bidsrv00.reload.net', - 'log': 'incomp_input_obj_version', - 'message': 'incomp_input_obj_version', - 'status': 'error' - }, - 'plcmID': 'placement_01', - 'partID': 'prx_part', - 'opdomID': '0', - 'bsrvID': 1, - 'adUnitCode': '1b243858-3c53-43dc-9fdf-89f839ea4a0f', - 'banner': {'w': 160, 'h': 600} - })); -} - -let getServerResponse = (pExt) => { - return JSON.parse(JSON.stringify({ - 'body': { - 'id': '2759340f70210d', - 'bidid': 'fbs-br-3mzdbycetjv8f8079', - 'seatbid': [ - { - 'bid': [ - { - 'id': 'fbs-br-stbd-bd-3mzdbycetjv8f807b', - 'price': 0, - 'nurl': '', - 'adm': '', - 'ext': pExt - } - ], - 'seat': 'fbs-br-stbd-3mzdbycetjv8f807a', - 'group': 0 - } - ] - }, - 'headers': {} - })); -} - -describe('ReloadAdapter', function () { - describe('isBidRequestValid', function () { - var bid = { - 'bidder': 'reload', - 'params': { - 'plcmID': 'placement_01', - 'partID': 'part00', - 'opdomID': 1, - 'bsrvID': 23, - 'type': 'pcm' - }, - '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(bid)).to.equal(true); - }); - - it('should return false when bsrvID is not number', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'plcmID': 'placement_01', - 'partID': 'part00', - 'opdomID': 1, - 'bsrvID': 'abc' - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when bsrvID > 99', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'plcmID': 'placement_01', - 'partID': 'part00', - 'opdomID': 1, - 'bsrvID': 230 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when bsrvID < 0', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'plcmID': 'placement_01', - 'partID': 'part00', - 'opdomID': 1, - 'bsrvID': -3, - 'type': 'pcm' - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'plcmID': 'placement_01' - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests()', function () { - let vRequests = spec.buildRequests(getValidBidRequests(), {}); - let vData = JSON.parse(vRequests[0].data); - - it('should send one requests', () => { - expect(vRequests.length).to.equal(1); - }); - - it('should send one requests, one impression', () => { - expect(vData.imp.length).to.equal(1); - }); - - it('should exists ext.type and ext.pcmdata', () => { - expect(vData.imp[0].banner).to.exist; - expect(vData.imp[0].banner.ext).to.exist; - expect(vData.imp[0].banner.ext.type).to.exist; - expect(vData.imp[0].banner.ext.pcmdata).to.exist; - expect(vData.imp[0].banner.ext.type).to.equal('pcm'); - }); - }); - - describe('interpretResponse()', function () { - it('Returns an empty array', () => { - let vData = spec.interpretResponse(getServerResponse(getExt2ServerResponse()), {}); - - expect(vData.length).to.equal(0); - }); - - it('Returns an array with one response', () => { - let vData = spec.interpretResponse(getServerResponse(getExt1ServerResponse()), {}); - expect(vData.length).to.equal(1); - }); - - it('required fileds', () => { - let vData = spec.interpretResponse(getServerResponse(getExt1ServerResponse()), {}); - expect(vData.length).to.equal(1); - expect(vData[0]).to.have.all.keys(['requestId', 'ad', 'cpm', 'width', 'height', 'creativeId', 'currency', 'ttl', 'netRevenue']); - }); - - it('CPM great than 0', () => { - let vData = spec.interpretResponse(getServerResponse(getExt1ServerResponse()), {}); - expect(vData[0].cpm).to.greaterThan(0); - }); - - it('instruction empty', () => { - let vResponse = Object.assign({}, getServerResponse(getExt1ServerResponse())); - vResponse.body.seatbid[0].bid[0].ext.pcmdata.instr = null; - let vData = spec.interpretResponse(vResponse, {}); - expect(vData.length).to.equal(0); - - vResponse = Object.assign({}, getServerResponse(getExt1ServerResponse())); - vResponse.body.seatbid[0].bid[0].ext.pcmdata.instr = undefined; - vData = spec.interpretResponse(vResponse, {}); - expect(vData.length).to.equal(0); - - vResponse = Object.assign({}, getServerResponse(getExt1ServerResponse())); - vResponse.body.seatbid[0].bid[0].ext.pcmdata.instr.go = undefined; - vData = spec.interpretResponse(vResponse, {}); - expect(vData.length).to.equal(0); - }); - - it('instruction with go = false', () => { - let vResponse = getServerResponse(getExt1ServerResponse()); - vResponse.body.seatbid[0].bid[0].ext.pcmdata.instr.go = false; - let vData = spec.interpretResponse(vResponse, {}); - expect(vData.length).to.equal(0); - }); - - it('incompatibility output object version (thisVer)', () => { - let vResponse = getServerResponse(getExt1ServerResponse()); - vResponse.body.seatbid[0].bid[0].ext.pcmdata.thisVer = '200'; - let vData = spec.interpretResponse(vResponse, {}); - expect(vData.length).to.equal(0); - }); - }); -}); diff --git a/test/spec/modules/resultsmediaBidAdapter_spec.js b/test/spec/modules/resultsmediaBidAdapter_spec.js deleted file mode 100644 index 0e2d4c0013a..00000000000 --- a/test/spec/modules/resultsmediaBidAdapter_spec.js +++ /dev/null @@ -1,574 +0,0 @@ -import {spec} from '../../../modules/resultsmediaBidAdapter.js'; -import * as utils from '../../../src/utils.js'; -import * as sinon from 'sinon'; - -var r1adapter = spec; - -describe('resultsmedia adapter tests', function () { - beforeEach(function() { - this.defaultBidderRequest = { - 'refererInfo': { - 'referer': 'Reference Page', - 'stack': [ - 'aodomain.dvl', - 'page.dvl' - ] - } - }; - }); - - describe('Verify 1.0 POST Banner Bid Request', function () { - it('buildRequests works', function () { - var bidRequestList = [ - { - 'bidder': 'resultsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaType': 'banner', - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'sizes': [[300, 250]], - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - expect(bidRequest.url).to.have.string('https://bid306.rtbsrv.com/bidder/?bid=3mhdom&zoneId=9999&hbv='); - expect(bidRequest.method).to.equal('POST'); - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.site).to.not.equal(null); - expect(openrtbRequest.site.ref).to.equal('Reference Page'); - expect(openrtbRequest.device).to.not.equal(null); - expect(openrtbRequest.device.ua).to.equal(navigator.userAgent); - expect(openrtbRequest.device.dnt).to.equal(0); - expect(openrtbRequest.imp[0].banner).to.not.equal(null); - expect(openrtbRequest.imp[0].banner.format[0].w).to.equal(300); - expect(openrtbRequest.imp[0].banner.format[0].h).to.equal(250); - expect(openrtbRequest.imp[0].ext.bidder.zoneId).to.equal(9999); - }); - - it('interpretResponse works', function() { - var bidList = { - 'body': [ - { - 'impid': 'div-gpt-ad-1438287399331-0', - 'w': 300, - 'h': 250, - 'adm': '
My Compelling Ad
', - 'price': 1, - 'crid': 'cr-cfy24' - } - ] - }; - - var bannerBids = r1adapter.interpretResponse(bidList); - - expect(bannerBids.length).to.equal(1); - const bid = bannerBids[0]; - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.creativeId).to.equal('cr-cfy24'); - expect(bid.currency).to.equal('USD'); - expect(bid.netRevenue).to.equal(true); - expect(bid.cpm).to.equal(1.0); - expect(bid.ttl).to.equal(350); - }); - }); - - describe('Verify POST Video Bid Request', function() { - it('buildRequests works', function () { - var bidRequestList = [ - { - 'bidder': 'resultsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'video': { - 'playerSize': [640, 480], - 'context': 'instream' - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-1', - 'sizes': [ - [300, 250] - ], - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - expect(bidRequest.url).to.have.string('https://bid306.rtbsrv.com/bidder/?bid=3mhdom&zoneId=9999&hbv='); - expect(bidRequest.method).to.equal('POST'); - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.site).to.not.equal(null); - expect(openrtbRequest.device).to.not.equal(null); - expect(openrtbRequest.device.ua).to.equal(navigator.userAgent); - expect(openrtbRequest.device).to.have.property('dnt'); - expect(openrtbRequest.imp[0].video).to.not.equal(null); - expect(openrtbRequest.imp[0].video.w).to.equal(640); - expect(openrtbRequest.imp[0].video.h).to.equal(480); - expect(openrtbRequest.imp[0].video.mimes[0]).to.equal('video/mp4'); - expect(openrtbRequest.imp[0].video.protocols).to.eql([2, 3, 5, 6]); - expect(openrtbRequest.imp[0].video.startdelay).to.equal(0); - expect(openrtbRequest.imp[0].video.skip).to.equal(0); - expect(openrtbRequest.imp[0].video.playbackmethod).to.eql([1, 2, 3, 4]); - expect(openrtbRequest.imp[0].video.delivery[0]).to.equal(1); - expect(openrtbRequest.imp[0].video.api).to.eql([1, 2, 5]); - }); - - it('interpretResponse works', function() { - var bidList = { - 'body': [ - { - 'impid': 'div-gpt-ad-1438287399331-1', - 'price': 1, - 'adm': 'https://example.com/', - 'adomain': [ - 'test.com' - ], - 'cid': '467415', - 'crid': 'cr-vid', - 'w': 800, - 'h': 600 - } - ] - }; - - var videoBids = r1adapter.interpretResponse(bidList); - - expect(videoBids.length).to.equal(1); - const bid = videoBids[0]; - expect(bid.width).to.equal(800); - expect(bid.height).to.equal(600); - expect(bid.vastUrl).to.equal('https://example.com/'); - expect(bid.mediaType).to.equal('video'); - expect(bid.creativeId).to.equal('cr-vid'); - expect(bid.currency).to.equal('USD'); - expect(bid.netRevenue).to.equal(true); - expect(bid.cpm).to.equal(1.0); - expect(bid.ttl).to.equal(600); - }); - }); - - describe('misc buildRequests', function() { - it('should send GDPR Consent data to resultsmedia tag', function () { - var bidRequestList = [ - { - 'bidder': 'resultsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-3', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var consentString = 'testConsentString'; - var gdprBidderRequest = this.defaultBidderRequest; - gdprBidderRequest.gdprConsent = { - 'gdprApplies': true, - 'consentString': consentString - }; - - var bidRequest = r1adapter.buildRequests(bidRequestList, gdprBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.user.ext.consent).to.equal(consentString); - expect(openrtbRequest.regs.ext.gdpr).to.equal(true); - }); - - it('prefer 2.0 sizes', function () { - var bidRequestList = [ - { - 'bidder': 'resultsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 600]] - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'sizes': [[300, 250]], - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.imp[0].banner.format[0].w).to.equal(300); - expect(openrtbRequest.imp[0].banner.format[0].h).to.equal(600); - }); - - it('does not return request for invalid banner size configuration', function () { - var bidRequestList = [ - { - 'bidder': 'resultsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300]] - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - expect(bidRequest.method).to.be.undefined; - }); - - it('does not return request for missing banner size configuration', function () { - var bidRequestList = [ - { - 'bidder': 'resultsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'banner': {} - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - expect(bidRequest.method).to.be.undefined; - }); - - it('reject bad sizes', function () { - var bidRequestList = [ - { - 'bidder': 'resultsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'banner': {'sizes': [['400', '500'], ['4n0', '5g0']]} - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.imp[0].banner.format.length).to.equal(1); - }); - - it('dnt is correctly set to 1', function () { - var bidRequestList = [ - { - 'bidder': 'resultsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 600]] - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var dntStub = sinon.stub(utils, 'getDNT').returns(1); - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - dntStub.restore(); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.device.dnt).to.equal(1); - }); - - it('supports string video sizes', function () { - var bidRequestList = [ - { - 'bidder': 'resultsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'video': { - 'context': 'instream', - 'playerSize': ['600', '300'] - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-1', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.imp[0].video.w).to.equal(600); - expect(openrtbRequest.imp[0].video.h).to.equal(300); - }); - - it('rejects bad video sizes', function () { - var bidRequestList = [ - { - 'bidder': 'resultsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'video': { - 'context': 'instream', - 'playerSize': ['badWidth', 'badHeight'] - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-1', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.imp[0].video.w).to.be.undefined; - expect(openrtbRequest.imp[0].video.h).to.be.undefined; - }); - - it('supports missing video size', function () { - var bidRequestList = [ - { - 'bidder': 'resultsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'video': { - 'context': 'instream' - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-1', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.imp[0].video.w).to.be.undefined; - expect(openrtbRequest.imp[0].video.h).to.be.undefined; - }); - - it('should return empty site data when refererInfo is missing', function() { - delete this.defaultBidderRequest.refererInfo; - var bidRequestList = [ - { - 'bidder': 'resultsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaType': 'banner', - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'sizes': [[300, 250]], - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(bidRequest.data); - - expect(openrtbRequest.site.domain).to.equal(''); - expect(openrtbRequest.site.page).to.equal(''); - expect(openrtbRequest.site.ref).to.equal(''); - }); - }); - - it('should return empty site.domain and site.page when refererInfo.stack is empty', function() { - this.defaultBidderRequest.refererInfo.stack = []; - var bidRequestList = [ - { - 'bidder': 'resultsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaType': 'banner', - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'sizes': [[300, 250]], - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(bidRequest.data); - - expect(openrtbRequest.site.domain).to.equal(''); - expect(openrtbRequest.site.page).to.equal(''); - expect(openrtbRequest.site.ref).to.equal('Reference Page'); - }); - - it('should secure correctly', function() { - this.defaultBidderRequest.refererInfo.stack[0] = ['https://securesite.dvl']; - var bidRequestList = [ - { - 'bidder': 'resultsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaType': 'banner', - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'sizes': [[300, 250]], - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(bidRequest.data); - - expect(openrtbRequest.imp[0].secure).to.equal(1); - }); - - it('should pass schain', function() { - var schain = { - 'ver': '1.0', - 'complete': 1, - 'nodes': [{ - 'asi': 'indirectseller.com', - 'sid': '00001', - 'hp': 1 - }, { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 1 - }] - }; - var bidRequestList = [ - { - 'bidder': 'resultsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaType': 'banner', - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'sizes': [[300, 250]], - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead', - 'schain': schain - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(bidRequest.data); - - expect(openrtbRequest.source.ext.schain).to.deep.equal(schain); - }); - - describe('misc interpretResponse', function () { - it('No bid response', function() { - var noBidResponse = r1adapter.interpretResponse({ - 'body': '' - }); - expect(noBidResponse.length).to.equal(0); - }); - }); - - describe('isBidRequestValid', function () { - var bid = { - 'bidder': 'resultsmedia', - 'params': { - 'zoneId': 9999 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'adUnitCode': 'bannerDiv' - }; - - it('should return true when required params found', function () { - expect(r1adapter.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when placementId missing', function () { - delete bid.params.zoneId; - expect(r1adapter.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('getUserSyncs', function () { - it('returns an empty string', function () { - expect(r1adapter.getUserSyncs()).to.deep.equal([]); - }); - }); -}); diff --git a/test/spec/modules/revcontentBidAdapter_spec.js b/test/spec/modules/revcontentBidAdapter_spec.js deleted file mode 100644 index 0a0263837c6..00000000000 --- a/test/spec/modules/revcontentBidAdapter_spec.js +++ /dev/null @@ -1,351 +0,0 @@ -// jshint esversion: 6, es3: false, node: true -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'; - -describe('revcontent adapter', function () { - let serverResponse, bidRequest, bidResponses; - let bids = []; - - describe('isBidRequestValid', function () { - let bid = { - bidder: 'revcontent', - nativeParams: {}, - params: { - size: {width: 300, height: 250}, - apiKey: '8a33fa9cf220ae685dcc3544f847cdda858d3b1c', - userId: 673, - domain: 'test.com', - endpoint: 'trends-s0.revcontent.com' - } - }; - - it('should return true when required params found', function () { - assert(spec.isBidRequestValid(bid)); - }); - - it('should return false when required params are missing', function () { - bid.params.apiKey = undefined; - assert.isFalse(spec.isBidRequestValid(bid)); - }); - }); - - describe('buildRequests', function () { - it('should send request with correct structure', function () { - let validBidRequests = [{ - bidder: 'revcontent', - nativeParams: {}, - params: { - size: {width: 300, height: 250}, - apiKey: '8a33fa9cf220ae685dcc3544f847cdda858d3b1c', - userId: 673, - widgetId: 33861, - endpoint: 'trends-s0.revcontent.com' - } - }]; - let request = spec.buildRequests(validBidRequests, {refererInfo: {referer: '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.ok(request.data); - }); - - it('should have default request structure', function () { - let keys = 'method,options,url,data,bid'.split(','); - let validBidRequests = [{ - bidder: 'revcontent', - nativeParams: {}, - params: { - size: {width: 300, height: 250}, - apiKey: '8a33fa9cf220ae685dcc3544f847cdda858d3b1c', - userId: 673, - domain: 'test.com', - endpoint: 'trends-s0.revcontent.com' - } - }]; - let request = spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}); - - request = request[0]; - let data = Object.keys(request); - - assert.deepEqual(keys, data); - }); - - it('should send info about device and unique bidfloor', function () { - let validBidRequests = [{ - bidder: 'revcontent', - nativeParams: {}, - params: { - size: {width: 300, height: 250}, - apiKey: '8a33fa9cf220ae685dcc3544f847cdda858d3b1c', - userId: 673, - domain: 'test.com', - endpoint: 'trends-s0.revcontent.com', - bidfloor: 0.05 - } - }]; - let request = spec.buildRequests(validBidRequests, {refererInfo: {referer: 'page'}}); - request = JSON.parse(request[0].data); - assert.equal(request.imp[0].bidfloor, 0.05); - assert.equal(request.device.ua, navigator.userAgent); - }); - - it('should send info about the site and default bidfloor', function () { - let validBidRequests = [{ - bidder: 'revcontent', - nativeParams: { - image: { - required: false - }, - 'title': { - required: false, - len: 140 - }, - clickUrl: { - required: false - }, - sponsoredBy: { - id: 5, - name: 'data', - type: 1 - } - }, - params: { - size: {width: 300, height: 250}, - apiKey: '8a33fa9cf220ae685dcc3544f847cdda858d3b1c', - userId: 673, - domain: 'test.com', - endpoint: 'trends-s0.revcontent.com' - } - }]; - let refererInfo = {referer: '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', - cat: ['IAB17'], - publisher: {id: 673, domain: 'test.com'} - }); - }); - }); - - describe('interpretResponse', function () { - it('should return if no body in response', function () { - let serverResponse = {}; - let bidRequest = {}; - - assert.ok(!spec.interpretResponse(serverResponse, bidRequest)); - }); - - const serverResponse = { - body: { - id: '5d61ca27-1b7a-4d5a-90ad-bbfc93e53f58', - seatbid: [ - { - bid: [ - { - id: '6bbe3eed-f443-4e2b-a8da-57fd6327b37d', - impid: '1', - price: 0.1, - adid: '4162547', - nurl: 'https://trends-s0.revcontent.com/push/track/?p=${AUCTION_PRICE}&d=nTCdHIfsgKOLFuV7DS1LF%2FnTk5HiFduGU65BgKgB%2BvKyG9YV7ceQWN76HMbBE0C6gwQeXUjravv3Hq5x9TT8CM6r2oUNgkGC9mhgv2yroTH9i3cSoH%2BilxyY19fMXFirtBz%2BF%2FEXKi4bsNh%2BDMPfj0L4elo%2FJEZmx4nslvOneJJjsFjJJtUJc%2F3UPivOisSCa%2B36mAgFQqt%2FSWBriYB%2BVAufz70LaGspF6T6jDzuIyVFJUpLhZVDtLRSJEzh7Lyzzw1FmYarp%2FPg0gZDY48aDdjw5A3Tlj%2Bap0cPHLDprNOyF0dmHDn%2FOVJEDRTWvrQ2JNK1t%2Fg1bGHIih0ec6XBVIBNurqRpLFBuUY6LgXCt0wRZWTByTEZ8AEv8IoYVILJAL%2BXL%2F9IyS4eTcdOUfn5X7gT8QBghCrAFrsCg8ZXKgWddTEXbpN1lU%2FzHdI5eSHkxkJ6WcYxSkY9PyripaIbmKiyb98LQMgTD%2B20RJO5dAmXTQTAcauw6IUPTjgSPEU%2Bd6L5Txd3CM00Hbd%2Bw1bREIQcpKEmlMwrRSwe4bu1BCjlh5A9gvU9Xc2sf7ekS3qPPmtp059r5IfzdNFQJB5aH9HqeDEU%2FxbMHx4ggMgojLBBL1fKrCKLAteEDQxd7PVmFJv7GHU2733vt5TnjKiEhqxHVFyi%2B0MIYMGIziM5HfUqfq3KUf%2F%2FeiCtJKXjg7FS6hOambdimSt7BdGDIZq9QECWdXsXcQqqVLwli27HYDMFVU3TWWRyjkjbhnQID9gQJlcpwIi87jVAODb6qP%2FKGQ%3D%3D', - adm: '{"ver":"1.1","assets":[{"id":3,"required":1,"img":{"url":"//img.revcontent.com/?url=https://revcontent-p0.s3.amazonaws.com/content/images/15761052960288727821.jpg&static=true"}},{"id":0,"required":1,"title":{"text":"Do You Eat Any of These Craving-trigger Foods?"}},{"id":5,"required":1,"data":{"value":""}}],"link":{"url":"https://trends-s0.revcontent.com/click.php?d=A7EVbNYBVyonty19Ak08zCr9J54qg%2Bmduq6p0Zyn5%2F%2Bapm4deUo9VAXmOGEIbUBf6i7m3%2F%2FWJm%2FzTha8SJ%2Br9MZL9jhhUxDeiKb6aRY1biLrvr6tFUd1phvtKqVmPd76l9VBLFMxS1brSzKjRCJlIGmyGJg7ueFvxpE9X%2BpHmdbE2uqUdRC49ENO3XZyHCCKMAZ8XD29fasX9Kli9mKpZTqw8vayFlXbVYSUwB8wfSwCt1sIUrt0aICYc0jcyWU3785GTS1xXzQj%2FIVszFYYrdTWd%2BDijjNZtFny0OomPHp8lRy5VcQVCuLpw0Fks4myvsE38XcNvs4wO3tWTNrI%2BMqcW1%2BD2OnMSq5nN5FCbmi2ly%2F1LbN9fibaFvW%2FQbzQhN9ZsAwmhm409UTtdmSA6hd96vDxDWLeUJhVO3UQyI0yq2TtVnB9tEICD8mZNWwYehOab%2BQ1EWmTerF6ZCDx8RyZus1UrsDfRwvTCyUjCmkZhmeo4QVJkpPy6QobCsngSaxkkKhH%2Fb7coZyBXXEt3ORoYBLUbfRO6nR8GdIt8413vrYr4gTAroh46VcWK0ls0gFNe2u3%2FqP%2By1yLKbzDVaR%2Fa02G%2Biiqbw86sCYfsy7qK9atyjNTm8RkH6JLESUzxc6IEazu4iwHKGnu5phTacmseXCi8y9Y5AdBZn8VnLP%2F2a%2FyAqq93xEH%2BIrkAdhGRY1tY39rBYAtvH%2FVyNFZcong%2FutUMYbp0WhDNyfl6iWxmpE28Cx9KDcqXss0NIwQm0AWeu8ogJCIG3faAkm5PdFsUdf2X9h3HuFDbnbvnXW27ml6z9GykEzv%2F8aSZlMZ"}}' - } - ] - } - ], - bidid: '7f729368-edb2-427a-bde7-a55b3bf8837c' - }, - headers: {} - }; - - const bidRequest = { - method: 'POST', - options: { - contentType: 'application/json' - }, - url: 'https://trends-s0.revcontent.com/rtb?apiKey=8a33fa9cf220ae685dcc3544f847cdda858d3b1c&userId=673', - data: '{"id":"5d61ca27-1b7a-4d5a-90ad-bbfc93e53f58","imp":[{"id":1,"bidderRequestId":"14e4dab7b5396e8","auctionId":"5d61ca27-1b7a-4d5a-90ad-bbfc93e53f58","transactionId":"69e69abf-a3ea-484d-a81c-d48dd0d5eaa3","native":{"request":{"ver":"1.1","context":2,"contextsubtype":21,"plcmttype":4,"plcmtcnt":4,"assets":[{"required":0,"id":3,"img":{"type":3}},{"required":0,"id":0,"title":{"len":140}},{"required":0,"id":5,"data":{"type":1}}]},"ver":"1.1","battr":[1,3,8,11,17]},"instl":0,"bidfloor":0.1,"secure":"1"}],"site":{"domain":"test.com","page":"https://feudfun.com/test22/revcontent_example.php","cat":["IAB17"],"publisher":{"id":673,"domain":"test.com"}},"device":{"ua":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:71.0) Gecko/20100101 Firefox/71.0","language":"en"},"user":{"id":1},"at":2,"bcat":["IAB24","IAB25","IAB25-1","IAB25-2","IAB25-3","IAB25-4","IAB25-5","IAB25-6","IAB25-7","IAB26","IAB26-1","IAB26-2","IAB26-3","IAB26-4"]}', - bid: [ - { - bidder: 'revcontent', - params: { - size: { - width: 300, - height: 250 - }, - apiKey: '8a33fa9cf220ae685dcc3544f847cdda858d3b1c', - userId: 673, - domain: 'test.com', - endpoint: 'trends-s0.revcontent.com' - }, - crumbs: { - pubcid: '7a0b4adc-c109-49f0-aadc-4a4b62ebe269' - }, - nativeParams: { - image: { - required: false - }, - 'title': { - required: false, - len: 140 - }, - clickUrl: { - required: false - }, - sponsoredBy: { - id: 5, - name: 'data', - type: 1 - } - }, - mediaTypes: { - native: { - image: { - required: false - }, - title: { - required: false, - len: 140 - }, - clickUrl: { - required: false - }, - sponsoredBy: { - id: 5, - name: 'data', - type: 1 - } - } - }, - adUnitCode: '/19968336/header-bid-tag-1', - transactionId: '69e69abf-a3ea-484d-a81c-d48dd0d5eaa3', - sizes: [], - bidId: '294a7f446202848', - bidderRequestId: '14e4dab7b5396e8', - auctionId: '5d61ca27-1b7a-4d5a-90ad-bbfc93e53f58', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 - } - ] - }; - - it('should set correct native params', function () { - const result = spec.interpretResponse(serverResponse, bidRequest)[0]; - - assert.equal(result.bidder, 'revcontent'); - assert.equal(result.bidderCode, 'revcontent'); - assert.equal(result.mediaType, 'native'); - assert.equal(result.requestId, '294a7f446202848'); - assert.equal(result.cpm, '0.1'); - assert.equal(result.creativeId, '4162547'); - }); - - it('validate template 728x90', function () { - bidRequest.bid[0].params.size.width = 728; - bidRequest.bid[0].params.size.height = 90; - - const result = spec.interpretResponse(serverResponse, bidRequest)[0]; - assert.equal(result.bidder, 'revcontent'); - assert.equal(result.bidderCode, 'revcontent'); - assert.equal(result.mediaType, 'native'); - assert.equal(result.requestId, '294a7f446202848'); - assert.equal(result.cpm, '0.1'); - assert.equal(result.creativeId, '4162547'); - }); - - it('validate template 300x600', function () { - bidRequest.bid[0].params.size.width = 300; - bidRequest.bid[0].params.size.height = 600; - - const result = spec.interpretResponse(serverResponse, bidRequest)[0]; - assert.equal(result.bidder, 'revcontent'); - assert.equal(result.bidderCode, 'revcontent'); - assert.equal(result.mediaType, 'native'); - assert.equal(result.requestId, '294a7f446202848'); - assert.equal(result.cpm, '0.1'); - assert.equal(result.creativeId, '4162547'); - }); - - it('validate template custom template', function () { - bidRequest.bid[0].params.template = '

{title}

SEE MORE
'; - - const result = spec.interpretResponse(serverResponse, bidRequest)[0]; - assert.equal(result.bidder, 'revcontent'); - assert.equal(result.bidderCode, 'revcontent'); - assert.equal(result.mediaType, 'native'); - assert.equal(result.requestId, '294a7f446202848'); - assert.equal(result.cpm, '0.1'); - assert.equal(result.creativeId, '4162547'); - }); - - it('validate template custom invalid template', function () { - bidRequest.bid[0].params.size.width = 100; - bidRequest.bid[0].params.size.height = 200; - - const result = spec.interpretResponse(serverResponse, bidRequest)[0]; - assert.equal(result.bidder, 'revcontent'); - assert.equal(result.bidderCode, 'revcontent'); - assert.equal(result.mediaType, 'native'); - assert.equal(result.requestId, '294a7f446202848'); - assert.equal(result.cpm, '0.1'); - assert.equal(result.creativeId, '4162547'); - }); - - it('should return empty when there is no bids in response', function () { - const serverResponse = { - body: { - id: null, - bidid: null, - seatbid: [{bid: []}], - cur: 'USD' - } - }; - let bidRequest = { - data: {}, - bids: [{bidId: 'bidId1'}] - }; - const result = spec.interpretResponse(serverResponse, bidRequest)[0]; - assert.ok(!result); - }); - }); - - describe('onBidWon', function () { - it('default bid won', function () { - const bid = { - nurl: 'https://trends-s0.revcontent.com/push/track/?p=${AUCTION_PRICE}&d=nTCdHIfsgKOLFuV7DS1LF%2FnTk5HiFduGU65BgKgB%2BvKyG9YV7ceQWN76HMbBE0C6gwQeXUjravv3Hq5x9TT8CM6r2oUNgkGC9mhgv2yroTH9i3cSoH%2BilxyY19fMXFirtBz%2BF%2FEXKi4bsNh%2BDMPfj0L4elo%2FJEZmx4nslvOneJJjsFjJJtUJc%2F3UPivOisSCa%2B36mAgFQqt%2FSWBriYB%2BVAufz70LaGspF6T6jDzuIyVFJUpLhZVDtLRSJEzh7Lyzzw1FmYarp%2FPg0gZDY48aDdjw5A3Tlj%2Bap0cPHLDprNOyF0dmHDn%2FOVJEDRTWvrQ2JNK1t%2Fg1bGHIih0ec6XBVIBNurqRpLFBuUY6LgXCt0wRZWTByTEZ8AEv8IoYVILJAL%2BXL%2F9IyS4eTcdOUfn5X7gT8QBghCrAFrsCg8ZXKgWddTEXbpN1lU%2FzHdI5eSHkxkJ6WcYxSkY9PyripaIbmKiyb98LQMgTD%2B20RJO5dAmXTQTAcauw6IUPTjgSPEU%2Bd6L5Txd3CM00Hbd%2Bw1bREIQcpKEmlMwrRSwe4bu1BCjlh5A9gvU9Xc2sf7ekS3qPPmtp059r5IfzdNFQJB5aH9HqeDEU%2FxbMHx4ggMgojLBBL1fKrCKLAteEDQxd7PVmFJv7GHU2733vt5TnjKiEhqxHVFyi%2B0MIYMGIziM5HfUqfq3KUf%2F%2FeiCtJKXjg7FS6hOambdimSt7BdGDIZq9QECWdXsXcQqqVLwli27HYDMFVU3TWWRyjkjbhnQID9gQJlcpwIi87jVAODb6qP%2FKGQ%3D%3D', - cpm: '0.1' - }; - const result = spec.onBidWon(bid); - assert.ok(result); - }); - }); - - describe('onBidWon', function() { - const bid = { - nurl: 'https://trends-s0.revcontent.com/push/track/?p=${AUCTION_PRICE}&d=nTCdHIfsgKOLFuV7DS1LF%2FnTk5HiFduGU65BgKgB%2BvKyG9YV7ceQWN76HMbBE0C6gwQeXUjravv3Hq5x9TT8CM6r2oUNgkGC9mhgv2yroTH9i3cSoH%2BilxyY19fMXFirtBz%2BF%2FEXKi4bsNh%2BDMPfj0L4elo%2FJEZmx4nslvOneJJjsFjJJtUJc%2F3UPivOisSCa%2B36mAgFQqt%2FSWBriYB%2BVAufz70LaGspF6T6jDzuIyVFJUpLhZVDtLRSJEzh7Lyzzw1FmYarp%2FPg0gZDY48aDdjw5A3Tlj%2Bap0cPHLDprNOyF0dmHDn%2FOVJEDRTWvrQ2JNK1t%2Fg1bGHIih0ec6XBVIBNurqRpLFBuUY6LgXCt0wRZWTByTEZ8AEv8IoYVILJAL%2BXL%2F9IyS4eTcdOUfn5X7gT8QBghCrAFrsCg8ZXKgWddTEXbpN1lU%2FzHdI5eSHkxkJ6WcYxSkY9PyripaIbmKiyb98LQMgTD%2B20RJO5dAmXTQTAcauw6IUPTjgSPEU%2Bd6L5Txd3CM00Hbd%2Bw1bREIQcpKEmlMwrRSwe4bu1BCjlh5A9gvU9Xc2sf7ekS3qPPmtp059r5IfzdNFQJB5aH9HqeDEU%2FxbMHx4ggMgojLBBL1fKrCKLAteEDQxd7PVmFJv7GHU2733vt5TnjKiEhqxHVFyi%2B0MIYMGIziM5HfUqfq3KUf%2F%2FeiCtJKXjg7FS6hOambdimSt7BdGDIZq9QECWdXsXcQqqVLwli27HYDMFVU3TWWRyjkjbhnQID9gQJlcpwIi87jVAODb6qP%2FKGQ%3D%3D', - cpm: '0.1' - }; - - beforeEach(function() { - sinon.stub(utils, 'triggerPixel'); - }); - - afterEach(function() { - utils.triggerPixel.restore(); - }); - - it('make sure only 1 ajax call is happening', function() { - spec.onBidWon(bid); - expect(utils.triggerPixel.calledOnce).to.equal(true); - }); - }); -}); diff --git a/test/spec/modules/rhythmoneBidAdapter_spec.js b/test/spec/modules/rhythmoneBidAdapter_spec.js deleted file mode 100644 index 93735c019e1..00000000000 --- a/test/spec/modules/rhythmoneBidAdapter_spec.js +++ /dev/null @@ -1,786 +0,0 @@ -import {spec} from '../../../modules/rhythmoneBidAdapter.js'; -import * as utils from '../../../src/utils.js'; -import * as sinon from 'sinon'; - -var r1adapter = spec; - -describe('rhythmone adapter tests', function () { - beforeEach(function() { - this.defaultBidderRequest = { - 'refererInfo': { - 'referer': 'Reference Page', - 'stack': [ - 'aodomain.dvl', - 'page.dvl' - ] - } - }; - }); - - describe('Verify 1.0 POST Banner Bid Request', function () { - it('buildRequests works', function () { - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - 'zone': 'myzone', - 'path': 'mypath' - }, - 'mediaType': 'banner', - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'sizes': [[300, 250]], - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - expect(bidRequest.url).to.have.string('https://tag.1rx.io/rmp/myplacement/0/mypath?z=myzone&hbv='); - expect(bidRequest.method).to.equal('POST'); - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.site).to.not.equal(null); - expect(openrtbRequest.site.ref).to.equal('Reference Page'); - expect(openrtbRequest.device).to.not.equal(null); - expect(openrtbRequest.device.ua).to.equal(navigator.userAgent); - expect(openrtbRequest.device.dnt).to.equal(0); - expect(openrtbRequest.imp[0].banner).to.not.equal(null); - expect(openrtbRequest.imp[0].banner.format[0].w).to.equal(300); - expect(openrtbRequest.imp[0].banner.format[0].h).to.equal(250); - expect(openrtbRequest.imp[0].ext.bidder.zone).to.equal('myzone'); - expect(openrtbRequest.imp[0].ext.bidder.path).to.equal('mypath'); - }); - - it('interpretResponse works', function() { - var bidList = { - 'body': [ - { - 'impid': 'div-gpt-ad-1438287399331-0', - 'w': 300, - 'h': 250, - 'adm': '
My Compelling Ad
', - 'price': 1, - 'crid': 'cr-cfy24' - } - ] - }; - - var bannerBids = r1adapter.interpretResponse(bidList); - - expect(bannerBids.length).to.equal(1); - const bid = bannerBids[0]; - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.creativeId).to.equal('cr-cfy24'); - expect(bid.currency).to.equal('USD'); - expect(bid.netRevenue).to.equal(true); - expect(bid.cpm).to.equal(1.0); - expect(bid.ttl).to.equal(350); - }); - }); - - describe('Verify POST Video Bid Request', function() { - it('buildRequests works', function () { - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - 'zone': 'myzone', - 'path': 'mypath' - }, - 'mediaTypes': { - 'video': { - 'playerSize': [640, 480], - 'context': 'instream' - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-1', - 'sizes': [ - [300, 250] - ], - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - expect(bidRequest.url).to.have.string('https://tag.1rx.io/rmp/myplacement/0/mypath?z=myzone&hbv='); - expect(bidRequest.method).to.equal('POST'); - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.site).to.not.equal(null); - expect(openrtbRequest.device).to.not.equal(null); - expect(openrtbRequest.device.ua).to.equal(navigator.userAgent); - expect(openrtbRequest.device).to.have.property('dnt'); - expect(openrtbRequest.imp[0].video).to.not.equal(null); - expect(openrtbRequest.imp[0].video.w).to.equal(640); - expect(openrtbRequest.imp[0].video.h).to.equal(480); - expect(openrtbRequest.imp[0].video.mimes[0]).to.equal('video/mp4'); - expect(openrtbRequest.imp[0].video.protocols).to.eql([2, 3, 5, 6]); - expect(openrtbRequest.imp[0].video.startdelay).to.equal(0); - expect(openrtbRequest.imp[0].video.skip).to.equal(0); - expect(openrtbRequest.imp[0].video.playbackmethod).to.eql([1, 2, 3, 4]); - expect(openrtbRequest.imp[0].video.delivery[0]).to.equal(1); - expect(openrtbRequest.imp[0].video.api).to.eql([1, 2, 5]); - }); - - it('interpretResponse works', function() { - var bidList = { - 'body': [ - { - 'impid': 'div-gpt-ad-1438287399331-1', - 'price': 1, - 'nurl': 'https://testdomain/rmp/placementid/0/path?reqId=1636037', - 'adomain': [ - 'test.com' - ], - 'cid': '467415', - 'crid': 'cr-vid', - 'w': 800, - 'h': 600 - } - ] - }; - - var videoBids = r1adapter.interpretResponse(bidList); - - expect(videoBids.length).to.equal(1); - const bid = videoBids[0]; - expect(bid.width).to.equal(800); - expect(bid.height).to.equal(600); - expect(bid.vastUrl).to.equal('https://testdomain/rmp/placementid/0/path?reqId=1636037'); - expect(bid.meta.advertiserDomains).to.deep.equal(['test.com']); - expect(bid.mediaType).to.equal('video'); - expect(bid.creativeId).to.equal('cr-vid'); - expect(bid.currency).to.equal('USD'); - expect(bid.netRevenue).to.equal(true); - expect(bid.cpm).to.equal(1.0); - expect(bid.ttl).to.equal(600); - }); - }); - - describe('Verify Multi-Format ads and Multiple Size Bid Request', function() { - it('buildRequests works', function () { - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - 'zone': 'myzone', - 'path': 'mypath', - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [300, 250], - [300, 600] - ] - }, - 'video': { - 'playerSize': [[640, 480]], - 'context': 'instream' - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-5', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.site).to.not.equal(null); - expect(openrtbRequest.site.ref).to.equal('Reference Page'); - expect(openrtbRequest.device).to.not.equal(null); - expect(openrtbRequest.device.ua).to.equal(navigator.userAgent); - expect(openrtbRequest.device).to.have.property('dnt'); - expect(openrtbRequest.imp[0].video).to.not.equal(null); - expect(openrtbRequest.imp[0].video.w).to.equal(640); - expect(openrtbRequest.imp[0].video.h).to.equal(480); - expect(openrtbRequest.imp[0].video.mimes[0]).to.equal('video/mp4'); - expect(openrtbRequest.imp[0].video.protocols).to.eql([2, 3, 5, 6]); - expect(openrtbRequest.imp[0].video.startdelay).to.equal(0); - expect(openrtbRequest.imp[0].video.skip).to.equal(0); - expect(openrtbRequest.imp[0].video.playbackmethod).to.eql([1, 2, 3, 4]); - expect(openrtbRequest.imp[0].video.delivery[0]).to.equal(1); - expect(openrtbRequest.imp[0].video.api).to.eql([1, 2, 5]); - expect(openrtbRequest.imp[0].banner).to.not.equal(null); - expect(openrtbRequest.imp[0].banner.format[0].w).to.equal(300); - expect(openrtbRequest.imp[0].banner.format[0].h).to.equal(250); - expect(openrtbRequest.imp[0].banner.format[1].w).to.equal(300); - expect(openrtbRequest.imp[0].banner.format[1].h).to.equal(600); - expect(openrtbRequest.imp[0].ext.bidder.zone).to.equal('myzone'); - expect(openrtbRequest.imp[0].ext.bidder.path).to.equal('mypath'); - }); - - it('interpretResponse works', function() { - var bidList = { - 'body': { - 'id': '1e810245dd1779', - 'seatbid': [ - { - 'bid': [ - { - 'impid': 'div-gpt-ad-1438287399331-5', - 'price': 1, - 'nurl': 'https://testdomain/rmp/placementid/0/path?reqId=1636037', - 'adomain': [ - 'test.com' - ], - 'cid': '467415', - 'crid': 'cr-vid', - 'w': 800, - 'h': 600 - } - ] - } - ] - } - }; - - var forRMPMultiFormatResponse = r1adapter.interpretResponse(bidList); - - expect(forRMPMultiFormatResponse.length).to.equal(1); - const bid = forRMPMultiFormatResponse[0]; - expect(bid.width).to.equal(800); - expect(bid.height).to.equal(600); - expect(bid.vastUrl).to.equal('https://testdomain/rmp/placementid/0/path?reqId=1636037'); - expect(bid.mediaType).to.equal('video'); - expect(bid.creativeId).to.equal('cr-vid'); - expect(bid.currency).to.equal('USD'); - expect(bid.netRevenue).to.equal(true); - expect(bid.cpm).to.equal(1.0); - expect(bid.ttl).to.equal(600); - }); - }); - - describe('misc buildRequests', function() { - it('should send GDPR Consent data to RhythmOne tag', function () { - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - 'zone': 'myzone', - 'path': 'mypath' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-3', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var consentString = 'testConsentString'; - var gdprBidderRequest = this.defaultBidderRequest; - gdprBidderRequest.gdprConsent = { - 'gdprApplies': true, - 'consentString': consentString - }; - - var bidRequest = r1adapter.buildRequests(bidRequestList, gdprBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.user.ext.consent).to.equal(consentString); - expect(openrtbRequest.regs.ext.gdpr).to.equal(true); - }); - - it('prefer 2.0 sizes', function () { - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - 'zone': 'myzone', - 'path': 'mypath' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 600]] - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'sizes': [[300, 250]], - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.imp[0].banner.format[0].w).to.equal(300); - expect(openrtbRequest.imp[0].banner.format[0].h).to.equal(600); - }); - - it('does not return request for invalid banner size configuration', function () { - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - 'zone': 'myzone', - 'path': 'mypath' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300]] - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - expect(bidRequest.method).to.be.undefined; - }); - - it('does not return request for missing banner size configuration', function () { - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - 'zone': 'myzone', - 'path': 'mypath' - }, - 'mediaTypes': { - 'banner': {} - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - expect(bidRequest.method).to.be.undefined; - }); - - it('reject bad sizes', function () { - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - 'zone': 'myzone', - 'path': 'mypath' - }, - 'mediaTypes': { - 'banner': {'sizes': [['400', '500'], ['4n0', '5g0']]} - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.imp[0].banner.format.length).to.equal(1); - }); - - it('dnt is correctly set to 1', function () { - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 600]] - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var dntStub = sinon.stub(utils, 'getDNT').returns(1); - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - dntStub.restore(); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.device.dnt).to.equal(1); - }); - - it('sets floor', function () { - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - 'floor': 100.0 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 600]] - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.imp[0].bidfloor).to.equal(100.0); - }); - - it('supports string video sizes', function () { - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - }, - 'mediaTypes': { - 'video': { - 'context': 'instream', - 'playerSize': ['600', '300'] - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-1', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.imp[0].video.w).to.equal(600); - expect(openrtbRequest.imp[0].video.h).to.equal(300); - }); - - it('rejects bad video sizes', function () { - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - }, - 'mediaTypes': { - 'video': { - 'context': 'instream', - 'playerSize': ['badWidth', 'badHeight'] - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-1', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.imp[0].video.w).to.be.undefined; - expect(openrtbRequest.imp[0].video.h).to.be.undefined; - }); - - it('supports missing video size', function () { - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - }, - 'mediaTypes': { - 'video': { - 'context': 'instream' - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-1', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.imp[0].video.w).to.be.undefined; - expect(openrtbRequest.imp[0].video.h).to.be.undefined; - }); - - it('uses default zone and path', function () { - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [300, 600] - ] - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - const openrtbRequest = JSON.parse(bidRequest.data); - expect(openrtbRequest.imp[0].ext.bidder.zone).to.equal('1r'); - expect(openrtbRequest.imp[0].ext.bidder.path).to.equal('mvo'); - }); - - it('should return empty when required params not found', function () { - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'zone': 'myzone', - 'path': 'mypath' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [300, 250] - ] - } - }, - 'adUnitCode': 'div-gpt-ad-1438287399331-3', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - - expect(bidRequest).to.be.empty; - }); - - it('should return empty site data when refererInfo is missing', function() { - delete this.defaultBidderRequest.refererInfo; - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - 'zone': 'myzone', - 'path': 'mypath' - }, - 'mediaType': 'banner', - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'sizes': [[300, 250]], - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(bidRequest.data); - - expect(openrtbRequest.site.domain).to.equal(''); - expect(openrtbRequest.site.page).to.equal(''); - expect(openrtbRequest.site.ref).to.equal(''); - }); - }); - - it('should return empty site.domain and site.page when refererInfo.stack is empty', function() { - this.defaultBidderRequest.refererInfo.stack = []; - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - 'zone': 'myzone', - 'path': 'mypath' - }, - 'mediaType': 'banner', - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'sizes': [[300, 250]], - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(bidRequest.data); - - expect(openrtbRequest.site.domain).to.equal(''); - expect(openrtbRequest.site.page).to.equal(''); - expect(openrtbRequest.site.ref).to.equal('Reference Page'); - }); - - it('should secure correctly', function() { - this.defaultBidderRequest.refererInfo.stack[0] = ['https://securesite.dvl']; - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - 'zone': 'myzone', - 'path': 'mypath' - }, - 'mediaType': 'banner', - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'sizes': [[300, 250]], - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead' - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(bidRequest.data); - - expect(openrtbRequest.imp[0].secure).to.equal(1); - }); - - it('should pass schain', function() { - var schain = { - 'ver': '1.0', - 'complete': 1, - 'nodes': [{ - 'asi': 'indirectseller.com', - 'sid': '00001', - 'hp': 1 - }, { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 1 - }] - }; - var bidRequestList = [ - { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - 'zone': 'myzone', - 'path': 'mypath' - }, - 'mediaType': 'banner', - 'adUnitCode': 'div-gpt-ad-1438287399331-0', - 'sizes': [[300, 250]], - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'bidRequestsCount': 1, - 'bidId': '51ef8751f9aead', - 'schain': schain - } - ]; - - var bidRequest = r1adapter.buildRequests(bidRequestList, this.defaultBidderRequest); - const openrtbRequest = JSON.parse(bidRequest.data); - - expect(openrtbRequest.source.ext.schain).to.deep.equal(schain); - }); - - describe('misc interpretResponse', function () { - it('No bid response', function() { - var noBidResponse = r1adapter.interpretResponse({ - 'body': '' - }); - expect(noBidResponse.length).to.equal(0); - }); - }); - - describe('isBidRequestValid', function () { - var bid = { - 'bidder': 'rhythmone', - 'params': { - 'placementId': 'myplacement', - 'path': 'mypath', - 'zone': 'myzone' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'adUnitCode': 'bannerDiv' - }; - - it('should return true when required params found', function () { - expect(r1adapter.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when placementId missing', function () { - delete bid.params.placementId; - expect(r1adapter.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('getUserSyncs', function () { - it('returns an empty string', function () { - expect(r1adapter.getUserSyncs()).to.deep.equal([]); - }); - }); -}); diff --git a/test/spec/modules/richaudienceBidAdapter_spec.js b/test/spec/modules/richaudienceBidAdapter_spec.js deleted file mode 100644 index 72410b71fb2..00000000000 --- a/test/spec/modules/richaudienceBidAdapter_spec.js +++ /dev/null @@ -1,1130 +0,0 @@ -// import or require modules necessary for the test, e.g.: -import {expect} from 'chai'; // may prefer 'assert' in place of 'expect' -import { - spec -} from 'modules/richaudienceBidAdapter.js'; -import {config} from 'src/config.js'; - -describe('Richaudience adapter tests', function () { - var DEFAULT_PARAMS_NEW_SIZES = [{ - adUnitCode: 'test-div', - bidId: '2c7c8e9c900244', - mediaTypes: { - banner: { - sizes: [ - [300, 250], [300, 600], [728, 90], [970, 250]] - } - }, - bidder: 'richaudience', - params: { - bidfloor: 0.5, - pid: 'ADb1f40rmi', - supplyType: 'site', - keywords: 'key1=value1;key2=value2' - }, - auctionId: '0cb3144c-d084-4686-b0d6-f5dbe917c563', - bidRequestsCount: 1, - bidderRequestId: '1858b7382993ca', - transactionId: '29df2112-348b-4961-8863-1b33684d95e6', - user: {} - }]; - - var DEFAULT_PARAMS_VIDEO_IN = [{ - adUnitCode: 'test-div', - bidId: '2c7c8e9c900244', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480], - mimes: ['video/mp4'] - } - }, - bidder: 'richaudience', - params: { - bidfloor: 0.5, - pid: 'ADb1f40rmi', - supplyType: 'site' - }, - auctionId: '0cb3144c-d084-4686-b0d6-f5dbe917c563', - bidRequestsCount: 1, - bidderRequestId: '1858b7382993ca', - transactionId: '29df2112-348b-4961-8863-1b33684d95e6', - user: {} - }]; - - var DEFAULT_PARAMS_VIDEO_OUT = [{ - adUnitCode: 'test-div', - bidId: '2c7c8e9c900244', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [640, 480], - mimes: ['video/mp4'] - } - }, - bidder: 'richaudience', - params: { - bidfloor: 0.5, - pid: 'ADb1f40rmi', - supplyType: 'site' - }, - auctionId: '0cb3144c-d084-4686-b0d6-f5dbe917c563', - bidRequestsCount: 1, - bidderRequestId: '1858b7382993ca', - transactionId: '29df2112-348b-4961-8863-1b33684d95e6', - user: {} - }]; - - var DEFAULT_PARAMS_BANNER_OUTSTREAM = [{ - adUnitCode: 'test-div', - bidId: '2c7c8e9c900244', - mediaTypes: { - banner: { - sizes: [[300, 250], [600, 300]] - } - }, - bidder: 'richaudience', - params: { - bidfloor: 0.5, - pid: 'ADb1f40rmi', - supplyType: 'site' - }, - auctionId: '0cb3144c-d084-4686-b0d6-f5dbe917c563', - bidRequestsCount: 1, - bidderRequestId: '1858b7382993ca', - transactionId: '29df2112-348b-4961-8863-1b33684d95e6', - user: {} - }]; - - var DEFAULT_PARAMS_APP = [{ - adUnitCode: 'test-div', - bidId: '2c7c8e9c900244', - sizes: [ - [300, 250], - [300, 600], - [728, 90], - [970, 250] - ], - bidder: 'richaudience', - params: { - bidfloor: 0.5, - ifa: 'AAAAAAAAA-BBBB-CCCC-1111-222222220000', - pid: 'ADb1f40rmi', - supplyType: 'app', - }, - auctionId: '0cb3144c-d084-4686-b0d6-f5dbe917c563', - bidRequestsCount: 1, - bidderRequestId: '1858b7382993ca', - transactionId: '29df2112-348b-4961-8863-1b33684d95e6' - }]; - - var DEFAULT_PARAMS_WO_OPTIONAL = [{ - adUnitCode: 'test-div', - bidId: '2c7c8e9c900244', - sizes: [ - [300, 250], - [300, 600], - [728, 90], - [970, 250] - ], - bidder: 'richaudience', - params: { - pid: 'ADb1f40rmi', - supplyType: 'site', - }, - auctionId: '851adee7-d843-48f9-a7e9-9ff00573fcbf', - bidRequestsCount: 1, - bidderRequestId: '1858b7382993ca', - transactionId: '29df2112-348b-4961-8863-1b33684d95e6' - }]; - - var BID_RESPONSE = { - body: { - cpm: 1.50, - adm: '', - media_type: 'js', - width: 300, - height: 250, - creative_id: '189198063', - netRevenue: true, - currency: 'USD', - ttl: 300, - dealId: 'dealId' - - } - }; - - var BID_RESPONSE_VIDEO = { - body: { - cpm: 1.50, - media_type: 'video', - width: 1, - height: 1, - creative_id: '189198063', - netRevenue: true, - currency: 'USD', - ttl: 300, - vastXML: '', - dealId: 'dealId' - } - }; - - var DEFAULT_PARAMS_GDPR = { - gdprConsent: { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }, - refererInfo: { - referer: 'http://domain.com', - numIframes: 0 - } - } - - it('Referer undefined', function() { - config.setConfig({ - 'currency': {'adServerCurrency': 'USD'} - }) - - const request = spec.buildRequests(DEFAULT_PARAMS_NEW_SIZES, { - gdprConsent: { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }, - refererInfo: {} - }) - const requestContent = JSON.parse(request[0].data); - expect(requestContent).to.have.property('referer').and.to.equal(null); - expect(requestContent).to.have.property('referer').and.to.equal(null); - }) - - it('Verify build request to prebid 3.0 display test', function() { - const request = spec.buildRequests(DEFAULT_PARAMS_NEW_SIZES, { - gdprConsent: { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }, - refererInfo: { - referer: 'https://domain.com', - numIframes: 0 - } - }); - - expect(request[0]).to.have.property('method').and.to.equal('POST'); - const requestContent = JSON.parse(request[0].data); - expect(requestContent).to.have.property('bidfloor').and.to.equal(0.5); - expect(requestContent).to.have.property('pid').and.to.equal('ADb1f40rmi'); - expect(requestContent).to.have.property('supplyType').and.to.equal('site'); - expect(requestContent).to.have.property('auctionId').and.to.equal('0cb3144c-d084-4686-b0d6-f5dbe917c563'); - expect(requestContent).to.have.property('bidId').and.to.equal('2c7c8e9c900244'); - expect(requestContent).to.have.property('BidRequestsCount').and.to.equal(1); - expect(requestContent).to.have.property('bidder').and.to.equal('richaudience'); - expect(requestContent).to.have.property('bidderRequestId').and.to.equal('1858b7382993ca'); - expect(requestContent).to.have.property('tagId').and.to.equal('test-div'); - expect(requestContent).to.have.property('referer').and.to.equal('https%3A%2F%2Fdomain.com'); - expect(requestContent).to.have.property('sizes'); - expect(requestContent.sizes[0]).to.have.property('w').and.to.equal(300); - expect(requestContent.sizes[0]).to.have.property('h').and.to.equal(250); - expect(requestContent.sizes[1]).to.have.property('w').and.to.equal(300); - expect(requestContent.sizes[1]).to.have.property('h').and.to.equal(600); - expect(requestContent.sizes[2]).to.have.property('w').and.to.equal(728); - expect(requestContent.sizes[2]).to.have.property('h').and.to.equal(90); - expect(requestContent.sizes[3]).to.have.property('w').and.to.equal(970); - expect(requestContent.sizes[3]).to.have.property('h').and.to.equal(250); - expect(requestContent).to.have.property('transactionId').and.to.equal('29df2112-348b-4961-8863-1b33684d95e6'); - expect(requestContent).to.have.property('timeout').and.to.equal(3000); - expect(requestContent).to.have.property('numIframes').and.to.equal(0); - expect(typeof requestContent.scr_rsl === 'string') - expect(typeof requestContent.cpuc === 'number') - expect(requestContent).to.have.property('kws').and.to.equal('key1=value1;key2=value2'); - }) - - it('Verify build request to prebid video inestream', function() { - const request = spec.buildRequests(DEFAULT_PARAMS_VIDEO_IN, { - gdprConsent: { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }, - refererInfo: { - referer: 'https://domain.com', - numIframes: 0 - } - }); - - expect(request[0]).to.have.property('method').and.to.equal('POST'); - const requestContent = JSON.parse(request[0].data); - - expect(requestContent).to.have.property('demand').and.to.equal('video'); - expect(requestContent.videoData).to.have.property('format').and.to.equal('instream'); - }) - - it('Verify build request to prebid video outstream', function() { - const request = spec.buildRequests(DEFAULT_PARAMS_VIDEO_OUT, { - gdprConsent: { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }, - refererInfo: { - referer: 'https://domain.com', - numIframes: 0 - } - }); - - expect(request[0]).to.have.property('method').and.to.equal('POST'); - const requestContent = JSON.parse(request[0].data); - - expect(requestContent).to.have.property('demand').and.to.equal('video'); - expect(requestContent.videoData).to.have.property('format').and.to.equal('outstream'); - }) - - describe('gdpr test', function () { - it('Verify build request with GDPR', function () { - config.setConfig({ - 'currency': { - 'adServerCurrency': 'USD' - }, - consentManagement: { - cmpApi: 'iab', - timeout: 8000, - allowAuctionWithoutConsent: true - } - }); - - const request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, { - gdprConsent: { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }, - refererInfo: { - referer: 'https://domain.com', - numIframes: 0 - } - }); - const requestContent = JSON.parse(request[0].data); - expect(requestContent).to.have.property('gdpr_consent').and.to.equal('BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA'); - }); - - it('Verify adding ifa when supplyType equal to app', function () { - const request = spec.buildRequests(DEFAULT_PARAMS_APP, { - gdprConsent: { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }, - refererInfo: { - referer: 'https://domain.com', - numIframes: 0 - } - }); - }); - - it('Verify build request with GDPR without gdprApplies', function () { - config.setConfig({ - 'currency': { - 'adServerCurrency': 'EUR' - }, - consentManagement: { - cmp: 'iab', - consentRequired: true, - timeout: 8000, - allowAuctionWithoutConsent: true - } - }); - const request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, { - gdprConsent: { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA' - }, - refererInfo: { - referer: 'https://domain.com', - numIframes: 0 - } - }); - const requestContent = JSON.parse(request[0].data); - expect(requestContent).to.have.property('gdpr_consent').and.to.equal('BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA'); - }); - }); - - describe('UID test', function () { - config.setConfig({ - consentManagement: { - cmpApi: 'iab', - timeout: 5000, - allowAuctionWithoutConsent: true - }, - userSync: { - userIds: [{ - name: 'id5Id', - params: { - partner: 173, // change to the Partner Number you received from ID5 - pd: 'MT1iNTBjY...' // optional, see table below for a link to how to generate this - }, - storage: { - type: 'html5', // "html5" is the required storage type - name: 'id5id', // "id5id" is the required storage name - expires: 90, // storage lasts for 90 days - refreshInSeconds: 8 * 3600 // refresh ID every 8 hours to ensure it's fresh - } - }], - auctionDelay: 50 // 50ms maximum auction delay, applies to all userId modules - } - }); - it('Verify build id5', function () { - var request; - DEFAULT_PARAMS_WO_OPTIONAL[0].userId = {}; - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.id5id = { uid: 1 }; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - var requestContent = JSON.parse(request[0].data); - - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.id5id = { uid: [] }; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.id5id = { uid: null }; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.id5id = { uid: {} }; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.id5id = null; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.id5id = {}; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - }); - - it('Verify build pubCommonId', function () { - DEFAULT_PARAMS_WO_OPTIONAL[0].userId = {}; - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.pubcid = 'pub_common_user_id'; - - var request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - var requestContent = JSON.parse(request[0].data); - - expect(requestContent.user).to.deep.equal([{ - 'userId': 'pub_common_user_id', - 'source': 'pubcommon' - }]); - - var request; - DEFAULT_PARAMS_WO_OPTIONAL[0].userId = {}; - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.pubcid = 1; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - var requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.pubcid = []; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.pubcid = null; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.pubcid = {}; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - }); - - it('Verify build criteoId', function () { - DEFAULT_PARAMS_WO_OPTIONAL[0].userId = {}; - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.criteoId = 'criteo-user-id'; - - var request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - var requestContent = JSON.parse(request[0].data); - - expect(requestContent.user).to.deep.equal([{ - 'userId': 'criteo-user-id', - 'source': 'criteo.com' - }]); - - var request; - DEFAULT_PARAMS_WO_OPTIONAL[0].userId = {}; - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.criteoId = 1; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - var requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.criteoId = []; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.criteoId = null; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.criteoId = {}; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - }); - - it('Verify build identityLink', function () { - DEFAULT_PARAMS_WO_OPTIONAL[0].userId = {}; - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.idl_env = 'identity-link-user-id'; - - var request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - var requestContent = JSON.parse(request[0].data); - - expect(requestContent.user).to.deep.equal([{ - 'userId': 'identity-link-user-id', - 'source': 'liveramp.com' - }]); - - var request; - DEFAULT_PARAMS_WO_OPTIONAL[0].userId = {}; - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.idl_env = 1; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - var requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.criteoId = []; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.idl_env = null; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.idl_env = {}; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - }); - it('Verify build liveIntentId', function () { - DEFAULT_PARAMS_WO_OPTIONAL[0].userId = {}; - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.idl_env = 'identity-link-user-id'; - - var request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - var requestContent = JSON.parse(request[0].data) - - expect(requestContent.user).to.deep.equal([{ - 'userId': 'identity-link-user-id', - 'source': 'liveramp.com' - }]); - - var request; - DEFAULT_PARAMS_WO_OPTIONAL[0].userId = {}; - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.idl_env = 1; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - var requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.criteoId = []; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.idl_env = null; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.idl_env = {}; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - }); - it('Verify build TradeDesk', function () { - DEFAULT_PARAMS_WO_OPTIONAL[0].userId = {}; - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.tdid = 'tdid-user-id'; - - var request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - var requestContent = JSON.parse(request[0].data) - - expect(requestContent.user).to.deep.equal([{ - 'userId': 'tdid-user-id', - 'source': 'adserver.org' - }]); - - request; - DEFAULT_PARAMS_WO_OPTIONAL[0].userId = {}; - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.idl_env = 1; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.criteoId = []; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.idl_env = null; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - - DEFAULT_PARAMS_WO_OPTIONAL[0].userId.idl_env = {}; - request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, DEFAULT_PARAMS_GDPR); - requestContent = JSON.parse(request[0].data); - expect(requestContent.user.eids).to.equal(undefined); - }); - }); - - it('Verify interprete response', function () { - const request = spec.buildRequests(DEFAULT_PARAMS_NEW_SIZES, { - gdprConsent: { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }, - refererInfo: { - referer: 'https://domain.com', - numIframes: 0 - } - }); - - const bids = spec.interpretResponse(BID_RESPONSE, request[0]); - expect(bids).to.have.lengthOf(1); - const bid = bids[0]; - expect(bid.cpm).to.equal(1.50); - expect(bid.ad).to.equal(''); - expect(bid.mediaType).to.equal('js'); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.creativeId).to.equal('189198063'); - expect(bid.netRevenue).to.equal(true); - expect(bid.currency).to.equal('USD'); - expect(bid.ttl).to.equal(300); - expect(bid.dealId).to.equal('dealId'); - }); - - it('no banner media response inestream', function () { - const request = spec.buildRequests(DEFAULT_PARAMS_VIDEO_IN, { - gdprConsent: { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }, - refererInfo: { - referer: 'https://domain.com', - numIframes: 0 - } - }); - - const bids = spec.interpretResponse(BID_RESPONSE_VIDEO, request[0]); - expect(bids).to.have.lengthOf(1); - const bid = bids[0]; - expect(bid.cpm).to.equal(1.50); - expect(bid.mediaType).to.equal('video'); - expect(bid.vastXml).to.equal(''); - expect(bid.cpm).to.equal(1.50); - expect(bid.width).to.equal(1); - expect(bid.height).to.equal(1); - expect(bid.creativeId).to.equal('189198063'); - expect(bid.netRevenue).to.equal(true); - expect(bid.currency).to.equal('USD'); - expect(bid.ttl).to.equal(300); - expect(bid.dealId).to.equal('dealId'); - }); - - it('no banner media response outstream', function () { - const request = spec.buildRequests(DEFAULT_PARAMS_VIDEO_OUT, { - gdprConsent: { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }, - refererInfo: { - referer: 'https://domain.com', - numIframes: 0 - } - }); - - const bids = spec.interpretResponse(BID_RESPONSE_VIDEO, request[0]); - expect(bids).to.have.lengthOf(1); - const bid = bids[0]; - expect(bid.cpm).to.equal(1.50); - expect(bid.mediaType).to.equal('video'); - expect(bid.vastXml).to.equal(''); - expect(bid.renderer.url).to.equal('https://cdn3.richaudience.com/prebidVideo/player.js'); - expect(bid.cpm).to.equal(1.50); - expect(bid.width).to.equal(1); - expect(bid.height).to.equal(1); - expect(bid.creativeId).to.equal('189198063'); - expect(bid.netRevenue).to.equal(true); - expect(bid.currency).to.equal('USD'); - expect(bid.ttl).to.equal(300); - expect(bid.dealId).to.equal('dealId'); - }); - - it('banner media and response VAST', function () { - const request = spec.buildRequests(DEFAULT_PARAMS_BANNER_OUTSTREAM, { - gdprConsent: { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }, - refererInfo: { - referer: 'https://domain.com', - numIframes: 0 - } - }); - - const bids = spec.interpretResponse(BID_RESPONSE_VIDEO, request[0]); - const bid = bids[0]; - expect(bid.mediaType).to.equal('video'); - expect(bid.vastXml).to.equal(''); - expect(bid.renderer.url).to.equal('https://cdn3.richaudience.com/prebidVideo/player.js'); - }); - - it('Verifies bidder_code', function () { - expect(spec.code).to.equal('richaudience'); - }); - - it('Verifies bidder aliases', function () { - expect(spec.aliases).to.have.lengthOf(1); - expect(spec.aliases[0]).to.equal('ra'); - }); - - it('Verifies bidder gvlid', function () { - expect(spec.gvlid).to.equal(108); - }); - - it('Verifies bidder supportedMediaTypes', function () { - expect(spec.supportedMediaTypes).to.have.lengthOf(2); - expect(spec.supportedMediaTypes[0]).to.equal('banner'); - expect(spec.supportedMediaTypes[1]).to.equal('video'); - }); - - it('Verifies if bid request is valid', function () { - expect(spec.isBidRequestValid(DEFAULT_PARAMS_NEW_SIZES[0])).to.equal(true); - expect(spec.isBidRequestValid(DEFAULT_PARAMS_WO_OPTIONAL[0])).to.equal(true); - expect(spec.isBidRequestValid({})).to.equal(false); - expect(spec.isBidRequestValid({ - params: {} - })).to.equal(false); - expect(spec.isBidRequestValid({ - params: { - pid: 'ADb1f40rmi' - } - })).to.equal(false); - expect(spec.isBidRequestValid({ - params: { - supplyType: 'site' - } - })).to.equal(false); - expect(spec.isBidRequestValid({ - params: { - supplyType: 'app' - } - })).to.equal(false); - expect(spec.isBidRequestValid({ - params: { - pid: 'ADb1f40rmi', - supplyType: 'site' - } - })).to.equal(true); - expect(spec.isBidRequestValid({ - params: { - pid: ['1gCB5ZC4XL', '1a40xk8qSV'], - supplyType: 'site' - } - })).to.equal(true); - expect(spec.isBidRequestValid({ - params: { - pid: 'ADb1f40rmi', - supplyType: 'site' - } - })).to.equal(true); - expect(spec.isBidRequestValid({ - params: { - pid: 'ADb1f40rmi', - supplyType: 'app', - ifa: 'AAAAAAAAA-BBBB-CCCC-1111-222222220000', - } - })).to.equal(true); - expect(spec.isBidRequestValid({ - params: { - pid: 'ADb1f40rmi', - supplyType: 'site', - bidfloor: 0.50, - } - })).to.equal(true); - expect(spec.isBidRequestValid({ - params: { - pid: 'ADb1f40rmi', - supplyType: 'site', - bidfloor: 0.50, - } - })).to.equal(true); - expect(spec.isBidRequestValid({ - params: { - pid: ['1gCB5ZC4XL', '1a40xk8qSV'], - bidfloor: 0.50, - } - })).to.equal(false); - expect(spec.isBidRequestValid({ - params: { - pid: ['1gCB5ZC4XL', '1a40xk8qSV'], - supplyType: 'site', - bidfloor: 0.50, - } - })).to.equal(true); - expect(spec.isBidRequestValid({ - params: { - supplyType: 'site', - bidfloor: 0.50, - ifa: 'AAAAAAAAA-BBBB-CCCC-1111-222222220000', - } - })).to.equal(false); - expect(spec.isBidRequestValid({ - params: { - pid: ['1gCB5ZC4XL', '1a40xk8qSV'], - supplyType: 'site', - bidfloor: 0.50, - ifa: 'AAAAAAAAA-BBBB-CCCC-1111-222222220000', - } - })).to.equal(true); - }); - - describe('userSync', function () { - it('Verifies user syncs iframe include', function () { - config.setConfig({ - 'userSync': {filterSettings: {iframe: {bidders: '*', filter: 'include'}}} - }) - - var syncs = spec.getUserSyncs({ - iframeEnabled: true - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true}, - ); - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('iframe'); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true, - }); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: true, - }, [], {consentString: '', gdprApplies: false}); - expect(syncs).to.have.lengthOf(1); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - }, [], {consentString: '', gdprApplies: true}); - expect(syncs).to.have.lengthOf(0); - }); - it('Verifies user syncs iframe exclude', function () { - config.setConfig({ - 'userSync': {filterSettings: {iframe: {bidders: '*', filter: 'exclude'}}} - }) - - var syncs = spec.getUserSyncs({ - iframeEnabled: true - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true}, - ); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true, - }); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: true, - }, [], {consentString: '', gdprApplies: false}); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - }, [], {consentString: '', gdprApplies: true}); - expect(syncs).to.have.lengthOf(0); - }); - - it('Verifies user syncs image include', function () { - config.setConfig({ - 'userSync': {filterSettings: {image: {bidders: '*', filter: 'include'}}} - }) - - var syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: true - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - referer: 'http://domain.com', - gdprApplies: true - }) - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('image'); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: true - }, [BID_RESPONSE], { - consentString: '', - referer: 'http://domain.com', - gdprApplies: true - }) - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('image'); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: true - }, [], { - consentString: null, - referer: 'http://domain.com', - gdprApplies: true - }) - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('image'); - }); - - it('Verifies user syncs image exclude', function () { - config.setConfig({ - 'userSync': {filterSettings: {image: {bidders: '*', filter: 'exclude'}}} - }) - - var syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: true - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - referer: 'http://domain.com', - gdprApplies: true - }) - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: true - }, [BID_RESPONSE], { - consentString: '', - referer: 'http://domain.com', - gdprApplies: true - }) - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: true - }, [], { - consentString: null, - referer: 'http://domain.com', - gdprApplies: true - }) - expect(syncs).to.have.lengthOf(0); - }); - - it('Verifies user syncs iframe/image include', function () { - config.setConfig({ - 'userSync': {filterSettings: {iframe: {bidders: '*', filter: 'include'}, image: {bidders: '*', filter: 'include'}}} - }) - - var syncs = spec.getUserSyncs({ - iframeEnabled: true, - pixelEnabled: true - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true}, - ); - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('iframe'); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: false - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true, - }); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: false - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: true, - pixelEnabled: true - }, [], {consentString: '', gdprApplies: false}); - expect(syncs).to.have.lengthOf(1); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: false - }, [], {consentString: '', gdprApplies: true}); - expect(syncs).to.have.lengthOf(0); - }); - - it('Verifies user syncs iframe/image exclude', function () { - config.setConfig({ - 'userSync': {filterSettings: {iframe: {bidders: '*', filter: 'exclude'}, image: {bidders: '*', filter: 'exclude'}}} - }) - - var syncs = spec.getUserSyncs({ - iframeEnabled: true, - pixelEnabled: true - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true}, - ); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: false - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true, - }); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: false - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: true, - pixelEnabled: true - }, [], {consentString: '', gdprApplies: false}); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: false - }, [], {consentString: '', gdprApplies: true}); - expect(syncs).to.have.lengthOf(0); - }); - - it('Verifies user syncs iframe exclude / image include', function () { - config.setConfig({ - 'userSync': {filterSettings: {iframe: {bidders: '*', filter: 'exclude'}, image: {bidders: '*', filter: 'include'}}} - }) - - var syncs = spec.getUserSyncs({ - iframeEnabled: true, - pixelEnabled: true - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true}, - ); - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('image'); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: false - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true, - }); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: false - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: true, - pixelEnabled: true - }, [], {consentString: '', gdprApplies: false}); - expect(syncs).to.have.lengthOf(1); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: false - }, [], {consentString: '', gdprApplies: true}); - expect(syncs).to.have.lengthOf(0); - }); - - it('Verifies user syncs iframe include / image exclude', function () { - config.setConfig({ - 'userSync': {filterSettings: {iframe: {bidders: '*', filter: 'include'}, image: {bidders: '*', filter: 'exclude'}}} - }) - - var syncs = spec.getUserSyncs({ - iframeEnabled: true, - pixelEnabled: true - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true}, - ); - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('iframe'); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: false - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true, - }); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: false - }, [BID_RESPONSE], { - consentString: 'BOZcQl_ObPFjWAeABAESCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NohBgA', - gdprApplies: true - }); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: true, - pixelEnabled: true - }, [], {consentString: '', gdprApplies: false}); - expect(syncs).to.have.lengthOf(1); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: false - }, [], {consentString: '', gdprApplies: true}); - expect(syncs).to.have.lengthOf(0); - }); - }) -}); diff --git a/test/spec/modules/riseBidAdapter_spec.js b/test/spec/modules/riseBidAdapter_spec.js deleted file mode 100644 index b3257cbda9d..00000000000 --- a/test/spec/modules/riseBidAdapter_spec.js +++ /dev/null @@ -1,381 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/riseBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import { config } from 'src/config.js'; -import { VIDEO } from '../../../src/mediaTypes.js'; - -const ENDPOINT = 'https://hb.yellowblue.io/hb'; -const TEST_ENDPOINT = 'https://hb.yellowblue.io/hb-test'; -const TTL = 360; - -describe('riseAdapter', 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 bid = { - 'bidder': spec.code, - 'adUnitCode': 'adunit-code', - 'sizes': [['640', '480']], - 'params': { - 'org': 'jdye8weeyirk00000001' - } - }; - - it('should return true when required params are passed', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not found', function () { - const newBid = Object.assign({}, bid); - delete newBid.params; - newBid.params = { - 'org': null - }; - expect(spec.isBidRequestValid(newBid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const bidRequests = [ - { - 'bidder': spec.code, - 'adUnitCode': 'adunit-code', - 'sizes': [[640, 480]], - 'params': { - 'org': 'jdye8weeyirk00000001' - }, - 'bidId': '299ffc8cca0b87', - 'bidderRequestId': '1144f487e563f9', - 'auctionId': 'bfc420c3-8577-4568-9766-a8a935fb620d', - } - ]; - - const testModeBidRequests = [ - { - 'bidder': spec.code, - 'adUnitCode': 'adunit-code', - 'sizes': [[640, 480]], - 'params': { - 'org': 'jdye8weeyirk00000001', - 'testMode': true - }, - 'bidId': '299ffc8cca0b87', - 'bidderRequestId': '1144f487e563f9', - 'auctionId': 'bfc420c3-8577-4568-9766-a8a935fb620d', - } - ]; - - const bidderRequest = { - bidderCode: 'rise', - } - - const customSessionId = '12345678'; - - it('sends bid request to ENDPOINT via GET', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.url).to.equal(ENDPOINT); - expect(request.method).to.equal('GET'); - } - }); - - it('sends the is_wrapper query param', function () { - bidRequests[0].params.isWrapper = true; - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data.is_wrapper).to.equal(true); - } - }); - - it('sends the custom session id as a query param', function () { - bidRequests[0].params.sessionId = customSessionId; - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data.session_id).to.equal(customSessionId); - } - }); - - it('sends bid request to test ENDPOINT via GET', function () { - const requests = spec.buildRequests(testModeBidRequests, bidderRequest); - for (const request of requests) { - expect(request.url).to.equal(TEST_ENDPOINT); - expect(request.method).to.equal('GET'); - } - }); - - it('should send the correct bid Id', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data.bid_id).to.equal('299ffc8cca0b87'); - } - }); - - it('should send the correct width and height', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.have.property('width', 640); - expect(request.data).to.have.property('height', 480); - } - }); - - it('should respect syncEnabled option', function() { - config.setConfig({ - userSync: { - syncEnabled: false, - filterSettings: { - all: { - bidders: '*', - filter: 'include' - } - } - } - }); - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.not.have.property('cs_method'); - } - }); - - it('should respect "iframe" filter settings', function () { - config.setConfig({ - userSync: { - syncEnabled: true, - filterSettings: { - iframe: { - bidders: [spec.code], - filter: 'include' - } - } - } - }); - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.have.property('cs_method', 'iframe'); - } - }); - - it('should respect "all" filter settings', function () { - config.setConfig({ - userSync: { - syncEnabled: true, - filterSettings: { - all: { - bidders: [spec.code], - filter: 'include' - } - } - } - }); - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.have.property('cs_method', 'iframe'); - } - }); - - it('should send the pixel user sync param if userSync is enabled and no "iframe" or "all" configs are present', function () { - config.setConfig({ - userSync: { - syncEnabled: true - } - }); - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.have.property('cs_method', 'pixel'); - } - }); - - it('should respect total exclusion', function() { - config.setConfig({ - userSync: { - syncEnabled: true, - filterSettings: { - image: { - bidders: [spec.code], - filter: 'exclude' - }, - iframe: { - bidders: [spec.code], - filter: 'exclude' - } - } - } - }); - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.not.have.property('cs_method'); - } - }); - - it('should have us_privacy param if usPrivacy is available in the bidRequest', function () { - const bidderRequestWithUSP = Object.assign({uspConsent: '1YNN'}, bidderRequest); - const requests = spec.buildRequests(bidRequests, bidderRequestWithUSP); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.have.property('us_privacy', '1YNN'); - } - }); - - it('should have an empty us_privacy param if usPrivacy is missing in the bidRequest', function () { - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.not.have.property('us_privacy'); - } - }); - - it('should not send the gdpr param if gdprApplies is false in the bidRequest', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {gdprApplies: false}}, bidderRequest); - const requests = spec.buildRequests(bidRequests, bidderRequestWithGDPR); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.not.have.property('gdpr'); - expect(request.data).to.not.have.property('gdpr_consent'); - } - }); - - 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 requests = spec.buildRequests(bidRequests, bidderRequestWithGDPR); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.have.property('gdpr', true); - expect(request.data).to.have.property('gdpr_consent', 'test-consent-string'); - } - }); - - it('should have schain param if it is available in the bidRequest', () => { - const schain = { - ver: '1.0', - complete: 1, - nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1 }], - }; - bidRequests[0].schain = schain; - const requests = spec.buildRequests(bidRequests, bidderRequest); - for (const request of requests) { - expect(request.data).to.be.an('object'); - expect(request.data).to.have.property('schain', '1.0,1!indirectseller.com,00001,,,,'); - } - }); - }); - - describe('interpretResponse', function () { - const response = { - cpm: 12.5, - vastXml: '', - width: 640, - height: 480, - requestId: '21e12606d47ba7', - netRevenue: true, - currency: 'USD' - }; - - it('should get correct bid response', function () { - let expectedResponse = [ - { - requestId: '21e12606d47ba7', - cpm: 12.5, - width: 640, - height: 480, - creativeId: '21e12606d47ba7', - currency: 'USD', - netRevenue: true, - ttl: TTL, - vastXml: '', - mediaType: VIDEO - } - ]; - const result = spec.interpretResponse({ body: response }); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - }) - - describe('getUserSyncs', function() { - const imageSyncResponse = { - body: { - userSyncPixels: [ - 'https://image-sync-url.test/1', - 'https://image-sync-url.test/2', - 'https://image-sync-url.test/3' - ] - } - }; - - const iframeSyncResponse = { - body: { - userSyncURL: 'https://iframe-sync-url.test' - } - }; - - it('should register all img urls from the response', function() { - const syncs = spec.getUserSyncs({ pixelEnabled: true }, [imageSyncResponse]); - expect(syncs).to.deep.equal([ - { - type: 'image', - url: 'https://image-sync-url.test/1' - }, - { - type: 'image', - url: 'https://image-sync-url.test/2' - }, - { - type: 'image', - url: 'https://image-sync-url.test/3' - } - ]); - }); - - it('should register the iframe url from the response', function() { - const syncs = spec.getUserSyncs({ iframeEnabled: true }, [iframeSyncResponse]); - expect(syncs).to.deep.equal([ - { - type: 'iframe', - url: 'https://iframe-sync-url.test' - } - ]); - }); - - it('should register both image and iframe urls from the responses', function() { - const syncs = spec.getUserSyncs({ pixelEnabled: true, iframeEnabled: true }, [iframeSyncResponse, imageSyncResponse]); - expect(syncs).to.deep.equal([ - { - type: 'iframe', - url: 'https://iframe-sync-url.test' - }, - { - type: 'image', - url: 'https://image-sync-url.test/1' - }, - { - type: 'image', - url: 'https://image-sync-url.test/2' - }, - { - type: 'image', - url: 'https://image-sync-url.test/3' - } - ]); - }); - - it('should handle an empty response', function() { - const syncs = spec.getUserSyncs({ iframeEnabled: true }, []); - expect(syncs).to.deep.equal([]); - }); - - it('should handle when user syncs are disabled', function() { - const syncs = spec.getUserSyncs({ pixelEnabled: false }, [imageSyncResponse]); - expect(syncs).to.deep.equal([]); - }); - }) -}); diff --git a/test/spec/modules/rivrAnalyticsAdapter_spec.js b/test/spec/modules/rivrAnalyticsAdapter_spec.js deleted file mode 100644 index 9add7ed5f7d..00000000000 --- a/test/spec/modules/rivrAnalyticsAdapter_spec.js +++ /dev/null @@ -1,150 +0,0 @@ -import * as utils from 'src/utils.js'; -import analyticsAdapter from 'modules/rivrAnalyticsAdapter.js'; -import { - sendImpressions, - handleClickEventWithClosureScope, - createUnOptimisedParamsField, - dataLoaderForHandler, - pinHandlerToHTMLElement, - setAuctionAbjectPosition, - createNewAuctionObject, - concatAllUnits, - trackAuctionEnd, - handleImpression, - getCookie, - storeAndReturnRivrUsrIdCookie, - arrayDifference, - activelyWaitForBannersToRender, -} from 'modules/rivrAnalyticsAdapter.js'; -import {expect} from 'chai'; -import adapterManager from 'src/adapterManager.js'; -import * as ajax from 'src/ajax.js'; -import CONSTANTS from 'src/constants.json'; - -const events = require('../../../src/events'); - -describe('RIVR Analytics adapter', () => { - const EXPIRING_QUEUE_TIMEOUT = 4000; - const EXPIRING_QUEUE_TIMEOUT_MOCK = 100; - const RVR_CLIENT_ID_MOCK = 'aCliendId'; - const SITE_CATEGORIES_MOCK = ['cat1', 'cat2']; - const EMITTED_AUCTION_ID = 1; - const TRACKER_BASE_URL_MOCK = 'tracker.rivr.simplaex.com'; - const UUID_REG_EXP = new RegExp('[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}', 'i'); - const MOCK_RIVRADDON_CONTEXT = {}; - let sandbox; - let ajaxStub; - let rivraddonsEnableAnalyticsStub; - let rivraddonsTrackPbjsEventStub; - let timer; - - before(() => { - sandbox = sinon.sandbox.create(); - window.rivraddon = { - analytics: { - enableAnalytics: () => {}, - getContext: () => { return MOCK_RIVRADDON_CONTEXT; }, - trackPbjsEvent: () => {}, - } - }; - rivraddonsEnableAnalyticsStub = sandbox.stub(window.rivraddon.analytics, 'enableAnalytics'); - }); - - beforeEach(() => { - timer = sandbox.useFakeTimers(0); - ajaxStub = sandbox.stub(ajax, 'ajax'); - sinon.stub(events, 'getEvents').returns([]); - - adapterManager.registerAnalyticsAdapter({ - code: 'rivr', - adapter: analyticsAdapter - }); - adapterManager.enableAnalytics({ - provider: 'rivr', - options: { - clientID: RVR_CLIENT_ID_MOCK, - adUnits: [utils.deepClone(BANNER_AD_UNITS_MOCK)], - siteCategories: SITE_CATEGORIES_MOCK, - } - }); - }); - - afterEach(() => { - analyticsAdapter.disableAnalytics(); - events.getEvents.restore(); - ajaxStub.restore(); - timer.restore(); - }); - - after(() => { - sandbox.restore(); - delete window.rivraddon; - }); - - it('enableAnalytics - should call rivraddon enableAnalytics with the correct arguments', () => { - // adapterManager.enableAnalytics() is called in beforeEach. If just called here it doesn't seem to work. - const firstArgument = rivraddonsEnableAnalyticsStub.getCall(0).args[0]; - const secondArgument = rivraddonsEnableAnalyticsStub.getCall(0).args[1]; - - expect(firstArgument.provider).to.be.equal('rivr'); - - expect(secondArgument).to.have.property('utils'); - expect(secondArgument).to.have.property('ajax'); - }); - - it('Firing an event when rivraddon context is not defined it should do nothing', () => { - let rivraddonsGetContextStub = sandbox.stub(window.rivraddon.analytics, 'getContext'); - rivraddonsTrackPbjsEventStub = sandbox.stub(window.rivraddon.analytics, 'trackPbjsEvent'); - - expect(rivraddonsTrackPbjsEventStub.callCount).to.be.equal(0); - - events.emit(CONSTANTS.EVENTS.AUCTION_INIT, {auctionId: EMITTED_AUCTION_ID, config: {}, timeout: 3000}); - - expect(rivraddonsTrackPbjsEventStub.callCount).to.be.equal(0); - - window.rivraddon.analytics.getContext.restore(); - window.rivraddon.analytics.trackPbjsEvent.restore(); - }); - - it('Firing AUCTION_INIT should call rivraddon trackPbjsEvent passing the parameters', () => { - rivraddonsTrackPbjsEventStub = sandbox.stub(window.rivraddon.analytics, 'trackPbjsEvent'); - - expect(rivraddonsTrackPbjsEventStub.callCount).to.be.equal(0); - - events.emit(CONSTANTS.EVENTS.AUCTION_INIT, {auctionId: EMITTED_AUCTION_ID, config: {}, timeout: 3000}); - - expect(rivraddonsTrackPbjsEventStub.callCount).to.be.equal(1); - - const firstArgument = rivraddonsTrackPbjsEventStub.getCall(0).args[0]; - expect(firstArgument.eventType).to.be.equal(CONSTANTS.EVENTS.AUCTION_INIT); - expect(firstArgument.args.auctionId).to.be.equal(EMITTED_AUCTION_ID); - - window.rivraddon.analytics.trackPbjsEvent.restore(); - }); - - const BANNER_AD_UNITS_MOCK = [ - { - code: 'banner-container1', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 200], [300, 600]] - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: '10433394', - reserve: 0.5 - } - }, - { - bidder: 'huddledmasses', - params: { - placement_id: 0 - } - }, - ] - } - ]; -}); diff --git a/test/spec/modules/roxotAnalyticsAdapter_spec.js b/test/spec/modules/roxotAnalyticsAdapter_spec.js deleted file mode 100644 index 79c58e36735..00000000000 --- a/test/spec/modules/roxotAnalyticsAdapter_spec.js +++ /dev/null @@ -1,443 +0,0 @@ -import roxotAnalytic from 'modules/roxotAnalyticsAdapter.js'; -import {expect} from 'chai'; -import {server} from 'test/mocks/xhr.js'; - -let events = require('src/events'); -let constants = require('src/constants.json'); - -describe('Roxot Prebid Analytic', function () { - let roxotConfigServerUrl = 'config-server'; - let roxotEventServerUrl = 'event-server'; - let publisherId = 'test_roxot_prebid_analytics_publisher_id'; - - let auctionId = '0ea14159-2058-4b87-a966-9d7652176a56'; - let timeout = 3000; - let auctionStartTimestamp = Date.now(); - let bidder = 'rubicon'; - - let bidAdUnit = 'div_with_bid'; - let noBidAdUnit = 'div_no_bid'; - let bidAfterTimeoutAdUnit = 'div_after_timeout'; - - let auctionInit = { - timestamp: auctionStartTimestamp, - auctionId: auctionId, - timeout: timeout - }; - - let bidRequested = { - auctionId: auctionId, - auctionStart: auctionStartTimestamp, - bidderCode: bidder, - bidderRequestId: '10340af0c7dc72', - bids: [ - { - adUnitCode: bidAdUnit, - auctionId: auctionId, - bidId: '298bf14ecbafb', - bidder: bidder, - bidderRequestId: '10340af0c7dc72', - sizes: [[300, 250]], - startTime: auctionStartTimestamp + 50, - transactionId: '7aafa3ee-a80a-46d7-a4a0-cbcba463d97a' - }, - { - adUnitCode: bidAfterTimeoutAdUnit, - auctionId: auctionId, - bidId: '36c6375e2dceba', - bidder: bidder, - bidderRequestId: '10340af0c7dc72', - sizes: [[300, 250]], - startTime: auctionStartTimestamp + 70, - transactionId: 'cf627df3-5828-4d3e-9dd0-c1733d328142' - }, - { - adUnitCode: noBidAdUnit, - auctionId: auctionId, - bidId: '36c6375e2dce21', - bidder: bidder, - bidderRequestId: '10340af0c7dc72', - sizes: [[300, 250]], - startTime: auctionStartTimestamp + 90, - transactionId: 'cf627df3-5828-4d3e-9dd0-c1737aafa3ee' - } - ], - doneCbCallCount: 1, - start: auctionStartTimestamp, - timeout: timeout - }; - - let bidAdjustmentWithBid = { - ad: 'html', - adId: '298bf14ecbafb', - adUnitCode: bidAdUnit, - auctionId: auctionId, - bidder: bidder, - bidderCode: bidder, - cpm: 1.01, - creativeId: '2249:92806132', - currency: 'USD', - height: 250, - mediaType: 'banner', - requestId: '298bf14ecbafb', - requestTimestamp: auctionStartTimestamp + 50, - responseTimestamp: auctionStartTimestamp + 50 + 421, - size: '300x250', - source: 'client', - status: 'rendered', - statusMessage: 'Bid available', - timeToRespond: 421, - ttl: 300, - width: 300 - }; - - let bidAdjustmentAfterTimeout = { - ad: 'html', - adId: '36c6375e2dceba', - adUnitCode: bidAfterTimeoutAdUnit, - auctionId: auctionId, - bidder: bidder, - bidderCode: bidder, - cpm: 2.02, - creativeId: '2249:92806132', - currency: 'USD', - height: 250, - mediaType: 'banner', - requestId: '36c6375e2dceba', - requestTimestamp: auctionStartTimestamp + 70, - responseTimestamp: auctionStartTimestamp + 70 + 6141, - size: '300x250', - source: 'client', - status: 'rendered', - statusMessage: 'Bid available', - timeToRespond: 6141, - ttl: 300, - width: 300 - }; - - let bidAdjustmentNoBid = { - ad: 'html', - adId: '36c6375e2dce21', - adUnitCode: noBidAdUnit, - auctionId: auctionId, - bidder: bidder, - bidderCode: bidder, - cpm: 0, - creativeId: '2249:92806132', - currency: 'USD', - height: 0, - mediaType: 'banner', - requestId: '36c6375e2dce21', - requestTimestamp: auctionStartTimestamp + 90, - responseTimestamp: auctionStartTimestamp + 90 + 215, - size: '300x250', - source: 'client', - status: 'rendered', - statusMessage: 'Bid available', - timeToRespond: 215, - ttl: 300, - width: 0 - }; - - let auctionEnd = { - auctionId: auctionId - }; - - let bidTimeout = [ - { - adUnitCode: bidAfterTimeoutAdUnit, - auctionId: auctionId, - bidId: '389444beed7361', - bidder: bidder, - timeout: timeout - } - ]; - - let bidResponseWithBid = bidAdjustmentWithBid; - let bidResponseAfterTimeout = bidAdjustmentAfterTimeout; - let bidResponseNoBid = bidAdjustmentNoBid; - let bidderDone = bidRequested; - let bidWon = bidAdjustmentWithBid; - - describe('correct build and send events', function () { - beforeEach(function () { - sinon.stub(events, 'getEvents').returns([]); - }); - afterEach(function () { - roxotAnalytic.disableAnalytics(); - events.getEvents.restore(); - }); - it('should send prepared events to backend', function () { - roxotAnalytic.enableAnalytics({ - provider: 'roxot', - options: { - publisherId: publisherId, - configServer: roxotConfigServerUrl, - server: roxotEventServerUrl - } - }); - - 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}'); - - events.emit(constants.EVENTS.AUCTION_INIT, auctionInit); - events.emit(constants.EVENTS.BID_REQUESTED, bidRequested); - events.emit(constants.EVENTS.BID_ADJUSTMENT, bidAdjustmentWithBid); - events.emit(constants.EVENTS.BID_RESPONSE, bidResponseWithBid); - events.emit(constants.EVENTS.BID_ADJUSTMENT, bidAdjustmentNoBid); - events.emit(constants.EVENTS.BID_RESPONSE, bidResponseNoBid); - events.emit(constants.EVENTS.BID_TIMEOUT, bidTimeout); - events.emit(constants.EVENTS.AUCTION_END, auctionEnd); - events.emit(constants.EVENTS.BID_ADJUSTMENT, bidAdjustmentAfterTimeout); - events.emit(constants.EVENTS.BID_RESPONSE, bidResponseAfterTimeout); - events.emit(constants.EVENTS.BIDDER_DONE, bidderDone); - events.emit(constants.EVENTS.BID_WON, bidWon); - - expect(server.requests.length).to.equal(4); - - expect(server.requests[1].url).to.equal('https://' + roxotEventServerUrl + '/a?publisherId=' + publisherId + '&host=localhost'); - expect(server.requests[2].url).to.equal('https://' + roxotEventServerUrl + '/bat?publisherId=' + publisherId + '&host=localhost'); - expect(server.requests[3].url).to.equal('https://' + roxotEventServerUrl + '/i?publisherId=' + publisherId + '&host=localhost'); - - let auction = JSON.parse(server.requests[1].requestBody); - expect(auction).to.include.all.keys('event', 'eventName', 'options', 'data'); - expect(auction.event).to.equal('a'); - - expect(auction.data).to.include.all.keys('id', 'start', 'finish', 'timeout', 'adUnits'); - expect(auction.data.id).to.equal(auctionId); - expect(auction.data.timeout).to.equal(timeout); - - expect(auction.data.adUnits).to.include.all.keys(bidAdUnit, bidAfterTimeoutAdUnit, noBidAdUnit); - expect(auction.data.adUnits[bidAdUnit].bidders).to.have.property(bidder); - expect(auction.data.adUnits[bidAfterTimeoutAdUnit].bidders).to.have.property(bidder); - expect(auction.data.adUnits[noBidAdUnit].bidders).to.have.property(bidder); - - expect(auction.data.adUnits[bidAdUnit].bidders[bidder].status).to.equal('bid'); - expect(auction.data.adUnits[bidAfterTimeoutAdUnit].bidders[bidder].status).to.equal('timeout'); - expect(auction.data.adUnits[noBidAdUnit].bidders[bidder].status).to.equal('noBid'); - - let bidAfterTimeout = JSON.parse(server.requests[2].requestBody); - expect(bidAfterTimeout).to.include.all.keys('event', 'eventName', 'options', 'data'); - expect(bidAfterTimeout.event).to.equal('bat'); - - expect(bidAfterTimeout.data).to.include.all.keys('start', 'finish', 'mediaType', 'adUnit', 'bidder', 'cpm', 'size', 'auction'); - expect(bidAfterTimeout.data.adUnit).to.equal(bidAfterTimeoutAdUnit); - expect(bidAfterTimeout.data.bidder).to.equal(bidder); - expect(bidAfterTimeout.data.cpm).to.equal(bidAdjustmentAfterTimeout.cpm); - - let impression = JSON.parse(server.requests[3].requestBody); - expect(impression).to.include.all.keys('event', 'eventName', 'options', 'data'); - expect(impression.event).to.equal('i'); - - expect(impression.data).to.include.all.keys('mediaType', 'adUnit', 'bidder', 'cpm', 'size', 'auction', 'isNew'); - expect(impression.data.adUnit).to.equal(bidAdUnit); - expect(impression.data.bidder).to.equal(bidder); - expect(impression.data.cpm).to.equal(bidAdjustmentWithBid.cpm); - }); - }); - - describe('support ad unit filter', function () { - beforeEach(function () { - sinon.stub(events, 'getEvents').returns([]); - }); - afterEach(function () { - roxotAnalytic.disableAnalytics(); - events.getEvents.restore(); - }); - it('should not send event for blocked ad unit', function () { - roxotAnalytic.enableAnalytics({ - provider: 'roxot', - options: { - publisherId: publisherId, - configServer: roxotConfigServerUrl, - server: roxotEventServerUrl, - adUnits: [noBidAdUnit, bidAfterTimeoutAdUnit] - } - }); - - 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}'); - - events.emit(constants.EVENTS.AUCTION_INIT, auctionInit); - events.emit(constants.EVENTS.BID_REQUESTED, bidRequested); - events.emit(constants.EVENTS.BID_ADJUSTMENT, bidAdjustmentWithBid); - events.emit(constants.EVENTS.BID_RESPONSE, bidResponseWithBid); - events.emit(constants.EVENTS.BID_ADJUSTMENT, bidAdjustmentNoBid); - events.emit(constants.EVENTS.BID_RESPONSE, bidResponseNoBid); - events.emit(constants.EVENTS.BID_TIMEOUT, bidTimeout); - events.emit(constants.EVENTS.AUCTION_END, auctionEnd); - events.emit(constants.EVENTS.BID_ADJUSTMENT, bidAdjustmentAfterTimeout); - events.emit(constants.EVENTS.BID_RESPONSE, bidResponseAfterTimeout); - events.emit(constants.EVENTS.BIDDER_DONE, bidderDone); - events.emit(constants.EVENTS.BID_WON, bidWon); - - expect(server.requests.length).to.equal(3); - - expect(server.requests[1].url).to.equal('https://' + roxotEventServerUrl + '/a?publisherId=' + publisherId + '&host=localhost'); - expect(server.requests[2].url).to.equal('https://' + roxotEventServerUrl + '/bat?publisherId=' + publisherId + '&host=localhost'); - - let auction = JSON.parse(server.requests[1].requestBody); - expect(auction.data.adUnits).to.include.all.keys(noBidAdUnit, bidAfterTimeoutAdUnit); - expect(auction.data.adUnits).to.not.include.all.keys(bidAdUnit); - }); - }); - - describe('should correct parse config', function () { - beforeEach(function () { - sinon.stub(events, 'getEvents').returns([]); - }); - - afterEach(function () { - roxotAnalytic.disableAnalytics(); - events.getEvents.restore(); - }); - - it('correct parse publisher config', function () { - let publisherOptions = { - publisherId: publisherId, - configServer: roxotConfigServerUrl, - server: roxotEventServerUrl, - anything: 'else', - }; - - roxotAnalytic.enableAnalytics({ - provider: 'roxot', - options: publisherOptions - }); - - expect(roxotAnalytic.getOptions().options).to.deep.equal(publisherOptions); - }); - - it('support deprecated options', function () { - let publisherOptions = { - publisherIds: [publisherId], - }; - - roxotAnalytic.enableAnalytics({ - provider: 'roxot', - options: publisherOptions - }); - - expect(roxotAnalytic.getOptions().options).to.deep.equal(publisherOptions); - expect(roxotAnalytic.getOptions().publisherId).to.equal(publisherId); - }); - - it('support default end-points', function () { - let publisherOptions = { - publisherId: publisherId, - }; - - roxotAnalytic.enableAnalytics({ - provider: 'roxot', - options: publisherOptions - }); - - expect(roxotAnalytic.getOptions().configServer).to.equal('pa.rxthdr.com/v3'); - expect(roxotAnalytic.getOptions().server).to.equal('pa.rxthdr.com/v3'); - }); - - it('support custom config end-point', function () { - let publisherOptions = { - publisherId: publisherId, - configServer: roxotConfigServerUrl - }; - - roxotAnalytic.enableAnalytics({ - provider: 'roxot', - options: publisherOptions - }); - - expect(roxotAnalytic.getOptions().configServer).to.equal(roxotConfigServerUrl); - expect(roxotAnalytic.getOptions().server).to.equal('pa.rxthdr.com/v3'); - }); - - it('support custom config and event end-point', function () { - let publisherOptions = { - publisherId: publisherId, - server: roxotEventServerUrl - }; - - roxotAnalytic.enableAnalytics({ - provider: 'roxot', - options: publisherOptions - }); - - expect(roxotAnalytic.getOptions().configServer).to.equal(roxotEventServerUrl); - expect(roxotAnalytic.getOptions().server).to.equal(roxotEventServerUrl); - }); - - it('support different config and event end-points', function () { - let publisherOptions = { - publisherId: publisherId, - configServer: roxotConfigServerUrl, - server: roxotEventServerUrl - }; - - roxotAnalytic.enableAnalytics({ - provider: 'roxot', - options: publisherOptions - }); - - expect(roxotAnalytic.getOptions().configServer).to.equal(roxotConfigServerUrl); - expect(roxotAnalytic.getOptions().server).to.equal(roxotEventServerUrl); - }); - - it('support adUnit filter', function () { - let publisherOptions = { - publisherId: publisherId, - adUnits: ['div1', 'div2'] - }; - - roxotAnalytic.enableAnalytics({ - provider: 'roxot', - options: publisherOptions - }); - - expect(roxotAnalytic.getOptions().adUnits).to.deep.equal(['div1', 'div2']); - }); - - it('support fail loading server config', function () { - let publisherOptions = { - publisherId: publisherId - }; - - roxotAnalytic.enableAnalytics({ - provider: 'roxot', - options: publisherOptions - }); - - server.requests[0].respond(500); - - expect(roxotAnalytic.getOptions().serverConfig).to.deep.equal({a: 1, i: 1, bat: 1, isError: 1}); - }); - }); - - describe('build utm tag data', function () { - beforeEach(function () { - localStorage.setItem('roxot_analytics_utm_source', 'utm_source'); - localStorage.setItem('roxot_analytics_utm_medium', 'utm_medium'); - localStorage.setItem('roxot_analytics_utm_campaign', ''); - localStorage.setItem('roxot_analytics_utm_term', ''); - localStorage.setItem('roxot_analytics_utm_content', ''); - localStorage.setItem('roxot_analytics_utm_ttl', Date.now()); - }); - afterEach(function () { - localStorage.removeItem('roxot_analytics_utm_source'); - localStorage.removeItem('roxot_analytics_utm_medium'); - localStorage.removeItem('roxot_analytics_utm_campaign'); - localStorage.removeItem('roxot_analytics_utm_term'); - localStorage.removeItem('roxot_analytics_utm_content'); - localStorage.removeItem('roxot_analytics_utm_ttl'); - }); - it('should build utm data from local storage', function () { - let utmTagData = roxotAnalytic.buildUtmTagData(); - expect(utmTagData.utm_source).to.equal('utm_source'); - expect(utmTagData.utm_medium).to.equal('utm_medium'); - expect(utmTagData.utm_campaign).to.equal(''); - expect(utmTagData.utm_term).to.equal(''); - expect(utmTagData.utm_content).to.equal(''); - }); - }); -}); diff --git a/test/spec/modules/rtbdemandBidAdapter_spec.js b/test/spec/modules/rtbdemandBidAdapter_spec.js deleted file mode 100644 index be9872ec01b..00000000000 --- a/test/spec/modules/rtbdemandBidAdapter_spec.js +++ /dev/null @@ -1,174 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/rtbdemandBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('rtbdemandAdapter', 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 () { - let bid = { - 'bidder': 'rtbdemand', - 'params': { - 'zoneid': '37', - 'floor': '0.05', - 'server': 'bidding.rtbdemand.com', - }, - '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(bid)).to.equal(true); - }); - - it('should return true when required params found', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'zoneid': '37', - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'zoneid': 0, - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidderRequest = { - bidderCode: 'rtbdemand', - auctionId: 'c45dd708-a418-42ec-b8a7-b70a6c6fab0a', - bidderRequestId: '178e34bad3658f', - bids: [ - { - bidder: 'rtbdemand', - params: { - zoneid: '37', - floor: '0.05', - server: 'bidding.rtbdemand.com', - }, - placementCode: '/19968336/header-bid-tag-0', - sizes: [[300, 250], [320, 50]], - bidId: '2ffb201a808da7', - bidderRequestId: '178e34bad3658f', - auctionId: 'c45dd708-a418-42ec-b8a7-b70a6c6fab0a', - transactionId: 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b' - }, - { - bidder: 'rtbdemand', - params: { - zoneid: '37', - floor: '0.05', - server: 'bidding.rtbdemand.com', - }, - placementCode: '/19968336/header-bid-tag-0', - sizes: [[728, 90], [320, 50]], - bidId: '2ffb201a808da7', - bidderRequestId: '178e34bad3658f', - auctionId: 'c45dd708-a418-42ec-b8a7-b70a6c6fab0a', - transactionId: 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b' - } - ], - start: 1472239426002, - auctionStart: 1472239426000, - timeout: 5000 - }; - - it('should add source and verison to the tag', function () { - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - const payload = request.data; - expect(payload.from).to.exist; - expect(payload.v).to.exist; - expect(payload.request_id).to.exist; - expect(payload.imp_id).to.exist; - expect(payload.aff).to.exist; - expect(payload.bid_floor).to.exist; - expect(payload.charset).to.exist; - expect(payload.site_domain).to.exist; - expect(payload.site_page).to.exist; - expect(payload.subid).to.exist; - expect(payload.flashver).to.exist; - expect(payload.tmax).to.exist; - }); - - it('sends bid request to ENDPOINT via GET', function () { - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(request.url).to.equal('https://bidding.rtbdemand.com/hb'); - expect(request.method).to.equal('GET'); - }); - }) - - describe('interpretResponse', function () { - let response = { - 'id': '543210', - 'seatbid': [ { - 'bid': [ { - 'id': '1111111', - 'impid': 'bidId-123456-1', - 'w': 728, - 'h': 90, - 'price': 0.09, - 'adm': '', - } ], - } ] - }; - - it('should get correct bid response', function () { - let expectedResponse = [ - { - requestId: 'bidId-123456-1', - creativeId: 'bidId-123456-1', - cpm: 0.09, - width: 728, - height: 90, - ad: '', - netRevenue: true, - currency: 'USD', - ttl: 360, - } - ]; - - let result = spec.interpretResponse({ body: response }); - expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); - }); - - it('handles nobid responses', function () { - let response = { - 'id': '543210', - 'seatbid': [ ] - }; - - let result = spec.interpretResponse({ body: response }); - expect(result.length).to.equal(0); - }); - }); - - describe('user sync', function () { - const syncUrl = 'https://bidding.rtbdemand.com/delivery/matches.php?type=iframe'; - - it('should register the sync iframe', function () { - expect(spec.getUserSyncs({})).to.be.undefined; - expect(spec.getUserSyncs({iframeEnabled: false})).to.be.undefined; - const options = spec.getUserSyncs({iframeEnabled: true}); - expect(options).to.not.be.undefined; - expect(options).to.have.lengthOf(1); - expect(options[0].type).to.equal('iframe'); - expect(options[0].url).to.equal(syncUrl); - }); - }); -}); diff --git a/test/spec/modules/rtbhouseBidAdapter_spec.js b/test/spec/modules/rtbhouseBidAdapter_spec.js deleted file mode 100644 index d6bee26d73b..00000000000 --- a/test/spec/modules/rtbhouseBidAdapter_spec.js +++ /dev/null @@ -1,533 +0,0 @@ -import { expect } from 'chai'; -import { OPENRTB, spec } from 'modules/rtbhouseBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('RTBHouseAdapter', () => { - 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 () { - let bid = { - 'bidder': 'rtbhouse', - 'params': { - 'publisherId': 'PREBID_TEST', - 'region': 'prebid-eu' - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]], - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('Checking backward compatibility. should return true', function () { - let bid2 = Object.assign({}, bid); - delete bid2.mediaTypes; - bid2.sizes = [[300, 250], [300, 600]]; - expect(spec.isBidRequestValid(bid2)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'someIncorrectParam': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests; - const bidderRequest = { - 'refererInfo': { - 'numIframes': 0, - 'reachedTop': true, - 'referer': 'https://example.com', - 'stack': ['https://example.com'] - } - }; - - beforeEach(() => { - bidRequests = [ - { - 'bidder': 'rtbhouse', - 'params': { - 'publisherId': 'PREBID_TEST', - 'region': 'prebid-eu', - 'test': 1 - }, - 'adUnitCode': 'adunit-code', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]], - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'transactionId': 'example-transaction-id', - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'directseller.com', - 'sid': '00001', - 'rid': 'BidRequest1', - 'hp': 1 - } - ] - } - } - ]; - }); - - it('should build test param into the request', () => { - let builtTestRequest = spec.buildRequests(bidRequests, bidderRequest).data; - expect(JSON.parse(builtTestRequest).test).to.equal(1); - }); - - it('should build valid OpenRTB banner object', () => { - const request = JSON.parse(spec.buildRequests(bidRequests, bidderRequest).data); - const imp = request.imp[0]; - expect(imp.banner).to.deep.equal({ - w: 300, - h: 250, - format: [{ - w: 300, - h: 250 - }, { - w: 300, - h: 600 - }] - }) - }); - - it('sends bid request to ENDPOINT via POST', function () { - let bidRequest = Object.assign([], bidRequests); - delete bidRequest[0].params.test; - const request = spec.buildRequests(bidRequest, bidderRequest); - expect(request.url).to.equal('https://prebid-eu.creativecdn.com/bidder/prebid/bids'); - expect(request.method).to.equal('POST'); - }); - - it('should not populate GDPR if for non-EEA users', function () { - let bidRequest = Object.assign([], bidRequests); - delete bidRequest[0].params.test; - const request = spec.buildRequests(bidRequest, bidderRequest); - let data = JSON.parse(request.data); - expect(data).to.not.have.property('regs'); - expect(data).to.not.have.property('user'); - }); - - it('should populate GDPR and consent string if available for EEA users', function () { - let bidRequest = Object.assign([], bidRequests); - delete bidRequest[0].params.test; - const request = spec.buildRequests( - bidRequest, - Object.assign({}, bidderRequest, { - gdprConsent: { - gdprApplies: true, - consentString: 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==' - } - }) - ); - let data = JSON.parse(request.data); - expect(data.regs.ext.gdpr).to.equal(1); - expect(data.user.ext.consent).to.equal('BOJ8RZsOJ8RZsABAB8AAAAAZ-A'); - }); - - it('should populate GDPR and empty consent string if available for EEA users without consent string but with consent', function () { - let bidRequest = Object.assign([], bidRequests); - delete bidRequest[0].params.test; - const request = spec.buildRequests( - bidRequest, - Object.assign({}, bidderRequest, { - gdprConsent: { - gdprApplies: true - } - }) - ); - let data = JSON.parse(request.data); - expect(data.regs.ext.gdpr).to.equal(1); - expect(data.user.ext.consent).to.equal(''); - }); - - it('should include banner imp in request', () => { - const bidRequest = Object.assign([], bidRequests); - const request = spec.buildRequests(bidRequest, bidderRequest); - const data = JSON.parse(request.data); - expect(data.imp[0].banner).to.not.be.empty; - }); - - it('should include source.tid in request', () => { - const bidRequest = Object.assign([], bidRequests); - const request = spec.buildRequests(bidRequest, bidderRequest); - const data = JSON.parse(request.data); - expect(data.source.tid).to.equal('example-transaction-id'); - }); - - it('should include bidfloor from floor module if avaiable', () => { - const bidRequest = Object.assign([], bidRequests); - bidRequest[0].getFloor = () => ({floor: 1.22}); - const request = spec.buildRequests(bidRequest, bidderRequest); - const data = JSON.parse(request.data); - expect(data.imp[0].bidfloor).to.equal(1.22) - }); - - it('should use bidfloor from floor module if both floor module and bid floor avaiable', () => { - const bidRequest = Object.assign([], bidRequests); - bidRequest[0].getFloor = () => ({floor: 1.22}); - bidRequest[0].params.bidfloor = 0.01; - const request = spec.buildRequests(bidRequest, bidderRequest); - const data = JSON.parse(request.data); - expect(data.imp[0].bidfloor).to.equal(1.22) - }); - - it('should include bidfloor in request if available', () => { - const bidRequest = Object.assign([], bidRequests); - bidRequest[0].params.bidfloor = 0.01; - const request = spec.buildRequests(bidRequest, bidderRequest); - const data = JSON.parse(request.data); - expect(data.imp[0].bidfloor).to.equal(0.01) - }); - - it('should include schain in request', () => { - const bidRequest = Object.assign([], bidRequests); - const request = spec.buildRequests(bidRequest, bidderRequest); - const data = JSON.parse(request.data); - expect(data.ext.schain).to.deep.equal({ - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'directseller.com', - 'sid': '00001', - 'rid': 'BidRequest1', - 'hp': 1 - } - ] - }); - }); - - it('should include source.tid in request', () => { - const bidRequest = Object.assign([], bidRequests); - const request = spec.buildRequests(bidRequest, bidderRequest); - const data = JSON.parse(request.data); - expect(data.source).to.have.deep.property('tid'); - }); - - it('should not include invalid schain', () => { - const bidRequest = Object.assign([], bidRequests); - bidRequest[0].schain = { - 'nodes': [{ - 'unknown_key': 1 - }] - }; - const request = spec.buildRequests(bidRequest, bidderRequest); - const data = JSON.parse(request.data); - expect(data.source).to.not.have.property('ext'); - }); - - describe('native imp', () => { - function basicRequest(extension) { - return Object.assign({ - bidder: 'bidder', - adUnitCode: 'adunit-code', - bidId: '1', - params: { - publisherId: 'PREBID_TEST', - region: 'prebid-eu', - test: 1 - } - }, extension); - } - - function buildImp(request) { - const resultRequest = spec.buildRequests([request], bidderRequest); - return JSON.parse(resultRequest.data).imp[0]; - } - - it('should extract native params when single mediaType', () => { - const imp = buildImp(basicRequest({ - mediaType: 'native', - nativeParams: { - title: { - required: true, - len: 100 - } - } - })); - expect(imp.native.request.assets[0]).to.deep.equal({ - id: OPENRTB.NATIVE.ASSET_ID.TITLE, - required: 1, - title: { - len: 100 - } - }) - }); - - it('should extract native params when many mediaTypes', () => { - const imp = buildImp(basicRequest({ - mediaTypes: { - native: { - title: { - len: 100 - } - } - } - })); - expect(imp.native.request.assets[0]).to.deep.equal({ - id: OPENRTB.NATIVE.ASSET_ID.TITLE, - required: 0, - title: { - len: 100 - } - }) - }); - - it('should not contain banner in imp', () => { - const imp = buildImp(basicRequest({ - mediaTypes: { - native: { - title: { - required: true - } - } - } - })); - expect(imp.banner).to.be.undefined; - }); - - describe('image sizes', () => { - it('should parse single image size', () => { - const imp = buildImp(basicRequest({ - mediaTypes: { - native: { - image: { - sizes: [300, 250] - } - } - } - })); - expect(imp.native.request.assets[0]).to.deep.equal({ - id: OPENRTB.NATIVE.ASSET_ID.IMAGE, - required: 0, - img: { - w: 300, - h: 250, - type: OPENRTB.NATIVE.IMAGE_TYPE.MAIN, - } - }) - }); - - it('should parse multiple image sizes', () => { - const imp = buildImp(basicRequest({ - mediaTypes: { - native: { - image: { - sizes: [[300, 250], [100, 100]] - } - } - } - })); - expect(imp.native.request.assets[0]).to.deep.equal({ - id: OPENRTB.NATIVE.ASSET_ID.IMAGE, - required: 0, - img: { - w: 300, - h: 250, - type: OPENRTB.NATIVE.IMAGE_TYPE.MAIN, - } - }) - }) - }); - - it('should parse aspect ratios with min_width', () => { - const imp = buildImp(basicRequest({ - mediaTypes: { - native: { - icon: { - aspect_ratios: [{ - min_width: 300, - ratio_width: 2, - ratio_height: 3, - }] - } - } - } - })); - expect(imp.native.request.assets[0]).to.deep.equal({ - id: OPENRTB.NATIVE.ASSET_ID.ICON, - required: 0, - img: { - type: OPENRTB.NATIVE.IMAGE_TYPE.ICON, - wmin: 300, - hmin: 450, - } - }) - }); - - it('should parse aspect ratios without min_width', () => { - const imp = buildImp(basicRequest({ - mediaTypes: { - native: { - icon: { - aspect_ratios: [{ - ratio_width: 2, - ratio_height: 3, - }] - } - } - } - })); - expect(imp.native.request.assets[0]).to.deep.equal({ - id: OPENRTB.NATIVE.ASSET_ID.ICON, - required: 0, - img: { - type: OPENRTB.NATIVE.IMAGE_TYPE.ICON, - wmin: 100, - hmin: 150, - } - }) - }); - - it('should handle all native assets', () => { - const imp = buildImp(basicRequest({ - mediaTypes: { - native: { - title: {}, - image: {}, - icon: {}, - sponsoredBy: {}, - body: {}, - cta: {}, - } - } - })); - expect(imp.native.request.assets.length).to.equal(6); - imp.native.request.assets.forEach(asset => { - expect(asset.id).to.be.at.least(1) - }) - }); - }); - }); - - describe('interpretResponse', function () { - let response = [{ - 'id': 'bidder_imp_identifier', - 'impid': '552b8922e28f27', - 'price': 0.5, - 'adid': 'Ad_Identifier', - 'adm': '', - 'adomain': ['rtbhouse.com'], - 'cid': 'Ad_Identifier', - 'w': 300, - 'h': 250 - }]; - - it('should get correct bid response', function () { - let expectedResponse = [ - { - 'requestId': '552b8922e28f27', - 'cpm': 0.5, - 'creativeId': 29681110, - 'width': 300, - 'height': 250, - 'ad': '', - 'mediaType': 'banner', - 'currency': 'USD', - 'ttl': 300, - 'meta': { advertiserDomains: ['rtbhouse.com'] }, - 'netRevenue': true - } - ]; - let bidderRequest; - let result = spec.interpretResponse({body: response}, {bidderRequest}); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('handles nobid responses', function () { - let response = ''; - let bidderRequest; - let result = spec.interpretResponse({body: response}, {bidderRequest}); - expect(result.length).to.equal(0); - }); - - describe('native', () => { - const adm = { - native: { - ver: 1.1, - link: { - url: 'https://example.com' - }, - imptrackers: [ - 'https://example.com/imptracker' - ], - assets: [{ - id: OPENRTB.NATIVE.ASSET_ID.TITLE, - required: 1, - title: { - text: 'Title text' - } - }, { - id: OPENRTB.NATIVE.ASSET_ID.IMAGE, - required: 1, - img: { - url: 'https://example.com/image.jpg', - w: 150, - h: 50 - } - }, { - id: OPENRTB.NATIVE.ASSET_ID.BODY, - required: 0, - data: { - value: 'Body text' - } - }], - } - }; - const response = [{ - 'id': 'id', - 'impid': 'impid', - 'price': 1, - 'adid': 'adid', - 'adm': JSON.stringify(adm), - 'adomain': ['rtbhouse.com'], - 'cid': 'cid', - 'w': 1, - 'h': 1 - }]; - - it('should contain native assets in valid format', () => { - 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', - clickUrl: encodeURIComponent('https://example.com'), - impressionTrackers: ['https://example.com/imptracker'], - image: { - url: encodeURIComponent('https://example.com/image.jpg'), - width: 150, - height: 50 - }, - body: 'Body text' - }); - }); - }); - }); -}); diff --git a/test/spec/modules/rtbsapeBidAdapter_spec.js b/test/spec/modules/rtbsapeBidAdapter_spec.js deleted file mode 100644 index 4c3814385b3..00000000000 --- a/test/spec/modules/rtbsapeBidAdapter_spec.js +++ /dev/null @@ -1,166 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/rtbsapeBidAdapter.js'; -import * as utils from 'src/utils.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); - }); - - 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); - }); - }); - - it('buildRequests', function () { - let bidRequestData = [{ - bidId: 'bid1234', - bidder: 'rtbsape', - params: {placeId: 4321}, - sizes: [[240, 400]] - }]; - let bidderRequest = { - auctionId: '2e208334-cafe-4c2c-b06b-f055ff876852', - bidderRequestId: '1392d0aa613366', - refererInfo: {} - }; - let request = spec.buildRequests(bidRequestData, bidderRequest); - expect(request.data.auctionId).to.equal('2e208334-cafe-4c2c-b06b-f055ff876852'); - expect(request.data.requestId).to.equal('1392d0aa613366'); - expect(request.data.bids[0].bidId).to.equal('bid1234'); - expect(request.data.timezone).to.not.equal(undefined); - }); - - describe('interpretResponse', function () { - it('banner', function () { - let serverResponse = { - body: { - bids: [{ - requestId: 'bid1234', - cpm: 2.21, - currency: 'RUB', - width: 240, - height: 400, - netRevenue: true, - ad: 'Ad html' - }] - } - }; - let bids = spec.interpretResponse(serverResponse, {data: {bids: [{mediaTypes: {banner: true}}]}}); - expect(bids).to.have.lengthOf(1); - let bid = bids[0]; - expect(bid.cpm).to.equal(2.21); - expect(bid.currency).to.equal('RUB'); - expect(bid.width).to.equal(240); - expect(bid.height).to.equal(400); - expect(bid.netRevenue).to.equal(true); - expect(bid.requestId).to.equal('bid1234'); - expect(bid.ad).to.equal('Ad html'); - }); - - describe('video (outstream)', function () { - let bid; - - before(() => { - let serverResponse = { - body: { - bids: [{ - requestId: 'bid1234', - adUnitCode: 'ad-bid1234', - cpm: 3.32, - currency: 'RUB', - width: 600, - height: 340, - netRevenue: true, - vastUrl: 'https://cdn-rtb.sape.ru/vast/4321.xml', - meta: { - mediaType: 'video' - } - }] - } - }; - let serverRequest = { - data: { - bids: [{ - bidId: 'bid1234', - adUnitCode: 'ad-bid1234', - mediaTypes: { - video: { - context: 'outstream' - } - }, - params: { - placeId: 4321, - video: { - playerMuted: false - } - } - }] - } - }; - let bids = spec.interpretResponse(serverResponse, serverRequest); - expect(bids).to.have.lengthOf(1); - bid = bids[0]; - }); - - it('should add renderer', () => { - expect(bid).to.have.own.property('renderer'); - expect(bid.renderer).to.be.instanceof(Renderer); - expect(bid.renderer.url).to.equal('https://cdn-rtb.sape.ru/js/player.js'); - expect(bid.playerMuted).to.equal(false); - }); - - it('should create player instance', () => { - let spy = false; - - window.sapeRtbPlayerHandler = function (id, w, h, m) { - const player = {addSlot: () => [id, w, h, m]} - expect(spy).to.equal(false); - spy = sinon.spy(player, 'addSlot'); - return player; - }; - - executeRenderer(bid.renderer, bid); - expect(spy).to.not.equal(false); - expect(spy.called).to.be.true; - - const spyCall = spy.getCall(0); - expect(spyCall.args[0].url).to.be.equal('https://cdn-rtb.sape.ru/vast/4321.xml'); - expect(spyCall.returnValue[0]).to.be.equal('ad-bid1234'); - expect(spyCall.returnValue[1]).to.be.equal(600); - expect(spyCall.returnValue[2]).to.be.equal(340); - expect(spyCall.returnValue[3]).to.be.equal(false); - }); - }); - }); - - it('getUserSyncs', function () { - 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'}); - }); - - describe('onBidWon', function () { - beforeEach(function () { - sinon.stub(utils, 'triggerPixel'); - }); - - afterEach(function () { - utils.triggerPixel.restore(); - }); - - it('called once', function () { - 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'}); - expect(utils.triggerPixel.called).to.equal(false); - }); - }); -}); diff --git a/test/spec/modules/rtbsolutionsBidAdapter_spec.js b/test/spec/modules/rtbsolutionsBidAdapter_spec.js deleted file mode 100644 index c47b086fe50..00000000000 --- a/test/spec/modules/rtbsolutionsBidAdapter_spec.js +++ /dev/null @@ -1,62 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/rtbsolutionsBidAdapter.js'; - -describe('rtbsolutionsBidAdapterTests', function () { - it('validate_pub_params_1', function () { - expect(spec.isBidRequestValid({ - bidder: 'rtbsolutions', - params: { - blockId: 777 - } - })).to.equal(true); - }); - it('validate_pub_params_2', function () { - expect(spec.isBidRequestValid({ - bidder: 'rtbsolutions', - params: { - s1: 'test' - } - })).to.equal(false); - }); - it('validate_generated_params', function () { - let bidderRequest = { - bids: [], - refererInfo: { - referer: '' - } - }; - bidderRequest.bids.push({ - bidId: 'bid1234', - bidder: 'rtbsolutions', - params: {blockId: 777}, - sizes: [[240, 400]] - }); - let request = spec.buildRequests(true, bidderRequest); - let req_data = request.data[0]; - expect(req_data.bid_id).to.equal('bid1234'); - }); - it('validate_response_params', function () { - let serverResponse = { - body: [{ - ad: 'Ad html', - bid_id: 'bid1234', - cpm: 1, - creative_id: 1, - height: 480, - nurl: 'http://test.test', - width: 640, - currency: 'USD', - }] - }; - let bids = spec.interpretResponse(serverResponse); - expect(bids).to.have.lengthOf(1); - let bid = bids[0]; - expect(bid.cpm).to.equal(1); - expect(bid.currency).to.equal('USD'); - expect(bid.width).to.equal(640); - expect(bid.height).to.equal(480); - expect(bid.netRevenue).to.equal(true); - expect(bid.requestId).to.equal('bid1234'); - expect(bid.ad).to.equal('Ad html'); - }); -}); diff --git a/test/spec/modules/rubiconAnalyticsAdapter_spec.js b/test/spec/modules/rubiconAnalyticsAdapter_spec.js deleted file mode 100644 index df8bf03b56a..00000000000 --- a/test/spec/modules/rubiconAnalyticsAdapter_spec.js +++ /dev/null @@ -1,2064 +0,0 @@ -import rubiconAnalyticsAdapter, { - SEND_TIMEOUT, - parseBidResponse, - getHostNameFromReferer, - storage, - rubiConf, -} from 'modules/rubiconAnalyticsAdapter.js'; -import CONSTANTS from 'src/constants.json'; -import { config } from 'src/config.js'; -import { server } from 'test/mocks/xhr.js'; -import * as mockGpt from '../integration/faker/googletag.js'; -import { - setConfig, - addBidResponseHook, -} from 'modules/currency.js'; -let Ajv = require('ajv'); -let schema = require('./rubiconAnalyticsSchema.json'); -let ajv = new Ajv({ - allErrors: true -}); - -let validator = ajv.compile(schema); - -function validate(message) { - validator(message); - expect(validator.errors).to.deep.equal(null); -} - -// using es6 "import * as events from 'src/events.js'" causes the events.getEvents stub not to work... -let events = require('src/events.js'); -let utils = require('src/utils.js'); - -const { - EVENTS: { - AUCTION_INIT, - AUCTION_END, - BID_REQUESTED, - BID_RESPONSE, - BIDDER_DONE, - BID_WON, - BID_TIMEOUT, - SET_TARGETING - } -} = CONSTANTS; - -const BID = { - 'bidder': 'rubicon', - 'width': 640, - 'height': 480, - 'mediaType': 'video', - 'statusMessage': 'Bid available', - 'bidId': '2ecff0db240757', - 'adId': 'fake_ad_id', - 'source': 'client', - 'requestId': '2ecff0db240757', - 'currency': 'USD', - 'creativeId': '3571560', - 'cpm': 1.22752, - 'ttl': 300, - 'netRevenue': false, - 'ad': '', - 'rubiconTargeting': { - 'rpfl_elemid': '/19968336/header-bid-tag-0', - 'rpfl_14062': '2_tier0100' - }, - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa', - 'responseTimestamp': 1519149629415, - 'requestTimestamp': 1519149628471, - 'adUnitCode': '/19968336/header-bid-tag-0', - 'timeToRespond': 944, - 'pbLg': '1.00', - 'pbMg': '1.20', - 'pbHg': '1.22', - 'pbAg': '1.20', - 'pbDg': '1.22', - 'pbCg': '', - 'size': '640x480', - 'adserverTargeting': { - 'hb_bidder': 'rubicon', - 'hb_adid': '2ecff0db240757', - 'hb_pb': 1.20, - 'hb_size': '640x480', - 'hb_source': 'client' - }, - getStatusCode() { - return 1; - } -}; - -const BID2 = Object.assign({}, BID, { - adUnitCode: '/19968336/header-bid-tag1', - bidId: '3bd4ebb1c900e2', - adId: 'fake_ad_id', - requestId: '3bd4ebb1c900e2', - width: 728, - height: 90, - mediaType: 'banner', - cpm: 1.52, - source: 'server', - seatBidId: 'aaaa-bbbb-cccc-dddd', - rubiconTargeting: { - 'rpfl_elemid': '/19968336/header-bid-tag1', - 'rpfl_14062': '2_tier0100' - }, - adserverTargeting: { - 'hb_bidder': 'rubicon', - 'hb_adid': '3bd4ebb1c900e2', - 'hb_pb': '1.500', - 'hb_size': '728x90', - 'hb_source': 'server' - } -}); - -const BID3 = Object.assign({}, BID, { - adUnitCode: '/19968336/siderail-tag1', - bidId: '5fg6hyy4r879f0', - adId: 'fake_ad_id', - requestId: '5fg6hyy4r879f0', - width: 300, - height: 250, - mediaType: 'banner', - cpm: 2.01, - source: 'server', - seatBidId: 'aaaa-bbbb-cccc-dddd', - rubiconTargeting: { - 'rpfl_elemid': '/19968336/siderail-tag1', - 'rpfl_14062': '15_tier0200' - }, - adserverTargeting: { - 'hb_bidder': 'rubicon', - 'hb_adid': '5fg6hyy4r879f0', - 'hb_pb': '2.00', - 'hb_size': '300x250', - 'hb_source': 'server' - } -}); - -const BID4 = Object.assign({}, BID, { - adUnitCode: '/19968336/header-bid-tag1', - bidId: '3bd4ebb1c900e2', - adId: 'fake_ad_id', - requestId: '3bd4ebb1c900e2', - width: 728, - height: 90, - mediaType: 'banner', - cpm: 1.52, - source: 'server', - pbsBidId: 'zzzz-yyyy-xxxx-wwww', - seatBidId: 'aaaa-bbbb-cccc-dddd', - rubiconTargeting: { - 'rpfl_elemid': '/19968336/header-bid-tag1', - 'rpfl_14062': '2_tier0100' - }, - adserverTargeting: { - 'hb_bidder': 'rubicon', - 'hb_adid': '3bd4ebb1c900e2', - 'hb_pb': '1.500', - 'hb_size': '728x90', - 'hb_source': 'server' - } -}); - -const floorMinRequest = { - 'bidder': 'rubicon', - 'params': { - 'accountId': '14062', - 'siteId': '70608', - 'zoneId': '335918', - 'userId': '12346', - 'keywords': ['a', 'b', 'c'], - 'inventory': {'rating': '4-star', 'prodtype': 'tech'}, - 'visitor': {'ucat': 'new', 'lastsearch': 'iphone'}, - 'position': 'atf' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'adUnitCode': '/19968336/siderail-tag1', - 'transactionId': 'c435626g-9e3f-401a-bee1-d56aec29a1d4', - 'sizes': [[300, 250]], - 'bidId': '5fg6hyy4r879f0', - 'bidderRequestId': '1be65d7958826a', - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa' -}; - -const MOCK = { - SET_TARGETING: { - [BID.adUnitCode]: BID.adserverTargeting, - [BID2.adUnitCode]: BID2.adserverTargeting, - [BID3.adUnitCode]: BID3.adserverTargeting - }, - AUCTION_INIT: { - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa', - 'timestamp': 1519767010567, - 'auctionStatus': 'inProgress', - 'adUnits': [ { - 'code': '/19968336/header-bid-tag1', - 'sizes': [[640, 480]], - 'bids': [ { - 'bidder': 'rubicon', - 'params': { - 'accountId': 1001, 'siteId': 113932, 'zoneId': 535512 - } - } ], - 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014' - } - ], - 'adUnitCodes': ['/19968336/header-bid-tag1'], - 'bidderRequests': [ { - 'bidderCode': 'rubicon', - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa', - 'bidderRequestId': '1be65d7958826a', - 'bids': [ { - 'bidder': 'rubicon', - 'params': { - 'accountId': 1001, 'siteId': 113932, 'zoneId': 535512 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[640, 480]] - } - }, - 'adUnitCode': '/19968336/header-bid-tag1', - 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014', - 'sizes': [[640, 480]], - 'bidId': '2ecff0db240757', - 'bidderRequestId': '1be65d7958826a', - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa', - 'src': 'client', - 'bidRequestsCount': 1 - } - ], - 'timeout': 3000, - 'refererInfo': { - 'referer': 'http://www.test.com/page.html', 'reachedTop': true, 'numIframes': 0, 'stack': ['http://www.test.com/page.html'] - } - } - ], - 'bidsReceived': [], - 'winningBids': [], - 'timeout': 3000, - 'config': { - 'accountId': 1001, 'endpoint': '//localhost:9999/event' - } - }, - BID_REQUESTED: { - 'bidder': 'rubicon', - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa', - 'bidderRequestId': '1be65d7958826a', - 'bids': [ - { - 'bidder': 'rubicon', - 'params': { - 'accountId': '1001', - 'siteId': '70608', - 'zoneId': '335918', - 'userId': '12346', - 'keywords': ['a', 'b', 'c'], - 'inventory': 'test', - 'visitor': {'ucat': 'new', 'lastsearch': 'iphone'}, - 'position': 'btf', - 'video': { - 'language': 'en', - 'playerHeight': 480, - 'playerWidth': 640, - 'size_id': 203, - 'skip': 1, - 'skipdelay': 15, - 'aeParams': { - 'p_aso.video.ext.skip': '1', - 'p_aso.video.ext.skipdelay': '15' - } - } - }, - 'mediaType': 'video', - 'adUnitCode': '/19968336/header-bid-tag-0', - 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014', - 'sizes': [[640, 480]], - 'bidId': '2ecff0db240757', - 'bidderRequestId': '1be65d7958826a', - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa', - 'src': 'client' - }, - { - 'bidder': 'rubicon', - 'params': { - 'accountId': '14062', - 'siteId': '70608', - 'zoneId': '335918', - 'userId': '12346', - 'keywords': ['a', 'b', 'c'], - 'inventory': {'rating': '4-star', 'prodtype': 'tech'}, - 'visitor': {'ucat': 'new', 'lastsearch': 'iphone'}, - 'position': 'atf' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[1000, 300], [970, 250], [728, 90]] - } - }, - 'adUnitCode': '/19968336/header-bid-tag1', - 'transactionId': 'c116413c-9e3f-401a-bee1-d56aec29a1d4', - 'sizes': [[1000, 300], [970, 250], [728, 90]], - 'bidId': '3bd4ebb1c900e2', - 'bidderRequestId': '1be65d7958826a', - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa', - 'src': 's2s' - } - ], - 'auctionStart': 1519149536560, - 'timeout': 5000, - 'start': 1519149562216, - 'refererInfo': { - 'referer': 'http://www.test.com/page.html', 'reachedTop': true, 'numIframes': 0, 'stack': ['http://www.test.com/page.html'] - } - }, - BID_RESPONSE: [ - BID, - BID2, - BID3 - ], - AUCTION_END: { - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa' - }, - BID_WON: [ - Object.assign({}, BID, { - 'status': 'rendered' - }), - Object.assign({}, BID2, { - 'status': 'rendered' - }), - Object.assign({}, BID3, { - 'status': 'rendered' - }) - ], - BIDDER_DONE: { - 'bidderCode': 'rubicon', - 'serverResponseTimeMs': 42, - 'bids': [ - BID, - Object.assign({}, BID2, { - 'serverResponseTimeMs': 42, - }), - Object.assign({}, BID3, { - 'serverResponseTimeMs': 55, - }) - ] - }, - BID_TIMEOUT: [ - { - 'bidId': '2ecff0db240757', - 'bidder': 'rubicon', - 'adUnitCode': '/19968336/header-bid-tag-0', - 'auctionId': '25c6d7f5-699a-4bfc-87c9-996f915341fa' - } - ] -}; - -const STUBBED_UUID = '12345678-1234-1234-1234-123456789abc'; - -const ANALYTICS_MESSAGE = { - 'channel': 'web', - 'eventTimeMillis': 1519767013781, - 'integration': 'pbjs', - 'version': '$prebid.version$', - 'referrerUri': 'http://www.test.com/page.html', - 'session': { - 'expires': 1519788613781, - 'id': STUBBED_UUID, - 'start': 1519767013781 - }, - 'referrerHostname': 'www.test.com', - 'auctions': [ - { - 'requestId': '25c6d7f5-699a-4bfc-87c9-996f915341fa', - 'clientTimeoutMillis': 3000, - 'serverTimeoutMillis': 1000, - 'accountId': 1001, - 'samplingFactor': 1, - 'adUnits': [ - { - 'adUnitCode': '/19968336/header-bid-tag-0', - 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014', - 'videoAdFormat': 'outstream', - 'mediaTypes': [ - 'video' - ], - 'dimensions': [ - { - 'width': 640, - 'height': 480 - } - ], - 'status': 'success', - 'accountId': 1001, - 'siteId': 70608, - 'zoneId': 335918, - 'adserverTargeting': { - 'hb_bidder': 'rubicon', - 'hb_adid': '2ecff0db240757', - 'hb_pb': '1.200', - 'hb_size': '640x480', - 'hb_source': 'client' - }, - 'bids': [ - { - 'bidder': 'rubicon', - 'bidId': '2ecff0db240757', - 'status': 'success', - 'source': 'client', - 'clientLatencyMillis': 3214, - 'params': { - 'accountId': '1001', - 'siteId': '70608', - 'zoneId': '335918' - }, - 'bidResponse': { - 'bidPriceUSD': 1.22752, - 'dimensions': { - 'width': 640, - 'height': 480 - }, - 'mediaType': 'video' - } - } - ] - }, - { - 'adUnitCode': '/19968336/header-bid-tag1', - 'transactionId': 'c116413c-9e3f-401a-bee1-d56aec29a1d4', - 'mediaTypes': [ - 'banner' - ], - 'dimensions': [ - { - 'width': 1000, - 'height': 300 - }, - { - 'width': 970, - 'height': 250 - }, - { - 'width': 728, - 'height': 90 - } - ], - 'status': 'success', - 'adserverTargeting': { - 'hb_bidder': 'rubicon', - 'hb_adid': '3bd4ebb1c900e2', - 'hb_pb': '1.500', - 'hb_size': '728x90', - 'hb_source': 'server' - }, - 'bids': [ - { - 'bidder': 'rubicon', - 'bidId': 'aaaa-bbbb-cccc-dddd', - 'status': 'success', - 'source': 'server', - 'clientLatencyMillis': 3214, - 'serverLatencyMillis': 42, - 'params': { - 'accountId': '14062', - 'siteId': '70608', - 'zoneId': '335918' - }, - 'bidResponse': { - 'bidPriceUSD': 1.52, - 'dimensions': { - 'width': 728, - 'height': 90 - }, - 'mediaType': 'banner' - } - } - ] - } - ] - } - ], - 'bidsWon': [ - { - 'bidder': 'rubicon', - 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014', - 'adUnitCode': '/19968336/header-bid-tag-0', - 'bidId': '2ecff0db240757', - 'status': 'success', - 'source': 'client', - 'clientLatencyMillis': 3214, - 'samplingFactor': 1, - 'accountId': 1001, - 'siteId': 70608, - 'zoneId': 335918, - 'params': { - 'accountId': '1001', - 'siteId': '70608', - 'zoneId': '335918' - }, - 'videoAdFormat': 'outstream', - 'mediaTypes': [ - 'video' - ], - 'adserverTargeting': { - 'hb_bidder': 'rubicon', - 'hb_adid': '2ecff0db240757', - 'hb_pb': '1.200', - 'hb_size': '640x480', - 'hb_source': 'client' - }, - 'bidResponse': { - 'bidPriceUSD': 1.22752, - 'dimensions': { - 'width': 640, - 'height': 480 - }, - 'mediaType': 'video' - }, - 'bidwonStatus': 'success' - }, - { - 'bidder': 'rubicon', - 'transactionId': 'c116413c-9e3f-401a-bee1-d56aec29a1d4', - 'adUnitCode': '/19968336/header-bid-tag1', - 'bidId': 'aaaa-bbbb-cccc-dddd', - 'status': 'success', - 'source': 'server', - 'clientLatencyMillis': 3214, - 'serverLatencyMillis': 42, - 'samplingFactor': 1, - 'accountId': 1001, - 'params': { - 'accountId': '14062', - 'siteId': '70608', - 'zoneId': '335918' - }, - 'mediaTypes': [ - 'banner' - ], - 'adserverTargeting': { - 'hb_bidder': 'rubicon', - 'hb_adid': '3bd4ebb1c900e2', - 'hb_pb': '1.500', - 'hb_size': '728x90', - 'hb_source': 'server' - }, - 'bidResponse': { - 'bidPriceUSD': 1.52, - 'dimensions': { - 'width': 728, - 'height': 90 - }, - 'mediaType': 'banner' - }, - 'bidwonStatus': 'success' - } - ], - 'wrapper': { - 'name': '10000_fakewrapper_test' - } -}; - -function performStandardAuction(gptEvents) { - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[1]); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - - if (gptEvents && gptEvents.length) { - gptEvents.forEach(gptEvent => mockGpt.emitEvent(gptEvent.eventName, gptEvent.params)); - } - - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON[0]); - events.emit(BID_WON, MOCK.BID_WON[1]); -} - -describe('rubicon analytics adapter', function () { - let sandbox; - let clock; - let getDataFromLocalStorageStub, setDataInLocalStorageStub, localStorageIsEnabledStub; - beforeEach(function () { - getDataFromLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage'); - setDataInLocalStorageStub = sinon.stub(storage, 'setDataInLocalStorage'); - localStorageIsEnabledStub = sinon.stub(storage, 'localStorageIsEnabled'); - mockGpt.disable(); - sandbox = sinon.sandbox.create(); - - localStorageIsEnabledStub.returns(true); - - sandbox.stub(events, 'getEvents').returns([]); - - sandbox.stub(utils, 'generateUUID').returns(STUBBED_UUID); - - clock = sandbox.useFakeTimers(1519767013781); - - rubiconAnalyticsAdapter.referrerHostname = ''; - - config.setConfig({ - s2sConfig: { - timeout: 1000, - accountId: 10000, - }, - rubicon: { - wrapperName: '10000_fakewrapper_test' - } - }) - }); - - afterEach(function () { - sandbox.restore(); - config.resetConfig(); - mockGpt.enable(); - getDataFromLocalStorageStub.restore(); - setDataInLocalStorageStub.restore(); - localStorageIsEnabledStub.restore(); - }); - - it('should require accountId', function () { - sandbox.stub(utils, 'logError'); - - rubiconAnalyticsAdapter.enableAnalytics({ - options: { - endpoint: '//localhost:9999/event' - } - }); - - expect(utils.logError.called).to.equal(true); - }); - - it('should require endpoint', function () { - sandbox.stub(utils, 'logError'); - - rubiconAnalyticsAdapter.enableAnalytics({ - options: { - accountId: 1001 - } - }); - - expect(utils.logError.called).to.equal(true); - }); - - describe('config subscribe', function() { - it('should update the pvid if user asks', function () { - expect(utils.generateUUID.called).to.equal(false); - config.setConfig({rubicon: {updatePageView: true}}); - expect(utils.generateUUID.called).to.equal(true); - }); - it('should merge in and preserve older set configs', function () { - config.setConfig({ - rubicon: { - wrapperName: '1001_general', - int_type: 'dmpbjs', - fpkvs: { - source: 'fb' - } - } - }); - expect(rubiConf).to.deep.equal({ - analyticsEventDelay: 0, - pvid: '12345678', - wrapperName: '1001_general', - int_type: 'dmpbjs', - fpkvs: { - source: 'fb' - }, - updatePageView: true - }); - - // update it with stuff - config.setConfig({ - rubicon: { - fpkvs: { - link: 'email' - } - } - }); - expect(rubiConf).to.deep.equal({ - analyticsEventDelay: 0, - pvid: '12345678', - wrapperName: '1001_general', - int_type: 'dmpbjs', - fpkvs: { - source: 'fb', - link: 'email' - }, - updatePageView: true - }); - - // overwriting specific edge keys should update them - config.setConfig({ - rubicon: { - fpkvs: { - link: 'iMessage', - source: 'twitter' - } - } - }); - expect(rubiConf).to.deep.equal({ - analyticsEventDelay: 0, - pvid: '12345678', - wrapperName: '1001_general', - int_type: 'dmpbjs', - fpkvs: { - link: 'iMessage', - source: 'twitter' - }, - updatePageView: true - }); - }); - }); - - describe('sampling', function () { - beforeEach(function () { - sandbox.stub(Math, 'random').returns(0.08); - sandbox.stub(utils, 'logError'); - }); - - afterEach(function () { - rubiconAnalyticsAdapter.disableAnalytics(); - }); - - describe('with options.samplingFactor', function () { - it('should sample', function () { - rubiconAnalyticsAdapter.enableAnalytics({ - options: { - endpoint: '//localhost:9999/event', - accountId: 1001, - samplingFactor: 10 - } - }); - - performStandardAuction(); - - expect(server.requests.length).to.equal(1); - }); - - it('should unsample', function () { - rubiconAnalyticsAdapter.enableAnalytics({ - options: { - endpoint: '//localhost:9999/event', - accountId: 1001, - samplingFactor: 20 - } - }); - - performStandardAuction(); - - expect(server.requests.length).to.equal(0); - }); - - it('should throw errors for invalid samplingFactor', function () { - rubiconAnalyticsAdapter.enableAnalytics({ - options: { - endpoint: '//localhost:9999/event', - accountId: 1001, - samplingFactor: 30 - } - }); - - performStandardAuction(); - - expect(server.requests.length).to.equal(0); - expect(utils.logError.called).to.equal(true); - }); - }); - describe('with options.sampling', function () { - it('should sample', function () { - rubiconAnalyticsAdapter.enableAnalytics({ - options: { - endpoint: '//localhost:9999/event', - accountId: 1001, - sampling: 0.1 - } - }); - - performStandardAuction(); - - expect(server.requests.length).to.equal(1); - }); - - it('should unsample', function () { - rubiconAnalyticsAdapter.enableAnalytics({ - options: { - endpoint: '//localhost:9999/event', - accountId: 1001, - sampling: 0.05 - } - }); - - performStandardAuction(); - - expect(server.requests.length).to.equal(0); - }); - - it('should throw errors for invalid samplingFactor', function () { - rubiconAnalyticsAdapter.enableAnalytics({ - options: { - endpoint: '//localhost:9999/event', - accountId: 1001, - sampling: 1 / 30 - } - }); - - performStandardAuction(); - - expect(server.requests.length).to.equal(0); - expect(utils.logError.called).to.equal(true); - }); - }); - }); - - describe('when handling events', function () { - beforeEach(function () { - rubiconAnalyticsAdapter.enableAnalytics({ - options: { - endpoint: '//localhost:9999/event', - accountId: 1001 - } - }); - }); - - afterEach(function () { - rubiconAnalyticsAdapter.disableAnalytics(); - }); - - it('should build a batched message from prebid events', function () { - performStandardAuction(); - - expect(server.requests.length).to.equal(1); - let request = server.requests[0]; - - expect(request.url).to.equal('//localhost:9999/event'); - - let message = JSON.parse(request.requestBody); - validate(message); - - expect(message).to.deep.equal(ANALYTICS_MESSAGE); - }); - - it('should handle bidResponse dimensions correctly', function () { - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - - // mock bid response with playerWidth and playerHeight (NO width and height) - let bidResponse1 = utils.deepClone(MOCK.BID_RESPONSE[0]); - delete bidResponse1.width; - delete bidResponse1.height; - bidResponse1.playerWidth = 640; - bidResponse1.playerHeight = 480; - - // mock bid response with no width height or playerwidth playerheight - let bidResponse2 = utils.deepClone(MOCK.BID_RESPONSE[1]); - delete bidResponse2.width; - delete bidResponse2.height; - delete bidResponse2.playerWidth; - delete bidResponse2.playerHeight; - - events.emit(BID_RESPONSE, bidResponse1); - events.emit(BID_RESPONSE, bidResponse2); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON[0]); - events.emit(BID_WON, MOCK.BID_WON[1]); - - let message = JSON.parse(server.requests[0].requestBody); - validate(message); - expect(message.auctions[0].adUnits[0].bids[0].bidResponse.dimensions).to.deep.equal({ - width: 640, - height: 480 - }); - expect(message.auctions[0].adUnits[1].bids[0].bidResponse.dimensions).to.equal(undefined); - }); - - it('should pass along adomians correctly', function () { - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - - // 1 adomains - let bidResponse1 = utils.deepClone(MOCK.BID_RESPONSE[0]); - bidResponse1.meta = { - advertiserDomains: ['magnite.com'] - } - - // two adomains - let bidResponse2 = utils.deepClone(MOCK.BID_RESPONSE[1]); - bidResponse2.meta = { - advertiserDomains: ['prebid.org', 'magnite.com'] - } - - // make sure we only pass max 10 adomains - bidResponse2.meta.advertiserDomains = [...bidResponse2.meta.advertiserDomains, ...bidResponse2.meta.advertiserDomains, ...bidResponse2.meta.advertiserDomains, ...bidResponse2.meta.advertiserDomains, ...bidResponse2.meta.advertiserDomains, ...bidResponse2.meta.advertiserDomains, ...bidResponse2.meta.advertiserDomains] - - events.emit(BID_RESPONSE, bidResponse1); - events.emit(BID_RESPONSE, bidResponse2); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON[0]); - events.emit(BID_WON, MOCK.BID_WON[1]); - - let message = JSON.parse(server.requests[0].requestBody); - validate(message); - expect(message.auctions[0].adUnits[0].bids[0].bidResponse.adomains).to.deep.equal(['magnite.com']); - expect(message.auctions[0].adUnits[1].bids[0].bidResponse.adomains).to.deep.equal(['prebid.org', 'magnite.com', 'prebid.org', 'magnite.com', 'prebid.org', 'magnite.com', 'prebid.org', 'magnite.com', 'prebid.org', 'magnite.com']); - }); - - it('should NOT pass along adomians correctly when edge cases', function () { - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - - // empty => nothing - let bidResponse1 = utils.deepClone(MOCK.BID_RESPONSE[0]); - bidResponse1.meta = { - advertiserDomains: [] - } - - // not array => nothing - let bidResponse2 = utils.deepClone(MOCK.BID_RESPONSE[1]); - bidResponse2.meta = { - advertiserDomains: 'prebid.org' - } - - events.emit(BID_RESPONSE, bidResponse1); - events.emit(BID_RESPONSE, bidResponse2); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON[0]); - events.emit(BID_WON, MOCK.BID_WON[1]); - - let message = JSON.parse(server.requests[0].requestBody); - validate(message); - expect(message.auctions[0].adUnits[0].bids[0].bidResponse.adomains).to.be.undefined; - expect(message.auctions[0].adUnits[1].bids[0].bidResponse.adomains).to.be.undefined; - }); - - function performFloorAuction(provider) { - let auctionInit = utils.deepClone(MOCK.AUCTION_INIT); - auctionInit.bidderRequests[0].bids[0].floorData = { - skipped: false, - modelVersion: 'someModelName', - modelWeight: 10, - modelTimestamp: 1606772895, - location: 'setConfig', - skipRate: 15, - fetchStatus: 'error', - floorProvider: provider - }; - let flooredResponse = { - ...BID, - floorData: { - floorValue: 4, - floorRule: '12345/sports|video', - floorCurrency: 'USD', - cpmAfterAdjustments: 2.1, - enforcements: { - enforceJS: true, - enforcePBS: false, - floorDeals: false, - bidAdjustment: true - }, - matchedFields: { - gptSlot: '12345/sports', - mediaType: 'video' - } - }, - status: 'bidRejected', - cpm: 0, - getStatusCode() { - return 2; - } - }; - - let notFlooredResponse = { - ...BID2, - floorData: { - floorValue: 1, - floorRule: '12345/news|banner', - floorCurrency: 'USD', - cpmAfterAdjustments: 1.55, - enforcements: { - enforceJS: true, - enforcePBS: false, - floorDeals: false, - bidAdjustment: true - }, - matchedFields: { - gptSlot: '12345/news', - mediaType: 'banner' - } - } - }; - - let floorMinResponse = { - ...BID3, - floorData: { - floorValue: 1.5, - floorRuleValue: 1, - floorRule: '12345/entertainment|banner', - floorCurrency: 'USD', - cpmAfterAdjustments: 2.00, - enforcements: { - enforceJS: true, - enforcePBS: false, - floorDeals: false, - bidAdjustment: true - }, - matchedFields: { - gptSlot: '12345/entertainment', - mediaType: 'banner' - } - } - }; - - let bidRequest = utils.deepClone(MOCK.BID_REQUESTED); - bidRequest.bids.push(floorMinRequest) - - // spoof the auction with just our duplicates - events.emit(AUCTION_INIT, auctionInit); - events.emit(BID_REQUESTED, bidRequest); - events.emit(BID_RESPONSE, flooredResponse); - events.emit(BID_RESPONSE, notFlooredResponse); - events.emit(BID_RESPONSE, floorMinResponse); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON[1]); - events.emit(BID_WON, MOCK.BID_WON[2]); - clock.tick(SEND_TIMEOUT + 1000); - - expect(server.requests.length).to.equal(1); - - let message = JSON.parse(server.requests[0].requestBody); - validate(message); - return message; - } - - it('should capture price floor information correctly', function () { - let message = performFloorAuction('rubicon'); - - // verify our floor stuff is passed - // top level floor info - expect(message.auctions[0].floors).to.deep.equal({ - location: 'setConfig', - modelName: 'someModelName', - modelWeight: 10, - modelTimestamp: 1606772895, - skipped: false, - enforcement: true, - dealsEnforced: false, - skipRate: 15, - fetchStatus: 'error', - provider: 'rubicon' - }); - // first adUnit's adSlot - expect(message.auctions[0].adUnits[0].gam.adSlot).to.equal('12345/sports'); - // since no other bids, we set adUnit status to no-bid - expect(message.auctions[0].adUnits[0].status).to.equal('no-bid'); - // first adUnits bid is rejected - expect(message.auctions[0].adUnits[0].bids[0].status).to.equal('rejected-ipf'); - expect(message.auctions[0].adUnits[0].bids[0].bidResponse.floorValue).to.equal(4); - // if bid rejected should take cpmAfterAdjustments val - expect(message.auctions[0].adUnits[0].bids[0].bidResponse.bidPriceUSD).to.equal(2.1); - - // second adUnit's adSlot - expect(message.auctions[0].adUnits[1].gam.adSlot).to.equal('12345/news'); - // top level adUnit status is success - expect(message.auctions[0].adUnits[1].status).to.equal('success'); - // second adUnits bid is success - expect(message.auctions[0].adUnits[1].bids[0].status).to.equal('success'); - expect(message.auctions[0].adUnits[1].bids[0].bidResponse.floorValue).to.equal(1); - expect(message.auctions[0].adUnits[1].bids[0].bidResponse.bidPriceUSD).to.equal(1.52); - - // second adUnit's adSlot - expect(message.auctions[0].adUnits[2].gam.adSlot).to.equal('12345/entertainment'); - // top level adUnit status is success - expect(message.auctions[0].adUnits[2].status).to.equal('success'); - // second adUnits bid is success - expect(message.auctions[0].adUnits[2].bids[0].status).to.equal('success'); - expect(message.auctions[0].adUnits[2].bids[0].bidResponse.floorValue).to.equal(1.5); - expect(message.auctions[0].adUnits[2].bids[0].bidResponse.floorRuleValue).to.equal(1); - expect(message.auctions[0].adUnits[2].bids[0].bidResponse.bidPriceUSD).to.equal(2.01); - }); - - it('should still send floor info if provider is not rubicon', function () { - let message = performFloorAuction('randomProvider'); - - // verify our floor stuff is passed - // top level floor info - expect(message.auctions[0].floors).to.deep.equal({ - location: 'setConfig', - modelName: 'someModelName', - modelWeight: 10, - modelTimestamp: 1606772895, - skipped: false, - enforcement: true, - dealsEnforced: false, - skipRate: 15, - fetchStatus: 'error', - provider: 'randomProvider' - }); - // first adUnit's adSlot - expect(message.auctions[0].adUnits[0].gam.adSlot).to.equal('12345/sports'); - // since no other bids, we set adUnit status to no-bid - expect(message.auctions[0].adUnits[0].status).to.equal('no-bid'); - // first adUnits bid is rejected - expect(message.auctions[0].adUnits[0].bids[0].status).to.equal('rejected-ipf'); - expect(message.auctions[0].adUnits[0].bids[0].bidResponse.floorValue).to.equal(4); - // if bid rejected should take cpmAfterAdjustments val - expect(message.auctions[0].adUnits[0].bids[0].bidResponse.bidPriceUSD).to.equal(2.1); - - // second adUnit's adSlot - expect(message.auctions[0].adUnits[1].gam.adSlot).to.equal('12345/news'); - // top level adUnit status is success - expect(message.auctions[0].adUnits[1].status).to.equal('success'); - // second adUnits bid is success - expect(message.auctions[0].adUnits[1].bids[0].status).to.equal('success'); - expect(message.auctions[0].adUnits[1].bids[0].bidResponse.floorValue).to.equal(1); - expect(message.auctions[0].adUnits[1].bids[0].bidResponse.bidPriceUSD).to.equal(1.52); - - // second adUnit's adSlot - expect(message.auctions[0].adUnits[2].gam.adSlot).to.equal('12345/entertainment'); - // top level adUnit status is success - expect(message.auctions[0].adUnits[2].status).to.equal('success'); - // second adUnits bid is success - expect(message.auctions[0].adUnits[2].bids[0].status).to.equal('success'); - expect(message.auctions[0].adUnits[2].bids[0].bidResponse.floorValue).to.equal(1.5); - expect(message.auctions[0].adUnits[2].bids[0].bidResponse.floorRuleValue).to.equal(1); - expect(message.auctions[0].adUnits[2].bids[0].bidResponse.bidPriceUSD).to.equal(2.01); - }); - - describe('with session handling', function () { - const expectedPvid = STUBBED_UUID.slice(0, 8); - beforeEach(function () { - config.setConfig({rubicon: {updatePageView: true}}); - }); - - it('should not log any session data if local storage is not enabled', function () { - localStorageIsEnabledStub.returns(false); - - let expectedMessage = utils.deepClone(ANALYTICS_MESSAGE); - delete expectedMessage.session; - delete expectedMessage.fpkvs; - - performStandardAuction(); - - expect(server.requests.length).to.equal(1); - let request = server.requests[0]; - - expect(request.url).to.equal('//localhost:9999/event'); - - let message = JSON.parse(request.requestBody); - validate(message); - - expect(message).to.deep.equal(expectedMessage); - }); - - it('should should pass along custom rubicon kv and pvid when defined', function () { - config.setConfig({rubicon: { - fpkvs: { - source: 'fb', - link: 'email' - } - }}); - performStandardAuction(); - expect(server.requests.length).to.equal(1); - let request = server.requests[0]; - let message = JSON.parse(request.requestBody); - validate(message); - - let expectedMessage = utils.deepClone(ANALYTICS_MESSAGE); - expectedMessage.session.pvid = STUBBED_UUID.slice(0, 8); - expectedMessage.fpkvs = [ - {key: 'source', value: 'fb'}, - {key: 'link', value: 'email'} - ] - expect(message).to.deep.equal(expectedMessage); - }); - - it('should convert kvs to strings before sending', function () { - config.setConfig({rubicon: { - fpkvs: { - number: 24, - boolean: false, - string: 'hello', - array: ['one', 2, 'three'], - object: {one: 'two'} - } - }}); - performStandardAuction(); - expect(server.requests.length).to.equal(1); - let request = server.requests[0]; - let message = JSON.parse(request.requestBody); - validate(message); - - let expectedMessage = utils.deepClone(ANALYTICS_MESSAGE); - expectedMessage.session.pvid = STUBBED_UUID.slice(0, 8); - expectedMessage.fpkvs = [ - {key: 'number', value: '24'}, - {key: 'boolean', value: 'false'}, - {key: 'string', value: 'hello'}, - {key: 'array', value: 'one,2,three'}, - {key: 'object', value: '[object Object]'} - ] - expect(message).to.deep.equal(expectedMessage); - }); - - it('should use the query utm param rubicon kv value and pass updated kv and pvid when defined', function () { - sandbox.stub(utils, 'getWindowLocation').returns({'search': '?utm_source=other', 'pbjs_debug': 'true'}); - - config.setConfig({rubicon: { - fpkvs: { - source: 'fb', - link: 'email' - } - }}); - performStandardAuction(); - expect(server.requests.length).to.equal(1); - let request = server.requests[0]; - let message = JSON.parse(request.requestBody); - validate(message); - - let expectedMessage = utils.deepClone(ANALYTICS_MESSAGE); - expectedMessage.session.pvid = STUBBED_UUID.slice(0, 8); - expectedMessage.fpkvs = [ - {key: 'source', value: 'other'}, - {key: 'link', value: 'email'} - ] - - message.fpkvs.sort((left, right) => left.key < right.key); - expectedMessage.fpkvs.sort((left, right) => left.key < right.key); - - expect(message).to.deep.equal(expectedMessage); - }); - - it('should pick up existing localStorage and use its values', function () { - // set some localStorage - let inputlocalStorage = { - id: '987654', - start: 1519766113781, // 15 mins before "now" - expires: 1519787713781, // six hours later - lastSeen: 1519766113781, - fpkvs: { source: 'tw' } - }; - getDataFromLocalStorageStub.withArgs('rpaSession').returns(btoa(JSON.stringify(inputlocalStorage))); - - config.setConfig({rubicon: { - fpkvs: { - link: 'email' // should merge this with what is in the localStorage! - } - }}); - performStandardAuction(); - expect(server.requests.length).to.equal(1); - let request = server.requests[0]; - let message = JSON.parse(request.requestBody); - validate(message); - - let expectedMessage = utils.deepClone(ANALYTICS_MESSAGE); - expectedMessage.session = { - id: '987654', - start: 1519766113781, - expires: 1519787713781, - pvid: expectedPvid - } - expectedMessage.fpkvs = [ - {key: 'source', value: 'tw'}, - {key: 'link', value: 'email'} - ] - expect(message).to.deep.equal(expectedMessage); - - let calledWith; - try { - calledWith = JSON.parse(atob(setDataInLocalStorageStub.getCall(0).args[1])); - } catch (e) { - calledWith = {}; - } - - expect(calledWith).to.deep.equal({ - id: '987654', // should have stayed same - start: 1519766113781, // should have stayed same - expires: 1519787713781, // should have stayed same - lastSeen: 1519767013781, // lastSeen updated to our "now" - fpkvs: { source: 'tw', link: 'email' }, // link merged in - pvid: expectedPvid // new pvid stored - }); - }); - - it('should overwrite matching localstorge value and use its remaining values', function () { - sandbox.stub(utils, 'getWindowLocation').returns({'search': '?utm_source=fb&utm_click=dog'}); - - // set some localStorage - let inputlocalStorage = { - id: '987654', - start: 1519766113781, // 15 mins before "now" - expires: 1519787713781, // six hours later - lastSeen: 1519766113781, - fpkvs: { source: 'tw', link: 'email' } - }; - getDataFromLocalStorageStub.withArgs('rpaSession').returns(btoa(JSON.stringify(inputlocalStorage))); - - config.setConfig({rubicon: { - fpkvs: { - link: 'email' // should merge this with what is in the localStorage! - } - }}); - performStandardAuction(); - expect(server.requests.length).to.equal(1); - let request = server.requests[0]; - let message = JSON.parse(request.requestBody); - validate(message); - - let expectedMessage = utils.deepClone(ANALYTICS_MESSAGE); - expectedMessage.session = { - id: '987654', - start: 1519766113781, - expires: 1519787713781, - pvid: expectedPvid - } - expectedMessage.fpkvs = [ - {key: 'source', value: 'fb'}, - {key: 'link', value: 'email'}, - {key: 'click', value: 'dog'} - ] - - message.fpkvs.sort((left, right) => left.key < right.key); - expectedMessage.fpkvs.sort((left, right) => left.key < right.key); - - expect(message).to.deep.equal(expectedMessage); - - let calledWith; - try { - calledWith = JSON.parse(atob(setDataInLocalStorageStub.getCall(0).args[1])); - } catch (e) { - calledWith = {}; - } - - expect(calledWith).to.deep.equal({ - id: '987654', // should have stayed same - start: 1519766113781, // should have stayed same - expires: 1519787713781, // should have stayed same - lastSeen: 1519767013781, // lastSeen updated to our "now" - fpkvs: { source: 'fb', link: 'email', click: 'dog' }, // link merged in - pvid: expectedPvid // new pvid stored - }); - }); - - it('should throw out session if lastSeen > 30 mins ago and create new one', function () { - // set some localStorage - let inputlocalStorage = { - id: '987654', - start: 1519764313781, // 45 mins before "now" - expires: 1519785913781, // six hours later - lastSeen: 1519764313781, // 45 mins before "now" - fpkvs: { source: 'tw' } - }; - getDataFromLocalStorageStub.withArgs('rpaSession').returns(btoa(JSON.stringify(inputlocalStorage))); - - config.setConfig({rubicon: { - fpkvs: { - link: 'email' // should merge this with what is in the localStorage! - } - }}); - - performStandardAuction(); - expect(server.requests.length).to.equal(1); - let request = server.requests[0]; - let message = JSON.parse(request.requestBody); - validate(message); - - let expectedMessage = utils.deepClone(ANALYTICS_MESSAGE); - // session should match what is already in ANALYTICS_MESSAGE, just need to add pvid - expectedMessage.session.pvid = expectedPvid; - - // the saved fpkvs should have been thrown out since session expired - expectedMessage.fpkvs = [ - {key: 'link', value: 'email'} - ] - expect(message).to.deep.equal(expectedMessage); - - let calledWith; - try { - calledWith = JSON.parse(atob(setDataInLocalStorageStub.getCall(0).args[1])); - } catch (e) { - calledWith = {}; - } - - expect(calledWith).to.deep.equal({ - id: STUBBED_UUID, // should have stayed same - start: 1519767013781, // should have stayed same - expires: 1519788613781, // should have stayed same - lastSeen: 1519767013781, // lastSeen updated to our "now" - fpkvs: { link: 'email' }, // link merged in - pvid: expectedPvid // new pvid stored - }); - }); - - it('should throw out session if past expires time and create new one', function () { - // set some localStorage - let inputlocalStorage = { - id: '987654', - start: 1519745353781, // 6 hours before "expires" - expires: 1519766953781, // little more than six hours ago - lastSeen: 1519767008781, // 5 seconds ago - fpkvs: { source: 'tw' } - }; - getDataFromLocalStorageStub.withArgs('rpaSession').returns(btoa(JSON.stringify(inputlocalStorage))); - - config.setConfig({rubicon: { - fpkvs: { - link: 'email' // should merge this with what is in the localStorage! - } - }}); - - performStandardAuction(); - expect(server.requests.length).to.equal(1); - let request = server.requests[0]; - let message = JSON.parse(request.requestBody); - validate(message); - - let expectedMessage = utils.deepClone(ANALYTICS_MESSAGE); - // session should match what is already in ANALYTICS_MESSAGE, just need to add pvid - expectedMessage.session.pvid = expectedPvid; - - // the saved fpkvs should have been thrown out since session expired - expectedMessage.fpkvs = [ - {key: 'link', value: 'email'} - ] - expect(message).to.deep.equal(expectedMessage); - - let calledWith; - try { - calledWith = JSON.parse(atob(setDataInLocalStorageStub.getCall(0).args[1])); - } catch (e) { - calledWith = {}; - } - - expect(calledWith).to.deep.equal({ - id: STUBBED_UUID, // should have stayed same - start: 1519767013781, // should have stayed same - expires: 1519788613781, // should have stayed same - lastSeen: 1519767013781, // lastSeen updated to our "now" - fpkvs: { link: 'email' }, // link merged in - pvid: expectedPvid // new pvid stored - }); - }); - }); - describe('with googletag enabled', function () { - let gptSlot0, gptSlot1; - let gptSlotRenderEnded0, gptSlotRenderEnded1; - beforeEach(function () { - mockGpt.enable(); - gptSlot0 = mockGpt.makeSlot({code: '/19968336/header-bid-tag-0'}); - gptSlotRenderEnded0 = { - eventName: 'slotRenderEnded', - params: { - slot: gptSlot0, - isEmpty: false, - advertiserId: 1111, - sourceAgnosticCreativeId: 2222, - sourceAgnosticLineItemId: 3333 - } - }; - - gptSlot1 = mockGpt.makeSlot({code: '/19968336/header-bid-tag1'}); - gptSlotRenderEnded1 = { - eventName: 'slotRenderEnded', - params: { - slot: gptSlot1, - isEmpty: false, - advertiserId: 4444, - sourceAgnosticCreativeId: 5555, - sourceAgnosticLineItemId: 6666 - } - }; - }); - - afterEach(function () { - mockGpt.disable(); - }); - - it('should add necessary gam information if gpt is enabled and slotRender event emmited', function () { - performStandardAuction([gptSlotRenderEnded0, gptSlotRenderEnded1]); - expect(server.requests.length).to.equal(1); - let request = server.requests[0]; - let message = JSON.parse(request.requestBody); - validate(message); - - let expectedMessage = utils.deepClone(ANALYTICS_MESSAGE); - expectedMessage.auctions[0].adUnits[0].gam = { - advertiserId: 1111, - creativeId: 2222, - lineItemId: 3333, - adSlot: '/19968336/header-bid-tag-0' - }; - expectedMessage.auctions[0].adUnits[1].gam = { - advertiserId: 4444, - creativeId: 5555, - lineItemId: 6666, - adSlot: '/19968336/header-bid-tag1' - }; - expect(message).to.deep.equal(expectedMessage); - }); - - it('should handle empty gam renders', function () { - performStandardAuction([gptSlotRenderEnded0, { - eventName: 'slotRenderEnded', - params: { - slot: gptSlot1, - isEmpty: true - } - }]); - expect(server.requests.length).to.equal(1); - let request = server.requests[0]; - let message = JSON.parse(request.requestBody); - validate(message); - - let expectedMessage = utils.deepClone(ANALYTICS_MESSAGE); - expectedMessage.auctions[0].adUnits[0].gam = { - advertiserId: 1111, - creativeId: 2222, - lineItemId: 3333, - adSlot: '/19968336/header-bid-tag-0' - }; - expectedMessage.auctions[0].adUnits[1].gam = { - isSlotEmpty: true, - adSlot: '/19968336/header-bid-tag1' - }; - expect(message).to.deep.equal(expectedMessage); - }); - - it('should still add gam ids if falsy', function () { - performStandardAuction([gptSlotRenderEnded0, { - eventName: 'slotRenderEnded', - params: { - slot: gptSlot1, - isEmpty: false, - advertiserId: 0, - sourceAgnosticCreativeId: 0, - sourceAgnosticLineItemId: 0 - } - }]); - expect(server.requests.length).to.equal(1); - let request = server.requests[0]; - let message = JSON.parse(request.requestBody); - validate(message); - - let expectedMessage = utils.deepClone(ANALYTICS_MESSAGE); - expectedMessage.auctions[0].adUnits[0].gam = { - advertiserId: 1111, - creativeId: 2222, - lineItemId: 3333, - adSlot: '/19968336/header-bid-tag-0' - }; - expectedMessage.auctions[0].adUnits[1].gam = { - advertiserId: 0, - creativeId: 0, - lineItemId: 0, - adSlot: '/19968336/header-bid-tag1' - }; - expect(message).to.deep.equal(expectedMessage); - }); - - it('should pick backup Ids if no sourceAgnostic available first', function () { - performStandardAuction([gptSlotRenderEnded0, { - eventName: 'slotRenderEnded', - params: { - slot: gptSlot1, - isEmpty: false, - advertiserId: 0, - lineItemId: 1234, - creativeId: 5678 - } - }]); - expect(server.requests.length).to.equal(1); - let request = server.requests[0]; - let message = JSON.parse(request.requestBody); - validate(message); - - let expectedMessage = utils.deepClone(ANALYTICS_MESSAGE); - expectedMessage.auctions[0].adUnits[0].gam = { - advertiserId: 1111, - creativeId: 2222, - lineItemId: 3333, - adSlot: '/19968336/header-bid-tag-0' - }; - expectedMessage.auctions[0].adUnits[1].gam = { - advertiserId: 0, - creativeId: 5678, - lineItemId: 1234, - adSlot: '/19968336/header-bid-tag1' - }; - expect(message).to.deep.equal(expectedMessage); - }); - - it('should correctly set adUnit for associated slots', function () { - performStandardAuction([gptSlotRenderEnded0, gptSlotRenderEnded1]); - expect(server.requests.length).to.equal(1); - let request = server.requests[0]; - let message = JSON.parse(request.requestBody); - validate(message); - - let expectedMessage = utils.deepClone(ANALYTICS_MESSAGE); - expectedMessage.auctions[0].adUnits[0].gam = { - advertiserId: 1111, - creativeId: 2222, - lineItemId: 3333, - adSlot: '/19968336/header-bid-tag-0' - }; - expectedMessage.auctions[0].adUnits[1].gam = { - advertiserId: 4444, - creativeId: 5555, - lineItemId: 6666, - adSlot: '/19968336/header-bid-tag1' - }; - expect(message).to.deep.equal(expectedMessage); - }); - - it('should send request when waitForGamSlots is present but no bidWons are sent', function () { - config.setConfig({ - rubicon: { - waitForGamSlots: true, - } - }); - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[1]); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - - // should send if just slotRenderEnded is emmitted for both - mockGpt.emitEvent(gptSlotRenderEnded0.eventName, gptSlotRenderEnded0.params); - mockGpt.emitEvent(gptSlotRenderEnded1.eventName, gptSlotRenderEnded1.params); - - expect(server.requests.length).to.equal(1); - let request = server.requests[0]; - let message = JSON.parse(request.requestBody); - validate(message); - - let expectedMessage = utils.deepClone(ANALYTICS_MESSAGE); - delete expectedMessage.bidsWon; // should not be any of these - expectedMessage.auctions[0].adUnits[0].gam = { - advertiserId: 1111, - creativeId: 2222, - lineItemId: 3333, - adSlot: '/19968336/header-bid-tag-0' - }; - expectedMessage.auctions[0].adUnits[1].gam = { - advertiserId: 4444, - creativeId: 5555, - lineItemId: 6666, - adSlot: '/19968336/header-bid-tag1' - }; - expect(message).to.deep.equal(expectedMessage); - }); - - it('should delay the event call depending on analyticsEventDelay config', function () { - config.setConfig({ - rubicon: { - waitForGamSlots: true, - analyticsEventDelay: 2000 - } - }); - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[1]); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - - // should send if just slotRenderEnded is emmitted for both - mockGpt.emitEvent(gptSlotRenderEnded0.eventName, gptSlotRenderEnded0.params); - mockGpt.emitEvent(gptSlotRenderEnded1.eventName, gptSlotRenderEnded1.params); - - // Should not be sent until delay - expect(server.requests.length).to.equal(0); - - // tick the clock and it should fire - clock.tick(2000); - - expect(server.requests.length).to.equal(1); - let request = server.requests[0]; - let message = JSON.parse(request.requestBody); - validate(message); - let expectedGam0 = { - advertiserId: 1111, - creativeId: 2222, - lineItemId: 3333, - adSlot: '/19968336/header-bid-tag-0' - }; - let expectedGam1 = { - advertiserId: 4444, - creativeId: 5555, - lineItemId: 6666, - adSlot: '/19968336/header-bid-tag1' - }; - expect(expectedGam0).to.deep.equal(message.auctions[0].adUnits[0].gam); - expect(expectedGam1).to.deep.equal(message.auctions[0].adUnits[1].gam); - }); - }); - - it('should correctly overwrite bidId if seatBidId is on the bidResponse', function () { - // Only want one bid request in our mock auction - let bidRequested = utils.deepClone(MOCK.BID_REQUESTED); - bidRequested.bids.shift(); - let auctionInit = utils.deepClone(MOCK.AUCTION_INIT); - auctionInit.adUnits.shift(); - - // clone the mock bidResponse and duplicate - let seatBidResponse = utils.deepClone(BID2); - seatBidResponse.seatBidId = 'abc-123-do-re-me'; - - const setTargeting = { - [seatBidResponse.adUnitCode]: seatBidResponse.adserverTargeting - }; - - const bidWon = Object.assign({}, seatBidResponse, { - 'status': 'rendered' - }); - - // spoof the auction with just our duplicates - events.emit(AUCTION_INIT, auctionInit); - events.emit(BID_REQUESTED, bidRequested); - events.emit(BID_RESPONSE, seatBidResponse); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, setTargeting); - events.emit(BID_WON, bidWon); - - let message = JSON.parse(server.requests[0].requestBody); - - validate(message); - expect(message.auctions[0].adUnits[0].bids[0].bidId).to.equal('abc-123-do-re-me'); - expect(message.bidsWon[0].bidId).to.equal('abc-123-do-re-me'); - }); - - it('should correctly overwrite bidId if pbsBidId is on the bidResponse', function () { - // Only want one bid request in our mock auction - let bidRequested = utils.deepClone(MOCK.BID_REQUESTED); - bidRequested.bids.shift(); - let auctionInit = utils.deepClone(MOCK.AUCTION_INIT); - auctionInit.adUnits.shift(); - - // clone the mock bidResponse and duplicate - let seatBidResponse = utils.deepClone(BID4); - - const setTargeting = { - [seatBidResponse.adUnitCode]: seatBidResponse.adserverTargeting - }; - - const bidWon = Object.assign({}, seatBidResponse, { - 'status': 'rendered' - }); - - // spoof the auction with just our duplicates - events.emit(AUCTION_INIT, auctionInit); - events.emit(BID_REQUESTED, bidRequested); - events.emit(BID_RESPONSE, seatBidResponse); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, setTargeting); - events.emit(BID_WON, bidWon); - - let message = JSON.parse(server.requests[0].requestBody); - - validate(message); - expect(message.auctions[0].adUnits[0].bids[0].bidId).to.equal('zzzz-yyyy-xxxx-wwww'); - expect(message.bidsWon[0].bidId).to.equal('zzzz-yyyy-xxxx-wwww'); - }); - - it('should correctly generate new bidId if it is 0', function () { - // Only want one bid request in our mock auction - let bidRequested = utils.deepClone(MOCK.BID_REQUESTED); - bidRequested.bids.shift(); - let auctionInit = utils.deepClone(MOCK.AUCTION_INIT); - auctionInit.adUnits.shift(); - - // clone the mock bidResponse and duplicate - let seatBidResponse = utils.deepClone(BID4); - seatBidResponse.pbsBidId = '0'; - - const setTargeting = { - [seatBidResponse.adUnitCode]: seatBidResponse.adserverTargeting - }; - - const bidWon = Object.assign({}, seatBidResponse, { - 'status': 'rendered' - }); - - // spoof the auction with just our duplicates - events.emit(AUCTION_INIT, auctionInit); - events.emit(BID_REQUESTED, bidRequested); - events.emit(BID_RESPONSE, seatBidResponse); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, setTargeting); - events.emit(BID_WON, bidWon); - - let message = JSON.parse(server.requests[0].requestBody); - - validate(message); - expect(message.auctions[0].adUnits[0].bids[0].bidId).to.equal(STUBBED_UUID); - expect(message.bidsWon[0].bidId).to.equal(STUBBED_UUID); - }); - - it('should pick the highest cpm bid if more than one bid per bidRequestId', function () { - // Only want one bid request in our mock auction - let bidRequested = utils.deepClone(MOCK.BID_REQUESTED); - bidRequested.bids.shift(); - let auctionInit = utils.deepClone(MOCK.AUCTION_INIT); - auctionInit.adUnits.shift(); - - // clone the mock bidResponse and duplicate - let duplicateResponse1 = utils.deepClone(BID2); - duplicateResponse1.cpm = 1.0; - duplicateResponse1.adserverTargeting.hb_pb = '1.0'; - duplicateResponse1.adserverTargeting.hb_adid = '1111'; - let duplicateResponse2 = utils.deepClone(BID2); - duplicateResponse2.cpm = 5.5; - duplicateResponse2.adserverTargeting.hb_pb = '5.5'; - duplicateResponse2.adserverTargeting.hb_adid = '5555'; - let duplicateResponse3 = utils.deepClone(BID2); - duplicateResponse3.cpm = 0.1; - duplicateResponse3.adserverTargeting.hb_pb = '0.1'; - duplicateResponse3.adserverTargeting.hb_adid = '3333'; - - const setTargeting = { - [duplicateResponse2.adUnitCode]: duplicateResponse2.adserverTargeting - }; - - const bidWon = Object.assign({}, duplicateResponse2, { - 'status': 'rendered' - }); - - // spoof the auction with just our duplicates - events.emit(AUCTION_INIT, auctionInit); - events.emit(BID_REQUESTED, bidRequested); - events.emit(BID_RESPONSE, duplicateResponse1); - events.emit(BID_RESPONSE, duplicateResponse2); - events.emit(BID_RESPONSE, duplicateResponse3); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, setTargeting); - events.emit(BID_WON, bidWon); - - let message = JSON.parse(server.requests[0].requestBody); - validate(message); - expect(message.auctions[0].adUnits[0].bids[0].bidResponse.bidPriceUSD).to.equal(5.5); - expect(message.auctions[0].adUnits[0].adserverTargeting.hb_pb).to.equal('5.5'); - expect(message.auctions[0].adUnits[0].adserverTargeting.hb_adid).to.equal('5555'); - expect(message.bidsWon.length).to.equal(1); - expect(message.bidsWon[0].bidResponse.bidPriceUSD).to.equal(5.5); - expect(message.bidsWon[0].adserverTargeting.hb_pb).to.equal('5.5'); - expect(message.bidsWon[0].adserverTargeting.hb_adid).to.equal('5555'); - }); - - it('should send batched message without BID_WON if necessary and further BID_WON events individually', function () { - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[1]); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON[0]); - - clock.tick(SEND_TIMEOUT + 1000); - - events.emit(BID_WON, MOCK.BID_WON[1]); - - expect(server.requests.length).to.equal(2); - - let message = JSON.parse(server.requests[0].requestBody); - validate(message); - expect(message.bidsWon.length).to.equal(1); - expect(message.auctions).to.deep.equal(ANALYTICS_MESSAGE.auctions); - expect(message.bidsWon[0]).to.deep.equal(ANALYTICS_MESSAGE.bidsWon[0]); - - message = JSON.parse(server.requests[1].requestBody); - validate(message); - expect(message.bidsWon.length).to.equal(1); - expect(message).to.not.have.property('auctions'); - expect(message.bidsWon[0]).to.deep.equal(ANALYTICS_MESSAGE.bidsWon[1]); - }); - - it('should properly mark bids as timed out', function () { - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(BID_TIMEOUT, MOCK.BID_TIMEOUT); - events.emit(AUCTION_END, MOCK.AUCTION_END); - - clock.tick(SEND_TIMEOUT + 1000); - - expect(server.requests.length).to.equal(1); - - let message = JSON.parse(server.requests[0].requestBody); - validate(message); - let timedOutBid = message.auctions[0].adUnits[0].bids[0]; - expect(timedOutBid.status).to.equal('error'); - expect(timedOutBid.error.code).to.equal('timeout-error'); - expect(timedOutBid).to.not.have.property('bidResponse'); - }); - - it('should pass aupName as pattern', function () { - let bidRequest = utils.deepClone(MOCK.BID_REQUESTED); - bidRequest.bids[0].ortb2Imp = { - ext: { - data: { - aupname: '1234/mycoolsite/*&gpt_leaderboard&deviceType=mobile' - } - } - }; - bidRequest.bids[1].ortb2Imp = { - ext: { - data: { - aupname: '1234/mycoolsite/*&gpt_skyscraper&deviceType=mobile' - } - } - }; - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, bidRequest); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - - clock.tick(SEND_TIMEOUT + 1000); - - expect(server.requests.length).to.equal(1); - - let message = JSON.parse(server.requests[0].requestBody); - validate(message); - expect(message.auctions[0].adUnits[0].pattern).to.equal('1234/mycoolsite/*&gpt_leaderboard&deviceType=mobile'); - expect(message.auctions[0].adUnits[1].pattern).to.equal('1234/mycoolsite/*&gpt_skyscraper&deviceType=mobile'); - }); - - it('should pass bidderDetail for multibid auctions', function () { - let bidResponse = utils.deepClone(MOCK.BID_RESPONSE[1]); - bidResponse.targetingBidder = 'rubi2'; - bidResponse.originalRequestId = bidResponse.requestId; - bidResponse.requestId = '1a2b3c4d5e6f7g8h9'; - - events.emit(AUCTION_INIT, MOCK.AUCTION_INIT); - events.emit(BID_REQUESTED, MOCK.BID_REQUESTED); - events.emit(BID_RESPONSE, MOCK.BID_RESPONSE[0]); - events.emit(BID_RESPONSE, bidResponse); - events.emit(BIDDER_DONE, MOCK.BIDDER_DONE); - events.emit(AUCTION_END, MOCK.AUCTION_END); - events.emit(SET_TARGETING, MOCK.SET_TARGETING); - events.emit(BID_WON, MOCK.BID_WON[0]); - - clock.tick(SEND_TIMEOUT + 1000); - - expect(server.requests.length).to.equal(1); - - let message = JSON.parse(server.requests[0].requestBody); - validate(message); - - expect(message.auctions[0].adUnits[1].bids[1].bidder).to.equal('rubicon'); - expect(message.auctions[0].adUnits[1].bids[1].bidderDetail).to.equal('rubi2'); - }); - - it('should successfully convert bid price to USD in parseBidResponse', function () { - // Set the rates - setConfig({ - adServerCurrency: 'JPY', - rates: { - USD: { - JPY: 100 - } - } - }); - - // set our bid response to JPY - const bidCopy = utils.deepClone(BID2); - bidCopy.currency = 'JPY'; - bidCopy.cpm = 100; - - // Now add the bidResponse hook which hooks on the currenct conversion function onto the bid response - let innerBid; - addBidResponseHook(function(adCodeId, bid) { - innerBid = bid; - }, 'elementId', bidCopy); - - // Use the rubi analytics parseBidResponse Function to get the resulting cpm from the bid response! - const bidResponseObj = parseBidResponse(innerBid); - expect(bidResponseObj).to.have.property('bidPriceUSD'); - expect(bidResponseObj.bidPriceUSD).to.equal(1.0); - }); - }); - - 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' - }}) - - rubiconAnalyticsAdapter.enableAnalytics({ - options: { - endpoint: '//localhost:9999/event', - accountId: 1001 - } - }); - - performStandardAuction(); - - expect(server.requests.length).to.equal(1); - const request = server.requests[0]; - const message = JSON.parse(request.requestBody); - expect(message.integration).to.equal('testType'); - - rubiconAnalyticsAdapter.disableAnalytics(); - }); - }); - - describe('wrapper details passed in', () => { - it('should correctly pass in the wrapper details if provided', () => { - config.setConfig({rubicon: { - wrapperName: '1001_wrapperName_exp.4', - wrapperFamily: '1001_wrapperName', - rule_name: 'na-mobile' - }}); - - rubiconAnalyticsAdapter.enableAnalytics({ - options: { - endpoint: '//localhost:9999/event', - accountId: 1001 - } - }); - - performStandardAuction(); - - expect(server.requests.length).to.equal(1); - const request = server.requests[0]; - const message = JSON.parse(request.requestBody); - expect(message.wrapper).to.deep.equal({ - name: '1001_wrapperName_exp.4', - family: '1001_wrapperName', - rule: 'na-mobile' - }); - - rubiconAnalyticsAdapter.disableAnalytics(); - }); - }); - - it('getHostNameFromReferer correctly grabs hostname from an input URL', function () { - let inputUrl = 'https://www.prebid.org/some/path?pbjs_debug=true'; - expect(getHostNameFromReferer(inputUrl)).to.equal('www.prebid.org'); - inputUrl = 'https://www.prebid.com/some/path?pbjs_debug=true'; - expect(getHostNameFromReferer(inputUrl)).to.equal('www.prebid.com'); - inputUrl = 'https://prebid.org/some/path?pbjs_debug=true'; - expect(getHostNameFromReferer(inputUrl)).to.equal('prebid.org'); - inputUrl = 'http://xn--p8j9a0d9c9a.xn--q9jyb4c/'; - expect(typeof getHostNameFromReferer(inputUrl)).to.equal('string'); - - // not non-UTF char's in query / path which break if noDecodeWholeURL not set - inputUrl = 'https://prebid.org/search_results/%95x%8Em%92%CA/?category=000'; - expect(getHostNameFromReferer(inputUrl)).to.equal('prebid.org'); - }); -}); diff --git a/test/spec/modules/rubiconAnalyticsSchema.json b/test/spec/modules/rubiconAnalyticsSchema.json deleted file mode 100644 index 13d39e46cd0..00000000000 --- a/test/spec/modules/rubiconAnalyticsSchema.json +++ /dev/null @@ -1,456 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-06/schema#", - "title": "Prebid Auctions", - "description": "A batched data object describing the lifecycle of an auction or multiple auction across a single page view.", - "type": "object", - "required": [ - "eventTimeMillis", - "integration", - "version" - ], - "anyOf": [ - { - "required": [ - "auctions" - ] - }, - { - "required": [ - "bidsWon" - ] - } - ], - "properties": { - "eventTimeMillis": { - "type": "integer", - "description": "Unix timestamp of time of creation for this batched event in milliseconds." - }, - "integration": { - "type": "string", - "description": "Integration type that generated this event.", - "default": "pbjs" - }, - "version": { - "type": "string", - "description": "Version of Prebid.js responsible for the auctions contained within." - }, - "fpkvs": { - "type": "array", - "description": "List of any dynamic key value pairs set by publisher.", - "minItems": 1, - "items": { - "type": "object", - "required": [ - "key", - "value" - ], - "properties": { - "key": { - "type": "string" - }, - "value": { - "type": "string" - } - } - } - }, - "session": { - "type": "object", - "description": "The session information for a given event", - "required": [ - "id", - "start", - "expires" - ], - "properties": { - "id": { - "type": "string", - "description": "UUID of session." - }, - "start": { - "type": "integer", - "description": "Unix timestamp of time of creation for this session in milliseconds." - }, - "expires": { - "type": "integer", - "description": "Unix timestamp of the maximum allowed time in milliseconds of the session." - }, - "pvid": { - "type": "string", - "description": "id to track page view." - } - } - }, - "auctions": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "required": [ - "adUnits", - "samplingFactor" - ], - "properties": { - "clientTimeoutMillis": { - "type": "integer", - "description": "Timeout given in client for given auction in milliseconds (if applicable)." - }, - "serverTimeoutMillis": { - "type": "integer", - "description": "Timeout configured for server adapter request in milliseconds (if applicable)." - }, - "accountId": { - "type": "number", - "description": "The account id for prebid server (if applicable)." - }, - "samplingFactor": { - "$ref": "#/definitions/samplingFactor" - }, - "adUnits": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "description": "An array of adUnits involved in this auction.", - "required": [ - "status", - "adUnitCode", - "transactionId", - "mediaTypes", - "dimensions", - "bids" - ], - "properties": { - "status": { - "type": "string", - "description": "The status of the adUnit" - }, - "adUnitCode": { - "type": "string", - "description": "The adUnit.code identifier" - }, - "transactionId": { - "type": "string", - "description": "The UUID generated id to represent this adunit in this auction." - }, - "adSlot": { - "type": "string" - }, - "mediaTypes": { - "$ref": "#/definitions/mediaTypes" - }, - "videoAdFormat": { - "$ref": "#/definitions/videoAdFormat" - }, - "dimensions": { - "type": "array", - "description": "All valid sizes included in this auction (note: may be sizeConfig filtered).", - "minItems": 1, - "items": { - "$ref": "#/definitions/dimensions" - } - }, - "adserverTargeting": { - "$ref": "#/definitions/adserverTargeting" - }, - "bids": { - "type": "array", - "description": "An array that contains a combination of the bids from the adUnit combined with their responses.", - "minItems": 1, - "items": { - "$ref": "#/definitions/bid" - } - }, - "accountId": { - "type": "number", - "description": "The Rubicon AccountId associated with this adUnit - Removed if null" - }, - "siteId": { - "type": "number", - "description": "The Rubicon siteId associated with this adUnit - Removed if null" - }, - "zoneId": { - "type": "number", - "description": "The Rubicon zoneId associated with this adUnit - Removed if null" - }, - "gam": { - "$ref": "#/definitions/gam" - } - } - } - } - } - } - }, - "bidsWon": { - "type": "array", - "minItems": 1, - "items": { - "allOf": [ - { - "$ref": "#/definitions/bid" - }, - { - "required": [ - "transactionId", - "accountId", - "samplingFactor", - "mediaTypes", - "adUnitCode", - "bidwonStatus" - ], - "properties": { - "transactionId": { - "type": "string" - }, - "accountId": { - "type": "number" - }, - "samplingFactor": { - "$ref": "#/definitions/samplingFactor" - }, - "adUnitCode": { - "type": "string" - }, - "videoAdFormat": { - "$ref": "#/definitions/videoAdFormat" - }, - "mediaTypes": { - "$ref": "#/definitions/mediaTypes" - }, - "adserverTargeting": { - "$ref": "#/definitions/adserverTargeting" - }, - "bidwonStatus": { - "description": "Whether the bid was successfully rendered or not", - "type": "string", - "enum": [ - "success", - "error" - ] - }, - "siteId": { - "type": "number", - "description": "The Rubicon siteId associated with this adUnit - Removed if null" - }, - "zoneId": { - "type": "number", - "description": "The Rubicon zoneId associated with this adUnit - Removed if null" - } - } - } - ] - } - }, - "wrapperName": { - "type": "string" - } - }, - "definitions": { - "gam": { - "type": "object", - "description": "The gam information for a given ad unit", - "required": [ - "adSlot" - ], - "properties": { - "adSlot": { - "type": "string" - }, - "advertiserId": { - "type": "integer" - }, - "creativeId": { - "type": "integer" - }, - "LineItemId": { - "type": "integer" - }, - "isSlotEmpty": { - "type": "boolean", - "enum": [true] - } - } - }, - "adserverTargeting": { - "type": "object", - "description": "The adserverTargeting key/value pairs", - "patternProperties": { - ".+": { - "type": "string" - } - } - }, - "samplingFactor": { - "type": "integer", - "description": "An integer value representing the factor to multiply event count by to receive unsampled count.", - "enum": [ - 1, - 10, - 20, - 40, - 100 - ] - }, - "videoAdFormat": { - "type": "string", - "description": "This value only provided for video specifies the ad format", - "enum": [ - "pre-roll", - "interstitial", - "outstream", - "mid-roll", - "post-roll", - "vertical" - ] - }, - "mediaTypes": { - "type": "array", - "uniqueItems": true, - "minItems": 1, - "items": { - "type": "string", - "enum": [ - "native", - "video", - "banner" - ] - } - }, - "dimensions": { - "type": "object", - "description": "Size object representing the dimensions of creative in pixels.", - "required": [ - "width", - "height" - ], - "properties": { - "width": { - "type": "integer", - "minimum": 1 - }, - "height": { - "type": "integer", - "minimum": 1 - } - } - }, - "bid": { - "type": "object", - "required": [ - "bidder", - "bidId", - "status", - "source" - ], - "properties": { - "bidder": { - "type": "string" - }, - "bidId": { - "type": "string", - "description": "UUID representing this individual bid request in this auction." - }, - "params": { - "description": "A copy of the bid.params from the adUnit.bids", - "anyOf": [ - { - "type": "object" - }, - { - "$ref": "#/definitions/params/rubicon" - } - ] - }, - "status": { - "type": "string", - "enum": [ - "success", - "no-bid", - "error", - "rejected-gdpr", - "rejected-ipf" - ] - }, - "error": { - "type": "object", - "required": [ - "code" - ], - "properties": { - "code": { - "type": "string", - "enum": [ - "request-error", - "connect-error", - "timeout-error" - ] - }, - "description": { - "type": "string" - } - } - }, - "source": { - "type": "string", - "enum": [ - "client", - "server" - ] - }, - "clientLatencyMillis": { - "type": "integer", - "description": "Latency from auction start to bid response recieved in milliseconds." - }, - "serverLatencyMillis": { - "type": "integer", - "description": "Latency returned by prebid server (response_time_ms)." - }, - "bidResponse": { - "type": "object", - "required": [ - "mediaType", - "bidPriceUSD" - ], - "properties": { - "dimensions": { - "$ref": "#/definitions/dimensions" - }, - "mediaType": { - "type": "string", - "enum": [ - "native", - "video", - "banner" - ] - }, - "bidPriceUSD": { - "type": "number", - "description": "The bid value denoted in USD" - }, - "dealId": { - "type": "integer", - "description": "The id associated with any potential deals" - } - } - } - } - }, - "params": { - "rubicon": { - "type": "object", - "properties": { - "accountId": { - "type": "number" - }, - "siteId": { - "type": "number" - }, - "zoneId": { - "type": "number" - } - } - } - } - } -} diff --git a/test/spec/modules/rubiconBidAdapter_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js deleted file mode 100644 index 1964d0d6ecc..00000000000 --- a/test/spec/modules/rubiconBidAdapter_spec.js +++ /dev/null @@ -1,3503 +0,0 @@ -import {expect} from 'chai'; -import { - spec, - getPriceGranularity, - masSizeOrdering, - resetUserSync, - hasVideoMediaType, - resetRubiConf -} from 'modules/rubiconBidAdapter.js'; -import {parse as parseQuery} from 'querystring'; -import {config} from 'src/config.js'; -import * as utils from 'src/utils.js'; -import find from 'core-js-pure/features/array/find.js'; -import {createEidsArray} from 'modules/userId/eids.js'; - -const INTEGRATION = `pbjs_lite_v$prebid.version$`; // $prebid.version$ will be substituted in by gulp in built prebid -const PBS_INTEGRATION = 'pbjs'; - -describe('the rubicon adapter', function () { - let sandbox, - bidderRequest, - sizeMap, - getFloorResponse, - logErrorSpy; - - /** - * @typedef {Object} sizeMapConverted - * @property {string} sizeId - * @property {string} size - * @property {Array.} sizeAsArray - * @property {number} width - * @property {number} height - */ - - /** - * @param {Array.} sizesMapConverted - * @param {Object} bid - * @return {sizeMapConverted} - */ - function getSizeIdForBid(sizesMapConverted, bid) { - return find(sizesMapConverted, item => (item.width === bid.width && item.height === bid.height)); - } - - /** - * @param {Array.} ads - * @param {sizeMapConverted} size - * @return {Object} - */ - function getResponseAdBySize(ads, size) { - return find(ads, item => item.size_id === size.sizeId); - } - - /** - * @param {Array.} bidRequests - * @param {sizeMapConverted} size - * @return {BidRequest} - */ - function getBidRequestBySize(bidRequests, size) { - return find(bidRequests, item => item.sizes[0][0] === size.width && item.sizes[0][1] === size.height); - } - - /** - * @typedef {Object} overrideProps - * @property {string} status - * @property {number} cpm - * @property {number} zone_id - * @property {number} ad_id - * @property {string} creative_id - * @property {string} targeting_key - rpfl_{id} - */ - /** - * @param {number} i - index - * @param {string} sizeId - id that maps to size - * @param {Array.} [indexOverMap] - * @return {{status: string, cpm: number, zone_id: *, size_id: *, impression_id: *, ad_id: *, creative_id: string, type: string, targeting: *[]}} - */ - - function getBidderRequest() { - return { - bidderCode: 'rubicon', - auctionId: 'c45dd708-a418-42ec-b8a7-b70a6c6fab0a', - bidderRequestId: '178e34bad3658f', - bids: [ - { - bidder: 'rubicon', - params: { - accountId: '14062', - siteId: '70608', - zoneId: '335918', - userId: '12346', - keywords: ['a', 'b', 'c'], - inventory: { - rating: '5-star', // This actually should not be sent to frank!! causes 400 - prodtype: ['tech', 'mobile'] - }, - visitor: { - ucat: 'new', - lastsearch: 'iphone', - likes: ['sports', 'video games'] - }, - position: 'atf', - referrer: 'localhost', - latLong: [40.7607823, '111.8910325'] - }, - adUnitCode: '/19968336/header-bid-tag-0', - code: 'div-1', - sizes: [[300, 250], [320, 50]], - bidId: '2ffb201a808da7', - bidderRequestId: '178e34bad3658f', - auctionId: 'c45dd708-a418-42ec-b8a7-b70a6c6fab0a', - transactionId: 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b' - } - ], - start: 1472239426002, - auctionStart: 1472239426000, - timeout: 5000 - }; - }; - - function createResponseAdByIndex(i, sizeId, indexOverMap) { - const overridePropMap = (indexOverMap && indexOverMap[i] && typeof indexOverMap[i] === 'object') ? indexOverMap[i] : {}; - const overrideProps = Object.keys(overridePropMap).reduce((aggregate, key) => { - aggregate[key] = overridePropMap[key]; - return aggregate; - }, {}); - - const getProp = (propName, defaultValue) => { - return (overrideProps[propName]) ? overridePropMap[propName] : defaultValue; - }; - - return { - 'status': getProp('status', 'ok'), - 'cpm': getProp('cpm', i / 100), - 'zone_id': getProp('zone_id', i + 1), - 'size_id': sizeId, - 'impression_id': getProp('impression_id', `1-${i}`), - 'ad_id': getProp('ad_id', i + 1), - 'advertiser': i + 1, - 'network': i + 1, - 'creative_id': getProp('creative_id', `crid-${i}`), - 'type': 'script', - 'script': 'alert(\'foo\')', - 'campaign_id': i + 1, - 'targeting': [ - { - 'key': getProp('targeting_key', `rpfl_${i}`), - 'values': ['43_tier_all_test'] - } - ] - }; - } - - /** - * @param {number} i - * @param {Array.} size - * @return {{ params: {accountId: string, siteId: string, zoneId: string }, adUnitCode: string, code: string, sizes: *[], bidId: string, bidderRequestId: string }} - */ - function createBidRequestByIndex(i, size) { - return { - bidder: 'rubicon', - params: { - accountId: '14062', - siteId: '70608', - zoneId: (i + 1).toString(), - userId: '12346', - position: 'atf', - referrer: 'localhost' - }, - adUnitCode: `/19968336/header-bid-tag-${i}`, - code: `div-${i}`, - sizes: [size], - bidId: i.toString(), - bidderRequestId: i.toString(), - auctionId: 'c45dd708-a418-42ec-b8a7-b70a6c6fab0a', - transactionId: 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b' - }; - } - - /** - * @param {boolean} [gdprApplies] - */ - function createGdprBidderRequest(gdprApplies) { - if (typeof gdprApplies === 'boolean') { - bidderRequest.gdprConsent = { - 'consentString': 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', - 'gdprApplies': gdprApplies - }; - } else { - bidderRequest.gdprConsent = { - 'consentString': 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==' - }; - } - } - - function createUspBidderRequest() { - bidderRequest.uspConsent = '1NYN'; - } - - function createVideoBidderRequest() { - createGdprBidderRequest(true); - createUspBidderRequest(); - - let bid = bidderRequest.bids[0]; - bid.mediaTypes = { - video: { - context: 'instream', - mimes: ['video/mp4', 'video/x-flv'], - api: [2], - minduration: 15, - playerSize: [640, 480], - maxduration: 30, - startdelay: 0, - playbackmethod: [2], - linearity: 1, - skip: 1, - skipafter: 15, - pos: 1, - protocols: [1, 2, 3, 4, 5, 6] - } - }; - bid.params.video = { - 'language': 'en', - 'skip': 1, - 'skipafter': 15, - 'playerHeight': 480, - 'playerWidth': 640, - 'size_id': 201, - }; - bid.userId = { - lipb: {lipbid: '0000-1111-2222-3333', segments: ['segA', 'segB']}, - idl_env: '1111-2222-3333-4444', - sharedid: {id: '1111', third: '2222'}, - tdid: '3000', - pubcid: '4000', - pubProvidedId: [{ - source: 'example.com', - uids: [{ - id: '333333', - ext: { - stype: 'ppuid' - } - }] - }, { - source: 'id-partner.com', - uids: [{ - id: '4444444' - }] - }], - criteoId: '1111', - }; - bid.userIdAsEids = createEidsArray(bid.userId); - bid.storedAuctionResponse = 11111; - } - - function createVideoBidderRequestNoVideo() { - let bid = bidderRequest.bids[0]; - bid.mediaTypes = { - video: { - context: 'instream' - }, - }; - bid.params.video = ''; - } - - function createVideoBidderRequestOutstream() { - let bid = bidderRequest.bids[0]; - bid.mediaTypes = { - video: { - context: 'outstream', - mimes: ['video/mp4', 'video/x-flv'], - api: [2], - minduration: 15, - playerSize: [640, 480], - maxduration: 30, - startdelay: 0, - playbackmethod: [2], - linearity: 1, - skip: 1, - skipafter: 15, - pos: 1, - protocols: [1, 2, 3, 4, 5, 6] - }, - }; - bid.params.accountId = 14062; - bid.params.siteId = 70608; - bid.params.zoneId = 335918; - bid.params.video = { - 'language': 'en', - 'skip': 1, - 'skipafter': 15, - 'playerHeight': 320, - 'playerWidth': 640, - 'size_id': 203 - }; - } - - beforeEach(function () { - sandbox = sinon.sandbox.create(); - logErrorSpy = sinon.spy(utils, 'logError'); - getFloorResponse = {}; - bidderRequest = { - bidderCode: 'rubicon', - auctionId: 'c45dd708-a418-42ec-b8a7-b70a6c6fab0a', - bidderRequestId: '178e34bad3658f', - bids: [ - { - bidder: 'rubicon', - params: { - accountId: '14062', - siteId: '70608', - zoneId: '335918', - pchain: 'GAM:11111-reseller1:22222', - userId: '12346', - keywords: ['a', 'b', 'c'], - inventory: { - rating: '5-star', // This actually should not be sent to frank!! causes 400 - prodtype: ['tech', 'mobile'] - }, - visitor: { - ucat: 'new', - lastsearch: 'iphone', - likes: ['sports', 'video games'] - }, - position: 'atf', - referrer: 'localhost', - latLong: [40.7607823, '111.8910325'] - }, - adUnitCode: '/19968336/header-bid-tag-0', - code: 'div-1', - sizes: [[300, 250], [320, 50]], - bidId: '2ffb201a808da7', - bidderRequestId: '178e34bad3658f', - auctionId: 'c45dd708-a418-42ec-b8a7-b70a6c6fab0a', - transactionId: 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b' - } - ], - start: 1472239426002, - auctionStart: 1472239426000, - timeout: 5000 - }; - - 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'} - // Create convenience properties for [sizeAsArray, width, height] by parsing the size string - ].map(item => { - const sizeAsArray = item.size.split('x').map(s => parseInt(s)); - return { - sizeId: item.sizeId, - size: item.size, - sizeAsArray: sizeAsArray.slice(), - width: sizeAsArray[0], - height: sizeAsArray[1] - }; - }); - }); - - afterEach(function () { - sandbox.restore(); - utils.logError.restore(); - config.resetConfig(); - resetRubiConf(); - delete $$PREBID_GLOBAL$$.installedModules; - }); - - describe('MAS mapping / ordering', function () { - it('should sort values without any MAS priority sizes in regular ascending order', function () { - let ordering = masSizeOrdering([126, 43, 65, 16]); - expect(ordering).to.deep.equal([16, 43, 65, 126]); - }); - - it('should sort MAS priority sizes in the proper order w/ rest ascending', function () { - let ordering = masSizeOrdering([43, 9, 65, 15, 16, 126]); - expect(ordering).to.deep.equal([15, 9, 16, 43, 65, 126]); - - ordering = masSizeOrdering([43, 15, 9, 65, 16, 126, 2]); - expect(ordering).to.deep.equal([15, 2, 9, 16, 43, 65, 126]); - - ordering = masSizeOrdering([8, 43, 9, 65, 16, 126, 2]); - expect(ordering).to.deep.equal([2, 9, 8, 16, 43, 65, 126]); - }); - }); - - describe('buildRequests implementation', function () { - describe('for requests', function () { - describe('to fastlane', function () { - it('should make a well-formed request object', function () { - sandbox.stub(Math, 'random').callsFake(() => 0.1); - let duplicate = Object.assign(bidderRequest); - duplicate.bids[0].params.floor = 0.01; - - let [request] = spec.buildRequests(duplicate.bids, duplicate); - let data = parseQuery(request.data); - - expect(request.url).to.equal('https://fastlane.rubiconproject.com/a/api/fastlane.json'); - - let expectedQuery = { - 'account_id': '14062', - 'site_id': '70608', - 'zone_id': '335918', - 'size_id': '15', - 'alt_size_ids': '43', - 'p_pos': 'atf', - 'rp_floor': '0.01', - 'rp_secure': /[01]/, - 'rand': '0.1', - 'tk_flint': INTEGRATION, - 'x_source.tid': 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b', - 'x_source.pchain': 'GAM:11111-reseller1:22222', - 'p_screen_res': /\d+x\d+/, - 'tk_user_key': '12346', - 'kw': 'a,b,c', - 'tg_v.ucat': 'new', - 'tg_v.lastsearch': 'iphone', - 'tg_v.likes': 'sports,video games', - 'tg_i.rating': '5-star', - 'tg_i.prodtype': 'tech,mobile', - 'tg_fl.eid': 'div-1', - 'rf': 'localhost' - }; - - // test that all values above are both present and correct - Object.keys(expectedQuery).forEach(key => { - let value = expectedQuery[key]; - if (value instanceof RegExp) { - expect(data[key]).to.match(value); - } else { - expect(data[key]).to.equal(value); - } - }); - }); - - it('should correctly send hard floors when getFloor function is present and returns valid floor', function () { - // default getFloor response is empty object so should not break and not send hard_floor - bidderRequest.bids[0].getFloor = () => getFloorResponse; - sinon.spy(bidderRequest.bids[0], 'getFloor'); - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - - // make sure banner bid called with right stuff - expect( - bidderRequest.bids[0].getFloor.calledWith({ - currency: 'USD', - mediaType: 'banner', - size: '*' - }) - ).to.be.true; - - let data = parseQuery(request.data); - expect(data.rp_hard_floor).to.be.undefined; - - // not an object should work and not send - getFloorResponse = undefined; - [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - data = parseQuery(request.data); - expect(data.rp_hard_floor).to.be.undefined; - - // make it respond with a non USD floor should not send it - getFloorResponse = {currency: 'EUR', floor: 1.0}; - [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - data = parseQuery(request.data); - expect(data.rp_hard_floor).to.be.undefined; - - // make it respond with a non USD floor should not send it - getFloorResponse = {currency: 'EUR'}; - [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - data = parseQuery(request.data); - expect(data.rp_hard_floor).to.be.undefined; - - // make it respond with USD floor and string floor - getFloorResponse = {currency: 'USD', floor: '1.23'}; - [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - data = parseQuery(request.data); - expect(data.rp_hard_floor).to.equal('1.23'); - - // make it respond with USD floor and num floor - getFloorResponse = {currency: 'USD', floor: 1.23}; - [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - data = parseQuery(request.data); - expect(data.rp_hard_floor).to.equal('1.23'); - }); - - it('should send rp_maxbids to AE if rubicon multibid config exists', function () { - var multibidRequest = utils.deepClone(bidderRequest); - multibidRequest.bidLimit = 5; - - let [request] = spec.buildRequests(multibidRequest.bids, multibidRequest); - let data = parseQuery(request.data); - - expect(data['rp_maxbids']).to.equal('5'); - }); - - it('should not send p_pos to AE if not params.position specified', function () { - var noposRequest = utils.deepClone(bidderRequest); - delete noposRequest.bids[0].params.position; - - let [request] = spec.buildRequests(noposRequest.bids, noposRequest); - let data = parseQuery(request.data); - - expect(data['site_id']).to.equal('70608'); - expect(data['p_pos']).to.equal(undefined); - }); - - it('should not send p_pos to AE if not params.position is invalid', function () { - var badposRequest = utils.deepClone(bidderRequest); - badposRequest.bids[0].params.position = 'bad'; - - let [request] = spec.buildRequests(badposRequest.bids, badposRequest); - let data = parseQuery(request.data); - - expect(data['site_id']).to.equal('70608'); - expect(data['p_pos']).to.equal(undefined); - }); - - it('should correctly send p_pos in sra fashion', function() { - config.setConfig({rubicon: {singleRequest: true}}); - // first one is atf - var sraPosRequest = utils.deepClone(bidderRequest); - - // second is not present - const bidCopy = utils.deepClone(sraPosRequest.bids[0]); - delete bidCopy.params.position; - sraPosRequest.bids.push(bidCopy); - - // third is btf - const bidCopy1 = utils.deepClone(sraPosRequest.bids[0]); - bidCopy1.params.position = 'btf'; - sraPosRequest.bids.push(bidCopy1); - - // fourth is invalid (aka not atf or btf) - const bidCopy2 = utils.deepClone(sraPosRequest.bids[0]); - bidCopy2.params.position = 'unknown'; - sraPosRequest.bids.push(bidCopy2); - - // fifth is not present - const bidCopy3 = utils.deepClone(sraPosRequest.bids[0]); - delete bidCopy3.params.position; - sraPosRequest.bids.push(bidCopy3); - - let [request] = spec.buildRequests(sraPosRequest.bids, sraPosRequest); - let data = parseQuery(request.data); - - expect(data['p_pos']).to.equal('atf;;btf;;'); - }); - - it('should not send x_source.pchain to AE if params.pchain is not specified', function () { - var noPchainRequest = utils.deepClone(bidderRequest); - delete noPchainRequest.bids[0].params.pchain; - - let [request] = spec.buildRequests(noPchainRequest.bids, noPchainRequest); - expect(request.data).to.contain('&site_id=70608&'); - expect(request.data).to.not.contain('x_source.pchain'); - }); - - it('ad engine query params should be ordered correctly', function () { - sandbox.stub(Math, 'random').callsFake(() => 0.1); - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - - const referenceOrdering = ['account_id', 'site_id', 'zone_id', 'size_id', 'alt_size_ids', 'p_pos', 'rf', 'p_geo.latitude', 'p_geo.longitude', 'kw', 'tg_v.ucat', 'tg_v.lastsearch', 'tg_v.likes', 'tg_i.rating', 'tg_i.prodtype', 'tk_flint', 'x_source.tid', 'x_source.pchain', 'p_screen_res', 'rp_secure', 'tk_user_key', 'tg_fl.eid', 'rp_maxbids', 'slots', 'rand']; - - request.data.split('&').forEach((item, i) => { - expect(item.split('=')[0]).to.equal(referenceOrdering[i]); - }); - }); - - it('should make a well-formed request object without latLong', function () { - let expectedQuery = { - 'account_id': '14062', - 'site_id': '70608', - 'zone_id': '335918', - 'size_id': '15', - 'alt_size_ids': '43', - 'p_pos': 'atf', - 'rp_secure': /[01]/, - 'rand': '0.1', - 'tk_flint': INTEGRATION, - 'x_source.tid': 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b', - 'p_screen_res': /\d+x\d+/, - 'tk_user_key': '12346', - 'kw': 'a,b,c', - 'tg_v.ucat': 'new', - 'tg_v.lastsearch': 'iphone', - 'tg_v.likes': 'sports,video games', - 'tg_i.rating': '5-star', - 'tg_i.prodtype': 'tech,mobile', - 'rf': 'localhost', - 'p_geo.latitude': undefined, - 'p_geo.longitude': undefined - }; - - sandbox.stub(Math, 'random').callsFake(() => 0.1); - - delete bidderRequest.bids[0].params.latLong; - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let data = parseQuery(request.data); - - expect(request.url).to.equal('https://fastlane.rubiconproject.com/a/api/fastlane.json'); - - // test that all values above are both present and correct - Object.keys(expectedQuery).forEach(key => { - let value = expectedQuery[key]; - if (value instanceof RegExp) { - expect(data[key]).to.match(value); - } else { - expect(data[key]).to.equal(value); - } - }); - - bidderRequest.bids[0].params.latLong = []; - [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - data = parseQuery(request.data); - - expect(request.url).to.equal('https://fastlane.rubiconproject.com/a/api/fastlane.json'); - - // test that all values above are both present and correct - Object.keys(expectedQuery).forEach(key => { - let value = expectedQuery[key]; - if (value instanceof RegExp) { - expect(data[key]).to.match(value); - } else { - expect(data[key]).to.equal(value); - } - }); - }); - - it('should add referer info to request data', function () { - let refererInfo = { - referer: 'https://www.prebid.org', - reachedTop: true, - numIframes: 1, - stack: [ - 'https://www.prebid.org/page.html', - 'https://www.prebid.org/iframe1.html', - ] - }; - - bidderRequest = Object.assign({refererInfo}, bidderRequest); - delete bidderRequest.bids[0].params.referrer; - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - - expect(parseQuery(request.data).rf).to.exist; - expect(parseQuery(request.data).rf).to.equal('https://www.prebid.org'); - }); - - it('page_url should use params.referrer, config.getConfig("pageUrl"), bidderRequest.refererInfo in that order', function () { - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(parseQuery(request.data).rf).to.equal('localhost'); - - delete bidderRequest.bids[0].params.referrer; - let refererInfo = {referer: 'https://www.prebid.org'}; - bidderRequest = Object.assign({refererInfo}, bidderRequest); - [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(parseQuery(request.data).rf).to.equal('https://www.prebid.org'); - - let origGetConfig = config.getConfig; - sandbox.stub(config, 'getConfig').callsFake(function (key) { - if (key === 'pageUrl') { - return 'https://www.rubiconproject.com'; - } - return origGetConfig.apply(config, arguments); - }); - [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(parseQuery(request.data).rf).to.equal('https://www.rubiconproject.com'); - - bidderRequest.bids[0].params.secure = true; - [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(parseQuery(request.data).rf).to.equal('https://www.rubiconproject.com'); - }); - - it('should use rubicon sizes if present (including non-mappable sizes)', function () { - var sizesBidderRequest = utils.deepClone(bidderRequest); - sizesBidderRequest.bids[0].params.sizes = [55, 57, 59, 801]; - - let [request] = spec.buildRequests(sizesBidderRequest.bids, sizesBidderRequest); - let data = parseQuery(request.data); - - expect(data['size_id']).to.equal('55'); - expect(data['alt_size_ids']).to.equal('57,59,801'); - }); - - it('should not validate bid request if no valid sizes', function () { - var sizesBidderRequest = utils.deepClone(bidderRequest); - sizesBidderRequest.bids[0].sizes = [[621, 250], [300, 251]]; - - let result = spec.isBidRequestValid(sizesBidderRequest.bids[0]); - - expect(result).to.equal(false); - }); - - it('should not validate bid request if no account id is present', function () { - var noAccountBidderRequest = utils.deepClone(bidderRequest); - delete noAccountBidderRequest.bids[0].params.accountId; - - let result = spec.isBidRequestValid(noAccountBidderRequest.bids[0]); - - expect(result).to.equal(false); - }); - - it('should allow a floor override', function () { - var floorBidderRequest = utils.deepClone(bidderRequest); - floorBidderRequest.bids[0].params.floor = 2; - - let [request] = spec.buildRequests(floorBidderRequest.bids, floorBidderRequest); - let data = parseQuery(request.data); - - expect(data['rp_floor']).to.equal('2'); - }); - - describe('GDPR consent config', function () { - it('should send "gdpr" and "gdpr_consent", when gdprConsent defines consentString and gdprApplies', function () { - createGdprBidderRequest(true); - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let data = parseQuery(request.data); - - expect(data['gdpr']).to.equal('1'); - expect(data['gdpr_consent']).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A=='); - }); - - it('should send only "gdpr_consent", when gdprConsent defines only consentString', function () { - createGdprBidderRequest(); - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let data = parseQuery(request.data); - - expect(data['gdpr_consent']).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A=='); - expect(data['gdpr']).to.equal(undefined); - }); - - it('should not send GDPR params if gdprConsent is not defined', function () { - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let data = parseQuery(request.data); - - expect(data['gdpr']).to.equal(undefined); - expect(data['gdpr_consent']).to.equal(undefined); - }); - - it('should set "gdpr" value as 1 or 0, using "gdprApplies" value of either true/false', function () { - createGdprBidderRequest(true); - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let data = parseQuery(request.data); - expect(data['gdpr']).to.equal('1'); - - createGdprBidderRequest(false); - [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - data = parseQuery(request.data); - expect(data['gdpr']).to.equal('0'); - }); - }); - - describe('USP Consent', function () { - it('should send us_privacy if bidderRequest has a value for uspConsent', function () { - createUspBidderRequest(); - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let data = parseQuery(request.data); - - expect(data['us_privacy']).to.equal('1NYN'); - }); - - it('should not send us_privacy if bidderRequest has no uspConsent value', function () { - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let data = parseQuery(request.data); - - expect(data['us_privacy']).to.equal(undefined); - }); - }); - - describe('first party data', function () { - it('should not have any tg_v or tg_i params if all are undefined', function () { - let params = { - inventory: { - rating: null, - prodtype: undefined - }, - visitor: { - ucat: undefined, - lastsearch: null, - likes: undefined - }, - }; - - // Overwrite the bidder request params with the above ones - Object.assign(bidderRequest.bids[0].params, params); - - // get the built request - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let data = parseQuery(request.data); - - // make sure that no tg_v or tg_i keys are present in the request - let matchingExp = RegExp('^tg_(i|v)\..*$') - Object.keys(data).forEach(key => { - expect(key).to.not.match(matchingExp); - }); - }); - - it('should contain valid params when some are undefined', function () { - let params = { - inventory: { - rating: undefined, - prodtype: ['tech', 'mobile'] - }, - visitor: { - ucat: null, - lastsearch: 'iphone', - likes: undefined - }, - }; - let undefinedKeys = ['tg_i.rating', 'tg_v.ucat', 'tg_v.likes'] - let expectedQuery = { - 'tg_v.lastsearch': 'iphone', - 'tg_i.prodtype': 'tech,mobile', - } - - // Overwrite the bidder request params with the above ones - Object.assign(bidderRequest.bids[0].params, params); - - // get the built request - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let data = parseQuery(request.data); - - // make sure none of the undefined keys are in query - undefinedKeys.forEach(key => { - expect(typeof data[key]).to.equal('undefined'); - }); - - // make sure the expected and defined ones do show up still - Object.keys(expectedQuery).forEach(key => { - let value = expectedQuery[key]; - expect(data[key]).to.equal(value); - }); - }); - - it('should merge first party data from getConfig with the bid params, if present', () => { - const site = { - keywords: 'e,f', - rating: '4-star', - ext: { - data: { - page: 'home' - } - }, - content: { - data: [{ - 'name': 'www.dataprovider1.com', - 'ext': { 'segtax': 1 }, - 'segment': [ - { 'id': '987' } - ] - }, { - 'name': 'www.dataprovider1.com', - 'ext': { 'segtax': 2 }, - 'segment': [ - { 'id': '432' } - ] - }] - } - }; - const user = { - data: [{ - 'name': 'www.dataprovider1.com', - 'ext': { 'segtax': 3 }, - 'segment': [ - { 'id': '687' }, - { 'id': '123' } - ] - }], - gender: 'M', - yob: '1984', - geo: {country: 'ca'}, - keywords: 'd', - ext: { - data: { - age: 40 - } - } - }; - - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - ortb2: { - site, - user - } - }; - return utils.deepAccess(config, key); - }); - - const expectedQuery = { - 'kw': 'a,b,c,d', - 'tg_v.ucat': 'new', - 'tg_v.lastsearch': 'iphone', - 'tg_v.likes': 'sports,video games', - 'tg_v.gender': 'M', - 'tg_v.age': '40', - 'tg_v.iab': '687,123', - 'tg_i.iab': '987,432', - 'tg_v.yob': '1984', - 'tg_i.rating': '4-star,5-star', - 'tg_i.page': 'home', - 'tg_i.prodtype': 'tech,mobile', - }; - - // get the built request - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let data = parseQuery(request.data); - - // make sure that tg_v, tg_i, and kw values are correct - Object.keys(expectedQuery).forEach(key => { - let value = expectedQuery[key]; - expect(data[key]).to.deep.equal(value); - }); - }); - }); - - describe('singleRequest config', 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}}); - - const expectedQuery = { - 'account_id': '14062', - 'site_id': '70608', - 'zone_id': '335918', - 'size_id': '15', - 'alt_size_ids': '43', - 'p_pos': 'atf', - 'rp_secure': /[01]/, - 'rand': '0.1', - 'tk_flint': INTEGRATION, - 'x_source.tid': 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b', - 'p_screen_res': /\d+x\d+/, - 'tk_user_key': '12346', - 'kw': 'a,b,c', - 'tg_v.ucat': 'new', - 'tg_v.lastsearch': 'iphone', - 'tg_v.likes': 'sports,video games', - 'tg_i.rating': '5-star', - 'tg_i.prodtype': 'tech,mobile', - 'tg_fl.eid': 'div-1', - 'rf': 'localhost' - }; - - const bidCopy = utils.deepClone(bidderRequest.bids[0]); - bidCopy.params.siteId = '70608'; - bidCopy.params.zoneId = '1111'; - bidderRequest.bids.push(bidCopy); - - const bidCopy2 = utils.deepClone(bidderRequest.bids[0]); - bidCopy2.params.siteId = '99999'; - bidCopy2.params.zoneId = '2222'; - bidderRequest.bids.push(bidCopy2); - - const bidCopy3 = utils.deepClone(bidderRequest.bids[0]); - bidCopy3.params.siteId = '99999'; - bidCopy3.params.zoneId = '3333'; - bidderRequest.bids.push(bidCopy3); - - const serverRequests = spec.buildRequests(bidderRequest.bids, bidderRequest); - - // array length should match the num of unique 'siteIds' - expect(serverRequests).to.be.a('array'); - expect(serverRequests).to.have.lengthOf(2); - - // collect all bidRequests so order can be checked against the url param slot order - const bidRequests = serverRequests.reduce((aggregator, item) => aggregator.concat(item.bidRequest), []); - let bidRequestIndex = 0; - - serverRequests.forEach(item => { - expect(item).to.be.a('object'); - expect(item).to.have.property('method'); - expect(item).to.have.property('url'); - expect(item).to.have.property('data'); - expect(item).to.have.property('bidRequest'); - - expect(item.method).to.equal('GET'); - expect(item.url).to.equal('https://fastlane.rubiconproject.com/a/api/fastlane.json'); - expect(item.data).to.be.a('string'); - - // 'bidRequest' type must be 'array' if SRA enabled - expect(item.bidRequest).to.be.a('array').to.have.lengthOf(2); - - item.bidRequest.forEach((bidRequestItem, i, array) => { - expect(bidRequestItem).to.be.a('object'); - // every 'siteId' values need to match - expect(bidRequestItem.params.siteId).to.equal(array[0].params.siteId); - }); - - const data = parseQuery(item.data); - - Object.keys(expectedQuery).forEach(key => { - expect(data).to.have.property(key); - - // extract semicolon delineated values - const params = data[key].split(';'); - - // skip value test for site and zone ids - if (key !== 'site_id' && key !== 'zone_id') { - if (expectedQuery[key] instanceof RegExp) { - params.forEach(paramItem => { - expect(paramItem).to.match(expectedQuery[key]); - }); - } else { - expect(params).to.contain(expectedQuery[key]); - } - } - - // check parsed url data list order with requestBid list, items must have same index in both lists - if (key === 'zone_id') { - params.forEach((p) => { - expect(bidRequests[bidRequestIndex]).to.be.a('object'); - expect(bidRequests[bidRequestIndex].params).to.be.a('object'); - - // 'zone_id' is used to verify so each bid must have a unique 'zone_id' - expect(p).to.equal(bidRequests[bidRequestIndex].params.zoneId); - - // increment to next bidRequest index having verified that item positions match in url params and bidRequest lists - bidRequestIndex++; - }); - } - }); - }); - }); - - 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}}); - let serverRequests; - let data; - - // TEST '10' BIDS, add 9 to 1 existing bid - for (let i = 0; i < 9; i++) { - let bidCopy = utils.deepClone(bidderRequest.bids[0]); - bidCopy.params.zoneId = `${i}0000`; - bidderRequest.bids.push(bidCopy); - } - serverRequests = spec.buildRequests(bidderRequest.bids, bidderRequest); - // '10' bids per SRA request: so there should be 1 request - expect(serverRequests.length).to.equal(1); - // and that one request should have data from 10 bids - expect(serverRequests[0].bidRequest).to.have.lengthOf(10); - // check that slots param value matches - expect(serverRequests[0].data.indexOf('&slots=10&') !== -1).to.equal(true); - // check that zone_id has 10 values (since all zone_ids are unique all should exist in get param) - data = parseQuery(serverRequests[0].data); - expect(data).to.be.a('object'); - expect(data).to.have.property('zone_id'); - expect(data.zone_id.split(';')).to.have.lengthOf(10); - - // TEST '100' BIDS, add 90 to the previously added 10 - for (let i = 0; i < 90; i++) { - let bidCopy = utils.deepClone(bidderRequest.bids[0]); - bidCopy.params.zoneId = `${(i + 10)}0000`; - bidderRequest.bids.push(bidCopy); - } - serverRequests = spec.buildRequests(bidderRequest.bids, bidderRequest); - // '100' bids: should be '10' SRA requests - expect(serverRequests.length).to.equal(10); - // check that each request has 10 items - serverRequests.forEach((serverRequest) => { - // and that one request should have data from 10 bids - expect(serverRequest.bidRequest).to.have.lengthOf(10); - // check that slots param value matches - expect(serverRequest.data.indexOf('&slots=10&') !== -1).to.equal(true); - }); - }); - - it('should not group bid requests if singleRequest does not equal true', function () { - config.setConfig({rubicon: {singleRequest: false}}); - - const bidCopy = utils.deepClone(bidderRequest.bids[0]); - bidderRequest.bids.push(bidCopy); - - const bidCopy2 = utils.deepClone(bidderRequest.bids[0]); - bidCopy2.params.siteId = '32001'; - bidderRequest.bids.push(bidCopy2); - - const bidCopy3 = utils.deepClone(bidderRequest.bids[0]); - bidCopy3.params.siteId = '32001'; - bidderRequest.bids.push(bidCopy3); - - let serverRequests = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(serverRequests).that.is.an('array').of.length(4); - }); - - it('should not group video bid requests', function () { - config.setConfig({rubicon: {singleRequest: true}}); - - const bidCopy = utils.deepClone(bidderRequest.bids[0]); - bidderRequest.bids.push(bidCopy); - - const bidCopy2 = utils.deepClone(bidderRequest.bids[0]); - bidCopy2.params.siteId = '32001'; - bidderRequest.bids.push(bidCopy2); - - const bidCopy3 = utils.deepClone(bidderRequest.bids[0]); - bidCopy3.params.siteId = '32001'; - bidderRequest.bids.push(bidCopy3); - - const bidCopy4 = utils.deepClone(bidderRequest.bids[0]); - bidCopy4.mediaTypes = { - video: { - context: 'instream', - playerSize: [640, 480], - mimes: ['video/mp4', 'video/x-ms-wmv'], - protocols: [2, 5], - maxduration: 30, - linearity: 1, - api: [2] - } - }; - bidCopy4.params.video = { - 'language': 'en', - 'p_aso.video.ext.skip': true, - 'p_aso.video.ext.skipdelay': 15, - 'playerHeight': 320, - 'playerWidth': 640, - 'size_id': 201, - 'aeParams': { - 'p_aso.video.ext.skip': '1', - 'p_aso.video.ext.skipdelay': '15' - } - }; - bidderRequest.bids.push(bidCopy4); - - let serverRequests = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(serverRequests).that.is.an('array').of.length(3); - }); - }); - - describe('user id config', function () { - it('should send tpid_tdid when userIdAsEids contains unifiedId', function () { - const clonedBid = utils.deepClone(bidderRequest.bids[0]); - clonedBid.userId = { - tdid: 'abcd-efgh-ijkl-mnop-1234' - }; - clonedBid.userIdAsEids = createEidsArray(clonedBid.userId); - let [request] = spec.buildRequests([clonedBid], bidderRequest); - let data = parseQuery(request.data); - - expect(data['tpid_tdid']).to.equal('abcd-efgh-ijkl-mnop-1234'); - expect(data['eid_adserver.org']).to.equal('abcd-efgh-ijkl-mnop-1234'); - }); - - describe('LiveIntent support', function () { - it('should send tpid_liveintent.com when userIdAsEids contains liveintentId', function () { - const clonedBid = utils.deepClone(bidderRequest.bids[0]); - clonedBid.userId = { - lipb: { - lipbid: '0000-1111-2222-3333', - segments: ['segA', 'segB'] - } - }; - clonedBid.userIdAsEids = createEidsArray(clonedBid.userId); - let [request] = spec.buildRequests([clonedBid], bidderRequest); - let data = parseQuery(request.data); - - expect(data['tpid_liveintent.com']).to.equal('0000-1111-2222-3333'); - expect(data['eid_liveintent.com']).to.equal('0000-1111-2222-3333'); - expect(data['tg_v.LIseg']).to.equal('segA,segB'); - }); - - it('should send tg_v.LIseg when userIdAsEids contains liveintentId with ext.segments as array', function () { - const clonedBid = utils.deepClone(bidderRequest.bids[0]); - clonedBid.userId = { - lipb: { - lipbid: '1111-2222-3333-4444', - segments: ['segD', 'segE'] - } - }; - clonedBid.userIdAsEids = createEidsArray(clonedBid.userId); - let [request] = spec.buildRequests([clonedBid], bidderRequest); - const unescapedData = unescape(request.data); - - expect(unescapedData.indexOf('&tpid_liveintent.com=1111-2222-3333-4444&') !== -1).to.equal(true); - expect(unescapedData.indexOf('&tg_v.LIseg=segD,segE&') !== -1).to.equal(true); - }); - }); - - describe('LiveRamp support', function () { - it('should send x_liverampidl when userIdAsEids contains liverampId', function () { - const clonedBid = utils.deepClone(bidderRequest.bids[0]); - clonedBid.userId = { - idl_env: '1111-2222-3333-4444' - }; - clonedBid.userIdAsEids = createEidsArray(clonedBid.userId); - let [request] = spec.buildRequests([clonedBid], bidderRequest); - let data = parseQuery(request.data); - - expect(data['x_liverampidl']).to.equal('1111-2222-3333-4444'); - }); - }); - - describe('pubcid support', function () { - it('should send eid_pubcid.org when userIdAsEids contains pubcid', function () { - const clonedBid = utils.deepClone(bidderRequest.bids[0]); - clonedBid.userId = { - pubcid: '1111' - }; - clonedBid.userIdAsEids = createEidsArray(clonedBid.userId); - let [request] = spec.buildRequests([clonedBid], bidderRequest); - let data = parseQuery(request.data); - - expect(data['eid_pubcid.org']).to.equal('1111^1'); - }); - }); - - describe('Criteo support', function () { - it('should send eid_criteo.com when userIdAsEids contains criteo', function () { - const clonedBid = utils.deepClone(bidderRequest.bids[0]); - clonedBid.userId = { - criteoId: '1111' - }; - clonedBid.userIdAsEids = createEidsArray(clonedBid.userId); - let [request] = spec.buildRequests([clonedBid], bidderRequest); - let data = parseQuery(request.data); - - expect(data['eid_criteo.com']).to.equal('1111^1'); - }); - }); - - describe('SharedID support', function () { - it('should send sharedid when userIdAsEids contains sharedId', function () { - const clonedBid = utils.deepClone(bidderRequest.bids[0]); - clonedBid.userId = { - sharedid: { - id: '1111', - third: '2222' - } - }; - clonedBid.userIdAsEids = createEidsArray(clonedBid.userId); - let [request] = spec.buildRequests([clonedBid], bidderRequest); - let data = parseQuery(request.data); - - expect(data['eid_sharedid.org']).to.equal('1111^1^2222'); - }); - }); - - describe('pubProvidedId support', function () { - it('should send pubProvidedId when userIdAsEids contains pubProvidedId ids', function () { - const clonedBid = utils.deepClone(bidderRequest.bids[0]); - clonedBid.userId = { - pubProvidedId: [{ - source: 'example.com', - uids: [{ - id: '11111', - ext: { - stype: 'ppuid' - } - }] - }, { - source: 'id-partner.com', - uids: [{ - id: '222222' - }] - }] - }; - clonedBid.userIdAsEids = createEidsArray(clonedBid.userId); - let [request] = spec.buildRequests([clonedBid], bidderRequest); - let data = parseQuery(request.data); - - expect(data['ppuid']).to.equal('11111'); - }); - }); - - describe('ID5 support', function () { - it('should send ID5 id when userIdAsEids contains ID5', function () { - const clonedBid = utils.deepClone(bidderRequest.bids[0]); - clonedBid.userId = { - id5id: { - uid: '11111', - ext: { - linkType: '22222' - } - } - }; - clonedBid.userIdAsEids = createEidsArray(clonedBid.userId); - let [request] = spec.buildRequests([clonedBid], bidderRequest); - let data = parseQuery(request.data); - - expect(data['eid_id5-sync.com']).to.equal('11111^1^22222'); - }); - }); - - describe('UserID catchall support', function () { - it('should send user id with generic format', function () { - const clonedBid = utils.deepClone(bidderRequest.bids[0]); - // Hardcoding userIdAsEids since createEidsArray returns empty array if source not found in eids.js - clonedBid.userIdAsEids = [{ - source: 'catchall', - uids: [{ - id: '11111', - atype: 2 - }] - }] - let [request] = spec.buildRequests([clonedBid], bidderRequest); - let data = parseQuery(request.data); - - expect(data['eid_catchall']).to.equal('11111^2'); - }); - }); - - describe('Config user.id support', function () { - it('should send ppuid when config defines user.id', function () { - config.setConfig({user: {id: '123'}}); - const clonedBid = utils.deepClone(bidderRequest.bids[0]); - clonedBid.userId = { - sharedid: { - id: '1111', - third: '2222' - } - }; - let [request] = spec.buildRequests([clonedBid], bidderRequest); - let data = parseQuery(request.data); - - expect(data['ppuid']).to.equal('123'); - }); - }); - }); - - describe('Prebid AdSlot', function () { - beforeEach(function () { - // enforce that the bid at 0 does not have a 'context' property - if (bidderRequest.bids[0].hasOwnProperty('ortb2Imp')) { - delete bidderRequest.bids[0].ortb2Imp; - } - }); - - it('should not send \"tg_i.pbadslot’\" if \"ortb2Imp.ext.data\" object is not valid', function () { - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - const data = parseQuery(request.data); - - expect(data).to.be.an('Object'); - expect(data).to.not.have.property('tg_i.pbadslot’'); - }); - - it('should not send \"tg_i.pbadslot’\" if \"ortb2Imp.ext.data.pbadslot\" is undefined', function () { - bidderRequest.bids[0].ortb2Imp = {}; - - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - const data = parseQuery(request.data); - - expect(data).to.be.an('Object'); - expect(data).to.not.have.property('tg_i.pbadslot’'); - }); - - it('should not send \"tg_i.pbadslot’\" if \"ortb2Imp.ext.data.pbadslot\" value is an empty string', function () { - bidderRequest.bids[0].ortb2Imp = { - ext: { - data: { - pbadslot: '' - } - } - }; - - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - const data = parseQuery(request.data); - - expect(data).to.be.an('Object'); - expect(data).to.not.have.property('tg_i.pbadslot'); - }); - - it('should send \"tg_i.pbadslot\" if \"ortb2Imp.ext.data.pbadslot\" value is a valid string', function () { - bidderRequest.bids[0].ortb2Imp = { - ext: { - data: { - pbadslot: 'abc' - } - } - } - - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - const data = parseQuery(request.data); - - expect(data).to.be.an('Object'); - expect(data).to.have.property('tg_i.pbadslot'); - expect(data['tg_i.pbadslot']).to.equal('abc'); - }); - - it('should send \"tg_i.pbadslot\" if \"ortb2Imp.ext.data.pbadslot\" value is a valid string, but all leading slash characters should be removed', function () { - bidderRequest.bids[0].ortb2Imp = { - ext: { - data: { - pbadslot: '/a/b/c' - } - } - } - - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - const data = parseQuery(request.data); - - expect(data).to.be.an('Object'); - expect(data).to.have.property('tg_i.pbadslot'); - expect(data['tg_i.pbadslot']).to.equal('a/b/c'); - }); - }); - - describe('GAM ad unit', function () { - beforeEach(function () { - // enforce that the bid at 0 does not have a 'context' property - if (bidderRequest.bids[0].hasOwnProperty('ortb2Imp')) { - delete bidderRequest.bids[0].ortb2Imp; - } - }); - - it('should not send \"tg_i.dfp_ad_unit_code’\" if \"ortb2Imp.ext.data\" object is not valid', function () { - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - const data = parseQuery(request.data); - - expect(data).to.be.an('Object'); - expect(data).to.not.have.property('tg_i.dfp_ad_unit_code’'); - }); - - it('should not send \"tg_i.dfp_ad_unit_code’\" if \"ortb2Imp.ext.data.adServer.adslot\" is undefined', function () { - bidderRequest.bids[0].ortb2Imp = {}; - - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - const data = parseQuery(request.data); - - expect(data).to.be.an('Object'); - expect(data).to.not.have.property('tg_i.dfp_ad_unit_code’'); - }); - - it('should not send \"tg_i.dfp_ad_unit_code’\" if \"ortb2Imp.ext.data.adServer.adslot\" value is an empty string', function () { - bidderRequest.bids[0].ortb2Imp = { - ext: { - data: { - adserver: { - adslot: '' - } - } - } - }; - - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - const data = parseQuery(request.data); - - expect(data).to.be.an('Object'); - expect(data).to.not.have.property('tg_i.dfp_ad_unit_code'); - }); - - it('should send \"tg_i.dfp_ad_unit_code\" if \"ortb2Imp.ext.data.adServer.adslot\" value is a valid string', function () { - bidderRequest.bids[0].ortb2Imp = { - ext: { - data: { - adserver: { - adslot: 'abc' - } - } - } - } - - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - const data = parseQuery(request.data); - - expect(data).to.be.an('Object'); - expect(data).to.have.property('tg_i.dfp_ad_unit_code'); - expect(data['tg_i.dfp_ad_unit_code']).to.equal('abc'); - }); - - it('should send \"tg_i.dfp_ad_unit_code\" if \"ortb2Imp.ext.data.adServer.adslot\" value is a valid string, but all leading slash characters should be removed', function () { - bidderRequest.bids[0].ortb2Imp = { - ext: { - data: { - adserver: { - adslot: 'a/b/c' - } - } - } - }; - - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - const data = parseQuery(request.data); - - expect(data).to.be.an('Object'); - expect(data).to.have.property('tg_i.dfp_ad_unit_code'); - expect(data['tg_i.dfp_ad_unit_code']).to.equal('a/b/c'); - }); - }); - }); - - describe('for video requests', function () { - it('should make a well-formed video request', function () { - createVideoBidderRequest(); - - sandbox.stub(Date, 'now').callsFake(() => - bidderRequest.auctionStart + 100 - ); - - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let post = request.data; - - expect(post).to.have.property('imp'); - // .with.length.of(1); - let imp = post.imp[0]; - expect(imp.id).to.equal(bidderRequest.bids[0].adUnitCode); - expect(imp.exp).to.equal(undefined); // now undefined - expect(imp.video.w).to.equal(640); - expect(imp.video.h).to.equal(480); - expect(imp.video.pos).to.equal(1); - expect(imp.video.context).to.equal('instream'); - expect(imp.video.minduration).to.equal(15); - expect(imp.video.maxduration).to.equal(30); - expect(imp.video.startdelay).to.equal(0); - expect(imp.video.skip).to.equal(1); - expect(imp.video.skipafter).to.equal(15); - expect(imp.ext.rubicon.video.playerWidth).to.equal(640); - expect(imp.ext.rubicon.video.playerHeight).to.equal(480); - expect(imp.ext.rubicon.video.size_id).to.equal(201); - expect(imp.ext.rubicon.video.language).to.equal('en'); - // Also want it to be in post.site.content.language - expect(post.site.content.language).to.equal('en'); - expect(imp.ext.rubicon.video.skip).to.equal(1); - expect(imp.ext.rubicon.video.skipafter).to.equal(15); - expect(imp.ext.prebid.auctiontimestamp).to.equal(1472239426000); - // should contain version - expect(post.ext.prebid.channel).to.deep.equal({name: 'pbjs', version: 'v$prebid.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'); - // LiveIntent should exist - expect(post.user.ext.eids[0].source).to.equal('liveintent.com'); - expect(post.user.ext.eids[0].uids[0].id).to.equal('0000-1111-2222-3333'); - expect(post.user.ext.eids[0].uids[0].atype).to.equal(3); - expect(post.user.ext.eids[0]).to.have.property('ext').that.is.an('object'); - expect(post.user.ext.eids[0].ext).to.have.property('segments').that.is.an('array'); - expect(post.user.ext.eids[0].ext.segments[0]).to.equal('segA'); - expect(post.user.ext.eids[0].ext.segments[1]).to.equal('segB'); - // LiveRamp should exist - expect(post.user.ext.eids[1].source).to.equal('liveramp.com'); - expect(post.user.ext.eids[1].uids[0].id).to.equal('1111-2222-3333-4444'); - expect(post.user.ext.eids[1].uids[0].atype).to.equal(3); - // SharedId should exist - expect(post.user.ext.eids[2].source).to.equal('sharedid.org'); - expect(post.user.ext.eids[2].uids[0].id).to.equal('1111'); - expect(post.user.ext.eids[2].uids[0].atype).to.equal(1); - expect(post.user.ext.eids[2].uids[0].ext.third).to.equal('2222'); - // UnifiedId should exist - expect(post.user.ext.eids[3].source).to.equal('adserver.org'); - expect(post.user.ext.eids[3].uids[0].atype).to.equal(1); - expect(post.user.ext.eids[3].uids[0].id).to.equal('3000'); - // PubCommonId should exist - expect(post.user.ext.eids[4].source).to.equal('pubcid.org'); - expect(post.user.ext.eids[4].uids[0].atype).to.equal(1); - expect(post.user.ext.eids[4].uids[0].id).to.equal('4000'); - // example should exist - expect(post.user.ext.eids[5].source).to.equal('example.com'); - expect(post.user.ext.eids[5].uids[0].id).to.equal('333333'); - // id-partner.com - expect(post.user.ext.eids[6].source).to.equal('id-partner.com'); - expect(post.user.ext.eids[6].uids[0].id).to.equal('4444444'); - // CriteoId should exist - expect(post.user.ext.eids[7].source).to.equal('criteo.com'); - expect(post.user.ext.eids[7].uids[0].id).to.equal('1111'); - expect(post.user.ext.eids[7].uids[0].atype).to.equal(1); - - expect(post.regs.ext.gdpr).to.equal(1); - expect(post.regs.ext.us_privacy).to.equal('1NYN'); - expect(post).to.have.property('ext').that.is.an('object'); - expect(post.ext.prebid.targeting.includewinners).to.equal(true); - expect(post.ext.prebid).to.have.property('cache').that.is.an('object'); - expect(post.ext.prebid.cache).to.have.property('vastxml').that.is.an('object'); - expect(post.ext.prebid.cache.vastxml).to.have.property('returnCreative').that.is.an('boolean'); - expect(post.ext.prebid.cache.vastxml.returnCreative).to.equal(false); - expect(post.ext.prebid.bidders.rubicon.integration).to.equal(PBS_INTEGRATION); - }); - - it('should correctly set bidfloor on imp when getfloor in scope', function () { - createVideoBidderRequest(); - // default getFloor response is empty object so should not break and not send hard_floor - bidderRequest.bids[0].getFloor = () => getFloorResponse; - sinon.spy(bidderRequest.bids[0], 'getFloor'); - - sandbox.stub(Date, 'now').callsFake(() => - bidderRequest.auctionStart + 100 - ); - - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - - // make sure banner bid called with right stuff - expect( - bidderRequest.bids[0].getFloor.calledWith({ - currency: 'USD', - mediaType: 'video', - size: [640, 480] - }) - ).to.be.true; - - // not an object should work and not send - 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}; - [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'}; - [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'}; - [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}; - [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(request.data.imp[0].bidfloor).to.equal(1.23); - }); - - it('should continue with auction and log error if getFloor throws one', function () { - createVideoBidderRequest(); - // default getFloor response is empty object so should not break and not send hard_floor - bidderRequest.bids[0].getFloor = () => { - throw new Error('An exception!'); - }; - sandbox.stub(Date, 'now').callsFake(() => - bidderRequest.auctionStart + 100 - ); - - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - - // log error called - expect(logErrorSpy.calledOnce).to.equal(true); - - // should have an imp - expect(request.data.imp).to.exist.and.to.be.a('array'); - expect(request.data.imp).to.have.lengthOf(1); - - // should be NO bidFloor - expect(request.data.imp[0].bidfloor).to.be.undefined; - }); - - it('should add alias name to PBS Request', function () { - createVideoBidderRequest(); - - bidderRequest.bidderCode = 'superRubicon'; - bidderRequest.bids[0].bidder = 'superRubicon'; - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - - // 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'}); - - // should have the imp ext bidder params be under the alias name not rubicon superRubicon - expect(request.data.imp[0].ext).to.have.property('superRubicon').that.is.an('object'); - expect(request.data.imp[0].ext).to.not.haveOwnProperty('rubicon'); - }); - - it('should add multibid configuration to PBS Request', function () { - createVideoBidderRequest(); - - const multibid = [{ - bidder: 'bidderA', - maxBids: 2 - }, { - bidder: 'bidderB', - maxBids: 2 - }]; - const expected = [{ - bidder: 'bidderA', - maxbids: 2 - }, { - bidder: 'bidderB', - maxbids: 2 - }]; - - config.setConfig({multibid: multibid}); - - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - - // should have the aliases object sent to PBS - expect(request.data.ext.prebid).to.haveOwnProperty('multibid'); - expect(request.data.ext.prebid.multibid).to.deep.equal(expected); - }); - - it('should pass client analytics to PBS endpoint if all modules included', function () { - createVideoBidderRequest(); - $$PREBID_GLOBAL$$.installedModules = []; - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let payload = request.data; - - expect(payload.ext.prebid.analytics).to.not.be.undefined; - 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 () { - createVideoBidderRequest(); - $$PREBID_GLOBAL$$.installedModules = ['rubiconBidAdapter', 'rubiconAnalyticsAdapter']; - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let payload = request.data; - - expect(payload.ext.prebid.analytics).to.not.be.undefined; - 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 () { - createVideoBidderRequest(); - $$PREBID_GLOBAL$$.installedModules = ['rubiconBidAdapter']; - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let payload = request.data; - - expect(payload.ext.prebid.analytics).to.be.undefined; - }); - - it('should send video exp param correctly when set', function () { - createVideoBidderRequest(); - config.setConfig({s2sConfig: {defaultTtl: 600}}); - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let post = request.data; - - // should exp set to the right value according to config - let imp = post.imp[0]; - expect(imp.exp).to.equal(600); - }); - - it('should not send video exp at all if not set in s2sConfig config', function () { - createVideoBidderRequest(); - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let post = request.data; - - // should exp set to the right value according to config - let imp = post.imp[0]; - // bidderFactory stringifies request body before sending so removes undefined attributes: - expect(imp.exp).to.equal(undefined); - }); - - it('should send tmax as the bidderRequest timeout value', function () { - createVideoBidderRequest(); - bidderRequest.timeout = 3333; - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let post = request.data; - expect(post.tmax).to.equal(3333); - }); - - it('should send correct bidfloor to PBS', function () { - createVideoBidderRequest(); - - bidderRequest.bids[0].params.floor = 0.1; - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(request.data.imp[0].bidfloor).to.equal(0.1); - - bidderRequest.bids[0].params.floor = 5.5; - [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(request.data.imp[0].bidfloor).to.equal(5.5); - - bidderRequest.bids[0].params.floor = '1.7'; - [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(request.data.imp[0].bidfloor).to.equal(1.7); - - bidderRequest.bids[0].params.floor = 0; - [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(request.data.imp[0].bidfloor).to.equal(0); - - bidderRequest.bids[0].params.floor = undefined; - [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(request.data.imp[0]).to.not.haveOwnProperty('bidfloor'); - - bidderRequest.bids[0].params.floor = null; - [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(request.data.imp[0]).to.not.haveOwnProperty('bidfloor'); - }); - - it('should send request with proper ad position', function () { - createVideoBidderRequest(); - let positionBidderRequest = utils.deepClone(bidderRequest); - positionBidderRequest.bids[0].mediaTypes.video.pos = 1; - let [request] = spec.buildRequests(positionBidderRequest.bids, positionBidderRequest); - expect(request.data.imp[0].video.pos).to.equal(1); - - positionBidderRequest = utils.deepClone(bidderRequest); - positionBidderRequest.bids[0].params.position = undefined; - positionBidderRequest.bids[0].mediaTypes.video.pos = undefined; - [request] = spec.buildRequests(positionBidderRequest.bids, positionBidderRequest); - expect(request.data.imp[0].video.pos).to.equal(undefined); - - positionBidderRequest = utils.deepClone(bidderRequest); - positionBidderRequest.bids[0].params.position = 'atf' - positionBidderRequest.bids[0].mediaTypes.video.pos = undefined; - [request] = spec.buildRequests(positionBidderRequest.bids, positionBidderRequest); - expect(request.data.imp[0].video.pos).to.equal(1); - - positionBidderRequest = utils.deepClone(bidderRequest); - positionBidderRequest.bids[0].params.position = 'btf'; - positionBidderRequest.bids[0].mediaTypes.video.pos = undefined; - [request] = spec.buildRequests(positionBidderRequest.bids, positionBidderRequest); - expect(request.data.imp[0].video.pos).to.equal(3); - - positionBidderRequest = utils.deepClone(bidderRequest); - positionBidderRequest.bids[0].params.position = 'foobar'; - positionBidderRequest.bids[0].mediaTypes.video.pos = undefined; - [request] = spec.buildRequests(positionBidderRequest.bids, positionBidderRequest); - expect(request.data.imp[0].video.pos).to.equal(undefined); - }); - - it('should properly enforce video.context to be either instream or outstream', function () { - let bid = bidderRequest.bids[0]; - bid.mediaTypes = { - video: { - context: 'instream', - mimes: ['video/mp4', 'video/x-ms-wmv'], - protocols: [2, 5], - maxduration: 30, - linearity: 1, - api: [2] - } - } - bid.params.video = {}; - - sandbox.stub(Date, 'now').callsFake(() => - bidderRequest.auctionStart + 100 - ); - - const bidRequestCopy = utils.deepClone(bidderRequest.bids[0]); - expect(spec.isBidRequestValid(bidRequestCopy)).to.equal(true); - - // change context to outstream, still true - bidRequestCopy.mediaTypes.video.context = 'outstream'; - expect(spec.isBidRequestValid(bidRequestCopy)).to.equal(true); - - // change context to random, false now - bidRequestCopy.mediaTypes.video.context = 'random'; - expect(spec.isBidRequestValid(bidRequestCopy)).to.equal(false); - - // change context to undefined, still false - bidRequestCopy.mediaTypes.video.context = undefined; - expect(spec.isBidRequestValid(bidRequestCopy)).to.equal(false); - - // remove context, still false - delete bidRequestCopy.mediaTypes.video.context; - expect(spec.isBidRequestValid(bidRequestCopy)).to.equal(false); - }); - - it('should enforce the new required mediaTypes.video params', function () { - createVideoBidderRequest(); - - sandbox.stub(Date, 'now').callsFake(() => - bidderRequest.auctionStart + 100 - ); - - expect(spec.isBidRequestValid(bidderRequest.bids[0])).to.equal(true); - - // change mimes to a non array, no good - createVideoBidderRequest(); - bidderRequest.bids[0].mediaTypes.video.mimes = 'video/mp4'; - expect(spec.isBidRequestValid(bidderRequest.bids[0])).to.equal(false); - - // delete mimes, no good - createVideoBidderRequest(); - delete bidderRequest.bids[0].mediaTypes.video.mimes; - expect(spec.isBidRequestValid(bidderRequest.bids[0])).to.equal(false); - - // change protocols to an int not array of ints, no good - createVideoBidderRequest(); - bidderRequest.bids[0].mediaTypes.video.protocols = 1; - expect(spec.isBidRequestValid(bidderRequest.bids[0])).to.equal(false); - - // delete protocols, no good - createVideoBidderRequest(); - delete bidderRequest.bids[0].mediaTypes.video.protocols; - expect(spec.isBidRequestValid(bidderRequest.bids[0])).to.equal(false); - - // change linearity to an string, no good - createVideoBidderRequest(); - bidderRequest.bids[0].mediaTypes.video.linearity = 'string'; - expect(spec.isBidRequestValid(bidderRequest.bids[0])).to.equal(false); - - // delete linearity, no good - createVideoBidderRequest(); - delete bidderRequest.bids[0].mediaTypes.video.linearity; - expect(spec.isBidRequestValid(bidderRequest.bids[0])).to.equal(false); - - // change api to an string, no good - createVideoBidderRequest(); - bidderRequest.bids[0].mediaTypes.video.api = 'string'; - expect(spec.isBidRequestValid(bidderRequest.bids[0])).to.equal(false); - - // delete api, no good - createVideoBidderRequest(); - delete bidderRequest.bids[0].mediaTypes.video.api; - expect(spec.isBidRequestValid(bidderRequest.bids[0])).to.equal(false); - }); - - it('bid request is valid when video context is outstream', function () { - createVideoBidderRequestOutstream(); - sandbox.stub(Date, 'now').callsFake(() => - bidderRequest.auctionStart + 100 - ); - - const bidRequestCopy = utils.deepClone(bidderRequest); - - let [request] = spec.buildRequests(bidRequestCopy.bids, bidRequestCopy); - expect(spec.isBidRequestValid(bidderRequest.bids[0])).to.equal(true); - expect(request.data.imp[0].ext.rubicon.video.size_id).to.equal(203); - }); - - it('should send banner request when outstream or instream video included but no rubicon video obect is present', function () { - // add banner and video mediaTypes - bidderRequest.mediaTypes = { - banner: { - sizes: [[300, 250]] - }, - video: { - context: 'outstream' - } - }; - // no video object in rubicon params, so we should see one call made for banner - - sandbox.stub(Date, 'now').callsFake(() => - bidderRequest.auctionStart + 100 - ); - - let requests = spec.buildRequests(bidderRequest.bids, bidderRequest); - - expect(requests.length).to.equal(1); - expect(requests[0].url).to.equal('https://fastlane.rubiconproject.com/a/api/fastlane.json'); - - bidderRequest.mediaTypes.video.context = 'instream'; - - requests = spec.buildRequests(bidderRequest.bids, bidderRequest); - - expect(requests.length).to.equal(1); - expect(requests[0].url).to.equal('https://fastlane.rubiconproject.com/a/api/fastlane.json'); - }); - - it('should send request as banner when invalid video bid in multiple mediaType bidRequest', function () { - createVideoBidderRequestNoVideo(); - - let bid = bidderRequest.bids[0]; - bid.mediaTypes.banner = { - sizes: [[300, 250]] - }; - - sandbox.stub(Date, 'now').callsFake(() => - bidderRequest.auctionStart + 100 - ); - - const bidRequestCopy = utils.deepClone(bidderRequest); - - let requests = spec.buildRequests(bidRequestCopy.bids, bidRequestCopy); - expect(requests.length).to.equal(1); - expect(requests[0].url).to.equal('https://fastlane.rubiconproject.com/a/api/fastlane.json'); - }); - - it('should include coppa flag in video bid request', () => { - createVideoBidderRequest(); - - sandbox.stub(Date, 'now').callsFake(() => - bidderRequest.auctionStart + 100 - ); - - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - 'coppa': true - }; - return config[key]; - }); - - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(request.data.regs.coppa).to.equal(1); - }); - - it('should include first party data', () => { - createVideoBidderRequest(); - - const site = { - ext: { - data: { - page: 'home' - } - }, - content: { - data: [{foo: 'bar'}] - }, - keywords: 'e,f', - rating: '4-star', - data: [{foo: 'bar'}] - }; - const user = { - ext: { - data: { - age: 31 - } - }, - keywords: 'd', - gender: 'M', - yob: '1984', - geo: {country: 'ca'}, - data: [{foo: 'bar'}] - }; - - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - ortb2: { - site, - user - } - }; - return utils.deepAccess(config, key); - }); - - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - - const expected = { - 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), - }; - - delete request.data.site.page; - delete request.data.site.content.language; - - expect(request.data.site.keywords).to.deep.equal('a,b,c'); - expect(request.data.user.keywords).to.deep.equal('d'); - expect(request.data.site.ext.data).to.deep.equal(expected.siteData); - expect(request.data.user.ext.data).to.deep.equal(expected.userData); - }); - - it('should include storedAuctionResponse in video bid request', function () { - createVideoBidderRequest(); - - sandbox.stub(Date, 'now').callsFake(() => - bidderRequest.auctionStart + 100 - ); - - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(request.data.imp).to.exist.and.to.be.a('array'); - expect(request.data.imp).to.have.lengthOf(1); - expect(request.data.imp[0].ext).to.exist.and.to.be.a('object'); - expect(request.data.imp[0].ext.prebid).to.exist.and.to.be.a('object'); - expect(request.data.imp[0].ext.prebid.storedauctionresponse).to.exist.and.to.be.a('object'); - expect(request.data.imp[0].ext.prebid.storedauctionresponse.id).to.equal('11111'); - }); - - it('should include pbadslot in bid request', function () { - createVideoBidderRequest(); - bidderRequest.bids[0].ortb2Imp = { - ext: { - data: { - pbadslot: '1234567890' - } - } - } - - sandbox.stub(Date, 'now').callsFake(() => - bidderRequest.auctionStart + 100 - ); - - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(request.data.imp[0].ext.data.pbadslot).to.equal('1234567890'); - }); - - it('should include GAM ad unit in bid request', function () { - createVideoBidderRequest(); - bidderRequest.bids[0].ortb2Imp = { - ext: { - data: { - adserver: { - adslot: '1234567890', - name: 'adServerName1' - } - } - } - }; - - sandbox.stub(Date, 'now').callsFake(() => - bidderRequest.auctionStart + 100 - ); - - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(request.data.imp[0].ext.data.adserver.adslot).to.equal('1234567890'); - expect(request.data.imp[0].ext.data.adserver.name).to.equal('adServerName1'); - }); - - it('should use the integration type provided in the config instead of the default', () => { - createVideoBidderRequest(); - 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', function () { - config.setConfig({user: {id: '123'}}); - createVideoBidderRequest(); - - sandbox.stub(Date, 'now').callsFake(() => - bidderRequest.auctionStart + 100 - ); - - let [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let post = request.data; - - expect(post).to.have.property('imp') - // .with.length.of(1); - let imp = post.imp[0]; - expect(imp.id).to.equal(bidderRequest.bids[0].adUnitCode); - expect(imp.exp).to.equal(undefined); - expect(imp.video.w).to.equal(640); - expect(imp.video.h).to.equal(480); - expect(imp.video.pos).to.equal(1); - expect(imp.video.context).to.equal('instream'); - expect(imp.video.minduration).to.equal(15); - expect(imp.video.maxduration).to.equal(30); - expect(imp.video.startdelay).to.equal(0); - expect(imp.video.skip).to.equal(1); - expect(imp.video.skipafter).to.equal(15); - expect(imp.ext.rubicon.video.playerWidth).to.equal(640); - expect(imp.ext.rubicon.video.playerHeight).to.equal(480); - expect(imp.ext.rubicon.video.size_id).to.equal(201); - expect(imp.ext.rubicon.video.language).to.equal('en'); - // Also want it to be in post.site.content.language - expect(post.site.content.language).to.equal('en'); - expect(imp.ext.rubicon.video.skip).to.equal(1); - expect(imp.ext.rubicon.video.skipafter).to.equal(15); - expect(imp.ext.prebid.auctiontimestamp).to.equal(1472239426000); - expect(post.user.ext.consent).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A=='); - - // Config user.id - expect(post.user.id).to.equal('123'); - - expect(post.regs.ext.gdpr).to.equal(1); - expect(post.regs.ext.us_privacy).to.equal('1NYN'); - expect(post).to.have.property('ext').that.is.an('object'); - expect(post.ext.prebid.targeting.includewinners).to.equal(true); - expect(post.ext.prebid).to.have.property('cache').that.is.an('object'); - expect(post.ext.prebid.cache).to.have.property('vastxml').that.is.an('object'); - expect(post.ext.prebid.cache.vastxml).to.have.property('returnCreative').that.is.an('boolean'); - expect(post.ext.prebid.cache.vastxml.returnCreative).to.equal(false); - expect(post.ext.prebid.bidders.rubicon.integration).to.equal(PBS_INTEGRATION); - }) - }); - - describe('combineSlotUrlParams', 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({ - 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: ''}, {}])).to.deep.equal({p1: ';;foo;', p2: ''}); - - 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'}); - - 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;;'}); - }); - }); - - describe('createSlotParams', function () { - it('should return a valid slot params object', function () { - let expectedQuery = { - 'account_id': '14062', - 'site_id': '70608', - 'zone_id': '335918', - 'size_id': 15, - 'alt_size_ids': '43', - 'p_pos': 'atf', - 'rp_secure': /[01]/, - 'tk_flint': INTEGRATION, - 'x_source.tid': 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b', - 'p_screen_res': /\d+x\d+/, - 'tk_user_key': '12346', - 'kw': 'a,b,c', - 'tg_v.ucat': 'new', - 'tg_v.lastsearch': 'iphone', - 'tg_v.likes': 'sports,video games', - 'tg_i.rating': '5-star', - 'tg_i.prodtype': 'tech,mobile', - 'tg_fl.eid': 'div-1', - 'rf': 'localhost' - }; - - const slotParams = spec.createSlotParams(bidderRequest.bids[0], bidderRequest); - - // test that all values above are both present and correct - Object.keys(expectedQuery).forEach(key => { - const value = expectedQuery[key]; - if (value instanceof RegExp) { - expect(slotParams[key]).to.match(value); - } else { - expect(slotParams[key]).to.equal(value); - } - }); - }); - - it('should not fail if keywords param is not an array', function () { - bidderRequest.bids[0].params.keywords = 'a,b,c'; - const slotParams = spec.createSlotParams(bidderRequest.bids[0], bidderRequest); - expect(slotParams.kw).to.equal('a,b,c'); - }); - }); - - describe('hasVideoMediaType', function () { - it('should return true if mediaType is video and size_id is set', function () { - createVideoBidderRequest(); - const legacyVideoTypeBidRequest = hasVideoMediaType(bidderRequest.bids[0]); - expect(legacyVideoTypeBidRequest).is.equal(true); - }); - - it('should return false if trying to use legacy mediaType with video', function () { - createVideoBidderRequest(); - delete bidderRequest.bids[0].mediaTypes; - bidderRequest.bids[0].mediaType = 'video'; - const legacyVideoTypeBidRequest = hasVideoMediaType(bidderRequest.bids[0]); - expect(legacyVideoTypeBidRequest).is.equal(false); - }); - - it('should return false if bidRequest.mediaType is not equal to video', function () { - expect(hasVideoMediaType({ - mediaType: 'banner' - })).is.equal(false); - }); - - it('should return false if bidRequest.mediaType is not defined', function () { - expect(hasVideoMediaType({})).is.equal(false); - }); - - it('should return true if bidRequest.mediaTypes.video.context is instream and size_id is defined', function () { - expect(hasVideoMediaType({ - mediaTypes: { - video: { - context: 'instream' - } - }, - params: { - video: { - size_id: 7 - } - } - })).is.equal(true); - }); - - it('should return false if bidRequest.mediaTypes.video.context is instream but size_id is not defined', function () { - expect(spec.isBidRequestValid({ - mediaTypes: { - video: { - context: 'instream' - } - }, - params: { - video: {} - } - })).is.equal(false); - }); - }); - }); - - describe('interpretResponse', function () { - describe('for fastlane', function () { - it('should handle a success response and sort by cpm', function () { - let response = { - 'status': 'ok', - 'account_id': 14062, - 'site_id': 70608, - 'zone_id': 530022, - 'size_id': 15, - 'alt_size_ids': [ - 43 - ], - 'tracking': '', - 'inventory': {}, - 'ads': [ - { - 'status': 'ok', - 'impression_id': '153dc240-8229-4604-b8f5-256933b9374c', - 'size_id': '15', - 'ad_id': '6', - 'adomain': ['test.com'], - 'advertiser': 7, - 'network': 8, - 'creative_id': 'crid-9', - 'type': 'script', - 'script': 'alert(\'foo\')', - 'campaign_id': 10, - 'cpm': 0.811, - 'targeting': [ - { - 'key': 'rpfl_14062', - 'values': [ - '15_tier_all_test' - ] - } - ] - }, - { - 'status': 'ok', - 'impression_id': '153dc240-8229-4604-b8f5-256933b9374d', - 'size_id': '43', - 'ad_id': '7', - 'adomain': ['test.com'], - 'advertiser': 7, - 'network': 8, - 'creative_id': 'crid-9', - 'type': 'script', - 'script': 'alert(\'foo\')', - 'campaign_id': 10, - 'cpm': 0.911, - 'targeting': [ - { - 'key': 'rpfl_14062', - 'values': [ - '43_tier_all_test' - ] - } - ] - } - ] - }; - - let bids = spec.interpretResponse({body: response}, { - bidRequest: bidderRequest.bids[0] - }); - - expect(bids).to.be.lengthOf(2); - - expect(bids[0].width).to.equal(320); - expect(bids[0].height).to.equal(50); - expect(bids[0].cpm).to.equal(0.911); - expect(bids[0].ttl).to.equal(300); - expect(bids[0].netRevenue).to.equal(true); - expect(bids[0].rubicon.advertiserId).to.equal(7); - expect(bids[0].rubicon.networkId).to.equal(8); - expect(bids[0].creativeId).to.equal('crid-9'); - expect(bids[0].currency).to.equal('USD'); - expect(bids[0].meta.mediaType).to.equal('banner'); - expect(String(bids[0].meta.advertiserDomains)).to.equal('test.com'); - expect(bids[0].ad).to.contain(`alert('foo')`) - .and.to.contain(``) - .and.to.contain(`
`); - expect(bids[0].rubiconTargeting.rpfl_elemid).to.equal('/19968336/header-bid-tag-0'); - expect(bids[0].rubiconTargeting.rpfl_14062).to.equal('43_tier_all_test'); - - expect(bids[1].width).to.equal(300); - expect(bids[1].height).to.equal(250); - expect(bids[1].cpm).to.equal(0.811); - expect(bids[1].ttl).to.equal(300); - expect(bids[1].netRevenue).to.equal(true); - expect(bids[1].rubicon.advertiserId).to.equal(7); - expect(bids[1].rubicon.networkId).to.equal(8); - expect(bids[1].creativeId).to.equal('crid-9'); - expect(bids[1].currency).to.equal('USD'); - expect(bids[1].ad).to.contain(`alert('foo')`) - .and.to.contain(``) - .and.to.contain(`
`); - expect(bids[1].rubiconTargeting.rpfl_elemid).to.equal('/19968336/header-bid-tag-0'); - expect(bids[1].rubiconTargeting.rpfl_14062).to.equal('15_tier_all_test'); - }); - - it('should pass netRevenue correctly if set in setConfig', function () { - let response = { - 'status': 'ok', - 'account_id': 14062, - 'site_id': 70608, - 'zone_id': 530022, - 'size_id': 15, - 'alt_size_ids': [ - 43 - ], - 'tracking': '', - 'inventory': {}, - 'ads': [ - { - 'status': 'ok', - 'impression_id': '153dc240-8229-4604-b8f5-256933b9374c', - 'size_id': '15', - 'ad_id': '6', - 'advertiser': 7, - 'network': 8, - 'creative_id': 'crid-9', - 'type': 'script', - 'script': 'alert(\'foo\')', - 'campaign_id': 10, - 'cpm': 0.811, - 'targeting': [ - { - 'key': 'rpfl_14062', - 'values': [ - '15_tier_all_test' - ] - } - ] - }, - { - 'status': 'ok', - 'impression_id': '153dc240-8229-4604-b8f5-256933b9374d', - 'size_id': '43', - 'ad_id': '7', - 'advertiser': 7, - 'network': 8, - 'creative_id': 'crid-9', - 'type': 'script', - 'script': 'alert(\'foo\')', - 'campaign_id': 10, - 'cpm': 0.911, - 'targeting': [ - { - 'key': 'rpfl_14062', - 'values': [ - '43_tier_all_test' - ] - } - ] - } - ] - }; - - // Set to false => false - config.setConfig({ - rubicon: { - netRevenue: false - } - }); - let bids = spec.interpretResponse({body: response}, { - bidRequest: bidderRequest.bids[0] - }); - expect(bids).to.be.lengthOf(2); - expect(bids[0].netRevenue).to.equal(false); - expect(bids[1].netRevenue).to.equal(false); - - // Set to true => true - config.setConfig({ - rubicon: { - netRevenue: true - } - }); - bids = spec.interpretResponse({body: response}, { - bidRequest: bidderRequest.bids[0] - }); - expect(bids).to.be.lengthOf(2); - expect(bids[0].netRevenue).to.equal(true); - expect(bids[1].netRevenue).to.equal(true); - - // Set to undefined => true - config.setConfig({ - rubicon: { - netRevenue: undefined - } - }); - bids = spec.interpretResponse({body: response}, { - bidRequest: bidderRequest.bids[0] - }); - expect(bids).to.be.lengthOf(2); - expect(bids[0].netRevenue).to.equal(true); - expect(bids[1].netRevenue).to.equal(true); - - // Set to string => true - config.setConfig({ - rubicon: { - netRevenue: 'someString' - } - }); - bids = spec.interpretResponse({body: response}, { - bidRequest: bidderRequest.bids[0] - }); - expect(bids).to.be.lengthOf(2); - expect(bids[0].netRevenue).to.equal(true); - expect(bids[1].netRevenue).to.equal(true); - - config.resetConfig(); - }); - it('should use "network-advertiser" if no creative_id', function () { - let response = { - 'status': 'ok', - 'account_id': 14062, - 'site_id': 70608, - 'zone_id': 530022, - 'size_id': 15, - 'alt_size_ids': [ - 43, 10, 2 - ], - 'tracking': '', - 'inventory': {} - }; - - response.ads = [ - { - 'status': 'ok', - 'impression_id': '153dc240-8229-4604-b8f5-256933b9374c', - 'size_id': '15', - 'ad_id': '6', - 'advertiser': 7, - 'network': 8, - 'type': 'script', - 'script': 'alert(\'foo\')', - 'campaign_id': 10, - 'cpm': 0.811, - 'targeting': [ - { - 'key': 'rpfl_14062', - 'values': [ - '15_tier_all_test' - ] - } - ] - } - ]; - - let bids = spec.interpretResponse({body: response}, { - bidRequest: bidderRequest.bids[0] - }); - expect(bids[0].creativeId).to.equal('8-7'); - - response.ads = [ - { - 'status': 'ok', - 'impression_id': '153dc240-8229-4604-b8f5-256933b9374d', - 'size_id': '43', - 'ad_id': '7', - 'type': 'script', - 'script': 'alert(\'foo\')', - 'campaign_id': 10, - 'cpm': 0.911, - 'targeting': [ - { - 'key': 'rpfl_14062', - 'values': [ - '43_tier_all_test' - ] - } - ] - } - ]; - - bids = spec.interpretResponse({body: response}, { - bidRequest: bidderRequest.bids[0] - }); - expect(bids[0].creativeId).to.equal('-'); - - response.ads = [ - { - 'status': 'ok', - 'impression_id': '153dc240-8229-4604-b8f5-256933b9374d', - 'size_id': '10', - 'ad_id': '7', - 'network': 8, - 'type': 'script', - 'script': 'alert(\'foo\')', - 'campaign_id': 10, - 'cpm': 0.911, - 'targeting': [ - { - 'key': 'rpfl_14062', - 'values': [ - '10_tier_all_test' - ] - } - ] - } - ]; - - bids = spec.interpretResponse({body: response}, { - bidRequest: bidderRequest.bids[0] - }); - expect(bids[0].creativeId).to.equal('8-'); - - response.ads = [ - { - 'status': 'ok', - 'impression_id': '153dc240-8229-4604-b8f5-256933b9374d', - 'size_id': '2', - 'ad_id': '7', - 'advertiser': 7, - 'type': 'script', - 'script': 'alert(\'foo\')', - 'campaign_id': 10, - 'cpm': 0.911, - 'targeting': [ - { - 'key': 'rpfl_14062', - 'values': [ - '2_tier_all_test' - ] - } - ] - } - ]; - - bids = spec.interpretResponse({body: response}, { - bidRequest: bidderRequest.bids[0] - }); - expect(bids[0].creativeId).to.equal('-7'); - }); - - it('should be fine with a CPM of 0', function () { - let response = { - 'status': 'ok', - 'account_id': 14062, - 'site_id': 70608, - 'zone_id': 530022, - 'size_id': 15, - 'alt_size_ids': [ - 43 - ], - 'tracking': '', - 'inventory': {}, - 'ads': [{ - 'status': 'ok', - 'cpm': 0, - 'size_id': 15 - }] - }; - - let bids = spec.interpretResponse({body: response}, { - bidRequest: bidderRequest.bids[0] - }); - - expect(bids).to.be.lengthOf(1); - expect(bids[0].cpm).to.be.equal(0); - }); - - it('should create bids with matching requestIds if imp id matches', function () { - let bidRequests = [{ - 'bidder': 'rubicon', - 'params': { - 'accountId': 1001, - 'siteId': 12345, - 'zoneId': 67890, - 'floor': null - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': '404a7b28-f276-41cc-a5cf-c1d3dc5671f9', - 'sizes': [[300, 250]], - 'bidId': '557ba307cef098', - 'bidderRequestId': '46a00704ffeb7', - 'auctionId': '3fdc6494-da94-44a0-a292-b55a90b08b2c', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0, - 'startTime': 1615412098213 - }, { - 'bidder': 'rubicon', - 'params': { - 'accountId': 1001, - 'siteId': 12345, - 'zoneId': 67890, - 'floor': null - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-1', - 'transactionId': '404a7b28-f276-41cc-a5cf-c1d3dc5671f9', - 'sizes': [[300, 250]], - 'bidId': '456gt123jkl098', - 'bidderRequestId': '46a00704ffeb7', - 'auctionId': '3fdc6494-da94-44a0-a292-b55a90b08b2c', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0, - 'startTime': 1615412098213 - }]; - - let response = { - 'status': 'ok', - 'account_id': 14062, - 'site_id': 70608, - 'zone_id': 530022, - 'size_id': 15, - 'alt_size_ids': [ - 43 - ], - 'tracking': '', - 'inventory': {}, - 'ads': [ - { - 'status': 'ok', - 'impression_id': '153dc240-8229-4604-b8f5-256933b9374c', - 'size_id': '15', - 'ad_id': '6', - 'advertiser': 7, - 'network': 8, - 'creative_id': 'crid-9', - 'type': 'script', - 'script': 'alert(\'foo\')', - 'campaign_id': 10, - 'cpm': 0.811, - 'targeting': [ - { - 'key': 'rpfl_14062', - 'values': [ - '15_tier_all_test' - ] - } - ] - }, - { - 'status': 'ok', - 'impression_id': '153dc240-8229-4604-b8f5-256933b9374c', - 'size_id': '15', - 'ad_id': '7', - 'advertiser': 7, - 'network': 8, - 'creative_id': 'crid-9', - 'type': 'script', - 'script': 'alert(\'foo\')', - 'campaign_id': 10, - 'cpm': 0.911, - 'targeting': [ - { - 'key': 'rpfl_14062', - 'values': [ - '43_tier_all_test' - ] - } - ] - }, - { - 'status': 'ok', - 'impression_id': '153dc240-8229-4604-b8f5-256933b9374d', - 'size_id': '43', - 'ad_id': '7', - 'advertiser': 7, - 'network': 8, - 'creative_id': 'crid-9', - 'type': 'script', - 'script': 'alert(\'foo\')', - 'campaign_id': 10, - 'cpm': 1.911, - 'targeting': [ - { - 'key': 'rpfl_14062', - 'values': [ - '43_tier_all_test' - ] - } - ] - } - ] - }; - - config.setConfig({ multibid: [{bidder: 'rubicon', maxbids: 2, targetbiddercodeprefix: 'rubi'}] }); - - let bids = spec.interpretResponse({body: response}, { - bidRequest: bidRequests - }); - - expect(bids).to.be.lengthOf(3); - expect(bids[0].requestId).to.not.equal(bids[1].requestId); - expect(bids[1].requestId).to.equal(bids[2].requestId); - }); - - it('should handle an error with no ads returned', function () { - let response = { - 'status': 'ok', - 'account_id': 14062, - 'site_id': 70608, - 'zone_id': 530022, - 'size_id': 15, - 'alt_size_ids': [ - 43 - ], - 'tracking': '', - 'inventory': {}, - 'ads': [] - }; - - let bids = spec.interpretResponse({body: response}, { - bidRequest: bidderRequest.bids[0] - }); - - expect(bids).to.be.lengthOf(0); - }); - - it('should handle an error', function () { - let response = { - 'status': 'ok', - 'account_id': 14062, - 'site_id': 70608, - 'zone_id': 530022, - 'size_id': 15, - 'alt_size_ids': [ - 43 - ], - 'tracking': '', - 'inventory': {}, - 'ads': [{ - 'status': 'not_ok', - }] - }; - - let bids = spec.interpretResponse({body: response}, { - bidRequest: bidderRequest.bids[0] - }); - - expect(bids).to.be.lengthOf(0); - }); - - it('should handle an error because of malformed json response', function () { - let response = '{test{'; - - let bids = spec.interpretResponse({body: response}, { - bidRequest: bidderRequest.bids[0] - }); - - expect(bids).to.be.lengthOf(0); - }); - - it('should handle a bidRequest argument of type Array', function () { - let response = { - 'status': 'ok', - 'account_id': 14062, - 'site_id': 70608, - 'zone_id': 530022, - 'size_id': 15, - 'alt_size_ids': [ - 43 - ], - 'tracking': '', - 'inventory': {}, - 'ads': [{ - 'status': 'ok', - 'cpm': 0, - 'size_id': 15 - }] - }; - - let bids = spec.interpretResponse({body: response}, { - bidRequest: [utils.deepClone(bidderRequest.bids[0])] - }); - - expect(bids).to.be.lengthOf(1); - expect(bids[0].cpm).to.be.equal(0); - }); - - describe('singleRequest enabled', function () { - it('handles bidRequest of type Array and returns associated adUnits', function () { - const overrideMap = []; - overrideMap[0] = {impression_id: '1'}; - - const stubAds = []; - for (let i = 0; i < 10; i++) { - stubAds.push(createResponseAdByIndex(i, sizeMap[i].sizeId, overrideMap)); - } - - const stubBids = []; - for (let i = 0; i < 10; i++) { - stubBids.push(createBidRequestByIndex(i, sizeMap[i].sizeAsArray.slice())); - } - - const bids = spec.interpretResponse({ - body: { - 'status': 'ok', - 'site_id': '1100', - 'account_id': 14062, - 'zone_id': 2100, - 'size_id': '1', - 'tracking': '', - 'inventory': {}, - 'ads': stubAds - } - }, {bidRequest: stubBids}); - expect(bids).to.be.a('array').with.lengthOf(10); - - bids.forEach((bid) => { - expect(bid).to.be.a('object'); - expect(bid).to.have.property('cpm').that.is.a('number'); - expect(bid).to.have.property('width').that.is.a('number'); - expect(bid).to.have.property('height').that.is.a('number'); - - // verify that result bid 'sizeId' links to a size from the sizeMap - const size = getSizeIdForBid(sizeMap, bid); - expect(size).to.be.a('object'); - - // use 'size' to verify that result bid links to the 'response.ad' passed to function - const associateAd = getResponseAdBySize(stubAds, size); - expect(associateAd).to.be.a('object'); - expect(associateAd).to.have.property('creative_id').that.is.a('string'); - - // use 'size' to verify that result bid links to the 'bidRequest' passed to function - const associateBidRequest = getBidRequestBySize(stubBids, size); - expect(associateBidRequest).to.be.a('object'); - expect(associateBidRequest).to.have.property('bidId').that.is.a('string'); - - // verify all bid properties set using 'ad' and 'bidRequest' match - // 'ad.creative_id === bid.creativeId' - expect(bid.requestId).to.equal(associateBidRequest.bidId); - // 'bid.requestId === bidRequest.bidId' - expect(bid.creativeId).to.equal(associateAd.creative_id); - }); - }); - - it('handles incorrect adUnits length by returning all bids with matching ads', function () { - const overrideMap = []; - overrideMap[0] = {impression_id: '1'}; - - const stubAds = []; - for (let i = 0; i < 6; i++) { - stubAds.push(createResponseAdByIndex(i, sizeMap[i].sizeId, overrideMap)); - } - - const stubBids = []; - for (let i = 0; i < 10; i++) { - stubBids.push(createBidRequestByIndex(i, sizeMap[i].sizeAsArray.slice())); - } - - const bids = spec.interpretResponse({ - body: { - 'status': 'ok', - 'site_id': '1100', - 'account_id': 14062, - 'zone_id': 2100, - 'size_id': '1', - 'tracking': '', - 'inventory': {}, - 'ads': stubAds - } - }, {bidRequest: stubBids}); - - // no bids expected because response didn't match requested bid number - expect(bids).to.be.a('array').with.lengthOf(6); - }); - - it('skips adUnits with error status and returns all bids with ok status', function () { - const stubAds = []; - // 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'}; - - for (let i = 0; i < 10; i++) { - stubAds.push(createResponseAdByIndex(i, sizeMap[i].sizeId, overrideMap)); - } - - const stubBids = []; - for (let i = 0; i < 10; i++) { - stubBids.push(createBidRequestByIndex(i, sizeMap[i].sizeAsArray.slice())); - } - - const bids = spec.interpretResponse({ - body: { - 'status': 'error', - 'site_id': '1100', - 'account_id': 14062, - 'zone_id': 2100, - 'size_id': '1', - 'tracking': '', - 'inventory': {}, - 'ads': stubAds - } - }, {bidRequest: stubBids}); - expect(bids).to.be.a('array').with.lengthOf(6); - - bids.forEach((bid) => { - expect(bid).to.be.a('object'); - expect(bid).to.have.property('cpm').that.is.a('number'); - expect(bid).to.have.property('width').that.is.a('number'); - expect(bid).to.have.property('height').that.is.a('number'); - - // verify that result bid 'sizeId' links to a size from the sizeMap - const size = getSizeIdForBid(sizeMap, bid); - expect(size).to.be.a('object'); - - // use 'size' to verify that result bid links to the 'response.ad' passed to function - const associateAd = getResponseAdBySize(stubAds, size); - expect(associateAd).to.be.a('object'); - expect(associateAd).to.have.property('creative_id').that.is.a('string'); - expect(associateAd).to.have.property('status').that.is.a('string'); - expect(associateAd.status).to.equal('ok'); - - // use 'size' to verify that result bid links to the 'bidRequest' passed to function - const associateBidRequest = getBidRequestBySize(stubBids, size); - expect(associateBidRequest).to.be.a('object'); - expect(associateBidRequest).to.have.property('bidId').that.is.a('string'); - - // verify all bid properties set using 'ad' and 'bidRequest' match - // 'ad.creative_id === bid.creativeId' - expect(bid.requestId).to.equal(associateBidRequest.bidId); - // 'bid.requestId === bidRequest.bidId' - expect(bid.creativeId).to.equal(associateAd.creative_id); - }); - }); - }); - }); - - describe('for video', function () { - beforeEach(function () { - createVideoBidderRequest(); - }); - - it('should register a successful bid', function () { - let response = { - cur: 'USD', - seatbid: [{ - bid: [{ - id: '0', - impid: 'instream_video1', - adomain: ['test.com'], - price: 2, - crid: '4259970', - ext: { - bidder: { - rp: { - mime: 'application/javascript', - size_id: 201, - advid: 12345 - } - }, - prebid: { - targeting: { - hb_uuid: '0c498f63-5111-4bed-98e2-9be7cb932a64' - }, - type: 'video' - } - } - }], - group: 0, - seat: 'rubicon' - }], - }; - - let bids = spec.interpretResponse({body: response}, { - bidRequest: bidderRequest.bids[0] - }); - - expect(bids).to.be.lengthOf(1); - - expect(bids[0].seatBidId).to.equal('0'); - expect(bids[0].creativeId).to.equal('4259970'); - expect(bids[0].cpm).to.equal(2); - expect(bids[0].ttl).to.equal(300); - expect(bids[0].netRevenue).to.equal(true); - 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'); - expect(bids[0].meta.advertiserId).to.equal(12345); - expect(bids[0].bidderCode).to.equal('rubicon'); - expect(bids[0].currency).to.equal('USD'); - expect(bids[0].width).to.equal(640); - expect(bids[0].height).to.equal(480); - }); - }); - - describe('for outstream video', function () { - const sandbox = sinon.createSandbox(); - beforeEach(function () { - createVideoBidderRequestOutstream(); - config.setConfig({rubicon: { - rendererConfig: { - align: 'left', - closeButton: true - }, - rendererUrl: 'https://example.test/renderer.js' - }}); - window.MagniteApex = { - renderAd: function() { - return null; - } - } - }); - - afterEach(function () { - sandbox.restore(); - delete window.MagniteApex; - }); - - it('should register a successful bid', function () { - let response = { - cur: 'USD', - seatbid: [{ - bid: [{ - id: '0', - impid: 'outstream_video1', - adomain: ['test.com'], - price: 2, - crid: '4259970', - ext: { - bidder: { - rp: { - mime: 'application/javascript', - size_id: 201, - advid: 12345 - } - }, - prebid: { - targeting: { - hb_uuid: '0c498f63-5111-4bed-98e2-9be7cb932a64' - }, - type: 'video' - } - } - }], - group: 0, - seat: 'rubicon' - }], - }; - - let bids = spec.interpretResponse({body: response}, { - bidRequest: bidderRequest.bids[0] - }); - - expect(bids).to.be.lengthOf(1); - - expect(bids[0].seatBidId).to.equal('0'); - expect(bids[0].creativeId).to.equal('4259970'); - expect(bids[0].cpm).to.equal(2); - expect(bids[0].ttl).to.equal(300); - expect(bids[0].netRevenue).to.equal(true); - 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'); - expect(bids[0].meta.advertiserId).to.equal(12345); - expect(bids[0].bidderCode).to.equal('rubicon'); - expect(bids[0].currency).to.equal('USD'); - expect(bids[0].width).to.equal(640); - expect(bids[0].height).to.equal(320); - // check custom renderer - expect(typeof bids[0].renderer).to.equal('object'); - expect(bids[0].renderer.getConfig()).to.deep.equal({ - align: 'left', - closeButton: true - }); - expect(bids[0].renderer.url).to.equal('https://example.test/renderer.js'); - }); - - it('should render ad with Magnite renderer', function () { - let response = { - cur: 'USD', - seatbid: [{ - bid: [{ - id: '0', - impid: 'outstream_video1', - adomain: ['test.com'], - price: 2, - crid: '4259970', - ext: { - bidder: { - rp: { - mime: 'application/javascript', - size_id: 201, - advid: 12345 - } - }, - prebid: { - targeting: { - hb_uuid: '0c498f63-5111-4bed-98e2-9be7cb932a64' - }, - type: 'video' - } - }, - nurl: 'https://test.com/vast.xml' - }], - group: 0, - seat: 'rubicon' - }], - }; - - sinon.spy(window.MagniteApex, 'renderAd'); - - let bids = spec.interpretResponse({body: response}, { - bidRequest: bidderRequest.bids[0] - }); - const bid = bids[0]; - bid.adUnitCode = 'outstream_video1_placement'; - const adUnit = document.createElement('div'); - adUnit.id = bid.adUnitCode; - document.body.appendChild(adUnit); - - bid.renderer.render(bid); - - const renderCall = window.MagniteApex.renderAd.getCall(0); - expect(renderCall.args[0]).to.deep.equal({ - closeButton: true, - collapse: true, - height: 320, - label: undefined, - placement: { - align: 'left', - attachTo: '#outstream_video1_placement', - position: 'append', - }, - vastUrl: 'https://test.com/vast.xml', - width: 640 - }); - // cleanup - adUnit.remove(); - }); - }); - - 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'}}); - const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(parseQuery(request.data).tk_flint).to.equal('testType_v$prebid.version$'); - }); - }); - }); - }); - - describe('user sync', function () { - const emilyUrl = 'https://eus.rubiconproject.com/usync.html'; - - beforeEach(function () { - resetUserSync(); - }); - - it('should register the Emily iframe', function () { - let syncs = spec.getUserSyncs({ - iframeEnabled: true - }); - - expect(syncs).to.deep.equal({type: 'iframe', url: emilyUrl}); - }); - - it('should not register the Emily iframe more than once', function () { - let syncs = spec.getUserSyncs({ - iframeEnabled: true - }); - expect(syncs).to.deep.equal({type: 'iframe', url: emilyUrl}); - - // when called again, should still have only been called once - syncs = spec.getUserSyncs(); - expect(syncs).to.equal(undefined); - }); - - it('should pass gdpr params if consent is true', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, { - gdprApplies: true, consentString: 'foo' - })).to.deep.equal({ - type: 'iframe', url: `${emilyUrl}?gdpr=1&gdpr_consent=foo` - }); - }); - - it('should pass gdpr params if consent is false', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, { - gdprApplies: false, consentString: 'foo' - })).to.deep.equal({ - type: 'iframe', url: `${emilyUrl}?gdpr=0&gdpr_consent=foo` - }); - }); - - it('should pass gdpr param gdpr_consent only when gdprApplies is undefined', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, { - consentString: 'foo' - })).to.deep.equal({ - type: 'iframe', url: `${emilyUrl}?gdpr_consent=foo` - }); - }); - - it('should pass no params if gdpr consentString is not defined', function () { - 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}, {}, { - consentString: 0 - })).to.deep.equal({ - type: 'iframe', url: `${emilyUrl}` - }); - }); - - it('should pass no params if gdpr consentString is null', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, { - consentString: null - })).to.deep.equal({ - type: 'iframe', url: `${emilyUrl}` - }); - }); - - it('should pass no params if gdpr consentString is a object', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, { - consentString: {} - })).to.deep.equal({ - type: 'iframe', url: `${emilyUrl}` - }); - }); - - it('should pass no params if gdpr is not defined', function () { - 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({ - type: 'iframe', url: `${emilyUrl}?us_privacy=1NYN` - }); - }); - - it('should pass us_privacy after gdpr if both are present', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, { - consentString: 'foo' - }, '1NYN')).to.deep.equal({ - type: 'iframe', url: `${emilyUrl}?gdpr_consent=foo&us_privacy=1NYN` - }); - }); - }); - - 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 mockConfig = { - priceGranularity: undefined, - customPriceBucket: { - buckets: [CUSTOM_PRICE_BUCKET_ITEM] - } - }; - sandbox.stub(config, 'getConfig').callsFake(key => { - return mockConfig[key]; - }); - - [ - {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; - const result = getPriceGranularity(config); - expect(typeof result).to.equal('object'); - expect(result).to.haveOwnProperty('ranges'); - expect(Array.isArray(result.ranges)).to.equal(true); - expect(result.ranges.length).to.be.greaterThan(0) - expect(result.ranges[0]).to.deep.equal(kvPair.val); - }); - }); - }); - - describe('Supply Chain Support', function () { - const nodePropsOrder = ['asi', 'sid', 'hp', 'rid', 'name', 'domain']; - let bidRequests; - let schainConfig; - - const getSupplyChainConfig = () => { - return { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'rubicon.com', - sid: '1234', - hp: 1, - rid: 'bid-request-1', - name: 'pub one', - domain: 'pub1.com' - }, - { - asi: 'theexchange.com', - sid: '5678', - hp: 1, - rid: 'bid-request-2', - name: 'pub two', - domain: 'pub2.com' - }, - { - asi: 'wesellads.com', - sid: '9876', - hp: 1, - rid: 'bid-request-3', - // name: 'alladsallthetime', - domain: 'alladsallthetime.com' - } - ] - }; - }; - - beforeEach(() => { - bidRequests = getBidderRequest(); - schainConfig = getSupplyChainConfig(); - bidRequests.bids[0].schain = schainConfig; - }); - - it('should properly serialize schain object with correct delimiters', () => { - const results = spec.buildRequests(bidRequests.bids, bidRequests); - const numNodes = schainConfig.nodes.length; - const schain = parseQuery(results[0].data).rp_schain; - - // each node serialization should start with an ! - expect(schain.match(/!/g).length).to.equal(numNodes); - - // 5 commas per node plus 1 for version - expect(schain.match(/,/g).length).to.equal(numNodes * 5 + 1); - }); - - it('should send the proper version for the schain', () => { - const results = spec.buildRequests(bidRequests.bids, bidRequests); - const schain = parseQuery(results[0].data).rp_schain.split('!'); - const version = schain.shift().split(',')[0]; - expect(version).to.equal(bidRequests.bids[0].schain.ver); - }); - - it('should send the correct value for complete in schain', () => { - const results = spec.buildRequests(bidRequests.bids, bidRequests); - const schain = parseQuery(results[0].data).rp_schain.split('!'); - const complete = schain.shift().split(',')[1]; - expect(complete).to.equal(String(bidRequests.bids[0].schain.complete)); - }); - - it('should send available params in the right order', () => { - const results = spec.buildRequests(bidRequests.bids, bidRequests); - const schain = parseQuery(results[0].data).rp_schain.split('!'); - schain.shift(); - - schain.forEach((serializeNode, nodeIndex) => { - const nodeProps = serializeNode.split(','); - nodeProps.forEach((nodeProp, propIndex) => { - const node = schainConfig.nodes[nodeIndex]; - const key = nodePropsOrder[propIndex]; - expect(nodeProp).to.equal(node[key] ? String(node[key]) : ''); - }); - }); - }); - - it('should copy the schain JSON to to bid.source.ext.schain', () => { - createVideoBidderRequest(); - const schain = getSupplyChainConfig(); - bidderRequest.bids[0].schain = schain; - const request = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(request[0].data.source.ext.schain).to.deep.equal(schain); - }); - }); - - describe('configurable settings', function() { - afterEach(() => { - config.setConfig({ - rubicon: { - bannerHost: 'rubicon', - videoHost: 'prebid-server', - syncHost: 'eus', - returnVast: false - } - }); - config.resetConfig(); - }); - - beforeEach(function () { - resetUserSync(); - }); - - it('should update fastlane endpoint if', function () { - config.setConfig({ - rubicon: { - bannerHost: 'fastlane-qa', - videoHost: 'prebid-server-qa', - syncHost: 'eus-qa', - returnVast: true - } - }); - - // banner - let [bannerRequest] = spec.buildRequests(bidderRequest.bids, bidderRequest); - expect(bannerRequest.url).to.equal('https://fastlane-qa.rubiconproject.com/a/api/fastlane.json'); - - // video and returnVast - createVideoBidderRequest(); - let [videoRequest] = spec.buildRequests(bidderRequest.bids, bidderRequest); - let post = videoRequest.data; - expect(videoRequest.url).to.equal('https://prebid-server-qa.rubiconproject.com/openrtb2/auction'); - expect(post.ext.prebid.cache.vastxml).to.have.property('returnCreative').that.is.an('boolean'); - expect(post.ext.prebid.cache.vastxml.returnCreative).to.equal(true); - - // user sync - let syncs = spec.getUserSyncs({ - iframeEnabled: true - }); - expect(syncs).to.deep.equal({type: 'iframe', url: 'https://eus-qa.rubiconproject.com/usync.html'}); - }); - }); -}); diff --git a/test/spec/modules/s2sTesting_spec.js b/test/spec/modules/s2sTesting_spec.js deleted file mode 100644 index 273f6747e52..00000000000 --- a/test/spec/modules/s2sTesting_spec.js +++ /dev/null @@ -1,333 +0,0 @@ -import s2sTesting from 'modules/s2sTesting.js'; - -var expect = require('chai').expect; - -describe('s2sTesting', function () { - describe('s2sTesting.getSource', function () { - // helper function to set random number and get the source - function getExpectedSource(randNumber, sourceWeights, sources) { - // set random number for testing - s2sTesting.globalRand = randNumber; - return s2sTesting.getSource(sourceWeights, sources); - } - - it('returns undefined if no sources', function () { - expect(getExpectedSource(0, {})).to.be.undefined; - expect(getExpectedSource(0.5, {})).to.be.undefined; - expect(getExpectedSource(0.9999, {})).to.be.undefined; - }); - - 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; - }); - - 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'); - }); - - 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'); - 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'); - }); - - 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'); - }); - - 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'); - }); - - 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'); - }); - - 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'); - }); - }); - - describe('s2sTesting.getSourceBidderMap', function () { - describe('setting source through s2sConfig', function () { - beforeEach(function () { - // set random number for testing - s2sTesting.globalRand = 0.7; - s2sTesting.bidSource = {}; - }); - - it('sets one client bidder', function () { - const s2sConfig = { - bidders: ['rubicon'], - bidderControl: {rubicon: {bidSource: {server: 1, client: 1}}} - }; - - s2sTesting.calculateBidSources(s2sConfig); - expect(s2sTesting.getSourceBidderMap()).to.eql({ - server: [], - client: ['rubicon'] - }); - }); - - it('sets one server bidder', function () { - const s2sConfig = { - bidders: ['rubicon'], - bidderControl: {rubicon: {bidSource: {server: 4, client: 1}}} - } - s2sTesting.calculateBidSources(s2sConfig); - expect(s2sTesting.getSourceBidderMap()).to.eql({ - server: ['rubicon'], - client: [] - }); - }); - - it('defaults to server', function () { - const s2sConfig = { - bidders: ['rubicon'], - } - s2sTesting.calculateBidSources(s2sConfig); - expect(s2sTesting.getSourceBidderMap()).to.eql({ - server: ['rubicon'], - client: [] - }); - }); - - it('sets two bidders', function () { - const s2sConfig = { - bidders: ['rubicon', 'appnexus'], - bidderControl: { - rubicon: {bidSource: {server: 3, client: 1}}, - appnexus: {bidSource: {server: 1, client: 1}} - } - } - s2sTesting.calculateBidSources(s2sConfig); - var serverClientBidders = s2sTesting.getSourceBidderMap(); - expect(serverClientBidders.server).to.eql(['rubicon']); - expect(serverClientBidders.client).to.have.members(['appnexus']); - }); - - it('sends both bidders to same source when weights are the same', function () { - s2sTesting.globalRand = 0.01; - - const s2sConfig = { - bidders: ['rubicon', 'appnexus'], - bidderControl: { - rubicon: {bidSource: {server: 1, client: 99}}, - appnexus: {bidSource: {server: 1, client: 99}} - } - } - s2sTesting.calculateBidSources(s2sConfig); - expect(s2sTesting.getSourceBidderMap()).to.eql({ - client: ['rubicon', 'appnexus'], - server: [] - }); - s2sTesting.calculateBidSources(s2sConfig); - expect(s2sTesting.getSourceBidderMap()).to.eql({ - client: ['rubicon', 'appnexus'], - server: [] - }); - s2sTesting.calculateBidSources(s2sConfig); - expect(s2sTesting.getSourceBidderMap()).to.eql({ - client: ['rubicon', 'appnexus'], - server: [] - }); - - const s2sConfig2 = { - bidders: ['rubicon', 'appnexus'], - bidderControl: { - rubicon: {bidSource: {server: 99, client: 1}}, - appnexus: {bidSource: {server: 99, client: 1}} - } - } - s2sTesting.calculateBidSources(s2sConfig2); - expect(s2sTesting.getSourceBidderMap()).to.eql({ - server: ['rubicon', 'appnexus'], - client: [] - }); - expect(s2sTesting.getSourceBidderMap()).to.eql({ - server: ['rubicon', 'appnexus'], - client: [] - }); - expect(s2sTesting.getSourceBidderMap()).to.eql({ - server: ['rubicon', 'appnexus'], - client: [] - }); - }); - }); - - describe('setting source through adUnits', function () { - const s2sConfig3 = {testing: true}; - - beforeEach(function () { - // set random number for testing - s2sTesting.globalRand = 0.7; - s2sTesting.bidSource = {}; - }); - - it('sets one bidder source from one adUnit', function () { - var adUnits = [ - {bids: [ - {bidder: 'rubicon', bidSource: {server: 4, client: 1}} - ]} - ]; - - expect(s2sTesting.getSourceBidderMap(adUnits, [])).to.eql({ - server: ['rubicon'], - client: [] - }); - // should have saved the source on the bid - expect(adUnits[0].bids[0].calcSource).to.equal('server'); - expect(adUnits[0].bids[0].finalSource).to.equal('server'); - - adUnits = [ - {bids: [ - {bidder: 'rubicon', bidSource: {server: 1, client: 1}} - ]} - ]; - expect(s2sTesting.getSourceBidderMap(adUnits, [])).to.eql({ - server: [], - client: ['rubicon'] - }); - // should have saved the source on the bid - expect(adUnits[0].bids[0].calcSource).to.equal('client'); - expect(adUnits[0].bids[0].finalSource).to.equal('client'); - }); - - it('defaults to client if no bidSource', function () { - var adUnits = [ - {bids: [ - {bidder: 'rubicon', bidSource: {}} - ]} - ]; - expect(s2sTesting.getSourceBidderMap(adUnits, [])).to.eql({ - server: [], - client: ['rubicon'] - }); - // should have saved the source on the bid - expect(adUnits[0].bids[0].calcSource).to.be.undefined; - expect(adUnits[0].bids[0].finalSource).to.equal('client'); - }); - - 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}} - ]} - ]; - var serverClientBidders = s2sTesting.getSourceBidderMap(adUnits, []); - expect(serverClientBidders.server).to.eql(['appnexus']); - expect(serverClientBidders.client).to.have.members(['rubicon']); - // should have saved the source on the bid - expect(adUnits[0].bids[0].calcSource).to.equal('client'); - expect(adUnits[0].bids[0].finalSource).to.equal('client'); - expect(adUnits[0].bids[1].calcSource).to.equal('server'); - expect(adUnits[0].bids[1].finalSource).to.equal('server'); - }); - - 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}} - ]} - ]; - var serverClientBidders = s2sTesting.getSourceBidderMap(adUnits, []); - expect(serverClientBidders.server).to.have.members(['rubicon']); - expect(serverClientBidders.server).to.not.have.members(['appnexus', 'bidder3']); - expect(serverClientBidders.client).to.have.members(['rubicon', 'appnexus', 'bidder3']); - // should have saved the source on the bid - expect(adUnits[0].bids[0].calcSource).to.equal('client'); - expect(adUnits[0].bids[0].finalSource).to.equal('client'); - expect(adUnits[0].bids[1].calcSource).to.equal('client'); - expect(adUnits[0].bids[1].finalSource).to.equal('client'); - expect(adUnits[1].bids[0].calcSource).to.equal('server'); - expect(adUnits[1].bids[0].finalSource).to.equal('server'); - expect(adUnits[1].bids[1].calcSource).to.equal('client'); - expect(adUnits[1].bids[1].finalSource).to.equal('client'); - }); - - 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}} - ]} - ]; - var serverClientBidders = s2sTesting.getSourceBidderMap(adUnits, []); - - expect(serverClientBidders.server).to.have.members(['appnexus', 'bidder3']); - expect(serverClientBidders.server).to.not.have.members(['rubicon']); - expect(serverClientBidders.client).to.have.members(['rubicon']); - expect(serverClientBidders.client).to.not.have.members(['appnexus', 'bidder3']); - // should have saved the source on the bid - expect(adUnits[0].bids[0].calcSource).to.equal('client'); - expect(adUnits[0].bids[0].finalSource).to.equal('client'); - expect(adUnits[0].bids[1].calcSource).to.equal('server'); - expect(adUnits[0].bids[1].finalSource).to.equal('server'); - expect(adUnits[0].bids[2].calcSource).to.equal('server'); - expect(adUnits[0].bids[2].finalSource).to.equal('server'); - }); - }); - - describe('setting source through s2sconfig and adUnits', function () { - beforeEach(function () { - // set random number for testing - s2sTesting.globalRand = 0.7; - }); - - 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}} - ]} - ]; - - // set rubicon: client and appnexus: server - const s2sConfig = { - bidders: ['rubicon', 'appnexus'], - testing: true, - bidderControl: { - rubicon: {bidSource: {server: 2, client: 1}}, - appnexus: {bidSource: {server: 1}} - } - } - s2sTesting.calculateBidSources(s2sConfig); - var serverClientBidders = s2sTesting.getSourceBidderMap(adUnits); - expect(serverClientBidders.server).to.have.members(['rubicon', 'appnexus']); - expect(serverClientBidders.client).to.have.members(['rubicon', 'appnexus']); - }); - }); - }); -}); diff --git a/test/spec/modules/saambaaBidAdapter_spec.js b/test/spec/modules/saambaaBidAdapter_spec.js deleted file mode 100755 index 80a85ae895d..00000000000 --- a/test/spec/modules/saambaaBidAdapter_spec.js +++ /dev/null @@ -1,139 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/saambaaBidAdapter.js'; -import { BANNER, VIDEO } from 'src/mediaTypes.js'; - -describe('saambaaBidAdapter', function () { - let bidRequests; - let bidRequestsVid; - - beforeEach(function () { - bidRequests = [{'bidder': 'saambaa', 'params': {'pubid': '121ab139faf7ac67428a23f1d0a9a71b', 'floor': 0.5, 'placement': 1234, size: '320x250'}, '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': 'saambaa', 'params': {'pubid': '121ab139faf7ac67428a23f1d0a9a71b', 'floor': 1.0, 'placement': 1234, size: '320x480', 'video': {'id': 123, 'skip': 1, 'mimes': ['video/mp4', 'application/javascript'], 'playbackmethod': [2, 6], 'maxduration': 30}}, 'crumbs': {'pubcid': '979fde13-c71e-4ac2-98b7-28c90f99b449'}, 'mediaTypes': {'video': {'playerSize': [[320, 480]], 'context': 'instream'}}, '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 () { - it('should return true when the required params are passed for banner', function () { - const bidRequest = bidRequests[0]; - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }); - - it('should return true when the required params are passed for video', function () { - const bidRequests = bidRequestsVid[0]; - expect(spec.isBidRequestValid(bidRequests)).to.equal(true); - }); - - it('should return false when no pub id params are passed', function () { - const bidRequest = bidRequests[0]; - bidRequest.params.pubid = ''; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when no placement params are passed', function () { - const bidRequest = bidRequests[0]; - bidRequest.params.placement = ''; - expect(spec.isBidRequestValid(bidRequest)).to.equal(false); - }); - - it('should return false when a bid request is not passed', function () { - expect(spec.isBidRequestValid()).to.equal(false); - expect(spec.isBidRequestValid({})).to.equal(false); - }); - }); - - describe('spec.buildRequests', function () { - it('should create a POST request for each bid', function () { - const bidRequest = bidRequests[0]; - const requests = spec.buildRequests([ bidRequest ]); - 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 ]); - expect(requests[0].method).to.equal('POST'); - }); - - it('should have domain in request', function () { - const bidRequest = bidRequests[0]; - const requests = spec.buildRequests([ bidRequest ]); - expect(requests[0].data.site.domain).length !== 0; - }); - }); - - describe('spec.interpretResponse', function () { - describe('for banner bids', function () { - it('should return no bids if the response is not valid', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { banner: {} }; - const bidResponse = spec.interpretResponse({ body: null }, { bidRequest }); - - if (typeof bidResponse !== 'undefined') { - expect(bidResponse.length).to.equal(0); - } else { - expect(true).to.equal(true); - } - }); - - it('should return no bids if the response is empty', function () { - const bidRequest = bidRequests[0]; - bidRequest.mediaTypes = { banner: {} }; - const bidResponse = spec.interpretResponse({ body: [] }, { bidRequest }); - if (typeof bidResponse !== 'undefined') { - expect(bidResponse.length).to.equal(0); - } else { expect(true).to.equal(true); } - }); - - it('should return valid video bid responses', function () { - let _mediaTypes = VIDEO; - const saambaabidreqVid = {'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 }, saambaabidreqVid); - delete bidResponseVid['vastUrl']; - delete bidResponseVid['ad']; - expect(bidResponseVid).to.deep.equal({ - requestId: bidRequestsVid[0].bidId, - bidderCode: 'saambaa', - creativeId: serverResponseVid.seatbid[0].bid[0].crid, - cpm: serverResponseVid.seatbid[0].bid[0].price, - width: serverResponseVid.seatbid[0].bid[0].w, - height: serverResponseVid.seatbid[0].bid[0].h, - mediaType: 'video', - meta: { advertiserDomains: serverResponseVid.seatbid[0].bid[0].adomain }, - currency: 'USD', - netRevenue: true, - ttl: 60 - }); - }); - - it('should return valid banner bid responses', function () { - const saambaabidreq = {bids: {}}; - bidRequests.forEach(bid => { - let _mediaTypes = (bid.mediaTypes && bid.mediaTypes.video ? VIDEO : BANNER); - saambaabidreq.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': '
', 'adomain': ['advertiserdomain.com'], 'iurl': '', 'cid': 'campaign1', 'crid': 'abcde-12345', 'w': 300, 'h': 250}], 'seat': '19513bcfca8006'}], 'bidid': '19513bcfca8006', 'cur': 'USD', 'w': 300, 'h': 250}; - - const bidResponse = spec.interpretResponse({ body: serverResponse }, saambaabidreq); - expect(bidResponse).to.deep.equal({ - requestId: bidRequests[0].bidId, - ad: serverResponse.seatbid[0].bid[0].adm, - bidderCode: 'saambaa', - creativeId: serverResponse.seatbid[0].bid[0].crid, - cpm: serverResponse.seatbid[0].bid[0].price, - width: serverResponse.seatbid[0].bid[0].w, - height: serverResponse.seatbid[0].bid[0].h, - mediaType: 'banner', - meta: { advertiserDomains: serverResponse.seatbid[0].bid[0].adomain }, - currency: 'USD', - netRevenue: true, - ttl: 60 - }); - }); - }); - }); -}); diff --git a/test/spec/modules/scaleableAnalyticsAdapter_spec.js b/test/spec/modules/scaleableAnalyticsAdapter_spec.js deleted file mode 100644 index 70b94a2b807..00000000000 --- a/test/spec/modules/scaleableAnalyticsAdapter_spec.js +++ /dev/null @@ -1,165 +0,0 @@ -import scaleableAnalytics from 'modules/scaleableAnalyticsAdapter.js'; -import { expect } from 'chai'; -import events from 'src/events.js'; -import CONSTANTS from 'src/constants.json'; -import { server } from 'test/mocks/xhr.js'; - -const BID_TIMEOUT = CONSTANTS.EVENTS.BID_TIMEOUT; -const AUCTION_INIT = CONSTANTS.EVENTS.AUCTION_INIT; -const BID_WON = CONSTANTS.EVENTS.BID_WON; -const AUCTION_END = CONSTANTS.EVENTS.AUCTION_END; - -describe('Scaleable Analytics Adapter', function() { - const bidsReceivedObj = { - adUnitCode: '12345', - bidderCode: 'test-code', - cpm: 3.14, - currency: 'USD', - dealId: null, - mediaType: 'banner', - timeToRespond: 285, - size: '300x250' - }; - - const MOCK_DATA = { - adUnitCode: '12345', - auctionEnd: { - bidsReceived: [bidsReceivedObj] - }, - bidderRequests: [{ - bids: [{ - adUnitCode: '12345', - bidder: 'test-code', - params: { - test: 'value' - } - }] - }], - site: '5c4fab7a829e955d6c265e72', - bidResponse: { - adUnitCode: '12345', - bidderCode: 'test-code', - cpm: 3.14, - timeToRespond: 285, - params: [{ - test: 'value' - }] - }, - bidTimeout: [ - { - adUnitCode: '67890', - bidder: 'test-code' - } - ] - }; - - const bidObj = MOCK_DATA.bidderRequests[0].bids[0]; - - const expectedBidRequests = [{bidder: 'scaleable_adunit_request'}].concat([ - { - bidder: bidObj.bidder, - params: bidObj.params - } - ]); - - MOCK_DATA.expectedRequestResponse = { - event: 'request', - site: MOCK_DATA.site, - adunits: [{ - code: bidObj.adUnitCode, - bidRequests: expectedBidRequests - }] - } - - MOCK_DATA.expectedBidTimeout = { - [MOCK_DATA.bidTimeout[0].adUnitCode]: [{ - timeouts: 1, - bidder: MOCK_DATA.bidTimeout[0].bidder - }] - }; - - MOCK_DATA.expectedAuctionEndResponse = { - event: 'bids', - site: MOCK_DATA.site, - adunits: [{ - code: MOCK_DATA.auctionEnd.bidsReceived[0].adUnitCode, - bidData: [{ - bidder: bidsReceivedObj.bidderCode, - cpm: bidsReceivedObj.cpm, - currency: bidsReceivedObj.currency, - dealId: bidsReceivedObj.dealId, - type: bidsReceivedObj.mediaType, - ttr: bidsReceivedObj.timeToRespond, - size: bidsReceivedObj.size - }] - }, - { - bidData: MOCK_DATA.expectedBidTimeout[MOCK_DATA.bidTimeout[0].adUnitCode], - code: MOCK_DATA.bidTimeout[0].adUnitCode - }] - } - - describe('Event Handling', function() { - beforeEach(function() { - sinon.stub(events, 'getEvents').returns([]); - - scaleableAnalytics.enableAnalytics({ - provider: 'scaleable', - options: { - site: MOCK_DATA.site - } - }); - }); - - afterEach(function() { - events.getEvents.restore(); - scaleableAnalytics.disableAnalytics(); - }); - - it('should handle the auction init event', function(done) { - events.emit(AUCTION_INIT, { - adUnitCodes: [MOCK_DATA.adUnitCode], - bidderRequests: MOCK_DATA.bidderRequests - }); - - const result = JSON.parse(server.requests[0].requestBody); - expect(result).to.deep.equal(MOCK_DATA.expectedRequestResponse); - - done(); - }); - - it('should handle the bid timeout event', function() { - events.emit(BID_TIMEOUT, MOCK_DATA.bidTimeout); - - const actual = scaleableAnalytics.getAuctionData(); - - expect(actual).to.deep.equal(MOCK_DATA.expectedBidTimeout); - }); - - it('should handle the bid won event', function(done) { - events.emit(BID_WON, MOCK_DATA.bidResponse); - - const result = JSON.parse(server.requests[0].requestBody); - expect(result).to.deep.equal({ - adunit: MOCK_DATA.adUnitCode, - code: MOCK_DATA.bidResponse.bidderCode, - cpm: MOCK_DATA.bidResponse.cpm, - ttr: MOCK_DATA.bidResponse.timeToRespond, - params: MOCK_DATA.bidResponse.params, - event: 'win', - site: MOCK_DATA.site - }); - - done(); - }); - - it('should handle the auction end event', function(done) { - events.emit(AUCTION_END, MOCK_DATA.auctionEnd); - - const result = JSON.parse(server.requests[0].requestBody); - expect(result).to.deep.equal(MOCK_DATA.expectedAuctionEndResponse); - - done(); - }); - }); -}); diff --git a/test/spec/modules/schain_spec.js b/test/spec/modules/schain_spec.js deleted file mode 100644 index 34d0cff9a60..00000000000 --- a/test/spec/modules/schain_spec.js +++ /dev/null @@ -1,487 +0,0 @@ -import { isValidSchainConfig, isSchainObjectValid, makeBidRequestsHook } from '../../../modules/schain.js'; -import { deepClone } from '../../../src/utils.js'; -import {config} from '../../../src/config.js'; -import { expect } from 'chai'; - -describe('#isValidSchainConfig: module config validation', function() { - it('if config is undefined or not an objct then return false', function() { - expect(isValidSchainConfig()).to.false; - expect(isValidSchainConfig('')).to.false; - expect(isValidSchainConfig([])).to.false; - expect(isValidSchainConfig(12)).to.false; - expect(isValidSchainConfig(3.14)).to.false; - }) - - it('if config is an object then return true', function() { - expect(isValidSchainConfig({})).to.true; - }) -}); - -describe('#isSchainObjectValid: schain object validation', function() { - let schainConfig; - - beforeEach(function() { - schainConfig = { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'indirectseller.com', - 'sid': '00001', - 'hp': 1 - }, - - { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 2 - } - ] - }; - }); - - it('Return true for correct config', function() { - expect(isSchainObjectValid(schainConfig, true)).to.true; - }); - - it('Return false for string config', function() { - schainConfig = JSON.stringify(schainConfig); - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if complete param is not an Integer', function() { - schainConfig.complete = 1; // integer - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.complete = '1'; // string - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.complete = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.complete = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.complete; // undefined - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.complete = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.complete = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if version param is not a String', function() { - schainConfig.ver = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.ver = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.ver = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.ver; // undefined - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.ver = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.ver = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if ext param is not an Object', function() { - schainConfig.ext = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.ext = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.ext = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.true; - delete schainConfig.ext; // undefined // param is optional thus this will result true - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.ext = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.ext = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if nodes param is not an Array', function() { - // by default schainConfig.nodes is array - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.nodes = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.nodes; // undefined - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if nodes[].asi is not a String', function() { - schainConfig.nodes[0].asi = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].asi = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].asi = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.nodes[0].asi; // undefined - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].asi = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].asi = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if nodes[].sid is not a String', function() { - schainConfig.nodes[1].sid = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].sid = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].sid = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.nodes[0].sid; // undefined - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].sid = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].sid = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if nodes[].hp is not an Integer', function() { - schainConfig.nodes[0].hp = '1'; // string - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].hp = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].hp = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.nodes[0].hp; // undefined - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].hp = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].hp = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if nodes[].rid is not a String', function() { - schainConfig.nodes[1].rid = 'rid value'; // string - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.nodes[1].rid = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].rid = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].rid = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.nodes[1].rid; // undefined // param is optional thus this will result true - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.nodes[1].rid = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].rid = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if nodes[].name is not a String', function() { - schainConfig.nodes[0].name = 'name value'; // string - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.nodes[0].name = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].name = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].name = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.nodes[0].name; // undefined // param is optional thus this will result true - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.nodes[0].name = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].name = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if nodes[].domain is not a String', function() { - schainConfig.nodes[1].domain = 'domain value'; // string - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.nodes[1].domain = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].domain = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].domain = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.false; - delete schainConfig.nodes[1].domain; // undefined // param is optional thus this will result true - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.nodes[1].domain = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[1].domain = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Returns false if nodes[].ext param is not an Object', function() { - schainConfig.nodes[0].ext = 1; // Integer - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].ext = 1.1; // float - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].ext = {}; // object - expect(isSchainObjectValid(schainConfig, true)).to.true; - delete schainConfig.nodes[0].ext; // undefined // param is optional thus this will result true - expect(isSchainObjectValid(schainConfig, true)).to.true; - schainConfig.nodes[0].ext = true; // boolean - expect(isSchainObjectValid(schainConfig, true)).to.false; - schainConfig.nodes[0].ext = []; // array - expect(isSchainObjectValid(schainConfig, true)).to.false; - }); - - it('Relaxed mode: Returns true even for invalid config if second argument is set to false', function() { - schainConfig = { - 'ver': 1.0, // invalid - 'complete': '1', // invalid - 'nodes': [ - { - 'asi': 'indirectseller.com', - 'sid': 1, // invalid - 'hp': '1' // invalid - }, - - { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 2 - } - ] - }; - expect(isSchainObjectValid(schainConfig, false)).to.true; - - schainConfig = {}; - expect(isSchainObjectValid(schainConfig, false)).to.true; - }) -}); - -describe('#makeBidRequestsHook', function() { - const bidderRequests = [ - { - 'bidderCode': 'rubicon', - 'bids': [ - { - 'bidder': 'rubicon', - 'params': { - 'accountId': 14062, - 'siteId': 70608, - 'zoneId': 498816 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '2e6d166eb869c3' - - } - ], - }, - { - 'bidderCode': 'districtm', - 'bids': [ - { - 'bidder': 'districtm', - 'params': { - 'placementId': 13144370 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '41cdeddf7b6905' - } - ], - }, - { - 'bidderCode': 'appnexus', - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 - }, - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '626cc7f1c4ccfc' - } - ], - - } - ]; - - const globalSchainConfig = { - 'schain': { - 'validation': 'off', - 'config': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'indirectseller.com', - 'sid': '00001', - 'hp': 1 - }, - - { - 'asi': 'indirectseller-2.com', - 'sid': '00002', - 'hp': 1 - } - ] - } - } - }; - - const goodStrictBidderConfig = { - bidders: ['appnexus'], - config: { - 'schain': { - 'validation': 'strict', - 'config': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'myoverride1.com', - 'sid': '00001', - 'hp': 1, - 'name': 'node1' - }, - { - 'asi': 'myoverride2.com', - 'sid': '00001', - 'hp': 1, - 'name': 'node2' - } - ] - } - } - } - } - - const badStrictBidderConfig = { - bidders: ['appnexus'], - config: { - 'schain': { - 'validation': 'strict', - 'config': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'myoverride1.com', - 'sid': 1, - 'hp': 1, - 'name': 342 - }, - { - 'asi': 'myoverride2.com', - 'sid': 2, - 'hp': 1, - 'name': '342' - } - ] - } - } - } - }; - - const goodRelaxedBidderConfig = { - bidders: ['districtm'], - config: { - 'schain': { - 'validation': 'relaxed', - 'config': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'myoverride.com', - 'sid': '00001', - 'hp': 1, - 'name': 'goodConfig' - } - ] - } - } - } - }; - - const badRelaxedBidderConfig = { - bidders: ['districtm'], - config: { - 'schain': { - 'validation': 'relaxed', - 'config': { - 'ver': 1, - 'complete': 1, - 'nodes': [ - { - 'asi': 'myoverride.com', - 'sid': 1, - 'hp': 1 - } - ] - } - } - } - }; - - beforeEach(function () { - config.setConfig(globalSchainConfig); - }); - - afterEach(function () { - config.resetConfig(); - - config.setBidderConfig({ - bidders: ['districtm'], - config: { - schain: null - } - }); - - config.setBidderConfig({ - bidders: ['appnexus'], - config: { - schain: null - } - }); - }); - - it('should properly read from bidder schain + global schain configs', function() { - function testCallback(bidderRequests) { - expect(bidderRequests[0].bids[0].schain).to.exist; - expect(bidderRequests[0].bids[0].schain).to.deep.equal(globalSchainConfig.schain.config); - expect(bidderRequests[1].bids[0].schain).to.exist; - expect(bidderRequests[1].bids[0].schain).to.deep.equal(goodRelaxedBidderConfig.config.schain.config); - expect(bidderRequests[2].bids[0].schain).to.exist; - expect(bidderRequests[2].bids[0].schain).to.deep.equal(goodStrictBidderConfig.config.schain.config); - } - - const testBidderRequests = deepClone(bidderRequests); - config.setBidderConfig(goodStrictBidderConfig); - config.setBidderConfig(goodRelaxedBidderConfig); - - makeBidRequestsHook(testCallback, testBidderRequests); - }); - - it('should reject bad strict config but allow a bad relaxed config for bidders trying to override it', function () { - function testCallback(bidderRequests) { - expect(bidderRequests[0].bids[0].schain).to.exist; - expect(bidderRequests[0].bids[0].schain).to.deep.equal(globalSchainConfig.schain.config); - expect(bidderRequests[1].bids[0].schain).to.exist; - expect(bidderRequests[1].bids[0].schain).to.deep.equal(badRelaxedBidderConfig.config.schain.config); - expect(bidderRequests[2].bids[0].schain).to.be.undefined; - } - - const testBidderRequests = deepClone(bidderRequests); - config.setBidderConfig(badStrictBidderConfig); - config.setBidderConfig(badRelaxedBidderConfig); - - makeBidRequestsHook(testCallback, testBidderRequests); - }); -}); diff --git a/test/spec/modules/seedingAllianceAdapter_spec.js b/test/spec/modules/seedingAllianceAdapter_spec.js deleted file mode 100755 index 81af9546ff0..00000000000 --- a/test/spec/modules/seedingAllianceAdapter_spec.js +++ /dev/null @@ -1,186 +0,0 @@ -// jshint esversion: 6, es3: false, node: true -import {assert, expect} from 'chai'; -import {spec} from 'modules/seedingAllianceBidAdapter.js'; -import { NATIVE } from 'src/mediaTypes.js'; -import { config } from 'src/config.js'; - -describe('SeedingAlliance adapter', function () { - let serverResponse, bidRequest, bidResponses; - let bid = { - 'bidder': 'seedingAlliance', - 'params': { - 'adUnitId': '1hq8' - } - }; - - describe('isBidRequestValid', function () { - it('should return true when required params found', function () { - assert(spec.isBidRequestValid(bid)); - }); - - it('should return false when AdUnitId is not set', function () { - delete bid.params.adUnitId; - assert.isFalse(spec.isBidRequestValid(bid)); - }); - }); - - describe('buildRequests', function () { - it('should send request with correct structure', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: {} - }]; - - let request = spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }); - - assert.equal(request.method, 'POST'); - assert.ok(request.data); - }); - - it('should have default request structure', function () { - let keys = 'site,device,cur,imp,user,regs'.split(','); - let validBidRequests = [{ - bidId: 'bidId', - params: {} - }]; - let request = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data); - let data = Object.keys(request); - - assert.deepEqual(keys, data); - }); - - it('Verify the auction ID', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: {}, - auctionId: 'auctionId' - }]; - let request = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' }, auctionId: validBidRequests[0].auctionId }).data); - - assert.equal(request.id, validBidRequests[0].auctionId); - }); - - it('Verify the device', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: {} - }]; - let request = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data); - - assert.equal(request.device.ua, navigator.userAgent); - }); - - it('Verify native asset ids', function () { - let validBidRequests = [{ - bidId: 'bidId', - params: {}, - nativeParams: { - body: { - required: true, - len: 350 - }, - image: { - required: true - }, - title: { - required: true - }, - sponsoredBy: { - required: true - }, - cta: { - required: true - }, - icon: { - required: true - } - } - }]; - - let assets = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { referer: 'page' } }).data).imp[0].native.request.assets; - - assert.equal(assets[0].id, 1); - assert.equal(assets[1].id, 3); - assert.equal(assets[2].id, 0); - assert.equal(assets[3].id, 2); - assert.equal(assets[4].id, 4); - assert.equal(assets[5].id, 5); - }); - }); - - describe('interpretResponse', function () { - const goodResponse = { - body: { - cur: 'EUR', - id: '4b516b80-886e-4ec0-82ae-9209e6d625fb', - seatbid: [ - { - seat: 'seedingAlliance', - bid: [{ - adm: { - native: { - assets: [ - {id: 0, title: {text: 'this is a title'}} - ], - imptrackers: ['https://domain.for/imp/tracker?price=${AUCTION_PRICE}'], - link: { - clicktrackers: ['https://domain.for/imp/tracker?price=${AUCTION_PRICE}'], - url: 'https://domain.for/ad/' - } - } - }, - impid: 1, - price: 0.55 - }] - } - ] - } - }; - const badResponse = { body: { - cur: 'EUR', - id: '4b516b80-886e-4ec0-82ae-9209e6d625fb', - seatbid: [] - }}; - - const bidRequest = { - data: {}, - bids: [{ bidId: 'bidId1' }] - }; - - it('should return null if body is missing or empty', function () { - const result = spec.interpretResponse(badResponse, bidRequest); - assert.equal(result.length, 0); - - delete badResponse.body - - const result1 = spec.interpretResponse(badResponse, bidRequest); - assert.equal(result.length, 0); - }); - - it('should return the correct params', function () { - const result = spec.interpretResponse(goodResponse, bidRequest); - const bid = goodResponse.body.seatbid[0].bid[0]; - - assert.deepEqual(result[0].currency, goodResponse.body.cur); - assert.deepEqual(result[0].requestId, bidRequest.bids[0].bidId); - assert.deepEqual(result[0].cpm, bid.price); - assert.deepEqual(result[0].creativeId, bid.crid); - assert.deepEqual(result[0].mediaType, 'native'); - assert.deepEqual(result[0].bidderCode, 'seedingAlliance'); - }); - - it('should return the correct tracking links', function () { - const result = spec.interpretResponse(goodResponse, bidRequest); - const bid = goodResponse.body.seatbid[0].bid[0]; - const regExpPrice = new RegExp('price=' + bid.price); - - result[0].native.clickTrackers.forEach(function (clickTracker) { - assert.ok(clickTracker.search(regExpPrice) > -1); - }); - - result[0].native.impressionTrackers.forEach(function (impTracker) { - assert.ok(impTracker.search(regExpPrice) > -1); - }); - }); - }); -}); diff --git a/test/spec/modules/seedtagBidAdapter_spec.js b/test/spec/modules/seedtagBidAdapter_spec.js deleted file mode 100644 index c82c8300d2e..00000000000 --- a/test/spec/modules/seedtagBidAdapter_spec.js +++ /dev/null @@ -1,471 +0,0 @@ -import { expect } from 'chai' -import { spec, getTimeoutUrl } from 'modules/seedtagBidAdapter.js' -import * as utils from 'src/utils.js' - -const PUBLISHER_ID = '0000-0000-01' -const ADUNIT_ID = '000000' - -function getSlotConfigs(mediaTypes, params) { - return { - params: params, - sizes: [[300, 250], [300, 600]], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - bidRequestsCount: 1, - bidder: 'seedtag', - mediaTypes: mediaTypes, - src: 'client', - transactionId: 'd704d006-0d6e-4a09-ad6c-179e7e758096' - } -} - -function createVideoSlotConfig(mediaType) { - return getSlotConfigs(mediaType, { - publisherId: PUBLISHER_ID, - adUnitId: ADUNIT_ID, - placement: 'video' - }) -} - -describe('Seedtag Adapter', function() { - describe('isBidRequestValid method', function() { - describe('returns true', function() { - describe('when banner slot config has all mandatory params', () => { - describe('and placement has the correct value', function() { - const createBannerSlotConfig = placement => { - return getSlotConfigs( - { banner: {} }, - { - publisherId: PUBLISHER_ID, - adUnitId: ADUNIT_ID, - placement - } - ) - } - const placements = ['banner', 'video', 'inImage', 'inScreen', 'inArticle'] - placements.forEach(placement => { - it('should be ' + placement, function() { - const isBidRequestValid = spec.isBidRequestValid( - createBannerSlotConfig(placement) - ) - expect(isBidRequestValid).to.equal(true) - }) - }) - }) - }) - describe('when video slot has all mandatory params', function() { - it('should return true, when video mediatype object are correct.', function() { - const slotConfig = getSlotConfigs( - { - video: { - context: 'instream', - playerSize: [[600, 200]] - } - }, - { - publisherId: PUBLISHER_ID, - adUnitId: ADUNIT_ID, - placement: 'video' - } - ) - const isBidRequestValid = spec.isBidRequestValid(slotConfig) - expect(isBidRequestValid).to.equal(true) - }) - }) - }) - describe('returns false', function() { - describe('when params are not correct', function() { - function createSlotConfig(params) { - return getSlotConfigs({ banner: {} }, params) - } - it('does not have the PublisherToken.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createSlotConfig({ - adUnitId: ADUNIT_ID, - placement: 'banner' - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('does not have the AdUnitId.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createSlotConfig({ - publisherId: PUBLISHER_ID, - placement: 'banner' - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('does not have the placement.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createSlotConfig({ - publisherId: PUBLISHER_ID, - adUnitId: ADUNIT_ID - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('does not have a the correct placement.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createSlotConfig({ - publisherId: PUBLISHER_ID, - adUnitId: ADUNIT_ID, - placement: 'another_thing' - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - }) - describe('when video mediaType object is not correct', function() { - function createVideoSlotconfig(mediaType) { - return getSlotConfigs(mediaType, { - publisherId: PUBLISHER_ID, - adUnitId: ADUNIT_ID, - placement: 'video' - }) - } - it('is a void object', function() { - const isBidRequestValid = spec.isBidRequestValid( - createVideoSlotConfig({ video: {} }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('does not have playerSize.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createVideoSlotConfig({ video: { context: 'instream' } }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('is not instream ', function() { - const isBidRequestValid = spec.isBidRequestValid( - createVideoSlotConfig({ - video: { - context: 'outstream', - playerSize: [[600, 200]] - } - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - describe('order does not matter', function() { - it('when video is not the first slot', function() { - const isBidRequestValid = spec.isBidRequestValid( - createVideoSlotConfig({ banner: {}, video: {} }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('when video is the first slot', function() { - const isBidRequestValid = spec.isBidRequestValid( - createVideoSlotConfig({ video: {}, banner: {} }) - ) - expect(isBidRequestValid).to.equal(false) - }) - }) - }) - }) - }) - - describe('buildRequests method', function() { - const bidderRequest = { - refererInfo: { referer: 'referer' }, - timeout: 1000 - } - const mandatoryParams = { - publisherId: PUBLISHER_ID, - adUnitId: ADUNIT_ID, - placement: 'banner' - } - const inStreamParams = Object.assign({}, mandatoryParams, { - video: { - mimes: 'mp4' - } - }) - const validBidRequests = [ - getSlotConfigs({ banner: {} }, mandatoryParams), - getSlotConfigs( - { video: { context: 'instream', playerSize: [[300, 200]] } }, - inStreamParams - ) - ] - it('Url params should be correct ', function() { - const request = spec.buildRequests(validBidRequests, bidderRequest) - expect(request.method).to.equal('POST') - expect(request.url).to.equal('https://s.seedtag.com/c/hb/bid') - }) - - it('Common data request should be correct', function() { - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(data.url).to.equal('referer') - expect(data.publisherToken).to.equal('0000-0000-01') - expect(typeof data.version).to.equal('string') - expect(['fixed', 'mobile', 'unknown'].indexOf(data.connectionType)).to.be.above(-1) - }) - - describe('adPosition param', function() { - it('should sended when publisher set adPosition param', function() { - const params = Object.assign({}, mandatoryParams, { - adPosition: 1 - }) - const validBidRequests = [getSlotConfigs({ banner: {} }, params)] - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(data.bidRequests[0].adPosition).to.equal(1) - }) - it('should not sended when publisher has not set adPosition param', function() { - const validBidRequests = [ - getSlotConfigs({ banner: {} }, mandatoryParams) - ] - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(data.bidRequests[0].adPosition).to.equal(undefined) - }) - }) - - describe('GDPR params', function() { - describe('when there arent consent management platform', function() { - it('cmp should be false', function() { - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(data.cmp).to.equal(false) - }) - }) - describe('when there are consent management platform', function() { - it('cmps should be true and ga should not sended, when gdprApplies is undefined', function() { - bidderRequest['gdprConsent'] = { - gdprApplies: undefined, - consentString: 'consentString' - } - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(data.cmp).to.equal(true) - expect(Object.keys(data).indexOf('data')).to.equal(-1) - expect(data.cd).to.equal('consentString') - }) - it('cmps should be true and all gdpr parameters should be sended, when there are gdprApplies', function() { - bidderRequest['gdprConsent'] = { - gdprApplies: true, - consentString: 'consentString' - } - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(data.cmp).to.equal(true) - expect(data.ga).to.equal(true) - expect(data.cd).to.equal('consentString') - }) - }) - }) - - describe('BidRequests params', function() { - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - const bidRequests = data.bidRequests - it('should request a Banner', function() { - const bannerBid = bidRequests[0] - expect(bannerBid.id).to.equal('30b31c1838de1e') - expect(bannerBid.transactionId).to.equal( - 'd704d006-0d6e-4a09-ad6c-179e7e758096' - ) - expect(bannerBid.supplyTypes[0]).to.equal('display') - expect(bannerBid.adUnitId).to.equal('000000') - expect(bannerBid.sizes[0][0]).to.equal(300) - expect(bannerBid.sizes[0][1]).to.equal(250) - expect(bannerBid.sizes[1][0]).to.equal(300) - expect(bannerBid.sizes[1][1]).to.equal(600) - }) - it('should request an InStream Video', function() { - const videoBid = bidRequests[1] - expect(videoBid.id).to.equal('30b31c1838de1e') - expect(videoBid.transactionId).to.equal( - 'd704d006-0d6e-4a09-ad6c-179e7e758096' - ) - expect(videoBid.supplyTypes[0]).to.equal('video') - expect(videoBid.adUnitId).to.equal('000000') - expect(videoBid.videoParams.mimes).to.equal('mp4') - expect(videoBid.videoParams.w).to.equal(300) - expect(videoBid.videoParams.h).to.equal(200) - expect(videoBid.sizes[0][0]).to.equal(300) - expect(videoBid.sizes[0][1]).to.equal(250) - expect(videoBid.sizes[1][0]).to.equal(300) - expect(videoBid.sizes[1][1]).to.equal(600) - }) - }) - }) - - describe('interpret response method', function() { - it('should return a void array, when the server response are not correct.', function() { - const request = { data: JSON.stringify({}) } - const serverResponse = { - body: {} - } - const bids = spec.interpretResponse(serverResponse, request) - expect(typeof bids).to.equal('object') - expect(bids.length).to.equal(0) - }) - it('should return a void array, when the server response have no bids.', function() { - const request = { data: JSON.stringify({}) } - const serverResponse = { body: { bids: [] } } - const bids = spec.interpretResponse(serverResponse, request) - expect(typeof bids).to.equal('object') - expect(bids.length).to.equal(0) - }) - describe('when the server response return a bid', function() { - describe('the bid is a banner', function() { - it('should return a banner bid', function() { - const request = { data: JSON.stringify({}) } - const serverResponse = { - body: { - bids: [ - { - bidId: '2159a54dc2566f', - price: 0.5, - currency: 'USD', - content: 'content', - width: 728, - height: 90, - mediaType: 'display', - ttl: 360, - nurl: 'testurl.com/nurl' - } - ], - cookieSync: { url: '' } - } - } - const bids = spec.interpretResponse(serverResponse, request) - expect(bids.length).to.equal(1) - expect(bids[0].requestId).to.equal('2159a54dc2566f') - expect(bids[0].cpm).to.equal(0.5) - expect(bids[0].width).to.equal(728) - expect(bids[0].height).to.equal(90) - expect(bids[0].currency).to.equal('USD') - expect(bids[0].netRevenue).to.equal(true) - expect(bids[0].ad).to.equal('content') - expect(bids[0].nurl).to.equal('testurl.com/nurl') - }) - }) - describe('the bid is a video', function() { - it('should return a instream bid', function() { - const request = { data: JSON.stringify({}) } - const serverResponse = { - body: { - bids: [ - { - bidId: '2159a54dc2566f', - price: 0.5, - currency: 'USD', - content: 'content', - width: 728, - height: 90, - mediaType: 'video', - ttl: 360, - nurl: undefined - } - ], - cookieSync: { url: '' } - } - } - const bids = spec.interpretResponse(serverResponse, request) - expect(bids.length).to.equal(1) - expect(bids[0].requestId).to.equal('2159a54dc2566f') - expect(bids[0].cpm).to.equal(0.5) - expect(bids[0].width).to.equal(728) - expect(bids[0].height).to.equal(90) - expect(bids[0].currency).to.equal('USD') - expect(bids[0].netRevenue).to.equal(true) - expect(bids[0].vastXml).to.equal('content') - }) - }) - }) - }) - - describe('user syncs method', function() { - it('should return empty array, when iframe sync option are disabled.', function() { - const syncOption = { iframeEnabled: false } - const serverResponses = [{ body: { cookieSync: 'someUrl' } }] - const cookieSyncArray = spec.getUserSyncs(syncOption, serverResponses) - expect(cookieSyncArray.length).to.equal(0) - }) - it('should return empty array, when the server response are wrong.', function() { - const syncOption = { iframeEnabled: true } - const serverResponses = [{ body: {} }] - const cookieSyncArray = spec.getUserSyncs(syncOption, serverResponses) - expect(cookieSyncArray.length).to.equal(0) - }) - it('should return empty array, when the server response are void.', function() { - const syncOption = { iframeEnabled: true } - const serverResponses = [{ body: { cookieSync: '' } }] - const cookieSyncArray = spec.getUserSyncs(syncOption, serverResponses) - expect(cookieSyncArray.length).to.equal(0) - }) - it('should return a array with the cookie sync, when the server response with a cookie sync.', function() { - const syncOption = { iframeEnabled: true } - const serverResponses = [{ body: { cookieSync: 'someUrl' } }] - const cookieSyncArray = spec.getUserSyncs(syncOption, serverResponses) - expect(cookieSyncArray.length).to.equal(1) - expect(cookieSyncArray[0].type).to.equal('iframe') - expect(cookieSyncArray[0].url).to.equal('someUrl') - }) - }) - - describe('onTimeout', function () { - beforeEach(function() { - sinon.stub(utils, 'triggerPixel') - }) - - afterEach(function() { - utils.triggerPixel.restore() - }) - - it('should return the correct endpoint', function () { - const params = { publisherId: '0000', adUnitId: '11111' } - const timeoutData = [{ params: [ params ] }]; - const timeoutUrl = getTimeoutUrl(timeoutData); - expect(timeoutUrl).to.equal( - 'https://s.seedtag.com/se/hb/timeout?publisherToken=' + - params.publisherId + - '&adUnitId=' + - params.adUnitId - ) - }) - - it('should set the timeout pixel', function() { - const params = { publisherId: '0000', adUnitId: '11111' } - const timeoutData = [{ params: [ params ] }]; - spec.onTimeout(timeoutData) - expect(utils.triggerPixel.calledWith('https://s.seedtag.com/se/hb/timeout?publisherToken=' + - params.publisherId + - '&adUnitId=' + - params.adUnitId)).to.equal(true); - }) - }) - - describe('onBidWon', function () { - beforeEach(function() { - sinon.stub(utils, 'triggerPixel') - }) - - afterEach(function() { - utils.triggerPixel.restore() - }) - - describe('without nurl', function() { - const bid = {} - - it('does not create pixel ', function() { - spec.onBidWon(bid) - expect(utils.triggerPixel.called).to.equal(false); - }) - }) - - describe('with nurl', function () { - const nurl = 'http://seedtag_domain/won' - const bid = { nurl } - - it('creates nurl pixel if bid nurl', function() { - spec.onBidWon({ nurl }) - expect(utils.triggerPixel.calledWith(nurl)).to.equal(true); - }) - }) - }) -}) diff --git a/test/spec/modules/segmentoBidAdapter_spec.js b/test/spec/modules/segmentoBidAdapter_spec.js deleted file mode 100644 index 17ad424f73f..00000000000 --- a/test/spec/modules/segmentoBidAdapter_spec.js +++ /dev/null @@ -1,187 +0,0 @@ -import { expect } from 'chai'; -import { spec } from '../../../modules/segmentoBidAdapter.js'; - -const BIDDER_CODE = 'segmento'; -const URL = 'https://prebid-bidder.rutarget.ru/bid'; -const SYNC_IFRAME_URL = 'https://tag.rutarget.ru/tag?event=otherPage&check=true&response=syncframe&synconly=true'; -const SYNC_IMAGE_URL = 'https://tag.rutarget.ru/tag?event=otherPage&check=true&synconly=true'; -const RUB = 'RUB'; -const TIME_TO_LIVE = 0; - -describe('SegmentoAdapter', function () { - describe('isBidRequestValid', function () { - const bid = { - bidder: BIDDER_CODE, - bidId: '51ef8751f9aead', - params: { - placementId: 34 - }, - adUnitCode: 'div-gpt-ad-1460505748561-0', - transactionId: 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - sizes: [[320, 50], [300, 250], [300, 600]], - bidderRequestId: '418b37f85e772c', - auctionId: '18fd8b8b0bd757' - }; - - it('should return true if placementId is a number', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false if placementId is not a number', function () { - bid.params.placementId = 'placementId'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false if no placementId param', function () { - delete bid.params.placementId; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const bids = [{ - bidder: 'segmento', - bidId: '51ef8751f9aead', - params: { - placementId: 34 - }, - adUnitCode: 'div-gpt-ad-1460505748561-0', - transactionId: 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - sizes: [[320, 50], [300, 250], [300, 600]], - bidderRequestId: '418b37f85e772c', - auctionId: '18fd8b8b0bd757' - }]; - - const bidderRequest = { - refererInfo: { - referer: 'https://comepage.com' - } - }; - - const request = spec.buildRequests(bids, bidderRequest); - it('should return POST method', function () { - expect(request.method).to.equal('POST'); - }); - - it('should return valid url', function () { - expect(request.url).to.equal(URL); - }); - - it('should return valid data', function () { - const data = request.data; - expect(data).to.have.all.keys('settings', 'places'); - expect(data.settings.currency).to.be.equal(RUB); - expect(data.settings.referrer).to.be.a('string'); - expect(data.settings.referrer).to.be.equal(bidderRequest.refererInfo.referer); - const places = data.places; - for (let i = 0; i < places.length; i++) { - const place = places[i]; - const bid = bids[i]; - expect(place).to.have.all.keys('id', 'placementId', 'sizes'); - expect(place.id).to.be.a('string'); - expect(place.id).to.be.equal(bid.bidId); - expect(place.placementId).to.be.a('number'); - expect(place.placementId).to.be.equal(bid.params.placementId); - expect(place.sizes).to.be.an('array'); - expect(place.sizes).to.deep.equal(bid.sizes); - } - }); - - it('should return empty places if no valid bids are passed', function () { - const request = spec.buildRequests([], {}); - expect(request.data.places).to.be.an('array').to.deep.equal([]); - }); - }); - - describe('interpretResponse', function() { - const serverResponse = { - body: { - bids: [{ - id: '51ef8751f9aead', - cpm: 0.23, - currency: RUB, - creativeId: 123, - displayUrl: 'displayUrl?t=123&p=456', - size: { - width: 300, - height: 250 - } - }] - } - }; - - const emptyServerResponse = { - body: { - bids: [] - } - }; - - it('should return valid data', function () { - const response = spec.interpretResponse(serverResponse); - expect(response).to.be.an('array'); - for (let i = 0; i < response.length; i++) { - const item = response[i]; - const bid = serverResponse.body.bids[i]; - expect(item).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'creativeId', - 'currency', 'netRevenue', 'ttl', 'adUrl'); - expect(item.requestId).to.be.a('string'); - expect(item.requestId).to.be.equal(bid.id); - expect(item.cpm).to.be.a('number'); - expect(item.cpm).to.be.equal(bid.cpm); - expect(item.width).to.be.a('number'); - expect(item.width).to.be.equal(bid.size.width); - expect(item.height).to.be.a('number'); - expect(item.height).to.be.equal(bid.size.height); - expect(item.creativeId).to.be.a('number'); - expect(item.creativeId).to.be.equal(bid.creativeId); - expect(item.currency).to.be.a('string'); - expect(item.currency).to.be.equal(bid.currency); - expect(item.netRevenue).to.be.a('boolean'); - expect(item.netRevenue).to.equal(true); - expect(item.ttl).to.be.a('number'); - expect(item.ttl).to.be.equal(TIME_TO_LIVE); - expect(item.adUrl).to.be.a('string'); - expect(item.adUrl).to.be.equal(bid.displayUrl); - } - }); - - it('should return empty array if no bids', function () { - const response = spec.interpretResponse(emptyServerResponse); - expect(response).to.be.an('array').to.deep.equal([]); - }); - - it('should return empty array if server response is invalid', function () { - const response = spec.interpretResponse({}); - expect(response).to.be.an('array').to.deep.equal([]); - }); - }); - - describe('getUserSyncs', function() { - it('should return iframe type if iframe enabled', function () { - const syncs = spec.getUserSyncs({ iframeEnabled: true }); - const sync = syncs[0]; - expect(syncs).to.be.an('array').with.lengthOf(1); - expect(sync).to.have.all.keys('type', 'url'); - expect(sync.type).to.be.a('string'); - expect(sync.type).to.be.equal('iframe'); - expect(sync.url).to.be.a('string'); - expect(sync.url).to.be.equal(SYNC_IFRAME_URL); - }); - - it('should return iframe type if iframe disabled, but image enable', function () { - const syncs = spec.getUserSyncs({ pixelEnabled: true }); - const sync = syncs[0]; - expect(syncs).to.be.an('array').with.lengthOf(1); - expect(sync).to.have.all.keys('type', 'url'); - expect(sync.type).to.be.a('string'); - expect(sync.type).to.be.equal('image'); - expect(sync.url).to.be.a('string'); - expect(sync.url).to.be.equal(SYNC_IMAGE_URL); - }); - - it('should return empty array if iframe and pixels disabled', function () { - const syncs = spec.getUserSyncs({}); - expect(syncs).to.be.an('array').to.deep.equal([]); - }); - }); -}); diff --git a/test/spec/modules/sekindoUMBidAdapter_spec.js b/test/spec/modules/sekindoUMBidAdapter_spec.js deleted file mode 100644 index 2c361c21303..00000000000 --- a/test/spec/modules/sekindoUMBidAdapter_spec.js +++ /dev/null @@ -1,168 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/sekindoUMBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('sekindoUMAdapter', function () { - const adapter = newBidder(spec); - - const bannerParams = { - 'spaceId': '14071' - }; - - const videoParams = { - 'spaceId': '14071', - 'video': { - playerWidth: 300, - playerHeight: 250, - vid_vastType: 2 // optional - } - }; - - var bidRequests = { - 'bidder': 'sekindoUM', - 'params': bannerParams, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'mediaType': 'banner' - }; - - describe('inherited functions', function () { - it('exists and is a function', function () { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - it('should return true when required params found', function () { - bidRequests.mediaType = 'banner'; - bidRequests.params = bannerParams; - expect(spec.isBidRequestValid(bidRequests)).to.equal(true); - }); - - it('should return false when required video params are missing', function () { - bidRequests.mediaType = 'video'; - bidRequests.params = bannerParams; - expect(spec.isBidRequestValid(bidRequests)).to.equal(false); - }); - - it('should return true when required Video params found', function () { - bidRequests.mediaType = 'video'; - bidRequests.params = videoParams; - expect(spec.isBidRequestValid(bidRequests)).to.equal(true); - }); - }); - - describe('buildRequests', function () { - it('banner data should be a query string and method = GET', function () { - bidRequests.mediaType = 'banner'; - bidRequests.params = bannerParams; - const request = spec.buildRequests([bidRequests]); - expect(request[0].data).to.be.a('string'); - expect(request[0].method).to.equal('GET'); - }); - - it('with gdprConsent, banner data should be a query string and method = GET', function () { - bidRequests.mediaType = 'banner'; - bidRequests.params = bannerParams; - const request = spec.buildRequests([bidRequests], {'gdprConsent': {'consentString': 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', 'vendorData': {}, 'gdprApplies': true}}); - expect(request[0].data).to.be.a('string'); - expect(request[0].method).to.equal('GET'); - }); - - it('video data should be a query string and method = GET', function () { - bidRequests.mediaType = 'video'; - bidRequests.params = videoParams; - const request = spec.buildRequests([bidRequests]); - expect(request[0].data).to.be.a('string'); - expect(request[0].method).to.equal('GET'); - }); - }); - - describe('interpretResponse', function () { - it('banner should get correct bid response', function () { - let response = { - 'headers': function(header) { - return 'dummy header'; - }, - 'body': {'id': '30b31c1838de1e', 'bidderCode': 'sekindoUM', 'cpm': 2.1951, 'width': 300, 'height': 250, 'ad': '

sekindo creative<\/h1>', 'ttl': 36000, 'creativeId': '323774', 'netRevenue': true, 'currency': 'USD'} - }; - - bidRequests.mediaType = 'banner'; - bidRequests.params = bannerParams; - let expectedResponse = [ - { - 'requestId': '30b31c1838de1e', - 'bidderCode': 'sekindoUM', - 'cpm': 2.1951, - 'width': 300, - 'height': 250, - 'creativeId': '323774', - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 36000, - 'ad': '

sekindo creative

' - } - ]; - let result = spec.interpretResponse(response, bidRequests); - expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); - }); - - it('vastXml video should get correct bid response', function () { - let response = { - 'headers': function(header) { - return 'dummy header'; - }, - 'body': {'id': '30b31c1838de1e', 'bidderCode': 'sekindoUM', 'cpm': 2.1951, 'width': 300, 'height': 250, 'vastXml': '', 'ttl': 36000, 'creativeId': '323774', 'netRevenue': true, 'currency': 'USD'} - }; - - bidRequests.mediaType = 'video'; - bidRequests.params = videoParams; - let expectedResponse = [ - { - 'requestId': '30b31c1838de1e', - 'bidderCode': 'sekindoUM', - 'cpm': 2.1951, - 'width': 300, - 'height': 250, - 'creativeId': '323774', - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 36000, - 'vastXml': '' - } - ]; - let result = spec.interpretResponse(response, bidRequests); - expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); - }); - - it('vastUrl video should get correct bid response', function () { - let response = { - 'headers': function(header) { - return 'dummy header'; - }, - 'body': {'id': '30b31c1838de1e', 'bidderCode': 'sekindoUM', 'cpm': 2.1951, 'width': 300, 'height': 250, 'vastUrl': 'https://vastUrl', 'ttl': 36000, 'creativeId': '323774', 'netRevenue': true, 'currency': 'USD'} - }; - bidRequests.mediaType = 'video'; - bidRequests.params = videoParams; - let expectedResponse = [ - { - 'requestId': '30b31c1838de1e', - 'bidderCode': 'sekindoUM', - 'cpm': 2.1951, - 'width': 300, - 'height': 250, - 'creativeId': '323774', - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 36000, - 'vastUrl': 'https://vastUrl' - } - ]; - let result = spec.interpretResponse(response, bidRequests); - expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); - }); - }); -}); diff --git a/test/spec/modules/serverbidServerBidAdapter_spec.js b/test/spec/modules/serverbidServerBidAdapter_spec.js deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/test/spec/modules/shareUserIds_spec.js b/test/spec/modules/shareUserIds_spec.js deleted file mode 100644 index 67e39533fc7..00000000000 --- a/test/spec/modules/shareUserIds_spec.js +++ /dev/null @@ -1,65 +0,0 @@ -import {userIdTargeting} from '../../../modules/userIdTargeting.js'; -import { expect } from 'chai'; - -describe('#userIdTargeting', function() { - let userIds; - let config; - - beforeEach(function() { - userIds = { - tdid: 'my-tdid' - }; - config = { - 'GAM': true, - 'GAM_KEYS': { - 'tdid': 'TD_ID' - } - }; - }); - - it('Do nothing if config is invaild', function() { - let pubads = window.googletag.pubads(); - pubads.clearTargeting(); - pubads.setTargeting('test', ['TEST']); - userIdTargeting(userIds, JSON.stringify(config)); - expect(pubads.getTargeting('test')).to.deep.equal(['TEST']); - }); - - it('all UserIds are passed as is with GAM: true', function() { - let pubads = window.googletag.pubads(); - pubads.clearTargeting(); - pubads.setTargeting('test', ['TEST']); - delete config.GAM_KEYS; - userIdTargeting(userIds, config); - expect(pubads.getTargeting('test')).to.deep.equal(['TEST']); - expect(pubads.getTargeting('tdid')).to.deep.equal(['my-tdid']); - }) - - it('Publisher prefered key-names are used', function() { - let pubads = window.googletag.pubads(); - pubads.clearTargeting(); - pubads.setTargeting('test', ['TEST']); - userIdTargeting(userIds, config); - expect(pubads.getTargeting('test')).to.deep.equal(['TEST']); - expect(pubads.getTargeting('TD_ID')).to.deep.equal(['my-tdid']); - }); - - it('Publisher does not want to pass an id', function() { - let pubads = window.googletag.pubads(); - pubads.clearTargeting(); - pubads.setTargeting('test', ['TEST']); - config.GAM_KEYS.tdid = ''; - userIdTargeting(userIds, config); - expect(pubads.getTargeting('tdid')).to.be.an('array').that.is.empty; - expect(pubads.getTargeting('test')).to.deep.equal(['TEST']); - }); - - it('User Id Targeting is added to googletag queue when GPT is not ready', function() { - let pubads = window.googletag.pubads; - delete window.googletag.pubads; - userIdTargeting(userIds, config); - window.googletag.pubads = pubads; - window.googletag.cmd.map(command => command()); - expect(window.googletag.pubads().getTargeting('TD_ID')).to.deep.equal(['my-tdid']); - }); -}); diff --git a/test/spec/modules/sharedIdSystem_spec.js b/test/spec/modules/sharedIdSystem_spec.js deleted file mode 100644 index ad51fe81cde..00000000000 --- a/test/spec/modules/sharedIdSystem_spec.js +++ /dev/null @@ -1,77 +0,0 @@ -import { - sharedIdSubmodule, -} from 'modules/sharedIdSystem.js'; -import { server } from 'test/mocks/xhr.js'; -import {uspDataHandler} from 'src/adapterManager'; - -let expect = require('chai').expect; - -describe('SharedId System', function() { - const SHAREDID_RESPONSE = {sharedId: 'testsharedid'}; - let uspConsentDataStub; - describe('Xhr Requests from getId()', function() { - let callbackSpy = sinon.spy(); - - beforeEach(function() { - callbackSpy.resetHistory(); - uspConsentDataStub = sinon.stub(uspDataHandler, 'getConsentData'); - }); - - afterEach(function () { - uspConsentDataStub.restore(); - }); - - it('should call shared id endpoint without consent data and handle a valid response', function () { - let submoduleCallback = sharedIdSubmodule.getId(undefined, undefined).callback; - submoduleCallback(callbackSpy); - - let request = server.requests[0]; - expect(request.url).to.equal('https://id.sharedid.org/id'); - expect(request.withCredentials).to.be.true; - - request.respond(200, {}, JSON.stringify(SHAREDID_RESPONSE)); - - expect(callbackSpy.calledOnce).to.be.true; - expect(callbackSpy.lastCall.lastArg.id).to.equal(SHAREDID_RESPONSE.sharedId); - }); - - it('should call shared id endpoint with consent data and handle a valid response', function () { - let consentData = { - gdprApplies: true, - consentString: 'abc12345234', - }; - - let submoduleCallback = sharedIdSubmodule.getId(undefined, consentData).callback; - submoduleCallback(callbackSpy); - - let request = server.requests[0]; - expect(request.url).to.equal('https://id.sharedid.org/id?gdpr=1&gdpr_consent=abc12345234'); - expect(request.withCredentials).to.be.true; - - request.respond(200, {}, JSON.stringify(SHAREDID_RESPONSE)); - - expect(callbackSpy.calledOnce).to.be.true; - expect(callbackSpy.lastCall.lastArg.id).to.equal(SHAREDID_RESPONSE.sharedId); - }); - - it('should call shared id endpoint with usp consent data and handle a valid response', function () { - uspConsentDataStub.returns('1YYY'); - let consentData = { - gdprApplies: true, - consentString: 'abc12345234', - }; - - let submoduleCallback = sharedIdSubmodule.getId(undefined, consentData).callback; - submoduleCallback(callbackSpy); - - let request = server.requests[0]; - expect(request.url).to.equal('https://id.sharedid.org/id?us_privacy=1YYY&gdpr=1&gdpr_consent=abc12345234'); - expect(request.withCredentials).to.be.true; - - request.respond(200, {}, JSON.stringify(SHAREDID_RESPONSE)); - - expect(callbackSpy.calledOnce).to.be.true; - expect(callbackSpy.lastCall.lastArg.id).to.equal(SHAREDID_RESPONSE.sharedId); - }); - }); -}); diff --git a/test/spec/modules/sharethroughBidAdapter_spec.js b/test/spec/modules/sharethroughBidAdapter_spec.js deleted file mode 100644 index 5c8e01536dd..00000000000 --- a/test/spec/modules/sharethroughBidAdapter_spec.js +++ /dev/null @@ -1,623 +0,0 @@ -import { expect } from 'chai'; -import { sharethroughAdapterSpec, sharethroughInternal } from 'modules/sharethroughBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import * as utils from '../../../src/utils.js'; -import { config } from 'src/config'; - -const spec = newBidder(sharethroughAdapterSpec).getSpec(); -const bidRequests = [ - { - bidder: 'sharethrough', - bidId: 'bidId1', - sizes: [[600, 300]], - placementCode: 'foo', - params: { - pkey: 'aaaa1111' - }, - userId: { - tdid: 'fake-tdid', - pubcid: 'fake-pubcid', - idl_env: 'fake-identity-link', - id5id: { - uid: 'fake-id5id', - ext: { - linkType: 2 - } - }, - sharedid: { - id: 'fake-sharedid', - third: 'fake-sharedthird' - }, - lipb: { - lipbid: 'fake-lipbid' - } - }, - crumbs: { - pubcid: 'fake-pubcid-in-crumbs-obj' - } - }, - { - bidder: 'sharethrough', - bidId: 'bidId2', - sizes: [[700, 400]], - placementCode: 'bar', - params: { - pkey: 'bbbb2222', - iframe: true - } - }, - { - bidder: 'sharethrough', - bidId: 'bidId3', - sizes: [[700, 400]], - placementCode: 'coconut', - params: { - pkey: 'cccc3333', - iframe: true, - iframeSize: [500, 500] - } - }, - { - bidder: 'sharethrough', - bidId: 'bidId4', - sizes: [[700, 400]], - placementCode: 'bar', - params: { - pkey: 'dddd4444', - badv: ['domain1.com', 'domain2.com'] - } - }, - { - bidder: 'sharethrough', - bidId: 'bidId5', - sizes: [[700, 400]], - placementCode: 'bar', - params: { - pkey: 'eeee5555', - bcat: ['IAB1-1', 'IAB1-2'] - } - }, -]; - -const prebidRequests = [ - { - method: 'POST', - url: 'https://btlr.sharethrough.com/WYu2BXv1/v1', - data: { - bidId: 'bidId', - placement_key: 'pKey' - }, - strData: { - skipIframeBusting: false, - sizes: [] - } - }, - { - method: 'POST', - url: 'https://btlr.sharethrough.com/WYu2BXv1/v1', - data: { - bidId: 'bidId', - placement_key: 'pKey' - }, - strData: { - skipIframeBusting: true, - sizes: [[300, 250], [300, 300], [250, 250], [600, 50]] - } - }, - { - method: 'POST', - url: 'https://btlr.sharethrough.com/WYu2BXv1/v1', - data: { - bidId: 'bidId', - placement_key: 'pKey' - }, - strData: { - skipIframeBusting: true, - iframeSize: [500, 500], - sizes: [[300, 250], [300, 300], [250, 250], [600, 50]] - } - }, - { - method: 'POST', - url: 'https://btlr.sharethrough.com/WYu2BXv1/v1', - data: { - bidId: 'bidId', - placement_key: 'pKey' - }, - strData: { - skipIframeBusting: false, - sizes: [[0, 0]] - } - }, - { - method: 'POST', - url: 'https://btlr.sharethrough.com/WYu2BXv1/v1', - data: { - bidId: 'bidId', - placement_key: 'pKey' - }, - strData: { - skipIframeBusting: false, - sizes: [[300, 250], [300, 300], [250, 250], [600, 50]] - } - } -]; - -const bidderResponse = { - body: { - 'adserverRequestId': '40b6afd5-6134-4fbb-850a-bb8972a46994', - 'bidId': 'bidId1', - 'version': 1, - 'creatives': [{ - 'auctionWinId': 'b2882d5e-bf8b-44da-a91c-0c11287b8051', - 'cpm': 12.34, - 'creative': { - 'deal_id': 'aDealId', - 'creative_key': 'aCreativeId', - 'title': '✓ à la mode' - } - }], - 'stxUserId': '' - }, - header: { get: (header) => header } -}; - -const setUserAgent = (uaString) => { - window.navigator['__defineGetter__']('userAgent', function() { - return uaString; - }); -}; - -describe('sharethrough internal spec', function() { - let windowStub, windowTopStub; - let stubbedReturn = [{ - appendChild: () => undefined - }] - beforeEach(function() { - windowStub = sinon.stub(window.document, 'getElementsByTagName'); - windowTopStub = sinon.stub(window.top.document, 'getElementsByTagName'); - windowStub.withArgs('body').returns(stubbedReturn); - windowTopStub.withArgs('body').returns(stubbedReturn); - }); - - afterEach(function() { - windowStub.restore(); - windowTopStub.restore(); - window.STR = undefined; - window.top.STR = undefined; - }); - - describe('we cannot access top level document', function() { - beforeEach(function() { - window.lockedInFrame = true; - }); - - afterEach(function() { - window.lockedInFrame = false; - }); - - it('appends sfp.js to the safeframe', function() { - sharethroughInternal.handleIframe(); - expect(windowStub.calledOnce).to.be.true; - }); - - it('does not append anything if sfp.js is already loaded in the safeframe', function() { - window.STR = { Tag: true }; - sharethroughInternal.handleIframe(); - expect(windowStub.notCalled).to.be.true; - expect(windowTopStub.notCalled).to.be.true; - }); - }); - - describe('we are able to bust out of the iframe', function() { - it('appends sfp.js to window.top', function() { - sharethroughInternal.handleIframe(); - expect(windowStub.calledOnce).to.be.true; - expect(windowTopStub.calledOnce).to.be.true; - }); - - it('only appends sfp-set-targeting.js if sfp.js is already loaded on the page', function() { - window.top.STR = { Tag: true }; - sharethroughInternal.handleIframe(); - expect(windowStub.calledOnce).to.be.true; - expect(windowTopStub.notCalled).to.be.true; - }); - }); -}); - -describe('sharethrough adapter spec', function() { - describe('.code', function() { - it('should return a bidder code of sharethrough', function() { - expect(spec.code).to.eql('sharethrough'); - }); - }); - - describe('.isBidRequestValid', function() { - it('should return false if req has no pkey', function() { - const invalidBidRequest = { - bidder: 'sharethrough', - params: { - notPKey: 'abc123' - } - }; - expect(spec.isBidRequestValid(invalidBidRequest)).to.eql(false); - }); - - it('should return false if req has wrong bidder code', function() { - const invalidBidRequest = { - bidder: 'notSharethrough', - params: { - notPKey: 'abc123' - } - }; - expect(spec.isBidRequestValid(invalidBidRequest)).to.eql(false); - }); - - it('should return true if req is correct', function() { - expect(spec.isBidRequestValid(bidRequests[0])).to.eq(true); - expect(spec.isBidRequestValid(bidRequests[1])).to.eq(true); - }); - }); - - describe('.buildRequests', function() { - it('should return an array of requests', function() { - const builtBidRequests = spec.buildRequests(bidRequests); - - expect(builtBidRequests[0].url).to.eq('https://btlr.sharethrough.com/WYu2BXv1/v1'); - expect(builtBidRequests[1].url).to.eq('https://btlr.sharethrough.com/WYu2BXv1/v1'); - expect(builtBidRequests[0].method).to.eq('POST'); - }); - - it('should set the instant_play_capable parameter correctly based on browser userAgent string', function() { - setUserAgent('Android Chrome/60'); - let builtBidRequests = spec.buildRequests(bidRequests); - expect(builtBidRequests[0].data.instant_play_capable).to.be.true; - - setUserAgent('iPhone Version/11'); - builtBidRequests = spec.buildRequests(bidRequests); - expect(builtBidRequests[0].data.instant_play_capable).to.be.true; - - setUserAgent('iPhone CriOS/60'); - builtBidRequests = spec.buildRequests(bidRequests); - expect(builtBidRequests[0].data.instant_play_capable).to.be.true; - - setUserAgent('Android Chrome/50'); - builtBidRequests = spec.buildRequests(bidRequests); - expect(builtBidRequests[0].data.instant_play_capable).to.be.false; - - setUserAgent('Android Chrome'); - builtBidRequests = spec.buildRequests(bidRequests); - expect(builtBidRequests[0].data.instant_play_capable).to.be.false; - - setUserAgent(undefined); - builtBidRequests = spec.buildRequests(bidRequests); - expect(builtBidRequests[0].data.instant_play_capable).to.be.false; - }); - - it('should set the secure parameter to false when the protocol is http', function() { - const stub = sinon.stub(sharethroughInternal, 'getProtocol').returns('http:'); - const bidRequest = spec.buildRequests(bidRequests, null)[0]; - expect(bidRequest.data.secure).to.be.false; - stub.restore(); - }); - - it('should set the secure parameter to true when the protocol is https', function() { - const stub = sinon.stub(sharethroughInternal, 'getProtocol').returns('https:'); - const bidRequest = spec.buildRequests(bidRequests, null)[0]; - expect(bidRequest.data.secure).to.be.true; - stub.restore(); - }); - - it('should set the secure parameter to true when the protocol is neither http or https', function() { - const stub = sinon.stub(sharethroughInternal, 'getProtocol').returns('about:'); - const bidRequest = spec.buildRequests(bidRequests, null)[0]; - expect(bidRequest.data.secure).to.be.true; - stub.restore(); - }); - - it('should add ccpa parameter if uspConsent is present', function() { - const uspConsent = '1YNN'; - const bidderRequest = { uspConsent: uspConsent }; - const bidRequest = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(bidRequest.data.us_privacy).to.eq(uspConsent); - }); - - it('should add consent parameters if gdprConsent is present', function() { - const gdprConsent = { consentString: 'consent_string123', gdprApplies: true }; - const bidderRequest = { gdprConsent: gdprConsent }; - const bidRequest = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(bidRequest.data.consent_required).to.eq(true); - expect(bidRequest.data.consent_string).to.eq('consent_string123'); - }); - - it('should handle gdprConsent is present but values are undefined case', function() { - const gdprConsent = { consent_string: undefined, gdprApplies: undefined }; - const bidderRequest = { gdprConsent: gdprConsent }; - const bidRequest = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(bidRequest.data).to.not.include.any.keys('consent_string'); - }); - - it('should add the ttduid parameter if a bid request contains a value for Unified ID from The Trade Desk', function() { - const bidRequest = spec.buildRequests(bidRequests)[0]; - expect(bidRequest.data.ttduid).to.eq('fake-tdid'); - }); - - it('should add the pubcid parameter if a bid request contains a value for the Publisher Common ID Module in the' + - ' userId object of the bidrequest', function() { - const bidRequest = spec.buildRequests(bidRequests)[0]; - expect(bidRequest.data.pubcid).to.eq('fake-pubcid'); - }); - - it('should add the pubcid parameter if a bid request contains a value for the Publisher Common ID Module in the' + - ' crumbs object of the bidrequest', function() { - const bidData = utils.deepClone(bidRequests); - delete bidData[0].userId.pubcid; - - const bidRequest = spec.buildRequests(bidData)[0]; - expect(bidRequest.data.pubcid).to.eq('fake-pubcid-in-crumbs-obj'); - }); - - it('should add the pubcid parameter if a bid request contains a value for the Publisher Common ID Module in the' + - ' crumbs object of the bidrequest', function() { - const bidRequest = spec.buildRequests(bidRequests)[0]; - delete bidRequest.userId; - expect(bidRequest.data.pubcid).to.eq('fake-pubcid'); - }); - - it('should add the idluid parameter if a bid request contains a value for Identity Link from Live Ramp', function() { - const bidRequest = spec.buildRequests(bidRequests)[0]; - expect(bidRequest.data.idluid).to.eq('fake-identity-link'); - }); - - it('should add the id5uid parameter if a bid request contains a value for ID5', function() { - const bidRequest = spec.buildRequests(bidRequests)[0]; - expect(bidRequest.data.id5uid.id).to.eq('fake-id5id'); - expect(bidRequest.data.id5uid.linkType).to.eq(2); - }); - - it('should add the shduid parameter if a bid request contains a value for Shared ID', function() { - const bidRequest = spec.buildRequests(bidRequests)[0]; - expect(bidRequest.data.shduid.id).to.eq('fake-sharedid'); - expect(bidRequest.data.shduid.third).to.eq('fake-sharedthird'); - }); - - it('should add the liuid parameter if a bid request contains a value for LiveIntent ID', function() { - const bidRequest = spec.buildRequests(bidRequests)[0]; - expect(bidRequest.data.liuid).to.eq('fake-lipbid'); - }); - - it('should add Sharethrough specific parameters', function() { - const builtBidRequests = spec.buildRequests(bidRequests); - expect(builtBidRequests[0]).to.deep.include({ - strData: { - skipIframeBusting: undefined, - iframeSize: undefined, - sizes: [[600, 300]] - } - }); - }); - - it('should add a supply chain parameter if schain is present', function() { - // shallow copy of the first bidRequest obj, so we don't mutate - const bidRequest = Object.assign({}, bidRequests[0]); - bidRequest['schain'] = { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'directseller.com', - sid: '00001', - rid: 'BidRequest1', - hp: 1 - } - ] - }; - - const builtBidRequest = spec.buildRequests([bidRequest])[0]; - expect(builtBidRequest.data.schain).to.eq(JSON.stringify(bidRequest.schain)); - }); - - it('should add badv if provided', () => { - const builtBidRequest = spec.buildRequests([bidRequests[3]])[0]; - - expect(builtBidRequest.data.badv).to.have.members(['domain1.com', 'domain2.com']) - }); - - it('should add bcat if provided', () => { - const builtBidRequest = spec.buildRequests([bidRequests[4]])[0]; - - expect(builtBidRequest.data.bcat).to.have.members(['IAB1-1', 'IAB1-2']) - }); - - it('should not add a supply chain parameter if schain is missing', function() { - const bidRequest = spec.buildRequests(bidRequests)[0]; - expect(bidRequest.data).to.not.include.any.keys('schain'); - }); - - it('should include the bidfloor parameter if it is present in the bid request', function() { - const bidRequest = Object.assign({}, bidRequests[0]); - bidRequest['bidfloor'] = 0.50; - const builtBidRequest = spec.buildRequests([bidRequest])[0]; - expect(builtBidRequest.data.bidfloor).to.eq(0.5); - }); - - it('should not include the bidfloor parameter if it is missing in the bid request', function() { - const bidRequest = Object.assign({}, bidRequests[0]); - const builtBidRequest = spec.buildRequests([bidRequest])[0]; - expect(builtBidRequest.data).to.not.include.any.keys('bidfloor'); - }); - - describe('coppa', function() { - it('should add coppa to request if enabled', function() { - config.setConfig({coppa: true}); - const bidRequest = Object.assign({}, bidRequests[0]); - const builtBidRequest = spec.buildRequests([bidRequest])[0]; - expect(builtBidRequest.data.coppa).to.eq(true); - }); - - it('should not add coppa to request if disabled', function() { - config.setConfig({coppa: false}); - const bidRequest = Object.assign({}, bidRequests[0]); - const builtBidRequest = spec.buildRequests([bidRequest])[0]; - expect(builtBidRequest.data.coppa).to.be.undefined; - }); - - it('should not add coppa to request if unknown value', function() { - config.setConfig({coppa: 'something'}); - const bidRequest = Object.assign({}, bidRequests[0]); - const builtBidRequest = spec.buildRequests([bidRequest])[0]; - expect(builtBidRequest.data.coppa).to.be.undefined; - }); - }); - }); - - describe('.interpretResponse', function() { - it('returns a correctly parsed out response', function() { - expect(spec.interpretResponse(bidderResponse, prebidRequests[0])[0]).to.deep.include( - { - width: 1, - height: 1, - cpm: 12.34, - creativeId: 'aCreativeId', - dealId: 'aDealId', - currency: 'USD', - netRevenue: true, - ttl: 360, - meta: { advertiserDomains: [] } - }); - }); - - it('returns a correctly parsed out response with largest size when strData.skipIframeBusting is true', function() { - expect(spec.interpretResponse(bidderResponse, prebidRequests[1])[0]).to.include( - { - width: 300, - height: 300, - cpm: 12.34, - creativeId: 'aCreativeId', - dealId: 'aDealId', - currency: 'USD', - netRevenue: true, - ttl: 360 - }); - }); - - it('returns a correctly parsed out response with explicitly defined size when strData.skipIframeBusting is true and strData.iframeSize is provided', function() { - expect(spec.interpretResponse(bidderResponse, prebidRequests[2])[0]).to.include( - { - width: 500, - height: 500, - cpm: 12.34, - creativeId: 'aCreativeId', - dealId: 'aDealId', - currency: 'USD', - netRevenue: true, - ttl: 360 - }); - }); - - it('returns a correctly parsed out response with explicitly defined size when strData.skipIframeBusting is false and strData.sizes contains [0, 0] only', function() { - expect(spec.interpretResponse(bidderResponse, prebidRequests[3])[0]).to.include( - { - width: 0, - height: 0, - cpm: 12.34, - creativeId: 'aCreativeId', - dealId: 'aDealId', - currency: 'USD', - netRevenue: true, - ttl: 360 - }); - }); - - it('returns a correctly parsed out response with explicitly defined size when strData.skipIframeBusting is false and strData.sizes contains multiple sizes', function() { - expect(spec.interpretResponse(bidderResponse, prebidRequests[4])[0]).to.include( - { - width: 300, - height: 300, - cpm: 12.34, - creativeId: 'aCreativeId', - dealId: 'aDealId', - currency: 'USD', - netRevenue: true, - ttl: 360 - }); - }); - - it('returns a blank array if there are no creatives', function() { - const bidResponse = { body: { creatives: [] } }; - expect(spec.interpretResponse(bidResponse, prebidRequests[0])).to.be.an('array').that.is.empty; - }); - - it('returns a blank array if body object is empty', function() { - const bidResponse = { body: {} }; - expect(spec.interpretResponse(bidResponse, prebidRequests[0])).to.be.an('array').that.is.empty; - }); - - it('returns a blank array if body is null', function() { - const bidResponse = { body: null }; - expect(spec.interpretResponse(bidResponse, prebidRequests[0])).to.be.an('array').that.is.empty; - }); - - it('correctly generates ad markup when skipIframeBusting is false', function() { - const adMarkup = spec.interpretResponse(bidderResponse, prebidRequests[0])[0].ad; - let resp = null; - - expect(() => btoa(JSON.stringify(bidderResponse))).to.throw(); - expect(() => resp = sharethroughInternal.b64EncodeUnicode(JSON.stringify(bidderResponse))).not.to.throw(); - expect(adMarkup).to.match( - /data-str-native-key="pKey" data-stx-response-name="str_response_bidId"/); - expect(!!adMarkup.indexOf(resp)).to.eql(true); - - // insert functionality to autodetect whether or not in safeframe, and handle JS insertion - expect(adMarkup).to.match(/isLockedInFrame/); - expect(adMarkup).to.match(/handleIframe/); - }); - - it('correctly generates ad markup when skipIframeBusting is true', function() { - const adMarkup = spec.interpretResponse(bidderResponse, prebidRequests[1])[0].ad; - let resp = null; - - expect(() => btoa(JSON.stringify(bidderResponse))).to.throw(); - expect(() => resp = sharethroughInternal.b64EncodeUnicode(JSON.stringify(bidderResponse))).not.to.throw(); - expect(adMarkup).to.match( - /data-str-native-key="pKey" data-stx-response-name="str_response_bidId"/); - expect(!!adMarkup.indexOf(resp)).to.eql(true); - expect(adMarkup).to.match( - /"'; - -describe('slimcutBidAdapter', 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() { - let bid = { - 'bidder': 'slimcut', - 'params': { - 'placementId': 83 - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '3c871ffa8ef14c', - 'bidderRequestId': 'b41642f1aee381', - 'auctionId': '4e156668c977d7' - }; - - it('should return true when required params found', function() { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when placementId is not valid (letters)', function() { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'placementId': 'ABCD' - }; - - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when placementId < 0', function() { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'placementId': -1 - }; - - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when required params are not passed', function() { - let bid = Object.assign({}, bid); - delete bid.params; - - bid.params = {}; - - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function() { - let bidRequests = [ - { - 'bidder': 'teads', - 'params': { - 'placementId': 10433394 - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '3c871ffa8ef14c', - 'bidderRequestId': 'b41642f1aee381', - 'auctionId': '4e156668c977d7', - 'deviceWidth': 1680 - } - ]; - - let bidderResquestDefault = { - 'auctionId': '4e156668c977d7', - 'bidderRequestId': 'b41642f1aee381', - 'timeout': 3000 - }; - - it('sends bid request to ENDPOINT via POST', function() { - const request = spec.buildRequests(bidRequests, bidderResquestDefault); - - expect(request.url).to.equal(ENDPOINT); - expect(request.method).to.equal('POST'); - }); - - it('should send GDPR to endpoint', function() { - let consentString = 'JRJ8RKfDeBNsERRDCSAAZ+A=='; - let bidderRequest = { - 'auctionId': '4e156668c977d7', - 'bidderRequestId': 'b41642f1aee381', - 'timeout': 3000, - 'gdprConsent': { - 'consentString': consentString, - 'gdprApplies': true, - 'vendorData': { - 'hasGlobalConsent': false - } - } - }; - - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.gdpr_iab).to.exist; - expect(payload.gdpr_iab.consent).to.equal(consentString); - }); - - it('should add referer info to payload', function () { - const bidRequest = Object.assign({}, bidRequests[0]) - const bidderRequest = { - refererInfo: { - referer: 'https://example.com/page.html', - reachedTop: true, - numIframes: 2 - } - } - const request = spec.buildRequests([bidRequest], bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.referrer).to.exist; - expect(payload.referrer).to.deep.equal('https://example.com/page.html') - }); - }); - - describe('getUserSyncs', () => { - let bids = { - 'body': { - 'responses': [{ - 'ad': AD_SCRIPT, - 'cpm': 0.5, - 'currency': 'USD', - 'height': 250, - 'netRevenue': true, - 'requestId': '3ede2a3fa0db94', - 'ttl': 360, - 'width': 300, - 'creativeId': 'er2ee', - 'transactionId': 'deadb33f', - 'winUrl': 'https://sb.freeskreen.com/win' - }] - } - }; - - it('should get the correct number of sync urls', () => { - let urls = spec.getUserSyncs({iframeEnabled: true}, bids); - expect(urls.length).to.equal(1); - expect(urls[0].url).to.equal('https://sb.freeskreen.com/async_usersync.html'); - }); - - it('should return no url if not iframe enabled', () => { - let urls = spec.getUserSyncs({iframeEnabled: false}, bids); - expect(urls.length).to.equal(0); - }); - }); - - describe('interpretResponse', function() { - let bids = { - 'body': { - 'responses': [{ - 'ad': AD_SCRIPT, - 'cpm': 0.5, - 'currency': 'USD', - 'height': 250, - 'netRevenue': true, - 'requestId': '3ede2a3fa0db94', - 'ttl': 360, - 'width': 300, - 'creativeId': 'er2ee', - 'transactionId': 'deadb33f', - 'winUrl': 'https://sb.freeskreen.com/win' - }] - } - }; - - it('should get correct bid response', function() { - let expectedResponse = [{ - 'cpm': 0.5, - 'width': 300, - 'height': 250, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 360, - 'ad': AD_SCRIPT, - 'requestId': '3ede2a3fa0db94', - 'creativeId': 'er2ee', - 'transactionId': 'deadb33f', - 'winUrl': 'https://sb.freeskreen.com/win' - }]; - - let result = spec.interpretResponse(bids); - expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); - }); - - it('handles nobid responses', function() { - let bids = { - 'body': { - 'responses': [] - } - }; - - let result = spec.interpretResponse(bids); - expect(result.length).to.equal(0); - }); - }); -}); diff --git a/test/spec/modules/smaatoBidAdapter_spec.js b/test/spec/modules/smaatoBidAdapter_spec.js deleted file mode 100644 index 1bc77fc9572..00000000000 --- a/test/spec/modules/smaatoBidAdapter_spec.js +++ /dev/null @@ -1,606 +0,0 @@ -import { spec } from 'modules/smaatoBidAdapter.js'; -import * as utils from 'src/utils.js'; -import {config} from 'src/config.js'; -import {createEidsArray} from 'modules/userId/eids.js'; - -const imageAd = { - image: { - img: { - url: 'https://prebid/static/ad.jpg', - w: 320, - h: 50, - ctaurl: 'https://prebid/track/ctaurl' - }, - impressiontrackers: [ - 'https://prebid/track/imp/1', - 'https://prebid/track/imp/2' - ], - clicktrackers: [ - 'https://prebid/track/click/1' - ] - } -}; - -const richmediaAd = { - richmedia: { - mediadata: { - content: '

RICHMEDIA CONTENT

', - w: 800, - h: 600 - }, - impressiontrackers: [ - 'https://prebid/track/imp/1', - 'https://prebid/track/imp/2' - ], - clicktrackers: [ - 'https://prebid/track/click/1' - ] - } -}; - -const ADTYPE_IMG = 'Img'; -const ADTYPE_RICHMEDIA = 'Richmedia'; -const ADTYPE_VIDEO = 'Video'; - -const site = { - keywords: 'power tools,drills' -}; - -const user = { - keywords: 'a,b', - gender: 'M', - yob: 1984 -}; - -const openRtbBidResponse = (adType) => { - let adm = ''; - - switch (adType) { - case ADTYPE_IMG: - adm = JSON.stringify(imageAd); - break; - case ADTYPE_RICHMEDIA: - adm = JSON.stringify(richmediaAd); - break; - case ADTYPE_VIDEO: - adm = ''; - break; - default: - throw Error('Invalid AdType'); - } - - let resp = { - body: { - bidid: '04db8629-179d-4bcd-acce-e54722969006', - cur: 'USD', - ext: {}, - id: '5ebea288-f13a-4754-be6d-4ade66c68877', - seatbid: [ - { - bid: [ - { - 'adm': adm, - 'adomain': [ - 'smaato.com' - ], - 'bidderName': 'smaato', - 'cid': 'CM6523', - 'crid': 'CR69381', - 'dealid': '12345', - 'id': '6906aae8-7f74-4edd-9a4f-f49379a3cadd', - 'impid': '226416e6e6bf41', - 'iurl': 'https://prebid/iurl', - 'nurl': 'https://prebid/nurl', - 'price': 0.01, - 'w': 350, - 'h': 50 - } - ], - seat: 'CM6523' - } - ], - }, - headers: { - get: function (header) { - if (header === 'X-SMT-ADTYPE') { - return adType; - } - } - } - }; - return resp; -}; - -const request = { - method: 'POST', - url: 'https://prebid.ad.smaato.net/oapi/prebid', - data: '' -}; - -const interpretedBidsImg = [ - { - requestId: '226416e6e6bf41', - cpm: 0.01, - width: 350, - height: 50, - ad: '
\"\"\"\"
', - ttl: 300, - creativeId: 'CR69381', - dealId: '12345', - netRevenue: true, - currency: 'USD', - meta: { - advertiserDomains: ['smaato.com'], - agencyId: 'CM6523', - networkName: 'smaato', - mediaType: 'banner' - } - } -]; - -const interpretedBidsRichmedia = [ - { - requestId: '226416e6e6bf41', - cpm: 0.01, - width: 350, - height: 50, - ad: '

RICHMEDIA CONTENT

\"\"\"\"
', - ttl: 300, - creativeId: 'CR69381', - dealId: '12345', - netRevenue: true, - currency: 'USD', - meta: { - advertiserDomains: ['smaato.com'], - agencyId: 'CM6523', - networkName: 'smaato', - mediaType: 'banner' - } - } -]; - -const interpretedBidsVideo = [ - { - requestId: '226416e6e6bf41', - cpm: 0.01, - width: 350, - height: 50, - vastXml: '', - ttl: 300, - creativeId: 'CR69381', - dealId: '12345', - netRevenue: true, - currency: 'USD', - meta: { - advertiserDomains: ['smaato.com'], - agencyId: 'CM6523', - networkName: 'smaato', - mediaType: 'video' - } - } -]; - -const defaultBidderRequest = { - gdprConsent: { - consentString: 'HFIDUYFIUYIUYWIPOI87392DSU', - gdprApplies: true - }, - uspConsent: 'uspConsentString', - refererInfo: { - referer: 'http://example.com/page.html', - }, - timeout: 1200 -}; - -const minimalBidderRequest = { - refererInfo: { - referer: 'http://example.com/page.html', - } -}; - -const singleBannerBidRequest = { - bidder: 'smaato', - params: { - publisherId: 'publisherId', - adspaceId: 'adspaceId' - }, - mediaTypes: { - banner: { - sizes: [[300, 50]] - } - }, - adUnitCode: '/19968336/header-bid-tag-0', - transactionId: 'transactionId', - sizes: [[300, 50]], - bidId: 'bidId', - bidderRequestId: 'bidderRequestId', - auctionId: 'auctionId', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 -}; - -const singleVideoBidRequest = { - bidder: 'smaato', - params: { - publisherId: 'publisherId', - adspaceId: 'adspaceId' - }, - mediaTypes: { - video: { - context: 'outstream', - playerSize: [[768, 1024]], - mimes: ['video\/mp4', 'video\/quicktime', 'video\/3gpp', 'video\/x-m4v'], - minduration: 5, - maxduration: 30, - startdelay: 0, - linearity: 1, - protocols: [7], - skip: 1, - skipmin: 5, - api: [7], - ext: {rewarded: 0} - } - }, - adUnitCode: '/19968336/header-bid-tag-0', - transactionId: 'transactionId', - sizes: [[300, 50]], - bidId: 'bidId', - bidderRequestId: 'bidderRequestId', - auctionId: 'auctionId', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 -}; - -const combinedBannerAndVideoBidRequest = { - bidder: 'smaato', - params: { - publisherId: 'publisherId', - adspaceId: 'adspaceId' - }, - mediaTypes: { - banner: { - sizes: [[300, 50]] - }, - video: { - context: 'outstream', - playerSize: [[768, 1024]], - mimes: ['video\/mp4', 'video\/quicktime', 'video\/3gpp', 'video\/x-m4v'], - minduration: 5, - maxduration: 30, - startdelay: 0, - linearity: 1, - protocols: [7], - skip: 1, - skipmin: 5, - api: [7], - ext: {rewarded: 0} - } - }, - adUnitCode: '/19968336/header-bid-tag-0', - transactionId: 'transactionId', - sizes: [[300, 50]], - bidId: 'bidId', - bidderRequestId: 'bidderRequestId', - auctionId: 'auctionId', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 -}; - -const inAppBidRequest = { - bidder: 'smaato', - params: { - publisherId: 'publisherId', - adspaceId: 'adspaceId', - app: { - ifa: 'aDeviceId', - geo: { - lat: 33.3, - lon: -88.8 - } - } - }, - mediaTypes: { - banner: { - sizes: [[300, 50]] - } - }, - adUnitCode: '/19968336/header-bid-tag-0', - transactionId: 'transactionId', - sizes: [[300, 50]], - bidId: 'bidId', - bidderRequestId: 'bidderRequestId', - auctionId: 'auctionId', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 -}; - -const userIdBidRequest = { - bidder: 'smaato', - params: { - publisherId: 'publisherId', - adspaceId: 'adspaceId' - }, - mediaTypes: { - banner: { - sizes: [[300, 50]] - } - }, - adUnitCode: '/19968336/header-bid-tag-0', - transactionId: 'transactionId', - sizes: [[300, 50]], - bidId: 'bidId', - bidderRequestId: 'bidderRequestId', - auctionId: 'auctionId', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0, - userId: { - criteoId: '123456', - tdid: '89145' - }, - userIdAsEids: createEidsArray({ - criteoId: '123456', - tdid: '89145' - }) -}; - -describe('smaatoBidAdapterTest', () => { - describe('isBidRequestValid', () => { - it('has valid params', () => { - expect(spec.isBidRequestValid({params: {publisherId: '123', adspaceId: '456'}})).to.be.true; - expect(spec.isBidRequestValid(singleBannerBidRequest)).to.be.true; - }); - it('has invalid params', () => { - expect(spec.isBidRequestValid({})).to.be.false; - expect(spec.isBidRequestValid({params: {}})).to.be.false; - expect(spec.isBidRequestValid({params: {publisherId: '123'}})).to.be.false; - expect(spec.isBidRequestValid({params: {publisherId: '123', adspaceId: 456}})).to.be.false; - }); - }); - - describe('buildRequests', () => { - beforeEach(() => { - this.req = JSON.parse(spec.buildRequests([singleBannerBidRequest], defaultBidderRequest).data); - this.sandbox = sinon.sandbox.create(); - }); - - afterEach(() => { - this.sandbox.restore(); - }); - - it('can override endpoint', () => { - const overridenEndpoint = 'https://prebid/bidder'; - let bidRequest = utils.deepClone(singleBannerBidRequest); - utils.deepSetValue(bidRequest, 'params.endpoint', overridenEndpoint); - const actualEndpoint = spec.buildRequests([bidRequest], defaultBidderRequest).url; - expect(actualEndpoint).to.equal(overridenEndpoint); - }); - - it('sends correct imps', () => { - expect(this.req.imp).to.deep.equal([ - { - id: 'bidId', - banner: { - w: 300, - h: 50, - format: [ - { - h: 50, - w: 300 - } - ] - }, - tagid: 'adspaceId' - } - ]) - }); - - it('sends correct site', () => { - expect(this.req.site.id).to.exist.and.to.be.a('string'); - expect(this.req.site.domain).to.exist.and.to.be.a('string'); - expect(this.req.site.page).to.exist.and.to.be.a('string'); - expect(this.req.site.ref).to.equal('http://example.com/page.html'); - expect(this.req.site.publisher.id).to.equal('publisherId'); - }) - - it('sends gdpr applies if exists', () => { - expect(this.req.regs.ext.gdpr).to.equal(1); - expect(this.req.user.ext.consent).to.equal('HFIDUYFIUYIUYWIPOI87392DSU'); - }); - - it('sends no gdpr applies if no gdpr exists', () => { - let req_without_gdpr = JSON.parse(spec.buildRequests([singleBannerBidRequest], minimalBidderRequest).data); - expect(req_without_gdpr.regs.ext.gdpr).to.not.exist; - expect(req_without_gdpr.user.ext.consent).to.not.exist; - }); - - it('sends usp if exists', () => { - expect(this.req.regs.ext.us_privacy).to.equal('uspConsentString'); - }); - - it('sends tmax', () => { - expect(this.req.tmax).to.equal(1200); - }); - - it('sends no usp if no usp exists', () => { - let req_without_usp = JSON.parse(spec.buildRequests([singleBannerBidRequest], minimalBidderRequest).data); - expect(req_without_usp.regs.ext.us_privacy).to.not.exist; - }); - - it('sends fp data', () => { - this.sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - ortb2: { - site, - user - } - }; - return utils.deepAccess(config, key); - }); - let bidRequest = utils.deepClone(singleBannerBidRequest); - let req_fpd = JSON.parse(spec.buildRequests([bidRequest], defaultBidderRequest).data); - expect(req_fpd.user.gender).to.equal('M'); - expect(req_fpd.user.yob).to.equal(1984); - expect(req_fpd.user.keywords).to.eql('a,b'); - expect(req_fpd.user.ext.consent).to.equal('HFIDUYFIUYIUYWIPOI87392DSU'); - expect(req_fpd.site.keywords).to.eql('power tools,drills'); - expect(req_fpd.site.publisher.id).to.equal('publisherId'); - }); - - it('has no user ids', () => { - expect(this.req.user.ext.eids).to.not.exist; - }); - }); - - describe('buildRequests for video imps', () => { - it('sends correct video imps', () => { - let req = JSON.parse(spec.buildRequests([singleVideoBidRequest], defaultBidderRequest).data); - expect(req.imp).to.deep.equal([ - { - id: 'bidId', - video: { - mimes: ['video\/mp4', 'video\/quicktime', 'video\/3gpp', 'video\/x-m4v'], - minduration: 5, - startdelay: 0, - linearity: 1, - h: 1024, - maxduration: 30, - skip: 1, - protocols: [7], - ext: { - rewarded: 0 - }, - skipmin: 5, - api: [7], - w: 768 - }, - tagid: 'adspaceId' - } - ]) - }); - it('allows combines banner and video imp in single bid request', () => { - let req = JSON.parse(spec.buildRequests([combinedBannerAndVideoBidRequest], defaultBidderRequest).data); - expect(req.imp).to.deep.equal([ - { - id: 'bidId', - banner: { - w: 300, - h: 50, - format: [ - { - h: 50, - w: 300 - } - ] - }, - video: { - mimes: ['video\/mp4', 'video\/quicktime', 'video\/3gpp', 'video\/x-m4v'], - minduration: 5, - startdelay: 0, - linearity: 1, - h: 1024, - maxduration: 30, - skip: 1, - protocols: [7], - ext: { - rewarded: 0 - }, - skipmin: 5, - api: [7], - w: 768 - }, - tagid: 'adspaceId' - } - ]) - }); - it('allows two imps in the same bid request', () => { - let req = JSON.parse(spec.buildRequests([singleBannerBidRequest, singleBannerBidRequest], defaultBidderRequest).data); - expect(req.imp).to.have.length(2); - }); - }); - - describe('in-app requests', () => { - it('add geo and ifa info to device object', () => { - let req = JSON.parse(spec.buildRequests([inAppBidRequest], defaultBidderRequest).data); - expect(req.device.geo).to.deep.equal({'lat': 33.3, 'lon': -88.8}); - expect(req.device.ifa).to.equal('aDeviceId'); - }); - it('add only ifa to device object', () => { - let inAppBidRequestWithoutGeo = utils.deepClone(inAppBidRequest); - delete inAppBidRequestWithoutGeo.params.app.geo - let req = JSON.parse(spec.buildRequests([inAppBidRequestWithoutGeo], defaultBidderRequest).data); - - expect(req.device.geo).to.not.exist; - expect(req.device.ifa).to.equal('aDeviceId'); - }); - it('add no specific device info if param does not exist', () => { - let req = JSON.parse(spec.buildRequests([singleBannerBidRequest], defaultBidderRequest).data); - expect(req.device.geo).to.not.exist; - expect(req.device.ifa).to.not.exist; - }); - }); - - describe('user ids in requests', () => { - it('user ids are added to user.ext.eids', () => { - let req = JSON.parse(spec.buildRequests([userIdBidRequest], defaultBidderRequest).data); - expect(req.user.ext.eids).to.exist; - expect(req.user.ext.eids).to.have.length(2); - }); - }); - - describe('interpretResponse', () => { - it('single image reponse', () => { - const bids = spec.interpretResponse(openRtbBidResponse(ADTYPE_IMG), request); - assert.deepStrictEqual(bids, interpretedBidsImg); - }); - it('single richmedia reponse', () => { - const bids = spec.interpretResponse(openRtbBidResponse(ADTYPE_RICHMEDIA), request); - assert.deepStrictEqual(bids, interpretedBidsRichmedia); - }); - it('single video reponse', () => { - const bids = spec.interpretResponse(openRtbBidResponse(ADTYPE_VIDEO), request); - assert.deepStrictEqual(bids, interpretedBidsVideo); - }); - it('ignores bid response with invalid ad type', () => { - let resp = openRtbBidResponse(ADTYPE_IMG); - resp.headers.get = (header) => { - if (header === 'X-SMT-ADTYPE') { - return undefined; - } - } - const bids = spec.interpretResponse(resp, request); - expect(bids).to.be.empty - }); - it('uses correct TTL when expire header exists', () => { - const clock = sinon.useFakeTimers(); - clock.tick(2000); - let resp = openRtbBidResponse(ADTYPE_IMG); - resp.headers.get = (header) => { - if (header === 'X-SMT-ADTYPE') { - return ADTYPE_IMG; - } - if (header === 'X-SMT-Expires') { - return 2000 + (400 * 1000); - } - } - const bids = spec.interpretResponse(resp, request); - expect(bids[0].ttl).to.equal(400); - clock.restore(); - }); - it('uses net revenue flag send from server', () => { - let resp = openRtbBidResponse(ADTYPE_IMG); - resp.body.seatbid[0].bid[0].ext = {net: false}; - const bids = spec.interpretResponse(resp, request); - expect(bids[0].netRevenue).to.equal(false); - }) - }); -}); diff --git a/test/spec/modules/smartadserverBidAdapter_spec.js b/test/spec/modules/smartadserverBidAdapter_spec.js deleted file mode 100644 index 749de43b9af..00000000000 --- a/test/spec/modules/smartadserverBidAdapter_spec.js +++ /dev/null @@ -1,718 +0,0 @@ -import { - expect -} from 'chai'; -import { - spec -} from 'modules/smartadserverBidAdapter.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/consentManagement.js'; - -// Default params with optional ones -describe('Smart bid adapter tests', function () { - var DEFAULT_PARAMS = [{ - adUnitCode: 'sas_42', - bidId: 'abcd1234', - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [300, 200] - ] - } - }, - bidder: 'smartadserver', - params: { - domain: 'https://prg.smartadserver.com', - siteId: '1234', - pageId: '5678', - formatId: '90', - target: 'test=prebid', - bidfloor: 0.420, - buId: '7569', - appName: 'Mozilla', - ckId: 42 - }, - requestId: 'efgh5678', - transactionId: 'zsfgzzg' - }]; - - var DEFAULT_PARAMS_WITH_EIDS = [{ - adUnitCode: 'sas_42', - bidId: 'abcd1234', - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [300, 200] - ] - } - }, - bidder: 'smartadserver', - params: { - domain: 'https://prg.smartadserver.com', - siteId: '1234', - pageId: '5678', - formatId: '90', - target: 'test=prebid', - bidfloor: 0.420, - buId: '7569', - appName: 'Mozilla', - ckId: 42 - }, - requestId: 'efgh5678', - transactionId: 'zsfgzzg', - userId: { - britepoolid: '1111', - criteoId: '1111', - digitrustid: { data: { id: 'DTID', keyv: 4, privacy: { optout: false }, producer: 'ABC', version: 2 } }, - id5id: { uid: '1111' }, - idl_env: '1111', - lipbid: '1111', - parrableid: 'eidVersion.encryptionKeyReference.encryptedValue', - pubcid: '1111', - tdid: '1111', - netId: 'fH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg', - } - }]; - - // Default params without optional ones - var DEFAULT_PARAMS_WO_OPTIONAL = [{ - adUnitCode: 'sas_42', - bidId: 'abcd1234', - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [300, 200] - ], - } - }, - - bidder: 'smartadserver', - params: { - domain: 'https://prg.smartadserver.com', - siteId: '1234', - pageId: '5678', - formatId: '90' - }, - requestId: 'efgh5678' - }]; - - var BID_RESPONSE = { - body: { - cpm: 12, - width: 300, - height: 250, - creativeId: 'zioeufg', - currency: 'GBP', - isNetCpm: true, - ttl: 300, - adUrl: 'http://awesome.fake.url', - ad: '< --- awesome script --- >', - cSyncUrl: 'http://awesome.fake.csync.url', - isNoAd: false - } - }; - - var BID_RESPONSE_IS_NO_AD = { - body: { - cpm: 12, - width: 300, - height: 250, - creativeId: 'zioeufg', - currency: 'GBP', - isNetCpm: true, - ttl: 300, - adUrl: 'http://awesome.fake.url', - ad: '< --- awesome script --- >', - cSyncUrl: 'http://awesome.fake.csync.url', - isNoAd: true - } - }; - - var BID_RESPONSE_IMAGE_SYNC = { - body: { - cpm: 12, - width: 300, - height: 250, - creativeId: 'zioeufg', - currency: 'GBP', - isNetCpm: true, - ttl: 300, - adUrl: 'http://awesome.fake.url', - ad: '< --- awesome script --- >', - cSyncUrl: 'http://awesome.fake.csync.url', - isNoAd: false, - dspPixels: ['pixelOne', 'pixelTwo', 'pixelThree'] - } - }; - - it('Verify build request', function () { - config.setConfig({ - 'currency': { - 'adServerCurrency': 'EUR' - } - }); - const request = spec.buildRequests(DEFAULT_PARAMS); - expect(request[0]).to.have.property('url').and.to.equal('https://prg.smartadserver.com/prebid/v1'); - expect(request[0]).to.have.property('method').and.to.equal('POST'); - const requestContent = JSON.parse(request[0].data); - - expect(requestContent).to.have.property('siteid').and.to.equal('1234'); - expect(requestContent).to.have.property('pageid').and.to.equal('5678'); - expect(requestContent).to.have.property('formatid').and.to.equal('90'); - expect(requestContent).to.have.property('currencyCode').and.to.equal('EUR'); - expect(requestContent).to.have.property('bidfloor').and.to.equal(0.42); - expect(requestContent).to.have.property('targeting').and.to.equal('test=prebid'); - expect(requestContent).to.have.property('tagId').and.to.equal('sas_42'); - expect(requestContent).to.have.property('sizes'); - expect(requestContent.sizes[0]).to.have.property('w').and.to.equal(300); - expect(requestContent.sizes[0]).to.have.property('h').and.to.equal(250); - expect(requestContent.sizes[1]).to.have.property('w').and.to.equal(300); - expect(requestContent.sizes[1]).to.have.property('h').and.to.equal(200); - expect(requestContent).to.not.have.property('pageDomain'); - expect(requestContent).to.have.property('transactionId').and.to.not.equal(null).and.to.not.be.undefined; - expect(requestContent).to.have.property('buid').and.to.equal('7569'); - expect(requestContent).to.have.property('appname').and.to.equal('Mozilla'); - expect(requestContent).to.have.property('ckid').and.to.equal(42); - }); - - it('Verify parse response with no ad', function () { - const request = spec.buildRequests(DEFAULT_PARAMS); - const bids = spec.interpretResponse(BID_RESPONSE_IS_NO_AD, request[0]); - expect(bids).to.have.lengthOf(0); - - expect(function () { - spec.interpretResponse(BID_RESPONSE_IS_NO_AD, { - data: 'invalid Json' - }) - }).to.not.throw(); - }); - - it('Verify parse response', function () { - const request = spec.buildRequests(DEFAULT_PARAMS); - const bids = spec.interpretResponse(BID_RESPONSE, request[0]); - expect(bids).to.have.lengthOf(1); - const bid = bids[0]; - expect(bid.cpm).to.equal(12); - expect(bid.adUrl).to.equal('http://awesome.fake.url'); - expect(bid.ad).to.equal('< --- awesome script --- >'); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.creativeId).to.equal('zioeufg'); - expect(bid.currency).to.equal('GBP'); - expect(bid.netRevenue).to.equal(true); - expect(bid.ttl).to.equal(300); - expect(bid.requestId).to.equal(DEFAULT_PARAMS[0].bidId); - - expect(function () { - spec.interpretResponse(BID_RESPONSE, { - data: 'invalid Json' - }) - }).to.not.throw(); - }); - - it('Verifies bidder code', function () { - expect(spec.code).to.equal('smartadserver'); - }); - - it('Verifies bidder aliases', function () { - expect(spec.aliases).to.have.lengthOf(1); - expect(spec.aliases[0]).to.equal('smart'); - }); - - it('Verifies if bid request valid', function () { - expect(spec.isBidRequestValid(DEFAULT_PARAMS[0])).to.equal(true); - expect(spec.isBidRequestValid(DEFAULT_PARAMS_WO_OPTIONAL[0])).to.equal(true); - expect(spec.isBidRequestValid({})).to.equal(false); - expect(spec.isBidRequestValid({ - params: {} - })).to.equal(false); - expect(spec.isBidRequestValid({ - params: { - pageId: 123 - } - })).to.equal(false); - expect(spec.isBidRequestValid({ - params: { - siteId: 123 - } - })).to.equal(false); - expect(spec.isBidRequestValid({ - params: { - formatId: 123, - pageId: 234 - } - })).to.equal(false); - expect(spec.isBidRequestValid({ - params: { - domain: 'www.test.com', - pageId: 234 - } - })).to.equal(false); - expect(spec.isBidRequestValid({ - params: { - domain: 'www.test.com', - formatId: 123, - siteId: 456, - pageId: 234 - } - })).to.equal(true); - expect(spec.isBidRequestValid({ - params: { - domain: 'www.test.com', - formatId: 123, - siteId: 456, - pageId: 234, - buId: 789, - appName: 'Mozilla' - } - })).to.equal(true); - expect(spec.isBidRequestValid({ - params: { - domain: 'www.test.com', - formatId: 123, - pageId: 234, - buId: 789, - appName: 'Mozilla' - } - })).to.equal(false); - }); - - it('Verifies user sync', function () { - var syncs = spec.getUserSyncs({ - iframeEnabled: true - }, [BID_RESPONSE]); - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.equal('http://awesome.fake.csync.url'); - - syncs = spec.getUserSyncs({ - iframeEnabled: false - }, [BID_RESPONSE]); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: true - }, []); - expect(syncs).to.have.lengthOf(0); - }); - - it('Verifies user sync using dspPixels', function () { - var syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: true - }, [BID_RESPONSE_IMAGE_SYNC]); - expect(syncs).to.have.lengthOf(3); - expect(syncs[0].type).to.equal('image'); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: false - }, [BID_RESPONSE_IMAGE_SYNC]); - expect(syncs).to.have.lengthOf(0); - - syncs = spec.getUserSyncs({ - iframeEnabled: false, - pixelEnabled: true - }, []); - expect(syncs).to.have.lengthOf(0); - }); - - describe('gdpr tests', function () { - afterEach(function () { - config.resetConfig(); - $$PREBID_GLOBAL$$.requestBids.removeAll(); - }); - - it('Verify build request with GDPR', function () { - config.setConfig({ - 'currency': { - 'adServerCurrency': 'EUR' - }, - consentManagement: { - cmp: 'iab', - consentRequired: true, - timeout: 1000, - allowAuctionWithoutConsent: true - } - }); - const request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, { - gdprConsent: { - consentString: 'BOKAVy4OKAVy4ABAB8AAAAAZ+A==', - gdprApplies: true - } - }); - const requestContent = JSON.parse(request[0].data); - expect(requestContent).to.have.property('gdpr').and.to.equal(true); - expect(requestContent).to.have.property('gdpr_consent').and.to.equal('BOKAVy4OKAVy4ABAB8AAAAAZ+A=='); - }); - - it('Verify build request with GDPR without gdprApplies', function () { - config.setConfig({ - 'currency': { - 'adServerCurrency': 'EUR' - }, - consentManagement: { - cmp: 'iab', - consentRequired: true, - timeout: 1000, - allowAuctionWithoutConsent: true - } - }); - const request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, { - gdprConsent: { - consentString: 'BOKAVy4OKAVy4ABAB8AAAAAZ+A==' - } - }); - const requestContent = JSON.parse(request[0].data); - expect(requestContent).to.not.have.property('gdpr'); - expect(requestContent).to.have.property('gdpr_consent').and.to.equal('BOKAVy4OKAVy4ABAB8AAAAAZ+A=='); - }); - }); - - describe('ccpa/us privacy tests', function () { - afterEach(function () { - config.resetConfig(); - $$PREBID_GLOBAL$$.requestBids.removeAll(); - }); - - it('Verify build request with us privacy', function () { - config.setConfig({ - 'currency': { - 'adServerCurrency': 'EUR' - }, - consentManagement: { - cmp: 'iab', - consentRequired: true, - timeout: 1000, - allowAuctionWithoutConsent: true - } - }); - - const uspConsentValue = '1YNN' - const request = spec.buildRequests(DEFAULT_PARAMS_WO_OPTIONAL, { - uspConsent: uspConsentValue - }); - const requestContent = JSON.parse(request[0].data); - - expect(requestContent).to.have.property('us_privacy').and.to.equal(uspConsentValue); - }); - }); - - describe('Instream video tests', function () { - afterEach(function () { - config.resetConfig(); - $$PREBID_GLOBAL$$.requestBids.removeAll(); - }); - - const INSTREAM_DEFAULT_PARAMS = [{ - adUnitCode: 'sas_42', - bidId: 'abcd1234', - bidder: 'smartadserver', - mediaTypes: { - video: { - context: 'instream', - playerSize: [[640, 480]] // It seems prebid.js transforms the player size array into an array of array... - } - }, - params: { - siteId: '1234', - pageId: '5678', - formatId: '90', - target: 'test=prebid', - bidfloor: 0.420, - buId: '7569', - appName: 'Mozilla', - ckId: 42, - video: { - protocol: 6 - } - }, - requestId: 'efgh5678', - transactionId: 'zsfgzzg' - }]; - - var INSTREAM_BID_RESPONSE = { - body: { - cpm: 12, - width: 640, - height: 480, - creativeId: 'zioeufg', - currency: 'GBP', - isNetCpm: true, - ttl: 300, - adUrl: 'http://awesome.fake-vast.url', - ad: '', - cSyncUrl: 'http://awesome.fake.csync.url' - } - }; - - it('Verify instream video build request', function () { - config.setConfig({ - 'currency': { - 'adServerCurrency': 'EUR' - } - }); - const request = spec.buildRequests(INSTREAM_DEFAULT_PARAMS); - expect(request[0]).to.have.property('url').and.to.equal('https://prg.smartadserver.com/prebid/v1'); - expect(request[0]).to.have.property('method').and.to.equal('POST'); - const requestContent = JSON.parse(request[0].data); - expect(requestContent).to.have.property('siteid').and.to.equal('1234'); - expect(requestContent).to.have.property('pageid').and.to.equal('5678'); - expect(requestContent).to.have.property('formatid').and.to.equal('90'); - expect(requestContent).to.have.property('currencyCode').and.to.equal('EUR'); - expect(requestContent).to.have.property('bidfloor').and.to.equal(0.42); - expect(requestContent).to.have.property('targeting').and.to.equal('test=prebid'); - expect(requestContent).to.have.property('tagId').and.to.equal('sas_42'); - expect(requestContent).to.not.have.property('pageDomain'); - expect(requestContent).to.have.property('transactionId').and.to.not.equal(null).and.to.not.be.undefined; - expect(requestContent).to.have.property('buid').and.to.equal('7569'); - expect(requestContent).to.have.property('appname').and.to.equal('Mozilla'); - expect(requestContent).to.have.property('ckid').and.to.equal(42); - expect(requestContent).to.have.property('isVideo').and.to.equal(true); - expect(requestContent).to.have.property('videoData'); - expect(requestContent.videoData).to.have.property('videoProtocol').and.to.equal(6); - expect(requestContent.videoData).to.have.property('playerWidth').and.to.equal(640); - expect(requestContent.videoData).to.have.property('playerHeight').and.to.equal(480); - }); - - it('Verify instream parse response', function () { - const request = spec.buildRequests(INSTREAM_DEFAULT_PARAMS); - const bids = spec.interpretResponse(INSTREAM_BID_RESPONSE, request[0]); - expect(bids).to.have.lengthOf(1); - const bid = bids[0]; - expect(bid.cpm).to.equal(12); - expect(bid.mediaType).to.equal('video'); - expect(bid.vastUrl).to.equal('http://awesome.fake-vast.url'); - expect(bid.vastXml).to.equal(''); - expect(bid.content).to.equal(''); - expect(bid.width).to.equal(640); - expect(bid.height).to.equal(480); - expect(bid.creativeId).to.equal('zioeufg'); - expect(bid.currency).to.equal('GBP'); - expect(bid.netRevenue).to.equal(true); - expect(bid.ttl).to.equal(300); - expect(bid.requestId).to.equal(INSTREAM_DEFAULT_PARAMS[0].bidId); - - expect(function () { - spec.interpretResponse(INSTREAM_BID_RESPONSE, { - data: 'invalid Json' - }) - }).to.not.throw(); - }); - - it('Verify not handled media type return empty request', function () { - config.setConfig({ - 'currency': { - 'adServerCurrency': 'EUR' - } - }); - const request = spec.buildRequests([{ - adUnitCode: 'sas_42', - bidder: 'smartadserver', - mediaTypes: { - video: { - context: 'badcontext' - } - }, - params: { - domain: 'https://prg.smartadserver.com', - siteId: '1234', - pageId: '5678', - formatId: '90', - target: 'test=prebid', - bidfloor: 0.420, - buId: '7569', - appName: 'Mozilla', - ckId: 42 - }, - requestId: 'efgh5678', - transactionId: 'zsfgzzg' - }, INSTREAM_DEFAULT_PARAMS[0]]); - expect(request[0]).to.be.empty; - expect(request[1]).to.not.be.empty; - }); - }); - - describe('Outstream video tests', function () { - afterEach(function () { - config.resetConfig(); - $$PREBID_GLOBAL$$.requestBids.removeAll(); - }); - - const OUTSTREAM_DEFAULT_PARAMS = [{ - adUnitCode: 'sas_43', - bidId: 'abcd1234', - bidder: 'smartadserver', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [[800, 600]] // It seems prebid.js transforms the player size array into an array of array... - } - }, - params: { - siteId: '1234', - pageId: '5678', - formatId: '91', - target: 'test=prebid-outstream', - bidfloor: 0.430, - buId: '7579', - appName: 'Mozilla', - ckId: 43, - video: { - protocol: 7 - } - }, - requestId: 'efgh5679', - transactionId: 'zsfgzzga' - }]; - - var OUTSTREAM_BID_RESPONSE = { - body: { - cpm: 14, - width: 800, - height: 600, - creativeId: 'zioeufga', - currency: 'USD', - isNetCpm: true, - ttl: 300, - adUrl: 'http://awesome.fake-vast2.url', - ad: '', - cSyncUrl: 'http://awesome.fake2.csync.url' - } - }; - - it('Verify outstream video build request', function () { - config.setConfig({ - 'currency': { - 'adServerCurrency': 'EUR' - } - }); - const request = spec.buildRequests(OUTSTREAM_DEFAULT_PARAMS); - expect(request[0]).to.have.property('url').and.to.equal('https://prg.smartadserver.com/prebid/v1'); - expect(request[0]).to.have.property('method').and.to.equal('POST'); - const requestContent = JSON.parse(request[0].data); - expect(requestContent).to.have.property('siteid').and.to.equal('1234'); - expect(requestContent).to.have.property('pageid').and.to.equal('5678'); - expect(requestContent).to.have.property('formatid').and.to.equal('91'); - expect(requestContent).to.have.property('currencyCode').and.to.equal('EUR'); - expect(requestContent).to.have.property('bidfloor').and.to.equal(0.43); - expect(requestContent).to.have.property('targeting').and.to.equal('test=prebid-outstream'); - expect(requestContent).to.have.property('tagId').and.to.equal('sas_43'); - expect(requestContent).to.not.have.property('pageDomain'); - expect(requestContent).to.have.property('transactionId').and.to.not.equal(null).and.to.not.be.undefined; - expect(requestContent).to.have.property('buid').and.to.equal('7579'); - expect(requestContent).to.have.property('appname').and.to.equal('Mozilla'); - expect(requestContent).to.have.property('ckid').and.to.equal(43); - expect(requestContent).to.have.property('isVideo').and.to.equal(false); - expect(requestContent).to.have.property('videoData'); - expect(requestContent.videoData).to.have.property('videoProtocol').and.to.equal(7); - expect(requestContent.videoData).to.have.property('playerWidth').and.to.equal(800); - expect(requestContent.videoData).to.have.property('playerHeight').and.to.equal(600); - }); - - it('Verify outstream parse response', function () { - const request = spec.buildRequests(OUTSTREAM_DEFAULT_PARAMS); - const bids = spec.interpretResponse(OUTSTREAM_BID_RESPONSE, request[0]); - expect(bids).to.have.lengthOf(1); - const bid = bids[0]; - expect(bid.cpm).to.equal(14); - expect(bid.mediaType).to.equal('video'); - expect(bid.vastUrl).to.equal('http://awesome.fake-vast2.url'); - expect(bid.vastXml).to.equal(''); - expect(bid.content).to.equal(''); - expect(bid.width).to.equal(800); - expect(bid.height).to.equal(600); - expect(bid.creativeId).to.equal('zioeufga'); - expect(bid.currency).to.equal('USD'); - expect(bid.netRevenue).to.equal(true); - expect(bid.ttl).to.equal(300); - expect(bid.requestId).to.equal(OUTSTREAM_DEFAULT_PARAMS[0].bidId); - - expect(function () { - spec.interpretResponse(OUTSTREAM_BID_RESPONSE, { - data: 'invalid Json' - }) - }).to.not.throw(); - }); - }); - - describe('External ids tests', function () { - it('Verify external ids in request and ids found', function () { - config.setConfig({ - 'currency': { - 'adServerCurrency': 'EUR' - } - }); - const request = spec.buildRequests(DEFAULT_PARAMS_WITH_EIDS); - expect(request[0]).to.have.property('url').and.to.equal('https://prg.smartadserver.com/prebid/v1'); - expect(request[0]).to.have.property('method').and.to.equal('POST'); - const requestContent = JSON.parse(request[0].data); - - expect(requestContent).to.have.property('eids'); - expect(requestContent.eids).to.not.equal(null).and.to.not.be.undefined; - expect(requestContent.eids.length).to.greaterThan(0); - for (let index in requestContent.eids) { - let eid = requestContent.eids[index]; - expect(eid.source).to.not.equal(null).and.to.not.be.undefined; - expect(eid.uids).to.not.equal(null).and.to.not.be.undefined; - for (let uidsIndex in eid.uids) { - let uid = eid.uids[uidsIndex]; - expect(uid.id).to.not.equal(null).and.to.not.be.undefined; - } - } - }); - }); - - describe('Supply Chain Serializer tests', function () { - it('Verify a multi node supply chain serialization matches iab example', function() { - let schain = { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'exchange1.com', - 'sid': '1234', - 'hp': 1, - 'rid': 'bid-request-1', - 'name': 'publisher', - 'domain': 'publisher.com' - }, - { - 'asi': 'exchange2.com', - 'sid': 'abcd', - 'hp': 1, - 'rid': 'bid-request-2', - 'name': 'intermediary', - 'domain': 'intermediary.com' - } - ] - }; - - let serializedSchain = spec.serializeSupplyChain(schain); - expect(serializedSchain).to.equal('1.0,1!exchange1.com,1234,1,bid-request-1,publisher,publisher.com!exchange2.com,abcd,1,bid-request-2,intermediary,intermediary.com'); - }); - - it('Verifiy that null schain produce null result', function () { - let actual = spec.serializeSupplyChain(null); - expect(null, actual); - }); - - it('Verifiy that schain with null nodes produce null result', function () { - let schain = { - 'ver': '1.0', - 'complete': 1 - - }; - let actual = spec.serializeSupplyChain(null); - expect(null, actual); - }); - }); -}); diff --git a/test/spec/modules/smarticoBidAdapter_spec.js b/test/spec/modules/smarticoBidAdapter_spec.js deleted file mode 100644 index e8ca5b0e127..00000000000 --- a/test/spec/modules/smarticoBidAdapter_spec.js +++ /dev/null @@ -1,118 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/smarticoBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; - -describe('smarticoBidAdapter', function () { - const adapter = newBidder(spec); - let bid = { - adUnitCode: 'adunit-code', - auctionId: '5kaj89l8-3456-2s56-c455-4g6h78jsdfgf', - bidRequestsCount: 1, - bidder: 'smartico', - bidderRequestId: '24081afs940568', - bidderRequestsCount: 1, - bidderWinsCount: 0, - bidId: '22499d052045', - mediaTypes: {banner: {sizes: [[300, 250]]}}, - params: { - token: 'FNVzUGZn9ebpIOoheh3kEJ2GQ6H6IyMH39sHXaya', - placementId: 'testPlacementId' - }, - sizes: [ - [300, 250] - ], - transactionId: '34562345-4dg7-46g7-4sg6-45gdsdj8fd56' - } - let bidderRequests = { - auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', - auctionStart: 1579746300522, - bidderCode: 'myBidderCode', - bidderRequestId: '15246a574e859f', - bids: [bid], - refererInfo: { - canonicalUrl: '', - numIframes: 0, - reachedTop: true - } - } - describe('isBidRequestValid', function () { - it('should return true where required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - }); - describe('buildRequests', function () { - let bidRequests = [ bid ]; - let request = spec.buildRequests(bidRequests, bidderRequests); - it('sends bid request via POST', function () { - expect(request.method).to.equal('POST'); - }); - it('must contain token', function() { - expect(request.data.bidParams[0].token).to.equal('FNVzUGZn9ebpIOoheh3kEJ2GQ6H6IyMH39sHXaya'); - }); - it('must contain auctionId', function() { - expect(request.data.auctionId).to.exist.and.to.be.a('string') - }); - it('must contain valid width and height', function() { - expect(request.data.bidParams[0]['banner-format-width']).to.exist.and.to.be.a('number') - expect(request.data.bidParams[0]['banner-format-height']).to.exist.and.to.be.a('number') - }); - }); - - describe('interpretResponse', function () { - let bidRequest = { - method: 'POST', - url: 'https://trmads.eu/preBidRequest', - bids: [bid], - data: [{ - token: 'FNVzUGZn9ebpIOoheh3kEJ2GQ6H6IyMH39sHXaya', - bidId: '22499d052045', - 'banner-format-width': 300, - 'banner-format-height': 250, - placementId: 'testPlacementId', - }] - }; - let serverResponse = [{ - bidId: '22499d052045', - id: 987654, - cpm: 10, - ttl: 30, - bannerFormatWidth: 300, - bannerFormatHeight: 250, - bannerFormatAlias: 'medium_rectangle' - }]; - let expectedResponse = [{ - requestId: bid.bidId, - cpm: 10, - width: 300, - height: 250, - creativeId: 987654, - netRevenue: false, // gross - ttl: 30, - ad: '`, - 'ttl': 500, - 'creativeId': '1234abcd', - 'netRevenue': true, - 'currency': 'USD', - 'aid': '30292e432662bd5f86d90774b944b039' - }, - { - 'requestId': '30b31c1838de1e', - 'cpm': 1.25, - 'width': 300, - 'height': 250, - 'vastUrl': 'https://mco-1-apex.go.sonobi.com/vast.xml?vid=30292e432662bd5f86d90774b944b038&ref=https%3A%2F%2Flocalhost%2F', - 'ttl': 500, - 'creativeId': '30292e432662bd5f86d90774b944b038', - 'netRevenue': true, - 'currency': 'USD', - 'dealId': 'dozerkey', - 'aid': '30292e432662bd5f86d90774b944b038', - 'mediaType': 'video' - }, - { - 'requestId': '30b31c1838de1g', - 'cpm': 1.07, - 'width': 300, - 'height': 600, - 'ad': ``, - 'ttl': 500, - 'creativeId': '1234abcd', - 'netRevenue': true, - 'currency': 'USD', - 'aid': '30292e432662bd5f86d90774b944b038' - }, - { - 'requestId': '30b31c1838de1zzzz', - 'cpm': 1.25, - 'width': 640, - 'height': 480, - 'vastUrl': 'https://mco-1-apex.go.sonobi.com/vast.xml?vid=30292e432662bd5f86d90774b944b038&ref=https%3A%2F%2Flocalhost%2F', - 'ttl': 500, - 'creativeId': 'somecrid', - 'netRevenue': true, - 'currency': 'USD', - 'dealId': 'dozerkey', - 'aid': 'force_1550072228_da1c5d030cb49150c5db8a2136175755', - 'mediaType': 'video', - renderer: () => {} - }, - ]; - - it('should map bidResponse to prebidResponse', function () { - const response = spec.interpretResponse(bidResponse, bidRequests); - response.forEach((resp, i) => { - expect(resp.requestId).to.equal(prebidResponse[i].requestId); - expect(resp.cpm).to.equal(prebidResponse[i].cpm); - - expect(resp.ttl).to.equal(prebidResponse[i].ttl); - expect(resp.creativeId).to.equal(prebidResponse[i].creativeId); - expect(resp.netRevenue).to.equal(prebidResponse[i].netRevenue); - expect(resp.currency).to.equal(prebidResponse[i].currency); - expect(resp.aid).to.equal(prebidResponse[i].aid); - if (resp.mediaType === 'video' && resp.renderer) { - expect(resp.vastUrl.indexOf('vast.xml')).to.be.greaterThan(0); - expect(resp.width).to.equal(prebidResponse[i].width); - expect(resp.height).to.equal(prebidResponse[i].height); - expect(resp.renderer).to.be.ok; - } else if (resp.mediaType === 'video') { - expect(resp.vastUrl.indexOf('vast.xml')).to.be.greaterThan(0); - expect(resp.ad).to.be.undefined; - expect(resp.width).to.be.undefined; - expect(resp.height).to.be.undefined; - } else { - expect(resp.ad.indexOf('localhost')).to.be.greaterThan(0); - expect(resp.width).to.equal(prebidResponse[i].width); - expect(resp.height).to.equal(prebidResponse[i].height); - } - }); - }); - }); - - describe('.getUserSyncs', function () { - let bidResponse = [{ - 'body': { - 'sbi_px': [{ - 'code': 'so', - 'delay': 0, - 'url': 'https://pixel-test', - 'type': 'image' - }] - } - }]; - - it('should return one sync pixel', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, bidResponse)).to.deep.equal([{ - type: 'image', - url: 'https://pixel-test' - }]); - }) - it('should return an empty array when sync is enabled but there are no bidResponses', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, [])).to.have.length(0); - }) - - it('should return an empty array when sync is enabled but no sync pixel returned', function () { - const pixel = Object.assign({}, bidResponse); - delete pixel[0].body.sbi_px; - expect(spec.getUserSyncs({ pixelEnabled: true }, bidResponse)).to.have.length(0); - }) - - it('should return an empty array', function () { - expect(spec.getUserSyncs({ pixelEnabled: false }, bidResponse)).to.have.length(0); - expect(spec.getUserSyncs({ pixelEnabled: true }, [])).to.have.length(0); - }); - }) - describe('_getPlatform', function () { - it('should return mobile', function () { - expect(_getPlatform({innerWidth: 767})).to.equal('mobile') - }) - it('should return tablet', function () { - expect(_getPlatform({innerWidth: 800})).to.equal('tablet') - }) - it('should return desktop', function () { - expect(_getPlatform({innerWidth: 1000})).to.equal('desktop') - }) - }) -}) diff --git a/test/spec/modules/sortableAnalyticsAdapter_spec.js b/test/spec/modules/sortableAnalyticsAdapter_spec.js deleted file mode 100644 index 258c4b8f74d..00000000000 --- a/test/spec/modules/sortableAnalyticsAdapter_spec.js +++ /dev/null @@ -1,307 +0,0 @@ -import {expect} from 'chai'; -import sortableAnalyticsAdapter, {TIMEOUT_FOR_REGISTRY, DEFAULT_PBID_TIMEOUT} from 'modules/sortableAnalyticsAdapter.js'; -import events from 'src/events.js'; -import CONSTANTS from 'src/constants.json'; -import * as prebidGlobal from 'src/prebidGlobal.js'; -import {server} from 'test/mocks/xhr.js'; - -describe('Sortable Analytics Adapter', function() { - let sandbox; - let clock; - - const initialConfig = { - provider: 'sortable', - options: { - siteId: 'testkey' - } - }; - - const TEST_DATA = { - AUCTION_INIT: { - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - timeout: 3000 - }, - BID_REQUESTED: { - refererInfo: { - referer: 'test.com', - reachedTop: true, - numIframes: 1 - }, - bidderCode: 'sortable', - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - bids: [{ - bidder: 'sortable', - params: { - tagId: 'medrec_1' - }, - adUnitCode: '300x250', - transactionId: 'aa02b498-8a99-418e-bc59-6b6fd45f32de', - sizes: [ - [300, 250] - ], - bidId: '26721042674416', - bidderRequestId: '10141593b1d84a', - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - bidRequestsCount: 1 - }, { - bidder: 'sortable', - params: { - tagId: 'lead_1' - }, - adUnitCode: '728x90', - transactionId: 'b7e9e957-af4f-4c47-8ca7-41f01cb4f105', - sizes: [ - [728, 90] - ], - bidId: '50fa575b41e596', - bidderRequestId: '37a8760be6db23', - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - bidRequestsCount: 1 - }], - start: 1553529405788 - }, - BID_ADJUSTMENT_1: { - bidderCode: 'sortable', - adId: '88221d316425f7', - mediaType: 'banner', - cpm: 0.70, - dealId: null, - currency: 'USD', - netRevenue: true, - ttl: 60, - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - responseTimestamp: 1553534161763, - bidder: 'sortable', - adUnitCode: '300x250', - timeToRespond: 331, - width: '300', - height: '250' - }, - AUCTION_END: { - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e' - }, - BID_ADJUSTMENT_2: { - bidderCode: 'sortable', - adId: '88221d316425f8', - mediaType: 'banner', - cpm: 0.50, - dealId: null, - currency: 'USD', - netRevenue: true, - ttl: 60, - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - responseTimestamp: 1553534161770, - bidder: 'sortable', - adUnitCode: '728x90', - timeToRespond: 338, - width: '728', - height: '90' - }, - BID_WON_1: { - bidderCode: 'sortable', - adId: '88221d316425f7', - mediaType: 'banner', - cpm: 0.70, - dealId: null, - currency: 'USD', - netRevenue: true, - ttl: 60, - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - responseTimestamp: 1553534161763, - bidder: 'sortable', - adUnitCode: '300x250', - timeToRespond: 331 - }, - BID_WON_2: { - bidderCode: 'sortable', - adId: '88221d316425f8', - mediaType: 'banner', - cpm: 0.50, - dealId: null, - currency: 'USD', - netRevenue: true, - ttl: 60, - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - responseTimestamp: 1553534161770, - bidder: 'sortable', - adUnitCode: '728x90', - timeToRespond: 338 - }, - BID_TIMEOUT: [{ - auctionId: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - adUnitCode: '300x250', - bidder: 'sortable' - }] - }; - - beforeEach(function() { - sandbox = sinon.sandbox.create(); - clock = sandbox.useFakeTimers(); - sandbox.stub(events, 'getEvents').returns([]); - sandbox.stub(prebidGlobal, 'getGlobal').returns({ - version: '1.0', - bidderSettings: { - 'sortable': { - bidCpmAdjustment: function (number) { - return number * 0.95; - } - } - } - }); - - sortableAnalyticsAdapter.enableAnalytics(initialConfig); - }); - - afterEach(function() { - sandbox.restore(); - clock.restore(); - sortableAnalyticsAdapter.disableAnalytics(); - }); - - describe('initialize adapter', function() { - const settings = sortableAnalyticsAdapter.getOptions(); - - it('should init settings correctly and apply defaults', function() { - expect(settings).to.include({ - 'disableSessionTracking': false, - 'key': initialConfig.options.siteId, - 'protocol': 'https', - 'url': `https://pa.deployads.com/pae/${initialConfig.options.siteId}`, - 'timeoutForPbid': DEFAULT_PBID_TIMEOUT - }); - }); - it('should assign a pageview ID', function() { - expect(settings).to.have.own.property('pageviewId'); - }); - }); - - describe('events tracking', function() { - beforeEach(function() { - server.requests = []; - }); - it('should send the PBID event', function() { - events.emit(CONSTANTS.EVENTS.AUCTION_INIT, TEST_DATA.AUCTION_INIT); - events.emit(CONSTANTS.EVENTS.BID_REQUESTED, TEST_DATA.BID_REQUESTED); - events.emit(CONSTANTS.EVENTS.BID_ADJUSTMENT, TEST_DATA.BID_ADJUSTMENT_1); - events.emit(CONSTANTS.EVENTS.BID_ADJUSTMENT, TEST_DATA.BID_ADJUSTMENT_2); - events.emit(CONSTANTS.EVENTS.AUCTION_END, TEST_DATA.AUCTION_END); - events.emit(CONSTANTS.EVENTS.BID_WON, TEST_DATA.BID_WON_1); - events.emit(CONSTANTS.EVENTS.BID_WON, TEST_DATA.BID_WON_2); - - clock.tick(DEFAULT_PBID_TIMEOUT); - - expect(server.requests.length).to.equal(1); - let result = JSON.parse(server.requests[0].requestBody); - expect(result).to.have.own.property('pbid'); - expect(result.pbid).to.deep.include({ - ai: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - ac: ['300x250', '728x90'], - adi: ['88221d316425f7', '88221d316425f8'], - bs: 'sortable', - bid: ['26721042674416', '50fa575b41e596'], - bif: 0.95, - brc: 1, - brid: ['10141593b1d84a', '37a8760be6db23'], - rs: ['300x250', '728x90'], - btcp: [0.70, 0.50], - btcc: 'USD', - btin: true, - btsrc: 'sortable', - c: [0.70, 0.50], - cc: 'USD', - did: null, - inr: true, - it: true, - iw: true, - ito: false, - mt: 'banner', - rtp: true, - nif: 1, - pbv: '1.0', - siz: ['300x250', '728x90'], - st: 1553529405788, - tgid: ['medrec_1', 'lead_1'], - to: 3000, - trid: ['aa02b498-8a99-418e-bc59-6b6fd45f32de', 'b7e9e957-af4f-4c47-8ca7-41f01cb4f105'], - ttl: 60, - ttr: [331, 338], - u: 'test.com', - _count: 2 - }); - }); - - it('should track a late bidWon event', function() { - events.emit(CONSTANTS.EVENTS.AUCTION_INIT, TEST_DATA.AUCTION_INIT); - events.emit(CONSTANTS.EVENTS.BID_REQUESTED, TEST_DATA.BID_REQUESTED); - events.emit(CONSTANTS.EVENTS.BID_ADJUSTMENT, TEST_DATA.BID_ADJUSTMENT_1); - events.emit(CONSTANTS.EVENTS.AUCTION_END, TEST_DATA.AUCTION_END); - - clock.tick(DEFAULT_PBID_TIMEOUT); - - events.emit(CONSTANTS.EVENTS.BID_WON, TEST_DATA.BID_WON_1); - - clock.tick(TIMEOUT_FOR_REGISTRY); - - expect(server.requests.length).to.equal(2); - const pbid_req = JSON.parse(server.requests[0].requestBody); - expect(pbid_req).to.have.own.property('pbid'); - const pbwon_req = JSON.parse(server.requests[1].requestBody); - expect(pbwon_req).to.have.own.property('pbrw'); - expect(pbwon_req.pbrw).to.deep.equal({ - ac: '300x250', - ai: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - bif: 0.95, - bs: 'sortable', - s: initialConfig.options.siteId, - cc: 'USD', - c: 0.70, - inr: true, - _count: 1, - _type: 'pbrw' - }); - }); - - it('should track late bidder timeouts', function() { - events.emit(CONSTANTS.EVENTS.AUCTION_INIT, TEST_DATA.AUCTION_INIT); - events.emit(CONSTANTS.EVENTS.BID_REQUESTED, TEST_DATA.BID_REQUESTED); - events.emit(CONSTANTS.EVENTS.AUCTION_END, TEST_DATA.AUCTION_END); - clock.tick(DEFAULT_PBID_TIMEOUT); - events.emit(CONSTANTS.EVENTS.BID_TIMEOUT, TEST_DATA.BID_TIMEOUT); - - clock.tick(TIMEOUT_FOR_REGISTRY); - - expect(server.requests.length).to.equal(2); - const pbid_req = JSON.parse(server.requests[0].requestBody); - expect(pbid_req).to.have.own.property('pbid'); - const pbto_req = JSON.parse(server.requests[1].requestBody); - expect(pbto_req).to.have.own.property('pbto'); - expect(pbto_req.pbto).to.deep.equal({ - ai: 'fb8d579a-5c3f-4705-ab94-3cff39005d9e', - s: initialConfig.options.siteId, - ac: '300x250', - bs: 'sortable', - _type: 'pbto', - _count: 1 - }); - }); - - it('should track errors', function() { - events.emit(CONSTANTS.EVENTS.AUCTION_INIT, TEST_DATA.AUCTION_INIT); - events.emit(CONSTANTS.EVENTS.BID_REQUESTED, {}); - - clock.tick(TIMEOUT_FOR_REGISTRY); - - expect(server.requests.length).to.equal(1); - const err_req = JSON.parse(server.requests[0].requestBody); - expect(err_req).to.have.own.property('pber'); - expect(err_req.pber).to.include({ - args: '{}', - s: initialConfig.options.siteId, - _count: 1, - ti: 'bidRequested', - _type: 'pber' - }); - expect(err_req.pber.msg).to.be.a('string'); - }); - }); -}); diff --git a/test/spec/modules/sortableBidAdapter_spec.js b/test/spec/modules/sortableBidAdapter_spec.js deleted file mode 100644 index 97f80e8dfeb..00000000000 --- a/test/spec/modules/sortableBidAdapter_spec.js +++ /dev/null @@ -1,572 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/sortableBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import * as utils from 'src/utils.js'; - -describe('sortableBidAdapter', function() { - const adapter = newBidder(spec); - - describe('isBidRequestValid', function () { - function makeBid() { - return { - 'bidder': 'sortable', - 'params': { - 'tagId': '403370', - 'siteId': 'example.com', - 'keywords': { - 'key1': 'val1', - 'key2': 'val2' - }, - 'floorSizeMap': { - '728x90': 0.15, - '300x250': 1.20 - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250] - ], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - } - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(makeBid())).to.equal(true); - }); - - it('should return false when tagId not passed correctly', function () { - let bid = makeBid(); - delete bid.params.tagId; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when sizes not passed correctly', function () { - let bid = makeBid(); - delete bid.sizes; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when sizes are wrong length', function () { - let bid = makeBid(); - bid.sizes = [[300]]; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when sizes are empty', function () { - let bid = makeBid(); - bid.sizes = []; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when require params are not passed', function () { - let bid = makeBid(); - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when the floorSizeMap is invalid', function () { - let bid = makeBid(); - bid.params.floorSizeMap = { - 'sixforty by foureighty': 1234 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - bid.params.floorSizeMap = { - '728x90': 'three' - } - expect(spec.isBidRequestValid(bid)).to.equal(false); - bid.params.floorSizeMap = 'a'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return true when the floorSizeMap is missing or empty', function () { - let bid = makeBid(); - bid.params.floorSizeMap = {}; - expect(spec.isBidRequestValid(bid)).to.equal(true); - delete bid.params.floorSizeMap; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - it('should return false when the keywords are invalid', function () { - let bid = makeBid(); - bid.params.keywords = { - 'badval': 1234 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - bid.params.keywords = 'a'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return true when the keywords are missing or empty', function () { - let bid = makeBid(); - bid.params.keywords = {}; - expect(spec.isBidRequestValid(bid)).to.equal(true); - delete bid.params.keywords; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return true with video media type', () => { - const videoBid = { - 'bidder': 'sortable', - 'params': { - 'tagId': '403370', - 'siteId': 'example.com', - }, - 'adUnitCode': 'adunit-code', - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'mediaTypes': { - 'video': { - } - } - }; - expect(spec.isBidRequestValid(videoBid)).to.equal(true); - }); - }); - - describe('buildRequests', function () { - const bidRequests = [{ - 'bidder': 'sortable', - 'params': { - 'tagId': '403370', - 'siteId': 'example.com', - 'floor': 0.21, - 'keywords': { - 'key1': 'val1', - 'key2': 'val2' - }, - 'floorSizeMap': { - '728x90': 0.15, - '300x250': 1.20 - } - }, - 'sizes': [ - [300, 250] - ], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }, { - 'bidder': 'sortable', - 'params': { - 'tagId': '403371', - 'siteId': 'example.com', - 'floor': 0.21 - }, - 'sizes': [ - [300, 250] - ], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'mediaTypes': { - 'native': { - 'body': {'required': true, 'sendId': true}, - 'clickUrl': {'required': true, 'sendId': true}, - 'cta': {'required': true, 'sendId': true}, - 'icon': {'required': true, 'sendId': true}, - 'image': {'required': true, 'sendId': true}, - 'sponsoredBy': {'required': true, 'sendId': true}, - 'title': {'required': true, 'sendId': true, 'len': 100} - } - } - }]; - - const request = spec.buildRequests(bidRequests, {refererInfo: { referer: 'http://example.com/page?param=val' }}); - const requestBody = JSON.parse(request.data); - - it('sends bid request to our endpoint via POST', function () { - expect(request.method).to.equal('POST'); - }); - - it('attaches source and version to endpoint URL as query params', function () { - const ENDPOINT = `https://c.deployads.com/openrtb2/auction?src=$$REPO_AND_VERSION$$&host=example.com`; - expect(request.url).to.equal(ENDPOINT); - }); - - it('sends screen dimensions', function () { - expect(requestBody.site.device.w).to.equal(screen.width); - expect(requestBody.site.device.h).to.equal(screen.height); - }); - - it('includes the ad size in the bid request', function () { - expect(requestBody.imp[0].banner.format[0].w).to.equal(300); - expect(requestBody.imp[0].banner.format[0].h).to.equal(250); - }); - - it('includes the params in the bid request', function () { - expect(requestBody.imp[0].ext.keywords).to.deep.equal( - {'key1': 'val1', - 'key2': 'val2'} - ); - expect(requestBody.site.publisher.id).to.equal('example.com'); - expect(requestBody.imp[0].tagid).to.equal('403370'); - expect(requestBody.imp[0].bidfloor).to.equal(0.21); - }); - - it('should have the floor size map set', function () { - expect(requestBody.imp[0].ext.floorSizeMap).to.deep.equal({ - '728x90': 0.15, - '300x250': 1.20 - }); - }); - - it('sets domain and href correctly', function () { - expect(requestBody.site.domain).to.equal('example.com'); - expect(requestBody.site.page).to.equal('http://example.com/page?param=val'); - }); - - it('should have the version in native object set for native bid', function() { - expect(requestBody.imp[1].native.ver).to.equal('1'); - }); - - it('should have the assets set for native bid', function() { - const assets = JSON.parse(requestBody.imp[1].native.request).assets; - expect(assets[0]).to.deep.equal({'title': {'len': 100}, 'required': 1, 'id': 0}); - expect(assets[1]).to.deep.equal({'img': {'type': 3, 'wmin': 1, 'hmin': 1}, 'required': 1, 'id': 1}); - expect(assets[2]).to.deep.equal({'img': {'type': 1, 'wmin': 1, 'hmin': 1}, 'required': 1, 'id': 2}); - expect(assets[3]).to.deep.equal({'data': {'type': 2}, 'required': 1, 'id': 3}); - expect(assets[4]).to.deep.equal({'data': {'type': 12}, 'required': 1, 'id': 4}); - expect(assets[5]).to.deep.equal({'data': {'type': 1}, 'required': 1, 'id': 5}); - }); - - const videoBidRequests = [{ - 'bidder': 'sortable', - 'params': { - 'tagId': '403370', - 'siteId': 'example.com', - 'video': { - 'minduration': 5, - 'maxduration': 10, - 'startdelay': 0 - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'mediaTypes': { - 'video': { - 'context': 'instream', - 'mimes': ['video/x-ms-wmv'], - 'playerSize': [[400, 300]], - 'api': [0], - 'protocols': [2, 3], - 'playbackmethod': [1] - } - } - }]; - - const videoRequest = spec.buildRequests(videoBidRequests, {refererInfo: { referer: 'http://localhost:9876/' }}); - const videoRequestBody = JSON.parse(videoRequest.data); - - it('should include video params', () => { - const video = videoRequestBody.imp[0].video; - expect(video.mimes).to.deep.equal(['video/x-ms-wmv']); - expect(video.w).to.equal(400); - expect(video.h).to.equal(300); - expect(video.api).to.deep.equal([0]); - expect(video.protocols).to.deep.equal([2, 3]); - expect(video.playbackmethod).to.deep.equal([1]); - expect(video.minduration).to.equal(5); - expect(video.maxduration).to.equal(10); - expect(video.startdelay).to.equal(0); - }); - - it('sets domain and href correctly', function () { - expect(videoRequestBody.site.domain).to.equal('localhost'); - expect(videoRequestBody.site.page).to.equal('http://localhost:9876/'); - }); - - const gdprBidRequests = [{ - 'bidder': 'sortable', - 'params': { - 'tagId': '403370', - 'siteId': 'example.com', - 'floor': 0.21, - 'keywords': {}, - 'floorSizeMap': {} - }, - 'sizes': [ - [300, 250] - ], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }]; - const consentString = 'BOJ/P2HOJ/P2HABABMAAAAAZ+A=='; - - function getGdprRequestBody(gdprApplies, consentString) { - const gdprRequest = spec.buildRequests(gdprBidRequests, {'gdprConsent': { - 'gdprApplies': gdprApplies, - 'consentString': consentString - }, - refererInfo: { - referer: 'http://localhost:9876/' - }}); - return JSON.parse(gdprRequest.data); - } - - it('should handle gdprApplies being present and true', function() { - const gdprRequestBody = getGdprRequestBody(true, consentString); - expect(gdprRequestBody.regs.ext.gdpr).to.equal(1); - expect(gdprRequestBody.user.ext.consent).to.equal(consentString); - }) - - it('should handle gdprApplies being present and false', function() { - const gdprRequestBody = getGdprRequestBody(false, consentString); - expect(gdprRequestBody.regs.ext.gdpr).to.equal(0); - expect(gdprRequestBody.user.ext.consent).to.equal(consentString); - }) - - it('should handle gdprApplies being undefined', function() { - const gdprRequestBody = getGdprRequestBody(undefined, consentString); - expect(gdprRequestBody.regs).to.deep.equal({ext: {}}); - expect(gdprRequestBody.user.ext.consent).to.equal(consentString); - }) - - it('should handle gdprConsent being undefined', function() { - const gdprRequest = spec.buildRequests(gdprBidRequests, {refererInfo: { referer: 'http://localhost:9876/' }}); - const gdprRequestBody = JSON.parse(gdprRequest.data); - expect(gdprRequestBody.regs).to.deep.equal({ext: {}}); - expect(gdprRequestBody.user.ext.consent).to.equal(undefined); - }) - - const eidsBidRequests = [{ - 'bidder': 'sortable', - 'params': { - 'tagId': '403370', - 'siteId': 'example.com', - 'floor': 0.21, - 'keywords': {}, - 'floorSizeMap': {} - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }]; - - it('should not set user ids when none present', function() { - const eidsRequest = spec.buildRequests(eidsBidRequests, {refererInfo: { - referer: 'http://localhost:9876/' - }}); - const eidsRequestBody = JSON.parse(eidsRequest.data); - - expect(eidsRequestBody.user.ext.eids).to.equal(undefined); - }) - - it('should set user ids when present', function() { - eidsBidRequests[0].userId = { criteoId: 'sample-userid' }; - const eidsRequest = spec.buildRequests(eidsBidRequests, {refererInfo: { - referer: 'http://localhost:9876/' - }}); - const eidsRequestBody = JSON.parse(eidsRequest.data); - - expect(eidsRequestBody.user.ext.eids.length).to.equal(1); - }) - }); - - describe('interpretResponse', function () { - function makeResponse() { - return { - body: { - 'id': '5e5c23a5ba71e78', - 'seatbid': [ - { - 'bid': [ - { - 'id': '6vmb3isptf', - 'crid': 'sortablescreative', - 'impid': '322add653672f68', - 'price': 1.22, - 'adm': '', - 'attr': [5], - 'h': 90, - 'nurl': 'http://nurl', - 'w': 728 - } - ], - 'seat': 'MOCK' - } - ], - 'bidid': '5e5c23a5ba71e78' - } - }; - } - - function makeNativeResponse() { - return { - body: { - 'id': '5e5c23a5ba71e77', - 'seatbid': [ - { - 'bid': [ - { - 'id': '6vmb3isptf', - 'crid': 'sortablescreative', - 'impid': '322add653672f67', - 'price': 1.55, - 'adm': '{"native":{"link":{"clicktrackers":[],"url":"https://www.sortable.com/"},"assets":[{"title":{"text":"Ads With Sortable"},"id":1},{"img":{"w":790,"url":"https://path.to/image","h":294},"id":2},{"img":{"url":"https://path.to/icon"},"id":3},{"data":{"value":"Body here"},"id":4},{"data":{"value":"Learn More"},"id":5},{"data":{"value":"Sortable"},"id":6}],"imptrackers":[],"ver":1}}', - 'ext': {'ad_format': 'native'}, - 'h': 90, - 'nurl': 'http://nurl', - 'w': 728 - } - ], - 'seat': 'MOCK' - } - ], - 'bidid': '5e5c23a5ba71e77' - } - }; - } - - const expectedBid = { - 'requestId': '322add653672f68', - 'cpm': 1.22, - 'width': 728, - 'height': 90, - 'creativeId': 'sortablescreative', - 'dealId': null, - 'currency': 'USD', - 'netRevenue': true, - 'mediaType': 'banner', - 'ttl': 60, - 'ad': '
' - }; - - const expectedNativeBid = { - 'requestId': '322add653672f67', - 'cpm': 1.55, - 'width': 728, - 'height': 90, - 'creativeId': 'sortablescreative', - 'dealId': null, - 'currency': 'USD', - 'netRevenue': true, - 'sortable': { 'ad_format': 'native' }, - 'mediaType': 'native', - 'ttl': 60, - 'native': { - 'clickUrl': 'https://www.sortable.com/', - 'title': 'Ads With Sortable', - 'image': {'url': 'https://path.to/image', 'height': 294, 'width': 790}, - 'icon': 'https://path.to/icon', - 'body': 'Body here', - 'cta': 'Learn More', - 'sponsoredBy': 'Sortable' - } - }; - - it('should get the correct bid response', function () { - let result = spec.interpretResponse(makeResponse()); - expect(result.length).to.equal(1); - expect(result[0]).to.deep.equal(expectedBid); - }); - - it('should handle a missing crid', function () { - let noCridResponse = makeResponse(); - delete noCridResponse.body.seatbid[0].bid[0].crid; - const fallbackCrid = noCridResponse.body.seatbid[0].bid[0].id; - let noCridResult = Object.assign({}, expectedBid, {'creativeId': fallbackCrid}); - let result = spec.interpretResponse(noCridResponse); - expect(result.length).to.equal(1); - expect(result[0]).to.deep.equal(noCridResult); - }); - - it('should handle a missing nurl', function () { - let noNurlResponse = makeResponse(); - delete noNurlResponse.body.seatbid[0].bid[0].nurl; - let noNurlResult = Object.assign({}, expectedBid); - noNurlResult.ad = ''; - let result = spec.interpretResponse(noNurlResponse); - expect(result.length).to.equal(1); - expect(result[0]).to.deep.equal(noNurlResult); - }); - - it('should handle a missing adm', function () { - let noAdmResponse = makeResponse(); - delete noAdmResponse.body.seatbid[0].bid[0].adm; - let noAdmResult = Object.assign({}, expectedBid); - delete noAdmResult.ad; - noAdmResult.adUrl = 'http://nurl'; - let result = spec.interpretResponse(noAdmResponse); - expect(result.length).to.equal(1); - expect(result[0]).to.deep.equal(noAdmResult); - }); - - it('handles empty bid response', function () { - let response = { - body: { - 'id': '5e5c23a5ba71e78', - 'seatbid': [] - } - }; - let result = spec.interpretResponse(response); - expect(result.length).to.equal(0); - }); - - it('should get the correct native bid response', function () { - let result = spec.interpretResponse(makeNativeResponse()); - expect(result.length).to.equal(1); - expect(result[0]).to.deep.equal(expectedNativeBid); - }); - - it('fail to parse invalid native bid response', function () { - let response = makeNativeResponse(); - response.body.seatbid[0].bid[0].adm = ''; - let result = spec.interpretResponse(response); - expect(result.length).to.equal(0); - }); - - it('should keep custom properties', () => { - 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); - expect(result.length).to.equal(1); - expect(result[0]).to.deep.equal(expectedResult); - }); - - it('should handle instream response', () => { - const response = makeResponse(); - const bid = response.body.seatbid[0].bid[0]; - delete bid.nurl; - bid.ext = {ad_format: 'instream'}; - const result = spec.interpretResponse(response)[0]; - expect(result.mediaType).to.equal('video'); - expect(result.vastXml).to.equal(bid.adm); - }); - - it('should return iframe syncs', () => { - const syncResponse = { - ext: { - sync_dsps: [ - ['iframe', 'http://example-dsp/sync-iframe'], - ['image', 'http://example-dsp/sync-image'] - ] - } - }; - expect(spec.getUserSyncs({iframeEnabled: true}, [{body: syncResponse}])).to.deep.equal([{ - type: 'iframe', - url: 'http://example-dsp/sync-iframe' - }]); - }); - - it('should return image syncs', () => { - const syncResponse = { - ext: { - sync_dsps: [ - ['iframe', 'http://example-dsp/sync-iframe'], - ['image', 'http://example-dsp/sync-image'] - ] - } - }; - expect(spec.getUserSyncs({pixelEnabled: true}, [{body: syncResponse}])).to.deep.equal([{ - type: 'image', - url: 'http://example-dsp/sync-image' - }]); - }); - }); -}); diff --git a/test/spec/modules/sovrnAnalyticsAdapter_spec.js b/test/spec/modules/sovrnAnalyticsAdapter_spec.js deleted file mode 100644 index d6795331417..00000000000 --- a/test/spec/modules/sovrnAnalyticsAdapter_spec.js +++ /dev/null @@ -1,541 +0,0 @@ -import sovrnAnalyticsAdapter from '../../../modules/sovrnAnalyticsAdapter.js'; -import { expect } from 'chai'; -import {config} from 'src/config.js'; -import adaptermanager from 'src/adapterManager.js'; -import { server } from 'test/mocks/xhr.js'; -var assert = require('assert'); - -let events = require('src/events'); -let constants = require('src/constants.json'); - -/** - * Emit analytics events - * @param {array} eventArr - array of objects to define the events that will fire - * @param {object} eventObj - key is eventType, value is event - * @param {string} auctionId - the auction id to attached to the events - */ -function emitEvent(eventType, event, auctionId) { - event.auctionId = auctionId; - events.emit(constants.EVENTS[eventType], event); -} - -let auctionStartTimestamp = Date.now(); -let timeout = 3000; -let auctionInit = { - timestamp: auctionStartTimestamp, - timeout: timeout -}; -let bidderCode = 'sovrn'; -let bidderRequestId = '123bri'; -let adUnitCode = 'div'; -let adUnitCode2 = 'div2'; -let bidId = 'bidid'; -let bidId2 = 'bidid2'; -let tId = '7aafa3ee-a80a-46d7-a4a0-cbcba463d97a'; -let tId2 = '99dca3ee-a80a-46d7-a4a0-cbcba463d97e'; -let bidRequested = { - auctionStart: auctionStartTimestamp, - bidderCode: bidderCode, - bidderRequestId: bidderRequestId, - bids: [ - { - adUnitCode: adUnitCode, - bidId: bidId, - bidder: bidderCode, - bidderRequestId: '10340af0c7dc72', - sizes: [[300, 250]], - startTime: auctionStartTimestamp + 100, - transactionId: tId - }, - { - adUnitCode: adUnitCode2, - bidId: bidId2, - bidder: bidderCode, - bidderRequestId: '10340af0c7dc72', - sizes: [[300, 250]], - startTime: auctionStartTimestamp + 100, - transactionId: tId2 - } - ], - doneCbCallCount: 1, - start: auctionStartTimestamp, - timeout: timeout -}; -let bidResponse = { - bidderCode: bidderCode, - width: 300, - height: 250, - statusMessage: 'Bid available', - adId: '3870e27a5752fb', - mediaType: 'banner', - source: 'client', - requestId: bidId, - cpm: 0.8584999918937682, - creativeId: 'cridprebidrtb', - dealId: null, - currency: 'USD', - netRevenue: true, - ad: '
divvy mcdiv
', - ttl: 60000, - responseTimestamp: auctionStartTimestamp + 150, - requestTimestamp: auctionStartTimestamp + 100, - bidder: bidderCode, - adUnitCode: adUnitCode, - timeToRespond: 50, - pbLg: '0.50', - pbMg: '0.80', - pbHg: '0.85', - pbAg: '0.85', - pbDg: '0.85', - pbCg: '', - size: '300x250', - adserverTargeting: { - hb_bidder: bidderCode, - hb_adid: '3870e27a5752fb', - hb_pb: '0.85' - }, - status: 'rendered' -}; - -let bidResponse2 = { - bidderCode: bidderCode, - width: 300, - height: 250, - statusMessage: 'Bid available', - adId: '9999e27a5752fb', - mediaType: 'banner', - source: 'client', - requestId: bidId2, - cpm: 0.12, - creativeId: 'cridprebidrtb', - dealId: null, - currency: 'USD', - netRevenue: true, - ad: '
divvy mcdiv
', - ttl: 60000, - responseTimestamp: auctionStartTimestamp + 150, - requestTimestamp: auctionStartTimestamp + 100, - bidder: bidderCode, - adUnitCode: adUnitCode2, - timeToRespond: 50, - pbLg: '0.10', - pbMg: '0.10', - pbHg: '0.10', - pbAg: '0.10', - pbDg: '0.10', - pbCg: '', - size: '300x250', - adserverTargeting: { - hb_bidder: bidderCode, - hb_adid: '9999e27a5752fb', - hb_pb: '0.10' - }, - status: 'rendered' -}; -let bidAdjustment = {}; -for (var k in bidResponse) bidAdjustment[k] = bidResponse[k]; -bidAdjustment.cpm = 0.8; -let bidAdjustmentNoMatchingRequest = { - bidderCode: 'not-sovrn', - width: 300, - height: 250, - statusMessage: 'Bid available', - adId: '1', - mediaType: 'banner', - source: 'client', - requestId: '1', - cpm: 0.10, - creativeId: '', - dealId: null, - currency: 'USD', - netRevenue: true, - ad: '
divvy mcdiv
', - ttl: 60000, - responseTimestamp: auctionStartTimestamp + 150, - requestTimestamp: auctionStartTimestamp + 100, - bidder: 'not-sovrn', - adUnitCode: '', - timeToRespond: 50, - pbLg: '0.00', - pbMg: '0.10', - pbHg: '0.10', - pbAg: '0.10', - pbDg: '0.10', - pbCg: '', - size: '300x250', - adserverTargeting: { - hb_bidder: 'not-sovrn', - hb_adid: '1', - hb_pb: '0.10' - }, -}; -let bidResponseNoMatchingRequest = bidAdjustmentNoMatchingRequest; - -describe('Sovrn Analytics Adapter', function () { - beforeEach(() => { - sinon.stub(events, 'getEvents').returns([]); - }); - afterEach(() => { - events.getEvents.restore(); - }); - - describe('enableAnalytics ', function () { - beforeEach(() => { - sinon.spy(sovrnAnalyticsAdapter, 'track'); - }); - afterEach(() => { - sovrnAnalyticsAdapter.disableAnalytics(); - sovrnAnalyticsAdapter.track.restore(); - }); - - it('should catch all events if affiliate id present', function () { - adaptermanager.enableAnalytics({ - provider: 'sovrn', - options: { - sovrnId: 123 - } - }); - - events.emit(constants.EVENTS.AUCTION_INIT, {}); - events.emit(constants.EVENTS.AUCTION_END, {}); - events.emit(constants.EVENTS.BID_REQUESTED, {}); - events.emit(constants.EVENTS.BID_RESPONSE, {}); - events.emit(constants.EVENTS.BID_WON, {}); - - sinon.assert.callCount(sovrnAnalyticsAdapter.track, 5); - }); - - it('should catch no events if no affiliate id', function () { - adaptermanager.enableAnalytics({ - provider: 'sovrn', - options: { - } - }); - - events.emit(constants.EVENTS.AUCTION_INIT, {}); - events.emit(constants.EVENTS.AUCTION_END, {}); - events.emit(constants.EVENTS.BID_REQUESTED, {}); - events.emit(constants.EVENTS.BID_RESPONSE, {}); - events.emit(constants.EVENTS.BID_WON, {}); - - sinon.assert.callCount(sovrnAnalyticsAdapter.track, 0); - }); - }); - - describe('sovrnAnalyticsAdapter ', function() { - beforeEach(() => { - sovrnAnalyticsAdapter.enableAnalytics({ - provider: 'sovrn', - options: { - sovrnId: 123 - } - }); - sinon.spy(sovrnAnalyticsAdapter, 'track'); - }); - afterEach(() => { - sovrnAnalyticsAdapter.disableAnalytics(); - sovrnAnalyticsAdapter.track.restore(); - }); - it('should have correct type', function () { - assert.equal(sovrnAnalyticsAdapter.getAdapterType(), 'endpoint') - }) - }); - - describe('auction data collector ', function() { - beforeEach(() => { - sovrnAnalyticsAdapter.enableAnalytics({ - provider: 'sovrn', - options: { - sovrnId: 123 - } - }); - sinon.spy(sovrnAnalyticsAdapter, 'track'); - }); - afterEach(() => { - sovrnAnalyticsAdapter.disableAnalytics(); - sovrnAnalyticsAdapter.track.restore(); - }); - it('should create auctiondata record from init ', function () { - let auctionId = '123.123.123.123'; - emitEvent('AUCTION_INIT', auctionInit, auctionId); - - let auctionData = sovrnAnalyticsAdapter.getAuctions(); - let currentAuction = auctionData[auctionId]; - assert(currentAuction); - let expectedTimeOutData = { - buffer: config.getConfig('timeoutBuffer'), - bidder: config.getConfig('bidderTimeout'), - }; - expect(currentAuction.auction.timeouts).to.deep.equal(expectedTimeOutData); - assert.equal(currentAuction.auction.payload, 'auction'); - assert.equal(currentAuction.auction.priceGranularity, config.getConfig('priceGranularity')) - assert.equal(currentAuction.auction.auctionId, auctionId); - assert.equal(currentAuction.auction.sovrnId, 123); - }); - it('should create a bidrequest object ', function() { - let auctionId = '234.234.234.234'; - emitEvent('AUCTION_INIT', auctionInit, auctionId); - emitEvent('BID_REQUESTED', bidRequested, auctionId); - - let auctionData = sovrnAnalyticsAdapter.getAuctions(); - let currentAuction = auctionData[auctionId]; - assert(currentAuction); - let requests = currentAuction.auction.requests; - assert(requests); - assert.equal(requests.length, 1); - assert.equal(requests[0].bidderCode, bidderCode); - assert.equal(requests[0].bidderRequestId, bidderRequestId); - assert.equal(requests[0].timeout, timeout); - let bids = requests[0].bids; - assert(bids); - assert.equal(bids.length, 2); - assert.equal(bids[0].bidId, bidId); - assert.equal(bids[0].bidder, bidderCode); - assert.equal(bids[0].transactionId, tId); - assert.equal(bids[0].sizes.length, 1); - assert.equal(bids[0].sizes[0][0], 300); - assert.equal(bids[0].sizes[0][1], 250); - expect(requests[0]).to.not.have.property('doneCbCallCount'); - expect(requests[0]).to.not.have.property('auctionId'); - }); - it('should add results to the bid with response ', function () { - let auctionId = '345.345.345.345'; - emitEvent('AUCTION_INIT', auctionInit, auctionId); - emitEvent('BID_REQUESTED', bidRequested, auctionId); - emitEvent('BID_RESPONSE', bidResponse, auctionId); - - let auctionData = sovrnAnalyticsAdapter.getAuctions(); - let currentAuction = auctionData[auctionId]; - let returnedBid = currentAuction.auction.requests[0].bids[0]; - assert.equal(returnedBid.bidId, bidId); - assert.equal(returnedBid.bidder, bidderCode); - assert.equal(returnedBid.transactionId, tId); - assert.equal(returnedBid.sizes.length, 1); - assert.equal(returnedBid.sizes[0][0], 300); - assert.equal(returnedBid.sizes[0][1], 250); - assert.equal(returnedBid.adserverTargeting.hb_adid, '3870e27a5752fb'); - assert.equal(returnedBid.adserverTargeting.hb_bidder, bidderCode); - assert.equal(returnedBid.adserverTargeting.hb_pb, '0.85'); - assert.equal(returnedBid.cpm, 0.8584999918937682); - }); - it('should add new unsynced bid if no request exists for response ', function () { - let auctionId = '456.456.456.456'; - emitEvent('AUCTION_INIT', auctionInit, auctionId); - emitEvent('BID_REQUESTED', bidRequested, auctionId); - emitEvent('BID_RESPONSE', bidResponseNoMatchingRequest, auctionId); - - let auctionData = sovrnAnalyticsAdapter.getAuctions(); - let currentAuction = auctionData[auctionId]; - let requests = currentAuction.auction.requests; - assert(requests); - assert.equal(requests.length, 1); - let bidRequest = requests[0].bids[0]; - expect(bidRequest).to.not.have.property('adserverTargeting'); - expect(bidRequest).to.not.have.property('cpm'); - expect(currentAuction.auction.unsynced[0]).to.deep.equal(bidResponseNoMatchingRequest); - }); - it('should adjust the bid ', function () { - let auctionId = '567.567.567.567'; - emitEvent('AUCTION_INIT', auctionInit, auctionId); - emitEvent('BID_REQUESTED', bidRequested, auctionId); - emitEvent('BID_ADJUSTMENT', bidResponse, auctionId); - emitEvent('BID_RESPONSE', bidAdjustment, auctionId); - - let auctionData = sovrnAnalyticsAdapter.getAuctions(); - let currentAuction = auctionData[auctionId]; - let returnedBid = currentAuction.auction.requests[0].bids[0]; - assert.equal(returnedBid.cpm, 0.8); - assert.equal(returnedBid.originalValues.cpm, 0.8584999918937682); - }); - }); - describe('auction data send ', function() { - let expectedPostBody = { - sovrnId: 123, - auctionId: '678.678.678.678', - payload: 'auction', - priceGranularity: 'medium', - }; - let expectedRequests = { - bidderCode: 'sovrn', - bidderRequestId: '123bri', - timeout: 3000 - }; - let expectedBids = { - adUnitCode: 'div', - bidId: 'bidid', - bidder: 'sovrn', - bidderRequestId: '10340af0c7dc72', - transactionId: '7aafa3ee-a80a-46d7-a4a0-cbcba463d97a', - width: 300, - height: 250, - statusMessage: 'Bid available', - adId: '3870e27a5752fb', - mediaType: 'banner', - source: 'client', - cpm: 0.8584999918937682, - creativeId: 'cridprebidrtb', - dealId: null, - currency: 'USD', - netRevenue: true, - ttl: 60000, - timeToRespond: 50, - size: '300x250', - status: 'rendered', - isAuctionWinner: true - }; - let SecondAdUnitExpectedBids = { - adUnitCode: 'div2', - bidId: 'bidid2', - bidder: 'sovrn', - bidderRequestId: '10340af0c7dc72', - transactionId: '99dca3ee-a80a-46d7-a4a0-cbcba463d97e', - width: 300, - height: 250, - statusMessage: 'Bid available', - adId: '9999e27a5752fb', - mediaType: 'banner', - source: 'client', - cpm: 0.12, - creativeId: 'cridprebidrtb', - dealId: null, - currency: 'USD', - netRevenue: true, - ttl: 60000, - timeToRespond: 50, - size: '300x250', - status: 'rendered', - isAuctionWinner: true - }; - let expectedAdServerTargeting = { - hb_bidder: 'sovrn', - hb_adid: '3870e27a5752fb', - hb_pb: '0.85' - }; - beforeEach(() => { - sovrnAnalyticsAdapter.enableAnalytics({ - provider: 'sovrn', - options: { - sovrnId: 123 - } - }); - sinon.spy(sovrnAnalyticsAdapter, 'track'); - }); - afterEach(() => { - sovrnAnalyticsAdapter.disableAnalytics(); - sovrnAnalyticsAdapter.track.restore(); - }); - it('should send auction data ', function () { - let auctionId = '678.678.678.678'; - emitEvent('AUCTION_INIT', auctionInit, auctionId); - emitEvent('BID_REQUESTED', bidRequested, auctionId); - emitEvent('BID_RESPONSE', bidResponse, auctionId); - emitEvent('BID_RESPONSE', bidResponse2, auctionId) - emitEvent('AUCTION_END', {}, auctionId); - let requestBody = JSON.parse(server.requests[0].requestBody); - let requestsFromRequestBody = requestBody.requests[0]; - let bidsFromRequests = requestsFromRequestBody.bids[0]; - expect(requestBody).to.deep.include(expectedPostBody); - expect(requestBody.timeouts).to.deep.equal({buffer: 400, bidder: 3000}); - expect(requestsFromRequestBody).to.deep.include(expectedRequests); - expect(bidsFromRequests).to.deep.include(expectedBids); - let bidsFromRequests2 = requestsFromRequestBody.bids[1]; - expect(bidsFromRequests2).to.deep.include(SecondAdUnitExpectedBids); - expect(bidsFromRequests.adserverTargeting).to.deep.include(expectedAdServerTargeting); - }); - }); - describe('bid won data send ', function() { - let auctionId = '789.789.789.789'; - let creativeId = 'cridprebidrtb'; - let requestId = 'requestId69'; - let bidWonEvent = { - ad: 'html', - adId: 'adId', - adUnitCode: adUnitCode, - auctionId: auctionId, - bidder: bidderCode, - bidderCode: bidderCode, - cpm: 1.01, - creativeId: creativeId, - currency: 'USD', - height: 250, - mediaType: 'banner', - requestId: requestId, - size: '300x250', - source: 'client', - status: 'rendered', - statusMessage: 'Bid available', - timeToRespond: 421, - ttl: 60, - width: 300 - }; - let expectedBidWonBody = { - sovrnId: 123, - payload: 'winner' - }; - let expectedWinningBid = { - bidderCode: bidderCode, - width: 300, - height: 250, - statusMessage: 'Bid available', - adId: 'adId', - mediaType: 'banner', - source: 'client', - requestId: requestId, - cpm: 1.01, - creativeId: creativeId, - currency: 'USD', - ttl: 60, - auctionId: auctionId, - bidder: bidderCode, - adUnitCode: adUnitCode, - timeToRespond: 421, - size: '300x250', - }; - beforeEach(() => { - sovrnAnalyticsAdapter.enableAnalytics({ - provider: 'sovrn', - options: { - sovrnId: 123 - } - }); - sinon.spy(sovrnAnalyticsAdapter, 'track'); - }); - afterEach(() => { - sovrnAnalyticsAdapter.disableAnalytics(); - sovrnAnalyticsAdapter.track.restore(); - }); - it('should send bid won data ', function () { - emitEvent('AUCTION_INIT', auctionInit, auctionId); - emitEvent('BID_WON', bidWonEvent, auctionId); - let requestBody = JSON.parse(server.requests[0].requestBody); - expect(requestBody).to.deep.include(expectedBidWonBody); - expect(requestBody.winningBid).to.deep.include(expectedWinningBid); - }); - }); - describe('Error Tracking', function() { - beforeEach(() => { - sovrnAnalyticsAdapter.enableAnalytics({ - provider: 'sovrn', - options: { - sovrnId: 123 - } - }); - sinon.spy(sovrnAnalyticsAdapter, 'track'); - }); - afterEach(() => { - sovrnAnalyticsAdapter.disableAnalytics() - sovrnAnalyticsAdapter.track.restore() - }); - it('should send an error message when a bid is received for a closed auction', function() { - let auctionId = '678.678.678.678'; - emitEvent('AUCTION_INIT', auctionInit, auctionId) - emitEvent('BID_REQUESTED', bidRequested, auctionId) - emitEvent('AUCTION_END', {}, auctionId) - server.requests[0].respond(200) - emitEvent('BID_RESPONSE', bidResponse, auctionId) - let requestBody = JSON.parse(server.requests[1].requestBody) - expect(requestBody.payload).to.equal('error') - expect(requestBody.message).to.include('Event Received after Auction Close Auction Id') - }) - }) -}) diff --git a/test/spec/modules/sovrnBidAdapter_spec.js b/test/spec/modules/sovrnBidAdapter_spec.js deleted file mode 100644 index 729c48c28f4..00000000000 --- a/test/spec/modules/sovrnBidAdapter_spec.js +++ /dev/null @@ -1,686 +0,0 @@ -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$$`; - -const adUnitBidRequest = { - 'bidder': 'sovrn', - 'params': { - 'tagid': 403370 - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', -} -const bidderRequest = { - refererInfo: { - referer: 'http://example.com/page.html', - } -}; - -describe('sovrnBidAdapter', function() { - describe('isBidRequestValid', function () { - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(adUnitBidRequest)).to.equal(true); - }); - - it('should return false when tagid not passed correctly', function () { - const bid = {...adUnitBidRequest} - const params = adUnitBidRequest.params - bid.params = {...params} - bid.params.tagid = 'ABCD' - expect(spec.isBidRequestValid(bid)).to.equal(false) - }); - - it('should return false when require params are not passed', function () { - const bid = {...adUnitBidRequest} - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - describe('basic bid parameters', function() { - const bidRequests = [adUnitBidRequest]; - const request = spec.buildRequests(bidRequests, bidderRequest); - - it('sends bid request to our endpoint via POST', function () { - expect(request.method).to.equal('POST'); - }); - - it('attaches source and version to endpoint URL as query params', function () { - expect(request.url).to.equal(ENDPOINT) - }); - - it('sets the proper banner object', function() { - 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.w).to.equal(1) - expect(payload.imp[0].banner.h).to.equal(1) - }) - - it('includes the ad unit code int the request', function() { - const payload = JSON.parse(request.data); - expect(payload.imp[0].adunitcode).to.equal('adunit-code') - }) - - it('converts tagid to string', function () { - expect(request.data).to.contain('"tagid":"403370"') - }); - }) - - it('accepts a single array as a size', function() { - const singleSize = [{ - 'bidder': 'sovrn', - 'params': { - 'tagid': '403370', - 'iv': 'vet' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [300, 250], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }] - const request = spec.buildRequests(singleSize, bidderRequest) - const payload = JSON.parse(request.data) - expect(payload.imp[0].banner.format).to.deep.equal([{w: 300, h: 250}]) - expect(payload.imp[0].banner.w).to.equal(1) - expect(payload.imp[0].banner.h).to.equal(1) - }) - - it('sends \'iv\' as query param if present', function () { - const ivBidRequests = [{ - 'bidder': 'sovrn', - 'params': { - 'tagid': '403370', - 'iv': 'vet' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }]; - const bidderRequest = { - refererInfo: { - referer: 'http://example.com/page.html', - } - }; - const request = spec.buildRequests(ivBidRequests, bidderRequest); - - expect(request.url).to.contain('iv=vet') - }); - - it('sends gdpr info if exists', function () { - let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - const bidderRequest = { - 'bidderCode': 'sovrn', - 'auctionId': '1d1a030790a475', - 'bidderRequestId': '22edbae2733bf6', - 'timeout': 3000, - gdprConsent: { - consentString: consentString, - gdprApplies: true - }, - refererInfo: { - referer: 'http://example.com/page.html', - } - }; - bidderRequest.bids = [adUnitBidRequest]; - - const data = JSON.parse(spec.buildRequests([adUnitBidRequest], bidderRequest).data); - - expect(data.regs.ext.gdpr).to.exist.and.to.be.a('number'); - expect(data.regs.ext.gdpr).to.equal(1); - expect(data.user.ext.consent).to.exist.and.to.be.a('string'); - expect(data.user.ext.consent).to.equal(consentString); - }); - - it('should send us_privacy if bidderRequest has a value for uspConsent', function () { - const uspString = '1NYN'; - const bidderRequest = { - 'bidderCode': 'sovrn', - 'auctionId': '1d1a030790a475', - 'bidderRequestId': '22edbae2733bf6', - 'timeout': 3000, - uspConsent: uspString, - refererInfo: { - referer: 'http://example.com/page.html', - } - }; - bidderRequest.bids = [adUnitBidRequest]; - - const data = JSON.parse(spec.buildRequests([adUnitBidRequest], bidderRequest).data); - - expect(data.regs.ext['us_privacy']).to.equal(uspString); - }); - - it('should add schain if present', function() { - const schainRequests = [{ - 'bidder': 'sovrn', - 'params': { - 'tagid': 403370 - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'directseller.com', - 'sid': '00001', - 'rid': 'BidRequest1', - 'hp': 1 - } - ] - } - }].concat(adUnitBidRequest); - const bidderRequest = { - refererInfo: { - referer: 'http://example.com/page.html', - } - }; - const data = JSON.parse(spec.buildRequests(schainRequests, bidderRequest).data); - - expect(data.source.ext.schain.nodes.length).to.equal(1) - }); - - it('should add ids to the bid request', function() { - const criteoIdRequest = [{ - 'bidder': 'sovrn', - 'params': { - 'tagid': 403370 - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - 'userId': { - 'criteoId': 'A_CRITEO_ID', - 'tdid': 'SOMESORTOFID', - } - }].concat(adUnitBidRequest); - const bidderRequest = { - refererInfo: { - referer: 'http://example.com/page.html', - } - }; - - const data = JSON.parse(spec.buildRequests(criteoIdRequest, bidderRequest).data); - expect(data.user.ext.eids[0].source).to.equal('criteo.com') - expect(data.user.ext.eids[0].uids[0].id).to.equal('A_CRITEO_ID') - expect(data.user.ext.eids[0].uids[0].atype).to.equal(1) - expect(data.user.ext.eids[1].source).to.equal('adserver.org') - expect(data.user.ext.eids[1].uids[0].id).to.equal('SOMESORTOFID') - expect(data.user.ext.eids[1].uids[0].ext.rtiPartner).to.equal('TDID') - expect(data.user.ext.eids[1].uids[0].atype).to.equal(1) - expect(data.user.ext.tpid[0].source).to.equal('criteo.com') - expect(data.user.ext.tpid[0].uid).to.equal('A_CRITEO_ID') - expect(data.user.ext.prebid_criteoid).to.equal('A_CRITEO_ID') - }); - - it('should ignore empty segments', function() { - const request = spec.buildRequests([adUnitBidRequest], bidderRequest) - const payload = JSON.parse(request.data) - expect(payload.imp[0].ext).to.be.undefined - }) - - it('should pass the segments param value as trimmed deal ids array', function() { - const segmentsRequests = [{ - 'bidder': 'sovrn', - 'params': { - 'segments': ' test1,test2 ' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250], - [300, 600] - ], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }] - const request = spec.buildRequests(segmentsRequests, bidderRequest) - const payload = JSON.parse(request.data) - expect(payload.imp[0].ext.deals[0]).to.equal('test1') - expect(payload.imp[0].ext.deals[1]).to.equal('test2') - }) - it('should use the floor provided from the floor module if present', function() { - const floorBid = {...adUnitBidRequest, getFloor: () => ({currency: 'USD', floor: 1.10})} - floorBid.params = { - tagid: 1234, - bidfloor: 2.00 - } - const request = spec.buildRequests([floorBid], bidderRequest) - const payload = JSON.parse(request.data) - expect(payload.imp[0].bidfloor).to.equal(1.10) - }) - it('should use the floor from the param if there is no floor from the floor module', function() { - const floorBid = {...adUnitBidRequest, getFloor: () => ({})} - floorBid.params = { - tagid: 1234, - bidfloor: 2.00 - } - const request = spec.buildRequests([floorBid], bidderRequest) - const payload = JSON.parse(request.data) - expect(payload.imp[0].bidfloor).to.equal(2.00) - }) - describe('First Party Data', function () { - let sandbox - - beforeEach(function() { - sandbox = sinon.sandbox.create() - }) - afterEach(function() { - sandbox.restore() - }) - it('should provide first party data if provided', function() { - sandbox.stub(config, 'getConfig').callsFake(key => { - const cfg = { - ortb2: { - site: { - keywords: 'test keyword' - }, - user: { - data: 'some user data' - } - } - }; - return utils.deepAccess(cfg, key); - }); - const request = spec.buildRequests([adUnitBidRequest], bidderRequest) - const payload = JSON.parse(request.data) - expect(payload.user.data).to.equal('some user data') - expect(payload.site.keywords).to.equal('test keyword') - expect(payload.site.page).to.equal('http://example.com/page.html') - expect(payload.site.domain).to.equal('example.com') - }) - it('should append impression first party data', function () { - const fpdBid = {...adUnitBidRequest} - fpdBid.ortb2Imp = { - ext: { - data: { - pbadslot: 'homepage-top-rect', - adUnitSpecificAttribute: '123' - } - } - } - const request = spec.buildRequests([fpdBid], bidderRequest) - const payload = JSON.parse(request.data) - expect(payload.imp[0].ext.data.pbadslot).to.equal('homepage-top-rect') - expect(payload.imp[0].ext.data.adUnitSpecificAttribute).to.equal('123') - }) - it('should not overwrite deals when impression fpd is present', function() { - const fpdBid = {...adUnitBidRequest} - fpdBid.params = {...adUnitBidRequest.params} - fpdBid.params.segments = 'seg1, seg2' - fpdBid.ortb2Imp = { - ext: { - data: { - pbadslot: 'homepage-top-rect', - adUnitSpecificAttribute: '123' - } - } - } - const request = spec.buildRequests([fpdBid], bidderRequest) - const payload = JSON.parse(request.data) - expect(payload.imp[0].ext.data.pbadslot).to.equal('homepage-top-rect') - expect(payload.imp[0].ext.data.adUnitSpecificAttribute).to.equal('123') - expect(payload.imp[0].ext.deals).to.deep.equal(['seg1', 'seg2']) - }) - }) - }); - - describe('interpretResponse', function () { - let response; - beforeEach(function () { - response = { - body: { - 'id': '37386aade21a71', - 'seatbid': [{ - 'bid': [{ - 'id': 'a_403370_332fdb9b064040ddbec05891bd13ab28', - 'crid': 'creativelycreatedcreativecreative', - 'impid': '263c448586f5a1', - 'price': 0.45882675, - 'nurl': '', - 'adm': '', - 'h': 90, - 'w': 728 - }] - }] - } - }; - }); - - it('should get the correct bid response', function () { - let expectedResponse = [{ - 'requestId': '263c448586f5a1', - 'cpm': 0.45882675, - 'width': 728, - 'height': 90, - 'creativeId': 'creativelycreatedcreativecreative', - 'dealId': null, - 'currency': 'USD', - 'netRevenue': true, - 'mediaType': 'banner', - 'ad': decodeURIComponent(`>`), - 'ttl': 60000, - 'meta': { advertiserDomains: [] } - }]; - - let result = spec.interpretResponse(response); - expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); - }); - - it('crid should default to the bid id if not on the response', function () { - delete response.body.seatbid[0].bid[0].crid; - let expectedResponse = [{ - 'requestId': '263c448586f5a1', - 'cpm': 0.45882675, - 'width': 728, - 'height': 90, - 'creativeId': response.body.seatbid[0].bid[0].id, - 'dealId': null, - 'currency': 'USD', - 'netRevenue': true, - 'mediaType': 'banner', - 'ad': decodeURIComponent(``), - 'ttl': 90, - 'meta': { advertiserDomains: [] } - }]; - - let result = spec.interpretResponse(response); - expect(result[0]).to.deep.equal(expectedResponse[0]); - }); - - it('should get correct bid response when dealId is passed', function () { - response.body.seatbid[0].bid[0].dealid = 'baking'; - - let expectedResponse = [{ - 'requestId': '263c448586f5a1', - 'cpm': 0.45882675, - 'width': 728, - 'height': 90, - 'creativeId': 'creativelycreatedcreativecreative', - 'dealId': 'baking', - 'currency': 'USD', - 'netRevenue': true, - 'mediaType': 'banner', - 'ad': decodeURIComponent(``), - 'ttl': 90, - 'meta': { advertiserDomains: [] } - }]; - - let result = spec.interpretResponse(response); - expect(result[0]).to.deep.equal(expectedResponse[0]); - }); - - it('should get correct bid response when ttl is set', function () { - response.body.seatbid[0].bid[0].ext = { 'ttl': 480 }; - - let expectedResponse = [{ - 'requestId': '263c448586f5a1', - 'cpm': 0.45882675, - 'width': 728, - 'height': 90, - 'creativeId': 'creativelycreatedcreativecreative', - 'dealId': null, - 'currency': 'USD', - 'netRevenue': true, - 'mediaType': 'banner', - 'ad': decodeURIComponent(``), - 'ttl': 480, - 'meta': { advertiserDomains: [] } - }]; - - let result = spec.interpretResponse(response); - expect(result[0]).to.deep.equal(expectedResponse[0]); - }); - - it('handles empty bid response', function () { - let response = { - body: { - 'id': '37386aade21a71', - 'seatbid': [] - } - }; - let result = spec.interpretResponse(response); - expect(result.length).to.equal(0); - }); - }); - - describe('getUserSyncs ', function() { - let syncOptions = { iframeEnabled: true, pixelEnabled: false }; - let iframeDisabledSyncOptions = { iframeEnabled: false, pixelEnabled: false }; - let serverResponse = [ - { - 'body': { - 'id': '546956d68c757f', - 'seatbid': [ - { - 'bid': [ - { - 'id': 'a_448326_16c2ada014224bee815a90d2248322f5', - 'impid': '2a3826aae345f4', - 'price': 1.0099999904632568, - 'nurl': 'http://localhost/rtb/impression?bannerid=220958&campaignid=3890&rtb_tid=15588614-75d2-40ab-b27e-13d2127b3c2e&rpid=1295&seatid=seat1&zoneid=448326&cb=26900712&tid=a_448326_16c2ada014224bee815a90d2248322f5', - 'adm': 'yo a creative', - 'crid': 'cridprebidrtb', - 'w': 160, - 'h': 600 - }, - { - 'id': 'a_430392_beac4c1515da4576acf6cb9c5340b40c', - 'impid': '3cf96fd26ed4c5', - 'price': 1.0099999904632568, - 'nurl': 'http://localhost/rtb/impression?bannerid=220957&campaignid=3890&rtb_tid=5bc0e68b-3492-448d-a6f9-26fa3fd0b646&rpid=1295&seatid=seat1&zoneid=430392&cb=62735099&tid=a_430392_beac4c1515da4576acf6cb9c5340b40c', - 'adm': 'yo a creative', - 'crid': 'cridprebidrtb', - 'w': 300, - 'h': 250 - }, - ] - } - ], - 'ext': { - 'iid': 13487408, - sync: { - pixels: [ - { - url: 'http://idprovider1.com' - }, - { - url: 'http://idprovider2.com' - } - ] - } - } - }, - 'headers': {} - } - ]; - - it('should return if iid present on server response & iframe syncs enabled', function() { - const expectedReturnStatement = [ - { - 'type': 'iframe', - 'url': 'https://ap.lijit.com/beacon?informer=13487408', - } - ]; - const returnStatement = spec.getUserSyncs(syncOptions, serverResponse); - expect(returnStatement[0]).to.deep.equal(expectedReturnStatement[0]); - }); - - it('should include gdpr consent string if present', function() { - const gdprConsent = { - gdprApplies: 1, - consentString: 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==' - } - const expectedReturnStatement = [ - { - 'type': 'iframe', - 'url': `https://ap.lijit.com/beacon?gdpr_consent=${gdprConsent.consentString}&informer=13487408`, - } - ]; - const returnStatement = spec.getUserSyncs(syncOptions, serverResponse, gdprConsent, ''); - expect(returnStatement[0]).to.deep.equal(expectedReturnStatement[0]); - }); - - it('should include us privacy string if present', function() { - const uspString = '1NYN'; - const expectedReturnStatement = [ - { - 'type': 'iframe', - 'url': `https://ap.lijit.com/beacon?us_privacy=${uspString}&informer=13487408`, - } - ]; - const returnStatement = spec.getUserSyncs(syncOptions, serverResponse, null, uspString); - expect(returnStatement[0]).to.deep.equal(expectedReturnStatement[0]); - }); - - it('should include all privacy strings if present', function() { - const gdprConsent = { - gdprApplies: 1, - consentString: 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==' - } - const uspString = '1NYN'; - const expectedReturnStatement = [ - { - 'type': 'iframe', - 'url': `https://ap.lijit.com/beacon?gdpr_consent=${gdprConsent.consentString}&us_privacy=${uspString}&informer=13487408`, - } - ]; - const returnStatement = spec.getUserSyncs(syncOptions, serverResponse, gdprConsent, uspString); - expect(returnStatement[0]).to.deep.equal(expectedReturnStatement[0]); - }); - - it('should not return if iid missing on server response', function() { - const returnStatement = spec.getUserSyncs(syncOptions, []); - expect(returnStatement).to.be.empty; - }); - - it('should not return if iframe syncs disabled', function() { - const returnStatement = spec.getUserSyncs(iframeDisabledSyncOptions, serverResponse); - expect(returnStatement).to.be.empty; - }); - - it('should include pixel syncs', function() { - let pixelEnabledOptions = { iframeEnabled: false, pixelEnabled: true }; - const resp2 = { - 'body': { - 'id': '546956d68c757f-2', - 'seatbid': [ - { - 'bid': [ - { - 'id': 'a_448326_16c2ada014224bee815a90d2248322f5-2', - 'impid': '2a3826aae345f4', - 'price': 1.0099999904632568, - 'nurl': 'http://localhost/rtb/impression?bannerid=220958&campaignid=3890&rtb_tid=15588614-75d2-40ab-b27e-13d2127b3c2e&rpid=1295&seatid=seat1&zoneid=448326&cb=26900712&tid=a_448326_16c2ada014224bee815a90d2248322f5', - 'adm': 'yo a creative', - 'crid': 'cridprebidrtb', - 'w': 160, - 'h': 600 - }, - { - 'id': 'a_430392_beac4c1515da4576acf6cb9c5340b40c-2', - 'impid': '3cf96fd26ed4c5', - 'price': 1.0099999904632568, - 'nurl': 'http://localhost/rtb/impression?bannerid=220957&campaignid=3890&rtb_tid=5bc0e68b-3492-448d-a6f9-26fa3fd0b646&rpid=1295&seatid=seat1&zoneid=430392&cb=62735099&tid=a_430392_beac4c1515da4576acf6cb9c5340b40c', - 'adm': 'yo a creative', - 'crid': 'cridprebidrtb', - 'w': 300, - 'h': 250 - }, - ] - } - ], - 'ext': { - 'iid': 13487408, - sync: { - pixels: [ - { - url: 'http://idprovider3.com' - }, - { - url: 'http://idprovider4.com' - } - ] - } - } - }, - 'headers': {} - } - const returnStatement = spec.getUserSyncs(pixelEnabledOptions, [...serverResponse, resp2]); - expect(returnStatement.length).to.equal(4); - expect(returnStatement).to.deep.include.members([ - { type: 'image', url: 'http://idprovider1.com' }, - { type: 'image', url: 'http://idprovider2.com' }, - { type: 'image', url: 'http://idprovider3.com' }, - { type: 'image', url: 'http://idprovider4.com' } - ]); - }); - }); - - describe('prebid 3 upgrade', function() { - const bidRequests = [{ - 'bidder': 'sovrn', - 'params': { - 'tagid': '403370' - }, - 'adUnitCode': 'adunit-code', - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [300, 600] - ] - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }]; - const bidderRequest = { - refererInfo: { - referer: 'http://example.com/page.html', - } - }; - const request = spec.buildRequests(bidRequests, bidderRequest); - 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.w).to.equal(1) - expect(payload.imp[0].banner.h).to.equal(1) - }) - - it('gets correct site info', function() { - expect(payload.site.page).to.equal('http://example.com/page.html'); - expect(payload.site.domain).to.equal('example.com'); - }) - }) -}) diff --git a/test/spec/modules/spotxBidAdapter_spec.js b/test/spec/modules/spotxBidAdapter_spec.js deleted file mode 100644 index 5d7b32eaeeb..00000000000 --- a/test/spec/modules/spotxBidAdapter_spec.js +++ /dev/null @@ -1,665 +0,0 @@ -import {expect} from 'chai'; -import {config} from 'src/config.js'; -import {spec, GOOGLE_CONSENT} from 'modules/spotxBidAdapter.js'; - -describe('the spotx adapter', function () { - function getValidBidObject() { - return { - bidId: 123, - mediaTypes: { - video: { - playerSize: [['300', '200']] - } - }, - params: { - channel_id: 12345, - } - }; - }; - - describe('isBidRequestValid', function() { - var bid; - - beforeEach(function() { - bid = getValidBidObject(); - }); - - it('should fail validation if the bid isn\'t defined or not an object', function() { - var result = spec.isBidRequestValid(); - - expect(result).to.equal(false); - - result = spec.isBidRequestValid('not an object'); - - expect(result).to.equal(false); - }); - - it('should succeed validation with all the right parameters', function() { - expect(spec.isBidRequestValid(getValidBidObject())).to.equal(true); - }); - - it('should succeed validation with mediaType and outstream_function or outstream_options', function() { - bid.mediaType = 'video'; - bid.params.outstream_function = 'outstream_func'; - - expect(spec.isBidRequestValid(bid)).to.equal(true); - - delete bid.params.outstream_function; - bid.params.outstream_options = { - slot: 'elemID' - }; - - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should succeed with ad_unit outstream and outstream function set', function() { - bid.params.ad_unit = 'outstream'; - bid.params.outstream_function = function() {}; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should succeed with ad_unit outstream, options set for outstream and slot provided', function() { - bid.params.ad_unit = 'outstream'; - bid.params.outstream_options = {slot: 'ad_container_id'}; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should fail without a channel_id', function() { - delete bid.params.channel_id; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should fail without playerSize', function() { - delete bid.mediaTypes.video.playerSize; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should fail without video', function() { - delete bid.mediaTypes.video; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should fail with ad_unit outstream but no options set for outstream', function() { - bid.params.ad_unit = 'outstream'; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should fail with ad_unit outstream, options set for outstream but no slot provided', function() { - bid.params.ad_unit = 'outstream'; - bid.params.outstream_options = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function() { - var bid, bidRequestObj; - - beforeEach(function() { - bid = getValidBidObject(); - bidRequestObj = {refererInfo: {referer: 'prebid.js'}}; - }); - - it('should build a very basic request', function() { - var request = spec.buildRequests([bid], bidRequestObj)[0]; - expect(request.method).to.equal('POST'); - expect(request.url).to.equal('https://search.spotxchange.com/openrtb/2.3/dados/12345?src_sys=prebid'); - expect(request.bidRequest).to.equal(bidRequestObj); - expect(request.data.id).to.equal(12345); - expect(request.data.ext.wrap_response).to.equal(1); - expect(request.data.imp.id).to.match(/\d+/); - expect(request.data.imp.secure).to.equal(0); - expect(request.data.imp.video).to.deep.equal({ - ext: { - sdk_name: 'Prebid 1+', - versionOrtb: '2.3' - }, - h: '200', - mimes: [ - 'application/javascript', - 'video/mp4', - 'video/webm' - ], - w: '300' - }); - expect(request.data.site).to.deep.equal({ - content: 'content', - id: '', - page: 'prebid.js' - }); - }); - - it('should change request parameters based on options sent', function() { - var request = spec.buildRequests([bid], bidRequestObj)[0]; - expect(request.data.imp.video.ext).to.deep.equal({ - sdk_name: 'Prebid 1+', - versionOrtb: '2.3' - }); - - bid.params = { - channel_id: 54321, - ad_mute: 1, - hide_skin: 1, - ad_volume: 1, - ad_unit: 'incontent', - outstream_options: {foo: 'bar'}, - outstream_function: '987', - custom: {bar: 'foo'}, - price_floor: 123, - start_delay: true, - number_of_ads: 2, - spotx_all_google_consent: 1, - min_duration: 5, - max_duration: 10, - placement_type: 1, - position: 1 - }; - - bid.userId = { - id5id: { uid: 'id5id_1' }, - tdid: 'tdid_1' - }; - - bid.crumbs = { - pubcid: 'pubcid_1' - }; - - bid.schain = { - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - hp: 1 - } - ] - } - - request = spec.buildRequests([bid], bidRequestObj)[0]; - expect(request.data.id).to.equal(54321); - expect(request.data.imp.video).to.contain({ - minduration: 5, - maxduration: 10 - }) - expect(request.data.imp.video.ext).to.deep.equal({ - ad_volume: 1, - hide_skin: 1, - ad_unit: 'incontent', - outstream_options: {foo: 'bar'}, - outstream_function: '987', - custom: {bar: 'foo'}, - sdk_name: 'Prebid 1+', - versionOrtb: '2.3', - placement: 1, - pos: 1 - }); - - expect(request.data.imp.video.startdelay).to.equal(1); - expect(request.data.imp.bidfloor).to.equal(123); - expect(request.data.ext).to.deep.equal({ - number_of_ads: 2, - wrap_response: 1 - }); - expect(request.data.user.ext).to.deep.equal({ - consented_providers_settings: GOOGLE_CONSENT, - eids: [{ - source: 'id5-sync.com', - uids: [{ - id: 'id5id_1', - ext: {} - }] - }, - { - source: 'adserver.org', - uids: [{ - id: 'tdid_1', - ext: { - rtiPartner: 'TDID' - } - }] - }], - fpc: 'pubcid_1' - }) - - expect(request.data.source).to.deep.equal({ - ext: { - schain: { - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - hp: 1 - } - ] - } - } - }) - }); - - it('should process premarket bids', function() { - var request; - sinon.stub(Date, 'now').returns(1000); - - bid.params.pre_market_bids = [{ - vast_url: 'prebid.js', - deal_id: '123abc', - price: 12, - currency: 'USD' - }]; - - request = spec.buildRequests([bid], bidRequestObj)[0]; - expect(request.data.imp.video.ext.pre_market_bids).to.deep.equal([ - { - 'cur': 'USD', - 'ext': { - 'event_log': [ - {} - ] - }, - 'id': '123abc', - 'seatbid': [ - { - 'bid': [ - { - 'adm': 'prebid.js', - 'dealid': '123abc', - 'impid': 1000, - 'price': 12, - } - ] - } - ] - } - ]); - Date.now.restore(); - }); - - it('should pass GDPR params', function() { - var request; - - bidRequestObj.gdprConsent = { - consentString: 'consent123', - gdprApplies: true - }; - - request = spec.buildRequests([bid], bidRequestObj)[0]; - - expect(request.data.regs.ext.gdpr).to.equal(1); - expect(request.data.user.ext.consent).to.equal('consent123'); - }); - - it('should pass CCPA us_privacy string', function() { - var request; - - bidRequestObj.uspConsent = '1YYY' - - request = spec.buildRequests([bid], bidRequestObj)[0]; - expect(request.data.regs.ext.us_privacy).to.equal('1YYY'); - }); - - it('should pass both GDPR params and CCPA us_privacy', function() { - var request; - - bidRequestObj.gdprConsent = { - consentString: 'consent123', - gdprApplies: true - }; - bidRequestObj.uspConsent = '1YYY' - - request = spec.buildRequests([bid], bidRequestObj)[0]; - expect(request.data.regs.ext.gdpr).to.equal(1); - expect(request.data.user.ext.consent).to.equal('consent123'); - expect(request.data.regs.ext.us_privacy).to.equal('1YYY'); - }); - - it('should pass min and max duration params', function() { - var request; - - bid.params.min_duration = 3 - bid.params.max_duration = 15 - - request = spec.buildRequests([bid], bidRequestObj)[0]; - - expect(request.data.imp.video.minduration).to.equal(3); - expect(request.data.imp.video.maxduration).to.equal(15); - }); - - it('should pass placement_type and position params', function() { - var request; - - bid.params.placement_type = 2 - bid.params.position = 5 - - request = spec.buildRequests([bid], bidRequestObj)[0]; - - expect(request.data.imp.video.ext.placement).to.equal(2); - expect(request.data.imp.video.ext.pos).to.equal(5); - }); - - it('should pass page param and override refererInfo.referer', function() { - var request; - - bid.params.page = 'https://example.com'; - - var origGetConfig = config.getConfig; - sinon.stub(config, 'getConfig').callsFake(function (key) { - if (key === 'pageUrl') { - return 'https://www.spotx.tv'; - } - return origGetConfig.apply(config, arguments); - }); - - request = spec.buildRequests([bid], bidRequestObj)[0]; - - expect(request.data.site.page).to.equal('https://example.com'); - config.getConfig.restore(); - }); - - it('should use pageUrl from config if page param is not passed', function() { - var request; - - var origGetConfig = config.getConfig; - sinon.stub(config, 'getConfig').callsFake(function (key) { - if (key === 'pageUrl') { - return 'https://www.spotx.tv'; - } - return origGetConfig.apply(config, arguments); - }); - - request = spec.buildRequests([bid], bidRequestObj)[0]; - - expect(request.data.site.page).to.equal('https://www.spotx.tv'); - config.getConfig.restore(); - }); - - it('should use refererInfo.referer if no page or pageUrl are passed', function() { - var request; - - request = spec.buildRequests([bid], bidRequestObj)[0]; - - expect(request.data.site.page).to.equal('prebid.js'); - }); - - it('should set ext.wrap_response to 0 when cache url is set and ignoreBidderCacheKey is true', function() { - var request; - - var origGetConfig = config.getConfig; - sinon.stub(config, 'getConfig').callsFake(function (key) { - if (key === 'cache') { - return { - url: 'prebidCacheLocation', - ignoreBidderCacheKey: true - }; - } - if (key === 'cache.url') { - return 'prebidCacheLocation'; - } - if (key === 'cache.ignoreBidderCacheKey') { - return true; - } - return origGetConfig.apply(config, arguments); - }); - - request = spec.buildRequests([bid], bidRequestObj)[0]; - - expect(request.data.ext.wrap_response).to.equal(0); - config.getConfig.restore(); - }); - }); - - describe('interpretResponse', function() { - var serverResponse, bidderRequestObj; - - beforeEach(function() { - bidderRequestObj = { - bidRequest: { - bids: [{ - mediaTypes: { - video: { - playerSize: [['400', '300']] - } - }, - bidId: 123, - params: { - player_width: 400, - player_height: 300, - content_page_url: 'prebid.js', - ad_mute: 1, - outstream_options: {foo: 'bar'}, - outstream_function: 'function' - } - }, { - mediaTypes: { - video: { - playerSize: [['200', '100']] - } - }, - bidId: 124, - params: { - player_width: 200, - player_height: 100, - content_page_url: 'prebid.js', - ad_mute: 1, - outstream_options: {foo: 'bar'}, - outstream_function: 'function' - } - }] - } - }; - - serverResponse = { - body: { - id: 12345, - seatbid: [{ - bid: [{ - impid: 123, - cur: 'USD', - price: 12, - adomain: ['abc.com'], - crid: 321, - w: 400, - h: 300, - ext: { - cache_key: 'cache123', - slot: 'slot123' - } - }, { - impid: 124, - cur: 'USD', - price: 13, - adomain: ['def.com'], - w: 200, - h: 100, - ext: { - cache_key: 'cache124', - slot: 'slot124' - } - }] - }] - } - }; - }); - - it('should return an array of bid responses', function() { - var responses = spec.interpretResponse(serverResponse, bidderRequestObj); - expect(responses).to.be.an('array').with.length(2); - expect(responses[0].cache_key).to.equal('cache123'); - expect(responses[0].channel_id).to.equal(12345); - expect(responses[0].meta.advertiserDomains[0]).to.equal('abc.com'); - expect(responses[0].cpm).to.equal(12); - expect(responses[0].creativeId).to.equal(321); - expect(responses[0].currency).to.equal('USD'); - expect(responses[0].height).to.equal(300); - expect(responses[0].mediaType).to.equal('video'); - expect(responses[0].netRevenue).to.equal(true); - expect(responses[0].requestId).to.equal(123); - expect(responses[0].ttl).to.equal(360); - expect(responses[0].vastUrl).to.equal('https://search.spotxchange.com/ad/vast.html?key=cache123'); - expect(responses[0].videoCacheKey).to.equal('cache123'); - expect(responses[0].width).to.equal(400); - expect(responses[1].cache_key).to.equal('cache124'); - expect(responses[1].channel_id).to.equal(12345); - expect(responses[1].cpm).to.equal(13); - expect(responses[1].meta.advertiserDomains[0]).to.equal('def.com'); - expect(responses[1].creativeId).to.equal(''); - expect(responses[1].currency).to.equal('USD'); - expect(responses[1].height).to.equal(100); - expect(responses[1].mediaType).to.equal('video'); - expect(responses[1].netRevenue).to.equal(true); - expect(responses[1].requestId).to.equal(124); - expect(responses[1].ttl).to.equal(360); - expect(responses[1].vastUrl).to.equal('https://search.spotxchange.com/ad/vast.html?key=cache124'); - expect(responses[1].videoCacheKey).to.equal('cache124'); - expect(responses[1].width).to.equal(200); - }); - }); - - describe('outstreamRender', function() { - var serverResponse, bidderRequestObj; - - beforeEach(function() { - bidderRequestObj = { - bidRequest: { - bids: [{ - mediaTypes: { - video: { - playerSize: [['400', '300']] - } - }, - bidId: 123, - params: { - ad_unit: 'outstream', - player_width: 400, - player_height: 300, - content_page_url: 'prebid.js', - outstream_options: { - ad_mute: 1, - foo: 'bar', - slot: 'slot123', - playersize_auto_adapt: true, - custom_override: { - digitrust_opt_out: 1, - vast_url: 'bad_vast' - } - }, - } - }] - } - }; - - serverResponse = { - body: { - id: 12345, - seatbid: [{ - bid: [{ - impid: 123, - cur: 'USD', - price: 12, - crid: 321, - w: 400, - h: 300, - ext: { - cache_key: 'cache123', - slot: 'slot123' - } - }] - }] - } - }; - }); - - it('should attempt to insert the EASI script', function() { - var scriptTag; - sinon.stub(window.document, 'getElementById').returns({ - appendChild: sinon.stub().callsFake(function(script) { scriptTag = script; }) - }); - var responses = spec.interpretResponse(serverResponse, bidderRequestObj); - - responses[0].renderer.render(responses[0]); - - expect(scriptTag.getAttribute('type')).to.equal('text/javascript'); - expect(scriptTag.getAttribute('src')).to.equal('https://js.spotx.tv/easi/v1/12345.js'); - expect(scriptTag.getAttribute('data-spotx_channel_id')).to.equal('12345'); - expect(scriptTag.getAttribute('data-spotx_vast_url')).to.equal('https://search.spotxchange.com/ad/vast.html?key=cache123'); - expect(scriptTag.getAttribute('data-spotx_ad_unit')).to.equal('incontent'); - expect(scriptTag.getAttribute('data-spotx_collapse')).to.equal('0'); - expect(scriptTag.getAttribute('data-spotx_autoplay')).to.equal('1'); - expect(scriptTag.getAttribute('data-spotx_blocked_autoplay_override_mode')).to.equal('1'); - expect(scriptTag.getAttribute('data-spotx_video_slot_can_autoplay')).to.equal('1'); - expect(scriptTag.getAttribute('data-spotx_digitrust_opt_out')).to.equal('1'); - expect(scriptTag.getAttribute('data-spotx_content_width')).to.equal('400'); - expect(scriptTag.getAttribute('data-spotx_content_height')).to.equal('300'); - expect(scriptTag.getAttribute('data-spotx_ad_mute')).to.equal('1'); - window.document.getElementById.restore(); - }); - - it('should append into an iframe', function() { - var scriptTag; - sinon.stub(window.document, 'getElementById').returns({ - nodeName: 'IFRAME', - contentDocument: { - body: { - appendChild: sinon.stub().callsFake(function(script) { scriptTag = script; }) - } - } - }); - - bidderRequestObj.bidRequest.bids[0].params.outstream_options.in_iframe = 'iframeId'; - - var responses = spec.interpretResponse(serverResponse, bidderRequestObj); - - responses[0].renderer.render(responses[0]); - - expect(scriptTag.getAttribute('type')).to.equal('text/javascript'); - expect(scriptTag.getAttribute('src')).to.equal('https://js.spotx.tv/easi/v1/12345.js'); - expect(scriptTag.getAttribute('data-spotx_channel_id')).to.equal('12345'); - expect(scriptTag.getAttribute('data-spotx_vast_url')).to.equal('https://search.spotxchange.com/ad/vast.html?key=cache123'); - expect(scriptTag.getAttribute('data-spotx_ad_unit')).to.equal('incontent'); - expect(scriptTag.getAttribute('data-spotx_collapse')).to.equal('0'); - expect(scriptTag.getAttribute('data-spotx_autoplay')).to.equal('1'); - expect(scriptTag.getAttribute('data-spotx_blocked_autoplay_override_mode')).to.equal('1'); - expect(scriptTag.getAttribute('data-spotx_video_slot_can_autoplay')).to.equal('1'); - expect(scriptTag.getAttribute('data-spotx_digitrust_opt_out')).to.equal('1'); - expect(scriptTag.getAttribute('data-spotx_content_width')).to.equal('400'); - expect(scriptTag.getAttribute('data-spotx_content_height')).to.equal('300'); - window.document.getElementById.restore(); - }); - - it('should adjust width and height to match slot clientWidth if playersize_auto_adapt is used', function() { - var scriptTag; - sinon.stub(window.document, 'getElementById').returns({ - clientWidth: 200, - appendChild: sinon.stub().callsFake(function(script) { scriptTag = script; }) - }); - var responses = spec.interpretResponse(serverResponse, bidderRequestObj); - - responses[0].renderer.render(responses[0]); - - expect(scriptTag.getAttribute('type')).to.equal('text/javascript'); - expect(scriptTag.getAttribute('src')).to.equal('https://js.spotx.tv/easi/v1/12345.js'); - expect(scriptTag.getAttribute('data-spotx_content_width')).to.equal('200'); - expect(scriptTag.getAttribute('data-spotx_content_height')).to.equal('150'); - window.document.getElementById.restore(); - }); - - it('should use a default 4/3 ratio if playersize_auto_adapt is used and response does not contain width or height', function() { - delete serverResponse.body.seatbid[0].bid[0].w; - delete serverResponse.body.seatbid[0].bid[0].h; - - var scriptTag; - sinon.stub(window.document, 'getElementById').returns({ - clientWidth: 200, - appendChild: sinon.stub().callsFake(function(script) { scriptTag = script; }) - }); - var responses = spec.interpretResponse(serverResponse, bidderRequestObj); - - responses[0].renderer.render(responses[0]); - - expect(scriptTag.getAttribute('type')).to.equal('text/javascript'); - expect(scriptTag.getAttribute('src')).to.equal('https://js.spotx.tv/easi/v1/12345.js'); - expect(scriptTag.getAttribute('data-spotx_content_width')).to.equal('200'); - expect(scriptTag.getAttribute('data-spotx_content_height')).to.equal('150'); - window.document.getElementById.restore(); - }); - }); -}); diff --git a/test/spec/modules/sspBCBidAdapter_spec.js b/test/spec/modules/sspBCBidAdapter_spec.js deleted file mode 100644 index efbfa37f6ca..00000000000 --- a/test/spec/modules/sspBCBidAdapter_spec.js +++ /dev/null @@ -1,477 +0,0 @@ -import { assert, expect } from 'chai'; -import { spec } from 'modules/sspBCBidAdapter.js'; -import * as utils from 'src/utils.js'; - -const BIDDER_CODE = 'sspBC'; -const BIDDER_URL = 'https://ssp.wp.pl/bidder/'; -const SYNC_URL = 'https://ssp.wp.pl/bidder/usersync'; - -describe('SSPBC adapter', function () { - function prepareTestData() { - const bidderRequestId = '1041bb47b0fafa'; - const auctionId = '8eda6d06-3d7c-4a94-9b35-74e42fbb3089'; - const transactionId = '50259989-b5c0-4edf-8f47-b1ef5fbedf39'; - const gdprConsent = { - consentString: 'BOtq-3dOtq-30BIABCPLC4-AAAAthr_7__7-_9_-_f__9uj3Or_v_f__30ccL59v_h_7v-_7fi_20nV4u_1vft9yfk1-5ctDztp505iakivHmqNeb9v_mz1_5pRP78k89r7337Ew_v8_v-b7JCON_Ig', - gdprApplies: true, - } - const bids = [{ - adUnitCode: 'test_wideboard', - bidder: BIDDER_CODE, - mediaTypes: { - banner: { - sizes: [ - [728, 90], - [750, 100], - [750, 200] - ] - } - }, - sizes: [ - [728, 90], - [750, 100], - [750, 200] - ], - params: { - id: '003', - siteId: '8816', - }, - auctionId, - bidderRequestId, - bidId: auctionId + '1', - transactionId, - }, - { - adUnitCode: 'test_rectangle', - bidder: BIDDER_CODE, - mediaTypes: { - banner: { - sizes: [ - [300, 250] - ] - } - }, - sizes: [ - [300, 250] - ], - params: { - id: '005', - siteId: '8816', - }, - auctionId, - bidderRequestId, - bidId: auctionId + '2', - transactionId, - } - ]; - const bid_OneCode = { - adUnitCode: 'test_wideboard', - bidder: BIDDER_CODE, - mediaTypes: { - banner: { - sizes: [ - [728, 90], - [750, 100], - [750, 200] - ] - } - }, - sizes: [ - [728, 90], - [750, 100], - [750, 200] - ], - auctionId, - bidderRequestId, - bidId: auctionId + '1', - transactionId, - }; - const bids_timeouted = [{ - adUnitCode: 'test_wideboard', - bidder: BIDDER_CODE, - params: [{ - id: '003', - siteId: '8816', - }], - auctionId, - bidId: auctionId + '1', - timeout: 100, - }, - { - adUnitCode: 'test_rectangle', - bidder: BIDDER_CODE, - params: [{ - id: '005', - siteId: '8816', - }], - auctionId, - bidId: auctionId + '2', - timeout: 100, - } - ]; - const bids_test = [{ - adUnitCode: 'test_wideboard', - bidder: BIDDER_CODE, - mediaTypes: { - banner: { - sizes: [ - [970, 300], - [750, 300], - [750, 200], - [750, 100], - [300, 250] - ] - } - }, - sizes: [ - [970, 300], - [750, 300], - [750, 200], - [750, 100], - [300, 250] - ], - params: { - id: '005', - siteId: '235911', - test: 1 - }, - auctionId, - bidderRequestId, - bidId: auctionId + '1', - transactionId, - }]; - const bidRequest = { - auctionId, - bidderCode: BIDDER_CODE, - bidderRequestId, - bids, - gdprConsent, - refererInfo: { - reachedTop: true, - referer: 'https://test.site.pl/', - stack: ['https://test.site.pl/'], - } - }; - const bidRequestSingle = { - auctionId, - bidderCode: BIDDER_CODE, - bidderRequestId, - bids: [bids[0]], - gdprConsent, - refererInfo: { - reachedTop: true, - referer: 'https://test.site.pl/', - stack: ['https://test.site.pl/'], - } - }; - const bidRequestOneCode = { - auctionId, - bidderCode: BIDDER_CODE, - bidderRequestId, - bids: [bid_OneCode], - gdprConsent, - refererInfo: { - reachedTop: true, - referer: 'https://test.site.pl/', - stack: ['https://test.site.pl/'], - } - }; - const bidRequestTest = { - auctionId, - bidderCode: BIDDER_CODE, - bidderRequestId, - bids: bids_test, - gdprConsent, - refererInfo: { - reachedTop: true, - referer: 'https://test.site.pl/', - stack: ['https://test.site.pl/'], - } - }; - const bidRequestTestNoGDPR = { - auctionId, - bidderCode: BIDDER_CODE, - bidderRequestId, - bids: bids_test, - refererInfo: { - reachedTop: true, - referer: 'https://test.site.pl/', - stack: ['https://test.site.pl/'], - } - }; - const serverResponse = { - 'body': { - 'id': auctionId, - 'seatbid': [{ - 'bid': [{ - 'id': '3347324c-6889-46d2-a800-ae78a5214c06', - 'impid': '003', - 'siteid': '8816', - 'slotid': '003', - 'price': 1, - 'adid': 'lxHWkB7OnZeso3QiN1N4', - 'nurl': '', - 'adm': 'AD CODE 1', - 'adomain': ['adomain.pl'], - 'cid': 'BZ4gAg21T5nNtxlUCDSW', - 'crid': 'lxHWkB7OnZeso3QiN1N4', - 'w': 728, - 'h': 90 - }], - 'seat': 'dsp1', - 'group': 0 - }, { - 'bid': [{ - 'id': '2d766853-ea07-4529-8299-5f0ebadc546a', - 'impid': '005', - 'siteid': '8816', - 'slotid': '005', - 'price': 2, - 'adm': 'AD CODE 2', - 'cid': '57744', - 'crid': '858252', - 'w': 300, - 'h': 250 - }], - 'seat': 'dsp2', - 'group': 0 - }], - 'cur': 'PLN' - } - }; - const serverResponseSingle = { - 'body': { - 'id': auctionId, - 'seatbid': [{ - 'bid': [{ - 'id': '3347324c-6889-46d2-a800-ae78a5214c06', - 'impid': '003', - 'siteid': '8816', - 'slotid': '003', - 'price': 1, - 'adid': 'lxHWkB7OnZeso3QiN1N4', - 'nurl': '', - 'adm': 'AD CODE 1', - 'adomain': ['adomain.pl'], - 'cid': 'BZ4gAg21T5nNtxlUCDSW', - 'crid': 'lxHWkB7OnZeso3QiN1N4', - 'w': 728, - 'h': 90 - }], - 'seat': 'dsp1', - 'group': 0 - }], - 'cur': 'PLN' - } - }; - const serverResponseOneCode = { - 'body': { - 'id': auctionId, - 'seatbid': [{ - 'bid': [{ - 'id': '3347324c-6889-46d2-a800-ae78a5214c06', - 'impid': 'bidid-' + auctionId + '1', - 'price': 1, - 'adid': 'lxHWkB7OnZeso3QiN1N4', - 'nurl': '', - 'adm': 'AD CODE 1', - 'adomain': ['adomain.pl'], - 'cid': 'BZ4gAg21T5nNtxlUCDSW', - 'crid': 'lxHWkB7OnZeso3QiN1N4', - 'w': 728, - 'h': 90, - 'ext': { - 'siteid': '8816', - 'slotid': '003', - }, - }], - 'seat': 'dsp1', - 'group': 0 - }], - 'cur': 'PLN' - } - }; - const emptyResponse = { - 'body': { - 'id': auctionId, - } - } - return { - bid_OneCode, - bids, - bids_test, - bids_timeouted, - bidRequest, - bidRequestOneCode, - bidRequestSingle, - bidRequestTest, - bidRequestTestNoGDPR, - serverResponse, - serverResponseOneCode, - serverResponseSingle, - emptyResponse - }; - }; - - describe('dependencies', function () { - it('utils should contain required functions', function () { - expect(utils.parseUrl).to.be.a('function'); - expect(utils.deepAccess).to.be.a('function'); - expect(utils.logWarn).to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - const { bids } = prepareTestData(); - let bid = bids[0]; - - it('should always return true whether bid has params (standard) or not (OneCode)', function () { - assert(spec.isBidRequestValid(bid)); - bid.params.id = undefined; - assert(spec.isBidRequestValid(bid)); - }); - }); - - describe('buildRequests', function () { - const { bids, bidRequest, bidRequestSingle } = prepareTestData(); - const request = spec.buildRequests(bids, bidRequest); - const requestSingle = spec.buildRequests([bids[0]], bidRequestSingle); - const payload = request ? JSON.parse(request.data) : { site: false, imp: false }; - const payloadSingle = request ? JSON.parse(requestSingle.data) : { site: false, imp: false }; - - it('should send bid request to endpoint via POST', function () { - expect(request.url).to.contain(BIDDER_URL); - expect(request.method).to.equal('POST'); - }); - - it('should contain prebid and bidder versions', function () { - expect(request.url).to.contain('bdver'); - expect(request.url).to.contain('pbver=$prebid.version$'); - }); - - it('should create one imp object per bid', function () { - expect(payload.imp.length).to.equal(bids.length); - expect(payloadSingle.imp.length).to.equal(1); - }); - - it('should save bidder request data', function () { - expect(request.bidderRequest).to.deep.equal(bidRequest); - }); - - it('should send site Id from bidder params', function () { - expect(payload.site.id).to.equal(bids[0].params.siteId); - }); - - it('should send page url from refererInfo', function () { - expect(payload.site.page).to.equal(bidRequest.refererInfo.referer); - }); - - it('should send gdpr data', function () { - expect(payload.regs).to.be.an('object').and.to.have.property('[ortb_extensions.gdpr]', 1); - expect(payload.user).to.be.an('object').and.to.have.property('[ortb_extensions.consent]', bidRequest.gdprConsent.consentString); - }); - }); - - describe('interpretResponse', function () { - const { bid_OneCode, bids, emptyResponse, serverResponse, serverResponseOneCode, serverResponseSingle, bidRequest, bidRequestOneCode, bidRequestSingle } = prepareTestData(); - const request = spec.buildRequests(bids, bidRequest); - const requestSingle = spec.buildRequests([bids[0]], bidRequestSingle); - const requestOneCode = spec.buildRequests([bid_OneCode], bidRequestOneCode); - - it('should handle nobid responses', function () { - let result = spec.interpretResponse(emptyResponse, request); - expect(result.length).to.equal(0); - }); - - it('should create bids from non-empty responses', function () { - let result = spec.interpretResponse(serverResponse, request); - let resultSingle = spec.interpretResponse(serverResponseSingle, requestSingle); - - expect(result.length).to.equal(bids.length); - expect(resultSingle.length).to.equal(1); - expect(resultSingle[0]).to.have.keys('ad', 'cpm', 'width', 'height', 'bidderCode', 'mediaType', 'meta', 'requestId', 'creativeId', 'currency', 'netRevenue', 'ttl'); - }); - - it('should create bid from OneCode (parameter-less) request, if response contains siteId', function () { - let resultOneCode = spec.interpretResponse(serverResponseOneCode, requestOneCode); - - expect(resultOneCode.length).to.equal(1); - expect(resultOneCode[0]).to.have.keys('ad', 'cpm', 'width', 'height', 'bidderCode', 'mediaType', 'meta', 'requestId', 'creativeId', 'currency', 'netRevenue', 'ttl'); - }); - - it('should not create bid from OneCode (parameter-less) request, if response does not contain siteId', function () { - let resultOneCodeNoMatch = spec.interpretResponse(serverResponse, requestOneCode); - - expect(resultOneCodeNoMatch.length).to.equal(0); - }); - - it('should handle a partial response', function () { - let resultPartial = spec.interpretResponse(serverResponseSingle, request); - expect(resultPartial.length).to.equal(1); - }); - - it('banner ad code should contain required variables', function () { - let resultSingle = spec.interpretResponse(serverResponseSingle, requestSingle); - let adcode = resultSingle[0].ad; - expect(adcode).to.be.a('string'); - expect(adcode).to.contain('window.rekid'); - expect(adcode).to.contain('window.mcad'); - expect(adcode).to.contain('window.gdpr'); - expect(adcode).to.contain('window.page'); - }) - }); - - describe('getUserSyncs', function () { - let syncResultAll = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }); - let syncResultImage = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }); - let syncResultNone = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }); - - it('should provide correct url, if frame sync is allowed', function () { - expect(syncResultAll).to.have.length(1); - expect(syncResultAll[0].url).to.have.string(SYNC_URL); - }); - - it('should send no syncs, if frame sync is not allowed', function () { - expect(syncResultImage).to.be.undefined; - expect(syncResultNone).to.be.undefined; - }); - }); - - describe('onBidWon', function () { - it('should generate no notification if bid is undefined', function () { - let notificationPayload = spec.onBidWon(); - expect(notificationPayload).to.be.undefined; - }); - - it('should generate notification with event name and request/adUnit data, if correct bid is provided. Should also contain site/slot data as arrays.', function () { - const { bids } = prepareTestData(); - let bid = bids[0]; - - let notificationPayload = spec.onBidWon(bid); - expect(notificationPayload).to.have.property('event').that.equals('bidWon'); - expect(notificationPayload).to.have.property('requestId').that.equals(bid.auctionId); - expect(notificationPayload).to.have.property('adUnit').that.deep.equals([bid.adUnitCode]); - expect(notificationPayload).to.have.property('siteId').that.is.an('array'); - expect(notificationPayload).to.have.property('slotId').that.is.an('array'); - }); - }); - - describe('onTimeout', function () { - it('should generate no notification if timeout data is undefined / has no bids', function () { - let notificationPayloadUndefined = spec.onTimeout(); - let notificationPayloadNoBids = spec.onTimeout([]); - - expect(notificationPayloadUndefined).to.be.undefined; - expect(notificationPayloadNoBids).to.be.undefined; - }); - - it('should generate single notification for any number of timeouted bids', function () { - const { bids_timeouted } = prepareTestData(); - let notificationPayload = spec.onTimeout(bids_timeouted); - - expect(notificationPayload).to.have.property('event').that.equals('timeout'); - expect(notificationPayload).to.have.property('requestId').that.equals(bids_timeouted[0].auctionId); - expect(notificationPayload).to.have.property('adUnit').that.deep.equals([bids_timeouted[0].adUnitCode, bids_timeouted[1].adUnitCode]); - }); - }); -}); diff --git a/test/spec/modules/staqAnalyticsAdapter_spec.js b/test/spec/modules/staqAnalyticsAdapter_spec.js deleted file mode 100644 index f8e3ba83bbe..00000000000 --- a/test/spec/modules/staqAnalyticsAdapter_spec.js +++ /dev/null @@ -1,302 +0,0 @@ -import analyticsAdapter, { ExpiringQueue, getUmtSource, storage } from 'modules/staqAnalyticsAdapter.js'; -import { expect } from 'chai'; -import adapterManager from 'src/adapterManager.js'; -import CONSTANTS from 'src/constants.json'; - -const events = require('../../../src/events'); - -const DIRECT = { - source: '(direct)', - medium: '(direct)', - campaign: '(direct)' -}; -const REFERRER = { - source: 'lander.com', - medium: '(referral)', - campaign: '(referral)', - content: '/lander.html' -}; -const GOOGLE_ORGANIC = { - source: 'google', - medium: '(organic)', - campaign: '(organic)' -}; -const CAMPAIGN = { - source: 'adkernel', - medium: 'email', - campaign: 'new_campaign', - c1: '1', - c2: '2', - c3: '3', - c4: '4', - c5: '5' - -}; -describe('', function() { - let sandbox; - - before(function() { - sandbox = sinon.sandbox.create(); - }); - - after(function() { - sandbox.restore(); - analyticsAdapter.disableAnalytics(); - }); - - describe('UTM source parser', function() { - let stubSetItem; - let stubGetItem; - - before(function() { - stubSetItem = sandbox.stub(storage, 'setItem'); - stubGetItem = sandbox.stub(storage, 'getItem'); - }); - - afterEach(function() { - sandbox.reset(); - }); - - it('should parse first direct visit as (direct)', function() { - stubGetItem.withArgs('adk_dpt_analytics').returns(undefined); - stubSetItem.returns(undefined); - let source = getUmtSource('https://example.com'); - expect(source).to.be.eql(DIRECT); - }); - - it('should parse visit from google as organic', function() { - stubGetItem.withArgs('adk_dpt_analytics').returns(undefined); - stubSetItem.returns(undefined); - let source = getUmtSource('https://example.com', 'https://www.google.com/search?q=pikachu'); - expect(source).to.be.eql(GOOGLE_ORGANIC); - }); - - it('should parse referral visit', function() { - stubGetItem.withArgs('adk_dpt_analytics').returns(undefined); - stubSetItem.returns(undefined); - let source = getUmtSource('https://example.com', 'https://lander.com/lander.html'); - expect(source).to.be.eql(REFERRER); - }); - - it('should parse referral visit from same domain as direct', function() { - stubGetItem.withArgs('adk_dpt_analytics').returns(undefined); - stubSetItem.returns(undefined); - let source = getUmtSource('https://lander.com/news.html', 'https://lander.com/lander.html'); - expect(source).to.be.eql(DIRECT); - }); - - it('should parse campaign visit', function() { - stubGetItem.withArgs('adk_dpt_analytics').returns(undefined); - stubSetItem.returns(undefined); - let source = getUmtSource('https://lander.com/index.html?utm_campaign=new_campaign&utm_source=adkernel&utm_medium=email&utm_c1=1&utm_c2=2&utm_c3=3&utm_c4=4&utm_c5=5'); - expect(source).to.be.eql(CAMPAIGN); - }); - }); - - describe('ExpiringQueue', function() { - let timer; - before(function() { - timer = sandbox.useFakeTimers(0); - }); - after(function() { - timer.restore(); - }); - - it('should notify after timeout period', (done) => { - let queue = new ExpiringQueue(() => { - let elements = queue.popAll(); - expect(elements).to.be.eql([1, 2, 3, 4]); - elements = queue.popAll(); - expect(elements).to.have.lengthOf(0); - expect(Date.now()).to.be.equal(200); - done(); - }, 100); - - queue.push(1); - setTimeout(() => { - queue.push([2, 3]); - timer.tick(50); - }, 50); - setTimeout(() => { - queue.push([4]); - timer.tick(100); - }, 100); - timer.tick(50); - }); - }); - - const REQUEST = { - bidderCode: 'AppNexus', - bidderName: 'AppNexus', - auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f', - bidderRequestId: '1a6fc81528d0f6', - bids: [{ - bidder: 'AppNexus', - params: {}, - adUnitCode: 'container-1', - transactionId: 'de90df62-7fd0-4fbc-8787-92d133a7dc06', - sizes: [ - [300, 250] - ], - bidId: '208750227436c1', - bidderRequestId: '1a6fc81528d0f6', - auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f' - }], - auctionStart: 1509369418387, - timeout: 3000, - start: 1509369418389 - }; - - const RESPONSE = { - bidderCode: 'AppNexus', - width: 300, - height: 250, - statusMessage: 'Bid available', - adId: '208750227436c1', - mediaType: 'banner', - cpm: 0.015, - ad: '', - auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f', - responseTimestamp: 1509369418832, - requestTimestamp: 1509369418389, - bidder: 'AppNexus', - adUnitCode: 'container-1', - timeToRespond: 443, - size: '300x250' - }; - - const bidTimeoutArgsV1 = [{ - bidId: '2baa51527bd015', - bidderCode: 'AppNexus', - adUnitCode: 'container-1', - auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f' - }, - { - bidId: '6fe3b4c2c23092', - bidderCode: 'AppNexus', - adUnitCode: 'container-2', - auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f' - }]; - - describe('Analytics adapter', function() { - let ajaxStub; - let timer; - - before(function() { - ajaxStub = sandbox.stub(analyticsAdapter, 'ajaxCall'); - timer = sandbox.useFakeTimers(0); - }); - - beforeEach(function() { - sandbox.stub(events, 'getEvents').callsFake(() => { - return [] - }); - }); - - afterEach(function() { - events.getEvents.restore(); - }); - - it('should be configurable', function() { - adapterManager.registerAnalyticsAdapter({ - code: 'staq', - adapter: analyticsAdapter - }); - - adapterManager.enableAnalytics({ - provider: 'staq', - options: { - connId: 777, - queueTimeout: 1000, - url: 'https://localhost/prebid' - } - }); - - expect(analyticsAdapter.context).to.have.property('connectionId', 777); - }); - - it('should handle auction init event', function() { - events.emit(CONSTANTS.EVENTS.AUCTION_INIT, { config: {}, timeout: 3000 }); - const ev = analyticsAdapter.context.queue.peekAll(); - expect(ev).to.have.length(1); - expect(ev[0]).to.be.eql({ event: 'auctionInit', auctionId: undefined }); - }); - - it('should handle bid request event', function() { - events.emit(CONSTANTS.EVENTS.BID_REQUESTED, REQUEST); - const ev = analyticsAdapter.context.queue.peekAll(); - expect(ev).to.have.length(2); - expect(ev[1]).to.be.eql({ - adUnitCode: 'container-1', - auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f', - event: 'bidRequested', - adapter: 'AppNexus', - bidderName: 'AppNexus' - }); - }); - - it('should handle bid response event', function() { - events.emit(CONSTANTS.EVENTS.BID_RESPONSE, RESPONSE); - const ev = analyticsAdapter.context.queue.peekAll(); - expect(ev).to.have.length(3); - expect(ev[2]).to.be.eql({ - adId: '208750227436c1', - event: 'bidResponse', - adapter: 'AppNexus', - bidderName: 'AppNexus', - auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f', - adUnitCode: 'container-1', - cpm: 0.015, - timeToRespond: 0.443, - height: 250, - width: 300, - bidWon: false, - }); - }); - - it('should handle timeouts properly', function() { - events.emit(CONSTANTS.EVENTS.BID_TIMEOUT, bidTimeoutArgsV1); - - const ev = analyticsAdapter.context.queue.peekAll(); - expect(ev).to.have.length(5); // remember, we added 2 timeout events - expect(ev[3]).to.be.eql({ - adapter: 'AppNexus', - auctionId: '66529d4c-8998-47c2-ab3e-5b953490b98f', - bidderName: 'AppNexus', - event: 'adapterTimedOut' - }) - }); - - it('should handle winning bid', function() { - events.emit(CONSTANTS.EVENTS.BID_WON, RESPONSE); - const ev = analyticsAdapter.context.queue.peekAll(); - expect(ev).to.have.length(6); - expect(ev[5]).to.be.eql({ - auctionId: '5018eb39-f900-4370-b71e-3bb5b48d324f', - adId: '208750227436c1', - event: 'bidWon', - adapter: 'AppNexus', - bidderName: 'AppNexus', - adUnitCode: 'container-1', - cpm: 0.015, - height: 250, - width: 300, - bidWon: true, - }); - }); - - it('should handle auction end event', function() { - timer.tick(447); - events.emit(CONSTANTS.EVENTS.AUCTION_END, RESPONSE); - let ev = analyticsAdapter.context.queue.peekAll(); - expect(ev).to.have.length(0); - expect(ajaxStub.calledOnce).to.be.equal(true); - let firstCallArgs0 = ajaxStub.firstCall.args[0]; - ev = JSON.parse(firstCallArgs0); - const ev6 = ev['events'][6]; - expect(ev['connId']).to.be.eql(777); - expect(ev6.auctionId).to.be.eql('5018eb39-f900-4370-b71e-3bb5b48d324f'); - expect(ev6.event).to.be.eql('auctionEnd'); - }); - }); -}); diff --git a/test/spec/modules/stroeerCoreBidAdapter_spec.js b/test/spec/modules/stroeerCoreBidAdapter_spec.js deleted file mode 100644 index 4b028d563d3..00000000000 --- a/test/spec/modules/stroeerCoreBidAdapter_spec.js +++ /dev/null @@ -1,533 +0,0 @@ -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 find from 'core-js-pure/features/array/find.js'; - -describe('stroeerCore bid adapter', function () { - let sandbox; - let fakeServer; - let bidderRequest; - let clock; - - beforeEach(() => { - bidderRequest = buildBidderRequest(); - sandbox = sinon.sandbox.create(); - fakeServer = sandbox.useFakeServer(); - clock = sandbox.useFakeTimers(); - }); - - afterEach(() => { - sandbox.restore(); - }); - - function assertStandardFieldsOnBid(bidObject, bidId, ad, width, height, cpm) { - assert.propertyVal(bidObject, 'requestId', bidId); - assert.propertyVal(bidObject, 'ad', ad); - assert.propertyVal(bidObject, 'width', width); - assert.propertyVal(bidObject, 'height', height); - assert.propertyVal(bidObject, 'cpm', cpm); - assert.propertyVal(bidObject, 'currency', 'EUR'); - assert.propertyVal(bidObject, 'netRevenue', true); - assert.propertyVal(bidObject, 'creativeId', ''); - } - - const AUCTION_ID = utils.getUniqueIdentifierStr(); - - // Vendor user ids and associated data - const userIds = Object.freeze({ - criteoId: 'criteo-user-id', - digitrustid: { - data: { - id: 'encrypted-user-id==', - keyv: 4, - privacy: {optout: false}, - producer: 'ABC', - version: 2 - } - }, - lipb: { - lipbid: 'T7JiRRvsRAmh88', - segments: ['999'] - } - }); - - const buildBidderRequest = () => ({ - auctionId: AUCTION_ID, - bidderRequestId: 'bidder-request-id-123', - bidderCode: 'stroeerCore', - timeout: 5000, - auctionStart: 10000, - bids: [{ - bidId: 'bid1', - bidder: 'stroeerCore', - adUnitCode: 'div-1', - mediaTypes: { - banner: { - sizes: [[300, 600], [160, 60]] - } - }, - params: { - sid: 'NDA=' - }, - userId: userIds - }, { - bidId: 'bid2', - bidder: 'stroeerCore', - adUnitCode: 'div-2', - mediaTypes: { - banner: { - sizes: [[728, 90]], - } - }, - params: { - sid: 'ODA=' - }, - userId: userIds - }], - }); - - const buildBidderRequestPreVersion3 = () => { - const request = buildBidderRequest(); - request.bids.forEach((bid) => { - bid.sizes = bid.mediaTypes.banner.sizes; - delete bid.mediaTypes; - bid.mediaType = 'banner'; - }); - return request; - }; - - const buildBidderResponse = () => ({ - 'bids': [{ - '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
' - }] - }); - - const createWindow = (href, params = {}) => { - let {parent, referrer, top, frameElement, placementElements = []} = params; - - const protocol = (href.indexOf('https') === 0) ? 'https:' : 'http:'; - const win = { - frameElement, - parent, - top, - location: { - protocol, href - }, - document: { - createElement: function () { - return { - setAttribute: function () { - } - } - }, - referrer, - getElementById: id => find(placementElements, el => el.id === id) - } - }; - - win.self = win; - - if (!parent) { - win.parent = win; - } - - if (!top) { - win.top = win; - } - - return win; - }; - - function createElement(id, offsetTop = 0) { - return { - id, - getBoundingClientRect: function () { - return { - top: offsetTop, height: 1 - } - } - } - } - - function setupSingleWindow(sandBox, placementElements = [createElement('div-1', 17), createElement('div-2', 54)]) { - const win = createWindow('http://www.xyz.com/', { - parent: win, top: win, frameElement: createElement(undefined, 304), placementElements: placementElements - }); - - win.innerHeight = 200; - - sandBox.stub(utils, 'getWindowSelf').returns(win); - sandBox.stub(utils, 'getWindowTop').returns(win); - - return win; - } - - function setupNestedWindows(sandBox, placementElements = [createElement('div-1', 17), createElement('div-2', 54)]) { - const topWin = createWindow('http://www.abc.org/', {referrer: 'http://www.google.com/?query=monkey'}); - topWin.innerHeight = 800; - - const midWin = createWindow('http://www.abc.org/', {parent: topWin, top: topWin, frameElement: createElement()}); - midWin.innerHeight = 400; - - const win = createWindow('http://www.xyz.com/', { - parent: midWin, top: topWin, frameElement: createElement(undefined, 304), placementElements - }); - - win.innerHeight = 200; - - sandBox.stub(utils, 'getWindowSelf').returns(win); - sandBox.stub(utils, 'getWindowTop').returns(topWin); - - return {topWin, midWin, win}; - } - - it('should only support BANNER mediaType', function () { - assert.deepEqual(spec.supportedMediaTypes, [BANNER]); - }); - - describe('bid validation entry point', () => { - let bidRequest; - - beforeEach(() => { - bidRequest = buildBidderRequest().bids[0]; - }); - - it('should have \"isBidRequestValid\" function', () => { - assert.isFunction(spec.isBidRequestValid); - }); - - it('should pass a valid bid', () => { - assert.isTrue(spec.isBidRequestValid(bidRequest)); - }); - - it('should exclude bids without slot id param', () => { - bidRequest.params.sid = undefined; - assert.isFalse(spec.isBidRequestValid(bidRequest)); - }); - - it('should exclude non-banner bids', () => { - delete bidRequest.mediaTypes.banner; - bidRequest.mediaTypes.video = { - playerSize: [640, 480] - }; - - assert.isFalse(spec.isBidRequestValid(bidRequest)); - }); - - it('should exclude non-banner, pre-version 3 bids', () => { - delete bidRequest.mediaTypes; - bidRequest.mediaType = VIDEO; - assert.isFalse(spec.isBidRequestValid(bidRequest)); - }); - }); - - describe('build request entry point', () => { - it('should have \"buildRequests\" function', () => { - assert.isFunction(spec.buildRequests); - }); - - describe('url on server request info object', () => { - let win; - beforeEach(() => { - win = setupSingleWindow(sandbox); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('should use hardcoded url as default endpoint', () => { - const bidReq = buildBidderRequest(); - let serverRequestInfo = spec.buildRequests(bidReq.bids, bidReq); - - assert.equal(serverRequestInfo.method, 'POST'); - assert.isObject(serverRequestInfo.data); - assert.equal(serverRequestInfo.url, 'https://hb.adscale.de/dsh'); - }); - - describe('should use custom url if provided', () => { - const samples = [{ - protocol: 'http:', 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'}, expected: 'https://other.com:234/xyz' - }, { - protocol: 'https:', - 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' - }, ]; - - samples.forEach(sample => { - it(`should use ${sample.expected} as endpoint when given params ${JSON.stringify(sample.params)} and protocol ${sample.protocol}`, - function () { - win.location.protocol = sample.protocol; - - const bidReq = buildBidderRequest(); - bidReq.bids[0].params = sample.params; - bidReq.bids.length = 1; - - let serverRequestInfo = spec.buildRequests(bidReq.bids, bidReq); - - assert.equal(serverRequestInfo.method, 'POST'); - assert.isObject(serverRequestInfo.data); - assert.equal(serverRequestInfo.url, sample.expected); - }); - }); - }); - }); - - describe('payload on server request info object', () => { - let topWin; - let win; - - let placementElements; - beforeEach(() => { - placementElements = [createElement('div-1', 17), createElement('div-2', 54)]; - ({ topWin, win } = setupNestedWindows(sandbox, placementElements)); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it('should have expected JSON structure', () => { - clock.tick(13500); - const bidReq = buildBidderRequest(); - - const serverRequestInfo = spec.buildRequests(bidReq.bids, bidReq); - - const expectedTimeout = bidderRequest.timeout - (13500 - bidderRequest.auctionStart); - - assert.equal(expectedTimeout, 1500); - - const expectedJsonPayload = { - 'id': AUCTION_ID, - 'timeout': expectedTimeout, - 'ref': topWin.document.referrer, - 'mpa': true, - 'ssl': false, - 'bids': [{ - 'sid': 'NDA=', 'bid': 'bid1', 'siz': [[300, 600], [160, 60]], 'viz': true - }, { - 'sid': 'ODA=', 'bid': 'bid2', 'siz': [[728, 90]], 'viz': true - }], - 'user': { - 'euids': userIds - } - }; - - // trim away fields with undefined - const actualJsonPayload = JSON.parse(JSON.stringify(serverRequestInfo.data)); - - assert.deepEqual(actualJsonPayload, expectedJsonPayload); - }); - - it('should handle banner sizes for pre version 3', () => { - // Version 3 changes the way how banner sizes are accessed. - // We can support backwards compatibility with version 2.x - const bidReq = buildBidderRequestPreVersion3(); - const serverRequestInfo = spec.buildRequests(bidReq.bids, bidReq); - assert.deepEqual(serverRequestInfo.data.bids[0].siz, [[300, 600], [160, 60]]); - assert.deepEqual(serverRequestInfo.data.bids[1].siz, [[728, 90]]); - }); - - describe('optional fields', () => { - it('should skip viz field when unable to determine visibility of placement', () => { - placementElements.length = 0; - const bidReq = buildBidderRequest(); - - const serverRequestInfo = spec.buildRequests(bidReq.bids, bidReq); - assert.lengthOf(serverRequestInfo.data.bids, 2); - - for (let bid of serverRequestInfo.data.bids) { - assert.isUndefined(bid.viz); - } - }); - - it('should skip ref field when unable to determine document referrer', () => { - // i.e., empty if user came from bookmark, or web page using 'rel="noreferrer" on link, etc - buildBidderRequest(); - - const serverRequestInfo = spec.buildRequests(bidderRequest.bids, bidderRequest); - assert.lengthOf(serverRequestInfo.data.bids, 2); - - for (let bid of serverRequestInfo.data.bids) { - assert.isUndefined(bid.ref); - } - }); - - const gdprSamples = [{consentString: 'RG9ua2V5IEtvbmc=', gdprApplies: true}, {consentString: 'UGluZyBQb25n', gdprApplies: false}]; - gdprSamples.forEach((sample) => { - it(`should add GDPR info ${JSON.stringify(sample)} when provided`, () => { - const bidReq = buildBidderRequest(); - bidReq.gdprConsent = sample; - - const serverRequestInfo = spec.buildRequests(bidReq.bids, bidReq); - - const actualGdpr = serverRequestInfo.data.gdpr; - assert.propertyVal(actualGdpr, 'applies', sample.gdprApplies); - assert.propertyVal(actualGdpr, 'consent', sample.consentString); - }); - }); - - const skippableGdprSamples = [{consentString: null, gdprApplies: true}, // - {consentString: 'UGluZyBQb25n', gdprApplies: null}, // - {consentString: null, gdprApplies: null}, // - {consentString: undefined, gdprApplies: true}, // - {consentString: 'UGluZyBQb25n', gdprApplies: undefined}, // - {consentString: undefined, gdprApplies: undefined}]; - skippableGdprSamples.forEach((sample) => { - it(`should not add GDPR info ${JSON.stringify(sample)} when one or more values are missing`, () => { - const bidReq = buildBidderRequest(); - bidReq.gdprConsent = sample; - - const serverRequestInfo = spec.buildRequests(bidReq.bids, bidReq); - - const actualGdpr = serverRequestInfo.data.gdpr; - assert.isUndefined(actualGdpr); - }); - }); - - it('should be able to build without third party user id data', () => { - const bidReq = buildBidderRequest(); - bidReq.bids.forEach(bid => delete bid.userId); - const serverRequestInfo = spec.buildRequests(bidReq.bids, bidReq); - assert.lengthOf(serverRequestInfo.data.bids, 2); - assert.notProperty(serverRequestInfo, 'uids'); - }); - }); - }); - }); - - describe('interpret response entry point', () => { - it('should have \"interpretResponse\" function', () => { - assert.isFunction(spec.interpretResponse); - }); - - const invalidResponses = ['', ' ', ' ', undefined, null]; - invalidResponses.forEach(sample => { - it('should ignore invalid responses (\"' + sample + '\") response', () => { - const result = spec.interpretResponse({body: sample}); - assert.isArray(result); - assert.lengthOf(result, 0); - }); - }); - - it('should interpret a standard response', () => { - const bidderResponse = buildBidderResponse(); - - const result = spec.interpretResponse({body: bidderResponse}); - assertStandardFieldsOnBid(result[0], 'bid1', '
tag1
', 300, 600, 4); - assertStandardFieldsOnBid(result[1], 'bid2', '
tag2
', 728, 90, 7.3); - }); - - it('should return empty array, when response contains no bids', () => { - const result = spec.interpretResponse({body: {bids: []}}); - assert.deepStrictEqual(result, []); - }); - }); - - describe('get user syncs entry point', () => { - let win; - beforeEach(() => { - win = setupSingleWindow(sandbox); - - // fake - win.document.createElement = function () { - const attrs = {}; - return { - setAttribute: (name, value) => { - attrs[name] = value - }, - getAttribute: (name) => attrs[name], - hasAttribute: (name) => attrs[name] !== undefined, - tagName: 'SCRIPT', - } - } - }); - - it('should have \"getUserSyncs\" function', () => { - assert.isFunction(spec.getUserSyncs); - }); - - 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}, ['']); - - assert.deepStrictEqual(userSyncResponse, [{type: 'iframe', url: expectedUrl}]); - }); - - it('should not perform user connect when there was no response', () => { - const userSyncResponse = spec.getUserSyncs({iframeEnabled: true}, []); - - assert.deepStrictEqual(userSyncResponse, []); - }); - - describe('and gdpr consent is defined', () => { - 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}); - - 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}); - - 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}, [''], {}); - - assert.deepStrictEqual(userSyncResponse, [{type: 'iframe', url: expectedUrl}]); - }); - }); - }); - - describe('and consent string is defined', () => { - 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}); - - 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}); - - assert.deepStrictEqual(userSyncResponse, [{type: 'iframe', url: expectedUrl}]); - }); - }); - }); - }); - - describe('when iframe option is disabled', () => { - it('should not perform user connect even when there was a response', () => { - 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}, []); - - assert.deepStrictEqual(userSyncResponse, []); - }); - }); - }); -}); diff --git a/test/spec/modules/stvBidAdapter_spec.js b/test/spec/modules/stvBidAdapter_spec.js deleted file mode 100644 index c2278313b2d..00000000000 --- a/test/spec/modules/stvBidAdapter_spec.js +++ /dev/null @@ -1,138 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/stvBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -const VADS_ENDPOINT_URL = 'https://ads.smartstream.tv/r/'; - -describe('stvAdapter', function () { - const adapter = newBidder(spec); - - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'stv', - 'params': { - 'placement': '6682', - 'pfilter': { - 'floorprice': 1000000 - }, - 'bcat': 'IAB2,IAB4', - 'dvt': 'desktop' - }, - 'sizes': [ - [300, 250] - ], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'someIncorrectParam': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [{ - 'bidder': 'stv', - 'params': { - 'source': 'vads', - 'placement': 'prer0-0%3D4137', - 'pfilter': { - 'min_duration': 1, - 'max_duration': 100, - 'min_bitrate': 32, - 'max_bitrate': 128, - }, - 'noskip': 1 - }, - 'mediaTypes': { - 'video': { - 'playerSize': [640, 480], - 'context': 'instream' - } - }, - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475' - }]; - - let bidderRequest = { - refererInfo: { - referer: 'some_referrer.net' - } - } - - const request = spec.buildRequests(bidRequests, bidderRequest); - it('sends bid video request to our vads endpoint via GET', function () { - expect(request[0].method).to.equal('GET'); - let data = request[0].data.replace(/rnd=\d+\&/g, '').replace(/ref=.*\&bid/g, 'bid'); - expect(data).to.equal('_f=vast2&alternative=prebid_js&_ps=prer0-0%3D4137&srw=640&srh=480&idt=100&bid_id=30b31c1838de1e&pfilter%5Bmin_duration%5D=1&pfilter%5Bmax_duration%5D=100&pfilter%5Bmin_bitrate%5D=32&pfilter%5Bmax_bitrate%5D=128&noskip=1'); - }); - }); - - describe('interpretResponse', function () { - let vadsServerVideoResponse = { - 'body': { - 'cpm': 5000000, - 'crid': 100500, - 'width': '300', - 'height': '250', - 'vastXml': '{"reason":7001,"status":"accepted"}', - 'requestId': '220ed41385952a', - 'currency': 'EUR', - 'ttl': 60, - 'netRevenue': true, - 'zone': '6682' - } - }; - - let expectedResponse = [{ - requestId: '23beaa6af6cdde', - cpm: 0.5, - width: 0, - height: 0, - creativeId: 100500, - dealId: '', - currency: 'EUR', - netRevenue: true, - ttl: 300, - vastXml: '{"reason":7001,"status":"accepted"}', - mediaType: 'video' - }]; - - it('should get the correct vads video bid response by display ad', function () { - let bidRequest = [{ - 'method': 'GET', - 'url': VADS_ENDPOINT_URL, - 'mediaTypes': { - 'video': { - 'playerSize': [640, 480], - 'context': 'instream' - } - }, - 'data': { - 'bid_id': '30b31c1838de1e' - } - }]; - let result = spec.interpretResponse(vadsServerVideoResponse, bidRequest[0]); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('handles empty bid response', function () { - let response = { - body: {} - }; - let result = spec.interpretResponse(response); - expect(result.length).to.equal(0); - }); - }); -}); diff --git a/test/spec/modules/sublimeBidAdapter_spec.js b/test/spec/modules/sublimeBidAdapter_spec.js deleted file mode 100644 index 2e1d65f0533..00000000000 --- a/test/spec/modules/sublimeBidAdapter_spec.js +++ /dev/null @@ -1,324 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/sublimeBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -let utils = require('src/utils'); - -describe('Sublime Adapter', function() { - const adapter = newBidder(spec); - - describe('sendEvent', function() { - let sandbox; - const triggeredPixelProperties = [ - 't', - 'tse', - 'z', - 'e', - 'src', - 'puid', - 'trId', - 'pbav', - 'pubpbv', - 'device', - 'pubtimeout', - ]; - - beforeEach(function () { - sandbox = sinon.sandbox.create(); - }); - - it('should trigger pixel', function () { - sandbox.spy(utils, 'triggerPixel'); - spec.sendEvent('test'); - expect(utils.triggerPixel.called).to.equal(true); - const params = utils.parseUrl(utils.triggerPixel.args[0][0]).search; - expect(Object.keys(params)).to.have.members(triggeredPixelProperties); - }); - - afterEach(function () { - sandbox.restore(); - }); - }) - - describe('inherited functions', function() { - it('exists and is a function', function() { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function() { - let bid = { - bidder: 'sublime', - params: { - zoneId: 24549, - endpoint: '', - }, - }; - - it('should return true when required params found', function() { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function() { - let bid = Object.assign({}, bid); - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function() { - let bidRequests = [ - { - bidder: 'sublime', - adUnitCode: 'sublime_code', - bidId: 'abc1234', - sizes: [[1800, 1000], [640, 300]], - requestId: 'xyz654', - params: { - zoneId: 123, - callbackName: 'false' - } - }, { - bidder: 'sublime', - adUnitCode: 'sublime_code_2', - bidId: 'abc1234_2', - sizes: [[1, 1]], - requestId: 'xyz654_2', - params: { - zoneId: 456, - } - } - ]; - - let bidderRequest = { - gdprConsent: { - consentString: 'EOHEIRCOUCOUIEHZIOEIU-TEST', - gdprApplies: true - }, - refererInfo: { - referer: 'https://example.com', - numIframes: 2, - } - }; - - let request = spec.buildRequests(bidRequests, bidderRequest); - - it('should have a post method', function() { - expect(request[0].method).to.equal('POST'); - expect(request[1].method).to.equal('POST'); - }); - - it('should contains a request id equals to the bid id', function() { - for (let i = 0; i < request.length; i = i + 1) { - expect(JSON.parse(request[i].data).requestId).to.equal(bidRequests[i].bidId); - } - }); - - it('should have an url that contains bid keyword', function() { - expect(request[0].url).to.match(/bid/); - expect(request[1].url).to.match(/bid/); - }); - }); - - describe('buildRequests: default arguments', function() { - let bidRequests = [{ - bidder: 'sublime', - adUnitCode: 'sublime_code', - bidId: 'abc1234', - sizes: [[1800, 1000], [640, 300]], - requestId: 'xyz654', - params: { - zoneId: 123 - } - }]; - - let request = spec.buildRequests(bidRequests); - - it('should have an url that match the default endpoint', function() { - expect(request[0].url).to.equal('https://pbjs.sskzlabs.com/bid'); - }); - }); - - describe('interpretResponse', function() { - let serverResponse = { - 'request_id': '3db3773286ee59', - 'sspname': 'foo', - 'cpm': 0.5, - 'ad': '', - }; - - it('should get correct bid response', function() { - // Mock the fire method - top.window.sublime = { - analytics: { - fire: function() {} - } - }; - - let expectedResponse = [ - { - requestId: '', - cpm: 0.5, - width: 1800, - height: 1000, - creativeId: 1, - dealId: 1, - currency: 'USD', - sspname: 'foo', - netRevenue: true, - ttl: 600, - pbav: '0.7.1', - ad: '', - }, - ]; - let result = spec.interpretResponse({body: serverResponse}); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('should get correct default size for 1x1', function() { - let serverResponse = { - 'requestId': 'xyz654_2', - 'sspname': 'sublime', - 'cpm': 0.5, - 'ad': '', - }; - - let bidRequest = { - bidder: 'sublime', - adUnitCode: 'sublime_code_2', - bidId: 'abc1234_2', - data: { - w: 1, - h: 1, - }, - requestId: 'xyz654_2', - params: { - zoneId: 456, - } - }; - - let result = spec.interpretResponse({body: serverResponse}, bidRequest); - - let expectedResponse = { - requestId: 'xyz654_2', - cpm: 0.5, - width: 1, - height: 1, - creativeId: 1, - dealId: 1, - currency: 'EUR', - netRevenue: true, - ttl: 600, - ad: '', - pbav: '0.7.1', - sspname: 'sublime' - }; - - expect(result[0]).to.deep.equal(expectedResponse); - }); - - it('should return bid empty response', function () { - let serverResponse = ''; - let bidRequest = {}; - - let result = spec.interpretResponse({ body: serverResponse }, bidRequest); - - let expectedResponse = []; - - expect(result).to.deep.equal(expectedResponse); - }); - - it('should return bid with default value in response', function () { - let serverResponse = { - 'requestId': 'xyz654_2', - 'sspname': 'sublime', - 'ad': '', - }; - - let bidRequest = { - bidder: 'sublime', - adUnitCode: 'sublime_code_2', - bidId: 'abc1234_2', - data: { - w: 1, - h: 1, - }, - requestId: 'xyz654_2', - params: { - zoneId: 456, - } - }; - - let result = spec.interpretResponse({ body: serverResponse }, bidRequest); - - let expectedResponse = { - requestId: 'xyz654_2', - cpm: 0, - width: 1, - height: 1, - creativeId: 1, - dealId: 1, - currency: 'EUR', - sspname: 'sublime', - netRevenue: true, - ttl: 600, - ad: '', - pbav: '0.7.1', - }; - - expect(result[0]).to.deep.equal(expectedResponse); - }); - - it('should return empty bid response because of timeout', function () { - let serverResponse = { - 'requestId': 'xyz654_2', - 'timeout': true, - 'ad': '', - }; - - let bidRequest = { - bidder: 'sublime', - adUnitCode: 'sublime_code_2', - bidId: 'abc1234_2', - data: { - w: 1, - h: 1, - }, - requestId: 'xyz654_2', - params: { - zoneId: 456, - } - }; - - let result = spec.interpretResponse({ body: serverResponse }, bidRequest); - - let expectedResponse = []; - - expect(result).to.deep.equal(expectedResponse); - - describe('On bid Time out', function () { - spec.onTimeout(result); - }); - }); - }); - - describe('onBidWon', function() { - let sandbox; - let bid = { foo: 'bar' }; - - beforeEach(function () { - sandbox = sinon.sandbox.create(); - }); - - it('should trigger "bidwon" pixel', function () { - sandbox.spy(utils, 'triggerPixel'); - spec.onBidWon(bid); - const params = utils.parseUrl(utils.triggerPixel.args[0][0]).search; - expect(params.e).to.equal('bidwon'); - }); - - afterEach(function () { - sandbox.restore(); - }); - }) -}); diff --git a/test/spec/modules/synacormediaBidAdapter_spec.js b/test/spec/modules/synacormediaBidAdapter_spec.js deleted file mode 100644 index 688f1c2c090..00000000000 --- a/test/spec/modules/synacormediaBidAdapter_spec.js +++ /dev/null @@ -1,1164 +0,0 @@ -import { assert, expect } from 'chai'; -import { BANNER } from 'src/mediaTypes.js'; -import { config } from 'src/config.js'; -import { spec } from 'modules/synacormediaBidAdapter.js'; - -describe('synacormediaBidAdapter ', function () { - describe('isBidRequestValid', function () { - let bid; - beforeEach(function () { - bid = { - sizes: [300, 250], - params: { - seatId: 'prebid', - tagId: '1234' - } - }; - }); - - it('should return true when params placementId and seatId are truthy', function () { - bid.params.placementId = bid.params.tagId; - delete bid.params.tagId; - assert(spec.isBidRequestValid(bid)); - }); - - it('should return true when params tagId and seatId are truthy', function () { - delete bid.params.placementId; - assert(spec.isBidRequestValid(bid)); - }); - - it('should return false when sizes are missing', function () { - delete bid.sizes; - assert.isFalse(spec.isBidRequestValid(bid)); - }); - - it('should return false when the only size is unwanted', function () { - bid.sizes = [[1, 1]]; - assert.isFalse(spec.isBidRequestValid(bid)); - }); - - it('should return false when seatId param is missing', function () { - delete bid.params.seatId; - assert.isFalse(spec.isBidRequestValid(bid)); - }); - - it('should return false when both placementId param and tagId param are missing', function () { - delete bid.params.placementId; - delete bid.params.tagId; - assert.isFalse(spec.isBidRequestValid(bid)); - }); - - it('should return false when params is missing or null', function () { - assert.isFalse(spec.isBidRequestValid({ params: null })); - assert.isFalse(spec.isBidRequestValid({})); - assert.isFalse(spec.isBidRequestValid(null)); - }); - }); - - describe('impression type', function () { - let nonVideoReq = { - bidId: '9876abcd', - sizes: [[300, 250], [300, 600]], - params: { - seatId: 'prebid', - tagId: '1234', - bidfloor: '0.50' - } - }; - - let bannerReq = { - bidId: '9876abcd', - sizes: [[300, 250], [300, 600]], - params: { - seatId: 'prebid', - tagId: '1234', - bidfloor: '0.50' - }, - mediaTypes: { - banner: { - format: [ - { - w: 300, - h: 600 - } - ], - pos: 0 - } - }, - }; - - let videoReq = { - bidId: '9876abcd', - sizes: [[640, 480]], - params: { - seatId: 'prebid', - tagId: '1234', - bidfloor: '0.50' - }, - mediaTypes: { - video: { - context: 'instream', - playerSize: [ - [ - 640, - 480 - ] - ] - } - }, - }; - it('should return correct impression type video/banner', function () { - assert.isFalse(spec.isVideoBid(nonVideoReq)); - assert.isFalse(spec.isVideoBid(bannerReq)); - assert.isTrue(spec.isVideoBid(videoReq)); - }); - }); - describe('buildRequests', function () { - let validBidRequestVideo = { - bidder: 'synacormedia', - params: { - seatId: 'prebid', - tagId: '1234', - video: { - minduration: 30 - } - }, - mediaTypes: { - video: { - context: 'instream', - playerSize: [[640, 480]] - } - }, - adUnitCode: 'video1', - transactionId: '93e5def8-29aa-4fe8-bd3a-0298c39f189a', - sizes: [[640, 480]], - bidId: '2624fabbb078e8', - bidderRequestId: '117954d20d7c9c', - auctionId: 'defd525f-4f1e-4416-a4cb-ae53be90e706', - src: 'client', - bidRequestsCount: 1 - }; - - let bidderRequestVideo = { - bidderCode: 'synacormedia', - auctionId: 'VideoAuctionId124', - bidderRequestId: '117954d20d7c9c', - auctionStart: 1553624929697, - timeout: 700, - refererInfo: { - referer: 'https://localhost:9999/test/pages/video.html?pbjs_debug=true', - reachedTop: true, - numIframes: 0, - stack: ['https://localhost:9999/test/pages/video.html?pbjs_debug=true'] - }, - start: 1553624929700 - }; - - bidderRequestVideo.bids = validBidRequestVideo; - let expectedDataVideo1 = { - id: 'v2624fabbb078e8-640x480', - tagid: '1234', - video: { - w: 640, - h: 480, - pos: 0, - minduration: 30 - } - }; - - let validBidRequest = { - bidId: '9876abcd', - sizes: [[300, 250], [300, 600]], - params: { - seatId: 'prebid', - tagId: '1234', - bidfloor: '0.50' - } - }; - - let bidderRequest = { - auctionId: 'xyz123', - refererInfo: { - referer: 'https://test.com/foo/bar' - } - }; - - let bidderRequestWithCCPA = { - auctionId: 'xyz123', - refererInfo: { - referer: 'https://test.com/foo/bar' - }, - uspConsent: '1YYY' - }; - - let expectedDataImp1 = { - banner: { - format: [ - { - h: 250, - w: 300 - }, - { - h: 600, - w: 300 - } - ], - pos: 0 - }, - id: 'b9876abcd', - tagid: '1234', - bidfloor: 0.5 - }; - - it('should return valid request when valid bids are used', function () { - // banner test - let req = spec.buildRequests([validBidRequest], bidderRequest); - expect(req).be.an('object'); - expect(req).to.have.property('method', 'POST'); - expect(req).to.have.property('url'); - expect(req.url).to.contain('https://prebid.technoratimedia.com/openrtb/bids/prebid?'); - expect(req.data).to.exist.and.to.be.an('object'); - expect(req.data.id).to.equal('xyz123'); - expect(req.data.imp).to.eql([expectedDataImp1]); - - // video test - let reqVideo = spec.buildRequests([validBidRequestVideo], bidderRequestVideo); - expect(reqVideo).be.an('object'); - expect(reqVideo).to.have.property('method', 'POST'); - expect(reqVideo).to.have.property('url'); - expect(reqVideo.url).to.contain('https://prebid.technoratimedia.com/openrtb/bids/prebid?'); - expect(reqVideo.data).to.exist.and.to.be.an('object'); - expect(reqVideo.data.id).to.equal('VideoAuctionId124'); - expect(reqVideo.data.imp).to.eql([expectedDataVideo1]); - }); - - it('should return multiple bids when multiple valid requests with the same seatId are used', function () { - let secondBidRequest = { - bidId: 'foobar', - sizes: [[300, 600]], - params: { - seatId: validBidRequest.params.seatId, - tagId: '5678', - bidfloor: '0.50' - } - }; - let req = spec.buildRequests([validBidRequest, secondBidRequest], bidderRequest); - expect(req).to.exist.and.be.an('object'); - expect(req).to.have.property('method', 'POST'); - expect(req).to.have.property('url'); - expect(req.url).to.contain('https://prebid.technoratimedia.com/openrtb/bids/prebid?'); - expect(req.data.id).to.equal('xyz123'); - expect(req.data.imp).to.eql([expectedDataImp1, { - banner: { - format: [ - { - h: 600, - w: 300 - } - ], - pos: 0 - }, - id: 'bfoobar', - tagid: '5678', - bidfloor: 0.5 - }]); - }); - - it('should return only first bid when different seatIds are used', function () { - let mismatchedSeatBidRequest = { - bidId: 'foobar', - sizes: [[300, 250]], - params: { - seatId: 'somethingelse', - tagId: '5678', - bidfloor: '0.50' - } - }; - let req = spec.buildRequests([mismatchedSeatBidRequest, validBidRequest], bidderRequest); - expect(req).to.have.property('method', 'POST'); - expect(req).to.have.property('url'); - expect(req.url).to.contain('https://somethingelse.technoratimedia.com/openrtb/bids/somethingelse?'); - expect(req.data.id).to.equal('xyz123'); - expect(req.data.imp).to.eql([ - { - banner: { - format: [ - { - h: 250, - w: 300 - } - ], - pos: 0 - }, - id: 'bfoobar', - tagid: '5678', - bidfloor: 0.5 - } - ]); - }); - - it('should not use bidfloor when the value is not a number', function () { - let badFloorBidRequest = { - bidId: '9876abcd', - sizes: [[300, 250]], - params: { - seatId: 'prebid', - tagId: '1234', - bidfloor: 'abcd' - } - }; - let req = spec.buildRequests([badFloorBidRequest], bidderRequest); - expect(req).to.have.property('method', 'POST'); - expect(req).to.have.property('url'); - expect(req.url).to.contain('https://prebid.technoratimedia.com/openrtb/bids/prebid?src=$$REPO_AND_VERSION$$'); - expect(req.data.id).to.equal('xyz123'); - expect(req.data.imp).to.eql([ - { - banner: { - format: [ - { - h: 250, - w: 300 - } - ], - pos: 0 - }, - id: 'b9876abcd', - tagid: '1234', - } - ]); - }); - - it('should not use bidfloor when there is no value', function () { - let badFloorBidRequest = { - bidId: '9876abcd', - sizes: [[300, 250]], - params: { - seatId: 'prebid', - tagId: '1234' - } - }; - let req = spec.buildRequests([badFloorBidRequest], bidderRequest); - expect(req).to.have.property('method', 'POST'); - expect(req).to.have.property('url'); - expect(req.url).to.contain('https://prebid.technoratimedia.com/openrtb/bids/prebid?src=$$REPO_AND_VERSION$$'); - expect(req.data.id).to.equal('xyz123'); - expect(req.data.imp).to.eql([ - { - banner: { - format: [ - { - h: 250, - w: 300 - } - ], - pos: 0 - }, - id: 'b9876abcd', - tagid: '1234', - } - ]); - }); - - it('should use the pos given by the bid request', function () { - let newPosBidRequest = { - bidId: '9876abcd', - sizes: [[300, 250]], - params: { - seatId: 'prebid', - tagId: '1234', - pos: 1 - } - }; - let req = spec.buildRequests([newPosBidRequest], bidderRequest); - expect(req).to.have.property('method', 'POST'); - expect(req).to.have.property('url'); - expect(req.url).to.contain('https://prebid.technoratimedia.com/openrtb/bids/prebid?src=$$REPO_AND_VERSION$$'); - expect(req.data.id).to.equal('xyz123'); - expect(req.data.imp).to.eql([ - { - banner: { - format: [ - { - h: 250, - w: 300 - } - ], - pos: 1 - }, - id: 'b9876abcd', - tagid: '1234' - } - ]); - }); - - it('should use the default pos if none in bid request', function () { - let newPosBidRequest = { - bidId: '9876abcd', - sizes: [[300, 250]], - params: { - seatId: 'prebid', - tagId: '1234', - } - }; - let req = spec.buildRequests([newPosBidRequest], bidderRequest); - expect(req).to.have.property('method', 'POST'); - expect(req).to.have.property('url'); - expect(req.url).to.contain('https://prebid.technoratimedia.com/openrtb/bids/prebid?src=$$REPO_AND_VERSION$$'); - expect(req.data.id).to.equal('xyz123'); - expect(req.data.imp).to.eql([ - { - banner: { - format: [ - { - h: 250, - w: 300 - } - ], - pos: 0 - }, - id: 'b9876abcd', - tagid: '1234' - } - ]); - }); - it('should not return a request when no valid bid request used', function () { - expect(spec.buildRequests([], bidderRequest)).to.be.undefined; - expect(spec.buildRequests([validBidRequest], null)).to.be.undefined; - }); - - it('should return empty impression when there is no valid sizes in bidrequest', function () { - let validBidReqWithoutSize = { - bidId: '9876abcd', - sizes: [], - params: { - seatId: 'prebid', - tagId: '1234', - bidfloor: '0.50' - } - }; - - let validBidReqInvalidSize = { - bidId: '9876abcd', - sizes: [[300]], - params: { - seatId: 'prebid', - tagId: '1234', - bidfloor: '0.50' - } - }; - - let bidderRequest = { - auctionId: 'xyz123', - refererInfo: { - referer: 'https://test.com/foo/bar' - } - }; - - let req = spec.buildRequests([validBidReqWithoutSize], bidderRequest); - assert.isUndefined(req); - req = spec.buildRequests([validBidReqInvalidSize], bidderRequest); - assert.isUndefined(req); - }); - it('should use all the video params in the impression request', function () { - let validBidRequestVideo = { - bidder: 'synacormedia', - params: { - seatId: 'prebid', - tagId: '1234', - video: { - minduration: 30, - maxduration: 45, - startdelay: 1, - linearity: 1, - placement: 1, - mimes: ['video/mp4'], - protocols: [1], - api: 1 - } - }, - mediaTypes: { - video: { - context: 'instream', - playerSize: [[640, 480]] - } - }, - adUnitCode: 'video1', - transactionId: '93e5def8-29aa-4fe8-bd3a-0298c39f189a', - sizes: [[640, 480]], - bidId: '2624fabbb078e8', - bidderRequestId: '117954d20d7c9c', - auctionId: 'defd525f-4f1e-4416-a4cb-ae53be90e706', - src: 'client', - bidRequestsCount: 1 - }; - - let req = spec.buildRequests([validBidRequestVideo], bidderRequest); - expect(req).to.have.property('method', 'POST'); - expect(req).to.have.property('url'); - expect(req.url).to.contain('https://prebid.technoratimedia.com/openrtb/bids/prebid?src=$$REPO_AND_VERSION$$'); - expect(req.data.id).to.equal('xyz123'); - expect(req.data.imp).to.eql([ - { - video: { - h: 480, - pos: 0, - w: 640, - minduration: 30, - maxduration: 45, - startdelay: 1, - linearity: 1, - placement: 1, - mimes: ['video/mp4'], - protocols: [1], - api: 1 - }, - id: 'v2624fabbb078e8-640x480', - tagid: '1234', - } - ]); - }); - it('should move any video params in the mediaTypes object to params.video object', function () { - let validBidRequestVideo = { - bidder: 'synacormedia', - params: { - seatId: 'prebid', - tagId: '1234', - video: { - minduration: 30, - maxduration: 45, - protocols: [1], - api: 1 - } - }, - mediaTypes: { - video: { - context: 'instream', - playerSize: [[640, 480]], - startdelay: 1, - linearity: 1, - placement: 1, - mimes: ['video/mp4'] - } - }, - adUnitCode: 'video1', - transactionId: '93e5def8-29aa-4fe8-bd3a-0298c39f189a', - sizes: [[640, 480]], - bidId: '2624fabbb078e8', - bidderRequestId: '117954d20d7c9c', - auctionId: 'defd525f-4f1e-4416-a4cb-ae53be90e706', - src: 'client', - bidRequestsCount: 1 - }; - - let req = spec.buildRequests([validBidRequestVideo], bidderRequest); - expect(req).to.have.property('method', 'POST'); - expect(req).to.have.property('url'); - expect(req.url).to.contain('https://prebid.technoratimedia.com/openrtb/bids/prebid?src=$$REPO_AND_VERSION$$'); - expect(req.data.id).to.equal('xyz123'); - expect(req.data.imp).to.eql([ - { - video: { - h: 480, - pos: 0, - w: 640, - minduration: 30, - maxduration: 45, - startdelay: 1, - linearity: 1, - placement: 1, - mimes: ['video/mp4'], - protocols: [1], - api: 1 - }, - id: 'v2624fabbb078e8-640x480', - tagid: '1234', - } - ]); - }); - it('should create params.video object if not present on bid request and move any video params in the mediaTypes object to it', function () { - let validBidRequestVideo = { - bidder: 'synacormedia', - params: { - seatId: 'prebid', - tagId: '1234' - }, - mediaTypes: { - video: { - context: 'instream', - playerSize: [[ 640, 480 ]], - startdelay: 1, - linearity: 1, - placement: 1, - mimes: ['video/mp4'] - } - }, - adUnitCode: 'video1', - transactionId: '93e5def8-29aa-4fe8-bd3a-0298c39f189a', - sizes: [[ 640, 480 ]], - bidId: '2624fabbb078e8', - bidderRequestId: '117954d20d7c9c', - auctionId: 'defd525f-4f1e-4416-a4cb-ae53be90e706', - src: 'client', - bidRequestsCount: 1 - }; - - let req = spec.buildRequests([validBidRequestVideo], bidderRequest); - expect(req.data.imp).to.eql([ - { - video: { - h: 480, - pos: 0, - w: 640, - startdelay: 1, - linearity: 1, - placement: 1, - mimes: ['video/mp4'] - }, - id: 'v2624fabbb078e8-640x480', - tagid: '1234', - } - ]); - }); - it('should contain the CCPA privacy string when UspConsent is in bidder request', function () { - // banner test - let req = spec.buildRequests([validBidRequest], bidderRequestWithCCPA); - expect(req).be.an('object'); - expect(req).to.have.property('method', 'POST'); - expect(req).to.have.property('url'); - expect(req.url).to.contain('https://prebid.technoratimedia.com/openrtb/bids/prebid?'); - expect(req.data).to.exist.and.to.be.an('object'); - expect(req.data.id).to.equal('xyz123'); - expect(req.data.regs.ext.us_privacy).to.equal('1YYY'); - expect(req.data.imp).to.eql([expectedDataImp1]); - }) - }); - - describe('Bid Requests with placementId should be backward compatible ', function () { - let validVideoBidReq = { - bidder: 'synacormedia', - params: { - seatId: 'prebid', - placementId: 'demo1', - pos: 1, - video: {} - }, - renderer: { - url: '../syncOutstreamPlayer.js' - }, - mediaTypes: { - video: { - playerSize: [[300, 250]], - context: 'outstream' - } - }, - adUnitCode: 'div-1', - transactionId: '0869f34e-090b-4b20-84ee-46ff41405a39', - sizes: [[300, 250]], - bidId: '22b3a2268d9f0e', - bidderRequestId: '1d195910597e13', - auctionId: '3375d336-2aea-4ee7-804c-6d26b621ad20', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 - }; - - let validBannerBidRequest = { - bidId: '9876abcd', - sizes: [[300, 250]], - params: { - seatId: 'prebid', - placementId: '1234', - } - }; - - let bidderRequest = { - refererInfo: { - referer: 'http://localhost:9999/' - }, - bidderCode: 'synacormedia', - auctionId: 'f8a75621-d672-4cbb-9275-3db7d74fb110' - }; - - it('should return valid bid request for banner impression', function () { - let req = spec.buildRequests([validBannerBidRequest], bidderRequest); - expect(req).to.have.property('method', 'POST'); - expect(req).to.have.property('url'); - expect(req.url).to.contain('//prebid.technoratimedia.com/openrtb/bids/prebid?src=$$REPO_AND_VERSION$$'); - }); - - it('should return valid bid request for video impression', function () { - let req = spec.buildRequests([validVideoBidReq], bidderRequest); - expect(req).to.have.property('method', 'POST'); - expect(req).to.have.property('url'); - expect(req.url).to.contain('//prebid.technoratimedia.com/openrtb/bids/prebid?src=$$REPO_AND_VERSION$$'); - }); - }); - - describe('Bid Requests with schain object ', function () { - let validBidReq = { - bidder: 'synacormedia', - params: { - seatId: 'prebid', - tagId: 'demo1', - pos: 1, - video: {} - }, - renderer: { - url: '../syncOutstreamPlayer.js' - }, - mediaTypes: { - video: { - playerSize: [[300, 250]], - context: 'outstream' - } - }, - adUnitCode: 'div-1', - transactionId: '0869f34e-090b-4b20-84ee-46ff41405a39', - sizes: [[300, 250]], - bidId: '22b3a2268d9f0e', - bidderRequestId: '1d195910597e13', - auctionId: '3375d336-2aea-4ee7-804c-6d26b621ad20', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0, - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - hp: 1 - } - ] - } - }; - let bidderRequest = { - refererInfo: { - referer: 'http://localhost:9999/' - }, - bidderCode: 'synacormedia', - auctionId: 'f8a75621-d672-4cbb-9275-3db7d74fb110', - bidderRequestId: '16d438671bfbec', - bids: [ - { - bidder: 'synacormedia', - params: { - seatId: 'prebid', - tagId: 'demo1', - pos: 1, - video: {} - }, - renderer: { - url: '../syncOutstreamPlayer.js' - }, - mediaTypes: { - video: { - playerSize: [[300, 250]], - context: 'outstream' - } - }, - adUnitCode: 'div-1', - sizes: [[300, 250]], - bidId: '211c0236bb8f4e', - bidderRequestId: '16d438671bfbec', - auctionId: 'f8a75621-d672-4cbb-9275-3db7d74fb110', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0, - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - hp: 1 - } - ] - } - } - ], - auctionStart: 1580310345205, - timeout: 1000, - start: 1580310345211 - }; - - it('should return valid bid request with schain object', function () { - let req = spec.buildRequests([validBidReq], bidderRequest); - expect(req).to.have.property('method', 'POST'); - expect(req).to.have.property('url'); - expect(req.url).to.contain('//prebid.technoratimedia.com/openrtb/bids/prebid?src=$$REPO_AND_VERSION$$'); - expect(req.data).to.have.property('source'); - expect(req.data.source).to.have.property('ext'); - expect(req.data.source.ext).to.have.property('schain'); - }); - }); - - describe('interpretResponse', function () { - let bidResponse = { - id: '10865933907263896~9998~0', - impid: 'b9876abcd', - price: 0.13, - crid: '1022-250', - adm: '', - nurl: 'https://uat-net.technoratimedia.com/openrtb/tags?ID=k5JkFVQ1RJT05fSU1QX0lEPXYyZjczN&AUCTION_PRICE=${AUCTION_PRICE}', - w: 300, - h: 250 - }; - let bidResponse2 = { - id: '10865933907263800~9999~0', - impid: 'b9876abcd', - price: 1.99, - crid: '9993-013', - adm: '', - nurl: 'https://uat-net.technoratimedia.com/openrtb/tags?ID=OTk5OX4wJkFVQ1RJT05fU0VBVF9JR&AUCTION_PRICE=${AUCTION_PRICE}', - w: 300, - h: 600 - }; - - let bidRequest = { - data: { - id: '', - imp: [ - { - id: 'abc123', - banner: { - format: [ - { - w: 400, - h: 350 - } - ], - pos: 1 - } - } - ], - }, - method: 'POST', - options: { - contentType: 'application/json', - withCredentials: true - }, - url: 'https://prebid.technoratimedia.com/openrtb/bids/prebid?src=prebid_prebid_3.27.0-pre' - }; - let serverResponse; - beforeEach(function () { - serverResponse = { - body: { - id: 'abc123', - seatbid: [{ - seat: '9998', - bid: [], - }] - } - }; - }); - - it('should return 1 video bid when 1 bid is in the video response', function () { - bidRequest = { - data: { - id: 'abcd1234', - imp: [ - { - video: { - w: 640, - h: 480 - }, - id: 'v2da7322b2df61f' - } - ] - }, - method: 'POST', - options: { - contentType: 'application/json', - withCredentials: true - }, - url: 'https://prebid.technoratimedia.com/openrtb/bids/prebid?src=prebid_prebid_3.27.0-pre' - }; - let serverRespVideo = { - body: { - id: 'abcd1234', - seatbid: [ - { - bid: [ - { - id: '11339128001692337~9999~0', - impid: 'v2da7322b2df61f', - price: 0.45, - nurl: 'https://uat-net.technoratimedia.com/openrtb/tags?ID=QVVDVElPTl9JRD1lOTBhYWU1My1hZDkwLTRkNDEtYTQxMC1lZDY1MjIxMDc0ZGMmQVVDVElPTl9CSURfSUQ9MTEzMzkxMjgwMDE2OTIzMzd-OTk5OX4wJkFVQ1RJT05fU0VBVF9JRD05OTk5JkFVQ1RJT05fSU1QX0lEPXYyZGE3MzIyYjJkZjYxZi02NDB4NDgwJkFDVE9SX1JFRj1ha2thLnRjcDovL2F3cy1lYXN0MUBhZHMxMy5jYXAtdXNlMS5zeW5hY29yLmNvbToyNTUxL3VzZXIvJGNMYmZiIy0xOTk4NTIzNTk3JlNFQVRfSUQ9cHJlYmlk&AUCTION_PRICE=${AUCTION_PRICE}', - adm: '\n\n\n\nSynacor Media Ad Server - 9999\nhttps://uat-net.technoratimedia.com/openrtb/tags?ID=QVVDVElPTl9JRD1lOTBhYWU1My1hZDkwLTRkNDEtYTQxMC1lZDY1MjIxMDc0ZGMmQVVDVElPTl9CSURfSUQ9MTEzMzkxMjgwMDE2OTIzMzd-OTk5OX4wJkFVQ1RJT05fU0VBVF9JRD05OTk5JkFVQ1RJT05fSU1QX0lEPXYyZGE3MzIyYjJkZjYxZi02NDB4NDgwJkFDVE9SX1JFRj1ha2thLnRjcDovL2F3cy1lYXN0MUBhZHMxMy5jYXAtdXNlMS5zeW5hY29yLmNvbToyNTUxL3VzZXIvJGNMYmZiIy0xOTk4NTIzNTk3JlNFQVRfSUQ9cHJlYmlk&AUCTION_PRICE=${AUCTION_PRICE}\n\n\n', - adomain: ['psacentral.org'], - cid: 'bidder-crid', - crid: 'bidder-cid', - cat: [], - w: 640, - h: 480 - } - ], - seat: '9999' - } - ] - } - }; - - // serverResponse.body.seatbid[0].bid.push(bidResponse); - let resp = spec.interpretResponse(serverRespVideo, bidRequest); - expect(resp).to.be.an('array').to.have.lengthOf(1); - expect(resp[0]).to.eql({ - requestId: '2da7322b2df61f', - cpm: 0.45, - width: 640, - height: 480, - creativeId: '9999_bidder-cid', - currency: 'USD', - netRevenue: true, - mediaType: 'video', - ad: '\n\n\n\nSynacor Media Ad Server - 9999\nhttps://uat-net.technoratimedia.com/openrtb/tags?ID=QVVDVElPTl9JRD1lOTBhYWU1My1hZDkwLTRkNDEtYTQxMC1lZDY1MjIxMDc0ZGMmQVVDVElPTl9CSURfSUQ9MTEzMzkxMjgwMDE2OTIzMzd-OTk5OX4wJkFVQ1RJT05fU0VBVF9JRD05OTk5JkFVQ1RJT05fSU1QX0lEPXYyZGE3MzIyYjJkZjYxZi02NDB4NDgwJkFDVE9SX1JFRj1ha2thLnRjcDovL2F3cy1lYXN0MUBhZHMxMy5jYXAtdXNlMS5zeW5hY29yLmNvbToyNTUxL3VzZXIvJGNMYmZiIy0xOTk4NTIzNTk3JlNFQVRfSUQ9cHJlYmlk&AUCTION_PRICE=0.45\n\n\n', - ttl: 60, - meta: { advertiserDomains: ['psacentral.org'] }, - videoCacheKey: 'QVVDVElPTl9JRD1lOTBhYWU1My1hZDkwLTRkNDEtYTQxMC1lZDY1MjIxMDc0ZGMmQVVDVElPTl9CSURfSUQ9MTEzMzkxMjgwMDE2OTIzMzd-OTk5OX4wJkFVQ1RJT05fU0VBVF9JRD05OTk5JkFVQ1RJT05fSU1QX0lEPXYyZGE3MzIyYjJkZjYxZi02NDB4NDgwJkFDVE9SX1JFRj1ha2thLnRjcDovL2F3cy1lYXN0MUBhZHMxMy5jYXAtdXNlMS5zeW5hY29yLmNvbToyNTUxL3VzZXIvJGNMYmZiIy0xOTk4NTIzNTk3JlNFQVRfSUQ9cHJlYmlk', - vastUrl: 'https://uat-net.technoratimedia.com/openrtb/tags?ID=QVVDVElPTl9JRD1lOTBhYWU1My1hZDkwLTRkNDEtYTQxMC1lZDY1MjIxMDc0ZGMmQVVDVElPTl9CSURfSUQ9MTEzMzkxMjgwMDE2OTIzMzd-OTk5OX4wJkFVQ1RJT05fU0VBVF9JRD05OTk5JkFVQ1RJT05fSU1QX0lEPXYyZGE3MzIyYjJkZjYxZi02NDB4NDgwJkFDVE9SX1JFRj1ha2thLnRjcDovL2F3cy1lYXN0MUBhZHMxMy5jYXAtdXNlMS5zeW5hY29yLmNvbToyNTUxL3VzZXIvJGNMYmZiIy0xOTk4NTIzNTk3JlNFQVRfSUQ9cHJlYmlk&AUCTION_PRICE=0.45' - }); - }); - - it('should return 1 bid when 1 bid is in the response', function () { - serverResponse.body.seatbid[0].bid.push(bidResponse); - let resp = spec.interpretResponse(serverResponse, bidRequest); - expect(resp).to.be.an('array').to.have.lengthOf(1); - expect(resp[0]).to.eql({ - requestId: '9876abcd', - cpm: 0.13, - width: 300, - height: 250, - creativeId: '9998_1022-250', - currency: 'USD', - netRevenue: true, - mediaType: BANNER, - ad: '', - ttl: 60 - }); - }); - - it('should return 2 bids when 2 bids are in the response', function () { - serverResponse.body.seatbid[0].bid.push(bidResponse); - serverResponse.body.seatbid.push({ - seat: '9999', - bid: [bidResponse2], - }); - let resp = spec.interpretResponse(serverResponse, bidRequest); - expect(resp).to.be.an('array').to.have.lengthOf(2); - expect(resp[0]).to.eql({ - requestId: '9876abcd', - cpm: 0.13, - width: 300, - height: 250, - creativeId: '9998_1022-250', - currency: 'USD', - netRevenue: true, - mediaType: BANNER, - ad: '', - ttl: 60 - }); - - expect(resp[1]).to.eql({ - requestId: '9876abcd', - cpm: 1.99, - width: 300, - height: 600, - creativeId: '9999_9993-013', - currency: 'USD', - netRevenue: true, - mediaType: BANNER, - ad: '', - ttl: 60 - }); - }); - - it('should not return a bid when no bid is in the response', function () { - let resp = spec.interpretResponse(serverResponse, bidRequest); - expect(resp).to.be.an('array').that.is.empty; - }); - - it('should not return a bid when there is no response body', function () { - expect(spec.interpretResponse({ body: null })).to.not.exist; - expect(spec.interpretResponse({ body: 'some error text' })).to.not.exist; - }); - - it('should not include videoCacheKey property on the returned response when cache url is present in the config', function () { - let sandbox = sinon.sandbox.create(); - let serverRespVideo = { - body: { - id: 'abcd1234', - seatbid: [ - { - bid: [ - { - id: '11339128001692337~9999~0', - impid: 'v2da7322b2df61f', - price: 0.45, - nurl: 'https://uat-net.technoratimedia.com/openrtb/tags?ID=QVVDVElPTl9JRD1lOTBhYWU1My1hZDkwLTRkNDEtYTQxMC1lZDY1MjIxMDc0ZGMmQVVDVElPTl9CSURfSUQ9MTEzMzkxMjgwMDE2OTIzMzd-OTk5OX4wJkFVQ1RJT05fU0VBVF9JRD05OTk5JkFVQ1RJT05fSU1QX0lEPXYyZGE3MzIyYjJkZjYxZi02NDB4NDgwJkFDVE9SX1JFRj1ha2thLnRjcDovL2F3cy1lYXN0MUBhZHMxMy5jYXAtdXNlMS5zeW5hY29yLmNvbToyNTUxL3VzZXIvJGNMYmZiIy0xOTk4NTIzNTk3JlNFQVRfSUQ9cHJlYmlk&AUCTION_PRICE=${AUCTION_PRICE}', - adm: '\n\n\n\nSynacor Media Ad Server - 9999\nhttps://uat-net.technoratimedia.com/openrtb/tags?ID=QVVDVElPTl9JRD1lOTBhYWU1My1hZDkwLTRkNDEtYTQxMC1lZDY1MjIxMDc0ZGMmQVVDVElPTl9CSURfSUQ9MTEzMzkxMjgwMDE2OTIzMzd-OTk5OX4wJkFVQ1RJT05fU0VBVF9JRD05OTk5JkFVQ1RJT05fSU1QX0lEPXYyZGE3MzIyYjJkZjYxZi02NDB4NDgwJkFDVE9SX1JFRj1ha2thLnRjcDovL2F3cy1lYXN0MUBhZHMxMy5jYXAtdXNlMS5zeW5hY29yLmNvbToyNTUxL3VzZXIvJGNMYmZiIy0xOTk4NTIzNTk3JlNFQVRfSUQ9cHJlYmlk&AUCTION_PRICE=${AUCTION_PRICE}\n\n\n', - adomain: ['psacentral.org'], - cid: 'bidder-crid', - crid: 'bidder-cid', - cat: [], - w: 640, - h: 480 - } - ], - seat: '9999' - } - ] - } - }; - - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - 'cache.url': 'faKeCacheUrl' - }; - return config[key]; - }); - - let resp = spec.interpretResponse(serverRespVideo, bidRequest); - sandbox.restore(); - expect(resp[0].videoCacheKey).to.not.exist; - }); - - it('should use video bid request height and width if not present in response', function () { - bidRequest = { - data: { - id: 'abcd1234', - imp: [ - { - video: { - w: 300, - h: 250 - }, - id: 'v2da7322b2df61f' - } - ] - }, - method: 'POST', - options: { - contentType: 'application/json', - withCredentials: true - }, - url: 'https://prebid.technoratimedia.com/openrtb/bids/prebid?src=prebid_prebid_3.27.0-pre' - }; - - let serverRespVideo = { - body: { - id: 'abcd1234', - seatbid: [ - { - bid: [ - { - id: '11339128001692337~9999~0', - impid: 'v2da7322b2df61f', - price: 0.45, - nurl: 'https://uat-net.technoratimedia.com/openrtb/tags?ID=QVVDVElPTl9JRD1lOTBhYWU1My1hZDkwLTRkNDEtYTQxMC1lZDY1MjIxMDc0ZGMmQVVDVElPTl9CSURfSUQ9MTEzMzkxMjgwMDE2OTIzMzd-OTk5OX4wJkFVQ1RJT05fU0VBVF9JRD05OTk5JkFVQ1RJT05fSU1QX0lEPXYyZGE3MzIyYjJkZjYxZi02NDB4NDgwJkFDVE9SX1JFRj1ha2thLnRjcDovL2F3cy1lYXN0MUBhZHMxMy5jYXAtdXNlMS5zeW5hY29yLmNvbToyNTUxL3VzZXIvJGNMYmZiIy0xOTk4NTIzNTk3JlNFQVRfSUQ9cHJlYmlk&AUCTION_PRICE=${AUCTION_PRICE}', - adm: '\n\n\n\nSynacor Media Ad Server - 9999\nhttps://uat-net.technoratimedia.com/openrtb/tags?ID=QVVDVElPTl9JRD1lOTBhYWU1My1hZDkwLTRkNDEtYTQxMC1lZDY1MjIxMDc0ZGMmQVVDVElPTl9CSURfSUQ9MTEzMzkxMjgwMDE2OTIzMzd-OTk5OX4wJkFVQ1RJT05fU0VBVF9JRD05OTk5JkFVQ1RJT05fSU1QX0lEPXYyZGE3MzIyYjJkZjYxZi02NDB4NDgwJkFDVE9SX1JFRj1ha2thLnRjcDovL2F3cy1lYXN0MUBhZHMxMy5jYXAtdXNlMS5zeW5hY29yLmNvbToyNTUxL3VzZXIvJGNMYmZiIy0xOTk4NTIzNTk3JlNFQVRfSUQ9cHJlYmlk&AUCTION_PRICE=${AUCTION_PRICE}\n\n\n', - adomain: ['psacentral.org'], - cid: 'bidder-crid', - crid: 'bidder-cid', - cat: [] - } - ], - seat: '9999' - } - ] - } - }; - let resp = spec.interpretResponse(serverRespVideo, bidRequest); - expect(resp).to.be.an('array').to.have.lengthOf(1); - expect(resp[0]).to.eql({ - requestId: '2da7322b2df61f', - cpm: 0.45, - width: 300, - height: 250, - creativeId: '9999_bidder-cid', - currency: 'USD', - netRevenue: true, - mediaType: 'video', - ad: '\n\n\n\nSynacor Media Ad Server - 9999\nhttps://uat-net.technoratimedia.com/openrtb/tags?ID=QVVDVElPTl9JRD1lOTBhYWU1My1hZDkwLTRkNDEtYTQxMC1lZDY1MjIxMDc0ZGMmQVVDVElPTl9CSURfSUQ9MTEzMzkxMjgwMDE2OTIzMzd-OTk5OX4wJkFVQ1RJT05fU0VBVF9JRD05OTk5JkFVQ1RJT05fSU1QX0lEPXYyZGE3MzIyYjJkZjYxZi02NDB4NDgwJkFDVE9SX1JFRj1ha2thLnRjcDovL2F3cy1lYXN0MUBhZHMxMy5jYXAtdXNlMS5zeW5hY29yLmNvbToyNTUxL3VzZXIvJGNMYmZiIy0xOTk4NTIzNTk3JlNFQVRfSUQ9cHJlYmlk&AUCTION_PRICE=0.45\n\n\n', - ttl: 60, - meta: { advertiserDomains: ['psacentral.org'] }, - videoCacheKey: 'QVVDVElPTl9JRD1lOTBhYWU1My1hZDkwLTRkNDEtYTQxMC1lZDY1MjIxMDc0ZGMmQVVDVElPTl9CSURfSUQ9MTEzMzkxMjgwMDE2OTIzMzd-OTk5OX4wJkFVQ1RJT05fU0VBVF9JRD05OTk5JkFVQ1RJT05fSU1QX0lEPXYyZGE3MzIyYjJkZjYxZi02NDB4NDgwJkFDVE9SX1JFRj1ha2thLnRjcDovL2F3cy1lYXN0MUBhZHMxMy5jYXAtdXNlMS5zeW5hY29yLmNvbToyNTUxL3VzZXIvJGNMYmZiIy0xOTk4NTIzNTk3JlNFQVRfSUQ9cHJlYmlk', - vastUrl: 'https://uat-net.technoratimedia.com/openrtb/tags?ID=QVVDVElPTl9JRD1lOTBhYWU1My1hZDkwLTRkNDEtYTQxMC1lZDY1MjIxMDc0ZGMmQVVDVElPTl9CSURfSUQ9MTEzMzkxMjgwMDE2OTIzMzd-OTk5OX4wJkFVQ1RJT05fU0VBVF9JRD05OTk5JkFVQ1RJT05fSU1QX0lEPXYyZGE3MzIyYjJkZjYxZi02NDB4NDgwJkFDVE9SX1JFRj1ha2thLnRjcDovL2F3cy1lYXN0MUBhZHMxMy5jYXAtdXNlMS5zeW5hY29yLmNvbToyNTUxL3VzZXIvJGNMYmZiIy0xOTk4NTIzNTk3JlNFQVRfSUQ9cHJlYmlk&AUCTION_PRICE=0.45' - }); - }); - - it('should use banner bid request height and width if not present in response', function () { - bidRequest = { - data: { - id: 'abc123', - imp: [ - { - banner: { - format: [{ - w: 400, - h: 350 - }] - }, - id: 'babc123' - } - ] - }, - method: 'POST', - options: { - contentType: 'application/json', - withCredentials: true - }, - url: 'https://prebid.technoratimedia.com/openrtb/bids/prebid?src=prebid_prebid_3.27.0-pre' - }; - - bidResponse = { - id: '10865933907263896~9998~0', - impid: 'babc123', - price: 0.13, - crid: '1022-250', - adm: '', - nurl: 'https://uat-net.technoratimedia.com/openrtb/tags?ID=k5JkFVQ1RJT05fSU1QX0lEPXYyZjczN&AUCTION_PRICE=${AUCTION_PRICE}', - }; - - serverResponse.body.seatbid[0].bid.push(bidResponse); - let resp = spec.interpretResponse(serverResponse, bidRequest); - expect(resp).to.be.an('array').to.have.lengthOf(1); - expect(resp[0]).to.eql({ - requestId: 'abc123', - cpm: 0.13, - width: 400, - height: 350, - creativeId: '9998_1022-250', - currency: 'USD', - netRevenue: true, - mediaType: BANNER, - ad: '', - ttl: 60 - }); - }); - }); - describe('getUserSyncs', function () { - it('should return a usersync when iframes is enabled', function () { - let usersyncs = spec.getUserSyncs({ - iframeEnabled: true - }, null); - expect(usersyncs).to.be.an('array').that.is.not.empty; - expect(usersyncs[0]).to.have.property('type', 'iframe'); - expect(usersyncs[0]).to.have.property('url'); - expect(usersyncs[0].url).to.contain('https://ad-cdn.technoratimedia.com/html/usersync.html'); - }); - - it('should not return a usersync when iframes are not enabled', function () { - let usersyncs = spec.getUserSyncs({ - pixelEnabled: true - }, null); - expect(usersyncs).to.be.an('array').that.is.empty; - }); - }); -}); diff --git a/test/spec/modules/tapadIdSystem_spec.js b/test/spec/modules/tapadIdSystem_spec.js deleted file mode 100644 index bc31f1d37ba..00000000000 --- a/test/spec/modules/tapadIdSystem_spec.js +++ /dev/null @@ -1,65 +0,0 @@ -import { tapadIdSubmodule, graphUrl } from 'modules/tapadIdSystem.js'; -import * as utils from 'src/utils.js'; - -import { server } from 'test/mocks/xhr.js'; - -describe('TapadIdSystem', function () { - describe('getId', function() { - const config = { params: { companyId: 12345 } }; - it('should call to real time graph endpoint and handle valid response', function() { - const callbackSpy = sinon.spy(); - const callback = tapadIdSubmodule.getId(config).callback; - callback(callbackSpy); - - const request = server.requests[0]; - expect(request.url).to.eq(`${graphUrl}?company_id=12345&tapad_id_type=TAPAD_ID`); - - request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify({ tapadId: 'your-tapad-id' })); - expect(callbackSpy.lastCall.lastArg).to.eq('your-tapad-id'); - }); - - it('should remove stored tapadId if not found', function() { - const callbackSpy = sinon.spy(); - const callback = tapadIdSubmodule.getId(config).callback; - callback(callbackSpy); - - const request = server.requests[0]; - - request.respond(404); - expect(callbackSpy.lastCall.lastArg).to.be.undefined; - }); - - it('should log message with invalid company id', function() { - const logMessageSpy = sinon.spy(utils, 'logMessage'); - const callbackSpy = sinon.spy(); - const callback = tapadIdSubmodule.getId(config).callback; - callback(callbackSpy); - - const request = server.requests[0]; - - request.respond(403); - expect(logMessageSpy.lastCall.lastArg).to.eq('Invalid Company Id. Contact prebid@tapad.com for assistance.'); - logMessageSpy.restore(); - }); - - it('should log message if company id not given', function() { - const logMessageSpy = sinon.spy(utils, 'logMessage'); - const callbackSpy = sinon.spy(); - const callback = tapadIdSubmodule.getId({}).callback; - callback(callbackSpy); - - expect(logMessageSpy.lastCall.lastArg).to.eq('Please provide a valid Company Id. Contact prebid@tapad.com for assistance.'); - logMessageSpy.restore(); - }); - - it('should log message if company id is incorrect format', function() { - const logMessageSpy = sinon.spy(utils, 'logMessage'); - const callbackSpy = sinon.spy(); - const callback = tapadIdSubmodule.getId({ params: { companyId: 'notANumber' } }).callback; - callback(callbackSpy); - - expect(logMessageSpy.lastCall.lastArg).to.eq('Please provide a valid Company Id. Contact prebid@tapad.com for assistance.'); - logMessageSpy.restore(); - }); - }); -}) diff --git a/test/spec/modules/taphypeBidAdapter_spec.js b/test/spec/modules/taphypeBidAdapter_spec.js deleted file mode 100644 index 6b36973814e..00000000000 --- a/test/spec/modules/taphypeBidAdapter_spec.js +++ /dev/null @@ -1,56 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/taphypeBidAdapter.js'; - -describe('taphypeBidAdapterTests', function () { - it('validate_pub_params', function () { - expect(spec.isBidRequestValid({ - bidder: 'taphype', - params: { - placementId: 12345 - } - })).to.equal(true); - }); - - it('validate_generated_params', function () { - let bidRequestData = [{ - bidId: 'bid12345', - bidder: 'taphype', - params: { - placementId: 12345 - }, - sizes: [[300, 250]] - }]; - - let request = spec.buildRequests(bidRequestData); - let req_data = request[0].data; - - expect(req_data.bidId).to.equal('bid12345'); - }); - - it('validate_response_params', function () { - let bidRequestData = { - data: { - bidId: 'bid12345' - } - }; - - let serverResponse = { - body: { - price: 1.23, - ad: '', - size: '300,250' - } - }; - - let bids = spec.interpretResponse(serverResponse, bidRequestData); - expect(bids).to.have.lengthOf(1); - let bid = bids[0]; - expect(bid.cpm).to.equal(1.23); - expect(bid.currency).to.equal('USD'); - expect(bid.width).to.equal('300'); - expect(bid.height).to.equal('250'); - expect(bid.netRevenue).to.equal(true); - expect(bid.requestId).to.equal('bid12345'); - expect(bid.ad).to.equal(''); - }); -}); diff --git a/test/spec/modules/tappxBidAdapter_spec.js b/test/spec/modules/tappxBidAdapter_spec.js deleted file mode 100644 index 9fab7d858e1..00000000000 --- a/test/spec/modules/tappxBidAdapter_spec.js +++ /dev/null @@ -1,359 +0,0 @@ -import { assert } from 'chai'; -import { spec } from 'modules/tappxBidAdapter'; - -const c_BIDREQUEST = { - data: { - }, - bids: [ - { - bidder: 'tappx', - params: { - host: 'testing.ssp.tappx.com\/rtb\/v2\/', - tappxkey: 'pub-1234-android-1234', - endpoint: 'ZZ1234PBJS', - bidfloor: 0.05 - }, - crumbs: { - pubcid: 'df2144f7-673f-4440-83f5-cd4a73642d99' - }, - fpd: { - context: { - adServer: { - name: 'gam', - adSlot: '/19968336/header-bid-tag-0' - }, - pbAdSlot: '/19968336/header-bid-tag-0', - }, - }, - mediaTypes: { - banner: { - sizes: [ - [ - 320, - 480 - ] - ] - } - }, - adUnitCode: 'div-1', - transactionId: '47dd44e8-e7db-417c-a8f1-621a2e1a117d', - sizes: [ - [ - 320, - 480 - ] - ], - bidId: '2170932097e505', - bidderRequestId: '140ba7a1ab7aeb', - auctionId: '1c54b4f1-645f-44e6-b8ae-5d43c923ef1c', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0, - } - ] -}; -const c_SERVERRESPONSE_B = { - body: { - id: '1c54b4f1-645f-44e6-b8ae-5d43c923ef1c', - bidid: 'bid3811165568213389257', - seatbid: [ - { - seat: '1', - group: 0, - bid: [ - { - id: '3811165568213389257', - impid: 1, - price: 0.05, - adm: "\t", - w: 320, - h: 480, - lurl: 'http://testing.ssp.tappx.com/rtb/RTBv2Loss?id=3811165568213389257&ep=ZZ1234PBJS&au=test&bu=localhost&sz=320x480&pu=0.005&pt=0.01&cid=&crid=&adv=&aid=${AUCTION_ID}&bidid=${AUCTION_BID_ID}&impid=${AUCTION_IMP_ID}&sid=${AUCTION_SEAT_ID}&adid=${AUCTION_AD_ID}&ap=${AUCTION_PRICE}&cur=${AUCTION_CURRENCY}&mbr=${AUCTION_MBR}&l=${AUCTION_LOSS}', - cid: '01744fbb521e9fb10ffea926190effea', - crid: 'a13cf884e66e7c660afec059c89d98b6', - adomain: [ - ], - }, - ], - }, - ], - cur: 'USD', - }, - headers: {} -}; - -const c_SERVERRESPONSE_V = { - body: { - id: '1c54b4f1-645f-44e6-b8ae-5d43c923ef1c', - bidid: 'bid3811165568213389257', - seatbid: [ - { - seat: '1', - group: 0, - bid: [ - { - id: '3811165568213389257', - impid: 1, - price: 0.05, - adm: "Tappx<\/AdSystem>Tappx<\/AdTitle><\/Impression><\/Error>00:00:22<\/Duration><\/Tracking><\/Tracking><\/Tracking><\/Tracking><\/Tracking><\/Tracking><\/Tracking><\/TrackingEvents><\/ClickThrough><\/ClickTracking><\/VideoClicks><\/MediaFile><\/MediaFiles><\/Linear><\/Creative><\/Creatives><\/InLine><\/Ad><\/VAST>", - 'lurl': 'https:\/\/ssp.api.tappx.com\/rtb\/RTBv2Loss?id=5001829913749291152&ep=VZ12TESTCTV&au=test&bu=localhost&sz=6x6&pu=0.005&pt=0.01&cid=&crid=&adv=&aid=${AUCTION_ID}&bidid=${AUCTION_BID_ID}&impid=${AUCTION_IMP_ID}&sid=${AUCTION_SEAT_ID}&adid=${AUCTION_AD_ID}&ap=${AUCTION_PRICE}&cur=${AUCTION_CURRENCY}&mbr=${AUCTION_MBR}&l=${AUCTION_LOSS}', - cid: '01744fbb521e9fb10ffea926190effea', - crid: 'a13cf884e66e7c660afec059c89d98b6', - adomain: [ - ], - }, - ], - }, - ], - cur: 'USD', - }, - headers: {} -}; - -const c_CONSENTSTRING = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; -const c_VALIDBIDREQUESTS = [{'bidder': 'tappx', 'params': {'host': 'testing.ssp.tappx.com\/rtb\/v2\/', 'tappxkey': 'pub-1234-android-1234', 'endpoint': 'ZZ1234PBJS', 'bidfloor': 0.005, 'test': 1}, 'userId': {'haloId': '0000x179MZAzMqUWsFonu7Drm3eDDBMYtj5SPoWQnl89Upk3WTlCvEnKI9SshX0p6eFJ7otPYix179MZAzMqUWsFonu7Drm3eDDBMYtj5SPoWQnl89Upk3WTlCvEnKI9SshX0p6e', 'id5id': {'uid': 'ID5@iu-PJX_OQ0d6FJjKS8kYfUpHriD_rEXbz6UYtYEJelYrDaZOLkh8WcF9J0ZHmEHFKZEBlLXsgP6xqXU3BCj4Ay0Z6fw_jSOaHxMHwd-voRHqFA4Q9NwAxFcVLyPWnNGZ9VbcSAPos1wupq7Xu3MIm-Bw_0vxjhZdWNy4chM9x3i', 'ext': {'linkType': 0}}, 'intentIqId': 'GIF89a\u0000\u0000\u0000\u0000�\u0000\u0000���\u0000\u0000\u0000?�\u0000\u0000\u0000\u0000\u0000\u0000,\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000A\u0000\u0000;', 'lotamePanoramaId': 'xTtLUY7GwqX2MMqSHo9RQ2YUOIBFhlASOR43I9KjvgtcrxIys3RxME96M02LTjWR', 'parrableId': {'eid': '02.YoqC9lWZh8.C8QTSiJTNgI6Pp0KCM5zZgEgwVMSsVP5W51X8cmiUHQESq9WRKB4nreqZJwsWIcNKlORhG4u25Wm6lmDOBmQ0B8hv0KP6uVQ97aouuH52zaz2ctVQTORUKkErPRPcaCJ7dKFcrNoF2i6WOR0S5Nk'}, 'pubcid': 'b1254-152f-12F5-5698-dI1eljK6C7WA', 'pubProvidedId': [{'source': 'domain.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 1, 'ext': {'stype': 'ppuid'}}]}, {'source': '3rdpartyprovided.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 3, 'ext': {'stype': 'sha256email'}}]}]}, 'userIdAsEids': [{'source': 'audigent.com', 'uids': [{'id': '0000fgclxw05ycn0608xiyi90bwpa0c0evvlif0hv1x0i0ku88il0ntek0o0qskvir0trr70u0wqxiix0zq3u1012pa5j315ogh1618nmsj91bmt41c1elzfjf1hl5r1i1kkc2jl', 'atype': 1}]}, {'source': 'id5-sync.com', 'uids': [{'id': 'ID5@iu-PJX_OQ0d6FJjKS8kYfUpHriD_qpoXJUngedfpNva812If1fHEqHHkamLC89txVxk1i9WGqeQrTX97HFCgv9QDa1M_bkHUBsAWFm-D5r1rYrsfMFFiyqwCAEzqNbvsUZXOYCAQSjPcLxR4of22w-U9_JDRThCGRDV3Fmvc38E', 'atype': 1, 'ext': {'linkType': 0}}]}], 'ortb2Imp': {'ext': {'data': {'adserver': {'name': 'gam', 'adslot': '/19968336/header-bid-tag-0'}, 'pbadslot': '/19968336/header-bid-tag-0'}}}, 'mediaTypes': {'banner': {'sizes': [[320, 480], [320, 50]]}}, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'transactionId': '71c0d86b-4b47-4aff-a6da-1af0b1712439', 'sizes': [[320, 480], [320, 50]], 'bidId': '264d7969b125a5', 'bidderRequestId': '1c674c14a3889c', 'auctionId': '13a8a3a9-ed3a-4101-9435-4699ee77bb62', 'src': 'client', 'bidRequestsCount': 1, 'bidderRequestsCount': 1, 'bidderWinsCount': 0}]; -const c_VALIDBIDAPPREQUESTS = [{'bidder': 'tappx', 'params': {'host': 'testing.ssp.tappx.com\/rtb\/v2\/', 'tappxkey': 'pub-1234-android-1234', 'endpoint': 'ZZ1234PBJS', 'bidfloor': 0.005, 'test': 1, 'app': {'name': 'Tappx Test', 'bundle': 'com.test.tappx', 'domain': 'tappx.com', 'publisher': { 'name': 'Tappx', 'domain': 'tappx.com' }}}, 'userId': {'haloId': '0000fgclxw05ycn0608xiyi90bwpa0c0evvlif0hv1x0i0ku88il0ntek0o0qskvir0trr70u0wqxiix0zq3u1012pa5j315ogh1618nmsj91bmt41c1elzfjf1hl5r1i1kkc2jl', 'id5id': {'uid': 'ID5@iu-PJX_OQ0d6FJjKS8kYfUpHriD_qpoXJUngedfpNva812If1fHEqHHkamLC89txVxk1i9WGqeQrTX97HFCgv9QDa1M_bkHUBsAWFm-D5r1rYrsfMFFiyqwCAEzqNbvsUZXOYCAQSjPcLxR4of22w-U9_JDRThCGRDV3Fmvc38E', 'ext': {'linkType': 0}}, 'intentIqId': 'GIF89a\u0001\u0000\u0001\u0000�\u0000\u0000���\u0000\u0000\u0000!�\u0004\u0001\u0000\u0000\u0000\u0000,\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0002\u0002D\u0001\u0000;', 'lotamePanoramaId': '8003916b61a95b185690ec103bdf4945a70213e01818a5e5d8690b542730755a', 'parrableId': {'eid': '01.1617088921.7faa68d9570a50ea8e4f359e9b99ca4b7509e948a6175b3e5b0b8cbaf5b62424104ccfb0191ca79366de8368ed267b89a68e236df5f41f96f238e4301659e9023fec05e46399fb1ad0a0'}, 'pubcid': 'b7143795-852f-42f0-8864-5ecbea1ade4e', 'pubProvidedId': [{'source': 'domain.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 1, 'ext': {'stype': 'ppuid'}}]}, {'source': '3rdpartyprovided.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 3, 'ext': {'stype': 'sha256email'}}]}]}, 'userIdAsEids': [{'source': 'audigent.com', 'uids': [{'id': '0000fgclxw05ycn0608xiyi90bwpa0c0evvlif0hv1x0i0ku88il0ntek0o0qskvir0trr70u0wqxiix0zq3u1012pa5j315ogh1618nmsj91bmt41c1elzfjf1hl5r1i1kkc2jl', 'atype': 1}]}, {'source': 'id5-sync.com', 'uids': [{'id': 'ID5@iu-PJX_OQ0d6FJjKS8kYfUpHriD_qpoXJUngedfpNva812If1fHEqHHkamLC89txVxk1i9WGqeQrTX97HFCgv9QDa1M_bkHUBsAWFm-D5r1rYrsfMFFiyqwCAEzqNbvsUZXOYCAQSjPcLxR4of22w-U9_JDRThCGRDV3Fmvc38E', 'atype': 1, 'ext': {'linkType': 0}}]}, {'source': 'intentiq.com', 'uids': [{'id': 'GIF89a\u0001\u0000\u0001\u0000�\u0000\u0000���\u0000\u0000\u0000!�\u0004\u0001\u0000\u0000\u0000\u0000,\u0000\u0000\u0000\u0000\u0001\u0000\u0001\u0000\u0000\u0002\u0002D\u0001\u0000;', 'atype': 1}]}, {'source': 'crwdcntrl.net', 'uids': [{'id': '8003916b61a95b185690ec103bdf4945a70213e01818a5e5d8690b542730755a', 'atype': 1}]}, {'source': 'parrable.com', 'uids': [{'id': '01.1617088921.7faa68d9570a50ea8e4f359e9b99ca4b7509e948a6175b3e5b0b8cbaf5b62424104ccfb0191ca79366de8368ed267b89a68e236df5f41f96f238e4301659e9023fec05e46399fb1ad0a0', 'atype': 1}]}, {'source': 'pubcid.org', 'uids': [{'id': 'b7143795-852f-42f0-8864-5ecbea1ade4e', 'atype': 1}]}, {'source': 'domain.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 1, 'ext': {'stype': 'ppuid'}}]}, {'source': '3rdpartyprovided.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 3, 'ext': {'stype': 'sha256email'}}]}], 'ortb2Imp': {'ext': {'data': {'adserver': {'name': 'gam', 'adslot': '/19968336/header-bid-tag-0'}, 'pbadslot': '/19968336/header-bid-tag-0'}}}, 'mediaTypes': {'banner': {'sizes': [[320, 480], [320, 50]]}}, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'transactionId': '71c0d86b-4b47-4aff-a6da-1af0b1712439', 'sizes': [[320, 480], [320, 50]], 'bidId': '264d7969b125a5', 'bidderRequestId': '1c674c14a3889c', 'auctionId': '13a8a3a9-ed3a-4101-9435-4699ee77bb62', 'src': 'client', 'bidRequestsCount': 1, 'bidderRequestsCount': 1, 'bidderWinsCount': 0}]; -const c_BIDDERREQUEST_B = {'bidderCode': 'tappx', 'auctionId': '13a8a3a9-ed3a-4101-9435-4699ee77bb62', 'bidderRequestId': '1c674c14a3889c', 'bids': [{'bidder': 'tappx', 'params': {'host': 'testing.ssp.tappx.com\/rtb\/v2\/', 'tappxkey': 'pub-1234-android-1234', 'endpoint': 'ZZ1234PBJS', 'bidfloor': 0.005, 'test': 1}, 'userId': {'haloId': '0000fgclxw05ycn0608xiyi90bwpa0c0evvlif0hv1x0i0ku88il0ntek0o0qskvir0trr70u0wqxiix0zq3u1012pa5j315ogh1618nmsj91bmt41c1elzfjf1hl5r1i1kkc2jl', 'id5id': {'uid': 'ID5@iu-PJX_OQ0d6FJjKS8kYfUpHriD_qpoXJUngedfpNva812If1fHEqHHkamLC89txVxk1i9WGqeQrTX97HFCgv9QDa1M_bkHUBsAWFm-D5r1rYrsfMFFiyqwCAEzqNbvsUZXOYCAQSjPcLxR4of22w-U9_JDRThCGRDV3Fmvc38E', 'ext': {'linkType': 0}}, 'intentIqId': 'GIF89a\u0000\u0000\u0000\u0000�\u0000\u0000���\u0000\u0000\u0000?�\u0000\u0000\u0000\u0000\u0000\u0000,\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000A\u0000\u0000;', 'lotamePanoramaId': '8003916b61a95b185690ec103bdf4945a70213e01818a5e5d8690b542730755a', 'parrableId': {'eid': '01.1617088921.7faa68d9570a50ea8e4f359e9b99ca4b7509e948a6175b3e5b0b8cbaf5b62424104ccfb0191ca79366de8368ed267b89a68e236df5f41f96f238e4301659e9023fec05e46399fb1ad0a0'}, 'pubcid': 'b7143795-852f-42f0-8864-5ecbea1ade4e', 'pubProvidedId': [{'source': 'domain.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 1, 'ext': {'stype': 'ppuid'}}]}, {'source': '3rdpartyprovided.com', 'uids': [{'id': 'value read from cookie or local storage', 'atype': 3, 'ext': {'stype': 'sha256email'}}]}]}, 'userIdAsEids': [{'source': 'audigent.com', 'uids': [{'id': '0000fgclxw05ycn0608xiyi90bwpa0c0evvlif0hv1x0i0ku88il0ntek0o0qskvir0trr70u0wqxiix0zq3u1012pa5j315ogh1618nmsj91bmt41c1elzfjf1hl5r1i1kkc2jl', 'atype': 1}]}, {'source': 'id5-sync.com', 'uids': [{'id': 'ID5@iu-PJX_OQ0d6FJjKS8kYfUpHriD_qpoXJUngedfpNva812If1fHEqHHkamLC89txVxk1i9WGqeQrTX97HFCgv9QDa1M_bkHUBsAWFm-D5r1rYrsfMFFiyqwCAEzqNbvsUZXOYCAQSjPcLxR4of22w-U9_JDRThCGRDV3Fmvc38E', 'atype': 1, 'ext': {'linkType': 0}}]}], 'ortb2Imp': {'ext': {'data': {'adserver': {'name': 'gam', 'adslot': '/19968336/header-bid-tag-0'}, 'pbadslot': '/19968336/header-bid-tag-0'}}}, 'mediaTypes': {'banner': {'sizes': [[320, 480], [320, 50]]}}, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'transactionId': '71c0d86b-4b47-4aff-a6da-1af0b1712439', 'sizes': [[320, 480], [320, 50]], 'bidId': '264d7969b125a5', 'bidderRequestId': '1c674c14a3889c', 'auctionId': '13a8a3a9-ed3a-4101-9435-4699ee77bb62', 'src': 'client', 'bidRequestsCount': 1, 'bidderRequestsCount': 1, 'bidderWinsCount': 0}], 'auctionStart': 1617088922120, 'timeout': 700, 'refererInfo': {'referer': 'http://localhost:9999/integrationExamples/gpt/gdpr_hello_world.html?pbjs_debug=true', 'reachedTop': true, 'isAmp': false, 'numIframes': 0, 'stack': ['http://localhost:9999/integrationExamples/gpt/gdpr_hello_world.html?pbjs_debug=true'], 'canonicalUrl': null}, 'gdprConsent': {'consentString': c_CONSENTSTRING, 'vendorData': {'metadata': 'BO-JeiTPABAOkAAABAENABA', 'gdprApplies': true, 'hasGlobalScope': false, 'cookieVersion': 1, 'created': '2020-12-09T09:22:09.900Z', 'lastUpdated': '2021-01-14T15:44:03.600Z', 'cmpId': 0, 'cmpVersion': 1, 'consentScreen': 0, 'consentLanguage': 'EN', 'vendorListVersion': 1, 'maxVendorId': 0, 'purposeConsents': {}, 'vendorConsents': {}}, 'gdprApplies': true, 'apiVersion': 1}, 'uspConsent': '1YCC', 'start': 1611308859099}; -const c_BIDDERREQUEST_V = {'method': 'POST', 'url': 'https://testing.ssp.tappx.com/rtb/v2//VZ12TESTCTV?type_cnn=prebidjs&v=0.1.10329', 'data': '{"site":{"name":"localhost","bundle":"localhost","domain":"localhost"},"user":{"ext":{}},"id":"e807363f-3095-43a8-a4a6-f44196cb7318","test":1,"at":1,"tmax":1000,"bidder":"tappx","imp":[{"video":{"w":320,"h":250,"mimes":["video/mp4","application/javascript"]},"id":"28f49c71b13f2f","tagid":"localhost_typeAdBanVid_windows","secure":1,"bidfloor":0.005,"ext":{"bidder":{"tappxkey":"pub-1234-desktop-1234","endpoint":"VZ12TESTCTV","host":"testing.ssp.tappx.com/rtb/v2/"}}}],"device":{"os":"windows","ip":"peer","ua":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36","h":864,"w":1536,"dnt":0,"language":"en","make":"Google Inc."},"params":{"host":"tappx.com","bidfloor":0.005},"regs":{"gdpr":0,"ext":{}}}', 'bids': {'bidder': 'tappx', 'params': {'host': 'testing.ssp.tappx.com/rtb/v2/', 'tappxkey': 'pub-1234-desktop-1234', 'endpoint': 'VZ12TESTCTV', 'bidfloor': 0.005, 'test': true}, 'crumbs': {'pubcid': 'dccfe922-3823-4676-b7b2-e5ed8743154e'}, 'ortb2Imp': {'ext': {'data': {'pbadslot': 'video-ad-div'}}}, 'renderer': {'options': {'text': 'Tappx Outstream Video'}}, 'mediaTypes': {'video': {'context': 'instream', 'mimes': ['video/mp4', 'application/javascript'], 'playerSize': [[320, 250]]}}, 'adUnitCode': 'video-ad-div', 'transactionId': 'ed41c805-d14c-49c3-954d-26b98b2aa2c2', 'sizes': [[320, 250]], 'bidId': '28f49c71b13f2f', 'bidderRequestId': '1401710496dc7', 'auctionId': 'e807363f-3095-43a8-a4a6-f44196cb7318', 'src': 'client', 'bidRequestsCount': 1, 'bidderRequestsCount': 1, 'bidderWinsCount': 0}} - -describe('Tappx bid adapter', function () { - /** - * IS REQUEST VALID - */ - describe('isBidRequestValid', function () { - it('should return true when required params found', function () { - assert.isTrue(spec.isBidRequestValid(c_BIDREQUEST.bids[0]), JSON.stringify(c_BIDREQUEST)); - }); - - it('should return false when params are missing', function () { - let badBidRequestParam = JSON.parse(JSON.stringify(c_BIDREQUEST)); - delete badBidRequestParam.bids[0].params; - assert.isFalse(spec.isBidRequestValid(badBidRequestParam.bids[0])); - }); - - it('should return false when tappxkey is missing', function () { - let badBidRequestTpxkey = JSON.parse(JSON.stringify(c_BIDREQUEST)); ; - delete badBidRequestTpxkey.bids[0].params.tappxkey; - assert.isFalse(spec.isBidRequestValid(badBidRequestTpxkey.bids[0])); - }); - - it('should return false when host is missing', function () { - let badBidRequestHost = JSON.parse(JSON.stringify(c_BIDREQUEST)); ; - delete badBidRequestHost.bids[0].params.host; - assert.isFalse(spec.isBidRequestValid(badBidRequestHost.bids[0])); - }); - - it('should return false when classic endpoint is missing', function () { - let badBidRequestClEp = JSON.parse(JSON.stringify(c_BIDREQUEST)); ; - delete badBidRequestClEp.bids[0].params.endpoint; - assert.isFalse(spec.isBidRequestValid(badBidRequestClEp.bids[0])); - }); - - it('should return true when endpoint is not set for new endpoints', function () { - let badBidRequestNwEp = JSON.parse(JSON.stringify(c_BIDREQUEST)); ; - delete badBidRequestNwEp.bids[0].params.endpoint; - badBidRequestNwEp.bids[0].params.host = 'zztesting.ssp.tappx.com/rtb/v2/'; - assert.isTrue(spec.isBidRequestValid(badBidRequestNwEp.bids[0])); - }); - - it('should return false for not instream requests', function () { - let badBidRequest_v = c_BIDDERREQUEST_V; - delete badBidRequest_v.bids.mediaTypes.banner; - badBidRequest_v.bids.mediaTypes.video = {}; - badBidRequest_v.bids.mediaTypes.video.context = 'outstream'; - badBidRequest_v.bids.mediaTypes.video.mimes = [ 'video/mp4', 'application/javascript' ]; - badBidRequest_v.bids.mediaTypes.video.playerSize = [320, 250]; - assert.isFalse(spec.isBidRequestValid(badBidRequest_v.bids)); - }); - }); - - /** - * BUILD REQUEST TEST - */ - describe('buildRequest', function () { - // Web Test - let validBidRequests = c_VALIDBIDREQUESTS; - let validBidRequests_V = c_VALIDBIDREQUESTS; - // App Test - let validAppBidRequests = c_VALIDBIDAPPREQUESTS; - - let bidderRequest = c_BIDDERREQUEST_B; - let bidderRequest_V = c_BIDDERREQUEST_V; - - it('should add gdpr/usp consent information to the request', function () { - const request = spec.buildRequests(validBidRequests, bidderRequest); - const payload = JSON.parse(request[0].data); - - expect(payload.regs.gdpr).to.exist.and.to.be.true; - expect(payload.regs.consent).to.exist.and.to.equal(c_CONSENTSTRING); - expect(payload.regs.ext.us_privacy).to.exist; - }); - - it('should properly build a banner request', function () { - const request = spec.buildRequests(validBidRequests, bidderRequest); - expect(request[0].url).to.match(/^(http|https):\/\/(.*)\.tappx\.com\/.+/); - expect(request[0].method).to.equal('POST'); - - const data = JSON.parse(request[0].data); - expect(data.site).to.not.equal(null); - expect(data.imp).to.have.lengthOf(1); - expect(data.imp[0].bidfloor, data).to.not.be.null; - expect(data.imp[0].banner).to.not.equal(null); - expect(data.imp[0].banner.w).to.be.oneOf([320, 50, 250, 480]); - expect(data.imp[0].banner.h).to.be.oneOf([320, 50, 250, 480]); - }); - - it('should properly build a video request', function () { - const request = spec.buildRequests(validBidRequests_V, bidderRequest_V); - expect(request[0].url).to.match(/^(http|https):\/\/(.*)\.tappx\.com\/.+/); - expect(request[0].method).to.equal('POST'); - - const data = JSON.parse(request[0].data); - expect(data.site).to.not.equal(null); - expect(data.imp).to.have.lengthOf(1); - expect(data.imp[0].bidfloor, data).to.not.be.null; - expect(data.imp[0].banner).to.not.equal(null); - expect(data.imp[0].banner.w).to.be.oneOf([320, 50, 250, 480]); - expect(data.imp[0].banner.h).to.be.oneOf([320, 50, 250, 480]); - }); - - it('should set user eids array', function () { - const request = spec.buildRequests(validBidRequests, bidderRequest); - - const data = JSON.parse(request[0].data); - expect(data.user.ext.eids, data).to.not.be.null; - expect(data.user.ext.eids[0]).to.have.keys(['source', 'uids']); - }); - - it('should properly build a banner request with app params', function () { - const request = spec.buildRequests(validAppBidRequests, bidderRequest); - expect(request[0].url).to.match(/^(http|https):\/\/(.*)\.tappx\.com\/.+/); - expect(request[0].method).to.equal('POST'); - - const data = JSON.parse(request[0].data); - expect(data.site).to.not.equal(null); - expect(data.imp).to.have.lengthOf(1); - expect(data.imp[0].bidfloor, data).to.not.be.null; - expect(data.imp[0].banner).to.not.equal(null); - expect(data.imp[0].banner.w).to.be.oneOf([320, 50, 250, 480]); - expect(data.imp[0].banner.h).to.be.oneOf([320, 50, 250, 480]); - }); - - it('should properly build a ext optional object', function() { - let extBidRequest = c_VALIDBIDREQUESTS; - extBidRequest[0].params.ext = {'optionalData': '1234'}; - let extBidderRequest = c_BIDDERREQUEST_B; - extBidderRequest.bids[0].ext = {'optionalData': '1234'}; - - const request = spec.buildRequests(extBidRequest, extBidderRequest); - const data = JSON.parse(request[0].data); - expect(data.imp[0].ext.bidder.ext).to.be.an('object'); - expect(data.imp[0].ext.bidder.ext.optionalData).to.be.equal('1234'); - }); - - it('should ignore ext optional if is not a object', function() { - let badExtBidRequest = c_VALIDBIDREQUESTS; - badExtBidRequest[0].params.ext = 'stringValue'; - let badExtBidderRequest = c_BIDDERREQUEST_B; - badExtBidderRequest.bids[0].ext = 'stringValue'; - - const request = spec.buildRequests(badExtBidRequest, badExtBidderRequest); - const data = JSON.parse(request[0].data); - expect(data.imp[0].ext.bidder.ext).not.to.be.an('string'); - expect(data.imp[0].ext.bidder.ext).to.be.an('undefined'); - expect(data.imp[0].ext.bidder).to.not.have.property('ext') - }); - }); - - /** - * INTERPRET RESPONSE TESTS - */ - describe('interpretResponse', function () { - it('receive banner reponse with single placement', function () { - const bids = spec.interpretResponse(c_SERVERRESPONSE_B, c_BIDDERREQUEST_B); - const bid = bids[0]; - expect(bid.cpm).to.exist; - expect(bid.ad).to.match(/^', - 'ttl': 700, - 'ad': '' - } - ]; - let request = spec.buildRequests(bidRequests)[0]; - let 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); - expect(result[0].ad).to.not.equal(null); - expect(result[0].currency).to.equal('TRY'); - expect(result[0].netRevenue).to.equal(false); - }); - }) -}) diff --git a/test/spec/modules/terceptAnalyticsAdapter_spec.js b/test/spec/modules/terceptAnalyticsAdapter_spec.js deleted file mode 100644 index 594e1e5f5b4..00000000000 --- a/test/spec/modules/terceptAnalyticsAdapter_spec.js +++ /dev/null @@ -1,787 +0,0 @@ -import terceptAnalyticsAdapter from 'modules/terceptAnalyticsAdapter.js'; -import { expect } from 'chai'; -import adapterManager from 'src/adapterManager.js'; -import * as utils from 'src/utils.js'; -import { server } from 'test/mocks/xhr.js'; - -let events = require('src/events'); -let constants = require('src/constants.json'); - -describe('tercept analytics adapter', function () { - beforeEach(function () { - sinon.stub(events, 'getEvents').returns([]); - }); - - afterEach(function () { - events.getEvents.restore(); - }); - - describe('track', function () { - let initOptions = { - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - hostName: 'us-central1-quikr-ebay.cloudfunctions.net', - pathName: '/prebid-analytics' - }; - - let prebidEvent = { - 'addAdUnits': {}, - 'requestBids': {}, - 'auctionInit': { - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'timestamp': 1576823893836, - 'auctionStatus': 'inProgress', - 'adUnits': [ - { - 'code': 'div-gpt-ad-1460505748561-0', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ] - } - }, - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 - }, - 'crumbs': { - 'pubcid': 'ff4002c4-ce05-4a61-b4ef-45a3cd93991a' - } - } - ], - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'transactionId': '6d275806-1943-4f3e-9cd5-624cbd05ad98' - } - ], - 'adUnitCodes': [ - 'div-gpt-ad-1460505748561-0' - ], - 'bidderRequests': [ - { - 'bidderCode': 'appnexus', - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'bidderRequestId': '155975c76e13b1', - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 - }, - 'crumbs': { - 'pubcid': 'ff4002c4-ce05-4a61-b4ef-45a3cd93991a' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': '6d275806-1943-4f3e-9cd5-624cbd05ad98', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '263efc09896d0c', - 'bidderRequestId': '155975c76e13b1', - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - } - ], - 'auctionStart': 1576823893836, - 'timeout': 1000, - 'refererInfo': { - 'referer': 'http://observer.com/integrationExamples/gpt/hello_world.html', - 'reachedTop': true, - 'numIframes': 0, - 'stack': [ - 'http://observer.com/integrationExamples/gpt/hello_world.html' - ] - }, - 'start': 1576823893838 - } - ], - 'noBids': [], - 'bidsReceived': [], - 'winningBids': [], - 'timeout': 1000 - }, - 'bidRequested': { - 'bidderCode': 'appnexus', - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'bidderRequestId': '155975c76e13b1', - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 - }, - 'crumbs': { - 'pubcid': 'ff4002c4-ce05-4a61-b4ef-45a3cd93991a' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': '6d275806-1943-4f3e-9cd5-624cbd05ad98', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '263efc09896d0c', - 'bidderRequestId': '155975c76e13b1', - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - } - ], - 'auctionStart': 1576823893836, - 'timeout': 1000, - 'refererInfo': { - 'referer': 'http://observer.com/integrationExamples/gpt/hello_world.html', - 'reachedTop': true, - 'numIframes': 0, - 'stack': [ - 'http://observer.com/integrationExamples/gpt/hello_world.html' - ] - }, - 'start': 1576823893838 - }, - 'bidAdjustment': { - 'bidderCode': 'appnexus', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '393976d8770041', - 'requestId': '263efc09896d0c', - 'mediaType': 'banner', - 'source': 'client', - 'cpm': 0.5, - 'creativeId': 96846035, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'appnexus': { - 'buyerMemberId': 9325 - }, - 'meta': { - 'advertiserId': 2529885 - }, - 'ad': '', - 'originalCpm': 0.5, - 'originalCurrency': 'USD', - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'responseTimestamp': 1576823894050, - 'requestTimestamp': 1576823893838, - 'bidder': 'appnexus', - 'timeToRespond': 212 - }, - 'bidTimeout': [ - ], - 'bidResponse': { - 'bidderCode': 'appnexus', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '393976d8770041', - 'requestId': '263efc09896d0c', - 'mediaType': 'banner', - 'source': 'client', - 'cpm': 0.5, - 'creativeId': 96846035, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'appnexus': { - 'buyerMemberId': 9325 - }, - 'meta': { - 'advertiserId': 2529885 - }, - 'ad': '', - 'originalCpm': 0.5, - 'originalCurrency': 'USD', - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'responseTimestamp': 1576823894050, - 'requestTimestamp': 1576823893838, - 'bidder': 'appnexus', - 'timeToRespond': 212, - 'pbLg': '0.50', - 'pbMg': '0.50', - 'pbHg': '0.50', - 'pbAg': '0.50', - 'pbDg': '0.50', - 'pbCg': '', - 'size': '300x250', - 'adserverTargeting': { - 'hb_bidder': 'appnexus', - 'hb_adid': '393976d8770041', - 'hb_pb': '0.50', - 'hb_size': '300x250', - 'hb_source': 'client', - 'hb_format': 'banner' - } - }, - 'auctionEnd': { - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'timestamp': 1576823893836, - 'auctionEnd': 1576823894054, - 'auctionStatus': 'completed', - 'adUnits': [ - { - 'code': 'div-gpt-ad-1460505748561-0', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ] - } - }, - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 - }, - 'crumbs': { - 'pubcid': 'ff4002c4-ce05-4a61-b4ef-45a3cd93991a' - } - } - ], - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'transactionId': '6d275806-1943-4f3e-9cd5-624cbd05ad98' - } - ], - 'adUnitCodes': [ - 'div-gpt-ad-1460505748561-0' - ], - 'bidderRequests': [ - { - 'bidderCode': 'appnexus', - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'bidderRequestId': '155975c76e13b1', - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 - }, - 'crumbs': { - 'pubcid': 'ff4002c4-ce05-4a61-b4ef-45a3cd93991a' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': '6d275806-1943-4f3e-9cd5-624cbd05ad98', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '263efc09896d0c', - 'bidderRequestId': '155975c76e13b1', - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - } - ], - 'auctionStart': 1576823893836, - 'timeout': 1000, - 'refererInfo': { - 'referer': 'http://observer.com/integrationExamples/gpt/hello_world.html', - 'reachedTop': true, - 'numIframes': 0, - 'stack': [ - 'http://observer.com/integrationExamples/gpt/hello_world.html' - ] - }, - 'start': 1576823893838 - } - ], - 'noBids': [], - 'bidsReceived': [ - { - 'bidderCode': 'appnexus', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '393976d8770041', - 'requestId': '263efc09896d0c', - 'mediaType': 'banner', - 'source': 'client', - 'cpm': 0.5, - 'creativeId': 96846035, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'appnexus': { - 'buyerMemberId': 9325 - }, - 'meta': { - 'advertiserId': 2529885 - }, - 'ad': '', - 'originalCpm': 0.5, - 'originalCurrency': 'USD', - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'responseTimestamp': 1576823894050, - 'requestTimestamp': 1576823893838, - 'bidder': 'appnexus', - 'timeToRespond': 212, - 'pbLg': '0.50', - 'pbMg': '0.50', - 'pbHg': '0.50', - 'pbAg': '0.50', - 'pbDg': '0.50', - 'pbCg': '', - 'size': '300x250', - 'adserverTargeting': { - 'hb_bidder': 'appnexus', - 'hb_adid': '393976d8770041', - 'hb_pb': '0.50', - 'hb_size': '300x250', - 'hb_source': 'client', - 'hb_format': 'banner' - } - } - ], - 'winningBids': [], - 'timeout': 1000 - }, - 'setTargeting': { - 'div-gpt-ad-1460505748561-0': { - 'hb_format': 'banner', - 'hb_source': 'client', - 'hb_size': '300x250', - 'hb_pb': '0.50', - 'hb_adid': '393976d8770041', - 'hb_bidder': 'appnexus', - 'hb_format_appnexus': 'banner', - 'hb_source_appnexus': 'client', - 'hb_size_appnexus': '300x250', - 'hb_pb_appnexus': '0.50', - 'hb_adid_appnexus': '393976d8770041', - 'hb_bidder_appnexus': 'appnexus' - } - }, - 'bidderDone': { - 'bidderCode': 'appnexus', - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'bidderRequestId': '155975c76e13b1', - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 - }, - 'crumbs': { - 'pubcid': 'ff4002c4-ce05-4a61-b4ef-45a3cd93991a' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': '6d275806-1943-4f3e-9cd5-624cbd05ad98', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '263efc09896d0c', - 'bidderRequestId': '155975c76e13b1', - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - } - ], - 'auctionStart': 1576823893836, - 'timeout': 1000, - 'refererInfo': { - 'referer': 'http://observer.com/integrationExamples/gpt/hello_world.html', - 'reachedTop': true, - 'numIframes': 0, - 'stack': [ - 'http://observer.com/integrationExamples/gpt/hello_world.html' - ] - }, - 'start': 1576823893838 - }, - 'bidWon': { - 'bidderCode': 'appnexus', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '393976d8770041', - 'requestId': '263efc09896d0c', - 'mediaType': 'banner', - 'source': 'client', - 'cpm': 0.5, - 'creativeId': 96846035, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'appnexus': { - 'buyerMemberId': 9325 - }, - 'meta': { - 'advertiserId': 2529885 - }, - 'ad': '', - 'originalCpm': 0.5, - 'originalCurrency': 'USD', - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'responseTimestamp': 1576823894050, - 'requestTimestamp': 1576823893838, - 'bidder': 'appnexus', - 'timeToRespond': 212, - 'pbLg': '0.50', - 'pbMg': '0.50', - 'pbHg': '0.50', - 'pbAg': '0.50', - 'pbDg': '0.50', - 'pbCg': '', - 'size': '300x250', - 'adserverTargeting': { - 'hb_bidder': 'appnexus', - 'hb_adid': '393976d8770041', - 'hb_pb': '0.50', - 'hb_size': '300x250', - 'hb_source': 'client', - 'hb_format': 'banner' - }, - 'status': 'rendered', - 'params': [ - { - 'placementId': 13144370 - } - ] - } - }; - let location = utils.getWindowLocation(); - - let expectedAfterBid = { - 'bids': [ - { - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'bidId': '263efc09896d0c', - 'bidderCode': 'appnexus', - 'cpm': 0.5, - 'creativeId': 96846035, - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': true, - 'renderStatus': 2, - 'requestId': '155975c76e13b1', - 'requestTimestamp': 1576823893838, - 'responseTimestamp': 1576823894050, - 'sizes': '300x250,300x600', - 'statusMessage': 'Bid available', - 'timeToRespond': 212 - } - ], - 'auctionInit': { - 'host': location.host, - 'path': location.pathname, - 'search': location.search, - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'timestamp': 1576823893836, - 'auctionStatus': 'inProgress', - 'adUnits': [ - { - 'code': 'div-gpt-ad-1460505748561-0', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ] - } - }, - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 - }, - 'crumbs': { - 'pubcid': 'ff4002c4-ce05-4a61-b4ef-45a3cd93991a' - } - } - ], - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'transactionId': '6d275806-1943-4f3e-9cd5-624cbd05ad98' - } - ], - 'adUnitCodes': [ - 'div-gpt-ad-1460505748561-0' - ], - 'bidderRequests': [ - { - 'bidderCode': 'appnexus', - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'bidderRequestId': '155975c76e13b1', - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': 13144370 - }, - 'crumbs': { - 'pubcid': 'ff4002c4-ce05-4a61-b4ef-45a3cd93991a' - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'transactionId': '6d275806-1943-4f3e-9cd5-624cbd05ad98', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '263efc09896d0c', - 'bidderRequestId': '155975c76e13b1', - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - } - ], - 'auctionStart': 1576823893836, - 'timeout': 1000, - 'refererInfo': { - 'referer': 'http://observer.com/integrationExamples/gpt/hello_world.html', - 'reachedTop': true, - 'numIframes': 0, - 'stack': [ - 'http://observer.com/integrationExamples/gpt/hello_world.html' - ] - }, - 'start': 1576823893838 - } - ], - 'noBids': [], - 'bidsReceived': [], - 'winningBids': [], - 'timeout': 1000, - 'config': initOptions - }, - 'initOptions': initOptions - }; - - let expectedAfterBidWon = { - 'bidWon': { - 'bidderCode': 'appnexus', - 'bidId': '263efc09896d0c', - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'auctionId': 'db377024-d866-4a24-98ac-5e430f881313', - 'creativeId': 96846035, - 'currency': 'USD', - 'cpm': 0.5, - 'netRevenue': true, - 'renderedSize': '300x250', - 'mediaType': 'banner', - 'statusMessage': 'Bid available', - 'status': 'rendered', - 'renderStatus': 4, - 'timeToRespond': 212, - 'requestTimestamp': 1576823893838, - 'responseTimestamp': 1576823894050 - }, - 'initOptions': initOptions - } - - adapterManager.registerAnalyticsAdapter({ - code: 'tercept', - adapter: terceptAnalyticsAdapter - }); - - beforeEach(function () { - adapterManager.enableAnalytics({ - provider: 'tercept', - options: initOptions - }); - }); - - afterEach(function () { - terceptAnalyticsAdapter.disableAnalytics(); - }); - - it('builds and sends auction data', function () { - // Step 1: Send auction init event - events.emit(constants.EVENTS.AUCTION_INIT, prebidEvent['auctionInit']); - - // Step 2: Send bid requested event - events.emit(constants.EVENTS.BID_REQUESTED, prebidEvent['bidRequested']); - - // Step 3: Send bid response event - events.emit(constants.EVENTS.BID_RESPONSE, prebidEvent['bidResponse']); - - // Step 4: Send bid time out event - events.emit(constants.EVENTS.BID_TIMEOUT, prebidEvent['bidTimeout']); - - // Step 5: Send auction end event - events.emit(constants.EVENTS.AUCTION_END, prebidEvent['auctionEnd']); - - expect(server.requests.length).to.equal(1); - - let realAfterBid = JSON.parse(server.requests[0].requestBody); - - expect(realAfterBid).to.deep.equal(expectedAfterBid); - - // Step 6: Send auction bid won event - events.emit(constants.EVENTS.BID_WON, prebidEvent['bidWon']); - - expect(server.requests.length).to.equal(2); - - let winEventData = JSON.parse(server.requests[1].requestBody); - - expect(winEventData).to.deep.equal(expectedAfterBidWon); - }); - }); -}); diff --git a/test/spec/modules/theAdxBidAdapter_spec.js b/test/spec/modules/theAdxBidAdapter_spec.js deleted file mode 100644 index 99e5156190c..00000000000 --- a/test/spec/modules/theAdxBidAdapter_spec.js +++ /dev/null @@ -1,642 +0,0 @@ -import { - expect -} from 'chai'; -import { - spec, - internals -} from 'modules/theAdxBidAdapter.js'; -import { - newBidder -} from 'src/adapters/bidderFactory.js'; - -describe('TheAdxAdapter', function () { - const adapter = newBidder(spec); - - describe('getUserSyncs', () => { - const USER_SYNC_IFRAME_URL = 'https://ssp.theadx.com/async_usersync_iframe.html' - const USER_SYNC_IMAGE_URL = 'https://ssp.theadx.com/async_usersync_image.gif' - - expect(spec.getUserSyncs({ - iframeEnabled: true, - pixelEnabled: true, - }, [{ - body: { - ext: { - sync: { - iframe: [USER_SYNC_IFRAME_URL], - image: [USER_SYNC_IMAGE_URL], - } - } - } - }])).to.deep.equal([{ - type: 'iframe', - url: USER_SYNC_IFRAME_URL - }, - { - type: 'image', - url: USER_SYNC_IMAGE_URL - }, - ]); - }); - - describe('bid validator', function () { - it('rejects a bid that is missing the placementId', function () { - let testBid = {}; - expect(spec.isBidRequestValid(testBid)).to.be.false; - }); - - it('accepts a bid with all the expected parameters', function () { - let testBid = { - params: { - pid: '1', - tagId: '1', - } - }; - - expect(spec.isBidRequestValid(testBid)).to.be.true; - }); - }); - - describe('request builder', function () { - // Taken from the docs, so used as much as is valid - const sampleBidRequest = { - 'bidder': 'tests', - 'bidId': '51ef8751f9aead', - 'params': { - 'pid': '1', - 'tagId': '1', - }, - 'adUnitCode': 'div-gpt-ad-sample', - 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', - 'sizes': [ - [300, 250] - ], - 'bidderRequestId': '418b37f85e772c', - 'auctionId': '18fd8b8b0bd757', - 'mediaTypes': { - banner: { - 'sizes': [ - [320, 50], - [300, 250], - [300, 600] - ] - } - } - }; - - const sampleBidderRequest = { - bidderRequestId: 'sample', - refererInfo: { - canonicalUrl: 'https://domain.com/to', - referer: 'https://domain.com/from' - } - } - - it('successfully generates a URL', function () { - const placementId = '1'; - - const bidRequests = [sampleBidRequest]; - - let results = spec.buildRequests(bidRequests, sampleBidderRequest); - let result = results.pop(); - - expect(result.url).to.not.be.undefined; - expect(result.url).to.not.be.null; - - expect(result.url).to.include('tagid=' + placementId); - }); - - it('uses the bidId id as the openRtb request ID', function () { - const bidId = '51ef8751f9aead'; - - let bidRequests = [ - sampleBidRequest - ]; - - let results = spec.buildRequests(bidRequests, sampleBidderRequest); - let result = results.pop(); - - // Double encoded JSON - let payload = JSON.parse(result.data); - - expect(payload).to.not.be.null; - expect(payload.id).to.equal(bidId); - }); - - it('generates the device payload as expected', function () { - let bidRequests = [ - sampleBidRequest - ]; - - let results = spec.buildRequests(bidRequests, sampleBidderRequest); - let result = results.pop(); - - // Double encoded JSON - let payload = JSON.parse(result.data); - - expect(payload).to.not.be.null; - let userData = payload.user; - - expect(userData).to.not.be.null; - }); - - it('generates multiple requests with single imp bodies', function () { - const SECOND_PLACEMENT_ID = '2'; - let firstBidRequest = JSON.parse(JSON.stringify(sampleBidRequest)); - let secondBidRequest = JSON.parse(JSON.stringify(sampleBidRequest)); - secondBidRequest.params.tagId = SECOND_PLACEMENT_ID; - - let bidRequests = [ - firstBidRequest, - secondBidRequest - ]; - - let results = spec.buildRequests(bidRequests, sampleBidderRequest); - - expect(results instanceof Array).to.be.true; - expect(results.length).to.equal(2); - - let firstRequest = results[0]; - - // Double encoded JSON - let firstPayload = JSON.parse(firstRequest.data); - - expect(firstPayload).to.not.be.null; - expect(firstPayload.imp).to.not.be.null; - expect(firstPayload.imp.length).to.equal(1); - - expect(firstRequest.url).to.not.be.null; - expect(firstRequest.url.indexOf('tagid=1')).to.be.gt(0); - - let secondRequest = results[1]; - - // Double encoded JSON - let secondPayload = JSON.parse(secondRequest.data); - - expect(secondPayload).to.not.be.null; - expect(secondPayload.imp).to.not.be.null; - expect(secondPayload.imp.length).to.equal(1); - - expect(secondRequest.url).to.not.be.null; - expect(secondRequest.url.indexOf(`tagid=${SECOND_PLACEMENT_ID}`)).to.be.gte(0); - }); - - it('generates a banner request as expected', function () { - // clone the sample for stability - let localBidRequest = JSON.parse(JSON.stringify(sampleBidRequest)); - - let results = spec.buildRequests([localBidRequest], sampleBidderRequest); - let result = results.pop(); - - // Double encoded JSON - let payload = JSON.parse(result.data); - - expect(payload).to.not.be.null; - - let imps = payload.imp; - - let firstImp = imps[0]; - - expect(firstImp.banner).to.not.be.null; - - let bannerData = firstImp.banner; - - expect(bannerData.w).to.equal(320); - expect(bannerData.h).to.equal(50); - }); - - it('generates a banner request using a singular adSize instead of an array', function () { - // clone the sample for stability - let localBidRequest = JSON.parse(JSON.stringify(sampleBidRequest)); - localBidRequest.sizes = [320, 50]; - localBidRequest.mediaTypes = { - banner: {} - }; - - let results = spec.buildRequests([localBidRequest], sampleBidderRequest); - let result = results.pop(); - - // Double encoded JSON - let payload = JSON.parse(result.data); - - expect(payload).to.not.be.null; - - let imps = payload.imp; - - let firstImp = imps[0]; - - expect(firstImp.banner).to.not.be.null; - - let bannerData = firstImp.banner; - - expect(bannerData.w).to.equal(320); - expect(bannerData.h).to.equal(50); - }); - - it('fails gracefully on an invalid size', function () { - // clone the sample for stability - let localBidRequest = JSON.parse(JSON.stringify(sampleBidRequest)); - localBidRequest.sizes = ['x', 'w']; - - localBidRequest.mediaTypes = { - banner: { - sizes: ['y', 'z'] - } - }; - - let results = spec.buildRequests([localBidRequest], sampleBidderRequest); - let result = results.pop(); - - // Double encoded JSON - let payload = JSON.parse(result.data); - - expect(payload).to.not.be.null; - - let imps = payload.imp; - - let firstImp = imps[0]; - - expect(firstImp.banner).to.not.be.null; - - let bannerData = firstImp.banner; - - expect(bannerData.w).to.equal(null); - expect(bannerData.h).to.equal(null); - }); - - it('generates a video request as expected', function () { - // clone the sample for stability - let localBidRequest = JSON.parse(JSON.stringify(sampleBidRequest)); - - localBidRequest.mediaTypes = { - video: { - sizes: [ - [326, 256] - ] - } - }; - - let results = spec.buildRequests([localBidRequest], sampleBidderRequest); - let result = results.pop(); - - // Double encoded JSON - let payload = JSON.parse(result.data); - - expect(payload).to.not.be.null; - - let imps = payload.imp; - - let firstImp = imps[0]; - - expect(firstImp.video).to.not.be.null; - - let videoData = firstImp.video; - expect(videoData.w).to.equal(326); - expect(videoData.h).to.equal(256); - }); - - it('generates a native request as expected', function () { - // clone the sample for stability - let localBidRequest = JSON.parse(JSON.stringify(sampleBidRequest)); - - localBidRequest.mediaTypes = { - native: { - image: { - required: false, - sizes: [100, 50] - }, - title: { - required: false, - len: 140 - }, - sponsoredBy: { - required: false - }, - clickUrl: { - required: false - }, - body: { - required: false - }, - icon: { - required: false, - sizes: [50, 50] - }, - } - }; - - let results = spec.buildRequests([localBidRequest], sampleBidderRequest); - let result = results.pop(); - - // Double encoded JSON - let payload = JSON.parse(result.data); - - expect(payload).to.not.be.null; - - let imps = payload.imp; - - let firstImp = imps[0]; - - expect(firstImp.native).to.not.be.null; - }); - - it('propagates the mediaTypes object in the built request', function () { - let localBidRequest = JSON.parse(JSON.stringify(sampleBidRequest)); - - localBidRequest.mediaTypes = { - video: {} - }; - - let results = spec.buildRequests([localBidRequest], sampleBidderRequest); - let result = results.pop(); - - let mediaTypes = result.mediaTypes; - - expect(mediaTypes).to.not.be.null; - expect(mediaTypes).to.not.be.undefined; - expect(mediaTypes.video).to.not.be.null; - expect(mediaTypes.video).to.not.be.undefined; - }); - }); - - describe('response interpreter', function () { - it('returns an empty array when no bids present', function () { - // an empty JSON body indicates no ad was found - - let result = spec.interpretResponse({ - body: '' - }, {}) - - expect(result).to.eql([]); - }); - - it('gracefully fails when a non-JSON body is present', function () { - let result = spec.interpretResponse({ - body: 'THIS IS NOT ' - }, {}) - - expect(result).to.eql([]); - }); - - it('returns a valid bid response on sucessful banner request', function () { - let incomingRequestId = 'XXtestingXX'; - let responsePrice = 3.14 - - let responseCreative = 'sample_creative&{FOR_COVARAGE}'; - - let responseCreativeId = '274'; - let responseCurrency = 'TRY'; - - let responseWidth = 300; - let responseHeight = 250; - let responseTtl = 213; - - let sampleResponse = { - id: '66043f5ca44ecd8f8769093b1615b2d9', - seatbid: [{ - bid: [{ - id: 'c21bab0e-7668-4d8f-908a-63e094c09197', - impid: '1', - price: responsePrice, - adid: responseCreativeId, - crid: responseCreativeId, - adm: responseCreative, - adomain: [ - 'www.domain.com' - ], - cid: '274', - attr: [], - w: responseWidth, - h: responseHeight, - ext: { - ttl: responseTtl - } - }], - seat: '201', - group: 0 - }], - bidid: 'c21bab0e-7668-4d8f-908a-63e094c09197', - cur: responseCurrency - }; - - let sampleRequest = { - bidId: incomingRequestId, - mediaTypes: { - banner: {} - }, - requestId: incomingRequestId - }; - let serverResponse = { - body: sampleResponse - } - let result = spec.interpretResponse(serverResponse, sampleRequest); - - expect(result.length).to.equal(1); - - let processedBid = result[0]; - - // expect(processedBid.requestId).to.equal(incomingRequestId); - expect(processedBid.cpm).to.equal(responsePrice); - expect(processedBid.width).to.equal(responseWidth); - expect(processedBid.height).to.equal(responseHeight); - expect(processedBid.ad).to.equal(responseCreative); - expect(processedBid.ttl).to.equal(responseTtl); - expect(processedBid.creativeId).to.equal(responseCreativeId); - expect(processedBid.netRevenue).to.equal(true); - expect(processedBid.currency).to.equal(responseCurrency); - }); - - it('returns an valid bid response on sucessful video request', function () { - let incomingRequestId = 'XXtesting-275XX'; - let responsePrice = 6 - let vast_url = 'https://theadx.com/vast?rid=a8ae0b48-a8db-4220-ba0c-7458f452b1f5&{FOR_COVARAGE}' - - let responseCreativeId = '1556'; - let responseCurrency = 'TRY'; - - let responseWidth = 284; - let responseHeight = 285; - let responseTtl = 286; - - let sampleResponse = { - id: '1234567890', - seatbid: [{ - bid: [{ - id: 'a8ae0b48-a8db-4220-ba0c-7458f452b1f5', - impid: '1', - price: responsePrice, - adid: responseCreativeId, - crid: responseCreativeId, - cid: '270', - attr: [], - w: responseWidth, - h: responseHeight, - ext: { - vast_url: vast_url, - ttl: responseTtl - } - }], - seat: '201', - group: 0 - }], - bidid: 'a8ae0b48-a8db-4220-ba0c-7458f452b1f5', - cur: 'TRY' - }; - - let sampleRequest = { - bidId: incomingRequestId, - mediaTypes: { - video: {} - }, - requestId: incomingRequestId - }; - - let result = spec.interpretResponse({ - body: sampleResponse - }, - sampleRequest - ); - - expect(result.length).to.equal(1); - - let processedBid = result[0]; - // expect(processedBid.requestId).to.equal(incomingRequestId); - expect(processedBid.cpm).to.equal(responsePrice); - expect(processedBid.width).to.equal(responseWidth); - expect(processedBid.height).to.equal(responseHeight); - expect(processedBid.ad).to.equal(null); - expect(processedBid.ttl).to.equal(responseTtl); - expect(processedBid.creativeId).to.equal(responseCreativeId); - expect(processedBid.netRevenue).to.equal(true); - expect(processedBid.currency).to.equal(responseCurrency); - expect(processedBid.vastUrl).to.equal(vast_url); - }); - - it('returns an valid bid response on sucessful native request', function () { - let incomingRequestId = 'XXtesting-275XX'; - let responsePrice = 6 - let nurl = 'https://app.theadx.com/ixc?rid=02aefd80-2df9-11e9-896d-d33384d77f5c&time=v-1549888312715&sp=1WzMjcRpeyk%3D'; - let linkUrl = 'https%3A%2F%2Fapp.theadx.com%2Fgclick%3Frid%3D02aefd80-2df9-11e9-896d-d33384d77f5c%26url%3Dhttps%253A%252F%252Fwww.theadx.com%252Ftr%252Fhedeflemeler' - let responseCreativeId = '1556'; - let responseCurrency = 'TRY'; - - let responseTtl = 286; - - let sampleResponse = { - id: '1234567890', - seatbid: [{ - bid: [{ - id: 'a8ae0b48-a8db-4220-ba0c-7458f452b1f5', - impid: '1', - nurl: nurl, - price: responsePrice, - adid: responseCreativeId, - crid: responseCreativeId, - cid: '270', - attr: [], - ext: { - ttl: responseTtl, - native: { - ver: 1, - link: { - url: linkUrl - }, - assets: [{ - id: 3, - img: { - url: 'https://ads.theadx.com/winwords/120/17508/154712307258.73.jpg', - h: 627, - w: 1200 - } - }, { - id: 0, - title: { - ext: 'SELF-MANAGED DSP' - } - }, { - id: 5, - data: { - value: 'Sponsored by Theadx' - } - }, { - id: 4, - data: { - value: 'Gerçek Zamanlı Self-Managed DSP ile kampanya oluşturmak ve yönetmek çok kolay ' - } - }, { - id: 2, - img: { - url: 'https://ads.theadx.com/winwords/120/17508/154712307258.74.png', - h: 128, - w: 128 - } - }] - }, - - rid: '02ac3e60-2df9-11e9-9d09-bba751e172da', - impu: 'https://ssp.theadx.com/ixc?rid=02ac3e60-2df9-11e9-9d09-bba751e172da&time=1549888312719&tid=1', - cliu: 'https://ssp.theadx.com/click?trid=02ac3e60-2df9-11e9-9d09-bba751e172da' - - } - }], - seat: '201', - group: 0 - }], - bidid: 'a8ae0b48-a8db-4220-ba0c-7458f452b1f5', - cur: 'TRY' - }; - - let sampleRequest = { - bidId: incomingRequestId, - mediaTypes: { - native: { - image: { - required: false, - sizes: [100, 50] - }, - title: { - required: false, - len: 140 - }, - sponsoredBy: { - required: false - }, - clickUrl: { - required: false - }, - body: { - required: false - }, - icon: { - required: false, - sizes: [50, 50] - } - - }, - }, - requestId: incomingRequestId - }; - - let result = spec.interpretResponse({ - body: sampleResponse - }, - sampleRequest - ); - - expect(result.length).to.equal(1); - - let processedBid = result[0]; - // expect(processedBid.requestId).to.equal(incomingRequestId); - expect(processedBid.cpm).to.equal(responsePrice); - expect(processedBid.width).to.equal(0); - expect(processedBid.height).to.equal(0); - expect(processedBid.ad).to.equal(null); - expect(processedBid.ttl).to.equal(responseTtl); - expect(processedBid.creativeId).to.equal(responseCreativeId); - expect(processedBid.netRevenue).to.equal(true); - expect(processedBid.currency).to.equal(responseCurrency); - expect(processedBid.native.impressionTrackers[0]).to.equal(nurl); - expect(processedBid.native.clickUrl).to.equal(linkUrl); - }); - }); -}); diff --git a/test/spec/modules/timBidAdapter_spec.js b/test/spec/modules/timBidAdapter_spec.js deleted file mode 100644 index bf2d2e28510..00000000000 --- a/test/spec/modules/timBidAdapter_spec.js +++ /dev/null @@ -1,152 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/timBidAdapter.js'; - -describe('timAdapterTests', function () { - describe('bidRequestValidity', function () { - it('bidRequest with publisherid and placementCode params', function () { - expect(spec.isBidRequestValid({ - bidder: 'tim', - params: { - publisherid: 'testid', - placementCode: 'testplacement' - } - })).to.equal(true); - }); - - it('bidRequest with only publisherid', function () { - expect(spec.isBidRequestValid({ - bidder: 'tim', - params: { - publisherid: 'testid' - } - })).to.equal(false); - }); - - it('bidRequest with only placementCode', function () { - expect(spec.isBidRequestValid({ - bidder: 'tim', - params: { - placementCode: 'testplacement' - } - })).to.equal(false); - }); - - it('bidRequest without params', function () { - expect(spec.isBidRequestValid({ - bidder: 'tim', - })).to.equal(false); - }); - }); - - describe('buildRequests', function () { - const validBidRequests = [{ - 'bidder': 'tim', - 'params': {'placementCode': 'placementCode', 'publisherid': 'testpublisherid'}, - 'mediaTypes': {'banner': {'sizes': [[300, 250]]}}, - 'adUnitCode': 'adUnitCode', - 'transactionId': 'transactionId', - 'sizes': [[300, 250]], - 'bidId': 'bidId', - 'bidderRequestId': 'bidderRequestId', - 'auctionId': 'auctionId', - 'src': 'client', - 'bidRequestsCount': 1 - }]; - - it('bidRequest method', function () { - const requests = spec.buildRequests(validBidRequests); - expect(requests[0].method).to.equal('GET'); - }); - - it('bidRequest url', function () { - const requests = spec.buildRequests(validBidRequests); - expect(requests[0].url).to.exist; - }); - - it('bidRequest data', function () { - const requests = spec.buildRequests(validBidRequests); - expect(requests[0].data).to.exist; - }); - - it('bidRequest options', function () { - const requests = spec.buildRequests(validBidRequests); - expect(requests[0].options).to.exist; - }); - }); - - describe('interpretResponse', function () { - const bidRequest = { - 'method': 'GET', - 'url': 'https://bidder.url/api/prebid/testpublisherid/header-bid-tag-0?br=%7B%22id%22%3A%223a3ac0d7fc2548%22%2C%22imp%22%3A%5B%7B%22id%22%3A%22251b8a6d3aac3e%22%2C%22banner%22%3A%7B%22w%22%3A300%2C%22h%22%3A250%7D%2C%22tagid%22%3A%22header-bid-tag-0%22%7D%5D%2C%22site%22%3A%7B%22domain%22%3A%22www.chinatimes.com%22%2C%22page%22%3A%22https%3A%2F%2Fwww.chinatimes.com%2Fa%22%2C%22publisher%22%3A%7B%22id%22%3A%22testpublisherid%22%7D%7D%2C%22device%22%3A%7B%22language%22%3A%22en%22%2C%22w%22%3A300%2C%22h%22%3A250%2C%22js%22%3A1%2C%22ua%22%3A%22Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F71.0.3578.98%20Safari%2F537.36%22%7D%2C%22bidId%22%3A%22251b8a6d3aac3e%22%7D', - 'data': '', - 'options': {'withCredentials': false} - }; - - const serverResponse = { - 'body': { - 'id': 'id', - 'seatbid': [] - }, - 'headers': {} - }; - - it('check empty array response', function () { - const result = spec.interpretResponse(serverResponse, bidRequest); - expect(result).to.deep.equal([]); - }); - - const validBidRequest = { - 'method': 'GET', - 'url': 'https://bidder.url/api/v2/services/prebid/testpublisherid/placementCodeTest?br=%7B%22id%22%3A%2248640869bd9db94%22%2C%22imp%22%3A%5B%7B%22id%22%3A%224746fcaa11197f3%22%2C%22banner%22%3A%7B%22w%22%3A300%2C%22h%22%3A250%7D%2C%22tagid%22%3A%22placementCodeTest%22%7D%5D%2C%22site%22%3A%7B%22domain%22%3A%22mediamart.tv%22%2C%22page%22%3A%22https%3A%2F%2Fmediamart.tv%2Fsas%2Ftests%2FDesktop%2Fcaesar%2Fdfptest.html%22%2C%22publisher%22%3A%7B%22id%22%3A%22testpublisherid%22%7D%7D%2C%22device%22%3A%7B%22language%22%3A%22en%22%2C%22w%22%3A300%2C%22h%22%3A250%2C%22js%22%3A1%2C%22ua%22%3A%22Mozilla%2F5.0%20(Windows%20NT%2010.0%3B%20Win64%3B%20x64)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Chrome%2F71.0.3578.98%20Safari%2F537.36%22%7D%2C%22bidId%22%3A%224746fcaa11197f3%22%7D', - 'data': '', - 'options': {'withCredentials': false} - }; - const validServerResponse = { - 'body': {'id': 'id', - 'seatbid': [ - {'bid': [{'id': 'id', - 'impid': 'impid', - 'price': 3, - 'nurl': 'https://bidder.url/api/v1/?price=${AUCTION_PRICE}&bidcur=USD&bidid=bidid=true', - 'adm': '', - 'adomain': [''], - 'cid': '1', - 'crid': '700', - 'w': 300, - 'h': 250 - }]}], - 'bidid': 'bidid', - 'cur': 'USD' - }, - 'headers': {} - }; - it('required keys', function () { - const result = spec.interpretResponse(validServerResponse, validBidRequest); - - let requiredKeys = [ - 'requestId', - 'creativeId', - 'adId', - 'cpm', - 'width', - 'height', - 'currency', - 'netRevenue', - 'ttl', - 'ad' - ]; - - let resultKeys = Object.keys(result[0]); - requiredKeys.forEach(function(key) { - expect(resultKeys.indexOf(key) !== -1).to.equal(true); - }); - }) - }); - - describe('getUserSyncs', function () { - it('check empty response getUserSyncs', function () { - const result = spec.getUserSyncs('', ''); - expect(result).to.deep.equal([]); - }); - }); -}); diff --git a/test/spec/modules/topRTBBidAdapter_spec.js b/test/spec/modules/topRTBBidAdapter_spec.js deleted file mode 100644 index 9b97917a0b6..00000000000 --- a/test/spec/modules/topRTBBidAdapter_spec.js +++ /dev/null @@ -1,67 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/topRTBBidAdapter.js'; - -describe('topRTBBidAdapterTests', function () { - it('validate_pub_params', function () { - expect(spec.isBidRequestValid({ - bidder: 'topRTB', - params: { - adUnitId: 'c5c06f77430c4c33814a0577cb4cc978' - }, - adName: 'banner' - })); - }); - - it('validate_generated_params', function () { - let bidRequestData = [{ - bidId: 'bid12345', - bidder: 'topRTB', - adName: 'banner', - adType: '{"banner":{"sizes":[[]]}}', - params: { - adUnitId: 'c5c06f77430c4c33814a0577cb4cc978' - }, - sizes: [[728, 90]] - }]; - - let request = spec.buildRequests(bidRequestData); - const current_url = request.url; - const search_params = current_url.searchParams; - }); - - it('validate_response_params', function () { - let bidRequestData = { - data: { - bidId: 'bid12345' - } - }; - - let serverResponse = { - body: [{ - 'cpm': 1, - 'mediadata': "Banner 728x90", - 'width': 728, - 'currency': 'USD', - 'id': 'cd95dffec6b645afbc4e5aa9f68f2ff3', - 'type': 'RICHMEDIA', - 'ttl': 4000, - 'bidId': 'bid12345', - 'status': 'success', - 'height': 90}], - 'adName': 'banner', - 'vastXml': '', - 'mediaType': 'banner', - 'tracking': 'https://ssp.toprtb.com/ssp/tracking?F0cloTiKIw%2BjZ2UNDvlKGn5%2FWoAO9cnlAUDm6gFBM8bImY2fKo%2BMTvI0XvXzFTZSb5v8o4EUbPId9hckptTqA4QPaWvpVYCRKRZceXNa4kjtvfm4j2e%2FcRKgkns2goHXi7IZC0sBIbE77WWg%2BPBYv%2BCu84H%2FSH69mi%2FDaWcQlfaEOdkaJdstJEkaZtkgWnFnS7aagte%2BfdEbOqcTxq5hzj%2BZ4NZbwgReuWTQZbfrMWjkXFbn%2B35vZuI319o6XH9n9fKLS4xp8zstXfQT2oSgjw1NmrwqRKf1efB1UaWlS1TbkSqxZ7Kcy7nJvAZrDk0tzcSeIxe4VfHpwgPPs%2BueUeGwz3o7OCh7H1sCmogSrmJFB9JTeXudFjC13iANAtu4SvG9bGIbiJxS%2BNfkjy2mLFm8kSIcIobjNkMEcUAwmoqJNRndwb66a3Iovk2NTo0Ly%2FV7Y5ECPcS5%2FPBrIEOuQXS5SNUPRWKoklX5nexHtOc%3D', - 'impression': 'https://ssp.toprtb.com/ssp/impression?id=64f29f7b226249f19925a680a506b32d' - }; - - let bids = spec.interpretResponse(serverResponse, bidRequestData); - expect(bids).to.have.lengthOf(1); - let bid = bids[0]; - expect(bid.cpm).to.equal(1); - expect(bid.currency).to.equal('USD'); - expect(bid.width).to.equal(728); - expect(bid.height).to.equal(90); - expect(bid.requestId).to.equal('bid12345'); - }); -}); diff --git a/test/spec/modules/tpmnBidAdapter_spec.js b/test/spec/modules/tpmnBidAdapter_spec.js deleted file mode 100644 index b4f6882dbe1..00000000000 --- a/test/spec/modules/tpmnBidAdapter_spec.js +++ /dev/null @@ -1,144 +0,0 @@ -/* eslint-disable no-tabs */ -import { expect } from 'chai'; -import { spec } from 'modules/tpmnBidAdapter.js'; - -describe('tpmnAdapterTests', function() { - describe('isBidRequestValid', function() { - let bid = { - adUnitCode: 'temp-unitcode', - bidder: 'tpmn', - params: { - inventoryId: '1', - publisherId: 'TPMN' - }, - bidId: '29092404798c9', - bidderRequestId: 'a01', - auctionId: 'da1d7a33-0260-4e83-a621-14674116f3f9', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - } - }; - it('should return true if a bid is valid banner bid request', function() { - expect(spec.isBidRequestValid(bid)).to.be.equal(true); - }); - - it('should return false where requried param is missing', function() { - let bid = Object.assign({}, bid); - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.be.equal(false); - }); - - it('should return false when required param values have invalid type', function() { - let bid = Object.assign({}, bid); - bid.params = { - 'inventoryId': null, - 'publisherId': null - }; - expect(spec.isBidRequestValid(bid)).to.be.equal(false); - }); - }); - - describe('buildRequests', function() { - it('should return an empty list if there are no bid requests', function() { - const emptyBidRequests = []; - const bidderRequest = {}; - const request = spec.buildRequests(emptyBidRequests, bidderRequest); - expect(request).to.be.an('array').that.is.empty; - }); - it('should generate a POST server request with bidder API url, data', function() { - const bid = { - adUnitCode: 'temp-unitcode', - bidder: 'tpmn', - params: { - inventoryId: '1', - publisherId: 'TPMN' - }, - bidId: '29092404798c9', - bidderRequestId: 'a01', - auctionId: 'da1d7a33-0260-4e83-a621-14674116f3f9', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - } - }; - const tempBidRequests = [bid]; - const tempBidderRequest = {refererInfo: { - referer: 'http://localhost/test', - site: { - domain: 'localhost', - page: 'http://localhost/test' - } - }}; - const builtRequest = spec.buildRequests(tempBidRequests, tempBidderRequest); - - expect(builtRequest).to.have.lengthOf(1); - expect(builtRequest[0].method).to.equal('POST'); - expect(builtRequest[0].url).to.match(/ad.tpmn.co.kr\/prebidhb.tpmn/); - const apiRequest = builtRequest[0].data; - expect(apiRequest.site).to.deep.equal({ - domain: 'localhost', - page: 'http://localhost/test' - }); - expect(apiRequest.bids).to.have.lengthOf('1'); - expect(apiRequest.bids[0].inventoryId).to.equal('1'); - expect(apiRequest.bids[0].publisherId).to.equal('TPMN'); - expect(apiRequest.bids[0].bidId).to.equal('29092404798c9'); - expect(apiRequest.bids[0].adUnitCode).to.equal('temp-unitcode'); - expect(apiRequest.bids[0].auctionId).to.equal('da1d7a33-0260-4e83-a621-14674116f3f9'); - expect(apiRequest.bids[0].sizes).to.have.lengthOf('1'); - expect(apiRequest.bids[0].sizes[0]).to.deep.equal({ - width: 300, - height: 250 - }); - }); - }); - - describe('interpretResponse', function() { - const bid = { - adUnitCode: 'temp-unitcode', - bidder: 'tpmn', - params: { - inventoryId: '1', - publisherId: 'TPMN' - }, - bidId: '29092404798c9', - bidderRequestId: 'a01', - auctionId: 'da1d7a33-0260-4e83-a621-14674116f3f9', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - } - }; - const tempBidRequests = [bid]; - - it('should return an empty aray to indicate no valid bids', function() { - const emptyServerResponse = {}; - const bidResponses = spec.interpretResponse(emptyServerResponse, tempBidRequests); - expect(bidResponses).is.an('array').that.is.empty; - }); - it('should return an empty array to indicate no valid bids', function() { - const mockBidResult = { - requestId: '9cf19229-34f6-4d06-bc1d-0e44e8d616c8', - cpm: 10.0, - creativeId: '1', - width: 300, - height: 250, - netRevenue: true, - currency: 'USD', - ttl: 1800, - ad: '', - adType: 'banner' - }; - const testServerResponse = { - headers: [], - body: [mockBidResult] - }; - const bidResponses = spec.interpretResponse(testServerResponse, tempBidRequests); - expect(bidResponses).deep.equal([mockBidResult]); - }); - }); -}); diff --git a/test/spec/modules/trendqubeBidAdapter_spec.js b/test/spec/modules/trendqubeBidAdapter_spec.js deleted file mode 100644 index f2ce95832ff..00000000000 --- a/test/spec/modules/trendqubeBidAdapter_spec.js +++ /dev/null @@ -1,270 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/trendqubeBidAdapter.js'; -import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; - -describe('TrendqubebBidAdapter', function () { - const bid = { - bidId: '23fhj33i987f', - bidder: 'trendqube', - params: { - placementId: 0, - traffic: BANNER - } - }; - - const bidderRequest = { - refererInfo: { - referer: 'test.com' - } - }; - - describe('isBidRequestValid', function () { - it('Should return true if there are bidId, params and placementId parameters present', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false if at least one of parameters is not present', function () { - delete bid.params.placementId; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function () { - let serverRequest = spec.buildRequests([bid], 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://ads.trendqube.com/?c=o&m=multi'); - }); - it('Returns valid data if array of bids is valid', function () { - let data = serverRequest.data; - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('deviceWidth', 'deviceHeight', 'language', 'secure', 'host', 'page', 'placements'); - 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.gdpr).to.not.exist; - expect(data.ccpa).to.not.exist; - let placement = data['placements'][0]; - expect(placement).to.have.keys('placementId', 'bidId', 'traffic', 'sizes', 'hPlayer', 'wPlayer', 'schain'); - expect(placement.placementId).to.equal(0); - expect(placement.bidId).to.equal('23fhj33i987f'); - expect(placement.traffic).to.equal(BANNER); - expect(placement.schain).to.be.an('object'); - }); - - it('Returns valid data for mediatype video', function () { - const playerSize = [300, 300]; - bid.mediaTypes = {}; - bid.params.traffic = VIDEO; - bid.mediaTypes[VIDEO] = { - playerSize - }; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data).to.be.an('object'); - let placement = data['placements'][0]; - expect(placement).to.be.an('object'); - expect(placement.traffic).to.equal(VIDEO); - expect(placement.wPlayer).to.equal(playerSize[0]); - expect(placement.hPlayer).to.equal(playerSize[1]); - }); - - it('Returns data with gdprConsent and without uspConsent', function () { - bidderRequest.gdprConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); - let data = serverRequest.data; - expect(data.gdpr).to.exist; - expect(data.gdpr).to.be.a('string'); - expect(data.gdpr).to.equal(bidderRequest.gdprConsent); - expect(data.ccpa).to.not.exist; - delete bidderRequest.gdprConsent; - }); - - it('Returns data with uspConsent and without gdprConsent', function () { - bidderRequest.uspConsent = 'test'; - serverRequest = spec.buildRequests([bid], bidderRequest); - let 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; - }); - - it('Returns empty data if no valid requests are passed', function () { - serverRequest = spec.buildRequests([]); - let data = serverRequest.data; - expect(data.placements).to.be.an('array').that.is.empty; - }); - }); - 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' - }] - }; - let bannerResponses = spec.interpretResponse(banner); - expect(bannerResponses).to.be.an('array').that.is.not.empty; - let dataItem = bannerResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - expect(dataItem.requestId).to.equal('23fhj33i987f'); - expect(dataItem.cpm).to.equal(0.4); - expect(dataItem.width).to.equal(300); - expect(dataItem.height).to.equal(250); - expect(dataItem.ad).to.equal('Test'); - expect(dataItem.ttl).to.equal(120); - expect(dataItem.creativeId).to.equal('2'); - expect(dataItem.netRevenue).to.be.true; - expect(dataItem.currency).to.equal('USD'); - }); - 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' - }] - }; - let videoResponses = spec.interpretResponse(video); - expect(videoResponses).to.be.an('array').that.is.not.empty; - - let dataItem = videoResponses[0]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'dealId', 'mediaType'); - 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'); - }); - 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', - }] - }; - let nativeResponses = spec.interpretResponse(native); - expect(nativeResponses).to.be.an('array').that.is.not.empty; - - let dataItem = nativeResponses[0]; - expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native'); - 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'); - }); - 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' - }] - }; - - let 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' - }] - }; - let 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', - }] - }; - let 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' - }] - }; - let serverResponses = spec.interpretResponse(invalid); - expect(serverResponses).to.be.an('array').that.is.empty; - }); - }); -}); diff --git a/test/spec/modules/tribeosBidAdapter_spec.js b/test/spec/modules/tribeosBidAdapter_spec.js deleted file mode 100644 index fd7f7087eb7..00000000000 --- a/test/spec/modules/tribeosBidAdapter_spec.js +++ /dev/null @@ -1,86 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/tribeosBidAdapter.js'; - -describe('tribeosBidAdapter', function() { - describe('isBidRequestValid', function() { - it('should return true if all parameters are passed', function() { - expect(spec.isBidRequestValid({ - bidder: 'tribeos', - params: { - placementId: '12345' - } - })).to.equal(true); - }); - - it('should return false is placementId is missing', function() { - expect(spec.isBidRequestValid({ - bidder: 'tribeos', - params: {} - })).to.equal(false); - }); - }); - - it('validate bid request data from backend', function() { - let bidRequestData = [{ - bidId: 'bid12', - bidder: 'tribeos', - mediaTypes: { - banner: { - sizes: [ - [300, 250] - ], - } - }, - params: { - placementId: 'test-bid' - } - }]; - - let request = spec.buildRequests(bidRequestData); - let payload = JSON.parse(request[0].data); - - expect(payload.bidId).to.equal('bid12'); - }); - - it('validate response parameters', function() { - let bidRequestData = { - data: { - bidId: '21f3e9c3ce92f2' - } - }; - - let serverResponse = { - body: { - 'id': '5e23a6c74314aa782328376f5954', - 'bidid': '5e23a6c74314aa782328376f5954', - 'seatbid': [{ - 'bid': [{ - 'id': '5e23a6c74314aa782328376f5954', - 'impid': '21f3e9c3ce92f2', - 'price': 1.1, - 'adid': '5e23a6c74314aa782328376f5954', - 'adm': '', - 'cid': '5e1eea895d37673aef2134825195rnd2', - 'crid': '5e0b71e6823bb66fcb6c9858', - 'h': 250, - 'w': 300 - }], - 'seats': '1' - }], - 'cur': 'USD' - } - }; - - let bids = spec.interpretResponse(serverResponse, bidRequestData); - expect(bids).to.have.lengthOf(1); - let bid = bids[0]; - - expect(bid.cpm).to.equal(1.1); - expect(bid.currency).to.equal('USD'); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.netRevenue).to.equal(true); - expect(bid.requestId).to.equal('21f3e9c3ce92f2'); - expect(bid.ad).to.equal(''); - }); -}); diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js deleted file mode 100644 index ae329b4a028..00000000000 --- a/test/spec/modules/trionBidAdapter_spec.js +++ /dev/null @@ -1,391 +0,0 @@ -import {expect} from 'chai'; -import * as utils from 'src/utils.js'; -import {spec, acceptPostMessage, getStorageData, setStorageData} from 'modules/trionBidAdapter.js'; - -const CONSTANTS = require('src/constants.json'); -const adloader = require('src/adloader'); - -const PLACEMENT_CODE = 'ad-tag'; -const BID_REQUEST_BASE_URL = 'https://in-appadvertising.com/api/bidRequest'; - -const TRION_BID = { - bidder: 'trion', - params: { - pubId: '1', - sectionId: '2' - }, - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - }, - adUnitCode: 'adunit-code', - sizes: [[300, 250], [300, 600]], - bidId: 'test-bid-id', - bidRequest: 'test-bid-request' -}; - -const TRION_BID_REQUEST = [TRION_BID]; - -const TRION_BIDDER_REQUEST = { - 'bidderCode': 'trion', - 'auctionId': '12345', - 'bidderRequestId': 'abc1234', - 'bids': TRION_BID_REQUEST -}; - -const TRION_BID_RESPONSE = { - bidId: 'test-bid-id', - sizes: [[300, 250], [300, 600]], - result: { - cpm: 100, - placeBid: true, - height: '250', - width: '300', - ad: 'test', - msg: 'response messaging' - } - -}; - -const getPublisherUrl = function () { - var url = null; - try { - if (window.top == window) { - url = window.location.href; - } else { - try { - url = window.top.location.href; - } catch (e) { - url = document.referrer; - } - } - } catch (e) { - } - return url -}; - -describe('Trion adapter tests', function () { - let adapter; - - beforeEach(function () { - // adapter = trionAdapter.createNew(); - sinon.stub(document.body, 'appendChild'); - }); - - afterEach(function () { - document.body.appendChild.restore(); - }); - - describe('isBidRequestValid', function () { - it('should return true with correct params', function () { - expect(spec.isBidRequestValid(TRION_BID)).to.equal(true); - }); - - it('should return false when params are missing', function () { - TRION_BID.params = {}; - - expect(spec.isBidRequestValid(TRION_BID)).to.equal(false); - TRION_BID.params = { - pubId: '1', - sectionId: '2' - }; - }); - - it('should return false when pubId is missing', function () { - TRION_BID.params = { - sectionId: '2' - }; - - expect(spec.isBidRequestValid(TRION_BID)).to.equal(false); - TRION_BID.params = { - pubId: '1', - sectionId: '2' - }; - }); - - it('should return false when sectionId is missing', function () { - TRION_BID.params = { - pubId: '1' - }; - - expect(spec.isBidRequestValid(TRION_BID)).to.equal(false); - TRION_BID.params = { - pubId: '1', - sectionId: '2' - }; - }); - }); - - describe('buildRequests', function () { - it('should return bids requests with empty params', function () { - let bidRequests = spec.buildRequests([]); - expect(bidRequests.length).to.equal(0); - }); - - it('should include the base bidrequest url', function () { - let bidRequests = spec.buildRequests(TRION_BID_REQUEST); - - let bidUrl = bidRequests[0].url; - expect(bidUrl).to.include(BID_REQUEST_BASE_URL); - }); - - it('should call buildRequests with the correct required params', function () { - let bidRequests = spec.buildRequests(TRION_BID_REQUEST); - - let bidUrlParams = bidRequests[0].data; - expect(bidUrlParams).to.include('pubId=1'); - expect(bidUrlParams).to.include('sectionId=2'); - expect(bidUrlParams).to.include('sizes=300x250,300x600'); - expect(bidUrlParams).to.include('vers=$prebid.version$'); - }); - - it('should call buildRequests with the correct optional params', function () { - let bidRequests = spec.buildRequests(TRION_BID_REQUEST); - let bidUrlParams = bidRequests[0].data; - expect(bidUrlParams).to.include(getPublisherUrl()); - }); - - // describe('webdriver', function () { - // let originalWD; - - // beforeEach(function () { - // originalWD = window.navigator.webdriver; - // }); - - // afterEach(function () { - // window.navigator['__defineGetter__']('webdriver', function () { - // return originalWD; - // }); - // }); - - // describe('is present', function () { - // beforeEach(function () { - // window.navigator['__defineGetter__']('webdriver', function () { - // return 1; - // }); - // }); - - // it('when there is non human traffic', function () { - // let bidRequests = spec.buildRequests(TRION_BID_REQUEST); - // let bidUrlParams = bidRequests[0].data; - // expect(bidUrlParams).to.include('tr_wd=1'); - // }); - // }); - - // describe('is not present', function () { - // beforeEach(function () { - // window.navigator['__defineGetter__']('webdriver', function () { - // return 0; - // }); - // }); - - // it('when there is not non human traffic', function () { - // let bidRequests = spec.buildRequests(TRION_BID_REQUEST); - // let bidUrlParams = bidRequests[0].data; - // expect(bidUrlParams).to.include('tr_wd=0'); - // }); - // }); - // }); - - describe('document', function () { - let originalHD; - let originalVS; - - beforeEach(function () { - originalHD = document.hidden; - originalVS = document.visibilityState; - }); - - afterEach(function () { - document['__defineGetter__']('hidden', function () { - return originalHD; - }); - document['__defineGetter__']('visibilityState', function () { - return originalVS; - }); - }); - - describe('is visible', function () { - beforeEach(function () { - document['__defineGetter__']('hidden', function () { - return 1; - }); - document['__defineGetter__']('visibilityState', function () { - return 'visible'; - }); - }); - - it('should detect and send the document is visible', function () { - let bidRequests = spec.buildRequests(TRION_BID_REQUEST); - let bidUrlParams = bidRequests[0].data; - expect(bidUrlParams).to.include('tr_hd=1'); - expect(bidUrlParams).to.include('tr_vs=visible'); - }); - }); - - describe('is hidden', function () { - beforeEach(function () { - document['__defineGetter__']('hidden', function () { - return 1; - }); - document['__defineGetter__']('visibilityState', function () { - return 'hidden'; - }); - }); - - it('should detect and send the document is hidden', function () { - let bidRequests = spec.buildRequests(TRION_BID_REQUEST); - let bidUrlParams = bidRequests[0].data; - expect(bidUrlParams).to.include('tr_hd=1'); - expect(bidUrlParams).to.include('tr_vs=hidden'); - }); - }); - }); - - describe('should call buildRequests with correct consent params', function () { - it('when gdpr is present', function () { - TRION_BIDDER_REQUEST.gdprConsent = { - consentString: 'test_gdpr_str', - gdprApplies: true - }; - let bidRequests = spec.buildRequests(TRION_BID_REQUEST, TRION_BIDDER_REQUEST); - let bidUrlParams = bidRequests[0].data; - let gcEncoded = encodeURIComponent(TRION_BIDDER_REQUEST.gdprConsent.consentString); - expect(bidUrlParams).to.include('gdprc=' + gcEncoded); - expect(bidUrlParams).to.include('gdpr=1'); - delete TRION_BIDDER_REQUEST.gdprConsent; - }); - - it('when us privacy is present', function () { - TRION_BIDDER_REQUEST.uspConsent = '1YYY'; - let bidRequests = spec.buildRequests(TRION_BID_REQUEST, TRION_BIDDER_REQUEST); - let bidUrlParams = bidRequests[0].data; - let uspEncoded = encodeURIComponent(TRION_BIDDER_REQUEST.uspConsent); - expect(bidUrlParams).to.include('usp=' + uspEncoded); - delete TRION_BIDDER_REQUEST.uspConsent; - }); - }); - }); - - describe('interpretResponse', function () { - it('when there is no response do not bid', function () { - let 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; - let response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); - - expect(response).to.deep.equal([]); - - TRION_BID_RESPONSE.result.placeBid = true; - }); - - it('when no cpm is in the response', function () { - TRION_BID_RESPONSE.result.cpm = 0; - let 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; - let response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); - expect(response).to.deep.equal([]); - TRION_BID_RESPONSE.result.ad = 'test'; - }); - - it('height and width are appropriately set', function () { - let bidWidth = '1'; - let bidHeight = '2'; - TRION_BID_RESPONSE.result.width = bidWidth; - TRION_BID_RESPONSE.result.height = bidHeight; - let 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'; - TRION_BID_RESPONSE.result.height = '250'; - }); - - it('cpm is properly set and transformed to cents', function () { - let bidCpm = 2; - TRION_BID_RESPONSE.result.cpm = bidCpm * 100; - let response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); - expect(response[0].cpm).to.equal(bidCpm); - TRION_BID_RESPONSE.result.cpm = 100; - }); - }); - - describe('getUserSyncs', function () { - const USER_SYNC_URL = 'https://in-appadvertising.com/api/userSync.html'; - const BASE_KEY = '_trion_'; - - beforeEach(function () { - delete window.TR_INT_T; - }); - - it('trion int is included in bid url', function () { - window.TR_INT_T = 'test_user_sync'; - let userTag = encodeURIComponent(window.TR_INT_T); - let bidRequests = spec.buildRequests(TRION_BID_REQUEST); - let bidUrlParams = bidRequests[0].data; - - expect(bidUrlParams).to.include(userTag); - }); - - it('should register trion user script', function () { - let syncs = spec.getUserSyncs({iframeEnabled: true}); - let pageUrl = getPublisherUrl(); - let pubId = 1; - let sectionId = 2; - let syncString = `?p=${pubId}&s=${sectionId}&u=${pageUrl}`; - expect(syncs[0]).to.deep.equal({type: 'iframe', url: USER_SYNC_URL + syncString}); - }); - - it('should register trion user script with gdpr params', function () { - let gdprConsent = { - consentString: 'test_gdpr_str', - gdprApplies: true - }; - let syncs = spec.getUserSyncs({iframeEnabled: true}, null, gdprConsent); - let pageUrl = getPublisherUrl(); - let pubId = 1; - let sectionId = 2; - let gcEncoded = encodeURIComponent(gdprConsent.consentString); - let syncString = `?p=${pubId}&s=${sectionId}&gc=${gcEncoded}&g=1&u=${pageUrl}`; - expect(syncs[0]).to.deep.equal({type: 'iframe', url: USER_SYNC_URL + syncString}); - }); - - it('should register trion user script with us privacy params', function () { - let uspConsent = '1YYY'; - let syncs = spec.getUserSyncs({iframeEnabled: true}, null, null, uspConsent); - let pageUrl = getPublisherUrl(); - let pubId = 1; - let sectionId = 2; - let uspEncoded = encodeURIComponent(uspConsent); - let syncString = `?p=${pubId}&s=${sectionId}&up=${uspEncoded}&u=${pageUrl}`; - expect(syncs[0]).to.deep.equal({type: 'iframe', url: USER_SYNC_URL + syncString}); - }); - - it('should except posted messages from user sync script', function () { - let testId = 'testId'; - let message = BASE_KEY + 'userId=' + testId; - setStorageData(BASE_KEY + 'int_t', null); - acceptPostMessage({data: message}); - let newKey = getStorageData(BASE_KEY + 'int_t'); - expect(newKey).to.equal(testId); - }); - - it('should not try to post messages not from trion', function () { - let testId = 'testId'; - let badId = 'badId'; - let message = 'Not Trion: userId=' + testId; - setStorageData(BASE_KEY + 'int_t', badId); - acceptPostMessage({data: message}); - let 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 deleted file mode 100644 index 30377ec0a5d..00000000000 --- a/test/spec/modules/tripleliftBidAdapter_spec.js +++ /dev/null @@ -1,877 +0,0 @@ -import { expect } from 'chai'; -import { tripleliftAdapterSpec } from 'modules/tripleliftBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import { deepClone } from 'src/utils.js'; -import { config } from 'src/config.js'; -import prebid from '../../../package.json'; -import * as utils from 'src/utils.js'; - -const ENDPOINT = 'https://tlx.3lift.com/header/auction?'; -const GDPR_CONSENT_STR = 'BOONm0NOONm0NABABAENAa-AAAARh7______b9_3__7_9uz_Kv_K7Vf7nnG072lPVA9LTOQ6gEaY'; - -describe('triplelift adapter', function () { - const adapter = newBidder(tripleliftAdapterSpec); - let bid, instreamBid; - let sandbox; - - this.beforeEach(() => { - bid = { - bidder: 'triplelift', - params: { - inventoryCode: '12345', - floor: 1.0, - }, - mediaTypes: { - banner: { - sizes: [ - [970, 250], - [1, 1] - ] - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - - instreamBid = { - bidder: 'triplelift', - params: { - inventoryCode: 'insteam_test', - floor: 1.0, - video: { - mimes: ['video/mp4'], - maxduration: 30, - minduration: 6, - w: 640, - h: 480 - } - }, - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480] - } - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }; - }) - - describe('inherited functions', function () { - it('exists and is a function', function () { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - it('should return true for valid bid request', function () { - expect(tripleliftAdapterSpec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return true when required params found', function () { - bid.params.inventoryCode = 'another_inv_code'; - expect(tripleliftAdapterSpec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return true when required params found - instream', function () { - expect(tripleliftAdapterSpec.isBidRequestValid(instreamBid)).to.equal(true); - }); - - it('should return true when required params found - instream - 2', function () { - delete instreamBid.mediaTypes.playerSize; - delete instreamBid.params.video.w; - delete instreamBid.params.video.h; - // the only required param is inventoryCode - expect(tripleliftAdapterSpec.isBidRequestValid(instreamBid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - delete bid.params.inventoryCode; - expect(tripleliftAdapterSpec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when required params are not passed - instream', function () { - delete instreamBid.params.inventoryCode; - expect(tripleliftAdapterSpec.isBidRequestValid(instreamBid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests; - let bidderRequest; - const schain = { - validation: 'strict', - config: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - hp: 1, - } - ] - } - }; - - this.beforeEach(() => { - bidRequests = [ - { - bidder: 'triplelift', - params: { - inventoryCode: '12345', - floor: 1.0, - }, - mediaTypes: { - banner: { - sizes: [ - [970, 250], - [1, 1] - ] - } - }, - adUnitCode: 'adunit-code', - sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - userId: {}, - schain, - ortb2Imp: { - ext: { - data: { - pbAdSlot: 'homepage-top-rect', - adUnitSpecificAttribute: 123 - } - } - } - }, - { - bidder: 'triplelift', - params: { - inventoryCode: 'insteam_test', - floor: 1.0, - video: { - mimes: ['video/mp4'], - maxduration: 30, - minduration: 6, - w: 640, - h: 480 - } - }, - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480] - } - }, - adUnitCode: 'adunit-code-instream', - sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - userId: {}, - schain, - }, - // banner and outstream video - { - bidder: 'triplelift', - params: { - inventoryCode: 'outstream_test', - floor: 1.0, - video: { - mimes: ['video/mp4'], - maxduration: 30, - minduration: 6, - w: 640, - h: 480 - } - }, - mediaTypes: { - video: { - context: 'outstream', - playerSize: [640, 480] - }, - banner: { - sizes: [ - [970, 250], - [1, 1] - ] - } - }, - adUnitCode: 'adunit-code-instream', - sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - userId: {}, - schain, - }, - // banner and incomplete video - { - bidder: 'triplelift', - params: { - inventoryCode: 'outstream_test', - floor: 1.0, - video: { - mimes: ['video/mp4'], - maxduration: 30, - minduration: 6, - w: 640, - h: 480 - } - }, - mediaTypes: { - video: { - - }, - banner: { - sizes: [ - [970, 250], - [1, 1] - ] - } - }, - adUnitCode: 'adunit-code-instream', - sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - userId: {}, - schain, - }, - // incomplete banner and incomplete video - { - bidder: 'triplelift', - params: { - inventoryCode: 'outstream_test', - floor: 1.0, - video: { - mimes: ['video/mp4'], - maxduration: 30, - minduration: 6, - w: 640, - h: 480 - } - }, - mediaTypes: { - video: { - - }, - banner: { - - } - }, - adUnitCode: 'adunit-code-instream', - sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - userId: {}, - schain, - }, - // banner and instream video - { - bidder: 'triplelift', - params: { - inventoryCode: 'outstream_test', - floor: 1.0, - video: { - mimes: ['video/mp4'], - maxduration: 30, - minduration: 6, - w: 640, - h: 480 - } - }, - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480] - }, - banner: { - sizes: [ - [970, 250], - [1, 1] - ] - } - }, - adUnitCode: 'adunit-code-instream', - sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - userId: {}, - schain, - }, - // banner and outream video and native - { - bidder: 'triplelift', - params: { - inventoryCode: 'outstream_test', - floor: 1.0, - video: { - mimes: ['video/mp4'], - maxduration: 30, - minduration: 6, - w: 640, - h: 480 - } - }, - mediaTypes: { - video: { - context: 'outstream', - playerSize: [640, 480] - }, - banner: { - sizes: [ - [970, 250], - [1, 1] - ] - }, - native: { - - } - }, - adUnitCode: 'adunit-code-instream', - sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']], - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - userId: {}, - schain, - } - ]; - - bidderRequest = { - bidderCode: 'triplelift', - auctionId: 'a7ebcd1d-66ff-4b5c-a82c-6a21a6ee5a18', - bidderRequestId: '5c55612f99bc11', - bids: [ - { - imp_id: 0, - cpm: 1.062, - width: 300, - height: 250, - ad: 'ad-markup', - iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg' - }, - { - imp_id: 1, - crid: '10092_76480_i2j6qm8u', - cpm: 0.01, - ad: 'The Trade Desk', - tlx_source: 'hdx' - } - ], - refererInfo: { - referer: 'https://examplereferer.com' - }, - gdprConsent: { - consentString: GDPR_CONSENT_STR, - gdprApplies: true - }, - }; - sandbox = sinon.sandbox.create(); - }); - afterEach(() => { - sandbox.restore(); - }); - - it('exists and is an object', function () { - const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); - expect(request).to.exist.and.to.be.a('object'); - }); - - it('should be able find video object from the instream request', function () { - const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); - expect(request.data.imp[1].video).to.exist.and.to.be.a('object'); - }); - - 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}]); - }); - - it('should be a post request and populate the payload', function () { - const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); - const payload = request.data; - 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[1].tagid).to.equal('insteam_test'); - expect(payload.imp[1].floor).to.equal(1.0); - expect(payload.imp[1].video).to.exist.and.to.be.a('object'); - // banner and outstream video - expect(payload.imp[2]).to.not.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}]); - // 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}]); - // 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}]); - // banner and instream video - expect(payload.imp[5]).to.not.have.property('banner'); - expect(payload.imp[5]).to.have.property('video'); - expect(payload.imp[5].video).to.exist.and.to.be.a('object'); - // banner and outream video and native - expect(payload.imp[6]).to.not.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}]); - }); - - it('should add tdid to the payload if included', function () { - const id = '6bca7f6b-a98a-46c0-be05-6020f7604598'; - bidRequests[0].userId.tdid = id; - 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, ext: {rtiPartner: 'TDID'}}]}]}}); - }); - - it('should add idl_env to the payload if included', function () { - const id = 'XY6104gr0njcH9UDIR7ysFFJcm2XNpqeJTYslleJ_cMlsFOfZI'; - bidRequests[0].userId.idl_env = id; - const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); - const payload = request.data; - expect(payload).to.exist; - expect(payload.user).to.deep.equal({ext: {eids: [{source: 'liveramp.com', uids: [{id, ext: {rtiPartner: 'idl'}}]}]}}); - }); - - it('should add criteoId to the payload if included', function () { - const id = '53e30ea700424f7bbdd793b02abc5d7'; - bidRequests[0].userId.criteoId = id; - 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, ext: {rtiPartner: 'criteoId'}}]}]}}); - }); - - it('should add tdid, idl_env and criteoId to the payload if both are included', function () { - const tdidId = '6bca7f6b-a98a-46c0-be05-6020f7604598'; - const idlEnvId = 'XY6104gr0njcH9UDIR7ysFFJcm2XNpqeJTYslleJ_cMlsFOfZI'; - const criteoId = '53e30ea700424f7bbdd793b02abc5d7'; - bidRequests[0].userId.tdid = tdidId; - bidRequests[0].userId.idl_env = idlEnvId; - bidRequests[0].userId.criteoId = criteoId; - - 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: tdidId, - ext: { rtiPartner: 'TDID' } - } - ], - }, - { - source: 'liveramp.com', - uids: [ - { - id: idlEnvId, - ext: { rtiPartner: 'idl' } - } - ] - }, - { - source: 'criteo.com', - uids: [ - { - id: criteoId, - ext: { rtiPartner: 'criteoId' } - } - ] - } - ] - } - }); - }); - - it('should consolidate user ids from multiple bid requests', function () { - const tdidId = '6bca7f6b-a98a-46c0-be05-6020f7604598'; - const idlEnvId = 'XY6104gr0njcH9UDIR7ysFFJcm2XNpqeJTYslleJ_cMlsFOfZI'; - const criteoId = '53e30ea700424f7bbdd793b02abc5d7'; - const pubcid = '3261d8ad-435d-481d-abd1-9f1a9ec99f0e'; - - const bidRequestsMultiple = [ - { ...bidRequests[0], userId: { tdid: tdidId, idl_env: idlEnvId, criteoId, pubcid } }, - { ...bidRequests[0], userId: { tdid: tdidId, idl_env: idlEnvId, criteoId, pubcid } }, - { ...bidRequests[0], userId: { tdid: tdidId, idl_env: idlEnvId, criteoId, pubcid } } - ]; - - const request = tripleliftAdapterSpec.buildRequests(bidRequestsMultiple, bidderRequest); - const payload = request.data; - - expect(payload.user).to.deep.equal({ - ext: { - eids: [ - { - source: 'adserver.org', - uids: [ - { - id: tdidId, - ext: { rtiPartner: 'TDID' } - } - ], - }, - { - source: 'liveramp.com', - uids: [ - { - id: idlEnvId, - ext: { rtiPartner: 'idl' } - } - ] - }, - { - source: 'criteo.com', - uids: [ - { - id: criteoId, - ext: { rtiPartner: 'criteoId' } - } - ] - }, - { - source: 'pubcid.org', - uids: [ - { - id: '3261d8ad-435d-481d-abd1-9f1a9ec99f0e', - ext: { rtiPartner: 'pubcid' } - } - ] - } - ] - } - }); - - expect(payload.user.ext.eids).to.be.an('array'); - expect(payload.user.ext.eids).to.have.lengthOf(4); - }); - - it('should return a query string for TL call', function () { - const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); - const url = request.url; - expect(url).to.exist; - expect(url).to.be.a('string'); - expect(url).to.match(/(?:tlx.3lift.com\/header\/auction)/) - expect(url).to.match(/(?:lib=prebid)/) - expect(url).to.match(new RegExp('(?:' + prebid.version + ')')) - expect(url).to.match(/(?:referrer)/); - }); - it('should return us_privacy param when CCPA info is available', function() { - bidderRequest.uspConsent = '1YYY'; - const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); - const url = request.url; - expect(url).to.match(/(\?|&)us_privacy=1YYY/); - }); - it('should return coppa param when COPPA config is set to true', function() { - sinon.stub(config, 'getConfig').withArgs('coppa').returns(true); - const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); - config.getConfig.restore(); - const url = request.url; - expect(url).to.match(/(\?|&)coppa=true/); - }); - it('should not return coppa param when COPPA config is set to false', function() { - sinon.stub(config, 'getConfig').withArgs('coppa').returns(false); - const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); - config.getConfig.restore(); - const url = request.url; - expect(url).not.to.match(/(\?|&)coppa=/); - }); - it('should return schain when present', function() { - const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); - const { data: payload } = request; - expect(payload.ext.schain).to.deep.equal(schain); - }); - it('should not create root level ext when schain is not present', function() { - bidRequests[0].schain = undefined; - const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); - const { data: payload } = request; - expect(payload.ext).to.deep.equal(undefined); - }); - it('should get floor from floors module if available', function() { - let floorInfo; - bidRequests[0].getFloor = () => floorInfo; - - // standard float response; expected functionality of floors module - floorInfo = { currency: 'USD', floor: 1.99 }; - let request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); - expect(request.data.imp[0].floor).to.equal(1.99); - - // if string response, convert to float - floorInfo = { currency: 'USD', floor: '1.99' }; - request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); - expect(request.data.imp[0].floor).to.equal(1.99); - }); - it('should call getFloor with the correct parameters based on mediaType', function() { - bidRequests.forEach(request => { - request.getFloor = () => {}; - sinon.spy(request, 'getFloor') - }); - - tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); - - // banner - expect(bidRequests[0].getFloor.calledWith({ - currency: 'USD', - mediaType: 'banner', - size: '*' - })).to.be.true; - - // instream - expect(bidRequests[1].getFloor.calledWith({ - currency: 'USD', - mediaType: 'video', - size: '*' - })).to.be.true; - - // banner and incomplete video (POST will only include banner) - expect(bidRequests[3].getFloor.calledWith({ - currency: 'USD', - mediaType: 'banner', - size: '*' - })).to.be.true; - - // banner and instream (POST will only include video) - expect(bidRequests[5].getFloor.calledWith({ - currency: 'USD', - mediaType: 'video', - size: '*' - })).to.be.true; - }); - it('should send global config fpd if kvps are available', function() { - const sens = null; - const category = ['news', 'weather', 'hurricane']; - const pmp_elig = 'true'; - const ortb2 = { - site: { - pmp_elig: pmp_elig, - ext: { - data: { - category: category - } - } - }, - user: { - sens: sens, - } - } - sandbox.stub(config, 'getConfig').callsFake(key => { - const config = { - ortb2 - }; - return utils.deepAccess(config, key); - }); - const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); - const { data: payload } = request; - expect(payload.ext.fpd.user).to.not.exist; - expect(payload.ext.fpd.context.data).to.haveOwnProperty('category'); - expect(payload.ext.fpd.context).to.haveOwnProperty('pmp_elig'); - }); - it('should send ad unit fpd if kvps are available', function() { - const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); - expect(request.data.imp[0].fpd.context).to.haveOwnProperty('data'); - expect(request.data.imp[0].fpd.context.data).to.haveOwnProperty('pbAdSlot'); - expect(request.data.imp[0].fpd.context.data).to.haveOwnProperty('adUnitSpecificAttribute'); - expect(request.data.imp[1].fpd).to.not.exist; - }); - }); - - describe('interpretResponse', function () { - let response, bidderRequest; - this.beforeEach(() => { - response = { - body: { - bids: [ - { - imp_id: 0, - cpm: 1.062, - width: 300, - height: 250, - ad: 'ad-markup', - iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg', - tl_source: 'tlx', - advertiser_name: 'fake advertiser name', - adomain: ['basspro.com', 'internetalerts.org'] - }, - { - imp_id: 1, - crid: '10092_76480_i2j6qm8u', - cpm: 9.99, - ad: 'The Trade Desk', - tlx_source: 'hdx' - } - ] - } - }; - bidderRequest = { - bidderCode: 'triplelift', - auctionId: 'a7ebcd1d-66ff-4b5c-a82c-6a21a6ee5a18', - bidderRequestId: '5c55612f99bc11', - bids: [ - { - imp_id: 0, - cpm: 1.062, - width: 300, - height: 250, - ad: 'ad-markup', - iurl: 'https://s.adroll.com/a/IYR/N36/IYRN366MFVDITBAGNNT5U6.jpg', - tl_source: 'tlx', - mediaTypes: { - banner: { - sizes: [ - [970, 250], - [1, 1] - ] - } - }, - bidId: '30b31c1838de1e', - }, - { - imp_id: 1, - crid: '10092_76480_i2j6qm8u', - cpm: 9.99, - ad: 'The Trade Desk', - tlx_source: 'hdx', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480] - } - }, - bidId: '30b31c1838de1e', - } - ], - refererInfo: { - referer: 'https://examplereferer.com' - }, - gdprConsent: { - consentString: GDPR_CONSENT_STR, - gdprApplies: true - } - }; - }) - - it('should get correct bid response', function () { - let expectedResponse = [ - { - requestId: '30b31c1838de1e', - cpm: 1.062, - width: 300, - height: 250, - netRevenue: true, - ad: 'ad-markup', - creativeId: 29681110, - dealId: '', - currency: 'USD', - ttl: 33, - tl_source: 'tlx', - meta: {} - }, - { - requestId: '30b31c1838de1e', - cpm: 1.062, - width: 300, - height: 250, - netRevenue: true, - ad: 'The Trade Desk', - creativeId: 29681110, - dealId: '', - currency: 'USD', - ttl: 33, - tl_source: 'hdx', - mediaType: 'video', - vastXml: 'The Trade Desk', - meta: {} - } - ]; - let result = tripleliftAdapterSpec.interpretResponse(response, {bidderRequest}); - expect(result).to.have.length(2); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - expect(Object.keys(result[1])).to.have.members(Object.keys(expectedResponse[1])); - }); - - it('should return multiple responses to support SRA', function () { - let result = tripleliftAdapterSpec.interpretResponse(response, {bidderRequest}); - expect(result).to.have.length(2); - }); - - it('should include the advertiser name in the meta field if available', function () { - let 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 () { - let 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'); - }); - }); - - describe('getUserSyncs', function() { - let expectedIframeSyncUrl = 'https://eb2.3lift.com/sync?gdpr=true&cmp_cs=' + GDPR_CONSENT_STR + '&'; - let expectedImageSyncUrl = 'https://eb2.3lift.com/sync?px=1&src=prebid&gdpr=true&cmp_cs=' + GDPR_CONSENT_STR + '&'; - - it('returns undefined when syncing is not enabled', function() { - expect(tripleliftAdapterSpec.getUserSyncs({})).to.equal(undefined); - expect(tripleliftAdapterSpec.getUserSyncs()).to.equal(undefined); - }); - - it('returns iframe user sync pixel when iframe syncing is enabled', function() { - let syncOptions = { - iframeEnabled: true - }; - let result = tripleliftAdapterSpec.getUserSyncs(syncOptions); - expect(result[0].type).to.equal('iframe'); - expect(result[0].url).to.equal(expectedIframeSyncUrl); - }); - - it('returns image user sync pixel when iframe syncing is disabled', function() { - let syncOptions = { - pixelEnabled: true - }; - let result = tripleliftAdapterSpec.getUserSyncs(syncOptions); - expect(result[0].type).to.equal('image') - expect(result[0].url).to.equal(expectedImageSyncUrl); - }); - - it('returns iframe user sync pixel when both options are enabled', function() { - let syncOptions = { - pixelEnabled: true, - iframeEnabled: true - }; - let result = tripleliftAdapterSpec.getUserSyncs(syncOptions); - expect(result[0].type).to.equal('iframe'); - expect(result[0].url).to.equal(expectedIframeSyncUrl); - }); - it('sends us_privacy param when info is available', function() { - let syncOptions = { - iframeEnabled: true - }; - let result = tripleliftAdapterSpec.getUserSyncs(syncOptions, null, null, '1YYY'); - expect(result[0].url).to.match(/(\?|&)us_privacy=1YYY/); - }); - }); -}); diff --git a/test/spec/modules/truereachBidAdapter_spec.js b/test/spec/modules/truereachBidAdapter_spec.js deleted file mode 100644 index 36441722648..00000000000 --- a/test/spec/modules/truereachBidAdapter_spec.js +++ /dev/null @@ -1,105 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/truereachBidAdapter.js'; - -describe('truereachBidAdapterTests', function () { - it('validate_pub_params', function () { - expect(spec.isBidRequestValid({ - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bidder: 'truereach', - params: { - site_id: '0142010a-8400-1b01-72cb-a553b9000009', - bidfloor: 0.1 - } - })).to.equal(true); - }); - - it('validate_generated_params', function () { - let bidRequestData = [{ - bidId: '34ce3f3b15190a', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bidder: 'truereach', - params: { - site_id: '0142010a-8400-1b01-72cb-a553b9000009', - bidfloor: 0.1 - }, - sizes: [[300, 250]] - }]; - - let request = spec.buildRequests(bidRequestData, {}); - let req_data = request.data; - - expect(request.method).to.equal('POST'); - expect(req_data.imp[0].id).to.equal('34ce3f3b15190a'); - expect(req_data.imp[0].banner.w).to.equal(300); - expect(req_data.imp[0].banner.h).to.equal(250); - expect(req_data.imp[0].bidfloor).to.equal(0.1); - }); - - it('validate_response_params', function () { - let serverResponse = { - body: { - 'id': '34ce3f3b15190a', - 'seatbid': [{ - 'bid': [{ - 'id': '0142010a-8400-0801-72dc-04a99e6f7fc0:1ed', - 'impid': '34ce3f3b15190a', - 'price': 2.55, - 'adm': '', - 'adid': '493', - 'adomain': ['https://www.momagic.com/'], - 'iurl': '', - 'cid': '260', - 'crid': '0142010a-8400-1b01-72cb-afb296000012', - 'w': 300, - 'h': 250 - }] - }], - 'bidid': '0142010a-8400-0801-72dc-04a99e6f7fc1', - 'cur': 'USD' - } - }; - - let bids = spec.interpretResponse(serverResponse, {}); - expect(bids).to.have.lengthOf(1); - let bid = bids[0]; - expect(bid.requestId).to.equal('34ce3f3b15190a'); - expect(bid.cpm).to.equal(2.55); - expect(bid.currency).to.equal('USD'); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.ad).to.equal(''); - expect(bid.ttl).to.equal(180); - expect(bid.creativeId).to.equal('0142010a-8400-1b01-72cb-afb296000012'); - expect(bid.netRevenue).to.equal(false); - expect(bid.meta.advertiserDomains[0]).to.equal('https://www.momagic.com/'); - }); - - describe('user_sync', function() { - const user_sync_url = 'http://ads.momagic.com/jsp/usersync.jsp'; - it('register_iframe_pixel_if_iframeEnabled_is_true', function() { - let syncs = spec.getUserSyncs( - {iframeEnabled: true} - ); - expect(syncs).to.be.an('array'); - expect(syncs.length).to.equal(1); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.equal(user_sync_url); - }); - - it('if_pixelEnabled_is_true', function() { - let syncs = spec.getUserSyncs( - {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 deleted file mode 100644 index c0155f87ab6..00000000000 --- a/test/spec/modules/trustxBidAdapter_spec.js +++ /dev/null @@ -1,1225 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/trustxBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import { config } from 'src/config.js'; - -describe('TrustXAdapter', 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 () { - let bid = { - 'bidder': 'trustx', - 'params': { - 'uid': '44' - }, - '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(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'uid': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - function parseRequest(url) { - const res = {}; - url.split('&').forEach((it) => { - const couple = it.split('='); - res[couple[0]] = decodeURIComponent(couple[1]); - }); - return res; - } - - const bidderRequest = { - refererInfo: { - referer: 'https://example.com' - } - }; - const referrer = bidderRequest.refererInfo.referer; - - let bidRequests = [ - { - 'bidder': 'trustx', - 'params': { - 'uid': '43' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '43' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90], [300, 250]], - 'bidId': '3150ccb55da321', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '45' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '42dbe3a7168a6a', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - it('should attach valid params to the tag', function () { - const request = spec.buildRequests([bidRequests[0]], bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'net'); - expect(payload).to.have.property('auids', '43'); - expect(payload).to.have.property('sizes', '300x250,300x600'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - expect(payload).to.have.property('wrapperType', 'Prebid_js'); - expect(payload).to.have.property('wrapperVersion', '$prebid.version$'); - }); - - it('sizes must not be duplicated', function () { - const request = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'net'); - expect(payload).to.have.property('auids', '43,43,45'); - expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - }); - - it('pt parameter must be "gross" if params.priceType === "gross"', function () { - bidRequests[1].params.priceType = 'gross'; - const request = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'gross'); - expect(payload).to.have.property('auids', '43,43,45'); - expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - delete bidRequests[1].params.priceType; - }); - - it('pt parameter must be "net" or "gross"', function () { - bidRequests[1].params.priceType = 'some'; - const request = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'net'); - expect(payload).to.have.property('auids', '43,43,45'); - expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - delete bidRequests[1].params.priceType; - }); - - it('if gdprConsent is present payload must have gdpr params', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {consentString: 'AAA', gdprApplies: true}}, bidderRequest); - const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('gdpr_consent', 'AAA'); - expect(payload).to.have.property('gdpr_applies', '1'); - }); - - it('if gdprApplies is false gdpr_applies must be 0', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {consentString: 'AAA', gdprApplies: false}}, bidderRequest); - const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('gdpr_consent', 'AAA'); - expect(payload).to.have.property('gdpr_applies', '0'); - }); - - it('if gdprApplies is undefined gdpr_applies must be 1', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {consentString: 'AAA'}}, bidderRequest); - const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('gdpr_consent', 'AAA'); - expect(payload).to.have.property('gdpr_applies', '1'); - }); - - it('if usPrivacy is present payload must have us_privacy param', function () { - const bidderRequestWithUSP = Object.assign({uspConsent: '1YNN'}, bidderRequest); - const request = spec.buildRequests(bidRequests, bidderRequestWithUSP)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('us_privacy', '1YNN'); - }); - - it('should convert keyword params to proper form and attaches to request', function () { - const bidRequestWithKeywords = [].concat(bidRequests); - bidRequestWithKeywords[1] = Object.assign({}, - bidRequests[1], - { - params: { - uid: '43', - keywords: { - single: 'val', - singleArr: ['val'], - singleArrNum: [5], - multiValMixed: ['value1', 2, 'value3'], - singleValNum: 123, - emptyStr: '', - emptyArr: [''], - badValue: {'foo': 'bar'} // should be dropped - } - } - } - ); - - const request = spec.buildRequests(bidRequestWithKeywords, bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload.keywords).to.be.an('string'); - payload.keywords = JSON.parse(payload.keywords); - - expect(payload.keywords).to.deep.equal([{ - 'key': 'single', - 'value': ['val'] - }, { - 'key': 'singleArr', - 'value': ['val'] - }, { - 'key': 'singleArrNum', - 'value': ['5'] - }, { - 'key': 'multiValMixed', - 'value': ['value1', '2', 'value3'] - }, { - 'key': 'singleValNum', - 'value': ['123'] - }, { - 'key': 'emptyStr' - }, { - 'key': 'emptyArr' - }]); - }); - }); - - describe('buildRequests with new format', function () { - function parseRequest(data) { - return JSON.parse(data); - } - const bidderRequest = { - refererInfo: {referer: 'https://example.com'}, - bidderRequestId: '22edbae2733bf6', - auctionId: '9e2dfbfe-00c7-4f5e-9850-4044df3229c7', - timeout: 3000 - }; - const referrer = encodeURIComponent(bidderRequest.refererInfo.referer); - - let bidRequests = [ - { - 'bidder': 'trustx', - 'params': { - 'uid': '43', - 'bidFloor': 1.25, - 'useNewFormat': true - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250], [300, 600]] - } - }, - 'bidId': '42dbe3a7168a6a', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '9e2dfbfe-00c7-4f5e-9850-4044df3229c7', - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '44', - 'useNewFormat': true - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '9e2dfbfe-00c7-4f5e-9850-4044df3229c7', - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '45', - 'useNewFormat': true - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'mediaTypes': { - 'video': { - 'playerSize': [[400, 600]], - 'mimes': ['video/mp4', 'video/webm', 'application/javascript', 'video/ogg'] - } - }, - 'bidId': '3150ccb55da321', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '9e2dfbfe-00c7-4f5e-9850-4044df3229c7', - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '41', - 'useNewFormat': true - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'mediaTypes': { - 'video': { - 'playerSize': [[400, 600]], - 'protocols': [1, 2, 3] - }, - 'banner': { - 'sizes': [[728, 90]] - } - }, - 'bidId': '3150ccb55da321', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '9e2dfbfe-00c7-4f5e-9850-4044df3229c7', - } - ]; - - it('should attach valid params to the tag', function () { - const request = spec.buildRequests([bidRequests[0]], bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.deep.equal({ - 'id': bidderRequest.bidderRequestId, - 'site': { - 'page': referrer - }, - 'tmax': bidderRequest.timeout, - 'source': { - 'tid': bidderRequest.auctionId, - 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'} - }, - 'imp': [{ - 'id': bidRequests[0].bidId, - 'tagid': bidRequests[0].params.uid, - 'ext': {'divid': bidRequests[0].adUnitCode}, - 'bidfloor': bidRequests[0].params.bidFloor, - 'banner': { - 'w': 300, - 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] - } - }] - }); - }); - - it('make possible to process request without mediaTypes', function () { - const request = spec.buildRequests([bidRequests[0], bidRequests[1]], bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.deep.equal({ - 'id': bidderRequest.bidderRequestId, - 'site': { - 'page': referrer - }, - 'tmax': bidderRequest.timeout, - 'source': { - 'tid': bidderRequest.auctionId, - 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'} - }, - 'imp': [{ - 'id': bidRequests[0].bidId, - 'tagid': bidRequests[0].params.uid, - 'ext': {'divid': bidRequests[0].adUnitCode}, - 'bidfloor': bidRequests[0].params.bidFloor, - 'banner': { - 'w': 300, - 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] - } - }, { - 'id': bidRequests[1].bidId, - 'tagid': bidRequests[1].params.uid, - 'ext': {'divid': bidRequests[1].adUnitCode}, - 'banner': { - 'w': 300, - 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] - } - }] - }); - }); - - it('should attach valid params to the video tag', function () { - const request = spec.buildRequests(bidRequests.slice(0, 3), bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.deep.equal({ - 'id': bidderRequest.bidderRequestId, - 'site': { - 'page': referrer - }, - 'tmax': bidderRequest.timeout, - 'source': { - 'tid': bidderRequest.auctionId, - 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'} - }, - 'imp': [{ - 'id': bidRequests[0].bidId, - 'tagid': bidRequests[0].params.uid, - 'ext': {'divid': bidRequests[0].adUnitCode}, - 'bidfloor': bidRequests[0].params.bidFloor, - 'banner': { - 'w': 300, - 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] - } - }, { - 'id': bidRequests[1].bidId, - 'tagid': bidRequests[1].params.uid, - 'ext': {'divid': bidRequests[1].adUnitCode}, - 'banner': { - 'w': 300, - 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] - } - }, { - 'id': bidRequests[2].bidId, - 'tagid': bidRequests[2].params.uid, - 'ext': {'divid': bidRequests[2].adUnitCode}, - 'video': { - 'w': 400, - 'h': 600, - 'mimes': ['video/mp4', 'video/webm', 'application/javascript', 'video/ogg'] - } - }] - }); - }); - - it('should support mixed mediaTypes', function () { - const request = spec.buildRequests(bidRequests, bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.deep.equal({ - 'id': bidderRequest.bidderRequestId, - 'site': { - 'page': referrer - }, - 'tmax': bidderRequest.timeout, - 'source': { - 'tid': bidderRequest.auctionId, - 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'} - }, - 'imp': [{ - 'id': bidRequests[0].bidId, - 'tagid': bidRequests[0].params.uid, - 'ext': {'divid': bidRequests[0].adUnitCode}, - 'bidfloor': bidRequests[0].params.bidFloor, - 'banner': { - 'w': 300, - 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] - } - }, { - 'id': bidRequests[1].bidId, - 'tagid': bidRequests[1].params.uid, - 'ext': {'divid': bidRequests[1].adUnitCode}, - 'banner': { - 'w': 300, - 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] - } - }, { - 'id': bidRequests[2].bidId, - 'tagid': bidRequests[2].params.uid, - 'ext': {'divid': bidRequests[2].adUnitCode}, - 'video': { - 'w': 400, - 'h': 600, - 'mimes': ['video/mp4', 'video/webm', 'application/javascript', 'video/ogg'], - } - }, { - 'id': bidRequests[3].bidId, - 'tagid': bidRequests[3].params.uid, - 'ext': {'divid': bidRequests[3].adUnitCode}, - 'banner': { - 'w': 728, - 'h': 90, - 'format': [{'w': 728, 'h': 90}] - }, - 'video': { - 'w': 400, - 'h': 600, - 'protocols': [1, 2, 3] - } - }] - }); - }); - - it('if gdprConsent is present payload must have gdpr params', function () { - const gdprBidderRequest = Object.assign({gdprConsent: {consentString: 'AAA', gdprApplies: true}}, bidderRequest); - const request = spec.buildRequests(bidRequests, gdprBidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('user'); - expect(payload.user).to.have.property('ext'); - expect(payload.user.ext).to.have.property('consent', 'AAA'); - expect(payload).to.have.property('regs'); - expect(payload.regs).to.have.property('ext'); - expect(payload.regs.ext).to.have.property('gdpr', 1); - }); - - it('if usPrivacy is present payload must have us_privacy param', function () { - const bidderRequestWithUSP = Object.assign({uspConsent: '1YNN'}, bidderRequest); - const request = spec.buildRequests(bidRequests, bidderRequestWithUSP)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('regs'); - expect(payload.regs).to.have.property('ext'); - expect(payload.regs.ext).to.have.property('us_privacy', '1YNN'); - }); - - it('if userId is present payload must have user.ext param with right keys', function () { - const eids = [ - { - source: 'pubcid.org', - uids: [{ - id: 'some-random-id-value', - atype: 1 - }] - }, - { - source: 'adserver.org', - uids: [{ - id: 'some-random-id-value', - atype: 1, - ext: { - rtiPartner: 'TDID' - } - }] - } - ]; - const bidRequestsWithUserIds = bidRequests.map((bid) => { - return Object.assign({ - userIdAsEids: eids - }, bid); - }); - const request = spec.buildRequests(bidRequestsWithUserIds, bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('user'); - expect(payload.user).to.have.property('ext'); - expect(payload.user.ext.eids).to.deep.equal(eids); - }); - - it('if schain is present payload must have source.ext.schain param', function () { - const schain = { - complete: 1, - nodes: [ - { - asi: 'indirectseller.com', - sid: '00001', - hp: 1 - } - ] - }; - const bidRequestsWithSChain = bidRequests.map((bid) => { - return Object.assign({ - schain: schain - }, bid); - }); - const request = spec.buildRequests(bidRequestsWithSChain, bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('source'); - expect(payload.source).to.have.property('ext'); - expect(payload.source.ext).to.have.property('schain'); - expect(payload.source.ext.schain).to.deep.equal(schain); - }); - - it('if content and segment is present in jwTargeting, payload must have right params', function () { - const jsContent = {id: 'test_jw_content_id'}; - const jsSegments = ['test_seg_1', 'test_seg_2']; - const bidRequestsWithJwTargeting = bidRequests.map((bid) => { - return Object.assign({ - rtd: { - jwplayer: { - targeting: { - segments: jsSegments, - content: jsContent - } - } - } - }, bid); - }); - const request = spec.buildRequests(bidRequestsWithJwTargeting, bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('user'); - expect(payload.user.data).to.deep.equal([{ - name: 'iow_labs_pub_data', - segment: [ - {name: 'jwpseg', value: jsSegments[0]}, - {name: 'jwpseg', value: jsSegments[1]} - ] - }]); - expect(payload).to.have.property('site'); - expect(payload.site.content).to.deep.equal(jsContent); - }); - - it('should contain the keyword values if it present in ortb2.(site/user)', function () { - const getConfigStub = sinon.stub(config, 'getConfig').callsFake( - arg => arg === 'ortb2.user' ? {'keywords': 'foo'} : (arg === 'ortb2.site' ? {'keywords': 'bar'} : null)); - const request = spec.buildRequests([bidRequests[0]], bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload.ext.keywords).to.deep.equal([{'key': 'user', 'value': ['foo']}, {'key': 'context', 'value': ['bar']}]); - getConfigStub.restore(); - }); - - it('shold be right tmax when timeout in config is less then timeout in bidderRequest', function() { - const getConfigStub = sinon.stub(config, 'getConfig').callsFake( - arg => arg === 'bidderTimeout' ? 2000 : null); - const request = spec.buildRequests([bidRequests[0]], bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload.tmax).to.equal(2000); - getConfigStub.restore(); - }); - it('shold be right tmax when timeout in bidderRequest is less then timeout in config', function() { - const getConfigStub = sinon.stub(config, 'getConfig').callsFake( - arg => arg === 'bidderTimeout' ? 5000 : null); - const request = spec.buildRequests([bidRequests[0]], bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload.tmax).to.equal(3000); - getConfigStub.restore(); - }); - - describe('floorModule', function () { - const floorTestData = { - 'currency': 'USD', - 'floor': 1.50 - }; - const bidRequest = Object.assign({ - getFloor: (_) => { - return floorTestData; - } - }, bidRequests[1]); - it('should return the value from getFloor if present', function () { - const request = spec.buildRequests([bidRequest], bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload.imp[0].bidfloor).to.equal(floorTestData.floor); - }); - 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); - const request = spec.buildRequests([bidRequestsWithFloor], bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload.imp[0].bidfloor).to.equal(floorTestData.floor); - }); - 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); - const request = spec.buildRequests([bidRequestsWithFloor], bidderRequest)[0]; - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload.imp[0].bidfloor).to.equal(bidfloor); - }); - }); - }); - - describe('interpretResponse', function () { - const responses = [ - {'bid': [{'price': 1.15, 'adm': '
test content 1
', 'auid': 43, 'h': 250, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.5, 'adm': '
test content 2
', 'auid': 44, 'h': 600, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.15, 'adm': '
test content 3
', 'auid': 43, 'h': 90, 'w': 728}], 'seat': '1'}, - {'bid': [{'price': 0, 'auid': 45, 'h': 250, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0, 'adm': '
test content 5
', 'h': 250, 'w': 300}], 'seat': '1'}, - undefined, - {'bid': [], 'seat': '1'}, - {'seat': '1'}, - ]; - - it('should get correct bid response', function () { - const bidRequests = [ - { - 'bidder': 'trustx', - 'params': { - 'uid': '43' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '659423fff799cb', - 'bidderRequestId': '5f2009617a7c0a', - 'auctionId': '1cbd2feafe5e8b', - } - ]; - const request = spec.buildRequests(bidRequests)[0]; - const expectedResponse = [ - { - 'requestId': '659423fff799cb', - 'cpm': 1.15, - 'creativeId': 43, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': [responses[0]]}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('should get correct multi bid response', function () { - const bidRequests = [ - { - 'bidder': 'trustx', - 'params': { - 'uid': '43' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '300bfeb0d71a5b', - 'bidderRequestId': '2c2bb1972df9a', - 'auctionId': '1fa09aee5c8c99', - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '44' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '4dff80cc4ee346', - 'bidderRequestId': '2c2bb1972df9a', - 'auctionId': '1fa09aee5c8c99', - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '43' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '5703af74d0472a', - 'bidderRequestId': '2c2bb1972df9a', - 'auctionId': '1fa09aee5c8c99', - } - ]; - const request = spec.buildRequests(bidRequests)[0]; - const expectedResponse = [ - { - 'requestId': '300bfeb0d71a5b', - 'cpm': 1.15, - 'creativeId': 43, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '4dff80cc4ee346', - 'cpm': 0.5, - 'creativeId': 44, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'ad': '
test content 2
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '5703af74d0472a', - 'cpm': 0.15, - 'creativeId': 43, - 'dealId': undefined, - 'width': 728, - 'height': 90, - 'ad': '
test content 3
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': responses.slice(0, 3)}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('handles wrong and nobid responses', function () { - const bidRequests = [ - { - 'bidder': 'trustx', - 'params': { - 'uid': '45' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '300bfeb0d7190gf', - 'bidderRequestId': '2c2bb1972d23af', - 'auctionId': '1fa09aee5c84d34', - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '46' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '300bfeb0d71321', - 'bidderRequestId': '2c2bb1972d23af', - 'auctionId': '1fa09aee5c84d34', - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '50' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '300bfeb0d7183bb', - 'bidderRequestId': '2c2bb1972d23af', - 'auctionId': '1fa09aee5c84d34', - } - ]; - const request = spec.buildRequests(bidRequests)[0]; - const result = spec.interpretResponse({'body': {'seatbid': responses.slice(3)}}, request); - expect(result.length).to.equal(0); - }); - - it('complicated case', function () { - const fullResponse = [ - {'bid': [{'price': 1.15, 'adm': '
test content 1
', 'auid': 43, 'h': 250, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.5, 'adm': '
test content 2
', 'auid': 44, 'h': 600, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.15, 'adm': '
test content 3
', 'auid': 43, 'h': 90, 'w': 728}], 'seat': '1'}, - {'bid': [{'price': 0.15, 'adm': '
test content 4
', 'auid': 43, 'h': 600, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.5, 'adm': '
test content 5
', 'auid': 44, 'h': 600, 'w': 350}], 'seat': '1'}, - ]; - const bidRequests = [ - { - 'bidder': 'trustx', - 'params': { - 'uid': '43' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '2164be6358b9', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '43' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '326bde7fbf69', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '44' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '4e111f1b66e4', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '43' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '26d6f897b516', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '44' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '1751cd90161', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - } - ]; - const request = spec.buildRequests(bidRequests)[0]; - const expectedResponse = [ - { - 'requestId': '2164be6358b9', - 'cpm': 1.15, - 'creativeId': 43, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '4e111f1b66e4', - 'cpm': 0.5, - 'creativeId': 44, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'ad': '
test content 2
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '26d6f897b516', - 'cpm': 0.15, - 'creativeId': 43, - 'dealId': undefined, - 'width': 728, - 'height': 90, - 'ad': '
test content 3
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '326bde7fbf69', - 'cpm': 0.15, - 'creativeId': 43, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'ad': '
test content 4
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': fullResponse}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('dublicate uids and sizes in one slot', function () { - const fullResponse = [ - {'bid': [{'price': 1.15, 'adm': '
test content 1
', 'auid': 43, 'h': 250, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.5, 'adm': '
test content 2
', 'auid': 43, 'h': 250, 'w': 300}], 'seat': '1'}, - ]; - const bidRequests = [ - { - 'bidder': 'trustx', - 'params': { - 'uid': '43' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '5126e301f4be', - 'bidderRequestId': '171c5405a390', - 'auctionId': '35bcbc0f7e79c', - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '43' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '57b2ebe70e16', - 'bidderRequestId': '171c5405a390', - 'auctionId': '35bcbc0f7e79c', - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '43' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '225fcd44b18c', - 'bidderRequestId': '171c5405a390', - 'auctionId': '35bcbc0f7e79c', - } - ]; - const request = spec.buildRequests(bidRequests)[0]; - const expectedResponse = [ - { - 'requestId': '5126e301f4be', - 'cpm': 1.15, - 'creativeId': 43, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '57b2ebe70e16', - 'cpm': 0.5, - 'creativeId': 43, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 2
', - 'currency': 'USD', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': fullResponse}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - }); - - it('should get correct video bid response', function () { - const bidRequests = [ - { - 'bidder': 'trustx', - 'params': { - 'uid': '50' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '57dfefb80eca', - 'bidderRequestId': '20394420a762a2', - 'auctionId': '140132d07b031', - 'mediaTypes': { - 'video': { - 'context': 'instream' - } - } - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '51' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': 'e893c787c22dd', - 'bidderRequestId': '20394420a762a2', - 'auctionId': '140132d07b031', - 'mediaTypes': { - 'video': { - 'context': 'instream' - } - } - } - ]; - const response = [ - {'bid': [{'price': 1.15, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 50, content_type: 'video', w: 300, h: 600}], 'seat': '2'}, - {'bid': [{'price': 1.00, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 51, content_type: 'video'}], 'seat': '2'} - ]; - const request = spec.buildRequests(bidRequests)[0]; - const expectedResponse = [ - { - 'requestId': '57dfefb80eca', - 'cpm': 1.15, - 'creativeId': 50, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'currency': 'USD', - 'mediaType': 'video', - 'netRevenue': true, - 'ttl': 360, - 'vastXml': '\n<\/Ad>\n<\/VAST>', - 'adResponse': { - 'content': '\n<\/Ad>\n<\/VAST>' - } - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': response}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('should have right renderer in the bid response', function () { - const spySetRenderer = sinon.spy(); - const stubRenderer = { - setRender: spySetRenderer - }; - const spyRendererInstall = sinon.spy(function() { return stubRenderer; }); - const stubRendererConst = { - install: spyRendererInstall - }; - const bidRequests = [ - { - 'bidder': 'trustx', - 'params': { - 'uid': '50' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': 'e6e65553fc8', - 'bidderRequestId': '1380f393215dc7', - 'auctionId': '10b8d2f3c697e3', - 'mediaTypes': { - 'video': { - 'context': 'outstream' - } - } - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '51' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': 'c8fdcb3f269f', - 'bidderRequestId': '1380f393215dc7', - 'auctionId': '10b8d2f3c697e3' - }, - { - 'bidder': 'trustx', - 'params': { - 'uid': '52' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '1de036c37685', - 'bidderRequestId': '1380f393215dc7', - 'auctionId': '10b8d2f3c697e3', - 'renderer': {} - } - ]; - const response = [ - {'bid': [{'price': 1.15, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 50, content_type: 'video', w: 300, h: 600}], 'seat': '2'}, - {'bid': [{'price': 1.00, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 51, content_type: 'video', w: 300, h: 250}], 'seat': '2'}, - {'bid': [{'price': 1.20, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 52, content_type: 'video', w: 300, h: 250}], 'seat': '2'} - ]; - const request = spec.buildRequests(bidRequests)[0]; - const expectedResponse = [ - { - 'requestId': 'e6e65553fc8', - 'cpm': 1.15, - 'creativeId': 50, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'currency': 'USD', - 'mediaType': 'video', - 'netRevenue': true, - 'ttl': 360, - 'vastXml': '\n<\/Ad>\n<\/VAST>', - 'adResponse': { - 'content': '\n<\/Ad>\n<\/VAST>' - }, - 'renderer': stubRenderer - }, - { - 'requestId': 'c8fdcb3f269f', - 'cpm': 1.00, - 'creativeId': 51, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'currency': 'USD', - 'mediaType': 'video', - 'netRevenue': true, - 'ttl': 360, - 'vastXml': '\n<\/Ad>\n<\/VAST>', - 'adResponse': { - 'content': '\n<\/Ad>\n<\/VAST>' - }, - 'renderer': stubRenderer - }, - { - 'requestId': '1de036c37685', - 'cpm': 1.20, - 'creativeId': 52, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'currency': 'USD', - 'mediaType': 'video', - 'netRevenue': true, - 'ttl': 360, - 'vastXml': '\n<\/Ad>\n<\/VAST>', - 'adResponse': { - 'content': '\n<\/Ad>\n<\/VAST>' - } - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': response}}, request, stubRendererConst); - - expect(spySetRenderer.calledTwice).to.equal(true); - expect(spySetRenderer.getCall(0).args[0]).to.be.a('function'); - expect(spySetRenderer.getCall(1).args[0]).to.be.a('function'); - - expect(spyRendererInstall.calledTwice).to.equal(true); - expect(spyRendererInstall.getCall(0).args[0]).to.deep.equal({ - id: 'e6e65553fc8', - url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', - loaded: false - }); - expect(spyRendererInstall.getCall(1).args[0]).to.deep.equal({ - id: 'c8fdcb3f269f', - url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', - loaded: false - }); - - expect(result).to.deep.equal(expectedResponse); - }); -}); diff --git a/test/spec/modules/turktelekomBidAdapter_spec.js b/test/spec/modules/turktelekomBidAdapter_spec.js deleted file mode 100644 index c4e55178638..00000000000 --- a/test/spec/modules/turktelekomBidAdapter_spec.js +++ /dev/null @@ -1,749 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/turktelekomBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('TurkTelekomAdapter', 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 () { - let bid = { - 'bidder': 'turktelekom', - 'params': { - 'uid': '17' - }, - '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(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'uid': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - function parseRequest(url) { - const res = {}; - url.split('&').forEach((it) => { - const couple = it.split('='); - res[couple[0]] = decodeURIComponent(couple[1]); - }); - return res; - } - - const bidderRequest = { - refererInfo: { - referer: 'https://example.com' - } - }; - const referrer = bidderRequest.refererInfo.referer; - - let bidRequests = [ - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '18' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }, - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '18' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90], [300, 250]], - 'bidId': '3150ccb55da321', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }, - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '20' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '42dbe3a7168a6a', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - it('should attach valid params to the tag', function () { - const request = spec.buildRequests([bidRequests[0]], bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'net'); - expect(payload).to.have.property('auids', '18'); - expect(payload).to.have.property('sizes', '300x250,300x600'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - expect(payload).to.have.property('wrapperType', 'Prebid_js'); - expect(payload).to.have.property('wrapperVersion', '$prebid.version$'); - }); - - it('sizes must not be duplicated', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'net'); - expect(payload).to.have.property('auids', '18,18,20'); - expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - }); - - it('pt parameter must be "gross" if params.priceType === "gross"', function () { - bidRequests[1].params.priceType = 'gross'; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'gross'); - expect(payload).to.have.property('auids', '18,18,20'); - expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - delete bidRequests[1].params.priceType; - }); - - it('pt parameter must be "net" or "gross"', function () { - bidRequests[1].params.priceType = 'some'; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'net'); - expect(payload).to.have.property('auids', '18,18,20'); - expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - delete bidRequests[1].params.priceType; - }); - - it('if gdprConsent is present payload must have gdpr params', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {consentString: 'AAA', gdprApplies: true}}, bidderRequest); - const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('gdpr_consent', 'AAA'); - expect(payload).to.have.property('gdpr_applies', '1'); - }); - - it('if gdprApplies is false gdpr_applies must be 0', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {consentString: 'AAA', gdprApplies: false}}, bidderRequest); - const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('gdpr_consent', 'AAA'); - expect(payload).to.have.property('gdpr_applies', '0'); - }); - - it('if gdprApplies is undefined gdpr_applies must be 1', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {consentString: 'AAA'}}, bidderRequest); - const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); - expect(request.data).to.be.an('string'); - const payload = parseRequest(request.data); - expect(payload).to.have.property('gdpr_consent', 'AAA'); - expect(payload).to.have.property('gdpr_applies', '1'); - }); - }); - - describe('interpretResponse', function () { - const responses = [ - {'bid': [{'price': 1.15, 'adm': '
test content 1
', 'auid': 17, 'h': 250, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.5, 'adm': '
test content 2
', 'auid': 18, 'h': 600, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.15, 'adm': '
test content 3
', 'auid': 17, 'h': 90, 'w': 728}], 'seat': '1'}, - {'bid': [{'price': 0, 'auid': 19, 'h': 250, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0, 'adm': '
test content 5
', 'h': 250, 'w': 300}], 'seat': '1'}, - undefined, - {'bid': [], 'seat': '1'}, - {'seat': '1'}, - ]; - - it('should get correct bid response', function () { - const bidRequests = [ - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '17' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '659423fff799cb', - 'bidderRequestId': '5f2009617a7c0a', - 'auctionId': '1cbd2feafe5e8b', - } - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '659423fff799cb', - 'cpm': 1.15, - 'creativeId': 17, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'bidderCode': 'turktelekom', - 'currency': 'TRY', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': [responses[0]]}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('should get correct multi bid response', function () { - const bidRequests = [ - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '17' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '300bfeb0d71a5b', - 'bidderRequestId': '2c2bb1972df9a', - 'auctionId': '1fa09aee5c8c99', - }, - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '18' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '4dff80cc4ee346', - 'bidderRequestId': '2c2bb1972df9a', - 'auctionId': '1fa09aee5c8c99', - }, - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '17' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '5703af74d0472a', - 'bidderRequestId': '2c2bb1972df9a', - 'auctionId': '1fa09aee5c8c99', - } - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '300bfeb0d71a5b', - 'cpm': 1.15, - 'creativeId': 17, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'bidderCode': 'turktelekom', - 'currency': 'TRY', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '4dff80cc4ee346', - 'cpm': 0.5, - 'creativeId': 18, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'ad': '
test content 2
', - 'bidderCode': 'turktelekom', - 'currency': 'TRY', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '5703af74d0472a', - 'cpm': 0.15, - 'creativeId': 17, - 'dealId': undefined, - 'width': 728, - 'height': 90, - 'ad': '
test content 3
', - 'bidderCode': 'turktelekom', - 'currency': 'TRY', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': responses.slice(0, 3)}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('handles wrong and nobid responses', function () { - const bidRequests = [ - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '19' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '300bfeb0d7190gf', - 'bidderRequestId': '2c2bb1972d23af', - 'auctionId': '1fa09aee5c84d34', - }, - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '20' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '300bfeb0d71321', - 'bidderRequestId': '2c2bb1972d23af', - 'auctionId': '1fa09aee5c84d34', - }, - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '25' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '300bfeb0d7183bb', - 'bidderRequestId': '2c2bb1972d23af', - 'auctionId': '1fa09aee5c84d34', - } - ]; - const request = spec.buildRequests(bidRequests); - const result = spec.interpretResponse({'body': {'seatbid': responses.slice(3)}}, request); - expect(result.length).to.equal(0); - }); - - it('complicated case', function () { - const fullResponse = [ - {'bid': [{'price': 1.15, 'adm': '
test content 1
', 'auid': 17, 'h': 250, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.5, 'adm': '
test content 2
', 'auid': 18, 'h': 600, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.15, 'adm': '
test content 3
', 'auid': 17, 'h': 90, 'w': 728}], 'seat': '1'}, - {'bid': [{'price': 0.15, 'adm': '
test content 4
', 'auid': 17, 'h': 600, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.5, 'adm': '
test content 5
', 'auid': 18, 'h': 600, 'w': 350}], 'seat': '1'}, - ]; - const bidRequests = [ - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '17' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '2164be6358b9', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '17' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '326bde7fbf69', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '18' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '4e111f1b66e4', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '17' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '26d6f897b516', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '44' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '1751cd90161', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - } - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '2164be6358b9', - 'cpm': 1.15, - 'creativeId': 17, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'bidderCode': 'turktelekom', - 'currency': 'TRY', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '4e111f1b66e4', - 'cpm': 0.5, - 'creativeId': 18, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'ad': '
test content 2
', - 'bidderCode': 'turktelekom', - 'currency': 'TRY', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '26d6f897b516', - 'cpm': 0.15, - 'creativeId': 17, - 'dealId': undefined, - 'width': 728, - 'height': 90, - 'ad': '
test content 3
', - 'bidderCode': 'turktelekom', - 'currency': 'TRY', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '326bde7fbf69', - 'cpm': 0.15, - 'creativeId': 17, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'ad': '
test content 4
', - 'bidderCode': 'turktelekom', - 'currency': 'TRY', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': fullResponse}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('dublicate uids and sizes in one slot', function () { - const fullResponse = [ - {'bid': [{'price': 1.15, 'adm': '
test content 1
', 'auid': 17, 'h': 250, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0.5, 'adm': '
test content 2
', 'auid': 17, 'h': 250, 'w': 300}], 'seat': '1'}, - ]; - const bidRequests = [ - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '17' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '5126e301f4be', - 'bidderRequestId': '171c5405a390', - 'auctionId': '35bcbc0f7e79c', - }, - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '17' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '57b2ebe70e16', - 'bidderRequestId': '171c5405a390', - 'auctionId': '35bcbc0f7e79c', - }, - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '17' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '225fcd44b18c', - 'bidderRequestId': '171c5405a390', - 'auctionId': '35bcbc0f7e79c', - } - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '5126e301f4be', - 'cpm': 1.15, - 'creativeId': 17, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'bidderCode': 'turktelekom', - 'currency': 'TRY', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '57b2ebe70e16', - 'cpm': 0.5, - 'creativeId': 17, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 2
', - 'bidderCode': 'turktelekom', - 'currency': 'TRY', - 'mediaType': 'banner', - 'netRevenue': true, - 'ttl': 360, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': fullResponse}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - }); - - it('should get correct video bid response', function () { - const bidRequests = [ - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '25' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '57dfefb80eca', - 'bidderRequestId': '20394420a762a2', - 'auctionId': '140132d07b031', - 'mediaTypes': { - 'video': { - 'context': 'instream' - } - } - }, - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '26' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': 'e893c787c22dd', - 'bidderRequestId': '20394420a762a2', - 'auctionId': '140132d07b031', - 'mediaTypes': { - 'video': { - 'context': 'instream' - } - } - } - ]; - const response = [ - {'bid': [{'price': 1.15, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 25, content_type: 'video', w: 300, h: 600}], 'seat': '2'}, - {'bid': [{'price': 1.00, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 26, content_type: 'video'}], 'seat': '2'} - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '57dfefb80eca', - 'cpm': 1.15, - 'creativeId': 25, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'bidderCode': 'turktelekom', - 'currency': 'TRY', - 'mediaType': 'video', - 'netRevenue': true, - 'ttl': 360, - 'vastXml': '\n<\/Ad>\n<\/VAST>', - 'adResponse': { - 'content': '\n<\/Ad>\n<\/VAST>' - } - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': response}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('should have right renderer in the bid response', function () { - const spySetRenderer = sinon.spy(); - const stubRenderer = { - setRender: spySetRenderer - }; - const spyRendererInstall = sinon.spy(function() { return stubRenderer; }); - const stubRendererConst = { - install: spyRendererInstall - }; - const bidRequests = [ - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '25' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': 'e6e65553fc8', - 'bidderRequestId': '1380f393215dc7', - 'auctionId': '10b8d2f3c697e3', - 'mediaTypes': { - 'video': { - 'context': 'outstream' - } - } - }, - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '26' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': 'c8fdcb3f269f', - 'bidderRequestId': '1380f393215dc7', - 'auctionId': '10b8d2f3c697e3' - }, - { - 'bidder': 'turktelekom', - 'params': { - 'uid': '27' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '1de036c37685', - 'bidderRequestId': '1380f393215dc7', - 'auctionId': '10b8d2f3c697e3', - 'renderer': {} - } - ]; - const response = [ - {'bid': [{'price': 1.15, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 25, content_type: 'video', w: 300, h: 600}], 'seat': '2'}, - {'bid': [{'price': 1.00, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 26, content_type: 'video', w: 300, h: 250}], 'seat': '2'}, - {'bid': [{'price': 1.20, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 27, content_type: 'video', w: 300, h: 250}], 'seat': '2'} - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': 'e6e65553fc8', - 'cpm': 1.15, - 'creativeId': 25, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'bidderCode': 'turktelekom', - 'currency': 'TRY', - 'mediaType': 'video', - 'netRevenue': true, - 'ttl': 360, - 'vastXml': '\n<\/Ad>\n<\/VAST>', - 'adResponse': { - 'content': '\n<\/Ad>\n<\/VAST>' - }, - 'renderer': stubRenderer - }, - { - 'requestId': 'c8fdcb3f269f', - 'cpm': 1.00, - 'creativeId': 26, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'bidderCode': 'turktelekom', - 'currency': 'TRY', - 'mediaType': 'video', - 'netRevenue': true, - 'ttl': 360, - 'vastXml': '\n<\/Ad>\n<\/VAST>', - 'adResponse': { - 'content': '\n<\/Ad>\n<\/VAST>' - }, - 'renderer': stubRenderer - }, - { - 'requestId': '1de036c37685', - 'cpm': 1.20, - 'creativeId': 27, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'bidderCode': 'turktelekom', - 'currency': 'TRY', - 'mediaType': 'video', - 'netRevenue': true, - 'ttl': 360, - 'vastXml': '\n<\/Ad>\n<\/VAST>', - 'adResponse': { - 'content': '\n<\/Ad>\n<\/VAST>' - } - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': response}}, request, stubRendererConst); - - expect(spySetRenderer.calledTwice).to.equal(true); - expect(spySetRenderer.getCall(0).args[0]).to.be.a('function'); - expect(spySetRenderer.getCall(1).args[0]).to.be.a('function'); - - expect(spyRendererInstall.calledTwice).to.equal(true); - expect(spyRendererInstall.getCall(0).args[0]).to.deep.equal({ - id: 'e6e65553fc8', - url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', - loaded: false - }); - expect(spyRendererInstall.getCall(1).args[0]).to.deep.equal({ - id: 'c8fdcb3f269f', - url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', - loaded: false - }); - - expect(result).to.deep.equal(expectedResponse); - }); -}); diff --git a/test/spec/modules/ucfunnelAnalyticsAdapter_spec.js b/test/spec/modules/ucfunnelAnalyticsAdapter_spec.js deleted file mode 100644 index 2b7f047c85a..00000000000 --- a/test/spec/modules/ucfunnelAnalyticsAdapter_spec.js +++ /dev/null @@ -1,487 +0,0 @@ -import { - ucfunnelAnalyticsAdapter, parseBidderCode, parseAdUnitCode, - ANALYTICS_VERSION, BIDDER_STATUS -} from 'modules/ucfunnelAnalyticsAdapter.js'; - -import {expect} from 'chai'; - -const events = require('src/events'); -const constants = require('src/constants.json'); - -const pbuid = 'pbuid-AA778D8A796AEA7A0843E2BBEB677766'; -const adid = 'test-ad-83444226E44368D1E32E49EEBE6D29'; -const auctionId = 'b0b39610-b941-4659-a87c-de9f62d3e13e'; - -describe('ucfunnel Prebid AnalyticsAdapter Testing', function () { - describe('event tracking and message cache manager', function () { - beforeEach(function () { - const configOptions = { - pbuid: pbuid, - adid: adid, - sampling: 0, - }; - - ucfunnelAnalyticsAdapter.enableAnalytics({ - provider: 'ucfunnelAnalytics', - options: configOptions - }); - }); - - afterEach(function () { - ucfunnelAnalyticsAdapter.disableAnalytics(); - }); - - describe('#parseBidderCode()', function() { - it('should get lower case bidder code from bidderCode field value', function() { - const receivedBids = [ - { - auctionId: auctionId, - adUnitCode: 'adunit_1', - bidder: 'ucfunnel', - bidderCode: 'UCFUNNEL', - requestId: 'a1b2c3d4', - timeToRespond: 72, - cpm: 0.1, - currency: 'USD', - ad: 'fake ad1' - }, - ]; - const result = parseBidderCode(receivedBids[0]); - expect(result).to.equal('ucfunnel'); - }); - it('should get lower case bidder code from bidder field value as bidderCode field is missing', function() { - const receivedBids = [ - { - auctionId: auctionId, - adUnitCode: 'adunit_1', - bidder: 'UCFUNNEL', - bidderCode: '', - requestId: 'a1b2c3d4', - timeToRespond: 72, - cpm: 0.1, - currency: 'USD', - ad: 'fake ad1' - }, - ]; - const result = parseBidderCode(receivedBids[0]); - expect(result).to.equal('ucfunnel'); - }); - }); - - describe('#parseAdUnitCode()', function() { - it('should get lower case adUnit code from adUnitCode field value', function() { - const receivedBids = [ - { - auctionId: auctionId, - adUnitCode: 'ADUNIT', - bidder: 'ucfunnel', - bidderCode: 'UCFUNNEL', - requestId: 'a1b2c3d4', - timeToRespond: 72, - cpm: 0.1, - currency: 'USD', - ad: 'fake ad1' - }, - ]; - const result = parseAdUnitCode(receivedBids[0]); - expect(result).to.equal('adunit'); - }); - }); - - describe('#getCachedAuction()', function() { - const existing = {timeoutBids: [{}]}; - ucfunnelAnalyticsAdapter.cachedAuctions['test_auction_id'] = existing; - - it('should get the existing cached object if it exists', function() { - const result = ucfunnelAnalyticsAdapter.getCachedAuction('test_auction_id'); - - expect(result).to.equal(existing); - }); - - it('should create a new object and store it in the cache on cache miss', function() { - const result = ucfunnelAnalyticsAdapter.getCachedAuction('no_such_id'); - - expect(result).to.deep.include({ - timeoutBids: [], - }); - }); - }); - - describe('when formatting JSON payload sent to backend', function() { - const receivedBids = [ - { - auctionId: auctionId, - adUnitCode: 'adunit_1', - bidder: 'ucfunnel', - bidderCode: 'ucfunnel', - requestId: 'a1b2c3d4', - timeToRespond: 72, - cpm: 0.1, - currency: 'USD', - ad: 'fake ad1' - }, - { - auctionId: auctionId, - adUnitCode: 'adunit_1', - bidder: 'ucfunnelx', - bidderCode: 'ucfunnelx', - requestId: 'b2c3d4e5', - timeToRespond: 100, - cpm: 0.08, - currency: 'USD', - ad: 'fake ad2' - }, - { - auctionId: auctionId, - adUnitCode: 'adunit_2', - bidder: 'ucfunnel', - bidderCode: 'ucfunnel', - requestId: 'c3d4e5f6', - timeToRespond: 120, - cpm: 0.09, - currency: 'USD', - ad: 'fake ad3' - }, - ]; - const highestCpmBids = [ - { - auctionId: auctionId, - adUnitCode: 'adunit_1', - bidder: 'ucfunnel', - bidderCode: 'ucfunnel', - // No requestId - timeToRespond: 72, - cpm: 0.1, - currency: 'USD', - ad: 'fake ad1' - } - ]; - const noBids = [ - { - auctionId: auctionId, - adUnitCode: 'adunit_2', - bidder: 'ucfunnel', - bidderCode: 'ucfunnel', - bidId: 'a1b2c3d4', - } - ]; - const timeoutBids = [ - { - auctionId: auctionId, - adUnitCode: 'adunit_2', - bidder: 'ucfunnel', - bidderCode: 'ucfunnel', - bidId: '00123d4c', - } - ]; - function assertHavingRequiredMessageFields(message) { - expect(message).to.include({ - version: ANALYTICS_VERSION, - auctionId: auctionId, - pbuid: pbuid, - adid: adid, - // referrer: window.location.href, - sampling: 0, - prebid: '$prebid.version$', - }); - } - - describe('#createCommonMessage', function() { - it('should correctly serialize some common fields', function() { - const message = ucfunnelAnalyticsAdapter.createCommonMessage(auctionId); - - assertHavingRequiredMessageFields(message); - }); - }); - - describe('#serializeBidResponse', function() { - it('should handle BID properly and serialize bid price related fields', function() { - const result = ucfunnelAnalyticsAdapter.serializeBidResponse(receivedBids[0], BIDDER_STATUS.BID); - - expect(result).to.include({ - prebidWon: false, - isTimeout: false, - status: BIDDER_STATUS.BID, - time: 72, - cpm: 0.1, - currency: 'USD', - }); - }); - - it('should handle NO_BID properly and set status to noBid', function() { - const result = ucfunnelAnalyticsAdapter.serializeBidResponse(noBids[0], BIDDER_STATUS.NO_BID); - - expect(result).to.include({ - prebidWon: false, - isTimeout: false, - status: BIDDER_STATUS.NO_BID, - }); - }); - - it('should handle BID_WON properly and serialize bid price related fields', function() { - const result = ucfunnelAnalyticsAdapter.serializeBidResponse(receivedBids[0], BIDDER_STATUS.BID_WON); - - expect(result).to.include({ - prebidWon: true, - isTimeout: false, - status: BIDDER_STATUS.BID_WON, - time: 72, - cpm: 0.1, - currency: 'USD', - }); - }); - - it('should handle TIMEOUT properly and set status to timeout and isTimeout to true', function() { - const result = ucfunnelAnalyticsAdapter.serializeBidResponse(noBids[0], BIDDER_STATUS.TIMEOUT); - - expect(result).to.include({ - prebidWon: false, - isTimeout: true, - status: BIDDER_STATUS.TIMEOUT, - }); - }); - }); - - describe('#addBidResponseToMessage()', function() { - it('should add a bid response in the output message, grouped by adunit_id and bidder', function() { - const message = { - adUnits: {} - }; - ucfunnelAnalyticsAdapter.addBidResponseToMessage(message, noBids[0], BIDDER_STATUS.NO_BID); - - expect(message.adUnits).to.deep.include({ - 'adunit_2': { - 'ucfunnel': { - prebidWon: false, - isTimeout: false, - status: BIDDER_STATUS.NO_BID, - } - } - }); - }); - }); - - describe('#createBidMessage()', function() { - it('should format auction message sent to the backend', function() { - const args = { - auctionId: auctionId, - timestamp: 1234567890, - timeout: 3000, - auctionEnd: 1234567990, - adUnitCodes: ['adunit_1', 'adunit_2'], - bidsReceived: receivedBids, - noBids: noBids - }; - - const result = ucfunnelAnalyticsAdapter.createBidMessage(args, highestCpmBids, timeoutBids); - - assertHavingRequiredMessageFields(result); - expect(result).to.deep.include({ - auctionElapsed: 100, - adUnits: { - 'adunit_1': { - 'ucfunnel': { - prebidWon: true, - isTimeout: false, - status: BIDDER_STATUS.BID, - time: 72, - cpm: 0.1, - currency: 'USD', - }, - 'ucfunnelx': { - prebidWon: false, - isTimeout: false, - status: BIDDER_STATUS.BID, - time: 100, - cpm: 0.08, - currency: 'USD', - } - }, - 'adunit_2': { - // this bid result exists in both bid and noBid arrays and should be treated as bid - 'ucfunnel': { - prebidWon: false, - isTimeout: true, - status: BIDDER_STATUS.TIMEOUT, - } - } - } - }); - }); - }); - - describe('#createImpressionMessage()', function() { - it('should format message sent to the backend with the bid result', function() { - const bid = receivedBids[0]; - const result = ucfunnelAnalyticsAdapter.createImpressionMessage(bid); - - assertHavingRequiredMessageFields(result); - expect(result.adUnits).to.deep.include({ - 'adunit_1': { - 'ucfunnel': { - prebidWon: true, - isTimeout: false, - status: BIDDER_STATUS.BID_WON, - time: 72, - cpm: 0.1, - currency: 'USD', - } - } - }); - }); - }); - - describe('#handleBidTimeout()', function() { - it('should cached the timeout bid as BID_TIMEOUT event was triggered', function() { - ucfunnelAnalyticsAdapter.cachedAuctions['test_timeout_auction_id'] = { 'timeoutBids': [] }; - const args = [{ - auctionId: 'test_timeout_auction_id', - timestamp: 1234567890, - timeout: 3000, - auctionEnd: 1234567990, - bidsReceived: receivedBids, - noBids: noBids - }]; - - ucfunnelAnalyticsAdapter.handleBidTimeout(args); - const result = ucfunnelAnalyticsAdapter.getCachedAuction('test_timeout_auction_id'); - expect(result).to.deep.include({ - timeoutBids: [{ - auctionId: 'test_timeout_auction_id', - timestamp: 1234567890, - timeout: 3000, - auctionEnd: 1234567990, - bidsReceived: receivedBids, - noBids: noBids - }] - }); - }); - }); - describe('#handleBidWon()', function() { - it('should call createImpressionMessage once as BID_WON event was triggered', function() { - sinon.spy(ucfunnelAnalyticsAdapter, 'createImpressionMessage'); - const receivedBids = [ - { - auctionId: auctionId, - adUnitCode: 'adunit_1', - bidder: 'ucfunnel', - bidderCode: 'ucfunnel', - requestId: 'a1b2c3d4', - timeToRespond: 72, - cpm: 0.1, - currency: 'USD', - ad: 'fake ad1' - }, - ] - - ucfunnelAnalyticsAdapter.handleBidWon(receivedBids[0]); - sinon.assert.callCount(ucfunnelAnalyticsAdapter.createImpressionMessage, 1); - ucfunnelAnalyticsAdapter.createImpressionMessage.restore(); - }); - }); - }); - }); - - describe('ucfunnel Analytics Adapter track handler ', function () { - const configOptions = { - pbuid: pbuid, - adid: adid, - sampling: 1, - }; - - beforeEach(function () { - sinon.stub(events, 'getEvents').returns([]); - ucfunnelAnalyticsAdapter.enableAnalytics({ - provider: 'ucfunnelAnalytics', - options: configOptions - }); - }); - - afterEach(function () { - ucfunnelAnalyticsAdapter.disableAnalytics(); - events.getEvents.restore(); - }); - - it('should call handleBidWon as BID_WON trigger event', function() { - sinon.spy(ucfunnelAnalyticsAdapter, 'handleBidWon'); - events.emit(constants.EVENTS.BID_WON, {}); - sinon.assert.callCount(ucfunnelAnalyticsAdapter.handleBidWon, 1); - ucfunnelAnalyticsAdapter.handleBidWon.restore(); - }); - - it('should call handleBidTimeout as BID_TIMEOUT trigger event', function() { - sinon.spy(ucfunnelAnalyticsAdapter, 'handleBidTimeout'); - events.emit(constants.EVENTS.BID_TIMEOUT, {}); - sinon.assert.callCount(ucfunnelAnalyticsAdapter.handleBidTimeout, 1); - ucfunnelAnalyticsAdapter.handleBidTimeout.restore(); - }); - - it('should call handleAuctionEnd as AUCTION_END trigger event', function() { - sinon.spy(ucfunnelAnalyticsAdapter, 'handleAuctionEnd'); - events.emit(constants.EVENTS.AUCTION_END, {}); - sinon.assert.callCount(ucfunnelAnalyticsAdapter.handleAuctionEnd, 1); - ucfunnelAnalyticsAdapter.handleAuctionEnd.restore(); - }); - }); - - describe('enableAnalytics and config parser', function () { - const configOptions = { - pbuid: pbuid, - adid: adid, - sampling: 0, - }; - - beforeEach(function () { - ucfunnelAnalyticsAdapter.enableAnalytics({ - provider: 'ucfunnelAnalytics', - options: configOptions - }); - }); - - afterEach(function () { - ucfunnelAnalyticsAdapter.disableAnalytics(); - }); - - it('should parse config correctly with optional values', function () { - expect(ucfunnelAnalyticsAdapter.getAnalyticsOptions().options).to.deep.equal(configOptions); - expect(ucfunnelAnalyticsAdapter.getAnalyticsOptions().pbuid).to.equal(configOptions.pbuid); - expect(ucfunnelAnalyticsAdapter.getAnalyticsOptions().adid).to.equal(configOptions.adid); - expect(ucfunnelAnalyticsAdapter.getAnalyticsOptions().sampled).to.equal(false); - }); - - it('should not enable Analytics when adid is missing', function () { - const configOptions = { - options: { - pbuid: pbuid - } - }; - const validConfig = ucfunnelAnalyticsAdapter.initConfig(configOptions); - expect(validConfig).to.equal(false); - }); - - it('should not enable Analytics when pbuid is missing', function () { - const configOptions = { - options: { - adid: adid - } - }; - const validConfig = ucfunnelAnalyticsAdapter.initConfig(configOptions); - expect(validConfig).to.equal(false); - }); - it('should fall back to default value when sampling factor is not number', function () { - const configOptions = { - options: { - pbuid: pbuid, - adid: adid, - sampling: 'string', - } - }; - ucfunnelAnalyticsAdapter.enableAnalytics({ - provider: 'ucfunnelAnalytics', - options: configOptions - }); - - expect(ucfunnelAnalyticsAdapter.getAnalyticsOptions().sampled).to.equal(false); - }); - }); -}); diff --git a/test/spec/modules/ucfunnelBidAdapter_spec.js b/test/spec/modules/ucfunnelBidAdapter_spec.js deleted file mode 100644 index bee420f40d4..00000000000 --- a/test/spec/modules/ucfunnelBidAdapter_spec.js +++ /dev/null @@ -1,295 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/ucfunnelBidAdapter.js'; -import {BANNER, VIDEO, NATIVE} from 'src/mediaTypes.js'; -const URL = 'https://hb.aralego.com/header'; -const BIDDER_CODE = 'ucfunnel'; - -const bidderRequest = { - uspConsent: '1YNN' -}; - -const userId = { - 'criteoId': 'vYlICF9oREZlTHBGRVdrJTJCUUJnc3U2ckNVaXhrV1JWVUZVSUxzZmJlcnJZR0ZxbVhFRnU5bDAlMkJaUWwxWTlNcmdEeHFrJTJGajBWVlV4T3lFQ0FyRVcxNyUyQlIxa0lLSlFhcWJpTm9PSkdPVkx0JTJCbzlQRTQlM0Q', - 'id5id': {'uid': 'ID5-8ekgswyBTQqnkEKy0ErmeQ1GN5wV4pSmA-RE4eRedA'}, - 'netId': 'fH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg', - 'parrableId': {'eid': '01.1608624401.fe44bca9b96873084a0d4e9d0ac5729f13790ba8f8e58fa4707b6b3c096df91c6b5f254992bdad4ab1dd4a89919081e9b877d7a039ac3183709277665bac124f28e277d109f0ff965058'}, - 'pubcid': 'd8aa10fa-d86c-451d-aad8-5f16162a9e64', - 'sharedid': {'id': '01ESHXW4HD29KMF387T63JQ9H5', 'third': '01ESHXW4HD29KMF387T63JQ9H5'}, - 'tdid': 'D6885E90-2A7A-4E0F-87CB-7734ED1B99A3', - 'haloId': {}, - 'uid2': {'id': 'eb33b0cb-8d35-4722-b9c0-1a31d4064888'}, - 'flocId': {'id': '12144', 'version': 'chrome.1.1'}, - 'connectid': '4567' -} - -const validBannerBidReq = { - bidder: BIDDER_CODE, - params: { - adid: 'ad-34BBD2AA24B678BBFD4E7B9EE3B872D', - bidfloor: 1.0 - }, - sizes: [[300, 250]], - bidId: '263be71e91dd9d', - auctionId: '9ad1fa8d-2297-4660-a018-b39945054746', - userId: userId, - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'exchange1.com', - 'sid': '1234', - 'hp': 1, - 'rid': 'bid-request-1', - 'name': 'publisher', - 'domain': 'publisher.com' - } - ] - } -}; - -const invalidBannerBidReq = { - bidder: BIDDER_CODE, - params: { - adid: 123456789 - }, - sizes: [[300, 250]], - bidId: '263be71e91dd9d', - auctionId: '9ad1fa8d-2297-4660-a018-b39945054746' -}; - -const validBannerBidRes = { - creative_type: BANNER, - ad_id: 'ad-34BBD2AA24B678BBFD4E7B9EE3B872D', - adm: '
', - cpm: 1.01, - height: 250, - width: 300, - crid: 'test-crid' -}; - -const invalidBannerBidRes = ''; - -const validVideoBidReq = { - bidder: BIDDER_CODE, - params: { - adid: 'ad-9A22D466494297EAC443D967B2622DA9' - }, - sizes: [[640, 360]], - bidId: '263be71e91dd9f', - auctionId: '9ad1fa8d-2297-4660-a018-b39945054746', -}; - -const validVideoBidRes = { - creative_type: VIDEO, - ad_id: 'ad-9A22D466494297EAC443D967B2622DA9', - vastUrl: 'https://ads.aralego.com/ads/58f9749f-0553-4993-8d9a-013a38b29e55', - vastXml: 'ucX I-Primo 00:00:30', - cpm: 1.01, - width: 640, - height: 360 -}; - -const validNativeBidReq = { - bidder: BIDDER_CODE, - params: { - adid: 'ad-627736446B2BD3A60E8AEABDB7BD833E' - }, - sizes: [[1, 1]], - bidId: '263be71e91dda0', - auctionId: '9ad1fa8d-2297-4660-a018-b39945054746', -}; - -const validNativeBidRes = { - creative_type: NATIVE, - ad_id: 'ad-9A22D466494297EAC443D967B2622DA9', - native: { - title: 'ucfunnel adExchange', - body: 'We monetize your traffic via historic data driven protocol', - cta: 'Learn more', - sponsoredBy: 'ucfunnel Co., Ltd.', - image: { - url: 'https://cdn.aralego.net/img/main/AdGent-1200x627.jpg', - width: 1200, - height: 627 - }, - icon: { - url: 'https://cdn.aralego.net/img/logo/logo-84x84.jpg', - widt: 84, - heigh: 84 - }, - clickUrl: 'https://www.ucfunnel.com', - clicktrackers: ['https://dev-ad-track.aralego.com/v1/nat/click?iid=72165d02-408a-470c-bb52-ae7d7b0a4549'], - impressionTrackers: ['https://www.aralego.net/imp?mf=native&adid=ad-9A22D466494297EAC443D967B2622DA9&auc=9ad1fa8d-2297-4660-a018-b39945054746'], - }, - cpm: 1.01, - height: 1, - width: 1 -}; - -const gdprConsent = { - consentString: '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', - vendorData: {}, - gdprApplies: true, - apiVersion: 2 -}; - -describe('ucfunnel Adapter', function () { - describe('request', function () { - it('should validate bid request', function () { - expect(spec.isBidRequestValid(validBannerBidReq)).to.equal(true); - }); - it('should not validate incorrect bid request', function () { - expect(spec.isBidRequestValid(invalidBannerBidReq)).to.equal(false); - }); - }); - describe('build request', function () { - const request = spec.buildRequests([validBannerBidReq], bidderRequest); - it('should create a POST request for every bid', function () { - expect(request[0].method).to.equal('GET'); - expect(request[0].url).to.equal(spec.ENDPOINT); - }); - - it('should attach the bid request object', function () { - expect(request[0].bidRequest).to.equal(validBannerBidReq); - }); - - it('should attach request data', function () { - const data = request[0].data; - 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); - expect(data.h).to.equal(height); - expect(data.eids).to.equal('uid2,eb33b0cb-8d35-4722-b9c0-1a31d4064888!verizonMediaId,4567'); - expect(data.cid).to.equal('12144'); - expect(data.schain).to.equal('1.0,1!exchange1.com,1234,1,bid-request-1,publisher,publisher.com'); - }); - - it('must parse bid size from a nested array', function () { - const width = 640; - const height = 480; - validBannerBidReq.sizes = [[ width, height ]]; - const requests = spec.buildRequests([ validBannerBidReq ]); - const data = requests[0].data; - expect(data.w).to.equal(width); - expect(data.h).to.equal(height); - }); - }); - - describe('interpretResponse', function () { - describe('should support banner', function () { - const request = spec.buildRequests([ validBannerBidReq ]); - const result = spec.interpretResponse({body: validBannerBidRes}, request[0]); - it('should build bid array for banner', function () { - expect(result.length).to.equal(1); - }); - - it('should have all relevant fields', function () { - const bid = result[0]; - - expect(bid.mediaType).to.equal(BANNER); - expect(bid.ad).to.exist; - expect(bid.requestId).to.equal('263be71e91dd9d'); - expect(bid.cpm).to.equal(1.01); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - }); - }); - - describe('handle banner no ad', function () { - const request = spec.buildRequests([ validBannerBidReq ]); - const result = spec.interpretResponse({body: invalidBannerBidRes}, request[0]); - it('should build bid array for banner', function () { - expect(result.length).to.equal(1); - }); - - it('should have all relevant fields', function () { - const bid = result[0]; - - expect(bid.ad).to.exist; - expect(bid.requestId).to.equal('263be71e91dd9d'); - expect(bid.cpm).to.equal(0); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - }); - }); - - describe('handle banner cpm under bidfloor', function () { - const request = spec.buildRequests([ validBannerBidReq ]); - const result = spec.interpretResponse({body: invalidBannerBidRes}, request[0]); - it('should build bid array for banner', function () { - expect(result.length).to.equal(1); - }); - - it('should have all relevant fields', function () { - const bid = result[0]; - - expect(bid.ad).to.exist; - expect(bid.requestId).to.equal('263be71e91dd9d'); - expect(bid.cpm).to.equal(0); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - }); - }); - - describe('should support video', function () { - const request = spec.buildRequests([ validVideoBidReq ]); - const result = spec.interpretResponse({body: validVideoBidRes}, request[0]); - it('should build bid array', function () { - expect(result.length).to.equal(1); - }); - - it('should have all relevant fields', function () { - const bid = result[0]; - - expect(bid.mediaType).to.equal(VIDEO); - expect(bid.vastUrl).to.exist; - expect(bid.vastXml).to.exist; - expect(bid.requestId).to.equal('263be71e91dd9f'); - expect(bid.cpm).to.equal(1.01); - expect(bid.width).to.equal(640); - expect(bid.height).to.equal(360); - }); - }); - - describe('should support native', function () { - const request = spec.buildRequests([ validNativeBidReq ]); - const result = spec.interpretResponse({body: validNativeBidRes}, request[0]); - it('should build bid array', function () { - expect(result.length).to.equal(1); - }); - - it('should have all relevant fields', function () { - const bid = result[0]; - - expect(bid.mediaType).to.equal(NATIVE); - expect(bid.native).to.exist; - expect(bid.requestId).to.equal('263be71e91dda0'); - expect(bid.cpm).to.equal(1.01); - expect(bid.width).to.equal(1); - expect(bid.height).to.equal(1); - expect(bid.native.clickUrl).to.equal('https://www.ucfunnel.com'); - expect(bid.native.clickTrackers[0]).to.equal('https://dev-ad-track.aralego.com/v1/nat/click?iid=72165d02-408a-470c-bb52-ae7d7b0a4549'); - }); - }); - }); - - describe('cookie sync', function () { - describe('cookie sync iframe', function () { - const result = spec.getUserSyncs({'iframeEnabled': true}, null, gdprConsent); - - it('should return cookie sync iframe info', function () { - expect(result[0].type).to.equal('iframe'); - expect(result[0].url).to.equal('https://cdn.aralego.net/ucfad/cookie/sync.html?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&'); - }); - }); - describe('cookie sync image', function () { - 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/underdogmediaBidAdapter_spec.js b/test/spec/modules/underdogmediaBidAdapter_spec.js deleted file mode 100644 index aeb9f56c851..00000000000 --- a/test/spec/modules/underdogmediaBidAdapter_spec.js +++ /dev/null @@ -1,485 +0,0 @@ -import { expect } from 'chai'; -import { spec, resetUserSync } from 'modules/underdogmediaBidAdapter.js'; - -describe('UnderdogMedia adapter', function () { - let bidRequests; - let bidderRequest; - - beforeEach(function () { - bidRequests = [ - { - bidder: 'underdogmedia', - params: { - siteId: 12143 - }, - adUnitCode: '/19968336/header-bid-tag-1', - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600], [728, 90], [160, 600], [320, 50]], - } - }, - bidId: '23acc48ad47af5', - auctionId: '0fb4905b-9456-4152-86be-c6f6d259ba99', - bidderRequestId: '1c56ad30b9b8ca8', - transactionId: '92489f71-1bf2-49a0-adf9-000cea934729' - } - ]; - - bidderRequest = { - timeout: 3000, - gdprConsent: { - gdprApplies: 1, - consentString: 'consentDataString', - vendorData: { - vendorConsents: { - '159': 1 - }, - }, - }, - } - }); - - describe('implementation', function () { - describe('for requests', function () { - it('should accept valid bid', function () { - let validBid = { - bidder: 'underdogmedia', - params: { - siteId: '12143' - }, - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - } - }; - const isValid = spec.isBidRequestValid(validBid); - - expect(isValid).to.equal(true); - }); - - it('should reject invalid bid missing sizes', function () { - let invalidBid = { - bidder: 'underdogmedia', - params: { - siteId: '12143', - } - }; - const isValid = spec.isBidRequestValid(invalidBid); - - expect(isValid).to.equal(false); - }); - - it('should reject invalid bid missing siteId', function () { - let invalidBid = { - bidder: 'underdogmedia', - params: {}, - mediaTypes: { - banner: { - sizes: [[300, 250], [300, 600]] - } - } - }; - const isValid = spec.isBidRequestValid(invalidBid); - - expect(isValid).to.equal(false); - }); - - it('request data should contain sid', function () { - let bidRequests = [ - { - bidId: '3c9408cdbf2f68', - bidder: 'underdogmedia', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - params: { - siteId: '12143' - }, - auctionId: '10b327aa396609', - adUnitCode: '/123456/header-bid-tag-1' - } - ]; - const request = spec.buildRequests(bidRequests, bidderRequest); - - expect(request.data.sid).to.equal('12143'); - }); - - it('request data should contain sizes', function () { - let bidRequests = [ - { - bidId: '3c9408cdbf2f68', - mediaTypes: { - banner: { - sizes: [[300, 250], [728, 90]] - } - }, - bidder: 'underdogmedia', - params: { - siteId: '12143' - }, - auctionId: '10b327aa396609', - adUnitCode: '/123456/header-bid-tag-1' - } - ]; - const request = spec.buildRequests(bidRequests, bidderRequest); - - expect(request.data.sizes).to.equal('300x250,728x90'); - }); - - it('request data should contain gdpr info', function () { - let bidRequests = [ - { - bidId: '3c9408cdbf2f68', - mediaTypes: { - banner: { - sizes: [[300, 250], [728, 90]] - } - }, - bidder: 'underdogmedia', - params: { - siteId: '12143' - }, - auctionId: '10b327aa396609', - adUnitCode: '/123456/header-bid-tag-1' - } - ]; - const request = spec.buildRequests(bidRequests, bidderRequest); - - expect(request.data.gdprApplies).to.equal(true); - expect(request.data.consentGiven).to.equal(true); - expect(request.data.consentData).to.equal('consentDataString'); - }); - - it('should not build a request if no vendorConsent', function () { - let bidRequests = [ - { - bidId: '3c9408cdbf2f68', - mediaTypes: { - banner: { - sizes: [[300, 250], [728, 90]] - } - }, - bidder: 'underdogmedia', - params: { - siteId: '12143' - }, - auctionId: '10b327aa396609', - adUnitCode: '/123456/header-bid-tag-1' - } - ]; - - let bidderRequest = { - timeout: 3000, - gdprConsent: { - gdprApplies: 1, - consentString: 'consentDataString', - vendorData: { - vendorConsents: { - '159': 0 - }, - }, - }, - } - const request = spec.buildRequests(bidRequests, bidderRequest); - - expect(request).to.equal(undefined); - }); - - it('should properly build a request if no vendorConsent but no gdprApplies', function () { - let bidRequests = [ - { - bidId: '3c9408cdbf2f68', - mediaTypes: { - banner: { - sizes: [[300, 250], [728, 90]] - } - }, - bidder: 'underdogmedia', - params: { - siteId: '12143' - }, - auctionId: '10b327aa396609', - adUnitCode: '/123456/header-bid-tag-1' - } - ]; - - let bidderRequest = { - timeout: 3000, - gdprConsent: { - gdprApplies: 0, - consentString: 'consentDataString', - vendorData: { - vendorConsents: { - '159': 0 - }, - }, - }, - } - const request = spec.buildRequests(bidRequests, bidderRequest); - - expect(request.data.sizes).to.equal('300x250,728x90'); - expect(request.data.sid).to.equal('12143'); - expect(request.data.gdprApplies).to.equal(false); - expect(request.data.consentGiven).to.equal(false); - expect(request.data.consentData).to.equal('consentDataString'); - }); - - it('should properly build a request if gdprConsent empty', function () { - let bidRequests = [ - { - bidId: '3c9408cdbf2f68', - mediaTypes: { - banner: { - sizes: [[300, 250], [728, 90]] - } - }, - bidder: 'underdogmedia', - params: { - siteId: '12143' - }, - auctionId: '10b327aa396609', - adUnitCode: '/123456/header-bid-tag-1' - } - ]; - - let bidderRequest = { - timeout: 3000, - gdprConsent: {} - } - const request = spec.buildRequests(bidRequests, bidderRequest); - - expect(request.data.sizes).to.equal('300x250,728x90'); - expect(request.data.sid).to.equal('12143'); - }); - - it('should have uspConsent if defined', function () { - const uspConsent = '1YYN' - bidderRequest.uspConsent = uspConsent - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.uspConsent).to.equal(uspConsent); - }); - - it('should not have uspConsent if not defined', function () { - bidderRequest.uspConsent = undefined - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.data.uspConsent).to.be.undefined; - }); - }); - - describe('bid responses', function () { - it('should return complete bid response', function () { - let serverResponse = { - body: { - mids: [ - { - ad_code_html: 'ad_code_html', - cpm: 2.5, - height: '600', - mid: '32634', - notification_url: 'notification_url', - tid: '4', - width: '160' - }, - { - ad_code_html: 'ad_code_html', - cpm: 2.5, - height: '250', - mid: '32633', - notification_url: 'notification_url', - tid: '2', - width: '300' - }, - ] - } - }; - const request = spec.buildRequests(bidRequests, bidderRequest); - const bids = spec.interpretResponse(serverResponse, request); - - expect(bids).to.be.lengthOf(2); - - expect(bids[0].bidderCode).to.equal('underdogmedia'); - expect(bids[0].cpm).to.equal(2.5); - expect(bids[0].width).to.equal('160'); - expect(bids[0].height).to.equal('600'); - expect(bids[0].ad).to.have.length.above(1); - expect(bids[0].creativeId).to.equal('32634'); - expect(bids[0].currency).to.equal('USD'); - }); - - it('should return empty bid response if mids empty', function () { - let serverResponse = { - body: { - mids: [] - } - }; - const request = spec.buildRequests(bidRequests, bidderRequest); - const bids = spec.interpretResponse(serverResponse, request); - - expect(bids).to.be.lengthOf(0); - }); - - it('should return empty bid response on incorrect size', function () { - let serverResponse = { - body: { - mids: [ - { - ad_code_html: 'ad_code_html', - cpm: 2.5, - height: '123', - mid: '32634', - notification_url: 'notification_url', - tid: '4', - width: '160' - } - ] - } - }; - const request = spec.buildRequests(bidRequests, bidderRequest); - const bids = spec.interpretResponse(serverResponse, request); - - expect(bids).to.be.lengthOf(0); - }); - - it('should return empty bid response on 0 cpm', function () { - let serverResponse = { - body: { - mids: [ - { - ad_code_html: 'ad_code_html', - cpm: 0, - height: '600', - mid: '32634', - notification_url: 'notification_url', - tid: '4', - width: '160' - } - ] - } - }; - const request = spec.buildRequests(bidRequests, bidderRequest); - const bids = spec.interpretResponse(serverResponse, request); - - expect(bids).to.be.lengthOf(0); - }); - - it('should return empty bid response if no ad in response', function () { - let serverResponse = { - body: { - mids: [ - { - ad_code_html: '', - cpm: 2.5, - height: '600', - mid: '32634', - notification_url: 'notification_url', - tid: '4', - width: '160' - } - ] - } - }; - const request = spec.buildRequests(bidRequests, bidderRequest); - const bids = spec.interpretResponse(serverResponse, request); - - expect(bids).to.be.lengthOf(0); - }); - - it('ad html string should contain the notification urls', function () { - let serverResponse = { - body: { - mids: [ - { - ad_code_html: 'ad_cod_html', - cpm: 2.5, - height: '600', - mid: '32634', - notification_url: 'notification_url', - tid: '4', - width: '160' - } - ] - } - }; - const request = spec.buildRequests(bidRequests, bidderRequest); - const bids = spec.interpretResponse(serverResponse, request); - - expect(bids[0].ad).to.have.string('notification_url'); - expect(bids[0].ad).to.have.string(';style=adapter'); - }); - }); - }); - - describe('getUserSyncs', function () { - const syncOptionsPixelOnly = { - 'pixelEnabled': true - }; - - const syncOptionsIframeOnly = { - 'iframeEnabled': true - }; - - const syncOptionsPixelAndIframe = { - 'pixelEnabled': true, - 'iframeEnabled': true - }; - - const responseWithUserSyncs = [{ - body: { - userSyncs: [ - { - type: 'image', - url: 'https://test.url.com' - }, - { - type: 'iframe', - url: 'https://test.url.com' - } - ] - } - }]; - - const responseWithEmptyUserSyncs = [{ - body: { - userSyncs: [] - } - }]; - - it('user syncs should only return what is allowed', function () { - const result = spec.getUserSyncs(syncOptionsPixelOnly, responseWithUserSyncs); - expect(result[0].type).to.equal('image'); - expect(result.length).to.equal(1); - }); - - it('user syncs should only load once per user', function () { - const result = spec.getUserSyncs(syncOptionsPixelAndIframe, responseWithUserSyncs); - expect(result).to.equal(undefined); - }); - - it('user syncs should return undefined when empty', function () { - resetUserSync(); - - const result = spec.getUserSyncs(syncOptionsPixelAndIframe, responseWithEmptyUserSyncs); - expect(result).to.equal(undefined); - }); - - it('should reset USER_SYNCED flag, allowing another sync', function () { - resetUserSync(); - - const result = spec.getUserSyncs(syncOptionsIframeOnly, responseWithUserSyncs); - expect(result[0].type).to.equal('iframe'); - expect(result.length).to.equal(1); - }); - - it('should return all enabled syncs', function () { - resetUserSync(); - - const result = spec.getUserSyncs(syncOptionsPixelAndIframe, responseWithUserSyncs); - expect(result[0].type).to.equal('image'); - expect(result[1].type).to.equal('iframe'); - expect(result.length).to.equal(2); - }); - }); -}); diff --git a/test/spec/modules/undertoneBidAdapter_spec.js b/test/spec/modules/undertoneBidAdapter_spec.js deleted file mode 100644 index 0faa321be5f..00000000000 --- a/test/spec/modules/undertoneBidAdapter_spec.js +++ /dev/null @@ -1,486 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/undertoneBidAdapter.js'; - -const URL = 'https://hb.undertone.com/hb'; -const BIDDER_CODE = 'undertone'; -const validBidReq = { - bidder: BIDDER_CODE, - params: { - placementId: '10433394', - publisherId: 12345 - }, - sizes: [[300, 250], [300, 600]], - bidId: '263be71e91dd9d', - auctionId: '9ad1fa8d-2297-4660-a018-b39945054747', -}; - -const invalidBidReq = { - bidder: BIDDER_CODE, - params: { - placementId: '123456789' - }, - sizes: [[300, 250], [300, 600]], - bidId: '263be71e91dd9d', - auctionId: '9ad1fa8d-2297-4660-a018-b39945054746' -}; - -const videoBidReq = [{ - adUnitCode: 'div-gpt-ad-1460505748561-0', - bidder: BIDDER_CODE, - params: { - placementId: '10433394', - publisherId: 12345, - video: { - id: 123, - skippable: true, - playbackMethod: 2, - maxDuration: 30 - } - }, - mediaTypes: {video: { - context: 'outstream', - playerSize: [640, 480] - }}, - sizes: [[300, 250], [300, 600]], - bidId: '263be71e91dd9d', - auctionId: '9ad1fa8d-2297-4660-a018-b39945054746' -}, -{ - adUnitCode: 'div-gpt-ad-1460505748561-1', - bidder: BIDDER_CODE, - params: { - placementId: '10433395', - publisherId: 12345 - }, - mediaTypes: {video: { - context: 'outstream', - playerSize: [640, 480] - }}, - sizes: [[300, 250], [300, 600]], - bidId: '263be71e91dd9d', - auctionId: '9ad1fa8d-2297-4660-a018-b39945054746' -}]; -const bidReq = [{ - adUnitCode: 'div-gpt-ad-1460505748561-0', - bidder: BIDDER_CODE, - params: { - placementId: '10433394', - publisherId: 12345, - }, - sizes: [[300, 250], [300, 600]], - bidId: '263be71e91dd9d', - auctionId: '9ad1fa8d-2297-4660-a018-b39945054746' -}, -{ - adUnitCode: 'div-gpt-ad-1460505748561-0', - bidder: BIDDER_CODE, - params: { - publisherId: 12345 - }, - sizes: [[1, 1]], - bidId: '453cf42d72bb3c', - auctionId: '6c22f5a5-59df-4dc6-b92c-f433bcf0a874' -}]; - -const bidReqUserIds = [{ - bidder: BIDDER_CODE, - params: { - placementId: '10433394', - publisherId: 12345 - }, - sizes: [[300, 250], [300, 600]], - bidId: '263be71e91dd9d', - auctionId: '9ad1fa8d-2297-4660-a018-b39945054746', - userId: { - idl_env: '1111', - tdid: '123456', - digitrustid: {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}}, - id5id: { uid: '1111' } - } -}, -{ - bidder: BIDDER_CODE, - params: { - publisherId: 12345 - }, - sizes: [[1, 1]], - bidId: '453cf42d72bb3c', - auctionId: '6c22f5a5-59df-4dc6-b92c-f433bcf0a874' -}]; - -const bidderReq = { - refererInfo: { - referer: 'http://prebid.org/dev-docs/bidder-adaptor.html' - } -}; - -const bidderReqGdpr = { - refererInfo: { - referer: 'http://prebid.org/dev-docs/bidder-adaptor.html' - }, - gdprConsent: { - gdprApplies: true, - consentString: 'acdefgh' - } -}; - -const bidderReqCcpa = { - refererInfo: { - referer: 'http://prebid.org/dev-docs/bidder-adaptor.html' - }, - uspConsent: 'NY12' -}; - -const bidderReqCcpaAndGdpr = { - refererInfo: { - referer: 'http://prebid.org/dev-docs/bidder-adaptor.html' - }, - gdprConsent: { - gdprApplies: true, - consentString: 'acdefgh' - }, - uspConsent: 'NY12' -}; - -const validBidRes = { - ad: '
Hello
', - publisherId: 12345, - bidRequestId: '263be71e91dd9d', - adId: 15, - cpm: 100, - nCampaignId: 2, - creativeId: '123abc', - currency: 'USD', - netRevenue: true, - width: 300, - height: 250, - ttl: 360 -}; - -const bidResponse = [validBidRes]; - -const bidResArray = [ - validBidRes, - { - ad: '', - bidRequestId: '263be71e91dd9d', - cpm: 100, - adId: '123abc', - currency: 'USD', - netRevenue: true, - width: 300, - height: 250, - ttl: 360 - }, - { - ad: '
Hello
', - bidRequestId: '', - cpm: 0, - adId: '123abc', - currency: 'USD', - netRevenue: true, - width: 300, - height: 250, - ttl: 360 - } -]; -const bidVideoResponse = [ - { - ad: '', - bidRequestId: '263be71e91dd9d', - cpm: 100, - adId: '123abc', - currency: 'USD', - mediaType: 'video', - netRevenue: true, - width: 300, - height: 250, - ttl: 360 - } -]; - -let element; -let sandbox; - -let elementParent = { - offsetLeft: 100, - offsetTop: 100, - offsetHeight: 100, - getAttribute: function() {} -}; - -describe('Undertone Adapter', () => { - describe('request', () => { - it('should validate bid request', () => { - expect(spec.isBidRequestValid(validBidReq)).to.equal(true); - }); - it('should not validate incorrect bid request', () => { - expect(spec.isBidRequestValid(invalidBidReq)).to.equal(undefined); - }); - }); - describe('build request', function () { - beforeEach(function() { - element = { - id: 'div-gpt-ad-1460505748561-0', - offsetLeft: 100, - offsetTop: 100, - offsetWidth: 300, - offsetHeight: 250 - }; - - sandbox = sinon.sandbox.create(); - sandbox.stub(document, 'getElementById').withArgs('div-gpt-ad-1460505748561-0').returns(element); - }); - - afterEach(function() { - sandbox.restore(); - }); - - it('should send request to correct url via POST not in GDPR or CCPA', function () { - const request = spec.buildRequests(bidReq, bidderReq); - const domainStart = bidderReq.refererInfo.referer.indexOf('//'); - const domainEnd = bidderReq.refererInfo.referer.indexOf('/', domainStart + 2); - const domain = bidderReq.refererInfo.referer.substring(domainStart + 2, domainEnd); - const REQ_URL = `${URL}?pid=${bidReq[0].params.publisherId}&domain=${domain}`; - expect(request.url).to.equal(REQ_URL); - expect(request.method).to.equal('POST'); - }); - it('should send request to correct url via POST when in GDPR', function () { - const request = spec.buildRequests(bidReq, bidderReqGdpr); - const domainStart = bidderReq.refererInfo.referer.indexOf('//'); - const domainEnd = bidderReq.refererInfo.referer.indexOf('/', domainStart + 2); - const domain = bidderReq.refererInfo.referer.substring(domainStart + 2, domainEnd); - let gdpr = bidderReqGdpr.gdprConsent.gdprApplies ? 1 : 0; - const REQ_URL = `${URL}?pid=${bidReq[0].params.publisherId}&domain=${domain}&gdpr=${gdpr}&gdprstr=${bidderReqGdpr.gdprConsent.consentString}`; - expect(request.url).to.equal(REQ_URL); - expect(request.method).to.equal('POST'); - }); - it('should send request to correct url via POST when in CCPA', function () { - const request = spec.buildRequests(bidReq, bidderReqCcpa); - const domainStart = bidderReq.refererInfo.referer.indexOf('//'); - const domainEnd = bidderReq.refererInfo.referer.indexOf('/', domainStart + 2); - const domain = bidderReq.refererInfo.referer.substring(domainStart + 2, domainEnd); - let ccpa = bidderReqCcpa.uspConsent; - const REQ_URL = `${URL}?pid=${bidReq[0].params.publisherId}&domain=${domain}&ccpa=${ccpa}`; - expect(request.url).to.equal(REQ_URL); - expect(request.method).to.equal('POST'); - }); - it('should send request to correct url via POST when in GDPR and CCPA', function () { - const request = spec.buildRequests(bidReq, bidderReqCcpaAndGdpr); - const domainStart = bidderReq.refererInfo.referer.indexOf('//'); - const domainEnd = bidderReq.refererInfo.referer.indexOf('/', domainStart + 2); - const domain = bidderReq.refererInfo.referer.substring(domainStart + 2, domainEnd); - let ccpa = bidderReqCcpaAndGdpr.uspConsent; - let gdpr = bidderReqCcpaAndGdpr.gdprConsent.gdprApplies ? 1 : 0; - const REQ_URL = `${URL}?pid=${bidReq[0].params.publisherId}&domain=${domain}&gdpr=${gdpr}&gdprstr=${bidderReqGdpr.gdprConsent.consentString}&ccpa=${ccpa}`; - expect(request.url).to.equal(REQ_URL); - expect(request.method).to.equal('POST'); - }); - it('should have all relevant fields', function () { - const request = spec.buildRequests(bidReq, bidderReq); - const bid1 = JSON.parse(request.data)['x-ut-hb-params'][0]; - expect(bid1.bidRequestId).to.equal('263be71e91dd9d'); - expect(bid1.sizes.length).to.equal(2); - expect(bid1.placementId).to.equal('10433394'); - expect(bid1.publisherId).to.equal(12345); - expect(bid1.coordinates).to.be.an('array'); - expect(bid1.params).to.be.an('object'); - const bid2 = JSON.parse(request.data)['x-ut-hb-params'][1]; - expect(bid2.bidRequestId).to.equal('453cf42d72bb3c'); - expect(bid2.sizes.length).to.equal(1); - expect(bid2.placementId === null).to.equal(true); - expect(bid2.publisherId).to.equal(12345); - expect(bid2.params).to.be.an('object'); - }); - it('should send video fields correctly', function () { - const request = spec.buildRequests(videoBidReq, bidderReq); - const bidVideo = JSON.parse(request.data)['x-ut-hb-params'][0]; - const bidVideo2 = JSON.parse(request.data)['x-ut-hb-params'][1]; - - expect(bidVideo.mediaType).to.equal('video'); - expect(bidVideo.video).to.be.an('object'); - expect(bidVideo.video.playerSize).to.be.an('array'); - expect(bidVideo.video.streamType).to.equal('outstream'); - expect(bidVideo.video.playbackMethod).to.equal(2); - expect(bidVideo.video.maxDuration).to.equal(30); - expect(bidVideo.video.skippable).to.equal(true); - - expect(bidVideo2.video.skippable).to.equal(null); - expect(bidVideo2.video.maxDuration).to.equal(null); - expect(bidVideo2.video.playbackMethod).to.equal(null); - }); - it('should send all userIds data to server', function () { - const request = spec.buildRequests(bidReqUserIds, bidderReq); - const bidCommons = JSON.parse(request.data)['commons']; - expect(bidCommons).to.be.an('object'); - expect(bidCommons.uids).to.be.an('object'); - expect(bidCommons.uids.tdid).to.equal('123456'); - expect(bidCommons.uids.idl_env).to.equal('1111'); - expect(bidCommons.uids.digitrustid.data.id).to.equal('DTID'); - expect(bidCommons.uids.id5id.uid).to.equal('1111'); - }); - it('should send page sizes sizes correctly', function () { - const request = spec.buildRequests(bidReqUserIds, bidderReq); - const bidCommons = JSON.parse(request.data)['commons']; - expect(bidCommons).to.be.an('object'); - expect(bidCommons.pageSize).to.be.an('array'); - expect(bidCommons.pageSize[0]).to.equal(window.innerWidth); - expect(bidCommons.pageSize[1]).to.equal(window.innerHeight); - }); - it('should send banner coordinates', function() { - const request = spec.buildRequests(bidReq, bidderReq); - const bid1 = JSON.parse(request.data)['x-ut-hb-params'][0]; - expect(bid1.coordinates).to.be.an('array'); - expect(bid1.coordinates[0]).to.equal(100); - expect(bid1.coordinates[1]).to.equal(100); - }); - it('should send banner coordinates plus parent', function() { - element.offsetParent = elementParent; - const request = spec.buildRequests(bidReq, bidderReq); - const bid1 = JSON.parse(request.data)['x-ut-hb-params'][0]; - expect(bid1.coordinates).to.be.an('array'); - expect(bid1.coordinates[0]).to.equal(200); - expect(bid1.coordinates[1]).to.equal(200); - }); - }); - - describe('interpretResponse', () => { - it('should build bid array', () => { - let result = spec.interpretResponse({body: bidResponse}); - expect(result.length).to.equal(1); - }); - - it('should have all relevant fields', () => { - const result = spec.interpretResponse({body: bidResponse}); - const bid = result[0]; - - expect(bid.requestId).to.equal('263be71e91dd9d'); - expect(bid.cpm).to.equal(100); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.meta.advertiserDomains).to.deep.equal([]); - expect(bid.creativeId).to.equal(15); - expect(bid.currency).to.equal('USD'); - expect(bid.netRevenue).to.equal(true); - expect(bid.ttl).to.equal(360); - }); - - 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); - }); - - it('should only use valid bid responses', () => { - expect(spec.interpretResponse({ body: bidResArray }).length).to.equal(1); - }); - - it('should detect video response', () => { - const videoResult = spec.interpretResponse({body: bidVideoResponse}); - const vbid = videoResult[0]; - - expect(vbid.mediaType).to.equal('video'); - }); - }); - - describe('getUserSyncs', () => { - let testParams = [ - { - name: 'with iframe and no gdpr or ccpa data', - arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, null], - expect: { - type: 'iframe', - pixels: ['https://cdn.undertone.com/js/usersync.html'] - } - }, - { - name: 'with iframe and gdpr on', - arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, {gdprApplies: true, consentString: '234234'}], - expect: { - type: 'iframe', - pixels: ['https://cdn.undertone.com/js/usersync.html?gdpr=1&gdprstr=234234'] - } - }, - { - name: 'with iframe and ccpa on', - arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, null, 'YN12'], - expect: { - type: 'iframe', - pixels: ['https://cdn.undertone.com/js/usersync.html?ccpa=YN12'] - } - }, - { - name: 'with iframe and no gdpr off or ccpa', - arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, {gdprApplies: false}], - expect: { - type: 'iframe', - pixels: ['https://cdn.undertone.com/js/usersync.html?gdpr=0&gdprstr='] - } - }, - { - name: 'with iframe and gdpr and ccpa', - 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'] - } - }, - { - name: 'with pixels and no gdpr or ccpa data', - arguments: [{ pixelEnabled: true }, {}, null], - expect: { - type: 'image', - pixels: ['https://usr.undertone.com/userPixel/syncOne?id=1&of=2', - 'https://usr.undertone.com/userPixel/syncOne?id=2&of=2'] - } - }, - { - name: 'with pixels and gdpr on', - 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', - 'https://usr.undertone.com/userPixel/syncOne?id=2&of=2&gdpr=1&gdprstr=234234'] - } - }, - { - name: 'with pixels and ccpa on', - arguments: [{ pixelEnabled: true }, {}, null, 'YN12'], - expect: { - type: 'image', - pixels: ['https://usr.undertone.com/userPixel/syncOne?id=1&of=2&ccpa=YN12', - 'https://usr.undertone.com/userPixel/syncOne?id=2&of=2&ccpa=YN12'] - } - }, - { - name: 'with pixels and gdpr off', - arguments: [{ pixelEnabled: true }, {}, {gdprApplies: false}], - expect: { - type: 'image', - pixels: ['https://usr.undertone.com/userPixel/syncOne?id=1&of=2&gdpr=0&gdprstr=', - 'https://usr.undertone.com/userPixel/syncOne?id=2&of=2&gdpr=0&gdprstr='] - } - }, - { - name: 'with pixels and gdpr and ccpa on', - 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', - 'https://usr.undertone.com/userPixel/syncOne?id=2&of=2&gdpr=1&gdprstr=234234&ccpa=YN12'] - } - } - ]; - - for (let i = 0; i < testParams.length; i++) { - let currParams = testParams[i]; - it(currParams.name, function () { - const result = spec.getUserSyncs.apply(this, currParams.arguments); - expect(result).to.have.lengthOf(currParams.expect.pixels.length); - for (let ix = 0; ix < currParams.expect.pixels.length; ix++) { - expect(result[ix].url).to.equal(currParams.expect.pixels[ix]); - expect(result[ix].type).to.equal(currParams.expect.type); - } - }); - } - }); -}); diff --git a/test/spec/modules/unicornBidAdapter_spec.js b/test/spec/modules/unicornBidAdapter_spec.js deleted file mode 100644 index dcd446b2bb0..00000000000 --- a/test/spec/modules/unicornBidAdapter_spec.js +++ /dev/null @@ -1,490 +0,0 @@ -import { assert, expect } from 'chai'; -import { spec } from 'modules/unicornBidAdapter.js'; -import * as _ from 'lodash'; - -const bidRequests = [ - { - bidder: 'unicorn', - params: { - bidfloorCpm: 0, - accountId: 12345 - }, - mediaTypes: { - banner: { - sizes: [[300, 250], [336, 280]] - } - }, - adUnitCode: '/19968336/header-bid-tag-0', - transactionId: 'ea0aa332-a6e1-4474-8180-83720e6b87bc', - sizes: [[300, 250], [336, 280]], - bidId: '226416e6e6bf41', - bidderRequestId: '1f41cbdcbe58d5', - auctionId: '77987c3a-9be9-4e43-985a-26fc91d84724', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 - }, - { - bidder: 'unicorn', - params: { - bidfloorCpm: 0, - accountId: 12345 - }, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - transactionId: 'cf801303-cf98-4b4a-9e0a-c27b93bce6d8', - sizes: [[300, 250]], - bidId: '37cdc0b5d0363b', - bidderRequestId: '1f41cbdcbe58d5', - auctionId: '77987c3a-9be9-4e43-985a-26fc91d84724', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 - }, - { - bidder: 'unicorn', - params: { - bidfloorCpm: 0 - }, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - adUnitCode: '/19968336/header-bid-tag-2', - transactionId: 'ba7f114c-3676-4a08-a26d-1ee293d521ed', - sizes: [[300, 250]], - bidId: '468569a6597a4', - bidderRequestId: '1f41cbdcbe58d5', - auctionId: '77987c3a-9be9-4e43-985a-26fc91d84724', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 - } -]; - -const validBidRequests = [ - { - bidder: 'unicorn', - params: { - placementId: 'rectangle-ad-1', - bidfloorCpm: 0, - accountId: 12345, - publisherId: 99999, - mediaId: 'example' - }, - mediaTypes: { - banner: { - sizes: [[300, 250], [336, 280]] - } - }, - adUnitCode: '/19968336/header-bid-tag-0', - transactionId: 'fbf94ccf-f377-4201-a662-32c2feb8ab6d', - sizes: [[300, 250], [336, 280]], - bidId: '2fb90842443e24', - bidderRequestId: '123ae4cc3eeb7e', - auctionId: 'c594a888-6744-46c6-8b0e-d188e40e83ef', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 - }, - { - bidder: 'unicorn', - params: { - bidfloorCpm: 0, - accountId: 12345 - }, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - adUnitCode: '/19968336/header-bid-tag-1', - transactionId: '2d65e313-f8a6-4888-b9ab-50fb3ca744ea', - sizes: [[300, 250]], - bidId: '352f86f158d97a', - bidderRequestId: '123ae4cc3eeb7e', - auctionId: 'c594a888-6744-46c6-8b0e-d188e40e83ef', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 - }, - { - bidder: 'unicorn', - params: { - placementId: 'rectangle-ad-2', - bidfloorCpm: 0, - accountId: 12345 - }, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - adUnitCode: '/19968336/header-bid-tag-2', - transactionId: '82f445a8-44bc-40bc-9913-739b40375566', - sizes: [[300, 250]], - bidId: '4cde82cc90126b', - bidderRequestId: '123ae4cc3eeb7e', - auctionId: 'c594a888-6744-46c6-8b0e-d188e40e83ef', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 - } -]; - -const bidderRequest = { - bidderCode: 'unicorn', - auctionId: 'c594a888-6744-46c6-8b0e-d188e40e83ef', - bidderRequestId: '123ae4cc3eeb7e', - bids: [ - { - bidder: 'unicorn', - params: { - placementId: 'rectangle-ad-1', - bidfloorCpm: 0, - accountId: 12345 - }, - mediaTypes: { - banner: { - sizes: [[300, 250], [336, 280]] - } - }, - adUnitCode: '/19968336/header-bid-tag-0', - transactionId: 'fbf94ccf-f377-4201-a662-32c2feb8ab6d', - sizes: [[300, 250], [336, 280]], - bidId: '2fb90842443e24', - bidderRequestId: '123ae4cc3eeb7e', - auctionId: 'c594a888-6744-46c6-8b0e-d188e40e83ef', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 - }, - { - bidder: 'unicorn', - params: { - bidfloorCpm: 0, - accountId: 12345 - }, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - adUnitCode: '/19968336/header-bid-tag-1', - transactionId: '2d65e313-f8a6-4888-b9ab-50fb3ca744ea', - sizes: [[300, 250]], - bidId: '352f86f158d97a', - bidderRequestId: '123ae4cc3eeb7e', - auctionId: 'c594a888-6744-46c6-8b0e-d188e40e83ef', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 - }, - { - bidder: 'unicorn', - params: { - placementId: 'rectangle-ad-2', - bidfloorCpm: 0, - accountId: 12345 - }, - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - adUnitCode: '/19968336/header-bid-tag-2', - transactionId: '82f445a8-44bc-40bc-9913-739b40375566', - sizes: [[300, 250]], - bidId: '4cde82cc90126b', - bidderRequestId: '123ae4cc3eeb7e', - auctionId: 'c594a888-6744-46c6-8b0e-d188e40e83ef', - src: 'client', - bidRequestsCount: 1, - bidderRequestsCount: 1, - bidderWinsCount: 0 - } - ], - auctionStart: 1581064124172, - timeout: 1000, - refererInfo: { - referer: 'https://uni-corn.net/', - reachedTop: true, - numIframes: 0, - stack: ['https://uni-corn.net/'] - }, - start: 1581064124177 -}; - -const openRTBRequest = { - id: '5ebea288-f13a-4754-be6d-4ade66c68877', - at: 1, - imp: [ - { - id: '216255f234b602', - banner: { - w: 300, - h: 250, - format: [ - { - w: 300, - h: 250 - }, - { - w: 336, - h: 280 - } - ] - }, - secure: 1, - bidfloor: 0, - tagid: 'rectangle-ad-1' - }, - { - id: '31e2b28ced2475', - banner: { - w: 300, - h: 250, - format: [ - { - w: 300, - h: 250 - } - ] - }, - secure: 1, - bidfloor: 0, - tagid: '/19968336/header-bid-tag-1' - }, - { - id: '40a333e047a9bd', - banner: { - w: 300, - h: 250, - format: [ - { - w: 300, - h: 250 - } - ] - }, - secure: 1, - bidfloor: 0, - tagid: 'rectangle-ad-2' - } - ], - cur: 'JPY', - ext: { - accountId: 12345 - }, - site: { - id: 'example', - publisher: { - id: 99999 - }, - domain: 'uni-corn.net', - page: 'https://uni-corn.net/', - ref: 'https://uni-corn.net/' - }, - device: { - language: 'ja', - ua: - 'Mozilla/5.0 (Linux; Android 8.0.0; ONEPLUS A5000) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36' - }, - user: { - id: '69d9e1c2-801e-4901-a665-fad467550fec' - }, - bcat: [], - source: { - ext: { - stype: 'prebid_uncn', - bidder: 'unicorn', - prebid_version: '1.0' - } - } -}; - -const serverResponse = { - body: { - bidid: '04db8629-179d-4bcd-acce-e54722969006', - cur: 'JPY', - ext: {}, - id: '5ebea288-f13a-4754-be6d-4ade66c68877', - seatbid: [ - { - bid: [ - { - adid: 'uqgbp4y0_OoqM1QOt', - adm: '
test
', - adomain: ['test1.co.jp'], - attr: [], - bundle: 'com.test1.android', - cat: ['IAB9'], - cid: '2196', - crid: 'ABCDE', - ext: { - imptrackers: ['https://uncn.jp/pb/2/view/test1'] - }, - h: 250, - id: '1', - impid: '216255f234b602', - iurl: 'https://assets.ucontent.net/test1.jpg', - price: 1.0017, - w: 300 - }, - { - adid: 'uqgbp4y0_uqjrNT7h_25512', - adm: '
test
', - adomain: ['test1.co.jp'], - attr: ['6'], - bundle: 'com.test1.android', - cat: ['IAB9'], - cid: '2196', - crid: 'abcde', - ext: { - imptrackers: ['https://uncn.jp/pb/2/view/test1'] - }, - h: 250, - id: '2', - impid: '31e2b28ced2475', - iurl: 'https://assets.ucontent.net/test1.jpg', - price: 0.9513, - w: 300 - } - ], - group: 0, - seat: '65' - }, - { - bid: [ - { - adid: 'uoNYC6II_eoySuXNi', - adm: '
test
', - adomain: ['test2.co.jp'], - attr: [], - bundle: 'jp.co.test2', - cat: ['IAB9'], - cid: '7315', - crid: 'XYZXYZ', - ext: { - imptrackers: ['https://uncn.jp/pb/2/view/test2'] - }, - h: 250, - id: '3', - impid: '40a333e047a9bd', - iurl: 'https://assets.ucontent.net/test2.jpg', - price: 0.674, - w: 300 - } - ], - group: 0, - seat: '274' - } - ], - units: 0 - }, - headers: {} -}; - -const request = { - method: 'POST', - url: 'https://ds.uncn.jp/pb/0/bid.json', - data: - '{"id":"5ebea288-f13a-4754-be6d-4ade66c68877","at":1,"imp":[{"id":"216255f234b602","banner":{"w":300,"h":250},"format":[{"w":300,"h":250},{"w":336,"h":280}],"secure":1,"bidfloor":0,"tagid":"/19968336/header-bid-tag-0"},{"id":"31e2b28ced2475","banner":{"w":"300","h":"250"},"format":[{"w":"300","h":"250"}],"secure":1,"bidfloor":0"tagid":"/19968336/header-bid-tag-1"},{"id":"40a333e047a9bd","banner":{"w":300,"h":250},"format":[{"w":300,"h":250}],"secure":1,"bidfloor":0,"tagid":"/19968336/header-bid-tag-2"}],"cur":"JPY","site":{"id":"uni-corn.net","publisher":{"id":12345},"domain":"uni-corn.net","page":"https://uni-corn.net/","ref":"https://uni-corn.net/"},"device":{"language":"ja","ua":"Mozilla/5.0 (Linux; Android 8.0.0; ONEPLUS A5000) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.93 Mobile Safari/537.36"},"user":{"id":"69d9e1c2-801e-4901-a665-fad467550fec"},"bcat":[],"source":{"ext":{"stype":"prebid_uncn","bidder":"unicorn","prebid_version":"1.0"}}}' -}; - -const interpretedBids = [ - { - requestId: '216255f234b602', - cpm: 1.0017, - width: 300, - height: 250, - ad: '
test
', - ttl: 1000, - creativeId: 'ABCDE', - netRevenue: false, - currency: 'JPY' - }, - { - requestId: '31e2b28ced2475', - cpm: 0.9513, - width: 300, - height: 250, - ad: '
test
', - ttl: 1000, - creativeId: 'abcde', - netRevenue: false, - currency: 'JPY' - }, - { - requestId: '40a333e047a9bd', - cpm: 0.674, - width: 300, - height: 250, - ad: '
test
', - ttl: 1000, - creativeId: 'XYZXYZ', - netRevenue: false, - currency: 'JPY' - } -]; - -describe('unicornBidAdapterTest', () => { - describe('isBidRequestValid', () => { - it('isBidRequestValid', () => { - expect(spec.isBidRequestValid(bidRequests[0])).to.equal(true); - expect(spec.isBidRequestValid(bidRequests[1])).to.equal(false); - expect(spec.isBidRequestValid(bidRequests[2])).to.equal(false); - }); - }); - - describe('buildBidRequest', () => { - it('buildBidRequest', () => { - const req = spec.buildRequests(validBidRequests, bidderRequest); - const removeUntestableAttrs = data => { - delete data['device']; - delete data['site']['domain']; - delete data['site']['page']; - delete data['id']; - data['imp'].forEach(imp => { - delete imp['id']; - }) - delete data['user']['id']; - return data; - }; - const uid = JSON.parse(req.data)['user']['id']; - const reqData = removeUntestableAttrs(JSON.parse(req.data)); - const openRTBRequestData = removeUntestableAttrs(openRTBRequest); - assert.deepStrictEqual(reqData, openRTBRequestData); - const req2 = spec.buildRequests(validBidRequests, bidderRequest); - const uid2 = JSON.parse(req2.data)['user']['id']; - assert.deepStrictEqual(uid, uid2); - }); - }); - - describe('interpretResponse', () => { - it('interpretResponse', () => { - const bids = spec.interpretResponse(serverResponse, request); - assert.deepStrictEqual(bids, interpretedBids); - }); - it('interpretResponseEmptyString', () => { - const bids = spec.interpretResponse('', request); - assert.deepStrictEqual(bids, []); - }); - it('interpretResponseEmptyArray', () => { - const bids = spec.interpretResponse([], request); - assert.deepStrictEqual(bids, []); - }); - }); -}); diff --git a/test/spec/modules/unrulyBidAdapter_spec.js b/test/spec/modules/unrulyBidAdapter_spec.js deleted file mode 100644 index b087ba042a9..00000000000 --- a/test/spec/modules/unrulyBidAdapter_spec.js +++ /dev/null @@ -1,331 +0,0 @@ -/* globals describe, it, beforeEach, afterEach, sinon */ -import { expect } from 'chai' -import * as utils from 'src/utils.js' -import { STATUS } from 'src/constants.json' -import { VIDEO } from 'src/mediaTypes.js' -import { Renderer } from 'src/Renderer.js' -import { adapter } from 'modules/unrulyBidAdapter.js' - -describe('UnrulyAdapter', function () { - function createOutStreamExchangeBid({ - adUnitCode = 'placement2', - statusCode = 1, - bidId = 'foo', - 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' - }) { - return { - 'ext': { - 'statusCode': statusCode, - 'renderer': { - 'id': 'unruly_inarticle', - 'config': { - 'siteId': 123456, - 'targetingUUID': 'xxx-yyy-zzz' - }, - 'url': 'https://video.unrulymedia.com/native/prebid-loader.js' - }, - 'adUnitCode': adUnitCode - }, - 'cpm': 20, - 'bidderCode': 'unruly', - 'width': 323, - 'vastUrl': vastUrl, - 'bidId': bidId, - 'height': 323 - } - } - - const createExchangeResponse = (...bids) => ({ - body: { bids } - }); - - let sandbox; - let fakeRenderer; - - beforeEach(function () { - sandbox = sinon.sandbox.create(); - sandbox.stub(utils, 'logError'); - sandbox.stub(Renderer, 'install'); - - fakeRenderer = { - setRender: sinon.stub() - }; - Renderer.install.returns(fakeRenderer) - }); - - afterEach(function () { - sandbox.restore(); - delete parent.window.unruly - }); - - it('should expose Unruly Bidder code', function () { - expect(adapter.code).to.equal('unruly') - }); - - it('should contain the VIDEO mediaType', function () { - expect(adapter.supportedMediaTypes).to.deep.equal([ VIDEO ]) - }); - - describe('isBidRequestValid', function () { - it('should be a function', function () { - expect(typeof adapter.isBidRequestValid).to.equal('function') - }); - - it('should return false if bid is falsey', function () { - expect(adapter.isBidRequestValid()).to.be.false; - }); - - it('should return true if bid.mediaType is "video"', function () { - const mockBid = { mediaType: 'video' }; - - expect(adapter.isBidRequestValid(mockBid)).to.be.true; - }); - - it('should return true if bid.mediaTypes.video.context is "outstream"', function () { - const mockBid = { - mediaTypes: { - video: { - context: 'outstream' - } - } - }; - - expect(adapter.isBidRequestValid(mockBid)).to.be.true; - }); - }); - - describe('buildRequests', function () { - it('should be a function', function () { - expect(typeof adapter.buildRequests).to.equal('function'); - }); - it('should return an object', function () { - const mockBidRequests = ['mockBid']; - expect(typeof adapter.buildRequests(mockBidRequests)).to.equal('object') - }); - it('should return a server request with a valid exchange url', function () { - const mockBidRequests = ['mockBid']; - expect(adapter.buildRequests(mockBidRequests).url).to.equal('https://targeting.unrulymedia.com/prebid') - }); - it('should return a server request with method === POST', function () { - const mockBidRequests = ['mockBid']; - expect(adapter.buildRequests(mockBidRequests).method).to.equal('POST'); - }); - it('should ensure contentType is `text/plain`', function () { - const mockBidRequests = ['mockBid']; - expect(adapter.buildRequests(mockBidRequests).options).to.deep.equal({ - contentType: 'text/plain' - }); - }); - it('should return a server request with valid payload', function () { - const mockBidRequests = ['mockBid']; - const mockBidderRequest = {bidderCode: 'mockBidder'}; - expect(adapter.buildRequests(mockBidRequests, mockBidderRequest).data) - .to.deep.equal({bidRequests: mockBidRequests, bidderRequest: mockBidderRequest}) - }) - }); - - describe('interpretResponse', function () { - it('should be a function', function () { - expect(typeof adapter.interpretResponse).to.equal('function'); - }); - it('should return [] when serverResponse is undefined', function () { - expect(adapter.interpretResponse()).to.deep.equal([]); - }); - it('should return [] when serverResponse has no bids', function () { - 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', bidId: 'mockBidId'}); - const mockServerResponse = createExchangeResponse(mockExchangeBid); - expect(adapter.interpretResponse(mockServerResponse)).to.deep.equal([ - { - requestId: 'mockBidId', - 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: { advertiserDomains: [] }, - currency: 'USD', - renderer: fakeRenderer, - mediaType: 'video' - } - ]) - }); - - 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', bidId: 'mockBidId'}); - const mockRenderer = { - url: 'value: mockRendererURL', - config: { - siteId: 123456, - targetingUUID: 'xxx-yyy-zzz' - } - }; - mockReturnedBid.ext.renderer = mockRenderer; - const mockServerResponse = createExchangeResponse(mockReturnedBid); - - adapter.interpretResponse(mockServerResponse); - - expect(Renderer.install.calledOnce).to.be.true; - sinon.assert.calledWithExactly( - Renderer.install, - Object.assign({}, mockRenderer, {callback: sinon.match.func}) - ); - - sinon.assert.calledOnce(fakeRenderer.setRender); - sinon.assert.calledWithExactly(fakeRenderer.setRender, sinon.match.func) - }); - - it('should return [] and log if bidResponse renderer config is not available', function () { - sinon.assert.notCalled(utils.logError) - - expect(Renderer.install.called).to.be.false; - expect(fakeRenderer.setRender.called).to.be.false; - - const mockReturnedBid = createOutStreamExchangeBid({adUnitCode: 'video1', bidId: 'mockBidId'}); - const mockRenderer = { - url: 'value: mockRendererURL' - }; - mockReturnedBid.ext.renderer = mockRenderer; - const mockServerResponse = createExchangeResponse(mockReturnedBid); - - expect(adapter.interpretResponse(mockServerResponse)).to.deep.equal([]); - - const logErrorCalls = utils.logError.getCalls(); - expect(logErrorCalls.length).to.equal(2); - - const [ configErrorCall, siteIdErrorCall ] = logErrorCalls; - - expect(configErrorCall.args.length).to.equal(1); - expect(configErrorCall.args[0].message).to.equal('UnrulyBidAdapter: Missing renderer config.'); - - expect(siteIdErrorCall.args.length).to.equal(1); - expect(siteIdErrorCall.args[0].message).to.equal('UnrulyBidAdapter: Missing renderer siteId.'); - }); - - it('should return [] and log if siteId is not available', function () { - sinon.assert.notCalled(utils.logError) - - expect(Renderer.install.called).to.be.false; - expect(fakeRenderer.setRender.called).to.be.false; - - const mockReturnedBid = createOutStreamExchangeBid({adUnitCode: 'video1', bidId: 'mockBidId'}); - const mockRenderer = { - url: 'value: mockRendererURL', - config: {} - }; - mockReturnedBid.ext.renderer = mockRenderer; - const mockServerResponse = createExchangeResponse(mockReturnedBid); - - expect(adapter.interpretResponse(mockServerResponse)).to.deep.equal([]); - - const logErrorCalls = utils.logError.getCalls(); - expect(logErrorCalls.length).to.equal(1); - - const [ siteIdErrorCall ] = logErrorCalls; - - expect(siteIdErrorCall.args.length).to.equal(1); - expect(siteIdErrorCall.args[0].message).to.equal('UnrulyBidAdapter: Missing renderer siteId.'); - }); - - it('bid is placed on the bid queue when render is called', function () { - const exchangeBid = createOutStreamExchangeBid({ adUnitCode: 'video', vastUrl: 'value: vastUrl' }); - const exchangeResponse = createExchangeResponse(exchangeBid); - - adapter.interpretResponse(exchangeResponse); - - sinon.assert.calledOnce(fakeRenderer.setRender); - fakeRenderer.setRender.firstCall.args[0](); - - expect(window.top).to.have.deep.nested.property('unruly.native.prebid.uq'); - - const uq = window.top.unruly.native.prebid.uq; - const sentRendererConfig = uq[0][1]; - - expect(uq[0][0]).to.equal('render'); - expect(sentRendererConfig.vastUrl).to.equal('value: vastUrl'); - expect(sentRendererConfig.renderer).to.equal(fakeRenderer); - expect(sentRendererConfig.adUnitCode).to.equal('video') - }); - - it('should ensure that renderer is placed in Prebid supply mode', function () { - const mockExchangeBid = createOutStreamExchangeBid({adUnitCode: 'video1', bidId: 'mockBidId'}); - const mockServerResponse = createExchangeResponse(mockExchangeBid); - - expect('unruly' in window.parent).to.equal(false); - - adapter.interpretResponse(mockServerResponse); - - const supplyMode = window.parent.unruly.native.supplyMode; - - expect(supplyMode).to.equal('prebid'); - }); - }); - - describe('getUserSyncs', () => { - it('should push user sync iframe if enabled', () => { - const mockConsent = {} - const response = {} - const syncOptions = { iframeEnabled: true } - const syncs = adapter.getUserSyncs(syncOptions, response, mockConsent) - expect(syncs[0]).to.deep.equal({ - type: 'iframe', - url: 'https://video.unrulymedia.com/iframes/third-party-iframes.html' - }); - }) - - it('should not push user sync iframe if not enabled', () => { - const mockConsent = {} - const response = {} - const syncOptions = { iframeEnabled: false } - const syncs = adapter.getUserSyncs(syncOptions, response, mockConsent); - expect(syncs).to.be.empty; - }); - }); - - it('should not append consent params if gdpr does not apply', () => { - const mockConsent = {} - const response = {} - const syncOptions = { iframeEnabled: true } - const syncs = adapter.getUserSyncs(syncOptions, response, mockConsent) - expect(syncs[0]).to.deep.equal({ - type: 'iframe', - url: 'https://video.unrulymedia.com/iframes/third-party-iframes.html' - }) - }); - - it('should append consent params if gdpr does apply and consent is given', () => { - const mockConsent = { - gdprApplies: true, - consentString: 'hello' - }; - const response = {} - const syncOptions = { iframeEnabled: true } - const syncs = adapter.getUserSyncs(syncOptions, response, mockConsent) - expect(syncs[0]).to.deep.equal({ - type: 'iframe', - url: 'https://video.unrulymedia.com/iframes/third-party-iframes.html?gdpr=1&gdpr_consent=hello' - }) - }); - - it('should append consent param if gdpr applies and no consent is given', () => { - const mockConsent = { - gdprApplies: true, - consentString: {} - }; - const response = {}; - const syncOptions = { iframeEnabled: true } - const syncs = adapter.getUserSyncs(syncOptions, response, mockConsent) - expect(syncs[0]).to.deep.equal({ - type: 'iframe', - url: 'https://video.unrulymedia.com/iframes/third-party-iframes.html?gdpr=0' - }) - }) -}); diff --git a/test/spec/modules/userId_spec.js b/test/spec/modules/userId_spec.js deleted file mode 100644 index 95bba079fa2..00000000000 --- a/test/spec/modules/userId_spec.js +++ /dev/null @@ -1,2924 +0,0 @@ -import { - attachIdSystem, - auctionDelay, - coreStorage, - init, - requestBidsHook, - setStoredConsentData, - setStoredValue, - setSubmoduleRegistry, - syncDelay, - PBJS_USER_ID_OPTOUT_NAME, - findRootDomain, -} from 'modules/userId/index.js'; -import {createEidsArray} from 'modules/userId/eids.js'; -import {config} from 'src/config.js'; -import * as utils from 'src/utils.js'; -import events from 'src/events.js'; -import CONSTANTS from 'src/constants.json'; -import {getGlobal} from 'src/prebidGlobal.js'; -import { - requestBidsHook as consentManagementRequestBidsHook, - resetConsentData, - setConsentConfig -} from 'modules/consentManagement.js'; -import {server} from 'test/mocks/xhr.js'; -import find from 'core-js-pure/features/array/find.js'; -import {unifiedIdSubmodule} from 'modules/unifiedIdSystem.js'; -import {pubCommonIdSubmodule} from 'modules/pubCommonIdSystem.js'; -import {britepoolIdSubmodule} from 'modules/britepoolIdSystem.js'; -import {id5IdSubmodule} from 'modules/id5IdSystem.js'; -import {identityLinkSubmodule} from 'modules/identityLinkIdSystem.js'; -import {dmdIdSubmodule} from 'modules/dmdIdSystem.js'; -import {liveIntentIdSubmodule} from 'modules/liveIntentIdSystem.js'; -import {merkleIdSubmodule} from 'modules/merkleIdSystem.js'; -import {netIdSubmodule} from 'modules/netIdSystem.js'; -import {nextrollIdSubmodule} from 'modules/nextrollIdSystem.js'; -import {intentIqIdSubmodule} from 'modules/intentIqIdSystem.js'; -import {zeotapIdPlusSubmodule} from 'modules/zeotapIdPlusIdSystem.js'; -import {sharedIdSubmodule} from 'modules/sharedIdSystem.js'; -import {haloIdSubmodule} from 'modules/haloIdSystem.js'; -import {pubProvidedIdSubmodule} from 'modules/pubProvidedIdSystem.js'; -import {criteoIdSubmodule} from 'modules/criteoIdSystem.js'; -import {mwOpenLinkIdSubModule} from 'modules/mwOpenLinkIdSystem.js'; -import {tapadIdSubmodule} from 'modules/tapadIdSystem.js'; -import {getPrebidInternal} from 'src/utils.js'; -import {uid2IdSubmodule} from 'modules/uid2IdSystem.js'; -import {admixerIdSubmodule} from 'modules/admixerIdSystem.js'; -import {deepintentDpesSubmodule} from 'modules/deepintentDpesIdSystem.js'; -import {flocIdSubmodule} from 'modules/flocIdSystem.js' - -let assert = require('chai').assert; -let expect = require('chai').expect; -const EXPIRED_COOKIE_DATE = 'Thu, 01 Jan 1970 00:00:01 GMT'; -const CONSENT_LOCAL_STORAGE_NAME = '_pbjs_userid_consent_data'; - -describe('User ID', function () { - function getConfigMock(...configArrays) { - return { - userSync: { - syncDelay: 0, - userIds: configArrays.map(configArray => (configArray && configArray.length >= 3) ? getStorageMock.apply(null, configArray) : null) - } - } - } - - function getStorageMock(name = 'pubCommonId', key = 'pubcid', type = 'cookie', expires = 30, 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}]} - } - } - - function getAdUnitMock(code = 'adUnit-code') { - return { - code, - mediaTypes: {banner: {}, native: {}}, - sizes: [[300, 200], [300, 600]], - bids: [{bidder: 'sampleBidder', params: {placementId: 'banner-only-bidder'}}, {bidder: 'anotherSampleBidder', params: {placementId: 'banner-only-bidder'}}] - }; - } - - function addConfig(cfg, name, value) { - if (cfg && cfg.userSync && cfg.userSync.userIds) { - cfg.userSync.userIds.forEach(element => { - if (element[name] !== undefined) { - element[name] = Object.assign(element[name], value); - } else { - element[name] = value; - } - }); - } - - return cfg; - } - - function findEid(eids, source) { - return find(eids, (eid) => { - if (eid.source === source) { return true; } - }); - } - - before(function () { - localStorage.removeItem(PBJS_USER_ID_OPTOUT_NAME); - }); - - beforeEach(function () { - coreStorage.setCookie(CONSENT_LOCAL_STORAGE_NAME, '', EXPIRED_COOKIE_DATE); - }); - - describe('Decorate Ad Units', function () { - beforeEach(function () { - coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('pubcid_alt', 'altpubcid200000', (new Date(Date.now() + 5000).toUTCString())); - sinon.spy(coreStorage, 'setCookie'); - }); - - afterEach(function () { - $$PREBID_GLOBAL$$.requestBids.removeAll(); - config.resetConfig(); - coreStorage.setCookie.restore(); - }); - - after(function () { - coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('pubcid_alt', '', EXPIRED_COOKIE_DATE); - }); - - it('Check same cookie behavior', function () { - let adUnits1 = [getAdUnitMock()]; - let adUnits2 = [getAdUnitMock()]; - let innerAdUnits1; - let innerAdUnits2; - - let pubcid = coreStorage.getCookie('pubcid'); - expect(pubcid).to.be.null; // there should be no cookie initially - - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'])); - - requestBidsHook(config => { - innerAdUnits1 = config.adUnits - }, {adUnits: adUnits1}); - pubcid = coreStorage.getCookie('pubcid'); // cookies is created after requestbidHook - - innerAdUnits1.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.pubcid'); - expect(bid.userId.pubcid).to.equal(pubcid); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'pubcid.org', - uids: [{id: pubcid, atype: 1}] - }); - }); - }); - - requestBidsHook(config => { - innerAdUnits2 = config.adUnits - }, {adUnits: adUnits2}); - assert.deepEqual(innerAdUnits1, innerAdUnits2); - }); - - it('Check different cookies', function () { - let adUnits1 = [getAdUnitMock()]; - let adUnits2 = [getAdUnitMock()]; - let innerAdUnits1; - let innerAdUnits2; - let pubcid1; - let pubcid2; - - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'])); - requestBidsHook((config) => { - innerAdUnits1 = config.adUnits - }, {adUnits: adUnits1}); - pubcid1 = coreStorage.getCookie('pubcid'); // get first cookie - coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); // erase cookie - - innerAdUnits1.forEach((unit) => { - unit.bids.forEach((bid) => { - expect(bid).to.have.deep.nested.property('userId.pubcid'); - expect(bid.userId.pubcid).to.equal(pubcid1); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'pubcid.org', - uids: [{id: pubcid1, atype: 1}] - }); - }); - }); - - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'])); - requestBidsHook((config) => { - innerAdUnits2 = config.adUnits - }, {adUnits: adUnits2}); - - pubcid2 = coreStorage.getCookie('pubcid'); // get second cookie - - innerAdUnits2.forEach((unit) => { - unit.bids.forEach((bid) => { - expect(bid).to.have.deep.nested.property('userId.pubcid'); - expect(bid.userId.pubcid).to.equal(pubcid2); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'pubcid.org', - uids: [{id: pubcid2, atype: 1}] - }); - }); - }); - - expect(pubcid1).to.not.equal(pubcid2); - }); - - it('Use existing cookie', function () { - let adUnits = [getAdUnitMock()]; - let innerAdUnits; - - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['pubCommonId', 'pubcid_alt', 'cookie'])); - requestBidsHook((config) => { - innerAdUnits = config.adUnits - }, {adUnits}); - innerAdUnits.forEach((unit) => { - unit.bids.forEach((bid) => { - expect(bid).to.have.deep.nested.property('userId.pubcid'); - expect(bid.userId.pubcid).to.equal('altpubcid200000'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'pubcid.org', - uids: [{id: 'altpubcid200000', atype: 1}] - }); - }); - }); - // Because the cookie exists already, there should be no setCookie call by default; the only setCookie call is - // to store consent data - expect(coreStorage.setCookie.callCount).to.equal(1); - }); - - it('Extend cookie', function () { - let adUnits = [getAdUnitMock()]; - let innerAdUnits; - let customConfig = getConfigMock(['pubCommonId', 'pubcid_alt', 'cookie']); - customConfig = addConfig(customConfig, 'params', {extend: true}); - - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule]); - init(config); - config.setConfig(customConfig); - requestBidsHook((config) => { - innerAdUnits = config.adUnits - }, {adUnits}); - innerAdUnits.forEach((unit) => { - unit.bids.forEach((bid) => { - expect(bid).to.have.deep.nested.property('userId.pubcid'); - expect(bid.userId.pubcid).to.equal('altpubcid200000'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'pubcid.org', - uids: [{id: 'altpubcid200000', atype: 1}] - }); - }); - }); - // Because extend is true, the cookie will be updated even if it exists already. The second setCookie call - // is for storing consentData - expect(coreStorage.setCookie.callCount).to.equal(2); - }); - - it('Disable auto create', function () { - let adUnits = [getAdUnitMock()]; - let innerAdUnits; - let customConfig = getConfigMock(['pubCommonId', 'pubcid', 'cookie']); - customConfig = addConfig(customConfig, 'params', {create: false}); - - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule]); - init(config); - config.setConfig(customConfig); - requestBidsHook((config) => { - innerAdUnits = config.adUnits - }, {adUnits}); - innerAdUnits.forEach((unit) => { - unit.bids.forEach((bid) => { - expect(bid).to.not.have.deep.nested.property('userId.pubcid'); - expect(bid).to.not.have.deep.nested.property('userIdAsEids'); - }); - }); - // setCookie is called once in order to store consentData - expect(coreStorage.setCookie.callCount).to.equal(1); - }); - - it('pbjs.getUserIds', function () { - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - config.setConfig({ - userSync: { - syncDelay: 0, - userIds: [{ - name: 'pubCommonId', value: {'pubcid': '11111'} - }] - } - }); - expect(typeof (getGlobal()).getUserIds).to.equal('function'); - expect((getGlobal()).getUserIds()).to.deep.equal({pubcid: '11111'}); - }); - - it('pbjs.getUserIdsAsEids', function () { - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - config.setConfig({ - userSync: { - syncDelay: 0, - userIds: [{ - name: 'pubCommonId', value: {'pubcid': '11111'} - }] - } - }); - expect(typeof (getGlobal()).getUserIdsAsEids).to.equal('function'); - expect((getGlobal()).getUserIdsAsEids()).to.deep.equal(createEidsArray((getGlobal()).getUserIds())); - }); - - it('pbjs.refreshUserIds refreshes', function() { - let sandbox = sinon.createSandbox(); - - let mockIdCallback = sandbox.stub().returns({id: {'MOCKID': '1111'}}); - - let mockIdSystem = { - name: 'mockId', - decode: function(value) { - return { - 'mid': value['MOCKID'] - }; - }, - getId: mockIdCallback - }; - - setSubmoduleRegistry([mockIdSystem]); - init(config); - config.setConfig({ - userSync: { - syncDelay: 0, - userIds: [{ - name: 'mockId', - value: {id: {mockId: '1111'}} - }] - } - }); - expect(typeof (getGlobal()).refreshUserIds).to.equal('function'); - - getGlobal().getUserIds(); // force initialization - - // update config so that getId will be called - config.setConfig({ - userSync: { - syncDelay: 0, - userIds: [{ - name: 'mockId', - storage: {name: 'mockid', type: 'cookie'}, - }] - } - }); - - getGlobal().refreshUserIds(); - expect(mockIdCallback.callCount).to.equal(1); - }); - - it('pbjs.refreshUserIds refreshes single', function() { - coreStorage.setCookie('MOCKID', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('REFRESH', '', EXPIRED_COOKIE_DATE); - - let sandbox = sinon.createSandbox(); - let mockIdCallback = sandbox.stub().returns({id: {'MOCKID': '1111'}}); - let refreshUserIdsCallback = sandbox.stub(); - - let mockIdSystem = { - name: 'mockId', - decode: function(value) { - return { - 'mid': value['MOCKID'] - }; - }, - getId: mockIdCallback - }; - - let refreshedIdCallback = sandbox.stub().returns({id: {'REFRESH': '1111'}}); - - let refreshedIdSystem = { - name: 'refreshedId', - decode: function(value) { - return { - 'refresh': value['REFRESH'] - }; - }, - getId: refreshedIdCallback - }; - - setSubmoduleRegistry([refreshedIdSystem, mockIdSystem]); - init(config); - config.setConfig({ - userSync: { - syncDelay: 0, - userIds: [ - { - name: 'mockId', - storage: {name: 'MOCKID', type: 'cookie'}, - }, - { - name: 'refreshedId', - storage: {name: 'refreshedid', type: 'cookie'}, - } - ] - } - }); - - getGlobal().getUserIds(); // force initialization - - getGlobal().refreshUserIds({submoduleNames: 'refreshedId'}, refreshUserIdsCallback); - - expect(refreshedIdCallback.callCount).to.equal(2); - expect(mockIdCallback.callCount).to.equal(1); - expect(refreshUserIdsCallback.callCount).to.equal(1); - }); - }); - - describe('Opt out', function () { - before(function () { - coreStorage.setCookie(PBJS_USER_ID_OPTOUT_NAME, '1', (new Date(Date.now() + 5000).toUTCString())); - }); - - beforeEach(function () { - sinon.stub(utils, 'logInfo'); - }); - - afterEach(function () { - // removed cookie - coreStorage.setCookie(PBJS_USER_ID_OPTOUT_NAME, '', EXPIRED_COOKIE_DATE); - $$PREBID_GLOBAL$$.requestBids.removeAll(); - utils.logInfo.restore(); - config.resetConfig(); - }); - - it('fails initialization if opt out cookie exists', function () { - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'])); - expect(utils.logInfo.args[0][0]).to.exist.and.to.equal('User ID - opt-out cookie found, exit module'); - }); - - it('initializes if no opt out cookie exists', function () { - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'])); - expect(utils.logInfo.args[0][0]).to.exist.and.to.contain('User ID - usersync config updated for 1 submodules'); - }); - }); - - describe('Handle variations of config values', function () { - beforeEach(function () { - sinon.stub(utils, 'logInfo'); - }); - - afterEach(function () { - $$PREBID_GLOBAL$$.requestBids.removeAll(); - utils.logInfo.restore(); - config.resetConfig(); - }); - - it('handles config with no usersync object', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, flocIdSubmodule]); - init(config); - config.setConfig({}); - // usersync is undefined, and no logInfo message for 'User ID - usersync config updated' - expect(typeof utils.logInfo.args[0]).to.equal('undefined'); - }); - - it('handles config with empty usersync object', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, flocIdSubmodule]); - init(config); - config.setConfig({userSync: {}}); - expect(typeof utils.logInfo.args[0]).to.equal('undefined'); - }); - - it('handles config with usersync and userIds that are empty objs', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, nextrollIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, flocIdSubmodule]); - init(config); - config.setConfig({ - userSync: { - userIds: [{}] - } - }); - expect(typeof utils.logInfo.args[0]).to.equal('undefined'); - }); - - it('handles config with usersync and userIds with empty names or that dont match a submodule.name', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, merkleIdSubmodule, netIdSubmodule, nextrollIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, flocIdSubmodule]); - init(config); - config.setConfig({ - userSync: { - userIds: [{ - name: '', - value: {test: '1'} - }, { - name: 'foo', - value: {test: '1'} - }] - } - }); - expect(typeof utils.logInfo.args[0]).to.equal('undefined'); - }); - - it('config with 1 configurations should create 1 submodules', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, nextrollIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, flocIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['unifiedId', 'unifiedid', 'cookie'])); - - expect(utils.logInfo.args[0][0]).to.exist.and.to.contain('User ID - usersync config updated for 1 submodules'); - }); - - it('handles config with name in different case', function () { - setSubmoduleRegistry([criteoIdSubmodule]); - init(config); - config.setConfig({ - userSync: { - userIds: [{ - name: 'Criteo' - }] - } - }); - - expect(utils.logInfo.args[0][0]).to.exist.and.to.contain('User ID - usersync config updated for 1 submodules'); - }); - - it('config with 21 configurations should result in 21 submodules add', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, liveIntentIdSubmodule, britepoolIdSubmodule, netIdSubmodule, nextrollIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, flocIdSubmodule]); - init(config); - config.setConfig({ - userSync: { - syncDelay: 0, - userIds: [{ - name: 'pubProvidedId' - }, { - name: 'pubCommonId', value: {'pubcid': '11111'} - }, { - name: 'unifiedId', - storage: {name: 'unifiedid', type: 'cookie'} - }, { - name: 'id5Id', - storage: {name: 'id5id', type: 'cookie'} - }, { - name: 'identityLink', - storage: {name: 'idl_env', type: 'cookie'} - }, { - name: 'liveIntentId', - storage: {name: '_li_pbid', type: 'cookie'} - }, { - name: 'britepoolId', - value: {'primaryBPID': '279c0161-5152-487f-809e-05d7f7e653fd'} - }, { - name: 'netId', - storage: {name: 'netId', type: 'cookie'} - }, { - name: 'nextrollId' - }, { - name: 'sharedId', - storage: {name: 'sharedid', type: 'cookie'} - }, { - name: 'intentIqId', - storage: {name: 'intentIqId', type: 'cookie'} - }, { - name: 'haloId', - storage: {name: 'haloId', type: 'cookie'} - }, { - name: 'zeotapIdPlus' - }, { - name: 'criteo' - }, { - name: 'mwOpenLinkId' - }, { - name: 'tapadId', - storage: {name: 'tapad_id', type: 'cookie'} - }, { - name: 'uid2' - }, { - name: 'admixerId', - storage: {name: 'admixerId', type: 'cookie'} - }, { - name: 'deepintentId', - storage: {name: 'deepintentId', type: 'cookie'} - }, { - name: 'flocId' - }, { - name: 'dmdId', - storage: {name: 'dmdId', type: 'cookie'} - }] - } - }); - expect(utils.logInfo.args[0][0]).to.exist.and.to.contain('User ID - usersync config updated for 21 submodules'); - }); - - it('config syncDelay updates module correctly', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, nextrollIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, flocIdSubmodule]); - - init(config); - config.setConfig({ - userSync: { - syncDelay: 99, - userIds: [{ - name: 'unifiedId', - storage: {name: 'unifiedid', type: 'cookie'} - }] - } - }); - expect(syncDelay).to.equal(99); - }); - - it('config auctionDelay updates module correctly', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, nextrollIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, flocIdSubmodule]); - init(config); - config.setConfig({ - userSync: { - auctionDelay: 100, - userIds: [{ - name: 'unifiedId', - storage: {name: 'unifiedid', type: 'cookie'} - }] - } - }); - expect(auctionDelay).to.equal(100); - }); - - it('config auctionDelay defaults to 0 if not a number', function () { - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, netIdSubmodule, nextrollIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, pubProvidedIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule, flocIdSubmodule]); - init(config); - config.setConfig({ - userSync: { - auctionDelay: '', - userIds: [{ - name: 'unifiedId', - storage: {name: 'unifiedid', type: 'cookie'} - }] - } - }); - expect(auctionDelay).to.equal(0); - }); - }); - - describe('auction and user sync delays', function () { - let sandbox; - let adUnits; - let mockIdCallback; - let auctionSpy; - - beforeEach(function () { - sandbox = sinon.createSandbox(); - sandbox.stub(global, 'setTimeout').returns(2); - sandbox.stub(global, 'clearTimeout'); - sandbox.stub(events, 'on'); - sandbox.stub(coreStorage, 'getCookie'); - - // remove cookie - coreStorage.setCookie('MOCKID', '', EXPIRED_COOKIE_DATE); - - adUnits = [getAdUnitMock()]; - - auctionSpy = sandbox.spy(); - mockIdCallback = sandbox.stub(); - const mockIdSystem = { - name: 'mockId', - decode: function (value) { - return { - 'mid': value['MOCKID'] - }; - }, - getId: function () { - const storedId = coreStorage.getCookie('MOCKID'); - if (storedId) { - return {id: {'MOCKID': storedId}}; - } - return {callback: mockIdCallback}; - } - }; - - init(config); - - attachIdSystem(mockIdSystem, true); - }); - - afterEach(function () { - $$PREBID_GLOBAL$$.requestBids.removeAll(); - config.resetConfig(); - sandbox.restore(); - }); - - it('delays auction if auctionDelay is set, timing out at auction delay', function () { - config.setConfig({ - userSync: { - auctionDelay: 33, - syncDelay: 77, - userIds: [{ - name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} - }] - } - }); - - requestBidsHook(auctionSpy, {adUnits}); - - // check auction was delayed - global.clearTimeout.calledOnce.should.equal(false); - global.setTimeout.calledOnce.should.equal(true); - global.setTimeout.calledWith(sinon.match.func, 33); - auctionSpy.calledOnce.should.equal(false); - - // check ids were fetched - mockIdCallback.calledOnce.should.equal(true); - - // callback to continue auction if timed out - global.setTimeout.callArg(0); - auctionSpy.calledOnce.should.equal(true); - - // does not call auction again once ids are synced - mockIdCallback.callArgWith(0, {'MOCKID': '1234'}); - auctionSpy.calledOnce.should.equal(true); - - // no sync after auction ends - events.on.called.should.equal(false); - }); - - it('delays auction if auctionDelay is set, continuing auction if ids are fetched before timing out', function (done) { - config.setConfig({ - userSync: { - auctionDelay: 33, - syncDelay: 77, - userIds: [{ - name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} - }] - } - }); - - requestBidsHook(auctionSpy, {adUnits}); - - // check auction was delayed - // global.setTimeout.calledOnce.should.equal(true); - global.clearTimeout.calledOnce.should.equal(false); - global.setTimeout.calledWith(sinon.match.func, 33); - auctionSpy.calledOnce.should.equal(false); - - // check ids were fetched - mockIdCallback.calledOnce.should.equal(true); - - // if ids returned, should continue auction - mockIdCallback.callArgWith(0, {'MOCKID': '1234'}); - auctionSpy.calledOnce.should.equal(true); - - // check ids were copied to bids - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.mid'); - expect(bid.userId.mid).to.equal('1234'); - expect(bid.userIdAsEids.length).to.equal(0);// "mid" is an un-known submodule for USER_IDS_CONFIG in eids.js - }); - done(); - }); - - // no sync after auction ends - events.on.called.should.equal(false); - }); - - it('does not delay auction if not set, delays id fetch after auction ends with syncDelay', function () { - config.setConfig({ - userSync: { - syncDelay: 77, - userIds: [{ - name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} - }] - } - }); - - // check config has been set correctly - expect(auctionDelay).to.equal(0); - expect(syncDelay).to.equal(77); - - requestBidsHook(auctionSpy, {adUnits}); - - // should not delay auction - global.setTimeout.calledOnce.should.equal(false); - auctionSpy.calledOnce.should.equal(true); - - // check user sync is delayed after auction is ended - mockIdCallback.calledOnce.should.equal(false); - events.on.calledOnce.should.equal(true); - events.on.calledWith(CONSTANTS.EVENTS.AUCTION_END, sinon.match.func); - - // once auction is ended, sync user ids after delay - events.on.callArg(1); - global.setTimeout.calledOnce.should.equal(true); - global.setTimeout.calledWith(sinon.match.func, 77); - mockIdCallback.calledOnce.should.equal(false); - - // once sync delay is over, ids should be fetched - global.setTimeout.callArg(0); - mockIdCallback.calledOnce.should.equal(true); - }); - - it('does not delay user id sync after auction ends if set to 0', function () { - config.setConfig({ - userSync: { - syncDelay: 0, - userIds: [{ - name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} - }] - } - }); - - expect(syncDelay).to.equal(0); - - requestBidsHook(auctionSpy, {adUnits}); - - // auction should not be delayed - global.setTimeout.calledOnce.should.equal(false); - auctionSpy.calledOnce.should.equal(true); - - // sync delay after auction is ended - mockIdCallback.calledOnce.should.equal(false); - events.on.calledOnce.should.equal(true); - events.on.calledWith(CONSTANTS.EVENTS.AUCTION_END, sinon.match.func); - - // once auction is ended, if no sync delay, fetch ids - events.on.callArg(1); - global.setTimeout.calledOnce.should.equal(false); - mockIdCallback.calledOnce.should.equal(true); - }); - - it('does not delay auction if there are no ids to fetch', function () { - coreStorage.getCookie.withArgs('MOCKID').returns('123456778'); - config.setConfig({ - userSync: { - auctionDelay: 33, - syncDelay: 77, - userIds: [{ - name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} - }] - } - }); - - requestBidsHook(auctionSpy, {adUnits}); - - global.setTimeout.calledOnce.should.equal(false); - auctionSpy.calledOnce.should.equal(true); - mockIdCallback.calledOnce.should.equal(false); - - // no sync after auction ends - events.on.called.should.equal(false); - }); - }); - - describe('Request bids hook appends userId to bid objs in adapters', function () { - let adUnits; - - beforeEach(function () { - adUnits = [getAdUnitMock()]; - }); - - it('test hook from pubcommonid cookie', function (done) { - coreStorage.setCookie('pubcid', 'testpubcid', (new Date(Date.now() + 100000).toUTCString())); - - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.pubcid'); - expect(bid.userId.pubcid).to.equal('testpubcid'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'pubcid.org', - uids: [{id: 'testpubcid', atype: 1}] - }); - - // verify no sharedid was added - expect(bid.userId).to.not.have.property('sharedid'); - expect(findEid(bid.userIdAsEids, 'sharedid.org')).to.be.undefined; - }); - }); - coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook from pubcommonid html5', function (done) { - // simulate existing browser local storage values - localStorage.setItem('pubcid', 'testpubcid'); - localStorage.setItem('pubcid_exp', new Date(Date.now() + 100000).toUTCString()); - - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'html5'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.pubcid'); - expect(bid.userId.pubcid).to.equal('testpubcid'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'pubcid.org', - uids: [{id: 'testpubcid', atype: 1}] - }); - - // verify no sharedid was added - expect(bid.userId).to.not.have.property('sharedid'); - expect(findEid(bid.userIdAsEids, 'sharedid.org')).to.be.undefined; - }); - }); - localStorage.removeItem('pubcid'); - localStorage.removeItem('pubcid_exp'); - done(); - }, {adUnits}); - }); - - it('test hook from pubcommonid config value object', function (done) { - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - config.setConfig(getConfigValueMock('pubCommonId', {'pubcidvalue': 'testpubcidvalue'})); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.pubcidvalue'); - expect(bid.userId.pubcidvalue).to.equal('testpubcidvalue'); - expect(bid.userIdAsEids.length).to.equal(0);// "pubcidvalue" is an un-known submodule for USER_IDS_CONFIG in eids.js - }); - }); - done(); - }, {adUnits}); - }); - - it('test hook from UnifiedId html5', function (done) { - // simulate existing browser local storage values - localStorage.setItem('unifiedid_alt', JSON.stringify({'TDID': 'testunifiedid_alt'})); - localStorage.setItem('unifiedid_alt_exp', ''); - - setSubmoduleRegistry([unifiedIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['unifiedId', 'unifiedid_alt', 'html5'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.tdid'); - expect(bid.userId.tdid).to.equal('testunifiedid_alt'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'adserver.org', - uids: [{id: 'testunifiedid_alt', atype: 1, ext: {rtiPartner: 'TDID'}}] - }); - }); - }); - localStorage.removeItem('unifiedid_alt'); - localStorage.removeItem('unifiedid_alt_exp'); - done(); - }, {adUnits}); - }); - - it('test hook from identityLink html5', function (done) { - // simulate existing browser local storage values - localStorage.setItem('idl_env', 'AiGNC8Z5ONyZKSpIPf'); - localStorage.setItem('idl_env_exp', ''); - - setSubmoduleRegistry([identityLinkSubmodule]); - init(config); - config.setConfig(getConfigMock(['identityLink', 'idl_env', 'html5'])); - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.idl_env'); - expect(bid.userId.idl_env).to.equal('AiGNC8Z5ONyZKSpIPf'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'liveramp.com', - uids: [{id: 'AiGNC8Z5ONyZKSpIPf', atype: 3}] - }); - }); - }); - localStorage.removeItem('idl_env'); - localStorage.removeItem('idl_env_exp'); - done(); - }, {adUnits}); - }); - - it('test hook from identityLink cookie', function (done) { - coreStorage.setCookie('idl_env', 'AiGNC8Z5ONyZKSpIPf', (new Date(Date.now() + 100000).toUTCString())); - - setSubmoduleRegistry([identityLinkSubmodule]); - init(config); - config.setConfig(getConfigMock(['identityLink', 'idl_env', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.idl_env'); - expect(bid.userId.idl_env).to.equal('AiGNC8Z5ONyZKSpIPf'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'liveramp.com', - uids: [{id: 'AiGNC8Z5ONyZKSpIPf', atype: 3}] - }); - }); - }); - coreStorage.setCookie('idl_env', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook from criteoIdModule cookie', function (done) { - coreStorage.setCookie('storage_bidid', JSON.stringify({'criteoId': 'test_bidid'}), (new Date(Date.now() + 100000).toUTCString())); - - setSubmoduleRegistry([criteoIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['criteo', 'storage_bidid', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.criteoId'); - expect(bid.userId.criteoId).to.equal('test_bidid'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'criteo.com', - uids: [{id: 'test_bidid', atype: 1}] - }); - }); - }); - coreStorage.setCookie('storage_bidid', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook from tapadIdModule cookie', function (done) { - coreStorage.setCookie('tapad_id', 'test-tapad-id', (new Date(Date.now() + 100000).toUTCString())); - - setSubmoduleRegistry([tapadIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['tapadId', 'tapad_id', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.tapadId'); - expect(bid.userId.tapadId).to.equal('test-tapad-id'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'tapad.com', - uids: [{id: 'test-tapad-id', atype: 1}] - }); - }); - }) - coreStorage.setCookie('tapad_id', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook from liveIntentId html5', function (done) { - // simulate existing browser local storage values - localStorage.setItem('_li_pbid', JSON.stringify({'unifiedId': 'random-ls-identifier'})); - localStorage.setItem('_li_pbid_exp', ''); - - setSubmoduleRegistry([liveIntentIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['liveIntentId', '_li_pbid', 'html5'])); - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.lipb'); - expect(bid.userId.lipb.lipbid).to.equal('random-ls-identifier'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'liveintent.com', - uids: [{id: 'random-ls-identifier', atype: 3}] - }); - }); - }); - localStorage.removeItem('_li_pbid'); - localStorage.removeItem('_li_pbid_exp'); - done(); - }, {adUnits}); - }); - - it('test hook from liveIntentId cookie', function (done) { - coreStorage.setCookie('_li_pbid', JSON.stringify({'unifiedId': 'random-cookie-identifier'}), (new Date(Date.now() + 100000).toUTCString())); - - setSubmoduleRegistry([liveIntentIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['liveIntentId', '_li_pbid', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.lipb'); - expect(bid.userId.lipb.lipbid).to.equal('random-cookie-identifier'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'liveintent.com', - uids: [{id: 'random-cookie-identifier', atype: 3}] - }); - }); - }); - coreStorage.setCookie('_li_pbid', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook from sharedId html5', function (done) { - // simulate existing browser local storage values - localStorage.setItem('sharedid', JSON.stringify({'id': 'test_sharedId', 'ts': 1590525289611})); - localStorage.setItem('sharedid_exp', ''); - - setSubmoduleRegistry([sharedIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['sharedId', 'sharedid', 'html5'])); - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.sharedid'); - expect(bid.userId.sharedid).to.have.deep.nested.property('id'); - expect(bid.userId.sharedid).to.have.deep.nested.property('third'); - expect(bid.userId.sharedid).to.deep.equal({ - id: 'test_sharedId', - third: 'test_sharedId' - }); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'sharedid.org', - uids: [{ - id: 'test_sharedId', - atype: 1, - ext: { - third: 'test_sharedId' - } - }] - }); - }); - }); - localStorage.removeItem('sharedid'); - localStorage.removeItem('sharedid_exp'); - done(); - }, {adUnits}); - }); - - it('test hook from sharedId html5 (id not synced)', function (done) { - // simulate existing browser local storage values - localStorage.setItem('sharedid', JSON.stringify({'id': 'test_sharedId', 'ns': true, 'ts': 1590525289611})); - localStorage.setItem('sharedid_exp', ''); - - setSubmoduleRegistry([sharedIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['sharedId', 'sharedid', 'html5'])); - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.sharedid'); - expect(bid.userId.sharedid).to.have.deep.nested.property('id'); - expect(bid.userId.sharedid).to.deep.equal({ - id: 'test_sharedId' - }); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'sharedid.org', - uids: [{ - id: 'test_sharedId', - atype: 1 - }] - }); - }); - }); - localStorage.removeItem('sharedid'); - localStorage.removeItem('sharedid_exp'); - done(); - }, {adUnits}); - }); - it('test hook from sharedId cookie', function (done) { - coreStorage.setCookie('sharedid', JSON.stringify({ - 'id': 'test_sharedId', - 'ts': 1590525289611 - }), (new Date(Date.now() + 100000).toUTCString())); - - setSubmoduleRegistry([sharedIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['sharedId', 'sharedid', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.sharedid'); - expect(bid.userId.sharedid).to.have.deep.nested.property('id'); - expect(bid.userId.sharedid).to.have.deep.nested.property('third'); - expect(bid.userId.sharedid).to.deep.equal({ - id: 'test_sharedId', - third: 'test_sharedId' - }); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'sharedid.org', - uids: [{ - id: 'test_sharedId', - atype: 1, - ext: { - third: 'test_sharedId' - } - }] - }); - }); - }); - coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - it('test hook from sharedId cookie (id not synced) ', function (done) { - coreStorage.setCookie('sharedid', JSON.stringify({ - 'id': 'test_sharedId', - 'ns': true, - 'ts': 1590525289611 - }), (new Date(Date.now() + 100000).toUTCString())); - - setSubmoduleRegistry([sharedIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['sharedId', 'sharedid', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.sharedid'); - expect(bid.userId.sharedid).to.have.deep.nested.property('id'); - expect(bid.userId.sharedid).to.deep.equal({ - id: 'test_sharedId' - }); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'sharedid.org', - uids: [{ - id: 'test_sharedId', - atype: 1 - }] - }); - }); - }); - coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('eidPermissions fun with bidders', function (done) { - coreStorage.setCookie('sharedid', JSON.stringify({ - 'id': 'test222', - 'ts': 1590525289611 - }), (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([sharedIdSubmodule]); - let eidPermissions; - getPrebidInternal().setEidPermissions = function (newEidPermissions) { - eidPermissions = newEidPermissions; - } - init(config); - config.setConfig({ - userSync: { - syncDelay: 0, - userIds: [ - { - name: 'sharedId', - bidders: [ - 'sampleBidder' - ], - storage: { - type: 'cookie', - name: 'sharedid', - expires: 28 - } - } - ] - } - }); - - requestBidsHook(function () { - expect(eidPermissions).to.deep.equal( - [ - { - bidders: [ - 'sampleBidder' - ], - source: 'sharedid.org' - } - ] - ); - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - if (bid.bidder === 'sampleBidder') { - expect(bid).to.have.deep.nested.property('userId.sharedid'); - expect(bid.userId.sharedid.id).to.equal('test222'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'sharedid.org', - uids: [ - { - id: 'test222', - atype: 1, - ext: { - third: 'test222' - } - } - ] - }); - } - if (bid.bidder === 'anotherSampleBidder') { - expect(bid).to.not.have.deep.nested.property('userId.sharedid'); - expect(bid).to.not.have.property('userIdAsEids'); - } - }); - }); - coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); - getPrebidInternal().setEidPermissions = undefined; - done(); - }, {adUnits}); - }); - - it('eidPermissions fun without bidders', function (done) { - coreStorage.setCookie('sharedid', JSON.stringify({ - 'id': 'test222', - 'ts': 1590525289611 - }), (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([sharedIdSubmodule]); - let eidPermissions; - getPrebidInternal().setEidPermissions = function (newEidPermissions) { - eidPermissions = newEidPermissions; - } - init(config); - config.setConfig({ - userSync: { - syncDelay: 0, - userIds: [ - { - name: 'sharedId', - storage: { - type: 'cookie', - name: 'sharedid', - expires: 28 - } - } - ] - } - }); - - requestBidsHook(function () { - expect(eidPermissions).to.deep.equal( - [] - ); - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.sharedid'); - expect(bid.userId.sharedid.id).to.equal('test222'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'sharedid.org', - uids: [ - { - id: 'test222', - atype: 1, - ext: { - third: 'test222' - } - }] - }); - }); - }); - getPrebidInternal().setEidPermissions = undefined; - coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook from pubProvidedId config params', function (done) { - setSubmoduleRegistry([pubProvidedIdSubmodule]); - init(config); - config.setConfig({ - userSync: { - syncDelay: 0, - userIds: [{ - name: 'pubProvidedId', - params: { - eids: [{ - source: 'example.com', - uids: [{ - id: 'value read from cookie or local storage', - ext: { - stype: 'ppuid' - } - }] - }, { - source: 'id-partner.com', - uids: [{ - id: 'value read from cookie or local storage', - ext: { - stype: 'dmp' - } - }] - }], - eidsFunction: function () { - return [{ - source: 'provider.com', - uids: [{ - id: 'value read from cookie or local storage', - ext: { - stype: 'sha256email' - } - }] - }] - } - } - } - ] - } - }); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.pubProvidedId'); - expect(bid.userId.pubProvidedId).to.deep.equal([{ - source: 'example.com', - uids: [{ - id: 'value read from cookie or local storage', - ext: { - stype: 'ppuid' - } - }] - }, { - source: 'id-partner.com', - uids: [{ - id: 'value read from cookie or local storage', - ext: { - stype: 'dmp' - } - }] - }, { - source: 'provider.com', - uids: [{ - id: 'value read from cookie or local storage', - ext: { - stype: 'sha256email' - } - }] - }]); - - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'example.com', - uids: [{ - id: 'value read from cookie or local storage', - ext: { - stype: 'ppuid' - } - }] - }); - expect(bid.userIdAsEids[2]).to.deep.equal({ - source: 'provider.com', - uids: [{ - id: 'value read from cookie or local storage', - ext: { - stype: 'sha256email' - } - }] - }); - }); - }); - done(); - }, {adUnits}); - }); - - it('test hook from liveIntentId html5', function (done) { - // simulate existing browser local storage values - localStorage.setItem('_li_pbid', JSON.stringify({'unifiedId': 'random-ls-identifier', 'segments': ['123']})); - localStorage.setItem('_li_pbid_exp', ''); - - setSubmoduleRegistry([liveIntentIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['liveIntentId', '_li_pbid', 'html5'])); - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.lipb'); - expect(bid.userId.lipb.lipbid).to.equal('random-ls-identifier'); - expect(bid.userId.lipb.segments).to.include('123'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'liveintent.com', - uids: [{id: 'random-ls-identifier', atype: 3}], - ext: {segments: ['123']} - }); - }); - }); - localStorage.removeItem('_li_pbid'); - localStorage.removeItem('_li_pbid_exp'); - done(); - }, {adUnits}); - }); - - it('test hook from liveIntentId cookie', function (done) { - coreStorage.setCookie('_li_pbid', JSON.stringify({ - 'unifiedId': 'random-cookie-identifier', - 'segments': ['123'] - }), (new Date(Date.now() + 100000).toUTCString())); - - setSubmoduleRegistry([liveIntentIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['liveIntentId', '_li_pbid', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.lipb'); - expect(bid.userId.lipb.lipbid).to.equal('random-cookie-identifier'); - expect(bid.userId.lipb.segments).to.include('123'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'liveintent.com', - uids: [{id: 'random-cookie-identifier', atype: 3}], - ext: {segments: ['123']} - }); - }); - }); - coreStorage.setCookie('_li_pbid', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook from britepoolid cookies', function (done) { - // simulate existing browser local storage values - coreStorage.setCookie('britepoolid', JSON.stringify({'primaryBPID': '279c0161-5152-487f-809e-05d7f7e653fd'}), (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([britepoolIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['britepoolId', 'britepoolid', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.britepoolid'); - expect(bid.userId.britepoolid).to.equal('279c0161-5152-487f-809e-05d7f7e653fd'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'britepool.com', - uids: [{id: '279c0161-5152-487f-809e-05d7f7e653fd', atype: 3}] - }); - }); - }); - coreStorage.setCookie('britepoolid', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook from dmdId cookies', function (done) { - // simulate existing browser local storage values - coreStorage.setCookie('dmdId', 'testdmdId', (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([dmdIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['dmdId', 'dmdId', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.dmdId'); - expect(bid.userId.dmdId).to.equal('testdmdId'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'hcn.health', - uids: [{id: 'testdmdId', atype: 3}] - }); - }); - }); - coreStorage.setCookie('dmdId', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook from netId cookies', function (done) { - // simulate existing browser local storage values - coreStorage.setCookie('netId', JSON.stringify({'netId': 'fH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg'}), (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([netIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['netId', 'netId', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.netId'); - expect(bid.userId.netId).to.equal('fH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'netid.de', - uids: [{id: 'fH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg', atype: 1}] - }); - }); - }); - coreStorage.setCookie('netId', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook from intentIqId cookies', function (done) { - // simulate existing browser local storage values - coreStorage.setCookie('intentIqId', 'abcdefghijk', (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([intentIqIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['intentIqId', 'intentIqId', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.intentIqId'); - expect(bid.userId.intentIqId).to.equal('abcdefghijk'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'intentiq.com', - uids: [{id: 'abcdefghijk', atype: 1}] - }); - }); - }); - coreStorage.setCookie('intentIqId', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook from haloId html5', function (done) { - // simulate existing browser local storage values - localStorage.setItem('haloId', JSON.stringify({'haloId': 'random-ls-identifier'})); - localStorage.setItem('haloId_exp', ''); - - setSubmoduleRegistry([haloIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['haloId', 'haloId', 'html5'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.haloId'); - expect(bid.userId.haloId).to.equal('random-ls-identifier'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'audigent.com', - uids: [{id: 'random-ls-identifier', atype: 1}] - }); - }); - }); - localStorage.removeItem('haloId'); - localStorage.removeItem('haloId_exp', ''); - done(); - }, {adUnits}); - }); - - it('test hook from merkleId cookies', function (done) { - // simulate existing browser local storage values - coreStorage.setCookie('merkleId', JSON.stringify({'pam_id': {'id': 'testmerkleId', 'keyID': 1}}), (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([merkleIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['merkleId', 'merkleId', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.merkleId'); - expect(bid.userId.merkleId).to.deep.equal({'id': 'testmerkleId', 'keyID': 1}); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'merkleinc.com', - uids: [{id: 'testmerkleId', atype: 3, ext: {keyID: 1}}] - }); - }); - }); - coreStorage.setCookie('merkleId', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook from zeotapIdPlus cookies', function (done) { - // simulate existing browser local storage values - coreStorage.setCookie('IDP', btoa(JSON.stringify('abcdefghijk')), (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([zeotapIdPlusSubmodule]); - init(config); - config.setConfig(getConfigMock(['zeotapIdPlus', 'IDP', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.IDP'); - expect(bid.userId.IDP).to.equal('abcdefghijk'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'zeotap.com', - uids: [{id: 'abcdefghijk', atype: 1}] - }); - }); - }); - coreStorage.setCookie('IDP', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook from mwOpenLinkId cookies', function (done) { - // simulate existing browser local storage values - coreStorage.setCookie('mwol', JSON.stringify({eid: 'XX-YY-ZZ-123'}), (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([mwOpenLinkIdSubModule]); - init(config); - config.setConfig(getConfigMock(['mwOpenLinkId', 'mwol', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.mwOpenLinkId'); - expect(bid.userId.mwOpenLinkId).to.equal('XX-YY-ZZ-123'); - }); - }); - coreStorage.setCookie('mwol', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook from admixerId html5', function (done) { - // simulate existing browser local storage values - localStorage.setItem('admixerId', 'testadmixerId'); - localStorage.setItem('admixerId_exp', ''); - - setSubmoduleRegistry([admixerIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['admixerId', 'admixerId', 'html5'])); - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.admixerId'); - expect(bid.userId.admixerId).to.equal('testadmixerId'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'admixer.net', - uids: [{id: 'testadmixerId', atype: 3}] - }); - }); - }); - localStorage.removeItem('admixerId'); - done(); - }, {adUnits}); - }); - - it('test hook from admixerId cookie', function (done) { - coreStorage.setCookie('admixerId', 'testadmixerId', (new Date(Date.now() + 100000).toUTCString())); - - setSubmoduleRegistry([admixerIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['admixerId', 'admixerId', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.admixerId'); - expect(bid.userId.admixerId).to.equal('testadmixerId'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'admixer.net', - uids: [{id: 'testadmixerId', atype: 3}] - }); - }); - }); - coreStorage.setCookie('admixerId', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook from deepintentId cookies', function (done) { - // simulate existing browser local storage values - coreStorage.setCookie('deepintentId', 'testdeepintentId', (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([deepintentDpesSubmodule]); - init(config); - config.setConfig(getConfigMock(['deepintentId', 'deepintentId', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.deepintentId'); - expect(bid.userId.deepintentId).to.deep.equal('testdeepintentId'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'deepintent.com', - uids: [{id: 'testdeepintentId', atype: 3}] - }); - }); - }); - coreStorage.setCookie('deepintentId', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook from deepintentId html5', function (done) { - // simulate existing browser local storage values - localStorage.setItem('deepintentId', 'testdeepintentId'); - localStorage.setItem('deepintentId_exp', ''); - - setSubmoduleRegistry([deepintentDpesSubmodule]); - init(config); - config.setConfig(getConfigMock(['deepintentId', 'deepintentId', 'html5'])); - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.deepintentId'); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'deepintent.com', - uids: [{id: 'testdeepintentId', atype: 3}] - }); - }); - }); - localStorage.removeItem('deepintentId'); - done(); - }, {adUnits}); - }); - - it('test hook when pubCommonId, unifiedId, id5Id, identityLink, britepoolId, intentIqId, zeotapIdPlus, sharedId, netId, haloId, Criteo, UID 2.0, admixerId, dmdId and mwOpenLinkId have data to pass', function (done) { - coreStorage.setCookie('pubcid', 'testpubcid', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('unifiedid', JSON.stringify({'TDID': 'testunifiedid'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('id5id', JSON.stringify({'universal_uid': 'testid5id'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('idl_env', 'AiGNC8Z5ONyZKSpIPf', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('britepoolid', JSON.stringify({'primaryBPID': 'testbritepoolid'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('dmdId', 'testdmdId', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('netId', JSON.stringify({'netId': 'testnetId'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('intentIqId', 'testintentIqId', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('IDP', btoa(JSON.stringify('zeotapId')), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('sharedid', JSON.stringify({ - 'id': 'test_sharedId', - 'ts': 1590525289611 - }), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('haloId', JSON.stringify({'haloId': 'testHaloId'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('storage_criteo', JSON.stringify({'criteoId': 'test_bidid'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('mwol', JSON.stringify({eid: 'XX-YY-ZZ-123'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('uid2id', 'Sample_AD_Token', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('admixerId', 'testadmixerId', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('deepintentId', 'testdeepintentId', (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, britepoolIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, criteoIdSubmodule, mwOpenLinkIdSubModule, tapadIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'], - ['unifiedId', 'unifiedid', 'cookie'], - ['id5Id', 'id5id', 'cookie'], - ['identityLink', 'idl_env', 'cookie'], - ['britepoolId', 'britepoolid', 'cookie'], - ['dmdId', 'dmdId', 'cookie'], - ['netId', 'netId', 'cookie'], - ['sharedId', 'sharedid', 'cookie'], - ['intentIqId', 'intentIqId', 'cookie'], - ['zeotapIdPlus', 'IDP', 'cookie'], - ['haloId', 'haloId', 'cookie'], - ['criteo', 'storage_criteo', 'cookie'], - ['mwOpenLinkId', 'mwol', 'cookie'], - ['tapadId', 'tapad_id', 'cookie'], - ['uid2', 'uid2id', 'cookie'], - ['admixerId', 'admixerId', 'cookie'], - ['deepintentId', 'deepintentId', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - // verify that the PubCommonId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.pubcid'); - expect(bid.userId.pubcid).to.equal('testpubcid'); - // also check that UnifiedId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.tdid'); - expect(bid.userId.tdid).to.equal('testunifiedid'); - // also check that Id5Id id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.id5id.uid'); - expect(bid.userId.id5id.uid).to.equal('testid5id'); - // check that identityLink id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.idl_env'); - expect(bid.userId.idl_env).to.equal('AiGNC8Z5ONyZKSpIPf'); - // also check that britepoolId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.britepoolid'); - expect(bid.userId.britepoolid).to.equal('testbritepoolid'); - // also check that dmdID id was copied to bid - expect(bid).to.have.deep.nested.property('userId.dmdId'); - expect(bid.userId.dmdId).to.equal('testdmdId'); - // also check that netId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.netId'); - expect(bid.userId.netId).to.equal('testnetId'); - expect(bid).to.have.deep.nested.property('userId.sharedid'); - expect(bid.userId.sharedid).to.deep.equal({ - id: 'test_sharedId', - third: 'test_sharedId' - }); - // also check that intentIqId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.intentIqId'); - expect(bid.userId.intentIqId).to.equal('testintentIqId'); - // also check that zeotapIdPlus id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.IDP'); - expect(bid.userId.IDP).to.equal('zeotapId'); - // also check that haloId id was copied to bid - expect(bid).to.have.deep.nested.property('userId.haloId'); - expect(bid.userId.haloId).to.equal('testHaloId'); - // also check that criteo id was copied to bid - expect(bid).to.have.deep.nested.property('userId.criteoId'); - expect(bid.userId.criteoId).to.equal('test_bidid'); - // also check that mwOpenLink id was copied to bid - expect(bid).to.have.deep.nested.property('userId.mwOpenLinkId'); - expect(bid.userId.mwOpenLinkId).to.equal('XX-YY-ZZ-123'); - expect(bid.userId.uid2).to.deep.equal({ - id: 'Sample_AD_Token' - }); - // also check that criteo id was copied to bid - expect(bid).to.have.deep.nested.property('userId.admixerId'); - expect(bid.userId.admixerId).to.equal('testadmixerId'); - - // also check that deepintentId was copied to bid - expect(bid).to.have.deep.nested.property('userId.deepintentId'); - expect(bid.userId.deepintentId).to.equal('testdeepintentId'); - - expect(bid.userIdAsEids.length).to.equal(16); - }); - }); - coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('unifiedid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('id5id', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('idl_env', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('britepoolid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('dmdId', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('netId', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('intentIqId', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('IDP', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('haloId', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('storage_criteo', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('mwol', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('uid2id', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('admixerId', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('deepintentId', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook when pubCommonId, unifiedId, id5Id, britepoolId, dmdId, intentIqId, zeotapIdPlus, sharedId, criteo, netId, haloId, UID 2.0, admixerId and mwOpenLinkId have their modules added before and after init', function (done) { - coreStorage.setCookie('pubcid', 'testpubcid', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('unifiedid', JSON.stringify({'TDID': 'cookie-value-add-module-variations'}), new Date(Date.now() + 5000).toUTCString()); - coreStorage.setCookie('id5id', JSON.stringify({'universal_uid': 'testid5id'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('idl_env', 'AiGNC8Z5ONyZKSpIPf', new Date(Date.now() + 5000).toUTCString()); - coreStorage.setCookie('britepoolid', JSON.stringify({'primaryBPID': 'testbritepoolid'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('netId', JSON.stringify({'netId': 'testnetId'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('sharedid', JSON.stringify({ - 'id': 'test_sharedId', - 'ts': 1590525289611 - }), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('intentIqId', 'testintentIqId', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('IDP', btoa(JSON.stringify('zeotapId')), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('haloId', JSON.stringify({'haloId': 'testHaloId'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('dmdId', 'testdmdId', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('storage_criteo', JSON.stringify({'criteoId': 'test_bidid'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('mwol', JSON.stringify({eid: 'XX-YY-ZZ-123'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('uid2id', 'Sample_AD_Token', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('admixerId', 'testadmixerId', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('deepintentId', 'testdeepintentId', (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([]); - - // attaching before init - attachIdSystem(pubCommonIdSubmodule); - - init(config); - - // attaching after init - attachIdSystem(unifiedIdSubmodule); - attachIdSystem(id5IdSubmodule); - attachIdSystem(identityLinkSubmodule); - attachIdSystem(britepoolIdSubmodule); - attachIdSystem(netIdSubmodule); - attachIdSystem(sharedIdSubmodule); - attachIdSystem(intentIqIdSubmodule); - attachIdSystem(zeotapIdPlusSubmodule); - attachIdSystem(haloIdSubmodule); - attachIdSystem(dmdIdSubmodule); - attachIdSystem(criteoIdSubmodule); - attachIdSystem(mwOpenLinkIdSubModule); - attachIdSystem(tapadIdSubmodule); - attachIdSystem(uid2IdSubmodule); - attachIdSystem(admixerIdSubmodule); - attachIdSystem(deepintentDpesSubmodule); - - config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'], - ['unifiedId', 'unifiedid', 'cookie'], - ['id5Id', 'id5id', 'cookie'], - ['identityLink', 'idl_env', 'cookie'], - ['britepoolId', 'britepoolid', 'cookie'], - ['netId', 'netId', 'cookie'], - ['sharedId', 'sharedid', 'cookie'], - ['intentIqId', 'intentIqId', 'cookie'], - ['zeotapIdPlus', 'IDP', 'cookie'], - ['haloId', 'haloId', 'cookie'], - ['dmdId', 'dmdId', 'cookie'], - ['criteo', 'storage_criteo', 'cookie'], - ['mwOpenLinkId', 'mwol', 'cookie'], - ['tapadId', 'tapad_id', 'cookie'], - ['uid2', 'uid2id', 'cookie'], - ['admixerId', 'admixerId', 'cookie'], - ['deepintentId', 'deepintentId', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - // verify that the PubCommonId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.pubcid'); - expect(bid.userId.pubcid).to.equal('testpubcid'); - // also check that UnifiedId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.tdid'); - expect(bid.userId.tdid).to.equal('cookie-value-add-module-variations'); - // also check that Id5Id id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.id5id.uid'); - expect(bid.userId.id5id.uid).to.equal('testid5id'); - // also check that identityLink id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.idl_env'); - expect(bid.userId.idl_env).to.equal('AiGNC8Z5ONyZKSpIPf'); - // also check that britepoolId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.britepoolid'); - expect(bid.userId.britepoolid).to.equal('testbritepoolid'); - // also check that britepoolId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.netId'); - expect(bid.userId.netId).to.equal('testnetId'); - expect(bid).to.have.deep.nested.property('userId.sharedid'); - expect(bid.userId.sharedid).to.deep.equal({ - id: 'test_sharedId', - third: 'test_sharedId' - }); - // also check that intentIqId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.intentIqId'); - expect(bid.userId.intentIqId).to.equal('testintentIqId'); - - // also check that zeotapIdPlus id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.IDP'); - expect(bid.userId.IDP).to.equal('zeotapId'); - // also check that haloId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.haloId'); - expect(bid.userId.haloId).to.equal('testHaloId'); - // also check that dmdId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.dmdId'); - expect(bid.userId.dmdId).to.equal('testdmdId'); - - // also check that criteo id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.criteoId'); - expect(bid.userId.criteoId).to.equal('test_bidid'); - - // also check that mwOpenLink id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.mwOpenLinkId'); - expect(bid.userId.mwOpenLinkId).to.equal('XX-YY-ZZ-123') - expect(bid.userId.uid2).to.deep.equal({ - id: 'Sample_AD_Token' - }); - - // also check that admixerId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.admixerId'); - expect(bid.userId.admixerId).to.equal('testadmixerId'); - // also check that deepintentId was copied to bid - expect(bid).to.have.deep.nested.property('userId.deepintentId'); - expect(bid.userId.deepintentId).to.equal('testdeepintentId'); - - expect(bid.userIdAsEids.length).to.equal(16); - }); - }); - coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('unifiedid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('id5id', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('idl_env', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('britepoolid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('netId', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('intentIqId', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('IDP', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('haloId', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('dmdId', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('storage_criteo', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('mwol', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('uid2id', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('admixerId', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('deepintentId', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test hook when sharedId(opted out) have their modules added before and after init', function (done) { - coreStorage.setCookie('sharedid', JSON.stringify({ - 'id': '00000000000000000000000000', - 'ts': 1590525289611 - }), (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([]); - init(config); - - attachIdSystem(sharedIdSubmodule); - - config.setConfig(getConfigMock(['sharedId', 'sharedid', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid.userIdAsEids).to.be.undefined; - }); - }); - coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - - it('test sharedid enabled via pubcid cookie', function (done) { - coreStorage.setCookie('pubcid', 'testpubcid', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('pubcid_sharedid', 'testsharedid', (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - - const customCfg = getConfigMock(['pubCommonId', 'pubcid', 'cookie']); - addConfig(customCfg, 'params', {enableSharedId: true}); - config.setConfig(customCfg); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - // verify that the PubCommonId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.pubcid'); - expect(bid.userId.pubcid).to.equal('testpubcid'); - expect(findEid(bid.userIdAsEids, 'pubcid.org')).to.deep.equal( - {'source': 'pubcid.org', 'uids': [{'id': 'testpubcid', 'atype': 1}]} - ); - // verify that the sharedid was also copied to bid - expect(bid).to.have.deep.nested.property('userId.sharedid'); - expect(bid.userId.sharedid).to.deep.equal({id: 'testsharedid'}); - expect(findEid(bid.userIdAsEids, 'sharedid.org')).to.deep.equal( - {'source': 'sharedid.org', 'uids': [{'id': 'testsharedid', 'atype': 1}]} - ); - }); - }); - coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('pubcid_sharedid', '', EXPIRED_COOKIE_DATE); - - done(); - }, {adUnits}); - }); - - it('test sharedid disabled via pubcid cookie', function (done) { - coreStorage.setCookie('pubcid', 'testpubcid', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('pubcid_sharedid', 'testsharedid', (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - - // pubCommonId's support for sharedId is off by default - config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - // verify that the PubCommonId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.pubcid'); - expect(bid.userId.pubcid).to.equal('testpubcid'); - expect(findEid(bid.userIdAsEids, 'pubcid.org')).to.deep.equal( - {'source': 'pubcid.org', 'uids': [{'id': 'testpubcid', 'atype': 1}]} - ); - // verify that the sharedid was not added to bid - expect(bid.userId).to.not.have.property('sharedid'); - expect(findEid(bid.userIdAsEids, 'sharedid.org')).to.be.undefined; - }); - }); - coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('pubcid_sharedid', '', EXPIRED_COOKIE_DATE); - - done(); - }, {adUnits}); - }); - - it('test sharedid enabled via pubcid html5', function (done) { - coreStorage.setDataInLocalStorage('pubcid', 'testpubcid'); - coreStorage.setDataInLocalStorage('pubcid_exp', new Date(Date.now() + 5000).toUTCString()); - coreStorage.setDataInLocalStorage('pubcid_sharedid', 'testsharedid'); - coreStorage.setDataInLocalStorage('pubcid_sharedid_exp', new Date(Date.now() + 5000).toUTCString()); - - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - - const customCfg = getConfigMock(['pubCommonId', 'pubcid', 'html5']); - addConfig(customCfg, 'params', {enableSharedId: true}); - config.setConfig(customCfg); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - // verify that the PubCommonId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.pubcid'); - expect(bid.userId.pubcid).to.equal('testpubcid'); - expect(findEid(bid.userIdAsEids, 'pubcid.org')).to.deep.equal( - {'source': 'pubcid.org', 'uids': [{'id': 'testpubcid', 'atype': 1}]} - ); - // verify that the sharedid was also copied to bid - expect(bid).to.have.deep.nested.property('userId.sharedid'); - expect(bid.userId.sharedid).to.deep.equal({id: 'testsharedid'}); - expect(findEid(bid.userIdAsEids, 'sharedid.org')).to.deep.equal( - {'source': 'sharedid.org', 'uids': [{'id': 'testsharedid', 'atype': 1}]} - ); - }); - }); - coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('pubcid_sharedid', '', EXPIRED_COOKIE_DATE); - - coreStorage.removeDataFromLocalStorage('pubcid'); - coreStorage.removeDataFromLocalStorage('pubcid_exp'); - coreStorage.removeDataFromLocalStorage('pubcid_sharedid'); - coreStorage.removeDataFromLocalStorage('pubcid_sharedid_exp'); - done(); - }, {adUnits}); - }); - - it('test expired sharedid via pubcid html5', function (done) { - coreStorage.setDataInLocalStorage('pubcid', 'testpubcid'); - coreStorage.setDataInLocalStorage('pubcid_exp', new Date(Date.now() + 5000).toUTCString()); - - // set sharedid to expired already - coreStorage.setDataInLocalStorage('pubcid_sharedid', 'testsharedid'); - coreStorage.setDataInLocalStorage('pubcid_sharedid_exp', new Date(Date.now() - 100).toUTCString()); - - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - - const customCfg = getConfigMock(['pubCommonId', 'pubcid', 'html5']); - addConfig(customCfg, 'params', {enableSharedId: true}); - config.setConfig(customCfg); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - // verify that the PubCommonId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.pubcid'); - expect(bid.userId.pubcid).to.equal('testpubcid'); - expect(findEid(bid.userIdAsEids, 'pubcid.org')).to.deep.equal( - {'source': 'pubcid.org', 'uids': [{'id': 'testpubcid', 'atype': 1}]} - ); - // verify that the sharedid was not added - expect(bid.userId).to.not.have.property('sharedid'); - expect(findEid(bid.userIdAsEids, 'sharedid.org')).to.be.undefined; - }); - }); - - coreStorage.removeDataFromLocalStorage('pubcid'); - coreStorage.removeDataFromLocalStorage('pubcid_exp'); - coreStorage.removeDataFromLocalStorage('pubcid_sharedid'); - coreStorage.removeDataFromLocalStorage('pubcid_sharedid_exp'); - done(); - }, {adUnits}); - }); - - it('test pubcid coexisting with sharedid', function (done) { - coreStorage.setCookie('pubcid', 'testpubcid', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('pubcid_sharedid', 'test111', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('sharedid', JSON.stringify({ - 'id': 'test222', - 'ts': 1590525289611 - }), (new Date(Date.now() + 5000).toUTCString())); - - // When both pubcommon and sharedid are configured, pubcommon are invoked first due to - // module loading order. This mean the output from the primary sharedid module will overwrite - // the one in pubcommon. - - setSubmoduleRegistry([pubCommonIdSubmodule, sharedIdSubmodule]); - init(config); - config.setConfig(getConfigMock(['pubCommonId', 'pubcid', 'cookie'], - ['sharedId', 'sharedid', 'cookie'], - )); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - // verify that the PubCommonId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.pubcid'); - expect(bid.userId.pubcid).to.equal('testpubcid'); - expect(findEid(bid.userIdAsEids, 'pubcid.org')).to.deep.equal( - {'source': 'pubcid.org', 'uids': [{'id': 'testpubcid', 'atype': 1}]} - ); - // verify that the sharedid was also copied to bid - expect(bid).to.have.deep.nested.property('userId.sharedid'); - expect(bid.userId.sharedid.id).to.equal('test222'); - expect(findEid(bid.userIdAsEids, 'sharedid.org').uids[0].id).to.equal('test222'); - }); - }); - coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('pubcid_sharedid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); - - done(); - }, {adUnits}); - }); - - it('test hook from UID2 cookie', function (done) { - coreStorage.setCookie('uid2id', 'Sample_AD_Token', (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([uid2IdSubmodule]); - init(config); - config.setConfig(getConfigMock(['uid2', 'uid2id', 'cookie'])); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.uid2'); - expect(bid.userId.uid2).to.have.deep.nested.property('id'); - expect(bid.userId.uid2).to.deep.equal({ - id: 'Sample_AD_Token' - }); - expect(bid.userIdAsEids[0]).to.deep.equal({ - source: 'uidapi.com', - uids: [{ - id: 'Sample_AD_Token', - atype: 3, - }] - }); - }); - }); - coreStorage.setCookie('uid2id', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - it('should add new id system ', function (done) { - coreStorage.setCookie('pubcid', 'testpubcid', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('unifiedid', JSON.stringify({'TDID': 'cookie-value-add-module-variations'}), new Date(Date.now() + 5000).toUTCString()); - coreStorage.setCookie('id5id', JSON.stringify({'universal_uid': 'testid5id'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('idl_env', 'AiGNC8Z5ONyZKSpIPf', new Date(Date.now() + 5000).toUTCString()); - coreStorage.setCookie('britepoolid', JSON.stringify({'primaryBPID': 'testbritepoolid'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('dmdId', 'testdmdId', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('netId', JSON.stringify({'netId': 'testnetId'}), new Date(Date.now() + 5000).toUTCString()); - coreStorage.setCookie('sharedid', JSON.stringify({ - 'id': 'test_sharedId', - 'ts': 1590525289611 - }), new Date(Date.now() + 5000).toUTCString()); - coreStorage.setCookie('intentIqId', 'testintentIqId', (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('IDP', btoa(JSON.stringify('zeotapId')), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('haloId', JSON.stringify({'haloId': 'testHaloId'}), (new Date(Date.now() + 5000).toUTCString())); - coreStorage.setCookie('admixerId', 'testadmixerId', new Date(Date.now() + 5000).toUTCString()); - coreStorage.setCookie('deepintentId', 'testdeepintentId', new Date(Date.now() + 5000).toUTCString()); - coreStorage.setCookie('MOCKID', JSON.stringify({'MOCKID': '123456778'}), new Date(Date.now() + 5000).toUTCString()); - coreStorage.setCookie('__uid2_advertising_token', 'Sample_AD_Token', (new Date(Date.now() + 5000).toUTCString())); - - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule, id5IdSubmodule, identityLinkSubmodule, britepoolIdSubmodule, netIdSubmodule, sharedIdSubmodule, intentIqIdSubmodule, zeotapIdPlusSubmodule, haloIdSubmodule, uid2IdSubmodule, admixerIdSubmodule, deepintentDpesSubmodule, dmdIdSubmodule]); - init(config); - - config.setConfig({ - userSync: { - syncDelay: 0, - userIds: [{ - name: 'pubCommonId', storage: {name: 'pubcid', type: 'cookie'} - }, { - name: 'unifiedId', storage: {name: 'unifiedid', type: 'cookie'} - }, { - name: 'id5Id', storage: {name: 'id5id', type: 'cookie'} - }, { - name: 'identityLink', storage: {name: 'idl_env', type: 'cookie'} - }, { - name: 'britepoolId', storage: {name: 'britepoolid', type: 'cookie'} - }, { - name: 'dmdId', storage: {name: 'dmdId', type: 'cookie'} - }, { - name: 'netId', storage: {name: 'netId', type: 'cookie'} - }, { - name: 'sharedId', storage: {name: 'sharedid', type: 'cookie'} - }, { - name: 'intentIqId', storage: {name: 'intentIqId', type: 'cookie'} - }, { - name: 'zeotapIdPlus' - }, { - name: 'haloId', storage: {name: 'haloId', type: 'cookie'} - }, { - name: 'admixerId', storage: {name: 'admixerId', type: 'cookie'} - }, { - name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} - }, { - name: 'uid2' - }, { - name: 'deepintentId', storage: {name: 'deepintentId', type: 'cookie'} - }] - } - }); - - // Add new submodule named 'mockId' - attachIdSystem({ - name: 'mockId', - decode: function (value) { - return { - 'mid': value['MOCKID'] - }; - }, - getId: function (config, storedId) { - if (storedId) return {}; - return {id: {'MOCKID': '1234'}}; - } - }); - - requestBidsHook(function () { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - // check PubCommonId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.pubcid'); - expect(bid.userId.pubcid).to.equal('testpubcid'); - // check UnifiedId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.tdid'); - expect(bid.userId.tdid).to.equal('cookie-value-add-module-variations'); - // also check that Id5Id id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.id5id.uid'); - expect(bid.userId.id5id.uid).to.equal('testid5id'); - // also check that identityLink id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.idl_env'); - expect(bid.userId.idl_env).to.equal('AiGNC8Z5ONyZKSpIPf'); - // also check that britepoolId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.britepoolid'); - expect(bid.userId.britepoolid).to.equal('testbritepoolid'); - // also check that dmdId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.dmdId'); - expect(bid.userId.dmdId).to.equal('testdmdId'); - // check MockId data was copied to bid - expect(bid).to.have.deep.nested.property('userId.netId'); - expect(bid.userId.netId).to.equal('testnetId'); - // also check that sharedId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.sharedid'); - expect(bid.userId.sharedid).to.deep.equal({ - id: 'test_sharedId', - third: 'test_sharedId' - }); - // check MockId data was copied to bid - expect(bid).to.have.deep.nested.property('userId.mid'); - expect(bid.userId.mid).to.equal('123456778'); - // also check that intentIqId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.intentIqId'); - expect(bid.userId.intentIqId).to.equal('testintentIqId'); - // also check that zeotapIdPlus id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.IDP'); - expect(bid.userId.IDP).to.equal('zeotapId'); - // also check that haloId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.haloId'); - expect(bid.userId.haloId).to.equal('testHaloId'); - expect(bid.userId.uid2).to.deep.equal({ - id: 'Sample_AD_Token' - }); - - // also check that admixerId id data was copied to bid - expect(bid).to.have.deep.nested.property('userId.admixerId'); - expect(bid.userId.admixerId).to.equal('testadmixerId'); - - // also check that deepintentId was copied to bid - expect(bid).to.have.deep.nested.property('userId.deepintentId'); - expect(bid.userId.deepintentId).to.equal('testdeepintentId'); - - expect(bid.userIdAsEids.length).to.equal(14); - }); - }); - coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('unifiedid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('id5id', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('idl_env', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('britepoolid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('netId', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('sharedid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('intentIqId', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('IDP', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('haloId', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('dmdId', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('admixerId', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('deepintentId', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('MOCKID', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('mwol', '', EXPIRED_COOKIE_DATE); - done(); - }, {adUnits}); - }); - }); - - describe('callbacks at the end of auction', function () { - beforeEach(function () { - sinon.stub(events, 'getEvents').returns([]); - sinon.stub(utils, 'triggerPixel'); - coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('pubcid_sharedid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('unifiedid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('_parrable_eid', '', EXPIRED_COOKIE_DATE); - }); - - afterEach(function () { - events.getEvents.restore(); - utils.triggerPixel.restore(); - coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('pubcid_sharedid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('unifiedid', '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie('_parrable_eid', '', EXPIRED_COOKIE_DATE); - resetConsentData(); - delete window.__tcfapi; - }); - - it('pubcid callback with url', function () { - let adUnits = [getAdUnitMock()]; - let innerAdUnits; - let customCfg = getConfigMock(['pubCommonId', 'pubcid', 'cookie']); - customCfg = addConfig(customCfg, 'params', {pixelUrl: '/any/pubcid/url'}); - - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule]); - init(config); - config.setConfig(customCfg); - requestBidsHook((config) => { - innerAdUnits = config.adUnits - }, {adUnits}); - - expect(utils.triggerPixel.called).to.be.false; - events.emit(CONSTANTS.EVENTS.AUCTION_END, {}); - expect(utils.triggerPixel.getCall(0).args[0]).to.include('/any/pubcid/url'); - }); - - it('unifiedid callback with url', function () { - let adUnits = [getAdUnitMock()]; - let innerAdUnits; - let customCfg = getConfigMock(['unifiedId', 'unifiedid', 'cookie']); - addConfig(customCfg, 'params', {url: '/any/unifiedid/url'}); - - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule]); - init(config); - config.setConfig(customCfg); - requestBidsHook((config) => { - innerAdUnits = config.adUnits - }, {adUnits}); - - expect(server.requests).to.be.empty; - events.emit(CONSTANTS.EVENTS.AUCTION_END, {}); - expect(server.requests[0].url).to.equal('/any/unifiedid/url'); - }); - - it('unifiedid callback with partner', function () { - let adUnits = [getAdUnitMock()]; - let innerAdUnits; - let customCfg = getConfigMock(['unifiedId', 'unifiedid', 'cookie']); - addConfig(customCfg, 'params', {partner: 'rubicon'}); - - setSubmoduleRegistry([pubCommonIdSubmodule, unifiedIdSubmodule]); - init(config); - config.setConfig(customCfg); - requestBidsHook((config) => { - innerAdUnits = config.adUnits - }, {adUnits}); - - expect(server.requests).to.be.empty; - events.emit(CONSTANTS.EVENTS.AUCTION_END, {}); - expect(server.requests[0].url).to.equal('https://match.adsrvr.org/track/rid?ttd_pid=rubicon&fmt=json'); - }); - - it('verify sharedid callback via pubcid when enabled', function () { - let adUnits = [getAdUnitMock()]; - let innerAdUnits; - let customCfg = getConfigMock(['pubCommonId', 'pubcid', 'cookie']); - customCfg = addConfig(customCfg, 'params', {pixelUrl: '/any/pubcid/url', enableSharedId: true}); - - server.respondWith('https://id.sharedid.org/id', function(xhr) { - xhr.respond(200, {}, '{"sharedId":"testsharedid"}'); - }); - server.respondImmediately = true; - - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - config.setConfig(customCfg); - requestBidsHook((config) => { - innerAdUnits = config.adUnits - }, {adUnits}); - - expect(utils.triggerPixel.called).to.be.false; - events.emit(CONSTANTS.EVENTS.AUCTION_END, {}); - expect(utils.triggerPixel.getCall(0).args[0]).to.include('/any/pubcid/url'); - - expect(server.requests[0].url).to.equal('https://id.sharedid.org/id'); - expect(coreStorage.getCookie('pubcid_sharedid')).to.equal('testsharedid'); - }); - - it('verify no sharedid callback via pubcid when disabled', function () { - let adUnits = [getAdUnitMock()]; - let innerAdUnits; - let customCfg = getConfigMock(['pubCommonId', 'pubcid', 'cookie']); - customCfg = addConfig(customCfg, 'params', {pixelUrl: '/any/pubcid/url'}); - - server.respondWith('https://id.sharedid.org/id', function(xhr) { - xhr.respond(200, {}, '{"sharedId":"testsharedid"}'); - }); - server.respondImmediately = true; - - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - config.setConfig(customCfg); - requestBidsHook((config) => { - innerAdUnits = config.adUnits - }, {adUnits}); - - expect(utils.triggerPixel.called).to.be.false; - events.emit(CONSTANTS.EVENTS.AUCTION_END, {}); - expect(utils.triggerPixel.getCall(0).args[0]).to.include('/any/pubcid/url'); - - expect(server.requests).to.have.lengthOf(0); - expect(coreStorage.getCookie('pubcid_sharedid')).to.be.null; - }); - - it('verify sharedid optout via pubcid when enabled', function () { - let adUnits = [getAdUnitMock()]; - let innerAdUnits; - let customCfg = getConfigMock(['pubCommonId', 'pubcid', 'cookie']); - customCfg = addConfig(customCfg, 'params', {pixelUrl: '/any/pubcid/url', enableSharedId: true}); - coreStorage.setCookie('pubcid_sharedid', 'testsharedid', (new Date(Date.now() + 5000).toUTCString())); - - server.respondWith('https://id.sharedid.org/id', function(xhr) { - xhr.respond(200, {}, '{"sharedId":"00000000000000000000000000"}'); - }); - server.respondImmediately = true; - - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - config.setConfig(customCfg); - requestBidsHook((config) => { - innerAdUnits = config.adUnits - }, {adUnits}); - - expect(utils.triggerPixel.called).to.be.false; - events.emit(CONSTANTS.EVENTS.AUCTION_END, {}); - expect(utils.triggerPixel.getCall(0).args[0]).to.include('/any/pubcid/url'); - - expect(server.requests[0].url).to.equal('https://id.sharedid.org/id'); - expect(coreStorage.getCookie('pubcid_sharedid')).to.be.null; - }); - - it('verify sharedid called with consent data when gdpr applies', function () { - let adUnits = [getAdUnitMock()]; - let customCfg = getConfigMock(['pubCommonId', 'pubcid', 'cookie']); - let consentConfig = { - cmpApi: 'iab', - timeout: 7500, - allowAuctionWithoutConsent: false - }; - customCfg = addConfig(customCfg, 'params', {pixelUrl: '/any/pubcid/url', enableSharedId: true}); - - server.respondWith('https://id.sharedid.org/id?gdpr=1&gdpr_consent=abc12345234', function(xhr) { - xhr.respond(200, {}, '{"sharedId":"testsharedid"}'); - }); - server.respondImmediately = true; - - let testConsentData = { - tcString: 'abc12345234', - gdprApplies: true, - purposeOneTreatment: false, - eventStatus: 'tcloaded', - vendor: {consents: {887: true}}, - purpose: { - consents: { - 1: true - } - } - }; - - window.__tcfapi = function () { }; - sinon.stub(window, '__tcfapi').callsFake((...args) => { - args[2](testConsentData, true); - }); - - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - config.setConfig(customCfg); - setConsentConfig(consentConfig); - - consentManagementRequestBidsHook(() => { - }, {}); - requestBidsHook((config) => { - }, {adUnits}); - - expect(utils.triggerPixel.called).to.be.false; - events.emit(CONSTANTS.EVENTS.AUCTION_END, {}); - expect(utils.triggerPixel.getCall(0).args[0]).to.include('/any/pubcid/url'); - - expect(server.requests[0].url).to.equal('https://id.sharedid.org/id?gdpr=1&gdpr_consent=abc12345234'); - expect(coreStorage.getCookie('pubcid_sharedid')).to.equal('testsharedid'); - }); - }); - - describe('Set cookie behavior', function () { - let coreStorageSpy; - beforeEach(function () { - coreStorageSpy = sinon.spy(coreStorage, 'setCookie'); - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - }); - afterEach(function () { - coreStorageSpy.restore(); - }); - it('should allow submodules to override the domain', function () { - const submodule = { - submodule: { - domainOverride: function () { - return 'foo.com' - } - }, - config: { - storage: { - type: 'cookie' - } - } - } - setStoredValue(submodule, 'bar'); - expect(coreStorage.setCookie.getCall(0).args[4]).to.equal('foo.com'); - }); - - it('should pass null for domain if submodule does not override the domain', function () { - const submodule = { - submodule: {}, - config: { - storage: { - type: 'cookie' - } - } - } - setStoredValue(submodule, 'bar'); - expect(coreStorage.setCookie.getCall(0).args[4]).to.equal(null); - }); - }); - - describe('Consent changes determine getId refreshes', function () { - let expStr; - let adUnits; - - const mockIdCookieName = 'MOCKID'; - let mockGetId = sinon.stub(); - let mockDecode = sinon.stub(); - let mockExtendId = sinon.stub(); - const mockIdSystem = { - name: 'mockId', - getId: mockGetId, - decode: mockDecode, - extendId: mockExtendId - }; - const userIdConfig = { - userSync: { - userIds: [{ - name: 'mockId', - storage: { - name: 'MOCKID', - type: 'cookie', - refreshInSeconds: 30 - } - }], - auctionDelay: 5 - } - }; - - let cmpStub; - let testConsentData; - const consentConfig = { - cmpApi: 'iab', - timeout: 7500, - allowAuctionWithoutConsent: false - }; - - const sharedBeforeFunction = function () { - // clear cookies - expStr = (new Date(Date.now() + 25000).toUTCString()); - coreStorage.setCookie(mockIdCookieName, '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie(`${mockIdCookieName}_last`, '', EXPIRED_COOKIE_DATE); - coreStorage.setCookie(CONSENT_LOCAL_STORAGE_NAME, '', EXPIRED_COOKIE_DATE); - - // init - adUnits = [getAdUnitMock()]; - init(config); - - // init id system - attachIdSystem(mockIdSystem); - config.setConfig(userIdConfig); - } - const sharedAfterFunction = function () { - config.resetConfig(); - mockGetId.reset(); - mockDecode.reset(); - mockExtendId.reset(); - cmpStub.restore(); - resetConsentData(); - delete window.__cmp; - delete window.__tcfapi; - }; - - describe('TCF v1', function () { - testConsentData = { - gdprApplies: true, - consentData: 'xyz', - apiVersion: 1 - }; - - beforeEach(function () { - sharedBeforeFunction(); - - // init v1 consent management - window.__cmp = function () { - }; - delete window.__tcfapi; - cmpStub = sinon.stub(window, '__cmp').callsFake((...args) => { - args[2](testConsentData); - }); - setConsentConfig(consentConfig); - }); - - afterEach(function () { - sharedAfterFunction(); - }); - - it('does not call getId if no stored consent data and refresh is not needed', function () { - coreStorage.setCookie(mockIdCookieName, JSON.stringify({id: '1234'}), expStr); - coreStorage.setCookie(`${mockIdCookieName}_last`, (new Date(Date.now() - 1 * 1000).toUTCString()), expStr); - - let innerAdUnits; - consentManagementRequestBidsHook(() => { - }, {}); - requestBidsHook((config) => { - innerAdUnits = config.adUnits - }, {adUnits}); - - sinon.assert.notCalled(mockGetId); - sinon.assert.calledOnce(mockDecode); - sinon.assert.calledOnce(mockExtendId); - }); - - it('calls getId if no stored consent data but refresh is needed', function () { - coreStorage.setCookie(mockIdCookieName, JSON.stringify({id: '1234'}), expStr); - coreStorage.setCookie(`${mockIdCookieName}_last`, (new Date(Date.now() - 60 * 1000).toUTCString()), expStr); - - let innerAdUnits; - consentManagementRequestBidsHook(() => { - }, {}); - requestBidsHook((config) => { - innerAdUnits = config.adUnits - }, {adUnits}); - - sinon.assert.calledOnce(mockGetId); - sinon.assert.calledOnce(mockDecode); - sinon.assert.notCalled(mockExtendId); - }); - - it('calls getId if empty stored consent and refresh not needed', function () { - coreStorage.setCookie(mockIdCookieName, JSON.stringify({id: '1234'}), expStr); - coreStorage.setCookie(`${mockIdCookieName}_last`, (new Date(Date.now() - 1 * 1000).toUTCString()), expStr); - - setStoredConsentData(); - - let innerAdUnits; - consentManagementRequestBidsHook(() => { - }, {}); - requestBidsHook((config) => { - innerAdUnits = config.adUnits - }, {adUnits}); - - sinon.assert.calledOnce(mockGetId); - sinon.assert.calledOnce(mockDecode); - sinon.assert.notCalled(mockExtendId); - }); - - it('calls getId if stored consent does not match current consent and refresh not needed', function () { - coreStorage.setCookie(mockIdCookieName, JSON.stringify({id: '1234'}), expStr); - coreStorage.setCookie(`${mockIdCookieName}_last`, (new Date(Date.now() - 1 * 1000).toUTCString()), expStr); - - setStoredConsentData({ - gdprApplies: testConsentData.gdprApplies, - consentString: 'abc', - apiVersion: testConsentData.apiVersion - }); - - let innerAdUnits; - consentManagementRequestBidsHook(() => { - }, {}); - requestBidsHook((config) => { - innerAdUnits = config.adUnits - }, {adUnits}); - - sinon.assert.calledOnce(mockGetId); - sinon.assert.calledOnce(mockDecode); - sinon.assert.notCalled(mockExtendId); - }); - - it('does not call getId if stored consent matches current consent and refresh not needed', function () { - coreStorage.setCookie(mockIdCookieName, JSON.stringify({id: '1234'}), expStr); - coreStorage.setCookie(`${mockIdCookieName}_last`, (new Date(Date.now() - 1 * 1000).toUTCString()), expStr); - - setStoredConsentData({ - gdprApplies: testConsentData.gdprApplies, - consentString: testConsentData.consentData, - apiVersion: testConsentData.apiVersion - }); - - let innerAdUnits; - consentManagementRequestBidsHook(() => { - }, {}); - requestBidsHook((config) => { - innerAdUnits = config.adUnits - }, {adUnits}); - - sinon.assert.notCalled(mockGetId); - sinon.assert.calledOnce(mockDecode); - sinon.assert.calledOnce(mockExtendId); - }); - }); - - describe('findRootDomain', function () { - let sandbox; - - beforeEach(function () { - setSubmoduleRegistry([pubCommonIdSubmodule]); - init(config); - config.setConfig({ - userSync: { - syncDelay: 0, - userIds: [ - { - name: 'pubCommonId', - value: { pubcid: '11111' }, - }, - ], - }, - }); - sandbox = sinon.createSandbox(); - sandbox - .stub(coreStorage, 'getCookie') - .onFirstCall() - .returns(null) // .co.uk - .onSecondCall() - .returns('writeable'); // realdomain.co.uk; - }); - - afterEach(function () { - sandbox.restore(); - }); - - it('should just find the root domain', function () { - var domain = findRootDomain('sub.realdomain.co.uk'); - expect(domain).to.be.eq('realdomain.co.uk'); - }); - - it('should find the full domain when no subdomain is present', function () { - var domain = findRootDomain('realdomain.co.uk'); - expect(domain).to.be.eq('realdomain.co.uk'); - }); - }); - }); -}); diff --git a/test/spec/modules/validationFpdModule_spec.js b/test/spec/modules/validationFpdModule_spec.js deleted file mode 100644 index 9e8072cb9ed..00000000000 --- a/test/spec/modules/validationFpdModule_spec.js +++ /dev/null @@ -1,313 +0,0 @@ -import {expect} from 'chai'; -import * as utils from 'src/utils.js'; -import { - filterArrayData, - validateFpd -} from 'modules/validationFpdModule/index.js'; - -describe('the first party data validation module', function () { - let ortb2 = { - device: { - h: 911, - w: 1733 - }, - user: { - data: [{ - segment: [{ - id: 'foo' - }], - name: 'bar', - ext: 'string' - }] - }, - site: { - content: { - data: [{ - segment: [{ - id: 'test' - }], - name: 'content', - ext: { - foo: 'bar' - } - }] - } - } - }; - - let conf = { - device: { - h: 500, - w: 750 - }, - user: { - keywords: 'test1, test2', - gender: 'f', - data: [{ - segment: [{ - id: 'test' - }], - name: 'alt' - }] - }, - site: { - ref: 'domain.com', - page: 'www.domain.com/test', - ext: { - data: { - inventory: ['first'] - } - } - } - }; - - describe('filtering first party array data', function () { - it('returns empty array if no valid data', function () { - let arr = [{}]; - let path = 'site.children.cat'; - let child = {type: 'string'}; - let parent = 'site'; - let key = 'cat'; - let validated = filterArrayData(arr, child, path, parent, key); - expect(validated).to.deep.equal([]); - }); - - it('filters invalid type of array data', function () { - let arr = ['foo', {test: 1}]; - let path = 'site.children.cat'; - let child = {type: 'string'}; - let parent = 'site'; - let key = 'cat'; - let validated = filterArrayData(arr, child, path, parent, key); - expect(validated).to.deep.equal(['foo']); - }); - - it('filters all data for missing required children', function () { - let arr = [{test: 1}]; - let path = 'site.children.content.children.data'; - let child = {type: 'object'}; - let parent = 'site'; - let key = 'data'; - let validated = filterArrayData(arr, child, path, parent, key); - expect(validated).to.deep.equal([]); - }); - - it('filters all data for invalid required children types', function () { - let arr = [{name: 'foo', segment: 1}]; - let path = 'site.children.content.children.data'; - let child = {type: 'object'}; - let parent = 'site'; - let key = 'data'; - let validated = filterArrayData(arr, child, path, parent, key); - expect(validated).to.deep.equal([]); - }); - - it('returns only data with valid required nested children types', function () { - let arr = [{name: 'foo', segment: [{id: '1'}, {id: 2}, 'foobar']}]; - let path = 'site.children.content.children.data'; - let child = {type: 'object'}; - let parent = 'site'; - let key = 'data'; - let validated = filterArrayData(arr, child, path, parent, key); - expect(validated).to.deep.equal([{name: 'foo', segment: [{id: '1'}]}]); - }); - }); - - describe('validating first party data', function () { - it('filters user.data[0].ext for incorrect type', function () { - let validated; - let duplicate = utils.deepClone(ortb2); - let expected = { - device: { - h: 911, - w: 1733 - }, - user: { - data: [{ - segment: [{ - id: 'foo' - }], - name: 'bar' - }] - }, - site: { - content: { - data: [{ - segment: [{ - id: 'test' - }], - name: 'content', - ext: { - foo: 'bar' - } - }] - } - } - }; - - validated = validateFpd(duplicate); - expect(validated).to.deep.equal(expected); - }); - - it('filters user and site for empty data', function () { - let validated; - let duplicate = utils.deepClone(ortb2); - let expected = { - device: { - h: 911, - w: 1733 - } - }; - - duplicate.user.data = []; - duplicate.site.content.data = []; - - validated = validateFpd(duplicate); - expect(validated).to.deep.equal(expected); - }); - - it('filters user for empty valid segment values', function () { - let validated; - let duplicate = utils.deepClone(ortb2); - let expected = { - device: { - h: 911, - w: 1733 - }, - site: { - content: { - data: [{ - segment: [{ - id: 'test' - }], - name: 'content', - ext: { - 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); - }); - - it('filters user.data[0].ext and site.content.data[0].segement[1] for invalid data', function () { - let validated; - let duplicate = utils.deepClone(ortb2); - let expected = { - device: { - h: 911, - w: 1733 - }, - user: { - data: [{ - segment: [{ - id: 'foo' - }], - name: 'bar' - }] - }, - site: { - content: { - data: [{ - segment: [{ - id: 'test' - }], - name: 'content', - ext: { - foo: 'bar' - } - }] - } - } - }; - - duplicate.site.content.data[0].segment.push({test: 3}); - - validated = validateFpd(duplicate); - expect(validated).to.deep.equal(expected); - }); - - it('filters device for invalid data types', function () { - let validated; - let duplicate = utils.deepClone(ortb2); - duplicate.device = { - h: '1', - w: '1' - } - - let expected = { - user: { - data: [{ - segment: [{ - id: 'foo' - }], - name: 'bar' - }] - }, - site: { - content: { - data: [{ - segment: [{ - id: 'test' - }], - name: 'content', - ext: { - foo: 'bar' - } - }] - } - } - }; - - duplicate.site.content.data[0].segment.push({test: 3}); - - validated = validateFpd(duplicate); - expect(validated).to.deep.equal(expected); - }); - - it('filters cur for invalid data type', function () { - let validated; - let duplicate = utils.deepClone(ortb2); - duplicate.cur = 8; - - let expected = { - device: { - h: 911, - w: 1733 - }, - user: { - data: [{ - segment: [{ - id: 'foo' - }], - name: 'bar' - }] - }, - site: { - content: { - data: [{ - segment: [{ - id: 'test' - }], - name: 'content', - ext: { - foo: 'bar' - } - }] - } - } - }; - - 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 deleted file mode 100644 index d78a5ce04f6..00000000000 --- a/test/spec/modules/vdoaiBidAdapter_spec.js +++ /dev/null @@ -1,141 +0,0 @@ -import {assert, expect} from 'chai'; -import {spec} from 'modules/vdoaiBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; - -const ENDPOINT_URL = 'https://prebid.vdo.ai/auction'; - -describe('vdoaiBidAdapter', function () { - const adapter = newBidder(spec); - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'vdoai', - 'params': { - placementId: 'testPlacementId' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [ - [300, 250] - ], - 'bidId': '1234asdf1234', - 'bidderRequestId': '1234asdf1234asdf', - 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf120' - }; - it('should return true where required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - }); - describe('buildRequests', function () { - let bidRequests = [ - { - 'bidder': 'vdoai', - 'params': { - placementId: 'testPlacementId' - }, - 'sizes': [ - [300, 250] - ], - 'bidId': '23beaa6af6cdde', - 'bidderRequestId': '19c0c1efdf37e7', - 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf1', - 'mediaTypes': 'banner' - } - ]; - - let bidderRequests = { - 'refererInfo': { - 'numIframes': 0, - 'reachedTop': true, - 'referer': 'https://example.com', - 'stack': ['https://example.com'] - } - }; - - const request = spec.buildRequests(bidRequests, bidderRequests); - it('sends bid request to our endpoint via POST', function () { - expect(request[0].method).to.equal('POST'); - }); - it('attaches source and version to endpoint URL as query params', function () { - expect(request[0].url).to.equal(ENDPOINT_URL); - }); - }); - - describe('interpretResponse', function () { - let bidRequest = [ - { - 'method': 'POST', - 'url': ENDPOINT_URL, - 'data': { - 'placementId': 'testPlacementId', - 'width': '300', - 'height': '200', - 'bidId': 'bidId123', - 'referer': 'www.example.com' - } - - } - ]; - let serverResponse = { - body: { - 'vdoCreative': '

I am an ad

', - 'price': 4.2, - 'adid': '12345asdfg', - 'currency': 'EUR', - 'statusMessage': 'Bid available', - 'requestId': 'bidId123', - 'width': 300, - 'height': 250, - 'netRevenue': true - } - }; - it('should get the correct bid response', function () { - let expectedResponse = [{ - 'requestId': 'bidId123', - 'cpm': 4.2, - 'width': 300, - 'height': 250, - 'creativeId': '12345asdfg', - 'currency': 'EUR', - 'netRevenue': true, - 'ttl': 3000, - 'ad': '

I am an ad

' - }]; - let result = spec.interpretResponse(serverResponse, bidRequest[0]); - expect(Object.keys(result)).to.deep.equal(Object.keys(expectedResponse)); - }); - - it('handles instream video responses', function () { - let serverResponse = { - body: { - 'vdoCreative': '', - 'price': 4.2, - 'adid': '12345asdfg', - 'currency': 'EUR', - 'statusMessage': 'Bid available', - 'requestId': 'bidId123', - 'width': 300, - 'height': 250, - 'netRevenue': true, - 'mediaType': 'video' - } - }; - let bidRequest = [ - { - 'method': 'POST', - 'url': ENDPOINT_URL, - 'data': { - 'placementId': 'testPlacementId', - 'width': '300', - 'height': '200', - 'bidId': 'bidId123', - 'referer': 'www.example.com', - 'mediaType': 'video' - } - } - ]; - - let result = spec.interpretResponse(serverResponse, bidRequest[0]); - expect(result[0]).to.have.property('vastXml'); - expect(result[0]).to.have.property('mediaType', 'video'); - }); - }); -}); diff --git a/test/spec/modules/verizonMediaIdSystem_spec.js b/test/spec/modules/verizonMediaIdSystem_spec.js deleted file mode 100644 index 10054b5674c..00000000000 --- a/test/spec/modules/verizonMediaIdSystem_spec.js +++ /dev/null @@ -1,204 +0,0 @@ -import {expect} from 'chai'; -import * as utils from 'src/utils.js'; -import {verizonMediaIdSubmodule} from 'modules/verizonMediaIdSystem.js'; - -describe('Verizon Media ID Submodule', () => { - const HASHED_EMAIL = '6bda6f2fa268bf0438b5423a9861a2cedaa5dec163c03f743cfe05c08a8397b2'; - const PIXEL_ID = '1234'; - const PROD_ENDPOINT = `https://ups.analytics.yahoo.com/ups/${PIXEL_ID}/fed`; - const OVERRIDE_ENDPOINT = 'https://foo/bar'; - - it('should have the correct module name declared', () => { - expect(verizonMediaIdSubmodule.name).to.equal('verizonMediaId'); - }); - - it('should have the correct TCFv2 Vendor ID declared', () => { - expect(verizonMediaIdSubmodule.gvlid).to.equal(25); - }); - - describe('getId()', () => { - let ajaxStub; - let getAjaxFnStub; - let consentData; - beforeEach(() => { - ajaxStub = sinon.stub(); - getAjaxFnStub = sinon.stub(verizonMediaIdSubmodule, 'getAjaxFn'); - getAjaxFnStub.returns(ajaxStub); - - consentData = { - gdpr: { - gdprApplies: 1, - consentString: 'GDPR_CONSENT_STRING' - }, - uspConsent: 'USP_CONSENT_STRING' - }; - }); - - afterEach(() => { - getAjaxFnStub.restore(); - }); - - function invokeGetIdAPI(configParams, consentData) { - let result = verizonMediaIdSubmodule.getId({ - params: configParams - }, consentData); - if (typeof result === 'object') { - result.callback(sinon.stub()); - } - return result; - } - - it('returns undefined if he and pixelId params are not passed', () => { - expect(invokeGetIdAPI({}, consentData)).to.be.undefined; - expect(ajaxStub.callCount).to.equal(0); - }); - - it('returns undefined if the pixelId param is not passed', () => { - expect(invokeGetIdAPI({ - he: HASHED_EMAIL - }, consentData)).to.be.undefined; - expect(ajaxStub.callCount).to.equal(0); - }); - - it('returns undefined if the he param is not passed', () => { - expect(invokeGetIdAPI({ - pixelId: PIXEL_ID - }, consentData)).to.be.undefined; - expect(ajaxStub.callCount).to.equal(0); - }); - - it('returns an object with the callback function if the correct params are passed', () => { - let result = invokeGetIdAPI({ - he: HASHED_EMAIL, - pixelId: PIXEL_ID - }, consentData); - expect(result).to.be.an('object').that.has.all.keys('callback'); - expect(result.callback).to.be.a('function'); - }); - - it('Makes an ajax GET request to the production API endpoint with query params', () => { - invokeGetIdAPI({ - he: HASHED_EMAIL, - pixelId: PIXEL_ID - }, consentData); - - const expectedParams = { - he: HASHED_EMAIL, - pixelId: PIXEL_ID, - '1p': '0', - gdpr: '1', - gdpr_consent: consentData.gdpr.consentString, - us_privacy: consentData.uspConsent - }; - const requestQueryParams = utils.parseQS(ajaxStub.firstCall.args[0].split('?')[1]); - - 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}); - }); - - it('Makes an ajax GET request to the specified override API endpoint with query params', () => { - invokeGetIdAPI({ - he: HASHED_EMAIL, - endpoint: OVERRIDE_ENDPOINT - }, consentData); - - const expectedParams = { - he: HASHED_EMAIL, - '1p': '0', - gdpr: '1', - gdpr_consent: consentData.gdpr.consentString, - us_privacy: consentData.uspConsent - }; - const requestQueryParams = utils.parseQS(ajaxStub.firstCall.args[0].split('?')[1]); - - 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}); - }); - - it('sets the callbacks param of the ajax function call correctly', () => { - invokeGetIdAPI({ - he: HASHED_EMAIL, - pixelId: PIXEL_ID, - }, consentData); - - expect(ajaxStub.firstCall.args[1]).to.be.an('object').that.has.all.keys(['success', 'error']); - }); - - it('sets GDPR consent data flag correctly when call is under GDPR jurisdiction.', () => { - invokeGetIdAPI({ - he: HASHED_EMAIL, - pixelId: PIXEL_ID, - }, consentData); - - const requestQueryParams = utils.parseQS(ajaxStub.firstCall.args[0].split('?')[1]); - expect(requestQueryParams.gdpr).to.equal('1'); - expect(requestQueryParams.gdpr_consent).to.equal(consentData.gdpr.consentString); - }); - - it('sets GDPR consent data flag correctly when call is NOT under GDPR jurisdiction.', () => { - consentData.gdpr.gdprApplies = false; - - invokeGetIdAPI({ - he: HASHED_EMAIL, - pixelId: PIXEL_ID, - }, consentData); - - const requestQueryParams = utils.parseQS(ajaxStub.firstCall.args[0].split('?')[1]); - expect(requestQueryParams.gdpr).to.equal('0'); - expect(requestQueryParams.gdpr_consent).to.equal(''); - }); - - [1, '1', true].forEach(firstPartyParamValue => { - it(`sets 1p payload property to '1' for a config value of ${firstPartyParamValue}`, () => { - invokeGetIdAPI({ - '1p': firstPartyParamValue, - he: HASHED_EMAIL, - pixelId: PIXEL_ID, - }, consentData); - - const requestQueryParams = utils.parseQS(ajaxStub.firstCall.args[0].split('?')[1]); - expect(requestQueryParams['1p']).to.equal('1'); - }); - }); - }); - - describe('decode()', () => { - const VALID_API_RESPONSES = [{ - key: 'vmiud', - expected: '1234', - payload: { - vmuid: '1234' - } - }, - { - key: 'connectid', - expected: '4567', - payload: { - connectid: '4567' - } - }, - { - key: 'both', - expected: '4567', - payload: { - vmuid: '1234', - connectid: '4567' - } - }]; - VALID_API_RESPONSES.forEach(responseData => { - it('should return a newly constructed object with the connectid for a payload with ${responseData.key} key(s)', () => { - expect(verizonMediaIdSubmodule.decode(responseData.payload)).to.deep.equal( - {connectid: responseData.expected} - ); - }); - }); - - [{}, '', {foo: 'bar'}].forEach((response) => { - it(`should return undefined for an invalid response "${JSON.stringify(response)}"`, () => { - expect(verizonMediaIdSubmodule.decode(response)).to.be.undefined; - }); - }); - }); -}); diff --git a/test/spec/modules/viBidAdapter_spec.js b/test/spec/modules/viBidAdapter_spec.js deleted file mode 100644 index e1a88c004bb..00000000000 --- a/test/spec/modules/viBidAdapter_spec.js +++ /dev/null @@ -1,911 +0,0 @@ -import { - ratioToPercentageCeil, - merge, - getDocumentHeight, - getOffset, - getWindowParents, - getRectCuts, - getTopmostReachableWindow, - topDocumentIsReachable, - isInsideIframe, - isInsideSafeframe, - getIframeType, - getFrameElements, - getElementCuts, - getInViewRatio, - getMayBecomeVisible, - getInViewPercentage, - getInViewRatioInsideTopFrame, - getOffsetTopDocument, - getOffsetTopDocumentPercentage, - getOffsetToView, - getOffsetToViewPercentage, - area, - get, - getViewabilityDescription, - mergeArrays, - documentFocus -} from 'modules/viBidAdapter.js'; - -describe('ratioToPercentageCeil', () => { - it('1 converts to percentage', () => - expect(ratioToPercentageCeil(0.01)).to.equal(1)); - it('2 converts to percentage', () => - expect(ratioToPercentageCeil(0.00000000001)).to.equal(1)); - it('3 converts to percentage', () => - expect(ratioToPercentageCeil(0.5)).to.equal(50)); - it('4 converts to percentage', () => - expect(ratioToPercentageCeil(1)).to.equal(100)); - it('5 converts to percentage', () => - expect(ratioToPercentageCeil(0.99)).to.equal(99)); - it('6 converts to percentage', () => - expect(ratioToPercentageCeil(0.990000000000001)).to.equal(100)); -}); - -describe('merge', () => { - it('merges two objects', () => { - expect( - merge({ a: 1, b: 2, d: 0 }, { a: 2, b: 2, c: 3 }, (a, b) => a + b) - ).to.deep.equal({ a: 3, b: 4, c: 3, d: 0 }); - }); -}); - -describe('getDocumentHeight', () => { - [ - { - curDocument: { - body: { - clientHeight: 0, - offsetHeight: 0, - scrollHeight: 0 - }, - documentElement: { - clientHeight: 0, - offsetHeight: 0, - scrollHeight: 0 - } - }, - expected: 0 - }, - { - curDocument: { - body: { - clientHeight: 0, - offsetHeight: 13, - scrollHeight: 24 - }, - documentElement: { - clientHeight: 0, - offsetHeight: 0, - scrollHeight: 0 - } - }, - expected: 24 - }, - { - curDocument: { - body: { - clientHeight: 0, - offsetHeight: 13, - scrollHeight: 24 - }, - documentElement: { - clientHeight: 100, - offsetHeight: 50, - scrollHeight: 30 - } - }, - expected: 100 - } - ].forEach(({ curDocument, expected }) => - expect(getDocumentHeight(curDocument)).to.be.equal(expected) - ); -}); - -describe('getOffset', () => { - [ - { - element: { - ownerDocument: { - defaultView: { - pageXOffset: 0, - pageYOffset: 0 - } - }, - getBoundingClientRect: () => ({ - top: 0, - right: 0, - bottom: 0, - left: 0 - }) - }, - expected: { - top: 0, - right: 0, - bottom: 0, - left: 0 - } - } - ].forEach(({ description, element, expected }, i) => - it( - 'returns element offsets from the document edges (including scroll): ' + - i, - () => expect(getOffset(element)).to.be.deep.equal(expected) - ) - ); - it('Throws when there is no window', () => - expect( - getOffset.bind(null, { - ownerDocument: { - defaultView: null - }, - getBoundingClientRect: () => ({ - top: 0, - right: 0, - bottom: 0, - left: 0 - }) - }) - ).to.throw()); -}); - -describe('getWindowParents', () => { - const win = {}; - win.top = win; - win.parent = win; - const win1 = { top: win, parent: win }; - const win2 = { top: win, parent: win1 }; - const win3 = { top: win, parent: win2 }; - - it('get parents up to the top', () => - expect(getWindowParents(win3)).to.be.deep.equal([win2, win1, win])); -}); - -describe('getTopmostReachableWindow', () => { - const win = {}; - win.top = win; - win.parent = win; - const win1 = { top: win, parent: win }; - const win2 = { top: win, parent: win1 }; - const win3 = { top: win, parent: win2 }; - - it('get parents up to the top', () => - expect(getTopmostReachableWindow(win3)).to.be.equal(win)); -}); - -const topWindow = { document, frameElement: 0 }; -topWindow.top = topWindow; -topWindow.parent = topWindow; -const topFrameElement = { - ownerDocument: { - defaultView: topWindow - } -}; -const frameWindow1 = { - top: topWindow, - parent: topWindow, - frameElement: topFrameElement -}; -const frameElement1 = { - ownerDocument: { - defaultView: frameWindow1 - } -}; -const frameWindow2 = { - top: topWindow, - parent: frameWindow1, - frameElement: frameElement1 -}; -const frameElement2 = { - ownerDocument: { - defaultView: frameWindow2 - } -}; -const frameWindow3 = { - top: topWindow, - parent: frameWindow2, - frameElement: frameElement2 -}; - -describe('topDocumentIsReachable', () => { - it('returns true if it no inside iframe', () => - expect(topDocumentIsReachable(topWindow)).to.be.true); - it('returns true if it can access top document', () => - expect(topDocumentIsReachable(frameWindow3)).to.be.true); -}); - -describe('isInsideIframe', () => { - it('returns true if window !== window.top', () => - expect(isInsideIframe(topWindow)).to.be.false); - it('returns true if window !== window.top', () => - expect(isInsideIframe(frameWindow1)).to.be.true); -}); - -const safeframeWindow = { $sf: {} }; - -describe('isInsideSafeframe', () => { - it('returns true if top window is not reachable and window.$sf is defined', () => - expect(isInsideSafeframe(safeframeWindow)).to.be.true); -}); - -const hostileFrameWindow = {}; - -describe('getIframeType', () => { - it('returns undefined when is not inside iframe', () => - expect(getIframeType(topWindow)).to.be.undefined); - it("returns 'safeframe' when inside sf", () => - expect(getIframeType(safeframeWindow)).to.be.equal('safeframe')); - it("returns 'friendly' when inside friendly iframe and can reach top window", () => - expect(getIframeType(frameWindow3)).to.be.equal('friendly')); - it("returns 'nonfriendly' when cannot get top window", () => - expect(getIframeType(hostileFrameWindow)).to.be.equal('nonfriendly')); -}); - -describe('getFrameElements', () => { - it('it returns a list iframe elements up to the top, topmost goes first', () => { - expect(getFrameElements(frameWindow3)).to.be.deep.equal([ - topFrameElement, - frameElement1, - frameElement2 - ]); - }); -}); - -describe('area', () => { - it('calculates area', () => expect(area(10, 10)).to.be.equal(100)); - it('calculates area', () => - expect( - area(10, 10, { top: -2, left: -2, bottom: 0, right: 0 }) - ).to.be.equal(64)); -}); - -describe('getElementCuts', () => { - it('returns element cuts', () => - expect( - getElementCuts({ - getBoundingClientRect() { - return { - top: 0, - right: 200, - bottom: 200, - left: 0 - }; - }, - ownerDocument: { - defaultView: { - innerHeight: 1000, - innerWidth: 1000 - } - } - }) - ).to.be.deep.equal({ - top: 0, - right: 0, - bottom: 0, - left: 0 - })); -}); - -describe('getInViewRatio', () => { - it('returns inViewRatio', () => - expect( - getInViewRatio({ - ownerDocument: { - defaultView: { - innerHeight: 1000, - innerWidth: 1000 - } - }, - offsetWidth: 200, - offsetHeight: 200, - getBoundingClientRect() { - return { - top: 0, - right: 200, - bottom: 200, - left: 0 - }; - } - }) - ).to.be.deep.equal(1)); -}); - -describe('getMayBecomeVisible', () => { - it('returns true if not inside iframe of visible inside the iframe', () => - expect( - getMayBecomeVisible({ - ownerDocument: { - defaultView: { - innerHeight: 1000, - innerWidth: 1000 - } - }, - offsetWidth: 200, - offsetHeight: 200, - getBoundingClientRect() { - return { - top: 0, - right: 200, - bottom: 200, - left: 0 - }; - } - }) - ).to.be.true); -}); - -describe('getInViewPercentage', () => { - it('returns inViewRatioPercentage', () => - expect( - getInViewPercentage({ - ownerDocument: { - defaultView: { - innerHeight: 1000, - innerWidth: 1000 - } - }, - offsetWidth: 200, - offsetHeight: 200, - getBoundingClientRect() { - return { - top: 0, - right: 200, - bottom: 200, - left: 0 - }; - } - }) - ).to.be.deep.equal(100)); -}); - -describe('getInViewRatioInsideTopFrame', () => { - it('returns inViewRatio', () => - expect( - getInViewRatioInsideTopFrame({ - ownerDocument: { - defaultView: { - innerHeight: 1000, - innerWidth: 1000 - } - }, - offsetWidth: 200, - offsetHeight: 200, - getBoundingClientRect() { - return { - top: 0, - right: 200, - bottom: 200, - left: 0 - }; - } - }) - ).to.be.deep.equal(1)); -}); - -describe('getOffsetTopDocument', () => { - it('returns offset relative to the top document', () => - expect( - getOffsetTopDocument({ - ownerDocument: { - defaultView: { - pageXOffset: 0, - pageYOffset: 0 - } - }, - getBoundingClientRect: () => ({ - top: 0, - right: 0, - bottom: 0, - left: 0 - }) - }) - ).to.be.deep.equal({ - top: 0, - right: 0, - bottom: 0, - left: 0 - })); -}); - -describe('getOffsetTopDocumentPercentage', () => { - it('returns offset from the top as a percentage of the page length', () => { - const topWindow = { - pageXOffset: 0, - pageYOffset: 100, - document: { - body: { - clientHeight: 1000 - } - } - }; - topWindow.top = topWindow; - topWindow.parent = topWindow; - expect( - getOffsetTopDocumentPercentage({ - ownerDocument: { - defaultView: topWindow - }, - getBoundingClientRect: () => ({ - top: 100, - right: 0, - bottom: 0, - left: 0 - }) - }) - ).to.be.equal(20); - }); - it('throws when cannot get window', () => - expect(() => - getOffsetTopDocumentPercentage({ - ownerDocument: {} - }) - ).to.throw()); - it("throw when top document isn't reachable", () => { - const topWindow = { ...topWindow, document: null }; - expect(() => - getOffsetTopDocumentPercentage({ - ownerDocument: { - defaultView: { - top: topWindow - } - } - }) - ).to.throw(); - }); -}); - -describe('getOffsetToView', () => { - expect( - getOffsetToView({ - ownerDocument: { - defaultView: { - scrollY: 0, - pageXOffset: 0, - pageYOffset: 0 - } - }, - getBoundingClientRect: () => ({ - top: 0, - right: 0, - bottom: 0, - left: 0 - }) - }) - ).to.be.equal(0); -}); - -describe('getOffsetToView', () => { - expect( - getOffsetToViewPercentage({ - ownerDocument: { - defaultView: { - scrollY: 0, - pageXOffset: 0, - pageYOffset: 0, - document: { - body: { - clientHeight: 1000 - } - } - } - }, - getBoundingClientRect: () => ({ - top: 0, - right: 0, - bottom: 0, - left: 0 - }) - }) - ).to.be.equal(0); -}); - -describe('getCuts without vCuts', () => { - const cases = { - 'completely in view 1': { - top: 0, - bottom: 200, - right: 200, - left: 0, - vw: 300, - vh: 300, - expected: { - top: 0, - right: 0, - bottom: 0, - left: 0 - } - }, - 'completely in view 2': { - top: 100, - bottom: 200, - right: 200, - left: 0, - vw: 300, - vh: 300, - expected: { - top: 0, - right: 0, - bottom: 0, - left: 0 - } - }, - 'half cut from the top': { - top: -200, - bottom: 200, - right: 200, - left: 0, - vw: 300, - vh: 300, - expected: { - top: -200, - right: 0, - bottom: 0, - left: 0 - } - }, - 'half cut from the bottom': { - top: 0, - bottom: 600, - right: 200, - left: 0, - vw: 300, - vh: 300, - expected: { - top: 0, - right: 0, - bottom: -300, - left: 0 - } - }, - 'quarter cut from top and bottom': { - top: -25, - bottom: 75, - right: 200, - left: 0, - vw: 300, - vh: 50, - expected: { - top: -25, - right: 0, - bottom: -25, - left: 0 - } - }, - 'out of view top': { - top: -200, - bottom: -5, - right: 200, - left: 0, - vw: 300, - vh: 200, - expected: { - top: -200, - right: 0, - bottom: 0, - left: 0 - } - }, - 'out of view bottom': { - top: 250, - bottom: 500, - right: 200, - left: 0, - vw: 300, - vh: 200, - expected: { - top: 0, - right: 0, - bottom: -300, - left: 0 - } - }, - 'half cut from left': { - top: 0, - bottom: 200, - left: -200, - right: 200, - vw: 300, - vh: 300, - expected: { - top: 0, - right: 0, - bottom: 0, - left: -200 - } - }, - 'half cut from left and top': { - top: -100, - bottom: 100, - left: -200, - right: 200, - vw: 300, - vh: 300, - expected: { - top: -100, - right: 0, - bottom: 0, - left: -200 - } - }, - 'quarter cut from all sides': { - top: -100, - left: -100, - bottom: 300, - right: 300, - vw: 200, - vh: 200, - expected: { - top: -100, - right: -100, - bottom: -100, - left: -100 - } - } - }; - for (let descr in cases) { - it(descr, () => { - const { expected, vh, vw, ...rect } = cases[descr]; - expect(getRectCuts(rect, vh, vw)).to.deep.equal(expected); - }); - } -}); - -describe('getCuts with vCuts', () => { - const cases = { - 'completely in view 1, half-cut viewport from top': { - top: 0, - right: 200, - bottom: 200, - left: 0, - vw: 200, - vh: 200, - vCuts: { - top: -100, - right: 0, - bottom: 0, - left: 0 - }, - expected: { - top: -100, - right: 0, - bottom: 0, - left: 0 - } - }, - 'completely in view 2, half-cut viewport from bottom': { - top: 100, - bottom: 200, - right: 200, - left: 0, - vw: 300, - vh: 300, - vCuts: { - top: 0, - right: 0, - bottom: -150, - left: 0 - }, - expected: { - top: 0, - right: 0, - bottom: -50, - left: 0 - } - }, - 'half cut from the top, 1/3 viewport cut from the bottom': { - top: -200, - bottom: 200, - right: 200, - left: 0, - vw: 300, - vh: 300, - vCuts: { - top: 0, - right: 0, - bottom: -100, - left: 0 - }, - expected: { - top: -200, - right: 0, - bottom: 0, - left: 0 - } - }, - 'half cut from the bottom': { - top: 0, - bottom: 600, - right: 200, - left: 0, - vw: 300, - vh: 300, - expected: { - top: 0, - right: 0, - bottom: -300, - left: 0 - } - }, - 'quarter cut from top and bottom': { - top: -25, - bottom: 75, - right: 200, - left: 0, - vw: 300, - vh: 50, - expected: { - top: -25, - right: 0, - bottom: -25, - left: 0 - } - }, - 'out of view top': { - top: -200, - bottom: -5, - right: 200, - left: 0, - vw: 300, - vh: 200, - expected: { - top: -200, - right: 0, - bottom: 0, - left: 0 - } - }, - 'out of view bottom': { - top: 250, - bottom: 500, - right: 200, - left: 0, - vw: 300, - vh: 200, - expected: { - top: 0, - right: 0, - bottom: -300, - left: 0 - } - }, - 'half cut from left': { - top: 0, - bottom: 200, - left: -200, - right: 200, - vw: 300, - vh: 300, - expected: { - top: 0, - right: 0, - bottom: 0, - left: -200 - } - }, - 'half cut from left and top': { - top: -100, - bottom: 100, - left: -200, - right: 200, - vw: 300, - vh: 300, - expected: { - top: -100, - right: 0, - bottom: 0, - left: -200 - } - }, - 'quarter cut from all sides': { - top: -100, - left: -100, - bottom: 300, - right: 300, - vw: 200, - vh: 200, - expected: { - top: -100, - right: -100, - bottom: -100, - left: -100 - } - } - }; - for (let descr in cases) { - it(descr, () => { - const { expected, vh, vw, vCuts, ...rect } = cases[descr]; - expect(getRectCuts(rect, vh, vw, vCuts)).to.deep.equal(expected); - }); - } -}); - -describe('get', () => { - it('returns a property in a nested object 1', () => - expect(get(['a'], { a: 1 })).to.equal(1)); - it('returns a property in a nested object 2', () => - expect(get(['a', 'b'], { a: { b: 1 } })).to.equal(1)); - it('returns a property in a nested object 3', () => - expect(get(['a', 'b'], { a: { b: 1 } })).to.equal(1)); - it('returns undefined if property does not exist', () => - expect(get(['a', 'b'], { b: 1 })).to.equal(undefined)); - it('returns undefined if property does not exist', () => - expect(get(['a', 'b'], undefined)).to.equal(undefined)); - it('returns undefined if property does not exist', () => - expect(get(['a', 'b'], 1213)).to.equal(undefined)); - const DEFAULT = -5; - it('returns defaultValue if property does not exist', () => - expect(get(['a', 'b'], { b: 1 }, DEFAULT)).to.equal(DEFAULT)); - it('returns defaultValue if property does not exist', () => - expect(get(['a', 'b'], undefined, DEFAULT)).to.equal(DEFAULT)); - it('returns defaultValue if property does not exist', () => - expect(get(['a', 'b'], 1213, DEFAULT)).to.equal(DEFAULT)); - it('can work with arrays 1', () => expect(get([0, 1], [[1, 2]])).to.equal(2)); - it('can work with arrays 2', () => - expect(get([0, 'a'], [{ a: 42 }])).to.equal(42)); -}); - -describe('getViewabilityDescription', () => { - it('returns error when there is no element', () => { - expect(getViewabilityDescription(null)).to.deep.equal({ - error: 'no element' - }); - }); - it('returns only iframe type for nonfrienly iframe', () => { - expect( - getViewabilityDescription({ - ownerDocument: { - defaultView: {} - } - }) - ).to.deep.equal({ - iframeType: 'nonfriendly' - }); - }); - it('returns only iframe type for safeframe iframe', () => { - expect( - getViewabilityDescription({ - ownerDocument: { - defaultView: { - $sf: true - } - } - }) - ).to.deep.equal({ - iframeType: 'safeframe' - }); - }); -}); - -describe('mergeSizes', () => { - it('merges provides arrays of tuples, leaving only unique', () => { - expect( - mergeArrays(x => x.join(','), [[1, 2], [2, 4]], [[1, 2]]) - ).to.deep.equal([[1, 2], [2, 4]]); - }); - it('merges provides arrays of tuples, leaving only unique', () => { - expect( - mergeArrays( - x => x.join(','), - [[1, 2], [2, 4]], - [[1, 2]], - [[400, 500], [500, 600]] - ) - ).to.deep.equal([[1, 2], [2, 4], [400, 500], [500, 600]]); - }); -}); - -describe('documentFocus', () => { - it('calls hasFocus function if it present, converting boolean to an int 0/1 value, returns undefined otherwise', () => { - expect( - documentFocus({ - hasFocus: () => true - }) - ).to.equal(1); - expect( - documentFocus({ - hasFocus: () => false - }) - ).to.equal(0); - expect(documentFocus({})).to.be.undefined; - }); -}); diff --git a/test/spec/modules/vidazooBidAdapter_spec.js b/test/spec/modules/vidazooBidAdapter_spec.js deleted file mode 100644 index d7f20c434ca..00000000000 --- a/test/spec/modules/vidazooBidAdapter_spec.js +++ /dev/null @@ -1,372 +0,0 @@ -import { expect } from 'chai'; -import { - spec as adapter, - SUPPORTED_ID_SYSTEMS, - createDomain, - hashCode, - extractPID, - extractCID, - extractSubDomain, - getStorageItem, - setStorageItem, - tryParseJSON, - getUniqueDealId, - getNextDealId, - getVidazooSessionId, -} from 'modules/vidazooBidAdapter.js'; -import * as utils from 'src/utils.js'; -import { version } from 'package.json'; -import { useFakeTimers } from 'sinon'; - -const SUB_DOMAIN = 'openrtb'; - -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', - 'requestId': 'b0777d85-d061-450e-9bc7-260dd54bbb7a' -}; - -const BIDDER_REQUEST = { - 'gdprConsent': { - 'consentString': 'consent_string', - 'gdprApplies': true - }, - 'uspConsent': 'consent_string', - 'refererInfo': { - 'referer': 'https://www.greatsite.com' - } -}; - -const SERVER_RESPONSE = { - body: { - results: [{ - 'ad': '', - 'price': 0.8, - 'creativeId': '12610997325162499419', - 'exp': 30, - 'width': 300, - 'height': 250, - 'cookies': [{ - 'src': 'https://sync.com', - 'type': 'iframe' - }, { - 'src': 'https://sync.com', - 'type': 'img' - }] - }] - } -}; - -const REQUEST = { - data: { - width: 300, - height: 250, - bidId: '2d52001cabd527' - } -}; - -describe('VidazooBidAdapter', function () { - describe('validtae 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'); - }); - }); - - 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 () { - sandbox = sinon.sandbox.create(); - sandbox.stub(Date, 'now').returns(1000); - }); - - it('should build request for each size', function () { - const hashUrl = hashCode(BIDDER_REQUEST.refererInfo.referer); - 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, - usPrivacy: 'consent_string', - sizes: ['300x250', '300x600'], - url: 'https%3A%2F%2Fwww.greatsite.com', - cb: 1000, - bidFloor: 0.1, - bidId: '2d52001cabd527', - adUnitCode: 'div-gpt-ad-12345-0', - publisherId: '59ac17c192832d0011283fe3', - dealId: 1, - sessionId: '', - uniqueDealId: `${hashUrl}_${Date.now().toString()}`, - bidderVersion: adapter.version, - prebidVersion: version, - res: `${window.top.screen.width}x${window.top.screen.height}`, - 'ext.param1': 'loremipsum', - 'ext.param2': 'dolorsitamet', - } - }); - }); - - after(function () { - 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://prebid.cootlogix.com/api/sync/iframe/?gdpr=0&gdpr_consent=&us_privacy=' - }]); - }); - - it('should have valid user sync with pixelEnabled', function () { - const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE]); - - expect(result).to.deep.equal([{ - 'url': 'https://prebid.cootlogix.com/api/sync/image/?gdpr=0&gdpr_consent=&us_privacy=', - '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 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: '' - }); - }); - - 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 () { - Object.keys(SUPPORTED_ID_SYSTEMS).forEach((idSystemProvider) => { - const id = Date.now().toString(); - const bid = utils.deepClone(BID); - - const userId = (function () { - switch (idSystemProvider) { - case 'digitrustid': return { data: { id: id } }; - case 'lipb': return { lipbid: id }; - case 'parrableId': return { eid: 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); - }); - }); - }); - - 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('vidazoo session id', function () { - it('should get undefined vidazoo session id', function () { - const sessionId = getVidazooSessionId(); - expect(sessionId).to.be.empty; - }); - - it('should get vidazoo session id from storage', function () { - const vidSid = '1234-5678'; - window.localStorage.setItem('vidSid', vidSid); - const sessionId = getVidazooSessionId(); - expect(sessionId).to.be.equal(vidSid); - }); - }); - - describe('deal id', function () { - const key = 'myDealKey'; - - it('should get the next deal id', function () { - const dealId = getNextDealId(key); - const nextDealId = getNextDealId(key); - expect(dealId).to.be.equal(1); - expect(nextDealId).to.be.equal(2); - }); - - it('should get the first deal id on expiration', function (done) { - setTimeout(function () { - const dealId = getNextDealId(key, 100); - expect(dealId).to.be.equal(1); - done(); - }, 200); - }); - }); - - describe('unique deal id', function () { - const key = 'myKey'; - let uniqueDealId; - uniqueDealId = getUniqueDealId(key); - - it('should get current unique deal id', function (done) { - // waiting some time so `now` will become past - setTimeout(() => { - const current = getUniqueDealId(key); - expect(current).to.be.equal(uniqueDealId); - done(); - }, 200); - }); - - it('should get new unique deal id on expiration', function () { - const current = getUniqueDealId(key, 100); - expect(current).to.not.be.equal(uniqueDealId); - }); - }); - - describe('storage utils', function () { - it('should get value from storage with create param', function () { - const now = Date.now(); - const clock = useFakeTimers({ - shouldAdvanceTime: true, - now - }); - setStorageItem('myKey', 2020); - const { value, created } = getStorageItem('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('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/videoNowBidAdapter_spec.js b/test/spec/modules/videoNowBidAdapter_spec.js deleted file mode 100644 index a419c73456b..00000000000 --- a/test/spec/modules/videoNowBidAdapter_spec.js +++ /dev/null @@ -1,599 +0,0 @@ -import { expect } from 'chai' -import { spec } from 'modules/videoNowBidAdapter.js' -import { replaceAuctionPrice } from 'src/utils.js' -import * as utils from 'src/utils.js'; - -// childNode.remove polyfill for ie11 -// suggested by: https://developer.mozilla.org/en-US/docs/Web/API/ChildNode/remove - -// from:https://github.com/jserz/js_piece/blob/master/DOM/ChildNode/remove()/remove().md -(function (arr) { - arr.forEach(function (item) { - if (item.hasOwnProperty('remove')) { - return; - } - Object.defineProperty(item, 'remove', { - configurable: true, - enumerable: true, - writable: true, - value: function remove() { - if (this.parentNode === null) { - return; - } - this.parentNode.removeChild(this); - } - }); - }); -})([Element.prototype, CharacterData.prototype, DocumentType.prototype]); - -const placementId = 'div-gpt-ad-1438287399331-1' -const LS_ITEM_NAME = 'videonow-config' - -const getValidServerResponse = () => { - const serverResponse = { - body: { - id: '111-111', - bidid: '2955a162-699e-4811-ce88-5c3ac973e73c', - cur: 'RUB', - seatbid: [ - { - bid: [ - { - id: 'e3bf2b82e3e9485113fad6c9b27f8768.1', - impid: '1', - price: 10.97, - nurl: 'https://localhost:8086/event/nurl', - netRevenue: false, - ttl: 800, - adm: '', - crid: 'e3bf2b82e3e9485113fad6c9b27f8768.1', - h: 640, - w: 480, - ext: { - init: 'https://localhost:8086/vn_init.js', - module: { - min: 'https://localhost:8086/vn_module.js', - log: 'https://localhost:8086/vn_module.js?log=1' - }, - format: { - name: 'flyRoll', - }, - }, - - }, - ], - group: 0, - }, - ], - price: 10, - ext: { - placementId, - pixels: [ - 'https://localhost:8086/event/pxlcookiematching?uiid=1', - 'https://localhost:8086/event/pxlcookiematching?uiid=2', - ], - iframes: [ - 'https://localhost:8086/event/ifrcookiematching?uiid=1', - 'https://localhost:8086/event/ifrcookiematching?uiid=2', - ], - }, - }, - headers: {}, - } - - return JSON.parse(JSON.stringify(serverResponse)) -} - -describe('videonowAdapterTests', function() { - describe('bidRequestValidity', function() { - it('bidRequest with pId', function() { - expect(spec.isBidRequestValid({ - bidder: 'videonow', - params: { - pId: '86858', - }, - })).to.equal(true) - }) - - it('bidRequest without pId', function() { - expect(spec.isBidRequestValid({ - bidder: 'videonow', - params: { - nomater: 86858, - }, - })).to.equal(false) - - it('bidRequest is empty', function() { - expect(spec.isBidRequestValid({})).to.equal(false) - }) - - it('bidRequest is undefned', function() { - expect(spec.isBidRequestValid(undefined)).to.equal(false) - }) - }) - - describe('bidRequest', function() { - const validBidRequests = [ - { - bidder: 'videonow', - params: { - pId: '1', - placementId, - url: 'https://localhost:8086/bid?p=exists', - bidFloor: 10, - cur: 'RUB' - }, - crumbs: { - pubcid: 'feded041-35dd-4b54-979a-6d7805abfa75', - }, - mediaTypes: { - banner: { - sizes: [[640, 480], [320, 200]] - }, - }, - adUnitCode: 'test-ad', - transactionId: '676403c7-09c9-4b56-be82-e7cae81f40b9', - sizes: [[640, 480], [320, 200]], - bidId: '268c309f46390d', - bidderRequestId: '1dfdd514c36ef6', - auctionId: '4d523546-889a-4029-9a79-13d3c69f9922', - src: 'client', - bidRequestsCount: 1, - }, - ] - - const bidderRequest = { - bidderCode: 'videonow', - auctionId: '4d523546-889a-4029-9a79-13d3c69f9922', - bidderRequestId: '1dfdd514c36ef6', - bids: [ - { - bidder: 'videonow', - params: { - pId: '1', - placementId, - url: 'https://localhost:8086/bid', - bidFloor: 10, - cur: 'RUB', - }, - crumbs: { - pubcid: 'feded041-35dd-4b54-979a-6d7805abfa75', - }, - mediaTypes: { - banner: { - sizes: [[640, 480], [320, 200]], - }, - }, - adUnitCode: 'test-ad', - transactionId: '676403c7-09c9-4b56-be82-e7cae81f40b9', - sizes: [[640, 480], [320, 200]], - bidId: '268c309f46390d', - bidderRequestId: '1dfdd514c36ef6', - auctionId: '4d523546-889a-4029-9a79-13d3c69f9922', - src: 'client', - bidRequestsCount: 1, - }, - ], - auctionStart: 1565794308584, - timeout: 3000, - refererInfo: { - referer: 'https://localhost:8086/page', - reachedTop: true, - numIframes: 0, - stack: [ - 'https://localhost:8086/page', - ], - }, - start: 1565794308589, - } - - const requests = spec.buildRequests(validBidRequests, bidderRequest) - const request = (requests && requests.length && requests[0]) || {} - - it('bidRequest count', function() { - expect(requests.length).to.equal(1) - }) - - it('bidRequest method', function() { - expect(request.method).to.equal('POST') - }) - - it('bidRequest url', function() { - expect(request.url).to.equal('https://localhost:8086/bid?p=exists&profile_id=1') - }) - - it('bidRequest data', function() { - const data = request.data - expect(data.aid).to.be.eql(validBidRequests[0].params.aid) - expect(data.id).to.be.eql(validBidRequests[0].bidId) - expect(data.sizes).to.be.eql(validBidRequests[0].sizes) - }) - - describe('bidRequest advanced', function() { - const bidderRequestEmptyParamsAndExtParams = { - bidder: 'videonow', - params: { - pId: '1', - }, - ext: { - p1: 'ext1', - p2: 'ext2', - }, - } - - it('bidRequest count', function() { - const requests = spec.buildRequests([bidderRequestEmptyParamsAndExtParams], bidderRequest) - expect(requests.length).to.equal(1) - }) - - it('bidRequest default url', function() { - const requests = spec.buildRequests([bidderRequestEmptyParamsAndExtParams], bidderRequest) - const request = (requests && requests.length && requests[0]) || {} - expect(request.url).to.equal('https://bidder.videonow.ru/prebid?profile_id=1') - }) - - it('bidRequest default currency', function() { - const requests = spec.buildRequests([bidderRequestEmptyParamsAndExtParams], bidderRequest) - const request = (requests && requests.length && requests[0]) || {} - const data = (request && request.data) || {} - expect(data.cur).to.equal('RUB') - }) - - it('bidRequest ext parameters ', function() { - const requests = spec.buildRequests([bidderRequestEmptyParamsAndExtParams], bidderRequest) - const request = (requests && requests.length && requests[0]) || {} - const data = (request && request.data) || {} - expect(data['ext_p1']).to.equal('ext1') - expect(data['ext_p2']).to.equal('ext2') - }) - - it('bidRequest without params', function() { - const bidderReq = { - bidder: 'videonow', - } - const requests = spec.buildRequests([bidderReq], bidderRequest) - expect(requests.length).to.equal(1) - }) - }) - }) - - describe('onBidWon', function() { - const cpm = 10 - const nurl = 'https://fakedomain.nld?price=${AUCTION_PRICE}' - const imgSrc = replaceAuctionPrice(nurl, cpm) - - beforeEach(function() { - sinon.stub(utils, 'triggerPixel') - }) - - afterEach(function() { - utils.triggerPixel.restore() - }) - - it('Should not create nurl pixel if bid is undefined', function() { - spec.onBidWon() - expect(utils.triggerPixel.called).to.equal(false); - }) - - it('Should not create nurl pixel if bid does not contains nurl', function() { - spec.onBidWon({}) - expect(utils.triggerPixel.called).to.equal(false); - }) - - it('Should create nurl pixel if bid nurl', function() { - spec.onBidWon({ nurl, cpm }) - expect(utils.triggerPixel.calledWith(imgSrc)).to.equal(true); - }) - }) - - describe('getUserSyncs', function() { - it('Should return an empty array if not get serverResponses', function() { - expect(spec.getUserSyncs({}).length).to.equal(0) - }) - - it('Should return an empty array if get serverResponses as empty array', function() { - expect(spec.getUserSyncs({}, []).length).to.equal(0) - }) - - it('Should return an empty array if serverResponses has no body', function() { - const serverResp = getValidServerResponse() - delete serverResp.body - const syncs = spec.getUserSyncs({}, [serverResp]) - expect(syncs.length).to.equal(0) - }) - - it('Should return an empty array if serverResponses has no ext', function() { - const serverResp = getValidServerResponse() - delete serverResp.body.ext - const syncs = spec.getUserSyncs({}, [serverResp]) - expect(syncs.length).to.equal(0) - }) - - it('Should return an array', function() { - const serverResp = getValidServerResponse() - const syncs = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [serverResp]) - expect(syncs.length).to.equal(4) - }) - - it('Should return pixels', function() { - const serverResp = getValidServerResponse() - const syncs = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [serverResp]) - expect(syncs.length).to.equal(2) - expect(syncs[0].type).to.equal('image') - expect(syncs[1].type).to.equal('image') - }) - - it('Should return iframes', function() { - const serverResp = getValidServerResponse() - const syncs = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, [serverResp]) - expect(syncs.length).to.equal(2) - expect(syncs[0].type).to.equal('iframe') - expect(syncs[1].type).to.equal('iframe') - }) - }) - - describe('interpretResponse', function() { - const bidRequest = { - method: 'POST', - url: 'https://localhost:8086/bid?profile_id=1', - data: { - id: '217b8ab59a18e8', - cpm: 10, - sizes: [[640, 480], [320, 200]], - cur: 'RUB', - placementId, - ref: 'https://localhost:8086/page', - }, - } - - it('Should have only one bid', function() { - const serverResponse = getValidServerResponse() - const result = spec.interpretResponse(serverResponse, bidRequest) - expect(result.length).to.equal(1) - }) - - it('Should have required keys', function() { - const serverResponse = getValidServerResponse() - const result = spec.interpretResponse(serverResponse, bidRequest) - const bid = serverResponse.body.seatbid[0].bid[0] - const res = result[0] - expect(res.requestId).to.be.eql(bidRequest.data.id) - expect(res.cpm).to.be.eql(bid.price) - expect(res.creativeId).to.be.eql(bid.crid) - expect(res.netRevenue).to.be.a('boolean') - expect(res.ttl).to.be.eql(bid.ttl) - expect(res.renderer).to.be.a('Object') - expect(res.renderer.render).to.be.a('function') - }) - - it('Should return an empty array if empty or no bids in response', function() { - expect(spec.interpretResponse({ body: '' }, {}).length).to.equal(0) - }) - - it('Should return an empty array if bidRequest\'s data is absent', function() { - const serverResponse = getValidServerResponse() - expect(spec.interpretResponse(serverResponse, undefined).length).to.equal(0) - }) - - it('Should return an empty array if bidRequest\'s data is not contains bidId ', function() { - const serverResponse = getValidServerResponse() - expect(spec.interpretResponse(serverResponse, { data: {} }).length).to.equal(0) - }) - - it('Should return an empty array if bidRequest\'s data bidId is undefined', function() { - const serverResponse = getValidServerResponse() - expect(spec.interpretResponse(serverResponse, { data: { id: null } }).length).to.equal(0) - }) - - it('Should return an empty array if serverResponse do not contains seatbid', function() { - expect(spec.interpretResponse({ body: {} }, bidRequest).length).to.equal(0) - }) - - it('Should return an empty array if serverResponse\'s seatbid is empty', function() { - expect(spec.interpretResponse({ body: { seatbid: [] } }, bidRequest).length).to.equal(0) - }) - - it('Should return an empty array if serverResponse\'s placementId is undefined', function() { - expect(spec.interpretResponse({ body: { seatbid: [1, 2] } }, bidRequest).length).to.equal(0) - }) - - it('Should return an empty array if serverResponse\'s id in the bid is undefined', function() { - const serverResp = getValidServerResponse() - delete serverResp.body.seatbid[0].bid[0].id - let res = spec.interpretResponse(serverResp, bidRequest) - expect(res.length).to.equal(0) - }) - - it('Should return an empty array if serverResponse\'s price in the bid is undefined', function() { - const serverResp = getValidServerResponse() - delete serverResp.body.seatbid[0].bid[0].price - const res = spec.interpretResponse(serverResp, bidRequest) - expect(res.length).to.equal(0) - }) - - it('Should return an empty array if serverResponse\'s price in the bid is 0', function() { - const serverResp = getValidServerResponse() - serverResp.body.seatbid[0].bid[0].price = 0 - const res = spec.interpretResponse(serverResp, bidRequest) - - expect(res.length).to.equal(0) - }) - - it('Should return an empty array if serverResponse\'s init in the bid\'s ext is undefined', function() { - const serverResp = getValidServerResponse() - delete serverResp.body.seatbid[0].bid[0].ext.init - const res = spec.interpretResponse(serverResp, bidRequest) - - expect(res.length).to.equal(0) - }) - - it('Should return an empty array if serverResponse\'s module in the bid\'s ext is undefined', function() { - const serverResp = getValidServerResponse() - delete serverResp.body.seatbid[0].bid[0].ext.module - const res = spec.interpretResponse(serverResp, bidRequest) - - expect(res.length).to.equal(0) - }) - - it('Should return an empty array if serverResponse\'s adm in the bid is undefined', function() { - const serverResp = getValidServerResponse() - delete serverResp.body.seatbid[0].bid[0].adm - const res = spec.interpretResponse(serverResp, bidRequest) - - expect(res.length).to.equal(0) - }) - - it('Should return an empty array if serverResponse\'s the bid\'s ext is undefined', function() { - const serverResp = getValidServerResponse() - delete serverResp.body.seatbid[0].bid[0].ext - const res = spec.interpretResponse(serverResp, bidRequest) - - expect(res.length).to.equal(0) - }) - - it('Default ttl is 300', function() { - const serverResp = getValidServerResponse() - delete serverResp.body.seatbid[0].bid[0].ttl - const res = spec.interpretResponse(serverResp, bidRequest) - expect(res.length).to.equal(1) - expect(res[0].ttl).to.equal(300) - }) - - it('Default netRevenue is true', function() { - const serverResp = getValidServerResponse() - delete serverResp.body.seatbid[0].bid[0].netRevenue - const res = spec.interpretResponse(serverResp, bidRequest) - expect(res.length).to.equal(1) - expect(res[0].netRevenue).to.be.true; - }) - - it('Default currency is RUB', function() { - const serverResp = getValidServerResponse() - delete serverResp.body.cur - const res = spec.interpretResponse(serverResp, bidRequest) - expect(res.length).to.equal(1) - expect(res[0].currency).to.equal('RUB') - }) - - describe('different module paths', function() { - beforeEach(function() { - window.localStorage && localStorage.setItem(LS_ITEM_NAME, '{}') - }) - - afterEach(function() { - const serverResp = getValidServerResponse() - const { module: { log, min }, init } = serverResp.body.seatbid[0].bid[0].ext - remove(init) - remove(log) - remove(min) - - function remove(src) { - if (!src) return - const d = document.querySelectorAll(`script[src^="${src}"]`) - // using the Array.prototype.forEach as a workaround for IE11... - // see https://developer.mozilla.org/en-US/docs/Web/API/NodeList - d && d.length && Array.prototype.forEach.call(d, el => el && el.remove()) - } - }) - - it('should use prod module by default', function() { - const serverResp = getValidServerResponse() - const res = spec.interpretResponse(serverResp, bidRequest) - expect(res.length).to.equal(1) - - const renderer = res[0].renderer - expect(renderer).to.be.an('object') - expect(renderer.url).to.equal(serverResp.body.seatbid[0].bid[0].ext.module.min) - }) - - it('should use "log" module if "prod" is not exists', function() { - const serverResp = getValidServerResponse() - delete serverResp.body.seatbid[0].bid[0].ext.module.min - const res = spec.interpretResponse(serverResp, bidRequest) - expect(res.length).to.equal(1) - - const renderer = res[0].renderer - expect(renderer).to.be.an('object') - expect(renderer.url).to.equal(serverResp.body.seatbid[0].bid[0].ext.module.log) - }) - - it('should correct combine src for init', function() { - const serverResp = getValidServerResponse() - - const src = `${serverResp.body.seatbid[0].bid[0].ext.init}?profileId=1` - const placementElement = document.createElement('div') - placementElement.setAttribute('id', placementId) - - const resp = spec.interpretResponse(serverResp, bidRequest) - expect(resp.length).to.equal(1) - - const renderer = resp[0].renderer - expect(renderer).to.be.an('object') - - document.body.appendChild(placementElement) - - renderer.render() - - // const res = document.querySelectorAll(`script[src="${src}"]`) - // expect(res.length).to.equal(1) - }) - - it('should correct combine src for init if init url contains "?"', function() { - const serverResp = getValidServerResponse() - - serverResp.body.seatbid[0].bid[0].ext.init += '?div=1' - const src = `${serverResp.body.seatbid[0].bid[0].ext.init}&profileId=1` - - const placementElement = document.createElement('div') - placementElement.setAttribute('id', placementId) - - const resp = spec.interpretResponse(serverResp, bidRequest) - expect(resp.length).to.equal(1) - - const renderer = resp[0].renderer - expect(renderer).to.be.an('object') - - document.body.appendChild(placementElement) - - renderer.render() - - // const res = document.querySelectorAll(`script[src="${src}"]`) - // expect(res.length).to.equal(1) - }) - }) - - describe('renderer object', function() { - it('execute renderer.render() should create window.videonow object', function() { - const serverResp = getValidServerResponse() - const res = spec.interpretResponse(serverResp, bidRequest) - expect(res.length).to.equal(1) - - const renderer = res[0].renderer - expect(renderer).to.be.an('object') - expect(renderer.render).to.a('function') - - const doc = window.document - const placementElement = doc.createElement('div') - placementElement.setAttribute('id', placementId) - doc.body.appendChild(placementElement) - - renderer.render() - expect(window.videonow).to.an('object') - }) - }) - - it('execute renderer.render() should not create window.videonow object if placement element not found', function() { - const serverResp = getValidServerResponse() - const res = spec.interpretResponse(serverResp, bidRequest) - expect(res.length).to.equal(1) - - const renderer = res[0].renderer - expect(renderer).to.be.an('object') - expect(renderer.render).to.a('function') - - renderer.render() - expect(window.videonow).to.be.undefined - }) - }) - }) -}) diff --git a/test/spec/modules/videofyBidAdapter_spec.js b/test/spec/modules/videofyBidAdapter_spec.js deleted file mode 100644 index 270eefd1efc..00000000000 --- a/test/spec/modules/videofyBidAdapter_spec.js +++ /dev/null @@ -1,253 +0,0 @@ -import { spec } from 'modules/videofyBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import * as utils from '../../../src/utils.js'; - -const { expect } = require('chai'); - -describe('Videofy Bid Adapter Test', 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 () { - let bid = { - 'bidder': 'videofy', - 'params': { - 'AV_PUBLISHERID': '123456', - 'AV_CHANNELID': '123456' - }, - 'adUnitCode': 'video1', - 'sizes': [[300, 250], [640, 480]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'requestId': 'a09c66c3-53e3-4428-b296-38fc08e7cd2a', - 'transactionId': 'd6f6b392-54a9-454c-85fb-a2fd882c4a2d', - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - something: 'is wrong' - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bid2Requests = [ - { - 'bidder': 'videofy', - 'params': { - 'AV_PUBLISHERID': '123456', - 'AV_CHANNELID': '123456' - }, - 'adUnitCode': 'test1', - 'sizes': [[300, 250], [640, 480]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'requestId': 'a09c66c3-53e3-4428-b296-38fc08e7cd2a', - 'transactionId': 'd6f6b392-54a9-454c-85fb-a2fd882c4a2d', - } - ]; - let bid1Request = [ - { - 'bidder': 'videofy', - 'params': { - 'AV_PUBLISHERID': '123456', - 'AV_CHANNELID': '123456' - }, - 'adUnitCode': 'test1', - 'sizes': [640, 480], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'requestId': 'a09c66c3-53e3-4428-b296-38fc08e7cd2a', - 'transactionId': 'd6f6b392-54a9-454c-85fb-a2fd882c4a2d', - } - ]; - - it('Test 2 requests', function () { - const requests = spec.buildRequests(bid2Requests); - expect(requests.length).to.equal(2); - const r1 = requests[0]; - const d1 = requests[0].data; - expect(d1).to.have.property('AV_PUBLISHERID'); - expect(d1.AV_PUBLISHERID).to.equal('123456'); - expect(d1).to.have.property('AV_CHANNELID'); - expect(d1.AV_CHANNELID).to.equal('123456'); - expect(d1).to.have.property('AV_WIDTH'); - expect(d1.AV_WIDTH).to.equal(300); - expect(d1).to.have.property('AV_HEIGHT'); - expect(d1.AV_HEIGHT).to.equal(250); - expect(d1).to.have.property('AV_URL'); - expect(d1).to.have.property('cb'); - expect(d1).to.have.property('s2s'); - expect(d1.s2s).to.equal('1'); - expect(d1).to.have.property('pbjs'); - expect(d1.pbjs).to.equal(1); - expect(r1).to.have.property('url'); - expect(r1.url).to.contain('https://servx.srv-mars.com/api/adserver/vast3/'); - const r2 = requests[1]; - const d2 = requests[1].data; - expect(d2).to.have.property('AV_PUBLISHERID'); - expect(d2.AV_PUBLISHERID).to.equal('123456'); - expect(d2).to.have.property('AV_CHANNELID'); - expect(d2.AV_CHANNELID).to.equal('123456'); - expect(d2).to.have.property('AV_WIDTH'); - expect(d2.AV_WIDTH).to.equal(640); - expect(d2).to.have.property('AV_HEIGHT'); - expect(d2.AV_HEIGHT).to.equal(480); - expect(d2).to.have.property('AV_URL'); - expect(d2).to.have.property('cb'); - expect(d2).to.have.property('s2s'); - expect(d2.s2s).to.equal('1'); - expect(d2).to.have.property('pbjs'); - expect(d2.pbjs).to.equal(1); - expect(r2).to.have.property('url'); - expect(r2.url).to.contain('https://servx.srv-mars.com/api/adserver/vast3/'); - }); - - it('Test 1 request', function () { - const requests = spec.buildRequests(bid1Request); - expect(requests.length).to.equal(1); - const r = requests[0]; - const d = requests[0].data; - expect(d).to.have.property('AV_PUBLISHERID'); - expect(d.AV_PUBLISHERID).to.equal('123456'); - expect(d).to.have.property('AV_CHANNELID'); - expect(d.AV_CHANNELID).to.equal('123456'); - expect(d).to.have.property('AV_WIDTH'); - expect(d.AV_WIDTH).to.equal(640); - expect(d).to.have.property('AV_HEIGHT'); - expect(d.AV_HEIGHT).to.equal(480); - expect(d).to.have.property('AV_URL'); - expect(d).to.have.property('cb'); - expect(d).to.have.property('s2s'); - expect(d.s2s).to.equal('1'); - expect(d).to.have.property('pbjs'); - expect(d.pbjs).to.equal(1); - expect(r).to.have.property('url'); - expect(r.url).to.contain('https://servx.srv-mars.com/api/adserver/vast3/'); - }); - }); - - describe('interpretResponse', function () { - let bidRequest = { - 'url': 'https://servx.srv-mars.com/api/adserver/vast3/', - 'data': { - 'bidId': '253dcb69fb2577', - AV_PUBLISHERID: '55b78633181f4603178b4568', - AV_CHANNELID: '55b7904d181f46410f8b4568', - } - }; - let serverResponse = {}; - serverResponse.body = 'FORDFORD00:00:15'; - - it('Check bid interpretResponse', function () { - const BIDDER_CODE = 'videofy'; - let bidResponses = spec.interpretResponse(serverResponse, bidRequest); - expect(bidResponses.length).to.equal(1); - let bidResponse = bidResponses[0]; - expect(bidResponse.requestId).to.equal(bidRequest.data.bidId); - expect(bidResponse.bidderCode).to.equal(BIDDER_CODE); - expect(bidResponse.cpm).to.equal('2'); - expect(bidResponse.ttl).to.equal(600); - expect(bidResponse.currency).to.equal('USD'); - expect(bidResponse.netRevenue).to.equal(true); - expect(bidResponse.mediaType).to.equal('video'); - }); - - it('safely handles XML parsing failure from invalid bid response', function () { - let invalidServerResponse = {}; - invalidServerResponse.body = '
'; - - let result = spec.interpretResponse(invalidServerResponse, bidRequest); - expect(result.length).to.equal(0); - }); - - it('handles nobid responses', function () { - let nobidResponse = {}; - nobidResponse.body = ''; - - let result = spec.interpretResponse(nobidResponse, bidRequest); - expect(result.length).to.equal(0); - }); - }); - - describe('getUserSyncs', function () { - it('Check get sync pixels from response', function () { - let pixelUrl = 'https://sync.pixel.url/sync'; - let pixelEvent = 'inventory'; - let pixelType = '3'; - let pixelStr = '{"url":"' + pixelUrl + '", "e":"' + pixelEvent + '", "t":' + pixelType + '}'; - let bidResponse = 'FORDFORD00:00:15'; - let serverResponse = [ - {body: bidResponse} - ]; - let syncPixels = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, serverResponse); - expect(syncPixels.length).to.equal(1); - let pixel = syncPixels[0]; - expect(pixel.url).to.equal(pixelUrl); - expect(pixel.type).to.equal('iframe'); - }); - }); - - describe('on bidWon', function () { - beforeEach(function() { - sinon.stub(utils, 'triggerPixel'); - }); - afterEach(function() { - utils.triggerPixel.restore(); - }); - it('exists and is a function', () => { - expect(spec.onBidWon).to.exist.and.to.be.a('function'); - }); - it('should return nothing', function () { - var response = spec.onBidWon({}); - expect(response).to.be.an('undefined') - expect(utils.triggerPixel.called).to.equal(true); - }); - }); - - describe('on Timeout', function () { - beforeEach(function() { - sinon.stub(utils, 'triggerPixel'); - }); - afterEach(function() { - utils.triggerPixel.restore(); - }); - it('exists and is a function', () => { - expect(spec.onTimeout).to.exist.and.to.be.a('function'); - }); - it('should return nothing', function () { - var response = spec.onTimeout({}); - expect(response).to.be.an('undefined') - expect(utils.triggerPixel.called).to.equal(true); - }); - }); - - describe('on Set Targeting', function () { - beforeEach(function() { - sinon.stub(utils, 'triggerPixel'); - }); - afterEach(function() { - utils.triggerPixel.restore(); - }); - it('exists and is a function', () => { - expect(spec.onSetTargeting).to.exist.and.to.be.a('function'); - }); - it('should return nothing', function () { - var response = spec.onSetTargeting({}); - expect(response).to.be.an('undefined') - expect(utils.triggerPixel.called).to.equal(true); - }); - }); -}); diff --git a/test/spec/modules/videoreachBidAdapter_spec.js b/test/spec/modules/videoreachBidAdapter_spec.js deleted file mode 100644 index e5c6b9b30ad..00000000000 --- a/test/spec/modules/videoreachBidAdapter_spec.js +++ /dev/null @@ -1,141 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/videoreachBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; - -const ENDPOINT_URL = 'https://a.videoreach.com/hb/'; - -describe('videoreachBidAdapter', function () { - describe('isBidRequestValid', function () { - let bid = { - 'params': { - 'TagId': 'ABCDE' - }, - 'bidId': '242d506d4e4f15', - 'bidderRequestId': '1893a2136a84a2', - 'auctionId': '8fb7b1c7-317b-4edf-83f0-c4669a318522', - 'transactionId': '85a2e190-0684-4f95-ad32-6c90757ed622' - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'TagId': '' - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [ - { - 'bidder': 'videoreach', - 'params': { - 'TagId': 'ABCDE' - }, - 'adUnitCode': 'adzone', - 'auctionId': '8fb7b1c7-317b-4edf-83f0-c4669a318522', - 'sizes': [[1, 1]], - 'bidId': '242d506d4e4f15', - 'bidderRequestId': '1893a2136a84a2', - 'transactionId': '85a2e190-0684-4f95-ad32-6c90757ed622', - 'mediaTypes': { - 'banner': { - 'sizes': [1, 1] - }, - } - } - ]; - - it('send bid request to endpoint', function () { - const request = spec.buildRequests(bidRequests); - - expect(request.url).to.equal(ENDPOINT_URL); - expect(request.method).to.equal('POST'); - }); - - it('send bid request with GDPR to endpoint', function () { - let consentString = 'BOEFEAyOEFEAyAHABDENAI4AAAB9vABAASA'; - - let bidderRequest = { - 'gdprConsent': { - 'consentString': consentString, - 'gdprApplies': true - } - }; - - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.gdpr.consent_required).to.exist; - expect(payload.gdpr.consent_string).to.equal(consentString); - }); - }); - - describe('interpretResponse', function () { - let serverResponse = - { - 'body': { - 'responses': [{ - 'bidId': '242d506d4e4f15', - 'transactionId': '85a2e190-0684-4f95-ad32-6c90757ed622', - 'cpm': 10.0, - 'width': '1', - 'height': '1', - 'ad': '', - 'ttl': 360, - 'creativeId': '5cb5dc9375c0e', - 'netRevenue': true, - 'currency': 'EUR', - 'sync': ['https:\/\/SYNC_URL'] - }] - } - }; - - it('should handle response', function() { - let expectedResponse = [ - { - cpm: 10.0, - width: '1', - height: '1', - currency: 'EUR', - netRevenue: true, - ttl: 360, - ad: '', - requestId: '242d506d4e4f15', - creativeId: '5cb5dc9375c0e' - } - ]; - - let result = spec.interpretResponse(serverResponse); - expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); - }); - - it('should handles empty response', function() { - let serverResponse = { - 'body': { - 'responses': [] - } - }; - - let result = spec.interpretResponse(serverResponse); - expect(result.length).to.equal(0); - }); - - describe('getUserSyncs', () => { - it('should push user sync images if enabled', () => { - const syncOptions = { pixelEnabled: true }; - const syncs = spec.getUserSyncs(syncOptions, [serverResponse]); - - expect(syncs[0]).to.deep.equal({ - type: 'image', - url: 'https://SYNC_URL' - }); - }) - }); - }); -}); diff --git a/test/spec/modules/viewdeosDXBidAdapter_spec.js b/test/spec/modules/viewdeosDXBidAdapter_spec.js deleted file mode 100644 index f9bee1b0efe..00000000000 --- a/test/spec/modules/viewdeosDXBidAdapter_spec.js +++ /dev/null @@ -1,336 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/viewdeosDXBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; - -const ENDPOINT = 'https://ghb.sync.viewdeos.com/auction/'; - -const DISPLAY_REQUEST = { - 'bidder': 'viewdeos', - 'params': { - 'aid': 12345 - }, - 'bidderRequestId': '7101db09af0db2', - 'auctionId': '2e41f65424c87c', - 'adUnitCode': 'adunit-code', - 'bidId': '84ab500420319d', - 'mediaTypes': {'banner': {'sizes': [[300, 250], [300, 600]]}} -}; - -const VIDEO_REQUEST = { - 'bidder': 'viewdeos', - 'params': { - 'aid': 12345 - }, - 'bidderRequestId': '7101db09af0db2', - 'auctionId': '2e41f65424c87c', - 'adUnitCode': 'adunit-code', - 'bidId': '84ab500420319d', - 'mediaTypes': {'video': {'playerSize': [480, 360], 'context': 'instream'}} -}; - -const SERVER_VIDEO_RESPONSE = { - 'source': {'aid': 12345, 'pubId': 54321}, - 'bids': [{ - 'vastUrl': 'http://rtb.sync.viewdeos.com/vast/?adid=44F2AEB9BFC881B3', - 'requestId': '2e41f65424c87c', - 'url': '44F2AEB9BFC881B3', - 'creative_id': 342516, - 'cmpId': 342516, - 'height': 480, - 'cur': 'USD', - 'width': 640, - 'cpm': 0.9 - } - ] -}; -const SERVER_OUSTREAM_VIDEO_RESPONSE = SERVER_VIDEO_RESPONSE; - -const SERVER_DISPLAY_RESPONSE = { - 'source': {'aid': 12345, 'pubId': 54321}, - 'bids': [{ - 'ad': '', - 'requestId': '2e41f65424c87c', - 'creative_id': 342516, - 'cmpId': 342516, - 'height': 250, - 'cur': 'USD', - 'width': 300, - 'cpm': 0.9 - }], - 'cookieURLs': ['link1', 'link2'] -}; -const SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS = { - 'source': {'aid': 12345, 'pubId': 54321}, - 'bids': [{ - 'ad': '', - 'requestId': '2e41f65424c87c', - 'creative_id': 342516, - 'cmpId': 342516, - 'height': 250, - 'cur': 'USD', - 'width': 300, - 'cpm': 0.9 - }], - 'cookieURLs': ['link3', 'link4'], - 'cookieURLSTypes': ['image', 'iframe'] -}; - -const outstreamVideoBidderRequest = { - bidderCode: 'bidderCode', - bids: [{ - 'params': { - 'aid': 12345, - 'outstream': { - 'video_controls': 'show' - } - }, - mediaTypes: { - video: { - context: 'outstream', - playerSize: [640, 480] - } - }, - bidId: '2e41f65424c87c' - }] -}; - -const videoBidderRequest = { - bidderCode: 'bidderCode', - bids: [{mediaTypes: {video: {}}, bidId: '2e41f65424c87c'}] -}; - -const displayBidderRequest = { - bidderCode: 'bidderCode', - bids: [{bidId: '2e41f65424c87c'}] -}; - -const displayBidderRequestWithGdpr = { - bidderCode: 'bidderCode', - bids: [{bidId: '2e41f65424c87c'}], - gdprConsent: { - gdprApplies: true, - consentString: 'test' - } -}; - -const videoEqResponse = [{ - vastUrl: 'http://rtb.sync.viewdeos.com/vast/?adid=44F2AEB9BFC881B3', - requestId: '2e41f65424c87c', - creativeId: 342516, - mediaType: 'video', - netRevenue: true, - currency: 'USD', - height: 480, - width: 640, - ttl: 3600, - cpm: 0.9 -}]; - -const displayEqResponse = [{ - requestId: '2e41f65424c87c', - creativeId: 342516, - mediaType: 'display', - netRevenue: true, - currency: 'USD', - ad: '', - height: 250, - width: 300, - ttl: 3600, - cpm: 0.9 -}]; - -describe('viewdeosDXBidAdapter', function () { - const adapter = newBidder(spec); - - describe('when outstream params are passing properly', function() { - const videoBids = spec.interpretResponse({body: SERVER_OUSTREAM_VIDEO_RESPONSE}, {bidderRequest: outstreamVideoBidderRequest}); - it('should return renderer with expected outstream params config', function() { - expect(!!videoBids[0].renderer).to.equal(true); - expect(videoBids[0].renderer.getConfig().video_controls).to.equal('show'); - }) - }) - - describe('user syncs as image', function () { - it('should be returned if pixel enabled', function () { - const syncs = spec.getUserSyncs({pixelEnabled: true}, [{body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS}]); - - expect(syncs.map(s => s.url)).to.deep.equal([SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS.cookieURLs[0]]); - expect(syncs.map(s => s.type)).to.deep.equal(['image']); - }) - }) - - describe('user syncs as iframe', function () { - it('should be returned if iframe enabled', function () { - const syncs = spec.getUserSyncs({iframeEnabled: true}, [{body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS}]); - - expect(syncs.map(s => s.url)).to.deep.equal([SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS.cookieURLs[1]]); - expect(syncs.map(s => s.type)).to.deep.equal(['iframe']); - }) - }) - - describe('user syncs with both types', function () { - it('should be returned if pixel and iframe enabled', function () { - const syncs = spec.getUserSyncs({ - iframeEnabled: true, - pixelEnabled: true - }, [{body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS}]); - - expect(syncs.map(s => s.url)).to.deep.equal(SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS.cookieURLs); - expect(syncs.map(s => s.type)).to.deep.equal(SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS.cookieURLSTypes); - }) - }) - - describe('user syncs', function () { - it('should not be returned if pixel not set', function () { - const syncs = spec.getUserSyncs({}, [{body: SERVER_DISPLAY_RESPONSE_WITH_MIXED_SYNCS}]); - - expect(syncs).to.be.empty; - }) - }) - - describe('inherited functions', function () { - it('exists and is a function', function () { - expect(adapter.callBids).to.exist.and.to.be.a('function'); - }); - }); - - describe('isBidRequestValid', function () { - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(VIDEO_REQUEST)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, VIDEO_REQUEST); - delete bid.params; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let videoBidRequests = [VIDEO_REQUEST]; - let displayBidRequests = [DISPLAY_REQUEST]; - let videoAndDisplayBidRequests = [DISPLAY_REQUEST, VIDEO_REQUEST]; - - const displayRequest = spec.buildRequests(displayBidRequests, {}); - const videoRequest = spec.buildRequests(videoBidRequests, {}); - const videoAndDisplayRequests = spec.buildRequests(videoAndDisplayBidRequests, {}); - - it('sends bid request to ENDPOINT via GET', function () { - expect(videoRequest.method).to.equal('GET'); - expect(displayRequest.method).to.equal('GET'); - expect(videoAndDisplayRequests.method).to.equal('GET'); - }); - - it('sends bid request to correct ENDPOINT', function () { - expect(videoRequest.url).to.equal(ENDPOINT); - expect(displayRequest.url).to.equal(ENDPOINT); - expect(videoAndDisplayRequests.url).to.equal(ENDPOINT); - }); - - it('sends correct video bid parameters', function () { - const bid = Object.assign({}, videoRequest.data); - delete bid.domain; - - const eq = { - callbackId: '84ab500420319d', - ad_type: 'video', - aid: 12345, - sizes: '480x360' - }; - - expect(bid).to.deep.equal(eq); - }); - - it('sends correct display bid parameters', function () { - const bid = Object.assign({}, displayRequest.data); - delete bid.domain; - - const eq = { - callbackId: '84ab500420319d', - ad_type: 'display', - aid: 12345, - sizes: '300x250,300x600' - }; - - expect(bid).to.deep.equal(eq); - }); - - it('sends correct video and display bid parameters', function () { - const bid = Object.assign({}, videoAndDisplayRequests.data); - delete bid.domain; - - const eq = { - callbackId: '84ab500420319d', - ad_type: 'display', - aid: 12345, - sizes: '300x250,300x600', - callbackId2: '84ab500420319d', - ad_type2: 'video', - aid2: 12345, - sizes2: '480x360' - }; - - expect(bid).to.deep.equal(eq); - }); - }); - - describe('interpretResponse', function () { - let serverResponse; - let bidderRequest; - let eqResponse; - - afterEach(function () { - serverResponse = null; - bidderRequest = null; - eqResponse = null; - }); - - it('should get correct video bid response', function () { - serverResponse = SERVER_VIDEO_RESPONSE; - bidderRequest = videoBidderRequest; - eqResponse = videoEqResponse; - - bidServerResponseCheck(); - }); - - it('should get correct display bid response', function () { - serverResponse = SERVER_DISPLAY_RESPONSE; - bidderRequest = displayBidderRequest; - eqResponse = displayEqResponse; - - bidServerResponseCheck(); - }); - - it('should set gdpr data correctly', function () { - const builtRequestData = spec.buildRequests([DISPLAY_REQUEST], displayBidderRequestWithGdpr); - - expect(builtRequestData.data.gdpr).to.be.equal(1); - expect(builtRequestData.data.gdpr_consent).to.be.equal(displayBidderRequestWithGdpr.gdprConsent.consentString); - }); - - function bidServerResponseCheck() { - const result = spec.interpretResponse({body: serverResponse}, {bidderRequest}); - - expect(result).to.deep.equal(eqResponse); - } - - function nobidServerResponseCheck() { - const noBidServerResponse = {bids: []}; - const noBidResult = spec.interpretResponse({body: noBidServerResponse}, {bidderRequest}); - - expect(noBidResult.length).to.equal(0); - } - - it('handles video nobid responses', function () { - bidderRequest = videoBidderRequest; - - nobidServerResponseCheck(); - }); - - it('handles display nobid responses', function () { - bidderRequest = displayBidderRequest; - - nobidServerResponseCheck(); - }); - }); -}); diff --git a/test/spec/modules/visxBidAdapter_spec.js b/test/spec/modules/visxBidAdapter_spec.js deleted file mode 100755 index 7a85d40c790..00000000000 --- a/test/spec/modules/visxBidAdapter_spec.js +++ /dev/null @@ -1,787 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/visxBidAdapter.js'; -import { config } from 'src/config.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import * as utils from 'src/utils.js'; - -describe('VisxAdapter', 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 () { - let bid = { - 'bidder': 'visx', - 'params': { - 'uid': '903536' - }, - '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(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'uid': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('it should fail on invalid video bid', function () { - let videoBid = Object.assign({}, bid); - videoBid.mediaTypes = { - video: { - context: 'instream', - playerSize: [400, 300] - } - }; - expect(spec.isBidRequestValid(videoBid)).to.equal(false); - }); - - it('it should pass on valid video bid', function () { - let videoBid = Object.assign({}, bid); - videoBid.mediaTypes = { - video: { - context: 'instream', - playerSize: [400, 300], - mimes: ['video/mp4'], - protocols: [3, 6] - } - }; - expect(spec.isBidRequestValid(videoBid)).to.equal(true); - }) - }); - - describe('buildRequests', function () { - const bidderRequest = { - refererInfo: { - referer: 'https://example.com' - } - }; - const referrer = bidderRequest.refererInfo.referer; - const schainObject = { - ver: '1.0', - nodes: [ - {asi: 'exchange2.com', sid: 'abcd', hp: 1}, - {asi: 'exchange1.com', sid: '1234!abcd', hp: 1, name: 'publisher, Inc.', domain: 'publisher.com'} - ] - }; - const schainString = JSON.stringify(schainObject); - let bidRequests = [ - { - 'bidder': 'visx', - 'params': { - 'uid': '903535' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }, - { - 'bidder': 'visx', - 'params': { - 'uid': '903535' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90], [300, 250]], - 'bidId': '3150ccb55da321', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }, - { - 'bidder': 'visx', - 'params': { - 'uid': '903536' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '42dbe3a7168a6a', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - }, - { - 'bidder': 'visx', - 'params': { - 'uid': '903537' - }, - 'adUnitCode': 'adunit-code-video-3', - 'mediaTypes': { - 'video': { - 'context': 'instream', - 'playerSize': [400, 300], - 'mimes': ['video/mp4', 'video/mpeg'], - 'protocols': [3, 6], - 'minduration': 5, - 'maxduration': 30 - } - }, - 'bidId': '39a4e3a7168a6a', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - it('should attach valid params to the tag', function () { - const request = spec.buildRequests([bidRequests[0]], bidderRequest); - const payload = request.data; - expect(payload).to.be.an('object'); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'net'); - expect(payload).to.have.property('auids', '903535'); - expect(payload).to.have.property('sizes', '300x250,300x600'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - expect(payload).to.have.property('cur', 'EUR'); - }); - - it('sizes must not be duplicated', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = request.data; - expect(payload).to.be.an('object'); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'net'); - expect(payload).to.have.property('auids', '903535,903535,903536,903537'); - expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - expect(payload).to.have.property('cur', 'EUR'); - }); - - it('pt parameter must be "net" if params.priceType === "gross"', function () { - bidRequests[1].params.priceType = 'gross'; - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = request.data; - expect(payload).to.be.an('object'); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'net'); - expect(payload).to.have.property('auids', '903535,903535,903536,903537'); - expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - expect(payload).to.have.property('cur', 'EUR'); - delete bidRequests[1].params.priceType; - }); - it('pt parameter must be "net" if params.priceType === "net"', function () { - bidRequests[1].params.priceType = 'net'; - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = request.data; - expect(payload).to.be.an('object'); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'net'); - expect(payload).to.have.property('auids', '903535,903535,903536,903537'); - expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - expect(payload).to.have.property('cur', 'EUR'); - delete bidRequests[1].params.priceType; - }); - - it('pt parameter must be "net" if params.priceType === "undefined"', function () { - bidRequests[1].params.priceType = 'undefined'; - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = request.data; - expect(payload).to.be.an('object'); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'net'); - expect(payload).to.have.property('auids', '903535,903535,903536,903537'); - expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - expect(payload).to.have.property('cur', 'EUR'); - delete bidRequests[1].params.priceType; - }); - - it('should add currency from currency.bidderCurrencyDefault', function () { - const getConfigStub = sinon.stub(config, 'getConfig').callsFake( - arg => arg === 'currency.bidderCurrencyDefault.visx' ? 'GBP' : 'USD'); - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = request.data; - expect(payload).to.be.an('object'); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'net'); - expect(payload).to.have.property('auids', '903535,903535,903536,903537'); - expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - expect(payload).to.have.property('cur', 'GBP'); - getConfigStub.restore(); - }); - - it('should add currency from currency.adServerCurrency', function () { - const getConfigStub = sinon.stub(config, 'getConfig').callsFake( - arg => arg === 'currency.bidderCurrencyDefault.visx' ? '' : 'USD'); - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = request.data; - expect(payload).to.be.an('object'); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'net'); - expect(payload).to.have.property('auids', '903535,903535,903536,903537'); - expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - expect(payload).to.have.property('cur', 'USD'); - getConfigStub.restore(); - }); - - it('if gdprConsent is present payload must have gdpr params', function () { - const request = spec.buildRequests(bidRequests, {gdprConsent: {consentString: 'AAA', gdprApplies: true}}); - const payload = request.data; - expect(payload).to.be.an('object'); - expect(payload).to.have.property('gdpr_consent', 'AAA'); - expect(payload).to.have.property('gdpr_applies', 1); - }); - - it('if gdprApplies is false gdpr_applies must be 0', function () { - const request = spec.buildRequests(bidRequests, {gdprConsent: {consentString: 'AAA', gdprApplies: false}}); - const payload = request.data; - expect(payload).to.be.an('object'); - expect(payload).to.have.property('gdpr_consent', 'AAA'); - expect(payload).to.have.property('gdpr_applies', 0); - }); - - it('if gdprApplies is undefined gdpr_applies must be 1', function () { - const request = spec.buildRequests(bidRequests, {gdprConsent: {consentString: 'AAA'}}); - const payload = request.data; - expect(payload).to.be.an('object'); - expect(payload).to.have.property('gdpr_consent', 'AAA'); - expect(payload).to.have.property('gdpr_applies', 1); - }); - - it('if schain is present payload must have schain param', function () { - const schainBidRequests = [ - Object.assign({schain: schainObject}, bidRequests[0]), - bidRequests[1], - bidRequests[2] - ]; - const request = spec.buildRequests(schainBidRequests, bidderRequest); - const payload = request.data; - expect(payload).to.be.an('object'); - expect(payload).to.have.property('schain', schainString); - expect(payload).to.have.property('u', referrer); - expect(payload).to.have.property('pt', 'net'); - expect(payload).to.have.property('auids', '903535,903535,903536'); - expect(payload).to.have.property('sizes', '300x250,300x600,728x90'); - expect(payload).to.have.property('r', '22edbae2733bf6'); - expect(payload).to.have.property('cur', 'EUR'); - }); - - it('if userId is available payload must have appropriate params', function () { - const schainBidRequests = [ - Object.assign({userId: { - tdid: '111', - id5id: { uid: '222' }, - digitrustid: {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}} - }}, bidRequests[0]), - bidRequests[1], - bidRequests[2] - ]; - const request = spec.buildRequests(schainBidRequests, bidderRequest); - const payload = request.data; - expect(payload).to.be.an('object'); - expect(payload).to.have.property('tdid', '111'); - expect(payload).to.have.property('id5', '222'); - expect(payload).to.have.property('dtid', 'DTID'); - }); - - it('should pass grouped video bid\'s params in payload', function () { - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = request.data; - expect(payload).to.have.property('protocols', ',,,3|6'); - expect(payload).to.have.property('mimes', ',,,video/mp4|video/mpeg'); - expect(payload).to.have.property('playerSize', ',,,400x300'); - expect(payload).to.have.property('minduration', ',,,5'); - expect(payload).to.have.property('maxduration', ',,,30'); - expect(payload).to.not.have.property('skip'); - }); - }); - - describe('interpretResponse', function () { - const responses = [ - {'bid': [{'price': 1.15, 'adm': '
test content 1
', 'auid': 903535, 'h': 250, 'w': 300, 'cur': 'EUR'}], 'seat': '1'}, - {'bid': [{'price': 0.5, 'adm': '
test content 2
', 'auid': 903536, 'h': 600, 'w': 300, 'cur': 'EUR'}], 'seat': '1'}, - {'bid': [{'price': 0.15, 'adm': '
test content 3
', 'auid': 903535, 'h': 90, 'w': 728, 'cur': 'EUR'}], 'seat': '1'}, - {'bid': [{'price': 0, 'auid': 903537, 'h': 250, 'w': 300, 'cur': 'EUR'}], 'seat': '1'}, - {'bid': [{'price': 0, 'adm': '
test content 5
', 'h': 250, 'w': 300, 'cur': 'EUR'}], 'seat': '1'}, - undefined, - {'bid': [], 'seat': '1'}, - {'seat': '1'}, - ]; - - it('should get correct bid response', function () { - const bidRequests = [ - { - 'bidder': 'visx', - 'params': { - 'uid': '903535' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '659423fff799cb', - 'bidderRequestId': '5f2009617a7c0a', - 'auctionId': '1cbd2feafe5e8b', - } - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '659423fff799cb', - 'cpm': 1.15, - 'creativeId': 903535, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'currency': 'EUR', - 'netRevenue': true, - 'ttl': 360, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': [responses[0]]}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('should get correct multi bid response', function () { - const bidRequests = [ - { - 'bidder': 'visx', - 'params': { - 'uid': '903535' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '300bfeb0d71a5b', - 'bidderRequestId': '2c2bb1972df9a', - 'auctionId': '1fa09aee5c8c99', - }, - { - 'bidder': 'visx', - 'params': { - 'uid': '903536' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '4dff80cc4ee346', - 'bidderRequestId': '2c2bb1972df9a', - 'auctionId': '1fa09aee5c8c99', - }, - { - 'bidder': 'visx', - 'params': { - 'uid': '903535' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '5703af74d0472a', - 'bidderRequestId': '2c2bb1972df9a', - 'auctionId': '1fa09aee5c8c99', - } - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '300bfeb0d71a5b', - 'cpm': 1.15, - 'creativeId': 903535, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'currency': 'EUR', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '4dff80cc4ee346', - 'cpm': 0.5, - 'creativeId': 903536, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'ad': '
test content 2
', - 'currency': 'EUR', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '5703af74d0472a', - 'cpm': 0.15, - 'creativeId': 903535, - 'dealId': undefined, - 'width': 728, - 'height': 90, - 'ad': '
test content 3
', - 'currency': 'EUR', - 'netRevenue': true, - 'ttl': 360, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': responses.slice(0, 3)}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('should return right currency', function () { - const bidRequests = [ - { - 'bidder': 'visx', - 'params': { - 'uid': '903535' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '659423fff799cb', - 'bidderRequestId': '5f2009617a7c0a', - 'auctionId': '1cbd2feafe5e8b', - } - ]; - const getConfigStub = sinon.stub(config, 'getConfig').returns('PLN'); - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '659423fff799cb', - 'cpm': 1.15, - 'creativeId': 903535, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'currency': 'PLN', - 'netRevenue': true, - 'ttl': 360, - } - ]; - - const response = Object.assign({}, responses[0]); - Object.assign(response.bid[0], {'cur': 'PLN'}); - const result = spec.interpretResponse({'body': {'seatbid': [response]}}, request); - expect(result).to.deep.equal(expectedResponse); - getConfigStub.restore(); - }); - - it('handles wrong and nobid responses', function () { - const bidRequests = [ - { - 'bidder': 'visx', - 'params': { - 'uid': '903537' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '300bfeb0d7190gf', - 'bidderRequestId': '2c2bb1972d23af', - 'auctionId': '1fa09aee5c84d34', - }, - { - 'bidder': 'visx', - 'params': { - 'uid': '903538' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '300bfeb0d71321', - 'bidderRequestId': '2c2bb1972d23af', - 'auctionId': '1fa09aee5c84d34', - }, - { - 'bidder': 'visx', - 'params': { - 'uid': '903539' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '300bfeb0d7183bb', - 'bidderRequestId': '2c2bb1972d23af', - 'auctionId': '1fa09aee5c84d34', - } - ]; - const request = spec.buildRequests(bidRequests); - const result = spec.interpretResponse({'body': {'seatbid': responses.slice(3)}}, request); - expect(result.length).to.equal(0); - }); - - it('complicated case', function () { - const fullResponse = [ - {'bid': [{'price': 1.15, 'adm': '
test content 1
', 'auid': 903535, 'h': 250, 'w': 300, 'cur': 'EUR'}], 'seat': '1'}, - {'bid': [{'price': 0.5, 'adm': '
test content 2
', 'auid': 903536, 'h': 600, 'w': 300, 'cur': 'EUR'}], 'seat': '1'}, - {'bid': [{'price': 0.15, 'adm': '
test content 3
', 'auid': 903535, 'h': 90, 'w': 728, 'cur': 'EUR'}], 'seat': '1'}, - {'bid': [{'price': 0.15, 'adm': '
test content 4
', 'auid': 903535, 'h': 600, 'w': 300, 'cur': 'EUR'}], 'seat': '1'}, - {'bid': [{'price': 0.5, 'adm': '
test content 5
', 'auid': 903536, 'h': 600, 'w': 350, 'cur': 'EUR'}], 'seat': '1'}, - ]; - const bidRequests = [ - { - 'bidder': 'visx', - 'params': { - 'uid': '903535' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '2164be6358b9', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'visx', - 'params': { - 'uid': '903535' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '326bde7fbf69', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'visx', - 'params': { - 'uid': '903536' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '4e111f1b66e4', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'visx', - 'params': { - 'uid': '903535' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '26d6f897b516', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - }, - { - 'bidder': 'visx', - 'params': { - 'uid': '903536' - }, - 'adUnitCode': 'adunit-code-2', - 'sizes': [[728, 90]], - 'bidId': '1751cd90161', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - } - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '2164be6358b9', - 'cpm': 1.15, - 'creativeId': 903535, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'currency': 'EUR', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '4e111f1b66e4', - 'cpm': 0.5, - 'creativeId': 903536, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'ad': '
test content 2
', - 'currency': 'EUR', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '26d6f897b516', - 'cpm': 0.15, - 'creativeId': 903535, - 'dealId': undefined, - 'width': 728, - 'height': 90, - 'ad': '
test content 3
', - 'currency': 'EUR', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '326bde7fbf69', - 'cpm': 0.15, - 'creativeId': 903535, - 'dealId': undefined, - 'width': 300, - 'height': 600, - 'ad': '
test content 4
', - 'currency': 'EUR', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '1751cd90161', - 'cpm': 0.5, - 'creativeId': 903536, - 'dealId': undefined, - 'width': 350, - 'height': 600, - 'ad': '
test content 5
', - 'currency': 'EUR', - 'netRevenue': true, - 'ttl': 360, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': fullResponse}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('dublicate uids and sizes in one slot', function () { - const fullResponse = [ - {'bid': [{'price': 1.15, 'adm': '
test content 1
', 'auid': 903535, 'h': 250, 'w': 300, 'cur': 'EUR'}], 'seat': '1'}, - {'bid': [{'price': 0.5, 'adm': '
test content 2
', 'auid': 903535, 'h': 250, 'w': 300, 'cur': 'EUR'}], 'seat': '1'}, - ]; - const bidRequests = [ - { - 'bidder': 'visx', - 'params': { - 'uid': '903535' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '5126e301f4be', - 'bidderRequestId': '171c5405a390', - 'auctionId': '35bcbc0f7e79c', - }, - { - 'bidder': 'visx', - 'params': { - 'uid': '903535' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '57b2ebe70e16', - 'bidderRequestId': '171c5405a390', - 'auctionId': '35bcbc0f7e79c', - }, - { - 'bidder': 'visx', - 'params': { - 'uid': '903535' - }, - 'adUnitCode': 'adunit-code-1', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '225fcd44b18c', - 'bidderRequestId': '171c5405a390', - 'auctionId': '35bcbc0f7e79c', - } - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'requestId': '5126e301f4be', - 'cpm': 1.15, - 'creativeId': 903535, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 1
', - 'currency': 'EUR', - 'netRevenue': true, - 'ttl': 360, - }, - { - 'requestId': '57b2ebe70e16', - 'cpm': 0.5, - 'creativeId': 903535, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '
test content 2
', - 'currency': 'EUR', - 'netRevenue': true, - 'ttl': 360, - } - ]; - - const result = spec.interpretResponse({'body': {'seatbid': fullResponse}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - - it('handles video bid', function () { - const fullResponse = [ - {'bid': [{'price': 0.5, 'adm': '', 'auid': 903537, 'w': 400, 'h': 300, 'cur': 'EUR'}], 'seat': '1'}, - ]; - const bidRequests = [ - { - 'bidder': 'visx', - 'params': { - 'uid': '903537' - }, - 'adUnitCode': 'adunit-code-1', - 'mediaTypes': { - 'video': { - 'context': 'instream', - 'playerSize': [400, 300], - 'mimes': ['video/mp4'], - 'protocols': [3, 6] - } - }, - 'sizes': [[400, 300]], - 'bidId': '2164be6358b9', - 'bidderRequestId': '106efe3247', - 'auctionId': '32a1f276cb87cb8', - } - ]; - const request = spec.buildRequests(bidRequests); - const expectedResponse = [ - { - 'mediaType': 'video', - 'requestId': '2164be6358b9', - 'cpm': 0.5, - 'creativeId': 903537, - 'dealId': undefined, - 'width': 400, - 'height': 300, - 'vastXml': '', - 'currency': 'EUR', - 'netRevenue': true, - 'ttl': 360, - } - ]; - const result = spec.interpretResponse({'body': {'seatbid': fullResponse}}, request); - expect(result).to.deep.equal(expectedResponse); - }); - }); - describe('check trackers', function () { - beforeEach(function () { - sinon.stub(utils, 'triggerPixel'); - }); - - afterEach(function () { - utils.triggerPixel.restore(); - }); - - it('onSetTargeting', function () { - const requestId = '111'; - spec.onSetTargeting({ requestId }); - expect(utils.triggerPixel.calledOnceWith('https://t.visx.net/track/pending?requestId=' + requestId)).to.equal(true); - }); - - it('onBidWon', function () { - const requestId = '111'; - spec.onBidWon({ requestId }); - expect(utils.triggerPixel.calledOnceWith('https://t.visx.net/track/win?requestId=' + requestId)).to.equal(true); - }); - - it('onTimeout', function () { - const data = { timeout: 3000, bidId: '23423', params: { uid: 1 } }; - spec.onTimeout(data); - expect(utils.triggerPixel.calledOnceWith('https://t.visx.net/track/bid_timeout?data=' + JSON.stringify(data))).to.equal(true); - }); - }); -}); diff --git a/test/spec/modules/vmgBidAdapter_spec.js b/test/spec/modules/vmgBidAdapter_spec.js deleted file mode 100644 index 41aa077adc7..00000000000 --- a/test/spec/modules/vmgBidAdapter_spec.js +++ /dev/null @@ -1,98 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/vmgBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -describe('VmgAdapter', 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 () { - let bidRequest = { - adUnitCode: 'div-0', - auctionId: 'd69cdd3f-75e3-42dc-b313-e54c0a99c757', - bidId: '280e2eb8ac3891', - bidRequestsCount: 1, - bidder: 'vmg', - bidderRequestId: '14690d27b056c8', - mediaTypes: { - banner: { - sizes: [ [ 970, 250 ] ] - } - }, - sizes: [ 970, 250 ], - src: 'client', - transactionId: 'af62f065-dfa7-4564-8cb2-d277dc6069f2' - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bidRequest)).to.equal(true); - }); - }) - - describe('buildRequests', function () { - let validBidRequests = [ - { - adUnitCode: 'div-0', - auctionId: 'd69cdd3f-75e3-42dc-b313-e54c0a99c757', - bidId: '280e2eb8ac3891', - bidRequestsCount: 1, - bidder: 'vmg', - bidderRequestId: '14690d27b056c8', - mediaTypes: { - banner: { - sizes: [ [ 970, 250 ] ] - } - }, - sizes: [ 970, 250 ], - src: 'client', - transactionId: 'af62f065-dfa7-4564-8cb2-d277dc6069f2' - } - ]; - - let bidderRequest = { - auctionId: 'd69cdd3f-75e3-42dc-b313-e54c0a99c757', - auctionStart: 1549316149227, - bidderCode: 'vmg', - bidderRequestId: '14690d27b056c8', - refererInfo: { - canonicalUrl: undefined, - numIframes: 0, - reachedTop: true, - referer: 'https://vmg.nyc/public_assets/adapt/prebid.html', - stack: [ 'https://vmg.nyc/public_assets/adapt/prebid.html' ] - }, - start: 1549316149229, - timeout: 1000 - }; - - it('buildRequests fires', function () { - let request = spec.buildRequests(validBidRequests, bidderRequest); - expect(request).to.exist; - expect(request.method).to.equal('POST'); - expect(request.data).to.exist; - }); - }) - - describe('interpretResponse', function () { - let serverResponse = {}; - serverResponse.body = { - 'div-0': ['test'] - }; - - var bidRequest = { - data: '[{"adUnitCode":"div-0","referer":"https://vmg.nyc/public_assets/adapt/prebid.html","bidId":"280e2eb8ac3891"}]', - method: 'POST', - url: 'https://predict.vmg.nyc' - }; - - it('interpresResponse fires', function () { - let bidResponses = spec.interpretResponse(serverResponse, bidRequest); - expect(bidResponses[0].dealId[0]).to.equal('test'); - }); - }); -}); diff --git a/test/spec/modules/voxBidAdapter_spec.js b/test/spec/modules/voxBidAdapter_spec.js deleted file mode 100644 index c6221cba9e5..00000000000 --- a/test/spec/modules/voxBidAdapter_spec.js +++ /dev/null @@ -1,320 +0,0 @@ -import { expect } from 'chai' -import { spec } from 'modules/voxBidAdapter.js' - -function getSlotConfigs(mediaTypes, params) { - return { - params: params, - sizes: [], - bidId: '2df8c0733f284e', - bidder: 'vox', - mediaTypes: mediaTypes, - transactionId: '31a58515-3634-4e90-9c96-f86196db1459' - } -} - -describe('VOX Adapter', function() { - const PLACE_ID = '5af45ad34d506ee7acad0c26'; - const bidderRequest = { - refererInfo: { referer: 'referer' } - } - const bannerMandatoryParams = { - placementId: PLACE_ID, - placement: 'banner' - } - const videoMandatoryParams = { - placementId: PLACE_ID, - placement: 'video' - } - const inImageMandatoryParams = { - placementId: PLACE_ID, - placement: 'inImage', - imageUrl: 'https://hybrid.ai/images/image.jpg' - } - const validBidRequests = [ - getSlotConfigs({ banner: {} }, bannerMandatoryParams), - 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: {}}, - { - placementId: PLACE_ID, - placement: 'banner' - } - ) - const isBidRequestValid = spec.isBidRequestValid(slotConfig) - expect(isBidRequestValid).to.equal(true) - }) - describe('and In-Image placement has the correct value', function() { - const slotConfig = getSlotConfigs( - { - banner: { - sizes: [[0, 0]] - } - }, - { - placementId: PLACE_ID, - placement: 'inImage', - imageUrl: 'imageUrl' - } - ) - const isBidRequestValid = spec.isBidRequestValid(slotConfig) - expect(isBidRequestValid).to.equal(true) - }) - describe('when video slot has all mandatory params.', function() { - it('should return true, when video mediatype object are correct.', function() { - const slotConfig = getSlotConfigs( - { - video: { - context: 'instream', - playerSize: [[640, 480]] - } - }, - { - placementId: PLACE_ID, - placement: 'video' - } - ) - const isBidRequestValid = spec.isBidRequestValid(slotConfig) - expect(isBidRequestValid).to.equal(true) - }) - }) - }) - }) - describe('returns false', function() { - describe('when params are not correct', function() { - function createSlotconfig(params) { - return getSlotConfigs({ banner: {} }, params) - } - it('does not have the placementId.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createSlotconfig({ - placement: 'banner' - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('does not have the placement.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createSlotconfig({ - placementId: PLACE_ID - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('does not have the imageUrl.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createSlotconfig({ - placementId: PLACE_ID, - placement: 'inImage' - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('does not have a the correct placement.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createSlotconfig({ - placementId: PLACE_ID, - placement: 'something' - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - }) - describe('when video mediaType object is not correct.', function() { - function createVideoSlotconfig(mediaType) { - return getSlotConfigs(mediaType, { - placementId: PLACE_ID, - placement: 'video' - }) - } - it('is a void object', function() { - const isBidRequestValid = spec.isBidRequestValid( - createVideoSlotconfig({ video: {} }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('does not have playerSize.', function() { - const isBidRequestValid = spec.isBidRequestValid( - createVideoSlotconfig({ video: { context: 'instream' } }) - ) - expect(isBidRequestValid).to.equal(false) - }) - it('does not have context', function() { - const isBidRequestValid = spec.isBidRequestValid( - createVideoSlotconfig({ - video: { - playerSize: [[640, 480]] - } - }) - ) - expect(isBidRequestValid).to.equal(false) - }) - }) - }) - }) - it('Url params should be correct ', function() { - const request = spec.buildRequests(validBidRequests, bidderRequest) - expect(request.method).to.equal('POST') - expect(request.url).to.equal('https://ssp.hybrid.ai/auction/prebid') - }) - - describe('buildRequests method', function() { - it('Common data request should be correct', function() { - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(Array.isArray(data.bidRequests)).to.equal(true) - expect(data.url).to.equal('referer') - data.bidRequests.forEach(bid => { - expect(bid.bidId).to.equal('2df8c0733f284e') - expect(bid.placeId).to.equal(PLACE_ID) - expect(bid.transactionId).to.equal('31a58515-3634-4e90-9c96-f86196db1459') - }) - }) - - describe('GDPR params', function() { - describe('when there are not consent management platform', function() { - it('cmp should be false', function() { - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(data.cmp).to.equal(false) - }) - }) - describe('when there are consent management platform', function() { - it('cmps should be true and ga should not sended, when gdprApplies is undefined', function() { - bidderRequest['gdprConsent'] = { - gdprApplies: undefined, - consentString: 'consentString' - } - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(data.cmp).to.equal(true) - expect(Object.keys(data).indexOf('data')).to.equal(-1) - expect(data.cs).to.equal('consentString') - }) - it('cmps should be true and all gdpr parameters should be sended, when there are gdprApplies', function() { - bidderRequest['gdprConsent'] = { - gdprApplies: true, - consentString: 'consentString' - } - const request = spec.buildRequests(validBidRequests, bidderRequest) - const data = JSON.parse(request.data) - expect(data.cmp).to.equal(true) - expect(data.ga).to.equal(true) - expect(data.cs).to.equal('consentString') - }) - }) - }) - }) - - describe('interpret response method', function() { - it('should return a void array, when the server response are not correct.', function() { - const request = { data: JSON.stringify({}) } - const serverResponse = { - body: {} - } - const bids = spec.interpretResponse(serverResponse, request) - expect(typeof bids).to.equal('object') - expect(bids.length).to.equal(0) - }) - it('should return a void array, when the server response have not got bids.', function() { - const request = { data: JSON.stringify({}) } - const serverResponse = { body: { bids: [] } } - const bids = spec.interpretResponse(serverResponse, request) - expect(typeof bids).to.equal('object') - expect(bids.length).to.equal(0) - }) - describe('when the server response return a bid', function() { - describe('the bid is a banner', function() { - it('should return a banner bid', function() { - const request = spec.buildRequests([validBidRequests[0]], bidderRequest) - const serverResponse = { - body: { - bids: [ - { - bidId: '2df8c0733f284e', - price: 0.5, - currency: 'USD', - content: { - content: 'html', - width: 100, - height: 100 - } - } - ] - } - } - const bids = spec.interpretResponse(serverResponse, request) - expect(bids.length).to.equal(1) - expect(bids[0].requestId).to.equal('2df8c0733f284e') - expect(bids[0].mediaType).to.equal(spec.supportedMediaTypes[0]) - expect(bids[0].cpm).to.equal(0.5) - expect(bids[0].width).to.equal(100) - expect(bids[0].height).to.equal(100) - expect(bids[0].currency).to.equal('USD') - expect(bids[0].netRevenue).to.equal(true) - expect(typeof bids[0].ad).to.equal('string') - }) - it('should return a In-Image bid', function() { - const request = spec.buildRequests([validBidRequests[2]], bidderRequest) - const serverResponse = { - body: { - bids: [ - { - bidId: '2df8c0733f284e', - price: 0.5, - currency: 'USD', - content: { - content: 'html', - width: 100, - height: 100 - }, - ttl: 360 - } - ] - } - } - const bids = spec.interpretResponse(serverResponse, request) - expect(bids.length).to.equal(1) - expect(bids[0].requestId).to.equal('2df8c0733f284e') - expect(bids[0].cpm).to.equal(0.5) - expect(bids[0].width).to.equal(100) - expect(bids[0].height).to.equal(100) - expect(bids[0].currency).to.equal('USD') - expect(bids[0].netRevenue).to.equal(true) - expect(typeof bids[0].ad).to.equal('string') - }) - }) - describe('the bid is a video', function() { - it('should return a video bid', function() { - const request = spec.buildRequests([validBidRequests[1]], bidderRequest) - const serverResponse = { - body: { - bids: [ - { - bidId: '2df8c0733f284e', - price: 0.5, - currency: 'USD', - content: 'html', - transactionId: '31a58515-3634-4e90-9c96-f86196db1459' - } - ] - } - } - const bids = spec.interpretResponse(serverResponse, request) - expect(bids.length).to.equal(1) - expect(bids[0].requestId).to.equal('2df8c0733f284e') - expect(bids[0].mediaType).to.equal(spec.supportedMediaTypes[1]) - expect(bids[0].cpm).to.equal(0.5) - expect(bids[0].currency).to.equal('USD') - expect(bids[0].netRevenue).to.equal(true) - expect(typeof bids[0].vastXml).to.equal('string') - }) - }) - }) - }) -}) diff --git a/test/spec/modules/vrtcalBidAdapter_spec.js b/test/spec/modules/vrtcalBidAdapter_spec.js deleted file mode 100644 index 729b0a723e4..00000000000 --- a/test/spec/modules/vrtcalBidAdapter_spec.js +++ /dev/null @@ -1,135 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/vrtcalBidAdapter.js'; - -describe('Vrtcal Adapter', function () { - let bid = { - bidId: 'bidID0001', - bidder: 'vrtcal', - bidderRequestId: 'brID0001', - auctionId: 'auID0001', - sizes: [[300, 250]], - transactionId: 'tid0001', - adUnitCode: 'vrtcal-test-adunit' - }; - - describe('isBidRequestValid', function () { - it('Should return true when base params as set', function () { - expect(spec.isBidRequestValid(bid)).to.be.true; - }); - it('Should return false when bid.bidId is blank', function () { - bid.bidId = ''; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - it('Should return false when bid.auctionId is blank', function () { - bid.auctionId = ''; - expect(spec.isBidRequestValid(bid)).to.be.false; - }); - }); - - describe('buildRequests', function () { - let serverRequests = spec.buildRequests([bid]); - - let serverRequest = serverRequests[0]; - - 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://rtb.vrtcal.com/bidder_prebid.vap?ssp=1804'); - }); - - it('Returns valid data if array of bids is valid', function () { - let data = JSON.parse(serverRequest.data); - expect(data).to.be.an('object'); - expect(data).to.have.all.keys('prebidJS', 'prebidAdUnitCode', 'id', 'imp', 'site', 'device'); - expect(data.prebidJS).to.not.equal(''); - expect(data.prebidAdUnitCode).to.not.equal(''); - }); - - it('Sets width and height based on existence of bid.mediaTypes.banner', function () { - let data = JSON.parse(serverRequest.data); - if (typeof (bid.mediaTypes) !== 'undefined' && typeof (bid.mediaTypes.banner) !== 'undefined' && typeof (bid.mediaTypes.banner.sizes) !== 'undefined') { - expect(data.imp[0].banner.w).to.equal(bid.mediaTypes.banner.sizes[0][0]); - expect(data.imp[0].banner.h).to.equal(bid.mediaTypes.banner.sizes[0][1]); - } else { - expect(data.imp[0].banner.w).to.equal(bid.sizes[0][0]); - expect(data.imp[0].banner.h).to.equal(bid.sizes[0][1]); - } - }); - - it('Returns empty data if no valid requests are passed', function () { - serverRequests = spec.buildRequests([]); - expect(serverRequests).to.be.an('array').that.is.empty; - }); - }); - - describe('interpretResponse', function () { - let bid = { - bidId: 'bidID0001', - bidder: 'vrtcal', - bidderRequestId: 'brID0001', - auctionId: 'auID0001', - sizes: [[300, 250]], - transactionId: 'tid0001', - adUnitCode: 'vrtcal-test-adunit' - }; - - let serverRequests = spec.buildRequests([bid]); - - let resObject = {body: {id: 'vrtcal-test-id', width: 300, height: 250, seatbid: [{bid: [{price: 3.0, w: 300, h: 250, crid: 'testcrid', adm: 'testad', nurl: 'https://vrtcal.com/faketracker'}]}], currency: 'USD', netRevenue: true, ttl: 900}}; - - let serverResponses = spec.interpretResponse(resObject, serverRequests); - - 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++) { - let dataItem = serverResponses[i]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'nurl'); - 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.nurl).to.be.a('string'); - } - - 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; - }); - }); - }); - - describe('onBidWon', function () { - let bid = { - bidId: '2dd581a2b6281d', - bidder: 'vrtcal', - bidderRequestId: '145e1d6a7837c9', - auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', - sizes: [[300, 250]], - transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e62', - adUnitCode: 'vrtcal-test-adunit' - }; - - let serverRequests = spec.buildRequests([bid]); - let resObject = {body: {id: 'vrtcal-test-id', width: 300, height: 250, seatbid: [{bid: [{price: 3.0, w: 300, h: 250, crid: 'testcrid', adm: 'testad', nurl: 'https://vrtcal.com/faketracker'}]}], currency: 'USD', netRevenue: true, ttl: 900}}; - let serverResponses = spec.interpretResponse(resObject, serverRequests); - let wonbid = serverResponses[0]; - - it('Returns true is nurl is good/not blank', function () { - expect(wonbid.nurl).to.not.equal(''); - expect(spec.onBidWon(wonbid)).to.be.true; - }); - }); -}); diff --git a/test/spec/modules/vubleAnalyticsAdapter_spec.js b/test/spec/modules/vubleAnalyticsAdapter_spec.js deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/test/spec/modules/vubleBidAdapter_spec.js b/test/spec/modules/vubleBidAdapter_spec.js deleted file mode 100644 index 2f0d1c1e262..00000000000 --- a/test/spec/modules/vubleBidAdapter_spec.js +++ /dev/null @@ -1,412 +0,0 @@ -// import or require modules necessary for the test, e.g.: - -import {expect} from 'chai'; -import {spec as adapter} from 'modules/vubleBidAdapter.js'; -import * as utils from 'src/utils.js'; - -describe('VubleAdapter', function () { - describe('Check methods existance', 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'); - }); - }); - - describe('Check method isBidRequestValid return', function () { - let bid = { - bidder: 'vuble', - params: { - env: 'net', - pubId: '3', - zoneId: '12345', - floorPrice: 5.00 // optional - }, - sizes: [[640, 360]], - mediaTypes: { - video: { - context: 'instream' - } - }, - }; - let bid2 = { - bidder: 'vuble', - params: { - env: 'net', - pubId: '3', - zoneId: '12345', - floorPrice: 5.00 // optional - }, - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 360] - } - }, - }; - - it('should be true', function () { - expect(adapter.isBidRequestValid(bid)).to.be.true; - expect(adapter.isBidRequestValid(bid2)).to.be.true; - }); - - it('should be false because the sizes are missing or in the wrong format', function () { - let wrongBid = utils.deepClone(bid); - wrongBid.sizes = '640360'; - expect(adapter.isBidRequestValid(wrongBid)).to.be.false; - - wrongBid = utils.deepClone(bid); - delete wrongBid.sizes; - expect(adapter.isBidRequestValid(wrongBid)).to.be.false; - }); - - it('should be false because the mediaType is missing or wrong', function () { - let wrongBid = utils.deepClone(bid); - wrongBid.mediaTypes = {}; - expect(adapter.isBidRequestValid(wrongBid)).to.be.false; - - wrongBid = utils.deepClone(bid); - delete wrongBid.mediaTypes; - expect(adapter.isBidRequestValid(wrongBid)).to.be.false; - }); - - it('should be false because the env is missing or wrong', function () { - let wrongBid = utils.deepClone(bid); - wrongBid.params.env = 'us'; - expect(adapter.isBidRequestValid(wrongBid)).to.be.false; - - wrongBid = utils.deepClone(bid); - delete wrongBid.params.env; - expect(adapter.isBidRequestValid(wrongBid)).to.be.false; - }); - - it('should be false because params.pubId is missing', function () { - let wrongBid = utils.deepClone(bid); - delete wrongBid.params.pubId; - expect(adapter.isBidRequestValid(wrongBid)).to.be.false; - }); - - it('should be false because params.zoneId is missing', function () { - let wrongBid = utils.deepClone(bid); - delete wrongBid.params.zoneId; - expect(adapter.isBidRequestValid(wrongBid)).to.be.false; - }); - }); - - describe('Check buildRequests method', function () { - // Bids to be formatted - let bid1 = { - bidder: 'vuble', - params: { - env: 'net', - pubId: '3', - zoneId: '12345', - floorPrice: 5.50 // optional - }, - sizes: [[640, 360]], - mediaTypes: { - video: { - context: 'instream' - } - }, - bidId: 'abdc', - adUnitCode: '' - }; - let bid2 = { - bidder: 'vuble', - params: { - env: 'com', - pubId: '8', - zoneId: '2468', - referrer: 'https://www.vuble.fr/' - }, - sizes: '640x360', - mediaTypes: { - video: { - context: 'outstream' - } - }, - bidId: 'efgh', - adUnitCode: 'code' - }; - let bid3 = { - bidder: 'vuble', - params: { - env: 'net', - pubId: '3', - zoneId: '3579', - }, - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 360] - } - }, - bidId: 'ijkl', - adUnitCode: '' - }; - - // Formatted requets - let request1 = { - method: 'POST', - url: 'https://player.mediabong.net/prebid/request', - data: { - width: '640', - height: '360', - pub_id: '3', - zone_id: '12345', - context: 'instream', - floor_price: 5.5, - url: '', - env: 'net', - bid_id: 'abdc', - adUnitCode: '' - } - }; - let request2 = { - method: 'POST', - url: 'https://player.mediabong.com/prebid/request', - data: { - width: '640', - height: '360', - pub_id: '8', - zone_id: '2468', - context: 'outstream', - floor_price: 0, - url: 'https://www.vuble.fr/', - env: 'com', - bid_id: 'efgh', - adUnitCode: 'code' - } - }; - let request3 = { - method: 'POST', - url: 'https://player.mediabong.net/prebid/request', - data: { - width: '640', - height: '360', - pub_id: '3', - zone_id: '3579', - context: 'instream', - floor_price: 0, - url: 'https://www.vuble.tv/', - env: 'net', - bid_id: 'ijkl', - adUnitCode: '' - } - }; - let request4 = { - method: 'POST', - url: 'https://player.mediabong.net/prebid/request', - data: { - width: '640', - height: '360', - pub_id: '3', - zone_id: '3579', - context: 'instream', - floor_price: 0, - url: '', - env: 'net', - bid_id: 'ijkl', - adUnitCode: '', - gdpr_consent: { - consent_string: 'test', - gdpr_applies: true - } - } - }; - let bidderRequest1 = { - refererInfo: { - referer: 'https://www.vuble.tv/', - reachedTop: true, - numIframes: 1, - stack: [ - 'http://example.com/page.html', - 'http://example.com/iframe1.html', - 'http://example.com/iframe2.html' - ] - } - }; - let bidderRequest2 = { - 'gdprConsent': { - consentString: 'test', - gdprApplies: true - } - }; - - it('must return the right formatted requests', function () { - expect(adapter.buildRequests([bid1, bid2])).to.deep.equal([request1, request2]); - expect(adapter.buildRequests([bid3], bidderRequest1)).to.deep.equal([request3]); - expect(adapter.buildRequests([bid3], bidderRequest2)).to.deep.equal([request4]); - }); - }); - - describe('Check interpretResponse method return', function () { - // Server's response - let response = { - body: { - status: 'ok', - cpm: 5.00, - creativeId: '2468', - url: 'https//player.mediabong.net/prebid/ad/a1b2c3d4', - dealId: 'MDB-TEST-1357' - } - }; - // bid Request - let bid = { - data: { - context: 'instream', - env: 'net', - width: '640', - height: '360', - pub_id: '3', - zone_id: '12345', - bid_id: 'abdc', - floor_price: 5.50, // optional - adUnitCode: 'code' - }, - method: 'POST', - url: 'https://player.mediabong.net/prebid/request' - }; - // Formatted reponse - let result = { - requestId: 'abdc', - cpm: 5.00, - width: '640', - height: '360', - ttl: 60, - creativeId: '2468', - dealId: 'MDB-TEST-1357', - netRevenue: true, - currency: 'USD', - vastUrl: 'https//player.mediabong.net/prebid/ad/a1b2c3d4', - mediaType: 'video' - }; - - it('should equal to the expected formatted result', function () { - expect(adapter.interpretResponse(response, bid)).to.deep.equal([result]); - }); - - it('should be empty because the status is missing or wrong', function () { - let wrongResponse = utils.deepClone(response); - wrongResponse.body.status = 'ko'; - expect(adapter.interpretResponse(wrongResponse, bid)).to.be.empty; - - wrongResponse = utils.deepClone(response); - delete wrongResponse.body.status; - expect(adapter.interpretResponse(wrongResponse, bid)).to.be.empty; - }); - - it('should be empty because the body is missing or wrong', function () { - let wrongResponse = utils.deepClone(response); - wrongResponse.body = [1, 2, 3]; - expect(adapter.interpretResponse(wrongResponse, bid)).to.be.empty; - - wrongResponse = utils.deepClone(response); - delete wrongResponse.body; - expect(adapter.interpretResponse(wrongResponse, bid)).to.be.empty; - }); - - it('should equal to the expected formatted result', function () { - response.body.renderer_url = 'vuble_renderer.js'; - result.adUnitCode = 'code'; - let formattedResponses = adapter.interpretResponse(response, bid); - expect(formattedResponses[0].adUnitCode).to.equal(result.adUnitCode); - }); - }); - - describe('Check getUserSyncs method return', function () { - // Sync options - let syncOptions = { - iframeEnabled: false - }; - // Server's response - let response = { - body: { - status: 'ok', - cpm: 5.00, - creativeId: '2468', - url: 'https//player.mediabong.net/prebid/ad/a1b2c3d4' - } - }; - // Formatted reponse - let result = { - type: 'iframe', - url: 'https://player.mediabong.net/csifr?1234' - }; - - it('should return an empty array', function () { - expect(adapter.getUserSyncs({}, [])).to.be.empty; - expect(adapter.getUserSyncs({}, [])).to.be.empty; - expect(adapter.getUserSyncs(syncOptions, [response])).to.be.empty; - expect(adapter.getUserSyncs(syncOptions, [response])).to.be.empty; - syncOptions.iframeEnabled = true; - expect(adapter.getUserSyncs(syncOptions, [response])).to.be.empty; - expect(adapter.getUserSyncs(syncOptions, [response])).to.be.empty; - }); - - it('should be equal to the expected result', function () { - response.body.iframeSync = 'https://player.mediabong.net/csifr?1234'; - expect(adapter.getUserSyncs(syncOptions, [response])).to.deep.equal([result]); - }) - }); - - describe('Check outstream scenario with renderer', function () { - // bid Request - let bid = { - data: { - context: 'outstream', - env: 'net', - width: '640', - height: '360', - pub_id: '3', - zone_id: '12345', - bid_id: 'abdc', - floor_price: 5.50, // optional - adUnitCode: 'code' - }, - method: 'POST', - url: 'https://player.mediabong.net/prebid/request' - }; - // Server's response - let response = { - body: { - status: 'ok', - cpm: 5.00, - creativeId: '2468', - url: 'https//player.mediabong.net/prebid/ad/a1b2c3d4', - dealId: 'MDB-TEST-1357', - renderer_id: 0, - renderer_url: 'vuble_renderer.js', - content: 'test' - } - }; - - let adResponse = { - ad: { - video: { - content: 'test' - } - } - }; - let adUnitCode = 'code'; - let rendererUrl = 'vuble_renderer.js'; - let rendererId = 0; - - let formattedResponses = adapter.interpretResponse(response, bid); - it('should equal to the expected format result', function () { - expect(formattedResponses[0].adResponse).to.deep.equal(adResponse); - expect(formattedResponses[0].adUnitCode).to.deep.equal(adUnitCode); - expect(formattedResponses[0].renderer.url).to.equal(rendererUrl); - expect(formattedResponses[0].renderer.id).to.equal(rendererId); - expect(formattedResponses[0].renderer.render).to.exist.and.to.be.a('function'); - }); - }); -}); diff --git a/test/spec/modules/vuukleBidAdapter_spec.js b/test/spec/modules/vuukleBidAdapter_spec.js deleted file mode 100644 index fdca4085c8e..00000000000 --- a/test/spec/modules/vuukleBidAdapter_spec.js +++ /dev/null @@ -1,59 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/vuukleBidAdapter.js'; - -describe('vuukleBidAdapterTests', function() { - let bidRequestData = { - bids: [ - { - bidId: 'testbid', - bidder: 'vuukle', - params: { - test: 1 - }, - sizes: [[300, 250]] - } - ] - }; - let request = []; - - it('validate_pub_params', function() { - expect( - spec.isBidRequestValid({ - bidder: 'vuukle', - params: { - test: 1 - } - }) - ).to.equal(true); - }); - - it('validate_generated_params', function() { - request = spec.buildRequests(bidRequestData.bids); - let req_data = request[0].data; - - expect(req_data.bidId).to.equal('testbid'); - }); - - it('validate_response_params', function() { - let serverResponse = { - body: { - 'cpm': 0.01, - 'width': 300, - 'height': 250, - 'creative_id': '12345', - 'ad': 'test ad' - } - }; - - request = spec.buildRequests(bidRequestData.bids); - let bids = spec.interpretResponse(serverResponse, request[0]); - expect(bids).to.have.lengthOf(1); - - let bid = bids[0]; - expect(bid.ad).to.equal('test ad'); - expect(bid.cpm).to.equal(0.01); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.creativeId).to.equal('12345'); - }); -}); diff --git a/test/spec/modules/waardexBidAdapter_spec.js b/test/spec/modules/waardexBidAdapter_spec.js deleted file mode 100644 index 73094dd72a0..00000000000 --- a/test/spec/modules/waardexBidAdapter_spec.js +++ /dev/null @@ -1,377 +0,0 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/waardexBidAdapter.js'; -import {auctionManager} from 'src/auctionManager.js'; -import {deepClone} from 'src/utils.js'; - -describe('waardexBidAdapter', () => { - describe('isBidRequestValid', () => { - it('should return true. bidId and params such as placementId and zoneId are present', () => { - const result = spec.isBidRequestValid({ - bidId: '112435ry', - bidder: 'waardex', - params: { - placementId: 1, - traffic: 'banner', - zoneId: 1, - } - }); - - expect(result).to.be.true; - }); - - it('should return false. bidId is not present in bid object', () => { - const result = spec.isBidRequestValid({ - bidder: 'waardex', - params: { - placementId: 1, - traffic: 'banner', - zoneId: 1, - } - }); - - expect(result).to.be.false; - }); - - it('should return false. zoneId is not present in bid.params object', () => { - const result = spec.isBidRequestValid({ - bidId: '112435ry', - bidder: 'waardex', - params: { - placementId: 1, - traffic: 'banner', - } - }); - - expect(result).to.be.false; - }); - - it('should return true when mediaTypes field is empty', () => { - const result = spec.isBidRequestValid({ - bidId: '112435ry', - bidder: 'waardex', - params: { - placementId: 1, - traffic: 'banner', - zoneId: 1, - } - }); - - expect(result).to.be.true; - }); - - it('should return false when mediaTypes.video.playerSize field is empty', () => { - const result = spec.isBidRequestValid({ - bidId: '112435ry', - bidder: 'waardex', - params: { - placementId: 1, - traffic: 'banner', - zoneId: 1, - }, - mediaTypes: { - video: {} - } - }); - - expect(result).to.be.false; - }); - - it('should return false when mediaTypes.video.playerSize field is not an array', () => { - const result = spec.isBidRequestValid({ - bidId: '112435ry', - bidder: 'waardex', - params: { - placementId: 1, - traffic: 'banner', - zoneId: 1, - }, - mediaTypes: { - video: { - playerSize: 'not-array' - } - } - }); - - expect(result).to.be.false; - }); - - it('should return false when mediaTypes.video.playerSize field is an empty array', () => { - const result = spec.isBidRequestValid({ - bidId: '112435ry', - bidder: 'waardex', - params: { - placementId: 1, - traffic: 'banner', - zoneId: 1, - }, - mediaTypes: { - video: { - playerSize: [] - } - } - }); - - expect(result).to.be.false; - }); - - it('should return false when mediaTypes.video.playerSize field is empty array', () => { - const result = spec.isBidRequestValid({ - bidId: '112435ry', - bidder: 'waardex', - params: { - placementId: 1, - traffic: 'banner', - zoneId: 1, - }, - mediaTypes: { - video: { - playerSize: [] - } - } - }); - - expect(result).to.be.false; - }); - - it('should return true when mediaTypes.video.playerSize field is non-empty array', () => { - const result = spec.isBidRequestValid({ - bidId: '112435ry', - bidder: 'waardex', - params: { - placementId: 1, - traffic: 'banner', - zoneId: 1, - }, - mediaTypes: { - video: { - playerSize: [[640, 400]] - } - } - }); - - expect(result).to.be.true; - }); - }); - - describe('buildRequests', () => { - let getAdUnitsStub; - const validBidRequests = [ - { - bidId: 'fergr675ujgh', - mediaTypes: { - banner: { - sizes: [[300, 600], [300, 250]] - } - }, - params: { - bidfloor: 1.5, - position: 1, - instl: 1, - zoneId: 100 - }, - }, - { - bidId: 'unique-bid-id-2', - mediaTypes: { - video: { - context: 'outstream', - playerSize: [[640, 400]] - } - }, - params: { - mimes: ['video/x-ms-wmv', 'video/mp4'], - minduration: 2, - maxduration: 10, - protocols: ['VAST 1.0', 'VAST 2.0'], - startdelay: -1, - placement: 1, - skip: 1, - skipafter: 2, - minbitrate: 0, - maxbitrate: 0, - delivery: [1, 2, 3], - playbackmethod: [1, 2], - api: [1, 2, 3, 4, 5, 6], - linearity: 1, - } - } - ]; - - const bidderRequest = { - refererInfo: { - referer: 'https://www.google.com/?some_param=some_value' - }, - }; - - beforeEach(() => getAdUnitsStub = sinon.stub(auctionManager, 'getAdUnits').callsFake(() => [])); - afterEach(() => getAdUnitsStub.restore()); - - it('should return valid build request object', () => { - const { - data: payload, - url, - method, - } = spec.buildRequests(validBidRequests, bidderRequest); - - const ENDPOINT = `https://hb.justbidit.xyz:8843/prebid?pubId=${validBidRequests[0].params.zoneId}`; - - expect(payload.bidRequests[0]).deep.equal({ - bidId: validBidRequests[0].bidId, - bidfloor: validBidRequests[0].params.bidfloor, - position: validBidRequests[0].params.position, - instl: validBidRequests[0].params.instl, - banner: { - sizes: [ - { - width: validBidRequests[0].mediaTypes.banner.sizes[0][0], - height: validBidRequests[0].mediaTypes.banner.sizes[0][1] - }, - { - width: validBidRequests[0].mediaTypes.banner.sizes[1][0], - height: validBidRequests[0].mediaTypes.banner.sizes[1][1] - }, - ], - } - }); - expect(url).to.equal(ENDPOINT); - expect(method).to.equal('POST'); - }); - }); - - describe('interpretResponse', () => { - const serverResponse = { - body: { - seatbid: [ - { - bid: [ - { - 'id': 'ec90d4ee25433c0875c56f59acc12109', - 'adm': 'banner should be here', - 'w': 300, - 'h': 250, - 'price': 0.15827000000000002, - 'nurl': 'http://n63.justbidit.xyz?w=n&p=${AUCTION_PRICE}&t=b&uq=eb31018b3da8965dde414c0006b1fb31', - 'impid': 'unique-bid-id-1', - 'adomain': [ - 'www.kraeuterhaus.de' - ], - 'cat': [ - 'IAB24' - ], - 'attr': [ - 4 - ], - 'iurl': 'https://rtb.bsmartdata.com/preview.php?id=13', - 'cid': '286557fda4585dc1c7f98b773de92509', - 'crid': 'dd2b5a1f3f1fc5e63b042ebf4b00ca80' - }, - ], - } - ], - }, - }; - - const request = { - 'ua': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/86.0.4240.198 Safari/537.36', - 'language': 'en', - 'referer': 'https%3A%2F%2Fwww.google.com%2F%3Fsome_param%3Dsome_value', - 'coppa': false, - 'data': { - 'bidRequests': [ - { - 'bidId': 'unique-bid-id-1', - 'bidfloor': 0.1, - 'position': 1, - 'instl': 1, - 'banner': { - 'sizes': [ - { - 'width': 300, - 'height': 600 - }, - { - 'width': 300, - 'height': 250 - } - ] - } - }, - ] - } - }; - - it('bid response is valid', () => { - const result = spec.interpretResponse(serverResponse, request); - - const expected = [ - { - requestId: 'unique-bid-id-1', - cpm: serverResponse.body.seatbid[0].bid[0].price, - currency: 'USD', - width: serverResponse.body.seatbid[0].bid[0].w, - height: serverResponse.body.seatbid[0].bid[0].h, - mediaType: 'banner', - creativeId: serverResponse.body.seatbid[0].bid[0].crid, - netRevenue: true, - ttl: 3000, - ad: serverResponse.body.seatbid[0].bid[0].adm, - dealId: serverResponse.body.seatbid[0].bid[0].dealid, - meta: { - cid: serverResponse.body.seatbid[0].bid[0].cid, - adomain: serverResponse.body.seatbid[0].bid[0].adomain, - mediaType: (serverResponse.body.seatbid[0].bid[0].ext || {}).mediaType, - }, - } - ]; - expect(result).deep.equal(expected); - }); - - it('invalid bid response. requestId is not exists in bid response', () => { - const invalidServerResponse = deepClone(serverResponse); - delete invalidServerResponse.body.seatbid[0].bid[0].id; - - const result = spec.interpretResponse(invalidServerResponse); - expect(result).deep.equal([]); - }); - - it('invalid bid response. cpm is not exists in bid response', () => { - const invalidServerResponse = deepClone(serverResponse); - delete invalidServerResponse.body.seatbid[0].bid[0].price; - - const result = spec.interpretResponse(invalidServerResponse); - expect(result).deep.equal([]); - }); - - it('invalid bid response. creativeId is not exists in bid response', () => { - const invalidServerResponse = deepClone(serverResponse); - delete invalidServerResponse.body.seatbid[0].bid[0].crid; - - const result = spec.interpretResponse(invalidServerResponse); - expect(result).deep.equal([]); - }); - - it('invalid bid response. width is not exists in bid response', () => { - const invalidServerResponse = deepClone(serverResponse); - delete invalidServerResponse.body.seatbid[0].bid[0].w; - - const result = spec.interpretResponse(invalidServerResponse); - expect(result).deep.equal([]); - }); - - it('invalid bid response. height is not exists in bid response', () => { - const invalidServerResponse = deepClone(serverResponse); - delete invalidServerResponse.body.seatbid[0].bid[0].h; - - const result = spec.interpretResponse(invalidServerResponse); - expect(result).deep.equal([]); - }); - - it('invalid bid response. ad is not exists in bid response', () => { - const invalidServerResponse = deepClone(serverResponse); - delete invalidServerResponse.body.seatbid[0].bid[0].adm; - - const result = spec.interpretResponse(invalidServerResponse); - expect(result).deep.equal([]); - }); - }); -}); diff --git a/test/spec/modules/welectBidAdapter_spec.js b/test/spec/modules/welectBidAdapter_spec.js deleted file mode 100644 index 571f68038ac..00000000000 --- a/test/spec/modules/welectBidAdapter_spec.js +++ /dev/null @@ -1,205 +0,0 @@ -import {expect} from 'chai'; -import {spec as adapter} from 'modules/welectBidAdapter.js'; - -describe('WelectAdapter', function () { - describe('Check methods existance', 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'); - }); - }); - - describe('Check method isBidRequestValid return', function () { - let bid = { - bidder: 'welect', - params: { - placementId: 'exampleAlias', - domain: 'www.welect.de' - }, - sizes: [[640, 360]], - mediaTypes: { - video: { - context: 'instream' - } - }, - }; - let bid2 = { - bidder: 'welect', - params: { - domain: 'www.welect.de' - }, - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 360] - } - }, - }; - - it('should be true', function () { - expect(adapter.isBidRequestValid(bid)).to.be.true; - }); - - it('should be false because the placementId is missing', function () { - expect(adapter.isBidRequestValid(bid2)).to.be.false; - }); - }); - - describe('Check buildRequests method', function () { - // Bids to be formatted - let bid1 = { - bidder: 'welect', - params: { - placementId: 'exampleAlias' - }, - sizes: [[640, 360]], - mediaTypes: { - video: { - context: 'instream' - } - }, - bidId: 'abdc' - }; - let bid2 = { - bidder: 'welect', - params: { - placementId: 'exampleAlias', - domain: 'www.welect2.de' - }, - sizes: [[640, 360]], - mediaTypes: { - video: { - context: 'instream' - } - }, - bidId: 'abdc', - gdprConsent: { - gdprApplies: 1, - gdprConsent: 'some_string' - } - }; - - let data1 = { - bid_id: 'abdc', - width: 640, - height: 360 - } - - let data2 = { - bid_id: 'abdc', - width: 640, - height: 360, - gdpr_consent: { - gdprApplies: 1, - tcString: 'some_string' - } - } - - // Formatted requets - let request1 = { - method: 'POST', - url: 'https://www.welect.de/api/v2/preflight/exampleAlias', - data: data1, - options: { - contentType: 'application/json', - withCredentials: false, - crossOrigin: true, - } - }; - - let request2 = { - method: 'POST', - url: 'https://www.welect2.de/api/v2/preflight/exampleAlias', - data: data2, - options: { - contentType: 'application/json', - withCredentials: false, - crossOrigin: true, - } - } - - it('defaults to www.welect.de, without gdpr object', function () { - expect(adapter.buildRequests([bid1])).to.deep.equal([request1]); - }) - - it('must return the right formatted requests, with gdpr object', function () { - expect(adapter.buildRequests([bid2])).to.deep.equal([request2]); - }); - }); - - describe('Check interpretResponse method return', function () { - // invalid server response - let unavailableResponse = { - body: { - available: false - } - }; - - let availableResponse = { - body: { - available: true, - bidResponse: { - ad: { - video: 'some vast url' - }, - cpm: 17, - creativeId: 'svmpreview', - currency: 'EUR', - netRevenue: true, - requestId: 'some bid id', - ttl: 120, - vastUrl: 'some vast url', - height: 640, - width: 320 - } - } - } - // bid Request - let bid = { - data: { - bid_id: 'some bid id', - width: 640, - height: 320, - gdpr_consent: { - gdprApplies: 1, - tcString: 'some_string' - } - }, - method: 'POST', - url: 'https://www.welect.de/api/v2/preflight/exampleAlias', - options: { - contentType: 'application/json', - withCredentials: false, - crossOrigin: true, - } - }; - // Formatted reponse - let result = { - ad: { - video: 'some vast url' - }, - cpm: 17, - creativeId: 'svmpreview', - currency: 'EUR', - height: 640, - netRevenue: true, - requestId: 'some bid id', - ttl: 120, - vastUrl: 'some vast url', - width: 320 - } - - it('if response reflects unavailability, should be empty', function () { - expect(adapter.interpretResponse(unavailableResponse, bid)).to.deep.equal([]); - }); - - it('if response reflects availability, should equal result', function() { - expect(adapter.interpretResponse(availableResponse, bid)).to.deep.equal([result]) - }) - }); -}); diff --git a/test/spec/modules/widespaceBidAdapter_spec.js b/test/spec/modules/widespaceBidAdapter_spec.js deleted file mode 100644 index 382bf2c593e..00000000000 --- a/test/spec/modules/widespaceBidAdapter_spec.js +++ /dev/null @@ -1,265 +0,0 @@ -import {expect} from 'chai'; -import {spec, storage} from 'modules/widespaceBidAdapter.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -describe('+widespaceAdatperTest', function () { - // Dummy bid request - const bidRequest = [{ - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'auctionId': 'bf1e57ee-fff2-4304-8143-91aaf423a948', - 'bidId': '4045696e2278cd', - 'bidder': 'widespace', - 'params': { - sid: '7b6589bf-95c8-4656-90b9-af9737bb9ad3', - currency: 'EUR', - demo: { - gender: 'M', - country: 'Sweden', - region: 'Stockholm', - postal: '15115', - city: 'Stockholm', - yob: '1984' - } - }, - 'bidderRequestId': '37a5f053efef34', - 'sizes': [[320, 320], [300, 250], [300, 300]], - 'transactionId': '4f68b713-04ba-4d7f-8df9-643bcdab5efb' - }, { - 'adUnitCode': 'div-gpt-ad-1460505748561-1', - 'auctionId': 'bf1e57ee-fff2-4304-8143-91aaf423a944', - 'bidId': '4045696e2278ab', - 'bidder': 'widespace', - 'params': { - sid: '7b6589bf-95c8-4656-90b9-af9737bb9ad4', - demo: { - gender: 'M', - country: 'Sweden', - region: 'Stockholm', - postal: '15115', - city: 'Stockholm', - yob: '1984' - } - }, - 'bidderRequestId': '37a5f053efef34', - 'sizes': [[300, 300]], - 'transactionId': '4f68b713-04ba-4d7f-8df9-643bcdab5efv' - }]; - - // Dummy bidderRequest object - const bidderRequest = { - auctionId: 'bf1e57ee-fff2-4304-8143-91aaf423a944', - auctionStart: 1527418994278, - bidderCode: 'widespace', - bidderRequestId: '37a5f053efef34', - timeout: 3000, - gdprConsent: { - consentString: 'consentString', - gdprApplies: true, - vendorData: { - hasGlobalScope: false - } - } - }; - - // Dummy bid response with ad code - const bidResponse = { - body: [{ - 'adId': '12345', - 'bidId': '67890', - 'code': '
', - 'cpm': 6.6, - 'currency': 'EUR', - 'height': 300, - 'netRev': true, - 'reqId': '224804081406', - 'status': 'ad', - 'ttl': 30, - 'width': 300, - 'syncPixels': ['https://url1.com/url', 'https://url2.com/url'] - }], - headers: {} - }; - - // Dummy bid response of noad - const bidResponseNoAd = { - body: [{ - 'status': 'noad', - }], - headers: {} - }; - - // Appending a div with id of adUnitCode so we can calculate vol - const div1 = document.createElement('div'); - div1.id = bidRequest[0].adUnitCode; - document.body.appendChild(div1); - const div2 = document.createElement('div'); - div2.id = bidRequest[0].adUnitCode; - document.body.appendChild(div2); - - // Adding custom data cookie se we can test cookie is readable - const theDate = new Date(); - const expDate = new Date(theDate.setMonth(theDate.getMonth() + 1)).toGMTString(); - window.document.cookie = `wsCustomData1={id: test};path=/;expires=${expDate};`; - const PERF_DATA = JSON.stringify({perf_status: 'OK', perf_reqid: '226920425154', perf_ms: '747'}); - window.document.cookie = `wsPerfData123=${PERF_DATA};path=/;expires=${expDate};`; - - // Connect dummy data test - const CONNECTION = navigator.connection || navigator.webkitConnection; - if (CONNECTION && CONNECTION.type && CONNECTION.downlinkMax) { - navigator.connection.downlinkMax = 80; - navigator.connection.type = 'wifi'; - } - - describe('+bidRequestValidity', function () { - it('bidRequest with sid and currency params', function () { - expect(spec.isBidRequestValid({ - bidder: 'widespace', - params: { - sid: '7b6589bf-95c8-4656-90b9-af9737bb9ad3', - currency: 'EUR' - } - })).to.equal(true); - }); - - it('-bidRequest with missing sid', function () { - expect(spec.isBidRequestValid({ - bidder: 'widespace', - params: { - currency: 'EUR' - } - })).to.equal(false); - }); - - it('-bidRequest with missing currency', function () { - expect(spec.isBidRequestValid({ - bidder: 'widespace', - params: { - sid: '7b6589bf-95c8-4656-90b9-af9737bb9ad3' - } - })).to.equal(true); - }); - }); - - describe('+bidRequest', function () { - let request; - const UrlRegExp = /^((ftp|http|https):)?\/\/[^ "]+$/; - before(function() { - request = spec.buildRequests(bidRequest, bidderRequest); - }) - - let fakeLocalStorage = {}; - let lsSetStub; - let lsGetStub; - let lsRemoveStub; - - beforeEach(function () { - lsSetStub = sinon.stub(storage, 'setDataInLocalStorage').callsFake(function (name, value) { - fakeLocalStorage[name] = value; - }); - - lsGetStub = sinon.stub(storage, 'getDataFromLocalStorage').callsFake(function (key) { - return fakeLocalStorage[key] || null; - }); - - lsRemoveStub = sinon.stub(storage, 'removeDataFromLocalStorage').callsFake(function (key) { - if (key && (fakeLocalStorage[key] !== null || fakeLocalStorage[key] !== undefined)) { - delete fakeLocalStorage[key]; - } - return true; - }); - }); - - afterEach(function () { - lsSetStub.restore(); - lsGetStub.restore(); - lsRemoveStub.restore(); - fakeLocalStorage = {}; - }); - - it('-bidRequest method is POST', function () { - expect(request[0].method).to.equal('POST'); - }); - - it('-bidRequest url is valid', function () { - expect(UrlRegExp.test(request[0].url)).to.equal(true); - }); - - it('-bidRequest data exist', function () { - expect(request[0].data).to.exist; - }); - - it('-bidRequest data is form data', function () { - expect(typeof request[0].data).to.equal('string'); - }); - - it('-bidRequest options have header type', function () { - expect(request[0].options.contentType).to.exist; - }); - - it('-cookie test for wsCustomData ', function () { - expect(request[0].data.indexOf('hb.cd') > -1).to.equal(true); - }); - }); - - describe('+interpretResponse', function () { - it('-required params available in response', function () { - const result = spec.interpretResponse(bidResponse, bidRequest); - let requiredKeys = [ - 'requestId', - 'cpm', - 'width', - 'height', - 'creativeId', - 'currency', - 'netRevenue', - 'ttl', - 'referrer', - 'ad' - ]; - const resultKeys = Object.keys(result[0]); - requiredKeys.forEach((key) => { - expect(includes(resultKeys, key)).to.equal(true); - }); - - // Each value except referrer should not be empty|null|undefined - result.forEach((res) => { - Object.keys(res).forEach((resKey) => { - if (resKey !== 'referrer') { - expect(res[resKey]).to.not.be.null; - expect(res[resKey]).to.not.be.undefined; - expect(res[resKey]).to.not.equal(''); - } - }); - }); - }); - - it('-empty result if noad responded', function () { - const noAdResult = spec.interpretResponse(bidResponseNoAd, bidRequest); - expect(noAdResult.length).to.equal(0); - }); - - it('-empty response should not breake anything in adapter', function () { - const noResponse = spec.interpretResponse({}, bidRequest); - expect(noResponse.length).to.equal(0); - }); - }); - - describe('+getUserSyncs', function () { - it('-always return an array', function () { - const userSync_test1 = spec.getUserSyncs({}, [bidResponse]); - expect(Array.isArray(userSync_test1)).to.equal(true); - - const userSync_test2 = spec.getUserSyncs({}, [bidResponseNoAd]); - expect(Array.isArray(userSync_test2)).to.equal(true); - - const userSync_test3 = spec.getUserSyncs({}, [bidResponse, bidResponseNoAd]); - expect(Array.isArray(userSync_test3)).to.equal(true); - - const userSync_test4 = spec.getUserSyncs(); - expect(Array.isArray(userSync_test4)).to.equal(true); - - const userSync_test5 = spec.getUserSyncs({}, []); - expect(Array.isArray(userSync_test5)).to.equal(true); - }); - }); -}); diff --git a/test/spec/modules/windtalkerBidAdapter_spec.js b/test/spec/modules/windtalkerBidAdapter_spec.js deleted file mode 100644 index 222a7611b01..00000000000 --- a/test/spec/modules/windtalkerBidAdapter_spec.js +++ /dev/null @@ -1,348 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/windtalkerBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; - -describe('Windtalker Adapter Tests', function () { - const slotConfigs = [{ - placementCode: '/DfpAccount1/slot1', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bidId: 'bid12345', - mediaType: 'banner', - params: { - pubId: '29521', - siteId: '26047', - placementId: '123', - bidFloor: '0.001', - ifa: 'IFA', - latitude: '40.712775', - longitude: '-74.005973' - } - }, { - placementCode: '/DfpAccount2/slot2', - mediaTypes: { - banner: { - sizes: [[728, 90]] - } - }, - bidId: 'bid23456', - mediaType: 'banner', - params: { - pubId: '29521', - siteId: '26047', - placementId: '1234', - bidFloor: '0.000001', - } - }]; - const nativeSlotConfig = [{ - placementCode: '/DfpAccount1/slot3', - bidId: 'bid12345', - mediaType: 'native', - nativeParams: { - title: { required: true, len: 200 }, - body: {}, - image: { wmin: 100 }, - sponsoredBy: { }, - icon: { } - }, - params: { - pubId: '29521', - placementId: '123', - siteId: '26047' - } - }]; - const videoSlotConfig = [{ - placementCode: '/DfpAccount1/slot4', - mediaTypes: { - video: { - playerSize: [[640, 480]] - } - }, - bidId: 'bid12345678', - mediaType: 'video', - video: { - skippable: true - }, - params: { - pubId: '29521', - placementId: '1234567', - siteId: '26047', - } - }]; - const appSlotConfig = [{ - placementCode: '/DfpAccount1/slot5', - bidId: 'bid12345', - params: { - pubId: '29521', - placementId: '1234', - app: { - id: '1111', - name: 'app name', - bundle: 'io.windtalker.apps', - storeUrl: 'https://windtalker.io/apps', - domain: 'windtalker.io' - } - } - }]; - - it('Verify build request', function () { - const request = spec.buildRequests(slotConfigs); - expect(request.url).to.equal('https://windtalkerdisplay.hb.adp3.net/'); - expect(request.method).to.equal('POST'); - const ortbRequest = JSON.parse(request.data); - // site object - expect(ortbRequest.site).to.not.equal(null); - expect(ortbRequest.site.publisher).to.not.equal(null); - expect(ortbRequest.site.publisher.id).to.equal('29521'); - expect(ortbRequest.site.ref).to.equal(window.top.document.referrer); - expect(ortbRequest.site.page).to.equal(window.location.href); - expect(ortbRequest.imp).to.have.lengthOf(2); - // device object - expect(ortbRequest.device).to.not.equal(null); - expect(ortbRequest.device.ua).to.equal(navigator.userAgent); - expect(ortbRequest.device.ifa).to.equal('IFA'); - expect(ortbRequest.device.geo.lat).to.equal('40.712775'); - expect(ortbRequest.device.geo.lon).to.equal('-74.005973'); - // slot 1 - expect(ortbRequest.imp[0].tagid).to.equal('123'); - expect(ortbRequest.imp[0].banner).to.not.equal(null); - expect(ortbRequest.imp[0].banner.w).to.equal(300); - expect(ortbRequest.imp[0].banner.h).to.equal(250); - expect(ortbRequest.imp[0].bidfloor).to.equal('0.001'); - // slot 2 - expect(ortbRequest.imp[1].tagid).to.equal('1234'); - expect(ortbRequest.imp[1].banner).to.not.equal(null); - expect(ortbRequest.imp[1].banner.w).to.equal(728); - expect(ortbRequest.imp[1].banner.h).to.equal(90); - expect(ortbRequest.imp[1].bidfloor).to.equal('0.000001'); - }); - - it('Verify parse response', function () { - const request = spec.buildRequests(slotConfigs); - const ortbRequest = JSON.parse(request.data); - const ortbResponse = { - seatbid: [{ - bid: [{ - impid: ortbRequest.imp[0].id, - price: 1.25, - adm: 'This is an Ad', - w: 300, - h: 250 - }] - }], - cur: 'USD' - }; - const bids = spec.interpretResponse({ body: ortbResponse }, request); - expect(bids).to.have.lengthOf(1); - // verify first bid - const bid = bids[0]; - expect(bid.cpm).to.equal(1.25); - expect(bid.ad).to.equal('This is an Ad'); - expect(bid.width).to.equal(300); - expect(bid.height).to.equal(250); - expect(bid.adId).to.equal('bid12345'); - expect(bid.creativeId).to.equal('bid12345'); - expect(bid.netRevenue).to.equal(true); - expect(bid.currency).to.equal('USD'); - expect(bid.ttl).to.equal(360); - }); - - it('Verify full passback', function () { - const request = spec.buildRequests(slotConfigs); - const bids = spec.interpretResponse({ body: null }, request) - expect(bids).to.have.lengthOf(0); - }); - - it('Verify Native request', function () { - const request = spec.buildRequests(nativeSlotConfig); - expect(request.url).to.equal('https://windtalkerdisplay.hb.adp3.net/'); - expect(request.method).to.equal('POST'); - const ortbRequest = JSON.parse(request.data); - // native impression - expect(ortbRequest.imp[0].tagid).to.equal('123'); - const nativePart = ortbRequest.imp[0]['native']; - expect(nativePart).to.not.equal(null); - expect(nativePart.ver).to.equal('1.1'); - expect(nativePart.request).to.not.equal(null); - // native request assets - const nativeRequest = JSON.parse(ortbRequest.imp[0]['native'].request); - expect(nativeRequest).to.not.equal(null); - expect(nativeRequest.assets).to.have.lengthOf(5); - expect(nativeRequest.assets[0].id).to.equal(1); - expect(nativeRequest.assets[1].id).to.equal(2); - expect(nativeRequest.assets[2].id).to.equal(3); - expect(nativeRequest.assets[3].id).to.equal(4); - expect(nativeRequest.assets[4].id).to.equal(5); - expect(nativeRequest.assets[0].required).to.equal(1); - expect(nativeRequest.assets[0].title).to.not.equal(null); - expect(nativeRequest.assets[0].title.len).to.equal(200); - expect(nativeRequest.assets[1].title).to.be.undefined; - expect(nativeRequest.assets[1].data).to.not.equal(null); - expect(nativeRequest.assets[1].data.type).to.equal(2); - expect(nativeRequest.assets[1].data.len).to.equal(200); - expect(nativeRequest.assets[2].required).to.equal(0); - expect(nativeRequest.assets[3].img).to.not.equal(null); - expect(nativeRequest.assets[3].img.wmin).to.equal(50); - expect(nativeRequest.assets[3].img.hmin).to.equal(50); - expect(nativeRequest.assets[3].img.type).to.equal(1); - expect(nativeRequest.assets[4].img).to.not.equal(null); - expect(nativeRequest.assets[4].img.wmin).to.equal(100); - expect(nativeRequest.assets[4].img.hmin).to.equal(150); - expect(nativeRequest.assets[4].img.type).to.equal(3); - }); - - it('Verify Native response', function () { - const request = spec.buildRequests(nativeSlotConfig); - expect(request.url).to.equal('https://windtalkerdisplay.hb.adp3.net/'); - expect(request.method).to.equal('POST'); - const ortbRequest = JSON.parse(request.data); - const nativeResponse = { - 'native': { - assets: [ - { id: 1, title: { text: 'Ad Title' } }, - { id: 2, data: { value: 'Test description' } }, - { id: 3, data: { value: 'Brand' } }, - { id: 4, img: { url: 'https://adx1public.s3.amazonaws.com/creatives_icon.png', w: 100, h: 100 } }, - { id: 5, img: { url: 'https://adx1public.s3.amazonaws.com/creatives_image.png', w: 300, h: 300 } } - ], - link: { url: 'https://brand.com/' } - } - }; - const ortbResponse = { - seatbid: [{ - bid: [{ - impid: ortbRequest.imp[0].id, - price: 1.25, - nurl: 'https://rtb.adx1.com/log', - adm: JSON.stringify(nativeResponse) - }] - }], - cur: 'USD', - }; - const bids = spec.interpretResponse({ body: ortbResponse }, request); - // verify bid - const bid = bids[0]; - expect(bid.cpm).to.equal(1.25); - expect(bid.adId).to.equal('bid12345'); - expect(bid.ad).to.be.undefined; - expect(bid.mediaType).to.equal('native'); - const nativeBid = bid['native']; - expect(nativeBid).to.not.equal(null); - expect(nativeBid.title).to.equal('Ad Title'); - expect(nativeBid.sponsoredBy).to.equal('Brand'); - expect(nativeBid.icon.url).to.equal('https://adx1public.s3.amazonaws.com/creatives_icon.png'); - expect(nativeBid.image.url).to.equal('https://adx1public.s3.amazonaws.com/creatives_image.png'); - expect(nativeBid.image.width).to.equal(300); - expect(nativeBid.image.height).to.equal(300); - expect(nativeBid.icon.width).to.equal(100); - expect(nativeBid.icon.height).to.equal(100); - expect(nativeBid.clickUrl).to.equal(encodeURIComponent('https://brand.com/')); - expect(nativeBid.impressionTrackers).to.have.lengthOf(1); - expect(nativeBid.impressionTrackers[0]).to.equal('https://rtb.adx1.com/log'); - }); - - it('Verify Video request', function () { - const request = spec.buildRequests(videoSlotConfig); - expect(request.url).to.equal('https://windtalkerdisplay.hb.adp3.net/'); - expect(request.method).to.equal('POST'); - const videoRequest = JSON.parse(request.data); - // site object - expect(videoRequest.site).to.not.equal(null); - expect(videoRequest.site.publisher.id).to.equal('29521'); - expect(videoRequest.site.ref).to.equal(window.top.document.referrer); - expect(videoRequest.site.page).to.equal(window.location.href); - // device object - expect(videoRequest.device).to.not.equal(null); - expect(videoRequest.device.ua).to.equal(navigator.userAgent); - // slot 1 - expect(videoRequest.imp[0].tagid).to.equal('1234567'); - expect(videoRequest.imp[0].video).to.not.equal(null); - expect(videoRequest.imp[0].video.w).to.equal(640); - expect(videoRequest.imp[0].video.h).to.equal(480); - expect(videoRequest.imp[0].banner).to.equal(null); - expect(videoRequest.imp[0].native).to.equal(null); - }); - - it('Verify parse video response', function () { - const request = spec.buildRequests(videoSlotConfig); - const videoRequest = JSON.parse(request.data); - const videoResponse = { - seatbid: [{ - bid: [{ - impid: videoRequest.imp[0].id, - price: 1.90, - adm: 'https://vid.example.com/9876', - crid: '510511_754567308' - }] - }], - cur: 'USD' - }; - const bids = spec.interpretResponse({ body: videoResponse }, request); - expect(bids).to.have.lengthOf(1); - // verify first bid - const bid = bids[0]; - expect(bid.cpm).to.equal(1.90); - expect(bid.vastUrl).to.equal('https://vid.example.com/9876'); - expect(bid.crid).to.equal('510511_754567308'); - expect(bid.width).to.equal(640); - expect(bid.height).to.equal(480); - expect(bid.adId).to.equal('bid12345678'); - expect(bid.netRevenue).to.equal(true); - expect(bid.currency).to.equal('USD'); - expect(bid.ttl).to.equal(360); - }); - - it('Verifies bidder code', function () { - expect(spec.code).to.equal('windtalker'); - }); - - it('Verifies supported media types', function () { - expect(spec.supportedMediaTypes).to.have.lengthOf(3); - expect(spec.supportedMediaTypes[0]).to.equal('banner'); - expect(spec.supportedMediaTypes[1]).to.equal('native'); - expect(spec.supportedMediaTypes[2]).to.equal('video'); - }); - - it('Verifies if bid request valid', function () { - expect(spec.isBidRequestValid(slotConfigs[0])).to.equal(true); - expect(spec.isBidRequestValid(slotConfigs[1])).to.equal(true); - expect(spec.isBidRequestValid(nativeSlotConfig[0])).to.equal(true); - expect(spec.isBidRequestValid(videoSlotConfig[0])).to.equal(true); - }); - - it('Verify app requests', function () { - const request = spec.buildRequests(appSlotConfig); - const ortbRequest = JSON.parse(request.data); - expect(ortbRequest.site).to.equal(null); - expect(ortbRequest.app).to.not.be.null; - expect(ortbRequest.app.publisher).to.not.equal(null); - expect(ortbRequest.app.publisher.id).to.equal('29521'); - expect(ortbRequest.app.id).to.equal('1111'); - expect(ortbRequest.app.name).to.equal('app name'); - expect(ortbRequest.app.bundle).to.equal('io.windtalker.apps'); - expect(ortbRequest.app.storeurl).to.equal('https://windtalker.io/apps'); - expect(ortbRequest.app.domain).to.equal('windtalker.io'); - }); - - it('Verify GDPR', function () { - const bidderRequest = { - gdprConsent: { - gdprApplies: true, - consentString: 'serialized_gpdr_data' - } - }; - const request = spec.buildRequests(slotConfigs, bidderRequest); - expect(request.url).to.equal('https://windtalkerdisplay.hb.adp3.net/'); - expect(request.method).to.equal('POST'); - const ortbRequest = JSON.parse(request.data); - expect(ortbRequest.user).to.not.equal(null); - expect(ortbRequest.user.ext).to.not.equal(null); - expect(ortbRequest.user.ext.consent).to.equal('serialized_gpdr_data'); - expect(ortbRequest.regs).to.not.equal(null); - expect(ortbRequest.regs.ext).to.not.equal(null); - expect(ortbRequest.regs.ext.gdpr).to.equal(1); - }); -}); diff --git a/test/spec/modules/wipesBidAdapter_spec.js b/test/spec/modules/wipesBidAdapter_spec.js deleted file mode 100644 index c453eca82c5..00000000000 --- a/test/spec/modules/wipesBidAdapter_spec.js +++ /dev/null @@ -1,150 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/wipesBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; - -const ENDPOINT_URL = 'https://adn-srv.reckoner-api.com/v1/prebid'; - -describe('wipesBidAdapter', function () { - const adapter = newBidder(spec); - - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'wipes', - 'params': { - asid: 'dWyPondh2EGB_bNlrVjzIXRZO9F0k1dpo0I8ZvQ' - }, - 'adUnitCode': 'adunit-code', - 'bidId': '51ef8751f9aead', - 'bidderRequestId': '15246a574e859f', - 'auctionId': 'b06c5141-fe8f-4cdf-9d7d-54415490a917', - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when asid not passed correctly', function () { - bid.params.asid = ''; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when require params are not passed', function () { - let bid = Object.assign({}, bid); - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [ - { - 'bidder': 'wipes', - 'params': { - asid: 'dWyPondh2EGB_bNlrVjzIXRZO9F0k1dpo0I8ZvQ' - }, - 'adUnitCode': 'adunit-code', - 'bidId': '51ef8751f9aead', - 'bidderRequestId': '15246a574e859f', - 'auctionId': 'b06c5141-fe8f-4cdf-9d7d-54415490a917', - }, - { - 'bidder': 'wipes', - 'params': { - asid: 'dWyPondh2EGB_bNlrVjzIXRZO9F0k1dpo0I8ZvQ' - }, - 'adUnitCode': 'adunit-code2', - 'bidId': '51ef8751f9aead', - 'bidderRequestId': '15246a574e859f', - 'auctionId': 'b06c5141-fe8f-4cdf-9d7d-54415490a917', - } - ]; - - let bidderRequest = { - refererInfo: { - numIframes: 0, - reachedTop: true, - referer: 'http://example.com', - stack: ['http://example.com'] - } - }; - - const request = spec.buildRequests(bidRequests, bidderRequest); - - it('sends bid request to our endpoint via GET', function () { - expect(request[0].method).to.equal('GET'); - expect(request[1].method).to.equal('GET'); - }); - - it('attaches source and version to endpoint URL as query params', function () { - expect(request[0].url).to.equal(ENDPOINT_URL); - expect(request[1].url).to.equal(ENDPOINT_URL); - }); - - it('adUnitCode should be sent as uc parameters on any requests', function () { - expect(request[0].data.asid).to.equal('dWyPondh2EGB_bNlrVjzIXRZO9F0k1dpo0I8ZvQ'); - expect(request[1].data.asid).to.equal('dWyPondh2EGB_bNlrVjzIXRZO9F0k1dpo0I8ZvQ'); - }); - }); - - describe('interpretResponse', function () { - let bidRequestVideo = [ - { - 'method': 'GET', - 'url': ENDPOINT_URL, - 'data': { - 'asid': 'dWyPondh2EGB_bNlrVjzIXRZO9F0k1dpo0I8ZvQ', - 'bid_id': '23beaa6af6cdde', - } - } - ]; - - let serverResponseVideo = { - body: { - 'uuid': 'a42947f8-f8fd-4cf7-bb72-31a87ab1f6ff', - 'ad_tag': '', - 'height': 160, - 'width': 300, - 'cpm': 850, - 'status_message': '', - 'currency': 'JPY', - 'video_creative_id': 600004, - 'bid_id': '23beaa6af6cdde' - } - }; - - it('should get the correct bid response for video', function () { - let expectedResponse = [{ - 'requestId': '23beaa6af6cdde', - 'cpm': 850, - 'width': 300, - 'height': 160, - 'creativeId': '600004', - 'dealId': undefined, - 'currency': 'JPY', - 'netRevenue': true, - 'ttl': 3000, - 'referrer': '', - 'mediaType': 'banner', - 'ad': '' - }]; - let result = spec.interpretResponse(serverResponseVideo, bidRequestVideo[0]); - expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); - expect(result[0].mediaType).to.equal(expectedResponse[0].mediaType); - }); - - it('handles empty bid response', function () { - let response = { - body: { - 'uid': 'a42947f8-f8fd-4cf7-bb72-31a87ab1f6ff', - 'height': 0, - 'crid': '', - 'statusMessage': '', - 'width': 0, - 'cpm': 0 - } - }; - let result = spec.interpretResponse(response, bidRequestVideo[0]); - expect(result.length).to.equal(0); - }); - }); -}); diff --git a/test/spec/modules/xhbBidAdapter_spec.js b/test/spec/modules/xhbBidAdapter_spec.js deleted file mode 100644 index a12abc74c64..00000000000 --- a/test/spec/modules/xhbBidAdapter_spec.js +++ /dev/null @@ -1,495 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/xhbBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import { deepClone } from 'src/utils.js'; - -const ENDPOINT = 'https://ib.adnxs.com/ut/v3/prebid'; - -describe('xhbAdapter', 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 () { - let bid = { - 'bidder': 'xhb', - 'params': { - 'placementId': '10433394' - }, - '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(bid)).to.equal(true); - }); - - it('should return true when required params found', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'member': '1234', - 'invCode': 'ABCD' - }; - - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when required params are not passed', function () { - let bid = Object.assign({}, bid); - delete bid.params; - bid.params = { - 'placementId': 0 - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [ - { - 'bidder': 'xhb', - 'params': { - 'placementId': '10433394' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '30b31c1838de1e', - 'bidderRequestId': '22edbae2733bf6', - 'auctionId': '1d1a030790a475', - } - ]; - - it('should parse out private sizes', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - privateSizes: [300, 250] - } - } - ); - - const request = spec.buildRequests([bidRequest]); - 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}]); - }); - - it('should add source and verison to the tag', function () { - const request = spec.buildRequests(bidRequests); - const payload = JSON.parse(request.data); - expect(payload.sdk).to.exist; - expect(payload.sdk).to.deep.equal({ - source: 'pbjs', - version: '$prebid.version$' - }); - }); - - it('should populate the ad_types array on all requests', function () { - ['banner', 'video', 'native'].forEach(type => { - const bidRequest = Object.assign({}, bidRequests[0]); - bidRequest.mediaTypes = {}; - bidRequest.mediaTypes[type] = {}; - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].ad_types).to.deep.equal([type]); - }); - }); - - it('should populate the ad_types array on outstream requests', function () { - const bidRequest = Object.assign({}, bidRequests[0]); - bidRequest.mediaTypes = {}; - bidRequest.mediaTypes.video = {context: 'outstream'}; - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].ad_types).to.deep.equal(['video']); - }); - - it('sends bid request to ENDPOINT via POST', function () { - const request = spec.buildRequests(bidRequests); - expect(request.url).to.equal(ENDPOINT); - expect(request.method).to.equal('POST'); - }); - - it('should attach valid video params to the tag', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - video: { - id: 123, - minduration: 100, - foobar: 'invalid' - } - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - expect(payload.tags[0].video).to.deep.equal({ - id: 123, - minduration: 100 - }); - }); - - it('should attach valid user params to the tag', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - user: { - external_uid: '123', - foobar: 'invalid' - } - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.user).to.exist; - expect(payload.user).to.deep.equal({ - external_uid: '123', - }); - }); - - it('should attach native params to the request', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - mediaType: 'native', - nativeParams: { - title: {required: true}, - body: {required: true}, - image: {required: true, sizes: [{ width: 100, height: 100 }]}, - cta: {required: false}, - sponsoredBy: {required: true} - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].native.layouts[0]).to.deep.equal({ - title: {required: true}, - description: {required: true}, - main_image: {required: true, sizes: [{ width: 100, height: 100 }]}, - ctatext: {required: false}, - sponsored_by: {required: true} - }); - }); - - it('sets minimum native asset params when not provided on adunit', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - mediaType: 'native', - nativeParams: { - image: {required: true}, - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].native.layouts[0]).to.deep.equal({ - main_image: {required: true, sizes: [{}]}, - }); - }); - - it('does not overwrite native ad unit params with mimimum params', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - mediaType: 'native', - nativeParams: { - image: { - aspect_ratios: [{ - min_width: 100, - ratio_width: 2, - ratio_height: 3, - }] - } - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].native.layouts[0]).to.deep.equal({ - main_image: { - required: true, - aspect_ratios: [{ - min_width: 100, - ratio_width: 2, - ratio_height: 3, - }] - }, - }); - }); - - it('should convert keyword params to proper form and attaches to request', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - keywords: { - single: 'val', - singleArr: ['val'], - singleArrNum: [5], - multiValMixed: ['value1', 2, 'value3'], - singleValNum: 123, - badValue: {'foo': 'bar'} // should be dropped - } - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].keywords).to.deep.equal([{ - 'key': 'single', - 'value': ['val'] - }, { - 'key': 'singleArr', - 'value': ['val'] - }, { - 'key': 'singleArrNum', - 'value': ['5'] - }, { - 'key': 'multiValMixed', - 'value': ['value1', '2', 'value3'] - }, { - 'key': 'singleValNum', - 'value': ['123'] - }]); - }); - - it('should add payment rules to the request', function () { - let bidRequest = Object.assign({}, - bidRequests[0], - { - params: { - placementId: '10433394', - usePaymentRule: true - } - } - ); - - const request = spec.buildRequests([bidRequest]); - const payload = JSON.parse(request.data); - - expect(payload.tags[0].use_pmt_rule).to.equal(true); - }); - - it('should add gdpr consent information to the request', function () { - let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - let bidderRequest = { - 'bidderCode': 'xhb', - 'auctionId': '1d1a030790a475', - 'bidderRequestId': '22edbae2733bf6', - 'timeout': 3000, - 'gdprConsent': { - consentString: consentString, - gdprApplies: true - } - }; - bidderRequest.bids = bidRequests; - - const request = spec.buildRequests(bidRequests, bidderRequest); - const payload = JSON.parse(request.data); - - expect(payload.gdpr_consent).to.exist; - expect(payload.gdpr_consent.consent_string).to.exist.and.to.equal(consentString); - expect(payload.gdpr_consent.consent_required).to.exist.and.to.be.true; - }); - }); - - describe('interpretResponse', function () { - let response = { - 'version': '3.0.0', - 'tags': [ - { - 'uuid': '3db3773286ee59', - 'tag_id': 10433394, - 'auction_id': '4534722592064951574', - 'nobid': false, - 'no_ad_url': 'https://lax1-ib.adnxs.com/no-ad', - 'timeout_ms': 10000, - 'ad_profile_id': 27079, - 'ads': [ - { - 'content_source': 'rtb', - 'ad_type': 'banner', - 'buyer_member_id': 958, - 'creative_id': 29681110, - 'media_type_id': 1, - 'media_subtype_id': 1, - 'cpm': 0.5, - 'cpm_publisher_currency': 0.5, - 'publisher_currency_code': '$', - 'client_initiated_ad_counting': true, - 'rtb': { - 'banner': { - 'content': '', - 'width': 300, - 'height': 250 - }, - 'trackers': [ - { - 'impression_urls': [ - 'https://lax1-ib.adnxs.com/impression' - ], - 'video_events': {} - } - ] - } - } - ] - } - ] - }; - - it('should get correct bid response', function () { - let expectedResponse = [ - { - 'requestId': '3db3773286ee59', - 'cpm': 0.5, - 'creativeId': 29681110, - 'dealId': undefined, - 'width': 300, - 'height': 250, - 'ad': '', - 'mediaType': 'banner', - 'currency': 'USD', - 'ttl': 300, - 'netRevenue': true, - 'appnexus': { - 'buyerMemberId': 958 - } - } - ]; - let bidderRequest; - let result = spec.interpretResponse({ body: response }, {bidderRequest}); - expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); - }); - - it('handles nobid responses', function () { - let response = { - 'version': '0.0.1', - 'tags': [{ - 'uuid': '84ab500420319d', - 'tag_id': 5976557, - 'auction_id': '297492697822162468', - 'nobid': true - }] - }; - let bidderRequest; - - let result = spec.interpretResponse({ body: response }, {bidderRequest}); - expect(result.length).to.equal(0); - }); - - it('handles non-banner media responses', function () { - let response = { - 'tags': [{ - 'uuid': '84ab500420319d', - 'ads': [{ - 'ad_type': 'video', - 'cpm': 0.500000, - 'notify_url': 'imptracker.com', - 'rtb': { - 'video': { - 'content': '' - } - } - }] - }] - }; - let bidderRequest; - - let 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'); - }); - - it('handles native responses', function () { - let response1 = deepClone(response); - response1.tags[0].ads[0].ad_type = 'native'; - response1.tags[0].ads[0].rtb.native = { - 'title': 'Native Creative', - 'desc': 'Cool description great stuff', - 'ctatext': 'Do it', - 'sponsored': 'AppNexus', - 'icon': { - 'width': 0, - 'height': 0, - 'url': 'https://cdn.adnxs.com/icon.png' - }, - 'main_img': { - 'width': 2352, - 'height': 1516, - 'url': 'https://cdn.adnxs.com/img.png' - }, - 'link': { - 'url': 'https://www.appnexus.com', - 'fallback_url': '', - 'click_trackers': ['https://nym1-ib.adnxs.com/click'] - }, - 'impression_trackers': ['https://example.com'], - }; - let bidderRequest; - - let 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'); - expect(result[0].native.image.url).to.equal('https://cdn.adnxs.com/img.png'); - }); - - it('supports configuring outstream renderers', function () { - const outstreamResponse = deepClone(response); - outstreamResponse.tags[0].ads[0].rtb.video = {}; - outstreamResponse.tags[0].ads[0].renderer_url = 'renderer.js'; - - const bidderRequest = { - bids: [{ - renderer: { - options: { - adText: 'configured' - } - } - }] - }; - - const result = spec.interpretResponse({ body: outstreamResponse }, {bidderRequest}); - expect(result[0].renderer.config).to.deep.equal( - bidderRequest.bids[0].renderer.options - ); - }); - }); -}); diff --git a/test/spec/modules/yieldlabBidAdapter_spec.js b/test/spec/modules/yieldlabBidAdapter_spec.js deleted file mode 100644 index 6dde671578c..00000000000 --- a/test/spec/modules/yieldlabBidAdapter_spec.js +++ /dev/null @@ -1,265 +0,0 @@ -import { expect } from 'chai' -import { spec } from 'modules/yieldlabBidAdapter.js' -import { newBidder } from 'src/adapters/bidderFactory.js' - -const REQUEST = { - 'bidder': 'yieldlab', - 'params': { - 'adslotId': '1111', - 'supplyId': '2222', - 'targeting': { - 'key1': 'value1', - 'key2': 'value2', - 'notDoubleEncoded': 'value3,value4' - }, - 'customParams': { - 'extraParam': true, - 'foo': 'bar' - }, - 'extId': 'abc' - }, - 'bidderRequestId': '143346cf0f1731', - 'auctionId': '2e41f65424c87c', - 'adUnitCode': 'adunit-code', - 'bidId': '2d925f27f5079f', - 'sizes': [728, 90], - 'userIdAsEids': [{ - 'source': 'netid.de', - 'uids': [{ - 'id': 'fH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg', - 'atype': 1 - }] - }], - 'schain': { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'indirectseller.com', - 'sid': '1', - 'hp': 1 - }, - { - 'asi': 'indirectseller2.com', - 'name': 'indirectseller2 name with comma , and bang !', - 'sid': '2', - 'hp': 1 - } - ] - } -} - -const RESPONSE = { - advertiser: 'yieldlab', - curl: 'https://www.yieldlab.de', - format: 0, - id: 1111, - price: 1, - pid: 2222, - adsize: '728x90', - adtype: 'BANNER' -} - -const VIDEO_RESPONSE = Object.assign({}, RESPONSE, { - 'adtype': 'VIDEO' -}) - -const REQPARAMS = { - json: true, - ts: 1234567890 -} - -const REQPARAMS_GDPR = Object.assign({}, REQPARAMS, { - gdpr: true, - consent: 'BN5lERiOMYEdiAKAWXEND1AAAAE6DABACMA' -}) - -describe('yieldlabBidAdapter', 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 () { - it('should return true when required params found', function () { - const request = { - 'params': { - 'adslotId': '1111', - 'supplyId': '2222' - } - } - expect(spec.isBidRequestValid(request)).to.equal(true) - }) - - it('should return false when required params are not passed', function () { - expect(spec.isBidRequestValid({})).to.equal(false) - }) - }) - - describe('buildRequests', function () { - const bidRequests = [REQUEST] - const request = spec.buildRequests(bidRequests) - - it('sends bid request to ENDPOINT via GET', function () { - expect(request.method).to.equal('GET') - }) - - it('returns a list of valid requests', function () { - expect(request.validBidRequests).to.eql([REQUEST]) - }) - - it('passes single-encoded targeting to bid request', function () { - expect(request.url).to.include('t=key1%3Dvalue1%26key2%3Dvalue2%26notDoubleEncoded%3Dvalue3%2Cvalue4') - }) - - it('passes userids to bid request', function () { - expect(request.url).to.include('ids=netid.de%3AfH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg') - }) - - it('passes extra params to bid request', function () { - expect(request.url).to.include('extraParam=true&foo=bar') - }) - - it('passes unencoded schain string to bid request', function () { - expect(request.url).to.include('schain=1.0,1!indirectseller.com,1,1,,,,!indirectseller2.com,2,1,,indirectseller2%20name%20with%20comma%20%2C%20and%20bang%20%21,,') - }) - - const refererRequest = spec.buildRequests(bidRequests, { - refererInfo: { - canonicalUrl: undefined, - numIframes: 0, - reachedTop: true, - referer: 'https://www.yieldlab.de/test?with=querystring', - stack: ['https://www.yieldlab.de/test?with=querystring'] - } - }) - - it('passes unencoded schain string to bid request when complete == 0', function () { - REQUEST.schain.complete = 0; - const request = spec.buildRequests([REQUEST]) - expect(request.url).to.include('schain=1.0,0!indirectseller.com,1,1,,,,!indirectseller2.com,2,1,,indirectseller2%20name%20with%20comma%20%2C%20and%20bang%20%21,,') - }) - - it('passes encoded referer to bid request', function () { - expect(refererRequest.url).to.include('pubref=https%3A%2F%2Fwww.yieldlab.de%2Ftest%3Fwith%3Dquerystring') - }) - - const gdprRequest = spec.buildRequests(bidRequests, { - gdprConsent: { - consentString: 'BN5lERiOMYEdiAKAWXEND1AAAAE6DABACMA', - gdprApplies: true - } - }) - - it('passes gdpr flag and consent if present', function () { - expect(gdprRequest.url).to.include('consent=BN5lERiOMYEdiAKAWXEND1AAAAE6DABACMA') - expect(gdprRequest.url).to.include('gdpr=true') - }) - }) - - 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) - }) - - it('should get correct bid response', function () { - const result = spec.interpretResponse({body: [RESPONSE]}, {validBidRequests: [REQUEST], queryParams: REQPARAMS}) - - expect(result[0].requestId).to.equal('2d925f27f5079f') - expect(result[0].cpm).to.equal(0.01) - expect(result[0].width).to.equal(728) - expect(result[0].height).to.equal(90) - expect(result[0].creativeId).to.equal('1111') - expect(result[0].dealId).to.equal(2222) - expect(result[0].currency).to.equal('EUR') - expect(result[0].netRevenue).to.equal(false) - expect(result[0].ttl).to.equal(300) - expect(result[0].referrer).to.equal('') - expect(result[0].ad).to.include('', - 'adid': '144762342', - 'adomain': [ - 'https://dummydomain.com' - ], - 'iurl': 'iurl', - 'cid': '109', - 'crid': 'creativeId', - 'cat': [], - 'w': 300, - 'h': 250, - 'ext': { - 'prebid': { - 'type': 'banner' - }, - 'bidder': { - 'appnexus': { - 'brand_id': 334553, - 'auction_id': 514667951122925701, - 'bidder_id': 2, - 'bid_ad_type': 0 - } - } - } - }, - { - 'id': 'bidId2', - 'impid': 'bidId2', - 'price': 0.1, - 'adm': '', - 'adid': '144762342', - 'adomain': [ - 'https://dummydomain.com' - ], - 'iurl': 'iurl', - 'cid': '109', - 'crid': 'creativeId', - 'cat': [], - 'w': 300, - 'h': 250, - 'ext': { - 'prebid': { - 'type': 'banner' - }, - 'bidder': { - 'appnexus': { - 'brand_id': 386046, - 'auction_id': 517067951122925501, - 'bidder_id': 2, - 'bid_ad_type': 0 - } - } - } - } - ], - 'seat': 'yieldlift' - } - ], - 'ext': { - 'usersync': { - 'sovrn': { - 'status': 'none', - 'syncs': [ - { - 'url': 'urlsovrn', - 'type': 'iframe' - } - ] - }, - 'appnexus': { - 'status': 'none', - 'syncs': [ - { - 'url': 'urlappnexus', - 'type': 'pixel' - } - ] - } - }, - 'responsetimemillis': { - 'appnexus': 127 - } - } - } -}; - -describe('YieldLift', function () { - describe('isBidRequestValid', function () { - it('should accept request if only unitId is passed', function () { - let bid = { - bidder: 'yieldlift', - params: { - unitId: 'unitId', - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - it('should accept request if only networkId is passed', function () { - let bid = { - bidder: 'yieldlift', - params: { - networkId: 'networkId', - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - it('should accept request if only publisherId is passed', function () { - let bid = { - bidder: 'yieldlift', - params: { - publisherId: 'publisherId', - } - }; - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('reject requests without params', function () { - let bid = { - bidder: 'yieldlift', - params: {} - }; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - it('creates request data', function () { - let request = spec.buildRequests(REQUEST.bidRequest, REQUEST); - - expect(request).to.exist.and.to.be.a('object'); - const payload = JSON.parse(request.data); - expect(payload.imp[0]).to.have.property('id', REQUEST.bidRequest[0].bidId); - expect(payload.imp[1]).to.have.property('id', REQUEST.bidRequest[1].bidId); - }); - - it('has gdpr data if applicable', function () { - const req = Object.assign({}, REQUEST, { - gdprConsent: { - consentString: 'consentString', - gdprApplies: true, - } - }); - let request = spec.buildRequests(REQUEST.bidRequest, req); - - const payload = JSON.parse(request.data); - expect(payload.user.ext).to.have.property('consent', req.gdprConsent.consentString); - expect(payload.regs.ext).to.have.property('gdpr', 1); - }); - }); - - describe('interpretResponse', function () { - it('have bids', function () { - let bids = spec.interpretResponse(RESPONSE, REQUEST); - expect(bids).to.be.an('array').that.is.not.empty; - validateBidOnIndex(0); - validateBidOnIndex(1); - - function validateBidOnIndex(index) { - expect(bids[index]).to.have.property('currency', 'USD'); - expect(bids[index]).to.have.property('requestId', RESPONSE.body.seatbid[0].bid[index].impid); - expect(bids[index]).to.have.property('cpm', RESPONSE.body.seatbid[0].bid[index].price); - expect(bids[index]).to.have.property('width', RESPONSE.body.seatbid[0].bid[index].w); - expect(bids[index]).to.have.property('height', RESPONSE.body.seatbid[0].bid[index].h); - expect(bids[index]).to.have.property('ad', RESPONSE.body.seatbid[0].bid[index].adm); - expect(bids[index]).to.have.property('creativeId', RESPONSE.body.seatbid[0].bid[index].crid); - expect(bids[index]).to.have.property('ttl', 30); - expect(bids[index]).to.have.property('netRevenue', true); - } - }); - - it('handles empty response', function () { - const EMPTY_RESP = Object.assign({}, RESPONSE, {'body': {}}); - const bids = spec.interpretResponse(EMPTY_RESP, REQUEST); - - expect(bids).to.be.empty; - }); - }); - - describe('getUserSyncs', function () { - it('handles no parameters', function () { - let opts = spec.getUserSyncs({}); - 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}); - - 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}, [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('pixel sync enabled should return results', function () { - let 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('all sync enabled should return all results', function () { - let opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [RESPONSE]); - - expect(opts.length).to.equal(2); - }); - }); -}); diff --git a/test/spec/modules/yieldmoBidAdapter_spec.js b/test/spec/modules/yieldmoBidAdapter_spec.js deleted file mode 100644 index 3b317f88dc6..00000000000 --- a/test/spec/modules/yieldmoBidAdapter_spec.js +++ /dev/null @@ -1,468 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/yieldmoBidAdapter.js'; -import * as utils from 'src/utils.js'; - -describe('YieldmoAdapter', function () { - const BANNER_ENDPOINT = 'https://ads.yieldmo.com/exchange/prebid'; - const VIDEO_ENDPOINT = 'https://ads.yieldmo.com/exchange/prebidvideo'; - - const mockBannerBid = (rootParams = {}, params = {}) => ({ - bidder: 'yieldmo', - params: { - bidFloor: 0.1, - ...params, - }, - adUnitCode: 'adunit-code', - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [300, 600], - ], - }, - }, - bidId: '30b31c1838de1e', - bidderRequestId: '22edbae2733bf6', - auctionId: '1d1a030790a475', - crumbs: { - pubcid: 'c604130c-0144-4b63-9bf2-c2bd8c8d86da', - }, - userId: { - tdid: '8d146286-91d4-4958-aff4-7e489dd1abd6' - }, - ...rootParams - }); - - const mockVideoBid = (rootParams = {}, params = {}, videoParams = {}) => ({ - bidder: 'yieldmo', - adUnitCode: 'adunit-code-video', - bidId: '321video123', - mediaTypes: { - video: { - playerSize: [640, 480], - context: 'instream', - mimes: ['video/mp4'] - }, - }, - params: { - placementId: '123', - ...params, - video: { - placement: 1, - maxduration: 30, - startdelay: 10, - protocols: [2, 3], - api: [2, 3], - skipppable: true, - playbackmethod: [1, 2], - ...videoParams - } - }, - ...rootParams - }); - - const mockBidderRequest = (params = {}, bids = [mockBannerBid()]) => ({ - bidderCode: 'yieldmo', - auctionId: 'e3a336ad-2761-4a1c-b421-ecc7c5294a34', - bidderRequestId: '14c4ede8c693f', - bids, - auctionStart: 1520001292880, - timeout: 3000, - start: 1520001292884, - doneCbCallCount: 0, - refererInfo: { - numIframes: 1, - reachedTop: true, - referer: 'yieldmo.com', - }, - ...params - }); - - const mockGetFloor = floor => ({getFloor: () => ({ currency: 'USD', floor })}); - - describe('isBidRequestValid', function () { - describe('Banner:', function () { - it('should return true when necessary information is found', function () { - expect(spec.isBidRequestValid(mockBannerBid())).to.be.true; - }); - - it('should return false when necessary information is not found', function () { - // empty bid - expect(spec.isBidRequestValid({})).to.be.false; - - // empty bidId - expect(spec.isBidRequestValid(mockBannerBid({bidId: ''}))).to.be.false; - - // empty adUnitCode - expect(spec.isBidRequestValid(mockBannerBid({adUnitCode: ''}))).to.be.false; - - let invalidBid = mockBannerBid(); - delete invalidBid.mediaTypes.banner; - expect(spec.isBidRequestValid(invalidBid)).to.be.false; - }); - }); - - describe('Instream video:', function () { - const getVideoBidWithoutParam = (key, paramToRemove) => { - let bid = mockVideoBid(); - delete utils.deepAccess(bid, key)[paramToRemove]; - return bid; - } - - it('should return true when necessary information is found', function () { - expect(spec.isBidRequestValid(mockVideoBid())).to.be.true; - }); - - it('should return false when necessary information is not found', function () { - // empty bidId - expect(spec.isBidRequestValid(mockVideoBid({bidId: ''}))).to.be.false; - - // empty adUnitCode - expect(spec.isBidRequestValid(mockVideoBid({adUnitCode: ''}))).to.be.false; - }); - - it('should return false when required mediaTypes.video.* param is not found', function () { - const getBidAndExclude = paramToRemove => getVideoBidWithoutParam('mediaTypes.video', paramToRemove); - - expect(spec.isBidRequestValid(getBidAndExclude('playerSize'))).to.be.false; - expect(spec.isBidRequestValid(getBidAndExclude('mimes'))).to.be.false; - }); - - it('should return false when required bid.params.* is not found', function () { - const getBidAndExclude = paramToRemove => getVideoBidWithoutParam('params', paramToRemove); - - expect(spec.isBidRequestValid(getBidAndExclude('placementId'))).to.be.false; - expect(spec.isBidRequestValid(getBidAndExclude('video'))).to.be.false; - }); - - it('should return false when required bid.params.video.* is not found', function () { - const getBidAndExclude = paramToRemove => getVideoBidWithoutParam('params.video', paramToRemove); - - expect(spec.isBidRequestValid(getBidAndExclude('placement'))).to.be.false; - expect(spec.isBidRequestValid(getBidAndExclude('maxduration'))).to.be.false; - expect(spec.isBidRequestValid(getBidAndExclude('startdelay'))).to.be.false; - expect(spec.isBidRequestValid(getBidAndExclude('protocols'))).to.be.false; - expect(spec.isBidRequestValid(getBidAndExclude('api'))).to.be.false; - }); - }); - }); - - describe('buildRequests', function () { - const build = (bidRequests, bidderReq = mockBidderRequest()) => spec.buildRequests(bidRequests, bidderReq); - const buildAndGetPlacementInfo = (bidRequests, index = 0, bidderReq = mockBidderRequest()) => - utils.deepAccess(build(bidRequests, bidderReq), `${index}.data.p`); - const buildAndGetData = (bidRequests, index = 0, bidderReq = mockBidderRequest()) => - utils.deepAccess(build(bidRequests, bidderReq), `${index}.data`) || {}; - - describe('Banner:', function () { - it('should attempt to send banner bid requests to the endpoint via GET', function () { - const requests = build([mockBannerBid()]); - expect(requests.length).to.equal(1); - expect(requests[0].method).to.equal('GET'); - expect(requests[0].url).to.be.equal(BANNER_ENDPOINT); - }); - - it('should not blow up if crumbs is undefined', function () { - expect(function () { - build([mockBannerBid({crumbs: undefined})]); - }).not.to.throw(); - }); - - it('should place bid information into the p parameter of data', function () { - let bidArray = [mockBannerBid()]; - expect(buildAndGetPlacementInfo(bidArray)).to.equal( - '[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1}]' - ); - - // multiple placements - bidArray.push(mockBannerBid( - {adUnitCode: 'adunit-2', bidId: '123a', bidderRequestId: '321', auctionId: '222'}, {bidFloor: 0.2})); - expect(buildAndGetPlacementInfo(bidArray)).to.equal( - '[{"placement_id":"adunit-code","callback_id":"30b31c1838de1e","sizes":[[300,250],[300,600]],"bidFloor":0.1},' + - '{"placement_id":"adunit-2","callback_id":"123a","sizes":[[300,250],[300,600]],"bidFloor":0.2}]' - ); - }); - - it('should add placement id if given', function () { - let bidArray = [mockBannerBid({}, {placementId: 'ym_1293871298'})]; - let placementInfo = buildAndGetPlacementInfo(bidArray); - expect(placementInfo).to.include('"ym_placement_id":"ym_1293871298"'); - expect(placementInfo).not.to.include('"ym_placement_id":"ym_0987654321"'); - - bidArray.push(mockBannerBid({}, {placementId: 'ym_0987654321'})); - placementInfo = buildAndGetPlacementInfo(bidArray); - expect(placementInfo).to.include('"ym_placement_id":"ym_1293871298"'); - expect(placementInfo).to.include('"ym_placement_id":"ym_0987654321"'); - }); - - it('should add additional information to data parameter of request', function () { - const data = buildAndGetData([mockBannerBid()]); - expect(data.hasOwnProperty('page_url')).to.be.true; - expect(data.hasOwnProperty('bust')).to.be.true; - expect(data.hasOwnProperty('pr')).to.be.true; - expect(data.hasOwnProperty('scrd')).to.be.true; - expect(data.dnt).to.be.false; - expect(data.hasOwnProperty('description')).to.be.true; - expect(data.hasOwnProperty('title')).to.be.true; - expect(data.hasOwnProperty('h')).to.be.true; - expect(data.hasOwnProperty('w')).to.be.true; - expect(data.hasOwnProperty('pubcid')).to.be.true; - expect(data.userConsent).to.equal('{"gdprApplies":"","cmp":""}'); - expect(data.us_privacy).to.equal(''); - }); - - it('should add pubcid as parameter of request', function () { - const pubcid = 'c604130c-0144-4b63-9bf2-c2bd8c8d86da2'; - const pubcidBid = mockBannerBid({crumbs: undefined, userId: {pubcid}}); - expect(buildAndGetData([pubcidBid]).pubcid).to.deep.equal(pubcid); - }); - - it('should add unified id as parameter of request', function () { - const unifiedIdBid = mockBannerBid({crumbs: undefined}); - expect(buildAndGetData([unifiedIdBid]).tdid).to.deep.equal(mockBannerBid().userId.tdid); - }); - - it('should add CRITEO RTUS id as parameter of request', function () { - const criteoId = 'aff4'; - const criteoIdBid = mockBannerBid({crumbs: undefined, userId: { criteoId }}); - expect(buildAndGetData([criteoIdBid]).cri_prebid).to.deep.equal(criteoId); - }); - - it('should add gdpr information to request if available', () => { - const gdprConsent = { - consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', - vendorData: {blerp: 1}, - gdprApplies: true, - }; - const data = buildAndGetData([mockBannerBid()], 0, mockBidderRequest({gdprConsent})); - expect(data.userConsent).equal( - JSON.stringify({ - gdprApplies: true, - cmp: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', - }) - ); - }); - - it('should add ccpa information to request if available', () => { - const uspConsent = '1YNY'; - const data = buildAndGetData([mockBannerBid()], 0, mockBidderRequest({uspConsent})); - expect(data.us_privacy).equal(uspConsent); - }); - - it('should add schain if it is in the bidRequest', () => { - const schain = { - ver: '1.0', - complete: 1, - nodes: [{asi: 'indirectseller.com', sid: '00001', hp: 1}], - }; - const data = buildAndGetData([mockBannerBid({schain})]); - expect(data.schain).equal(JSON.stringify(schain)); - }); - - it('should process floors module if available', function () { - const placementsData = JSON.parse(buildAndGetPlacementInfo([ - mockBannerBid({...mockGetFloor(3.99)}), - mockBannerBid({...mockGetFloor(1.23)}, { bidFloor: 1.1 }), - ])); - expect(placementsData[0].bidFloor).to.equal(3.99); - expect(placementsData[1].bidFloor).to.equal(1.23); - }); - - it('should use bidFloor if no floors module is available', function() { - const placementsData = JSON.parse(buildAndGetPlacementInfo([ - mockBannerBid({}, { bidFloor: 1.2 }), - mockBannerBid({}, { bidFloor: 0.7 }), - ])); - expect(placementsData[0].bidFloor).to.equal(1.2); - expect(placementsData[1].bidFloor).to.equal(0.7); - }); - - it('should not write 0 bidfloor value by default', function() { - const placementsData = JSON.parse(buildAndGetPlacementInfo([mockBannerBid()])); - expect(placementsData[0].bidfloor).to.undefined; - }); - - it('should not exceed max url length', () => { - const longString = new Array(8000).join('a'); - const localWindow = utils.getWindowTop(); - - const originalTitle = localWindow.document.title; - localWindow.document.title = longString; - - const request = spec.buildRequests( - [mockBannerBid()], - mockBidderRequest({ - refererInfo: { - numIframes: 1, - reachedTop: true, - referer: longString, - }, - }) - )[0]; - const url = `${request.url}?${utils.parseQueryStringParameters(request.data)}`; - - expect(url.length).equal(8000); - - localWindow.document.title = originalTitle; - }); - - it('should only shortcut properties rather then completely remove it', () => { - const longString = new Array(7516).join('a'); - const localWindow = utils.getWindowTop(); - - const originalTitle = localWindow.document.title; - localWindow.document.title = `testtitle${longString}`; - - const request = spec.buildRequests( - [mockBannerBid()], - mockBidderRequest({ - refererInfo: { - numIframes: 1, - reachedTop: true, - referer: longString, - }, - }) - )[0]; - - expect(request.data.title.length).greaterThan(0); - - localWindow.document.title = originalTitle; - }); - }); - - describe('Instream video:', function () { - it('should attempt to send video bid requests to the endpoint via POST', function () { - const requests = build([mockVideoBid()]); - expect(requests.length).to.equal(1); - expect(requests[0].method).to.equal('POST'); - expect(requests[0].url).to.be.equal(VIDEO_ENDPOINT); - }); - - it('should process floors module if available', function () { - const requests = build([ - mockVideoBid({...mockGetFloor(3.99)}), - mockVideoBid({...mockGetFloor(1.23)}, { bidfloor: 1.1 }), - ]); - const imps = requests[0].data.imp; - expect(imps[0].bidfloor).to.equal(3.99); - expect(imps[1].bidfloor).to.equal(1.23); - }); - - it('should use bidfloor if no floors module is available', function() { - const requests = build([ - mockVideoBid({}, { bidfloor: 1.2 }), - mockVideoBid({}, { bidfloor: 0.7 }), - ]); - const imps = requests[0].data.imp; - expect(imps[0].bidfloor).to.equal(1.2); - expect(imps[1].bidfloor).to.equal(0.7); - }); - - it('should have 0 bidfloor value by default', function() { - const requests = build([mockVideoBid()]); - expect(requests[0].data.imp[0].bidfloor).to.equal(0); - }); - }); - }); - - describe('interpretResponse', function () { - const mockServerResponse = () => ({ - body: [{ - callback_id: '21989fdbef550a', - cpm: 3.45455, - width: 300, - height: 250, - ad: '' + - '
', - creative_id: '9874652394875', - adomain: ['www.example.com'], - }], - header: 'header?', - }); - - it('should correctly reorder the server response', function () { - const newResponse = spec.interpretResponse(mockServerResponse()); - expect(newResponse.length).to.be.equal(1); - expect(newResponse[0]).to.deep.equal({ - requestId: '21989fdbef550a', - cpm: 3.45455, - width: 300, - height: 250, - creativeId: '9874652394875', - currency: 'USD', - netRevenue: true, - ttl: 300, - ad: '' + - '
', - meta: { - advertiserDomains: ['www.example.com'], - mediaType: 'banner', - }, - }); - }); - - it('should correctly reorder video bids', function () { - const response = mockServerResponse(); - const seatbid = [ - { - bid: { - adm: '', - adomain: ['www.example.com'], - crid: 'dd65c0a7536aff', - impid: '91ea8bba1', - price: 1.5, - }, - }, - ]; - const bidRequest = { - data: { - imp: [ - { - id: '91ea8bba1', - video: { - h: 250, - w: 300, - }, - }, - ], - }, - }; - - response.body.seatbid = seatbid; - - const newResponse = spec.interpretResponse(response, bidRequest); - expect(newResponse.length).to.be.equal(2); - expect(newResponse[1]).to.deep.equal({ - cpm: 1.5, - creativeId: 'dd65c0a7536aff', - currency: 'USD', - height: 250, - mediaType: 'video', - meta: { - advertiserDomains: ['www.example.com'], - mediaType: 'video', - }, - netRevenue: true, - requestId: '91ea8bba1', - ttl: 300, - vastXml: '', - width: 300, - }); - }); - - it('should not add responses if the cpm is 0 or null', function () { - let response = mockServerResponse(); - response.body[0].cpm = 0; - expect(spec.interpretResponse(response)).to.deep.equal([]); - - response.body[0].cpm = null; - expect(spec.interpretResponse(response)).to.deep.equal([]); - }); - }); - - describe('getUserSync', function () { - it('should return a tracker with type and url as parameters', function () { - expect(spec.getUserSyncs()).to.deep.equal([]); - }); - }); -}); diff --git a/test/spec/modules/yieldoneAnalyticsAdapter_spec.js b/test/spec/modules/yieldoneAnalyticsAdapter_spec.js deleted file mode 100644 index 81a6365bba2..00000000000 --- a/test/spec/modules/yieldoneAnalyticsAdapter_spec.js +++ /dev/null @@ -1,280 +0,0 @@ -import yieldoneAnalytics from 'modules/yieldoneAnalyticsAdapter.js'; -import { targeting } from 'src/targeting.js'; -import { expect } from 'chai'; -let events = require('src/events'); -let adapterManager = require('src/adapterManager').default; -let constants = require('src/constants.json'); - -describe('Yieldone Prebid Analytic', function () { - let sendStatStub; - let getAllTargetingStub; - const fakeTargeting = { - '0000': {'someId': 'someValue'} - }; - - describe('enableAnalytics', function () { - beforeEach(function () { - sendStatStub = sinon.stub(yieldoneAnalytics, 'sendStat'); - getAllTargetingStub = sinon.stub(targeting, 'getAllTargeting').returns(fakeTargeting); - sinon.stub(events, 'getEvents').returns([]); - }); - - afterEach(function () { - sendStatStub.restore(); - getAllTargetingStub.restore(); - events.getEvents.restore(); - }); - - after(function () { - yieldoneAnalytics.disableAnalytics(); - }); - - it('should catch all events', function (done) { - adapterManager.registerAnalyticsAdapter({ - code: 'yieldone', - adapter: yieldoneAnalytics - }); - - const initOptions = { - pubId: '123456' - }; - - const auctionId = 'test-test-test'; - const testReferrer = 'http://test'; - - const request = [ - { - bidderCode: 'biddertest_1', - auctionId: auctionId, - refererInfo: {referer: testReferrer}, - bids: [ - { - adUnitCode: '0000', - auctionId: auctionId, - bidId: '1234', - bidder: 'biddertest_1', - mediaTypes: {banner: {sizes: [[300, 250], [336, 280]]}}, - params: {param1: '111', param2: '222'}, - sizes: [[300, 250], [336, 280]] - }, - { - adUnitCode: '0000', - auctionId: auctionId, - bidId: '5678', - bidder: 'biddertest_1', - mediaTypes: {banner: {sizes: [[300, 250], [336, 280]]}}, - params: {param1: '222', param2: '222'}, - sizes: [[300, 250], [336, 280]] - } - ] - }, - { - bidderCode: 'biddertest_2', - auctionId: auctionId, - refererInfo: {referer: testReferrer}, - bids: [ - { - adUnitCode: '0000', - auctionId: auctionId, - bidId: '91011', - bidder: 'biddertest_2', - mediaTypes: {banner: {sizes: [[300, 250], [336, 280]]}}, - params: {paramA: '111', paramB: '222'}, - sizes: [[300, 250], [336, 280]] - } - ] - }, - { - bidderCode: 'biddertest_3', - auctionId: auctionId, - refererInfo: {referer: testReferrer}, - bids: [ - { - adUnitCode: '0000', - auctionId: auctionId, - bidId: '12131', - bidder: 'biddertest_3', - mediaTypes: {banner: {sizes: [[300, 250], [336, 280]]}}, - params: {param_1: '111', param_2: '222'}, - sizes: [[300, 250], [336, 280]] - }, - { - adUnitCode: '0000', - auctionId: auctionId, - bidId: '14151', - bidder: 'biddertest_3', - mediaTypes: {banner: {sizes: [[300, 250], [336, 280]]}}, - params: {param_1: '333', param_2: '222'}, - sizes: [[300, 250], [336, 280]] - } - ] - } - ]; - - const responses = [ - { - ad: 'test ad content 1', - width: 300, - height: 250, - statusMessage: 'Bid available', - bidId: '1234', - auctionId: auctionId, - cpm: 0.1, - bidder: 'biddertest_1', - adUnitCode: '0000', - timeToRespond: 100 - }, - { - ad: 'test ad content 2', - width: 336, - height: 280, - statusMessage: 'Bid available', - bidId: '5678', - auctionId: auctionId, - cpm: 0.2, - bidder: 'biddertest_1', - adUnitCode: '0000', - timeToRespond: 100 - }, - { - ad: 'test ad content 3', - width: 300, - height: 250, - statusMessage: 'Bid available', - bidId: '91011', - auctionId: auctionId, - cpm: 0.3, - bidder: 'biddertest_2', - adUnitCode: '0000', - timeToRespond: 100 - }, - { - bidId: '12131', - auctionId: auctionId, - bidder: 'biddertest_3' - }, - { - bidId: '14151', - auctionId: auctionId, - bidder: 'biddertest_3' - } - ]; - - const winner = { - ad: 'test ad content 3', - width: 300, - height: 250, - statusMessage: 'Bid available', - bidId: '91011', - auctionId: auctionId, - cpm: 0.3, - bidder: 'biddertest_2', - adUnitCode: '0000', - timeToRespond: 100 - }; - - const auctionEnd = { - auctionId: auctionId, - bidsReceived: responses.slice(0, 3) - }; - - const preparedResponses = responses.map((resp) => { - const res = Object.assign({}, resp); - delete res.ad; - return res; - }); - - const expectedEvents = [ - { - eventType: constants.EVENTS.AUCTION_INIT, - params: { - config: initOptions, - auctionId: auctionId - } - }, - { - eventType: constants.EVENTS.BID_REQUESTED, - params: Object.assign(request[0]) - }, - { - eventType: constants.EVENTS.BID_REQUESTED, - params: Object.assign(request[1]) - }, - { - eventType: constants.EVENTS.BID_REQUESTED, - params: Object.assign(request[2]) - }, - { - eventType: constants.EVENTS.BID_RESPONSE, - params: Object.assign(preparedResponses[0]) - }, - { - eventType: constants.EVENTS.BID_RESPONSE, - params: Object.assign(preparedResponses[1]) - }, - { - eventType: constants.EVENTS.BID_RESPONSE, - params: Object.assign(preparedResponses[2]) - }, - { - eventType: constants.EVENTS.BID_TIMEOUT, - params: Object.assign(request[2]) - } - ]; - const expectedResult = { - pubId: initOptions.pubId, - page: {url: testReferrer}, - wrapper_version: '$prebid.version$', - events: expectedEvents - }; - - const preparedWinnerParams = Object.assign({adServerTargeting: fakeTargeting}, winner); - delete preparedWinnerParams.ad; - const wonExpectedEvents = [ - { - eventType: constants.EVENTS.BID_WON, - params: preparedWinnerParams - } - ]; - const wonExpectedResult = { - pubId: initOptions.pubId, - page: {url: testReferrer}, - wrapper_version: '$prebid.version$', - events: wonExpectedEvents - }; - - adapterManager.enableAnalytics({ - provider: 'yieldone', - options: initOptions - }); - - events.emit(constants.EVENTS.AUCTION_INIT, {config: initOptions, auctionId: auctionId}); - - events.emit(constants.EVENTS.BID_REQUESTED, request[0]); - events.emit(constants.EVENTS.BID_REQUESTED, request[1]); - events.emit(constants.EVENTS.BID_REQUESTED, request[2]); - - events.emit(constants.EVENTS.BID_RESPONSE, responses[0]); - events.emit(constants.EVENTS.BID_RESPONSE, responses[1]); - events.emit(constants.EVENTS.BID_RESPONSE, responses[2]); - - events.emit(constants.EVENTS.BID_TIMEOUT, [responses[3], responses[4]]); - - events.emit(constants.EVENTS.AUCTION_END, auctionEnd); - - expect(yieldoneAnalytics.eventsStorage[auctionId]).to.deep.equal(expectedResult); - - delete yieldoneAnalytics.eventsStorage[auctionId]; - - setTimeout(function() { - events.emit(constants.EVENTS.BID_WON, winner); - - sinon.assert.callCount(sendStatStub, 2); - expect(yieldoneAnalytics.eventsStorage[auctionId]).to.deep.equal(wonExpectedResult); - - delete yieldoneAnalytics.eventsStorage[auctionId]; - done(); - }, 1000); - }); - }); -}); diff --git a/test/spec/modules/yieldoneBidAdapter_spec.js b/test/spec/modules/yieldoneBidAdapter_spec.js deleted file mode 100644 index 84065682297..00000000000 --- a/test/spec/modules/yieldoneBidAdapter_spec.js +++ /dev/null @@ -1,245 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/yieldoneBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; - -const ENDPOINT = 'https://y.one.impact-ad.jp/h_bid'; -const USER_SYNC_URL = 'https://y.one.impact-ad.jp/push_sync'; -const VIDEO_PLAYER_URL = 'https://img.ak.impact-ad.jp/ic/pone/ivt/firstview/js/dac-video-prebid.min.js'; - -describe('yieldoneBidAdapter', function() { - const adapter = newBidder(spec); - - describe('isBidRequestValid', function () { - let bid = { - 'bidder': 'yieldone', - 'params': { - placementId: '36891' - }, - 'adUnitCode': 'adunit-code', - 'sizes': [[300, 250], [336, 280]], - 'bidId': '23beaa6af6cdde', - 'bidderRequestId': '19c0c1efdf37e7', - 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf1', - }; - - it('should return true when required params found', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); - - it('should return false when placementId not passed correctly', function () { - bid.params.placementId = ''; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - - it('should return false when require params are not passed', function () { - let bid = Object.assign({}, bid); - bid.params = {}; - expect(spec.isBidRequestValid(bid)).to.equal(false); - }); - }); - - describe('buildRequests', function () { - let bidRequests = [ - { - 'bidder': 'yieldone', - 'params': { - placementId: '36891' - }, - 'adUnitCode': 'adunit-code1', - 'sizes': [[300, 250], [336, 280]], - 'bidId': '23beaa6af6cdde', - 'bidderRequestId': '19c0c1efdf37e7', - 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf1', - }, - { - 'bidder': 'yieldone', - 'params': { - placementId: '47919' - }, - 'adUnitCode': 'adunit-code2', - 'sizes': [[300, 250]], - 'bidId': '382091349b149f"', - 'bidderRequestId': '"1f9c98192de251"', - 'auctionId': '61466567-d482-4a16-96f0-fe5f25ffbdf1', - } - ]; - - let bidderRequest = { - refererInfo: { - numIframes: 0, - reachedTop: true, - referer: 'http://example.com', - stack: ['http://example.com'] - } - }; - - const request = spec.buildRequests(bidRequests, bidderRequest); - - it('sends bid request to our endpoint via GET', function () { - expect(request[0].method).to.equal('GET'); - expect(request[1].method).to.equal('GET'); - }); - - it('attaches source and version to endpoint URL as query params', function () { - expect(request[0].url).to.equal(ENDPOINT); - expect(request[1].url).to.equal(ENDPOINT); - }); - - it('parameter sz has more than one size on banner requests', function () { - expect(request[0].data.sz).to.equal('300x250,336x280'); - expect(request[1].data.sz).to.equal('300x250'); - }); - - it('width and height should be set as separate parameters on outstream requests', function () { - const bidRequest = Object.assign({}, bidRequests[0]); - bidRequest.mediaTypes = {}; - bidRequest.mediaTypes.video = {context: 'outstream'}; - const request = spec.buildRequests([bidRequest], bidderRequest); - expect(request[0].data.w).to.equal('300'); - expect(request[0].data.h).to.equal('250'); - }); - - it('adUnitCode should be sent as uc parameters on any requests', function () { - expect(request[0].data.uc).to.equal('adunit-code1'); - expect(request[1].data.uc).to.equal('adunit-code2'); - }); - }); - - describe('interpretResponse', function () { - let bidRequestBanner = [ - { - 'method': 'GET', - 'url': 'https://y.one.impact-ad.jp/h_bid', - 'data': { - 'v': 'hb1', - 'p': '36891', - 'sz': '300x250,336x280', - 'cb': 12892917383, - 'r': 'http%3A%2F%2Flocalhost%3A9876%2F%3Fid%3D74552836', - 'uid': '23beaa6af6cdde', - 't': 'i' - } - } - ]; - - let serverResponseBanner = { - body: { - 'adTag': '', - 'uid': '23beaa6af6cdde', - 'height': 250, - 'width': 300, - 'cpm': 0.0536616, - 'crid': '2494768', - 'currency': 'JPY', - 'statusMessage': 'Bid available', - 'dealId': 'P1-FIX-7800-DSP-MON' - } - }; - - it('should get the correct bid response for banner', function () { - let expectedResponse = [{ - 'requestId': '23beaa6af6cdde', - 'cpm': 53.6616, - 'width': 300, - 'height': 250, - 'creativeId': '2494768', - 'dealId': 'P1-FIX-7800-DSP-MON', - 'currency': 'JPY', - 'netRevenue': true, - 'ttl': 3000, - 'referrer': '', - 'mediaType': 'banner', - 'ad': '' - }]; - let result = spec.interpretResponse(serverResponseBanner, bidRequestBanner[0]); - expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); - expect(result[0].mediaType).to.equal(expectedResponse[0].mediaType); - }); - - let serverResponseVideo = { - body: { - 'uid': '23beaa6af6cdde', - 'height': 360, - 'width': 640, - 'cpm': 0.0536616, - 'dealId': 'P1-FIX-766-DSP-MON', - 'crid': '2494768', - 'currency': 'JPY', - 'statusMessage': 'Bid available', - 'adm': '' - } - }; - - let bidRequestVideo = [ - { - 'method': 'GET', - 'url': 'https://y.one.impact-ad.jp/h_bid', - 'data': { - 'v': 'hb1', - 'p': '41993', - 'w': '640', - 'h': '360', - 'cb': 12892917383, - 'r': 'http%3A%2F%2Flocalhost%3A9876%2F%3Fid%3D74552836', - 'uid': '23beaa6af6cdde', - 't': 'i' - } - } - ]; - - it('should get the correct bid response for video', function () { - let expectedResponse = [{ - 'requestId': '23beaa6af6cdde', - 'cpm': 53.6616, - 'width': 640, - 'height': 360, - 'creativeId': '2494768', - 'dealId': 'P1-FIX-7800-DSP-MON', - 'currency': 'JPY', - 'netRevenue': true, - 'ttl': 3000, - 'referrer': '', - 'mediaType': 'video', - 'vastXml': '', - 'renderer': { - id: '23beaa6af6cdde', - url: VIDEO_PLAYER_URL - } - }]; - let result = spec.interpretResponse(serverResponseVideo, bidRequestVideo[0]); - expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])); - expect(result[0].mediaType).to.equal(expectedResponse[0].mediaType); - expect(result[0].renderer.id).to.equal(expectedResponse[0].renderer.id); - expect(result[0].renderer.url).to.equal(expectedResponse[0].renderer.url); - }); - - it('handles empty bid response', function () { - let response = { - body: { - 'uid': '2c0b634db95a01', - 'height': 0, - 'crid': '', - 'statusMessage': 'Bid returned empty or error response', - 'width': 0, - 'cpm': 0 - } - }; - let result = spec.interpretResponse(response, bidRequestBanner[0]); - expect(result.length).to.equal(0); - }); - }); - - describe('getUserSyncs', function () { - it('handles empty sync options', function () { - expect(spec.getUserSyncs({})).to.be.undefined; - }); - - it('should return a sync url if iframe syncs are enabled', function () { - expect(spec.getUserSyncs({ - 'iframeEnabled': true - })).to.deep.equal([{ - type: 'iframe', url: USER_SYNC_URL - }]); - }); - }); -}); diff --git a/test/spec/modules/yuktamediaAnalyticsAdapter_spec.js b/test/spec/modules/yuktamediaAnalyticsAdapter_spec.js deleted file mode 100644 index e8eb4ab73be..00000000000 --- a/test/spec/modules/yuktamediaAnalyticsAdapter_spec.js +++ /dev/null @@ -1,713 +0,0 @@ -import yuktamediaAnalyticsAdapter from 'modules/yuktamediaAnalyticsAdapter.js'; -import { expect } from 'chai'; -let events = require('src/events'); -let constants = require('src/constants.json'); - -let prebidAuction = { - 'auctionInit': { - 'auctionId': 'ca421611-0bc0-4164-a69c-fe4158c68954', - 'timestamp': 1595850680304, - }, - 'bidRequested': { - 'bidderCode': 'appnexus', - 'auctionId': 'ca421611-0bc0-4164-a69c-fe4158c68954', - 'bidderRequestId': '181df4d465699c', - 'bids': [ - { - 'bidder': 'appnexus', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ] - } - }, - 'userId': { - 'id5id': { uid: 'ID5-ZHMOxXeRXPe3inZKGD-Lj0g7y8UWdDbsYXQ_n6aWMQ' }, - 'parrableid': '01.1595590997.46d951017bdc272ca50b88dbcfb0545cfc636bec3e3d8c02091fb1b413328fb2fd3baf65cb4114b3f782895fd09f82f02c9042b85b42c4654d08ba06dc77f0ded936c8ea3fc4085b4a99', - 'pubcid': '100a8bc9-f588-4c22-873e-a721cb68bc34' - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '2bccebeda7fbe4', - 'bidderRequestId': '181df4d465699c', - 'auctionId': 'ca421611-0bc0-4164-a69c-fe4158c68954', - 'src': 'client', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 1, - 'bidderWinsCount': 0 - } - ], - 'auctionStart': 1595850680304, - 'timeout': 1100, - 'start': 1595850680307 - }, - 'noBid': {}, - 'bidTimeout': [], - 'bidResponse': { - 'bidderCode': 'appnexus', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'getStatusCode': function () { return 1; }, - 'adId': '3ade442375213f', - 'requestId': '2bccebeda7fbe4', - 'mediaType': 'banner', - 'source': 'client', - 'cpm': 0.5, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'auctionId': 'ca421611-0bc0-4164-a69c-fe4158c68954', - 'responseTimestamp': 1595850681254, - 'requestTimestamp': 1595850680307, - 'bidder': 'appnexus', - 'timeToRespond': 947, - 'size': '300x250', - 'adserverTargeting': { - 'hb_bidder': 'appnexus', - 'hb_adid': '3ade442375213f', - 'hb_pb': '0.50', - 'hb_size': '300x250', - 'hb_source': 'client', - 'hb_format': 'banner' - } - }, - 'auctionEnd': { - 'auctionId': 'ca421611-0bc0-4164-a69c-fe4158c68954' - }, - 'bidWon': { - 'bidderCode': 'appnexus', - 'width': 300, - 'height': 250, - 'requestId': '2bccebeda7fbe4', - 'mediaType': 'banner', - 'source': 'client', - 'cpm': 0.5, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'auctionId': 'ca421611-0bc0-4164-a69c-fe4158c68954', - 'responseTimestamp': 1595850681254, - 'requestTimestamp': 1595850680307, - 'bidder': 'appnexus', - 'timeToRespond': 947, - 'size': '300x250', - 'adserverTargeting': { - 'hb_bidder': 'appnexus', - 'hb_adid': '3ade442375213f', - 'hb_pb': '0.50', - 'hb_size': '300x250', - 'hb_source': 'client', - 'hb_format': 'banner' - }, - 'status': 'rendered' - } -}; - -let prebidNativeAuction = { - 'auctionInit': { - 'auctionId': '86e005fa-1900-4782-b6df-528500f09128', - 'timestamp': 1595589742100, - }, - 'bidRequested': { - 'bidderCode': 'appnexus', - 'auctionId': '86e005fa-1900-4782-b6df-528500f09128', - 'tid': 'f9c220eb-e44f-412b-92ff-8c24085ca675', - 'bids': [ - { - 'bidder': 'appnexus', - 'bid_id': '19a879bd73bc8d', - 'nativeParams': { - 'title': { - 'required': true, - 'len': 800 - }, - 'image': { - 'required': true, - 'sizes': [ - 989, - 742 - ] - }, - 'sponsoredBy': { - 'required': true - } - }, - 'mediaTypes': { - 'native': { - 'title': { - 'required': true, - 'len': 800 - }, - 'image': { - 'required': true, - 'sizes': [ - 989, - 742 - ] - }, - 'sponsoredBy': { - 'required': true - } - } - }, - 'adUnitCode': '/19968336/prebid_native_example_1', - 'sizes': [], - 'bidId': '19a879bd73bc8d', - 'auctionId': '86e005fa-1900-4782-b6df-528500f09128', - 'src': 's2s', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 0, - 'bidderWinsCount': 0 - }, - { - 'bidder': 'appnexus', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ] - } - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '28f8cc7d10f2db', - 'auctionId': '86e005fa-1900-4782-b6df-528500f09128', - 'src': 's2s', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 2, - 'bidderWinsCount': 0 - } - ], - 'auctionStart': 1595589742100, - 'timeout': 1000, - 'src': 's2s', - 'start': 1595589742108 - }, - 'bidRequested1': { - 'bidderCode': 'ix', - 'auctionId': '86e005fa-1900-4782-b6df-528500f09128', - 'bidderRequestId': '5e64168f3654af', - 'bids': [ - { - 'bidder': 'ix', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } - }, - 'adUnitCode': 'dfp-ad-rightrail_top', - 'sizes': [[300, 250]], - 'bidId': '9424dea605368f', - 'bidderRequestId': '5e64168f3654af', - 'auctionId': '86e005fa-1900-4782-b6df-528500f09128', - 'src': 's2s' - } - ], - 'auctionStart': 1595589742100, - 'timeout': 1000, - 'src': 's2s', - 'start': 1595589742108 - }, - 'noBid': { - 'bidder': 'ix', - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 300, - 250 - ] - ] - } - }, - 'adUnitCode': 'dfp-ad-rightrail_top', - 'transactionId': 'd99d90e0-663a-459d-8c87-4c92ce6a527c', - 'sizes': [[300, 250]], - 'bidId': '9424dea605368f', - 'bidderRequestId': '5e64168f3654af', - 'auctionId': '86e005fa-1900-4782-b6df-528500f09128', - 'src': 's2s', - 'bidRequestsCount': 1, - 'bidderRequestsCount': 4, - 'bidderWinsCount': 0 - }, - 'bidTimeout': [ - { - 'bidId': '28f8cc7d10f2db', - 'bidder': 'appnexus', - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'auctionId': '86e005fa-1900-4782-b6df-528500f09128' - } - ], - 'bidResponse': { - 'bidderCode': 'appnexus', - 'statusMessage': 'Bid available', - 'source': 's2s', - 'getStatusCode': function () { return 1; }, - 'cpm': 10, - 'adserverTargeting': { - 'hb_bidder': 'appnexus', - 'hb_pb': '10.00', - 'hb_adid': '4e756c72ee9044', - 'hb_size': 'undefinedxundefined', - 'hb_source': 's2s', - 'hb_format': 'native', - 'hb_native_linkurl': 'some_long_url', - 'hb_native_title': 'This is a Prebid Native Creative', - 'hb_native_brand': 'Prebid.org' - }, - 'native': { - 'clickUrl': { - 'url': 'some_long_url' - }, - 'impressionTrackers': [ - 'some_long_url' - ], - 'javascriptTrackers': [], - 'image': { - 'url': 'some_long_image_path', - 'width': 989, - 'height': 742 - }, - 'title': 'This is a Prebid Native Creative', - 'sponsoredBy': 'Prebid.org' - }, - 'currency': 'USD', - 'ttl': 60, - 'netRevenue': true, - 'auctionId': '86e005fa-1900-4782-b6df-528500f09128', - 'responseTimestamp': 1595589742827, - 'requestTimestamp': 1595589742108, - 'bidder': 'appnexus', - 'adUnitCode': '/19968336/prebid_native_example_1', - 'timeToRespond': 719, - 'size': 'undefinedxundefined' - }, - 'auctionEnd': { - 'auctionId': '86e005fa-1900-4782-b6df-528500f09128' - }, - 'bidWon': { - 'bidderCode': 'appnexus', - 'mediaType': 'native', - 'source': 's2s', - 'getStatusCode': function () { return 1; }, - 'cpm': 10, - 'adserverTargeting': { - 'hb_bidder': 'appnexus', - 'hb_pb': '10.00', - 'hb_adid': '4e756c72ee9044', - 'hb_size': 'undefinedxundefined', - 'hb_source': 's2s', - 'hb_format': 'native', - 'hb_native_linkurl': 'some_long_url', - 'hb_native_title': 'This is a Prebid Native Creative', - 'hb_native_brand': 'Prebid.org' - }, - 'native': { - 'clickUrl': { - 'url': 'some_long_url' - }, - 'impressionTrackers': [ - 'some_long_url' - ], - 'javascriptTrackers': [], - 'image': { - 'url': 'some_long_image_path', - 'width': 989, - 'height': 742 - }, - 'title': 'This is a Prebid Native Creative', - 'sponsoredBy': 'Prebid.org' - }, - 'currency': 'USD', - 'ttl': 60, - 'netRevenue': true, - 'auctionId': '86e005fa-1900-4782-b6df-528500f09128', - 'responseTimestamp': 1595589742827, - 'requestTimestamp': 1595589742108, - 'bidder': 'appnexus', - 'adUnitCode': '/19968336/prebid_native_example_1', - 'timeToRespond': 719, - 'size': 'undefinedxundefined', - 'status': 'rendered' - } -} - -describe('yuktamedia analytics adapter', function () { - beforeEach(() => { - sinon.stub(events, 'getEvents').returns([]); - }); - afterEach(() => { - events.getEvents.restore(); - }); - - describe('enableAnalytics', function () { - beforeEach(() => { - sinon.spy(yuktamediaAnalyticsAdapter, 'track'); - }); - afterEach(() => { - yuktamediaAnalyticsAdapter.disableAnalytics(); - yuktamediaAnalyticsAdapter.track.restore(); - }); - - it('should catch all events 1', function () { - yuktamediaAnalyticsAdapter.enableAnalytics({ - provider: 'yuktamedia', - options: { - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: true, - enableSession: true, - enableUserIdCollection: true - } - }); - events.emit(constants.EVENTS.AUCTION_INIT, prebidAuction[constants.EVENTS.AUCTION_INIT]); - sinon.assert.called(yuktamediaAnalyticsAdapter.track); - }); - - it('should catch all events 2', function () { - yuktamediaAnalyticsAdapter.enableAnalytics({ - provider: 'yuktamedia', - options: { - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: true, - enableSession: true, - enableUserIdCollection: true - } - }); - events.emit(constants.EVENTS.BID_REQUESTED, prebidAuction[constants.EVENTS.BID_REQUESTED]); - sinon.assert.called(yuktamediaAnalyticsAdapter.track); - }); - - it('should catch all events 3', function () { - yuktamediaAnalyticsAdapter.enableAnalytics({ - provider: 'yuktamedia', - options: { - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: true, - enableSession: true, - enableUserIdCollection: true - } - }); - events.emit(constants.EVENTS.NO_BID, prebidAuction[constants.EVENTS.NO_BID]); - sinon.assert.called(yuktamediaAnalyticsAdapter.track); - }); - - it('should catch all events 4', function () { - yuktamediaAnalyticsAdapter.enableAnalytics({ - provider: 'yuktamedia', - options: { - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: true, - enableSession: true, - enableUserIdCollection: true - } - }); - events.emit(constants.EVENTS.BID_TIMEOUT, prebidAuction[constants.EVENTS.BID_TIMEOUT]); - sinon.assert.called(yuktamediaAnalyticsAdapter.track); - }); - - it('should catch all events 5', function () { - yuktamediaAnalyticsAdapter.enableAnalytics({ - provider: 'yuktamedia', - options: { - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: true, - enableSession: true, - enableUserIdCollection: true - } - }); - events.emit(constants.EVENTS.BID_RESPONSE, prebidAuction[constants.EVENTS.BID_RESPONSE]); - sinon.assert.called(yuktamediaAnalyticsAdapter.track); - }); - - it('should catch all events 6', function () { - yuktamediaAnalyticsAdapter.enableAnalytics({ - provider: 'yuktamedia', - options: { - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: true, - enableSession: true, - enableUserIdCollection: true - } - }); - events.emit(constants.EVENTS.AUCTION_END, prebidAuction[constants.EVENTS.AUCTION_END]); - sinon.assert.called(yuktamediaAnalyticsAdapter.track); - }); - - it('should catch no events if no pubKey and pubId', function () { - yuktamediaAnalyticsAdapter.enableAnalytics({ - provider: 'yuktamedia', - options: { - } - }); - - events.emit(constants.EVENTS.AUCTION_INIT, {}); - events.emit(constants.EVENTS.AUCTION_END, {}); - events.emit(constants.EVENTS.BID_REQUESTED, {}); - events.emit(constants.EVENTS.BID_RESPONSE, {}); - events.emit(constants.EVENTS.BID_WON, {}); - - sinon.assert.callCount(yuktamediaAnalyticsAdapter.track, 0); - }); - - it('should catch nobid, timeout and bidwon event events one of eight', function () { - yuktamediaAnalyticsAdapter.enableAnalytics({ - provider: 'yuktamedia', - options: { - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: true, - enableSession: true, - enableUserIdCollection: true - } - }); - events.emit(constants.EVENTS.AUCTION_INIT, prebidNativeAuction[constants.EVENTS.AUCTION_INIT]); - sinon.assert.called(yuktamediaAnalyticsAdapter.track); - }); - - it('should catch nobid, timeout and bidwon event events two of eight', function () { - yuktamediaAnalyticsAdapter.enableAnalytics({ - provider: 'yuktamedia', - options: { - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: true, - enableSession: true, - enableUserIdCollection: true - } - }); - events.emit(constants.EVENTS.BID_REQUESTED, prebidNativeAuction[constants.EVENTS.BID_REQUESTED]); - sinon.assert.called(yuktamediaAnalyticsAdapter.track); - }); - - it('should catch nobid, timeout and bidwon event events three of eight', function () { - yuktamediaAnalyticsAdapter.enableAnalytics({ - provider: 'yuktamedia', - options: { - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: true, - enableSession: true, - enableUserIdCollection: true - } - }); - events.emit(constants.EVENTS.BID_REQUESTED, prebidNativeAuction[constants.EVENTS.BID_REQUESTED + '1']); - sinon.assert.called(yuktamediaAnalyticsAdapter.track); - }); - - it('should catch nobid, timeout and bidwon event events four of eight', function () { - yuktamediaAnalyticsAdapter.enableAnalytics({ - provider: 'yuktamedia', - options: { - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: true, - enableSession: true, - enableUserIdCollection: true - } - }); - events.emit(constants.EVENTS.NO_BID, prebidNativeAuction[constants.EVENTS.NO_BID]); - sinon.assert.called(yuktamediaAnalyticsAdapter.track); - }); - - it('should catch nobid, timeout and bidwon event events five of eight', function () { - yuktamediaAnalyticsAdapter.enableAnalytics({ - provider: 'yuktamedia', - options: { - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: true, - enableSession: true, - enableUserIdCollection: true - } - }); - events.emit(constants.EVENTS.BID_TIMEOUT, prebidNativeAuction[constants.EVENTS.BID_TIMEOUT]); - sinon.assert.called(yuktamediaAnalyticsAdapter.track); - }); - - it('should catch nobid, timeout and bidwon event events six of eight', function () { - yuktamediaAnalyticsAdapter.enableAnalytics({ - provider: 'yuktamedia', - options: { - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: true, - enableSession: true, - enableUserIdCollection: true - } - }); - events.emit(constants.EVENTS.BID_RESPONSE, prebidNativeAuction[constants.EVENTS.BID_RESPONSE]); - sinon.assert.called(yuktamediaAnalyticsAdapter.track); - }); - - it('should catch nobid, timeout and bidwon event events seven of eight', function () { - yuktamediaAnalyticsAdapter.enableAnalytics({ - provider: 'yuktamedia', - options: { - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: true, - enableSession: true, - enableUserIdCollection: true - } - }); - events.emit(constants.EVENTS.AUCTION_END, prebidNativeAuction[constants.EVENTS.AUCTION_END]); - sinon.assert.called(yuktamediaAnalyticsAdapter.track); - }); - - it('should catch nobid, timeout and bidwon event events eight of eight', function () { - yuktamediaAnalyticsAdapter.enableAnalytics({ - provider: 'yuktamedia', - options: { - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: true, - enableSession: true, - enableUserIdCollection: true - } - }); - events.emit(constants.EVENTS.AUCTION_END, prebidNativeAuction[constants.EVENTS.BID_WON]); - sinon.assert.called(yuktamediaAnalyticsAdapter.track); - }); - }); - - describe('build utm tag data', function () { - beforeEach(function () { - localStorage.setItem('yuktamediaAnalytics_utm_source', 'prebid'); - localStorage.setItem('yuktamediaAnalytics_utm_medium', 'ad'); - localStorage.setItem('yuktamediaAnalytics_utm_campaign', ''); - localStorage.setItem('yuktamediaAnalytics_utm_term', ''); - localStorage.setItem('yuktamediaAnalytics_utm_content', ''); - localStorage.setItem('yuktamediaAnalytics_utm_timeout', Date.now()); - }); - - afterEach(function () { - localStorage.clear(); - }); - - it('should build utm data from local storage', function () { - let utmTagData = yuktamediaAnalyticsAdapter.buildUtmTagData({ - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: true, - enableSession: true, - enableUserIdCollection: true - }); - expect(utmTagData.utm_source).to.equal('prebid'); - expect(utmTagData.utm_medium).to.equal('ad'); - expect(utmTagData.utm_campaign).to.equal(''); - expect(utmTagData.utm_term).to.equal(''); - expect(utmTagData.utm_content).to.equal(''); - }); - - it('should return empty object for disabled utm setting', function () { - let utmTagData = yuktamediaAnalyticsAdapter.buildUtmTagData({ - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: false, - enableSession: true, - enableUserIdCollection: true - }); - expect(utmTagData).deep.equal({}); - }); - }); - - describe('build session information', function () { - beforeEach(() => { - sinon.spy(yuktamediaAnalyticsAdapter, 'track'); - localStorage.clear(); - }); - afterEach(() => { - yuktamediaAnalyticsAdapter.disableAnalytics(); - yuktamediaAnalyticsAdapter.track.restore(); - localStorage.clear(); - }); - - it('should create session id in local storage if enabled', function () { - yuktamediaAnalyticsAdapter.enableAnalytics({ - provider: 'yuktamedia', - options: { - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: true, - enableSession: true, - enableUserIdCollection: true - } - }); - events.emit(constants.EVENTS.AUCTION_INIT, prebidAuction[constants.EVENTS.AUCTION_INIT]); - events.emit(constants.EVENTS.BID_REQUESTED, prebidAuction[constants.EVENTS.BID_REQUESTED]); - events.emit(constants.EVENTS.NO_BID, prebidAuction[constants.EVENTS.NO_BID]); - events.emit(constants.EVENTS.BID_TIMEOUT, prebidAuction[constants.EVENTS.BID_TIMEOUT]); - events.emit(constants.EVENTS.BID_RESPONSE, prebidAuction[constants.EVENTS.BID_RESPONSE]); - events.emit(constants.EVENTS.AUCTION_END, prebidAuction[constants.EVENTS.AUCTION_END]); - expect(localStorage.getItem('yuktamediaAnalytics_session_id')).to.not.equal(null); - }); - - it('should not create session id in local storage if disabled', function () { - yuktamediaAnalyticsAdapter.enableAnalytics({ - provider: 'yuktamedia', - options: { - pubId: '1', - pubKey: 'ZXlKaGJHY2lPaUpJVXpJMU5pSjkuT==', - enableUTMCollection: true, - enableSession: false, - enableUserIdCollection: true - } - }); - events.emit(constants.EVENTS.AUCTION_INIT, prebidAuction[constants.EVENTS.AUCTION_INIT]); - events.emit(constants.EVENTS.BID_REQUESTED, prebidAuction[constants.EVENTS.BID_REQUESTED]); - events.emit(constants.EVENTS.NO_BID, prebidAuction[constants.EVENTS.NO_BID]); - events.emit(constants.EVENTS.BID_TIMEOUT, prebidAuction[constants.EVENTS.BID_TIMEOUT]); - events.emit(constants.EVENTS.BID_RESPONSE, prebidAuction[constants.EVENTS.BID_RESPONSE]); - events.emit(constants.EVENTS.AUCTION_END, prebidAuction[constants.EVENTS.AUCTION_END]); - expect(localStorage.getItem('yuktamediaAnalytics_session_id')).to.equal(null); - }); - }); -}); diff --git a/test/spec/modules/zedoBidAdapter_spec.js b/test/spec/modules/zedoBidAdapter_spec.js deleted file mode 100644 index 8e5a789656e..00000000000 --- a/test/spec/modules/zedoBidAdapter_spec.js +++ /dev/null @@ -1,354 +0,0 @@ -import { expect } from 'chai'; -import { spec } from 'modules/zedoBidAdapter'; - -describe('The ZEDO bidding adapter', function () { - describe('isBidRequestValid', function () { - it('should return false when given an invalid bid', function () { - const bid = { - bidder: 'zedo', - }; - const isValid = spec.isBidRequestValid(bid); - expect(isValid).to.equal(false); - }); - - it('should return true when given a channelcode bid', function () { - const bid = { - bidder: 'zedo', - params: { - channelCode: 20000000, - dimId: 9 - }, - }; - const isValid = spec.isBidRequestValid(bid); - expect(isValid).to.equal(true); - }); - }); - - describe('buildRequests', function () { - const bidderRequest = { - timeout: 3000, - }; - - it('should properly build a channelCode request for dim Id with type not defined', function () { - const bidRequests = [ - { - bidder: 'zedo', - adUnitCode: 'p12345', - transactionId: '12345667', - sizes: [[300, 200]], - params: { - channelCode: 20000000, - dimId: 10, - pubId: 1 - }, - }, - ]; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.url).to.match(/^https:\/\/saxp.zedo.com\/asw\/fmh.json/); - expect(request.method).to.equal('GET'); - const zedoRequest = request.data; - expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"publisher":1,"width":300,"height":200,"dimension":10,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"display"}]}]}'); - }); - - it('should properly build a channelCode request for video with type defined', function () { - const bidRequests = [ - { - bidder: 'zedo', - adUnitCode: 'p12345', - transactionId: '12345667', - sizes: [640, 480], - mediaTypes: { - video: { - context: 'instream', - }, - }, - params: { - channelCode: 20000000, - dimId: 85 - }, - }, - ]; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.url).to.match(/^https:\/\/saxp.zedo.com\/asw\/fmh.json/); - expect(request.method).to.equal('GET'); - const zedoRequest = request.data; - expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"publisher":0,"width":640,"height":480,"dimension":85,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"Inarticle"}]}]}'); - }); - - describe('buildGDPRRequests', function () { - let consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - const bidderRequest = { - timeout: 3000, - gdprConsent: { - 'consentString': consentString, - 'gdprApplies': true - } - }; - - it('should properly build request with gdpr consent', function () { - const bidRequests = [ - { - bidder: 'zedo', - adUnitCode: 'p12345', - transactionId: '12345667', - sizes: [[300, 200]], - params: { - channelCode: 20000000, - dimId: 10 - }, - }, - ]; - const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.method).to.equal('GET'); - const zedoRequest = request.data; - expect(zedoRequest).to.equal('g={"placements":[{"network":20,"channel":0,"publisher":0,"width":300,"height":200,"dimension":10,"version":"$prebid.version$","keyword":"","transactionId":"12345667","renderers":[{"name":"display"}]}],"gdpr":1,"gdpr_consent":"BOJ8RZsOJ8RZsABAB8AAAAAZ+A=="}'); - }); - }); - }); - describe('interpretResponse', function () { - it('should return an empty array when there is bid response', function () { - const response = {}; - const request = { bidRequests: [] }; - const bids = spec.interpretResponse(response, request); - expect(bids).to.have.lengthOf(0); - }); - - it('should properly parse a bid response with no valid creative', function () { - const response = { - body: { - ad: [ - { - 'slotId': 'ad1d762', - 'network': '2000', - 'creatives': [ - { - 'adId': '12345', - 'height': '600', - 'width': '160', - 'isFoc': true, - 'creativeDetails': { - 'type': 'StdBanner', - 'adContent': { - 'focImage': { - 'url': 'https://c13.zedo.com/OzoDB/0/0/0/blank.gif', - 'target': '_blank', - } - } - }, - 'cpm': '0' - } - ] - } - ] - } - }; - const request = { - bidRequests: [{ - bidder: 'zedo', - adUnitCode: 'p12345', - bidId: 'test-bidId', - params: { - channelCode: 2000000, - dimId: 9 - } - }] - }; - const bids = spec.interpretResponse(response, request); - expect(bids).to.have.lengthOf(0); - }); - - it('should properly parse a bid response with valid display creative', function () { - const response = { - body: { - ad: [ - { - 'slotId': 'ad1d762', - 'network': '2000', - 'creatives': [ - { - 'adId': '12345', - 'height': '600', - 'width': '160', - 'isFoc': true, - 'creativeDetails': { - 'type': 'StdBanner', - 'adContent': '' - }, - 'bidCpm': '720000' - } - ] - } - ] - } - }; - const request = { - bidRequests: [{ - bidder: 'zedo', - adUnitCode: 'test-requestId', - bidId: 'test-bidId', - params: { - channelCode: 2000000, - dimId: 9 - }, - }] - }; - const bids = spec.interpretResponse(response, request); - expect(bids).to.have.lengthOf(1); - expect(bids[0].requestId).to.equal('ad1d762'); - expect(bids[0].cpm).to.equal(0.72); - expect(bids[0].width).to.equal('160'); - expect(bids[0].height).to.equal('600'); - }); - - it('should properly parse a bid response with valid video creative', function () { - const response = { - body: { - ad: [ - { - 'slotId': 'ad1d762', - 'network': '2000', - 'creatives': [ - { - 'adId': '12345', - 'height': '480', - 'width': '640', - 'isFoc': true, - 'creativeDetails': { - 'type': 'VAST', - 'adContent': '' - }, - 'bidCpm': '780000' - } - ] - } - ] - } - }; - const request = { - bidRequests: [{ - bidder: 'zedo', - adUnitCode: 'test-requestId', - bidId: 'test-bidId', - params: { - channelCode: 2000000, - dimId: 85 - }, - }] - }; - - const bids = spec.interpretResponse(response, request); - expect(bids).to.have.lengthOf(1); - expect(bids[0].requestId).to.equal('ad1d762'); - expect(bids[0].cpm).to.equal(0.78); - expect(bids[0].width).to.equal('640'); - expect(bids[0].height).to.equal('480'); - expect(bids[0].adType).to.equal('VAST'); - expect(bids[0].vastXml).to.not.equal(''); - expect(bids[0].ad).to.be.an('undefined'); - expect(bids[0].renderer).not.to.be.an('undefined'); - }); - }); - - describe('user sync', function () { - it('should register the iframe sync url', function () { - let syncs = spec.getUserSyncs({ - iframeEnabled: true - }); - expect(syncs).to.not.be.an('undefined'); - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('iframe'); - }); - - it('should pass gdpr params', function () { - let syncs = spec.getUserSyncs({ iframeEnabled: true }, {}, { - gdprApplies: false, consentString: 'test' - }); - expect(syncs).to.not.be.an('undefined'); - expect(syncs).to.have.lengthOf(1); - expect(syncs[0].type).to.equal('iframe'); - expect(syncs[0].url).to.contains('gdpr=0'); - }); - }); - - describe('bid events', function () { - it('should trigger a win pixel', function () { - const bid = { - 'bidderCode': 'zedo', - 'width': '300', - 'height': '250', - 'statusMessage': 'Bid available', - 'adId': '148018fe5e', - 'cpm': 0.5, - 'ad': 'dummy data', - 'ad_id': '12345', - 'sizeId': '15', - 'adResponse': - { - 'creatives': [ - { - 'adId': '12345', - 'height': '480', - 'width': '640', - 'isFoc': true, - 'creativeDetails': { - 'type': 'VAST', - 'adContent': '' - }, - 'seeder': { - 'network': 1234, - 'servedChan': 1234567, - }, - 'cpm': '1200000', - 'servedChan': 1234, - }] - }, - 'params': [{ - 'channelCode': '123456', - 'dimId': '85' - }], - 'requestTimestamp': 1540401686, - 'responseTimestamp': 1540401687, - 'timeToRespond': 6253, - 'pbLg': '0.50', - 'pbMg': '0.50', - 'pbHg': '0.53', - 'adUnitCode': '/123456/header-bid-tag-0', - 'bidder': 'zedo', - 'size': '300x250', - 'adserverTargeting': { - 'hb_bidder': 'zedo', - 'hb_adid': '148018fe5e', - 'hb_pb': '10.00', - } - }; - spec.onBidWon(bid); - spec.onTimeout(bid); - }); - it('should trigger a timeout pixel', function () { - const bid = { - 'bidderCode': 'zedo', - 'width': '300', - 'height': '250', - 'statusMessage': 'Bid available', - 'adId': '148018fe5e', - 'cpm': 0.5, - 'ad': 'dummy data', - 'ad_id': '12345', - 'sizeId': '15', - 'params': [{ - 'channelCode': '123456', - 'dimId': '85' - }], - 'timeout': 1, - 'requestTimestamp': 1540401686, - 'responseTimestamp': 1540401687, - 'timeToRespond': 6253, - 'adUnitCode': '/123456/header-bid-tag-0', - 'bidder': 'zedo', - 'size': '300x250', - }; - spec.onBidWon(bid); - spec.onTimeout(bid); - }); - }); -}); diff --git a/test/spec/modules/zemantaBidAdapter_spec.js b/test/spec/modules/zemantaBidAdapter_spec.js deleted file mode 100644 index 523cdcd2eb3..00000000000 --- a/test/spec/modules/zemantaBidAdapter_spec.js +++ /dev/null @@ -1,558 +0,0 @@ -import {expect} from 'chai'; -import {spec} from 'modules/zemantaBidAdapter.js'; -import {config} from 'src/config.js'; -import {server} from 'test/mocks/xhr'; - -describe('Zemanta Adapter', function () { - describe('Bid request and response', function () { - const commonBidRequest = { - bidder: 'zemanta', - params: { - publisher: { - id: 'publisher-id' - }, - }, - bidId: '2d6815a92ba1ba', - auctionId: '12043683-3254-4f74-8934-f941b085579e', - } - const nativeBidRequestParams = { - nativeParams: { - image: { - required: true, - sizes: [ - 120, - 100 - ], - sendId: true - }, - title: { - required: true, - sendId: true - }, - sponsoredBy: { - required: false - } - }, - } - - const displayBidRequestParams = { - sizes: [ - [ - 300, - 250 - ] - ] - } - - describe('isBidRequestValid', function () { - before(() => { - config.setConfig({ - zemanta: { - bidderUrl: 'https://bidder-url.com', - } - } - ) - }) - after(() => { - config.resetConfig() - }) - - it('should fail when bid is invalid', function () { - const bid = { - bidder: 'zemanta', - params: { - publisher: { - id: 'publisher-id', - } - }, - } - expect(spec.isBidRequestValid(bid)).to.equal(false) - }) - it('should succeed when bid contains native params', function () { - const bid = { - bidder: 'zemanta', - params: { - publisher: { - id: 'publisher-id', - } - }, - ...nativeBidRequestParams, - } - expect(spec.isBidRequestValid(bid)).to.equal(true) - }) - it('should succeed when bid contains sizes', function () { - const bid = { - bidder: 'zemanta', - params: { - publisher: { - id: 'publisher-id', - } - }, - ...displayBidRequestParams, - } - expect(spec.isBidRequestValid(bid)).to.equal(true) - }) - it('should fail if publisher id is not set', function () { - const bid = { - bidder: 'zemanta', - ...nativeBidRequestParams, - } - expect(spec.isBidRequestValid(bid)).to.equal(false) - }) - it('should succeed with outbrain config', function () { - const bid = { - bidder: 'zemanta', - params: { - publisher: { - id: 'publisher-id', - } - }, - ...nativeBidRequestParams, - } - config.resetConfig() - config.setConfig({ - outbrain: { - bidderUrl: 'https://bidder-url.com', - } - }) - expect(spec.isBidRequestValid(bid)).to.equal(true) - }) - it('should fail if bidder url is not set', function () { - const bid = { - bidder: 'zemanta', - params: { - publisher: { - id: 'publisher-id', - } - }, - ...nativeBidRequestParams, - } - config.resetConfig() - expect(spec.isBidRequestValid(bid)).to.equal(false) - }) - }) - - describe('buildRequests', function () { - before(() => { - config.setConfig({ - zemanta: { - bidderUrl: 'https://bidder-url.com', - } - } - ) - }) - after(() => { - config.resetConfig() - }) - - const commonBidderRequest = { - refererInfo: { - referer: 'https://example.com/' - } - } - - it('should build native request', function () { - const bidRequest = { - ...commonBidRequest, - ...nativeBidRequestParams, - } - const expectedNativeAssets = { - assets: [ - { - required: 1, - id: 3, - img: { - type: 3, - w: 120, - h: 100 - } - }, - { - required: 1, - id: 0, - title: {} - }, - { - required: 0, - id: 5, - data: { - type: 1 - } - } - ] - } - const expectedData = { - site: { - page: 'https://example.com/', - publisher: { - id: 'publisher-id' - } - }, - device: { - ua: navigator.userAgent - }, - source: { - fd: 1 - }, - cur: [ - 'USD' - ], - imp: [ - { - id: '1', - native: { - request: JSON.stringify(expectedNativeAssets) - } - } - ] - } - const res = spec.buildRequests([bidRequest], commonBidderRequest) - expect(res.url).to.equal('https://bidder-url.com') - expect(res.data).to.deep.equal(JSON.stringify(expectedData)) - }); - - it('should build display request', function () { - const bidRequest = { - ...commonBidRequest, - ...displayBidRequestParams, - } - const expectedData = { - site: { - page: 'https://example.com/', - publisher: { - id: 'publisher-id' - } - }, - device: { - ua: navigator.userAgent - }, - source: { - fd: 1 - }, - cur: [ - 'USD' - ], - imp: [ - { - id: '1', - banner: { - format: [ - { - w: 300, - h: 250 - } - ] - } - } - ] - } - const res = spec.buildRequests([bidRequest], commonBidderRequest) - expect(res.url).to.equal('https://bidder-url.com') - expect(res.data).to.deep.equal(JSON.stringify(expectedData)) - }) - - it('should pass optional parameters in request', function () { - const bidRequest = { - ...commonBidRequest, - ...nativeBidRequestParams, - } - bidRequest.params.tagid = 'test-tag' - bidRequest.params.publisher.name = 'test-publisher' - bidRequest.params.publisher.domain = 'test-publisher.com' - bidRequest.params.bcat = ['bad-category'] - bidRequest.params.badv = ['bad-advertiser'] - - const res = spec.buildRequests([bidRequest], commonBidderRequest) - const resData = JSON.parse(res.data) - expect(resData.imp[0].tagid).to.equal('test-tag') - expect(resData.site.publisher.name).to.equal('test-publisher') - expect(resData.site.publisher.domain).to.equal('test-publisher.com') - expect(resData.bcat).to.deep.equal(['bad-category']) - expect(resData.badv).to.deep.equal(['bad-advertiser']) - }); - - it('should pass bidder timeout', function () { - const bidRequest = { - ...commonBidRequest, - ...nativeBidRequestParams, - } - const bidderRequest = { - ...commonBidderRequest, - timeout: 500 - } - const res = spec.buildRequests([bidRequest], bidderRequest) - const resData = JSON.parse(res.data) - expect(resData.tmax).to.equal(500) - }); - - it('should pass GDPR consent', function () { - const bidRequest = { - ...commonBidRequest, - ...nativeBidRequestParams, - } - const bidderRequest = { - ...commonBidderRequest, - gdprConsent: { - gdprApplies: true, - consentString: 'consentString', - } - } - const res = spec.buildRequests([bidRequest], bidderRequest) - const resData = JSON.parse(res.data) - expect(resData.user.ext.consent).to.equal('consentString') - expect(resData.regs.ext.gdpr).to.equal(1) - }); - - it('should pass us privacy consent', function () { - const bidRequest = { - ...commonBidRequest, - ...nativeBidRequestParams, - } - const bidderRequest = { - ...commonBidderRequest, - uspConsent: 'consentString' - } - const res = spec.buildRequests([bidRequest], bidderRequest) - const resData = JSON.parse(res.data) - expect(resData.regs.ext.us_privacy).to.equal('consentString') - }); - - it('should pass coppa consent', function () { - const bidRequest = { - ...commonBidRequest, - ...nativeBidRequestParams, - } - config.setConfig({coppa: true}) - - const res = spec.buildRequests([bidRequest], commonBidderRequest) - const resData = JSON.parse(res.data) - expect(resData.regs.coppa).to.equal(1) - - config.resetConfig() - }); - }) - - describe('interpretResponse', function () { - it('should return empty array if no valid bids', function () { - const res = spec.interpretResponse({}, []) - expect(res).to.be.an('array').that.is.empty - }); - - it('should interpret native response', function () { - const serverResponse = { - body: { - id: '0a73e68c-9967-4391-b01b-dda2d9fc54e4', - seatbid: [ - { - bid: [ - { - id: '82822cf5-259c-11eb-8a52-f29e5275aa57', - impid: '1', - price: 1.1, - nurl: 'http://example.com/win/${AUCTION_PRICE}', - adm: '{"ver":"1.2","assets":[{"id":3,"required":1,"img":{"url":"http://example.com/img/url","w":120,"h":100}},{"id":0,"required":1,"title":{"text":"Test title"}},{"id":5,"data":{"value":"Test sponsor"}}],"link":{"url":"http://example.com/click/url"},"eventtrackers":[{"event":1,"method":1,"url":"http://example.com/impression"}]}', - adomain: [ - 'example.com' - ], - cid: '3487171', - crid: '28023739', - cat: [ - 'IAB10-2' - ] - } - ], - seat: 'acc-5537' - } - ], - bidid: '82822cf5-259c-11eb-8a52-b48e7518c657', - cur: 'USD' - }, - } - const request = { - bids: [ - { - ...commonBidRequest, - ...nativeBidRequestParams, - } - ] - } - const expectedRes = [ - { - requestId: request.bids[0].bidId, - cpm: 1.1, - creativeId: '28023739', - ttl: 360, - netRevenue: false, - currency: 'USD', - mediaType: 'native', - nurl: 'http://example.com/win/${AUCTION_PRICE}', - meta: { - 'advertiserDomains': [ - 'example.com' - ] - }, - native: { - clickTrackers: undefined, - clickUrl: 'http://example.com/click/url', - image: { - url: 'http://example.com/img/url', - width: 120, - height: 100 - }, - title: 'Test title', - sponsoredBy: 'Test sponsor', - impressionTrackers: [ - 'http://example.com/impression', - ] - } - } - ] - - const res = spec.interpretResponse(serverResponse, request) - expect(res).to.deep.equal(expectedRes) - }); - - it('should interpret display response', function () { - const serverResponse = { - body: { - id: '6b2eedc8-8ff5-46ef-adcf-e701b508943e', - seatbid: [ - { - bid: [ - { - id: 'd90fe7fa-28d7-11eb-8ce4-462a842a7cf9', - impid: '1', - price: 1.1, - nurl: 'http://example.com/win/${AUCTION_PRICE}', - adm: '
ad
', - adomain: [ - 'example.com' - ], - cid: '3865084', - crid: '29998660', - cat: [ - 'IAB10-2' - ], - w: 300, - h: 250 - } - ], - seat: 'acc-6536' - } - ], - bidid: 'd90fe7fa-28d7-11eb-8ce4-13d94bfa26f9', - cur: 'USD' - } - } - const request = { - bids: [ - { - ...commonBidRequest, - ...displayBidRequestParams - } - ] - } - const expectedRes = [ - { - requestId: request.bids[0].bidId, - cpm: 1.1, - creativeId: '29998660', - ttl: 360, - netRevenue: false, - currency: 'USD', - mediaType: 'banner', - nurl: 'http://example.com/win/${AUCTION_PRICE}', - ad: '
ad
', - width: 300, - height: 250, - meta: { - 'advertiserDomains': [ - 'example.com' - ] - }, - } - ] - - const res = spec.interpretResponse(serverResponse, request) - expect(res).to.deep.equal(expectedRes) - }); - }) - }) - - describe('getUserSyncs', function () { - const usersyncUrl = 'https://usersync-url.com'; - beforeEach(() => { - config.setConfig({ - zemanta: { - usersyncUrl: usersyncUrl, - } - } - ) - }) - after(() => { - config.resetConfig() - }) - - it('should return user sync if pixel enabled', function () { - const ret = spec.getUserSyncs({pixelEnabled: true}) - expect(ret).to.deep.equal([{type: 'image', url: 'https://usersync-url.com'}]) - }) - it('should return user sync if pixel enabled with outbrain config', function () { - config.resetConfig() - config.setConfig({ - outbrain: { - usersyncUrl: 'https://usersync-url.com', - } - }) - const ret = spec.getUserSyncs({pixelEnabled: true}) - expect(ret).to.deep.equal([{type: 'image', url: 'https://usersync-url.com'}]) - }) - - it('should not return user sync if pixel disabled', function () { - 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}) - expect(ret).to.be.an('array').that.is.empty - }) - - it('should pass GDPR consent', function() { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {gdprApplies: true, consentString: 'foo'}, undefined)).to.deep.equal([{ - type: 'image', url: `${usersyncUrl}&gdpr=1&gdpr_consent=foo` - }]); - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {gdprApplies: false, consentString: 'foo'}, undefined)).to.deep.equal([{ - type: 'image', url: `${usersyncUrl}&gdpr=0&gdpr_consent=foo` - }]); - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {gdprApplies: true, consentString: undefined}, undefined)).to.deep.equal([{ - type: 'image', url: `${usersyncUrl}&gdpr=1&gdpr_consent=` - }]); - }); - - it('should pass US consent', function() { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, undefined, '1NYN')).to.deep.equal([{ - type: 'image', url: `${usersyncUrl}&us_privacy=1NYN` - }]); - }); - - it('should pass GDPR and US consent', function() { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {gdprApplies: true, consentString: 'foo'}, '1NYN')).to.deep.equal([{ - type: 'image', url: `${usersyncUrl}&gdpr=1&gdpr_consent=foo&us_privacy=1NYN` - }]); - }); - }) - - describe('onBidWon', function () { - it('should make an ajax call with the original cpm', function () { - const bid = { - nurl: 'http://example.com/win/${AUCTION_PRICE}', - cpm: 2.1, - originalCpm: 1.1, - } - spec.onBidWon(bid) - expect(server.requests[0].url).to.equals('http://example.com/win/1.1') - }); - }) -}) diff --git a/test/spec/modules/zeotapIdPlusIdSystem_spec.js b/test/spec/modules/zeotapIdPlusIdSystem_spec.js deleted file mode 100644 index 9de6fa843bc..00000000000 --- a/test/spec/modules/zeotapIdPlusIdSystem_spec.js +++ /dev/null @@ -1,195 +0,0 @@ -import { expect } from 'chai'; -import find from 'core-js-pure/features/array/find.js'; -import { config } from 'src/config.js'; -import { init, requestBidsHook, setSubmoduleRegistry } from 'modules/userId/index.js'; -import { storage, getStorage, zeotapIdPlusSubmodule } from 'modules/zeotapIdPlusIdSystem.js'; -import * as storageManager from 'src/storageManager.js'; - -const ZEOTAP_COOKIE_NAME = 'IDP'; -const ZEOTAP_COOKIE = 'THIS-IS-A-DUMMY-COOKIE'; -const ENCODED_ZEOTAP_COOKIE = btoa(JSON.stringify(ZEOTAP_COOKIE)); - -function getConfigMock() { - return { - userSync: { - syncDelay: 0, - userIds: [{ - name: 'zeotapIdPlus' - }] - } - } -} - -function getAdUnitMock(code = 'adUnit-code') { - return { - code, - mediaTypes: {banner: {}, native: {}}, - sizes: [ - [300, 200], - [300, 600] - ], - bids: [{ - bidder: 'sampleBidder', - params: { placementId: 'banner-only-bidder' } - }] - }; -} - -function unsetCookie() { - storage.setCookie(ZEOTAP_COOKIE_NAME, ''); -} - -function unsetLocalStorage() { - storage.setDataInLocalStorage(ZEOTAP_COOKIE_NAME, ''); -} - -describe('Zeotap ID System', function() { - describe('Zeotap Module invokes StorageManager with appropriate arguments', function() { - let getStorageManagerSpy; - - beforeEach(function() { - getStorageManagerSpy = sinon.spy(storageManager, 'getStorageManager'); - }); - - it('when a stored Zeotap ID exists it is added to bids', function() { - let store = getStorage(); - expect(getStorageManagerSpy.calledOnce).to.be.true; - sinon.assert.calledWith(getStorageManagerSpy, 301, 'zeotapIdPlus'); - }); - }); - - describe('test method: getId calls storage methods to fetch ID', function() { - let cookiesAreEnabledStub; - let getCookieStub; - let localStorageIsEnabledStub; - let getDataFromLocalStorageStub; - - beforeEach(() => { - cookiesAreEnabledStub = sinon.stub(storage, 'cookiesAreEnabled'); - getCookieStub = sinon.stub(storage, 'getCookie'); - localStorageIsEnabledStub = sinon.stub(storage, 'localStorageIsEnabled'); - getDataFromLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage'); - }); - - afterEach(() => { - storage.cookiesAreEnabled.restore(); - storage.getCookie.restore(); - storage.localStorageIsEnabled.restore(); - storage.getDataFromLocalStorage.restore(); - unsetCookie(); - unsetLocalStorage(); - }); - - it('should check if cookies are enabled', function() { - let id = zeotapIdPlusSubmodule.getId(); - expect(cookiesAreEnabledStub.calledOnce).to.be.true; - }); - - it('should call getCookie if cookies are enabled', function() { - cookiesAreEnabledStub.returns(true); - let id = zeotapIdPlusSubmodule.getId(); - expect(cookiesAreEnabledStub.calledOnce).to.be.true; - expect(getCookieStub.calledOnce).to.be.true; - sinon.assert.calledWith(getCookieStub, 'IDP'); - }); - - it('should check for localStorage if cookies are disabled', function() { - cookiesAreEnabledStub.returns(false); - localStorageIsEnabledStub.returns(true) - let id = zeotapIdPlusSubmodule.getId(); - expect(cookiesAreEnabledStub.calledOnce).to.be.true; - expect(getCookieStub.called).to.be.false; - expect(localStorageIsEnabledStub.calledOnce).to.be.true; - expect(getDataFromLocalStorageStub.calledOnce).to.be.true; - sinon.assert.calledWith(getDataFromLocalStorageStub, 'IDP'); - }); - }); - - describe('test method: getId', function() { - afterEach(() => { - unsetCookie(); - unsetLocalStorage(); - }); - - it('provides the stored Zeotap id if a cookie exists', function() { - storage.setCookie(ZEOTAP_COOKIE_NAME, ENCODED_ZEOTAP_COOKIE); - let id = zeotapIdPlusSubmodule.getId(); - expect(id).to.deep.equal({ - id: ENCODED_ZEOTAP_COOKIE - }); - }); - - it('provides the stored Zeotap id if cookie is absent but present in local storage', function() { - storage.setDataInLocalStorage(ZEOTAP_COOKIE_NAME, ENCODED_ZEOTAP_COOKIE); - let id = zeotapIdPlusSubmodule.getId(); - expect(id).to.deep.equal({ - id: ENCODED_ZEOTAP_COOKIE - }); - }); - - it('returns undefined if both cookie and local storage are empty', function() { - let id = zeotapIdPlusSubmodule.getId(); - expect(id).to.be.undefined - }) - }); - - describe('test method: decode', function() { - it('provides the Zeotap ID (IDP) from a stored object', function() { - let zeotapId = { - id: ENCODED_ZEOTAP_COOKIE, - }; - - expect(zeotapIdPlusSubmodule.decode(zeotapId)).to.deep.equal({ - IDP: ZEOTAP_COOKIE - }); - }); - - it('provides the Zeotap ID (IDP) from a stored string', function() { - let zeotapId = ENCODED_ZEOTAP_COOKIE; - - expect(zeotapIdPlusSubmodule.decode(zeotapId)).to.deep.equal({ - IDP: ZEOTAP_COOKIE - }); - }); - }); - - describe('requestBids hook', function() { - let adUnits; - - beforeEach(function() { - adUnits = [getAdUnitMock()]; - storage.setCookie( - ZEOTAP_COOKIE_NAME, - ENCODED_ZEOTAP_COOKIE - ); - setSubmoduleRegistry([zeotapIdPlusSubmodule]); - init(config); - config.setConfig(getConfigMock()); - }); - - afterEach(function() { - unsetCookie(); - unsetLocalStorage(); - }); - - it('when a stored Zeotap ID exists it is added to bids', function(done) { - requestBidsHook(function() { - adUnits.forEach(unit => { - unit.bids.forEach(bid => { - expect(bid).to.have.deep.nested.property('userId.IDP'); - expect(bid.userId.IDP).to.equal(ZEOTAP_COOKIE); - const zeotapIdAsEid = find(bid.userIdAsEids, e => e.source == 'zeotap.com'); - expect(zeotapIdAsEid).to.deep.equal({ - source: 'zeotap.com', - uids: [{ - id: ZEOTAP_COOKIE, - atype: 1, - }] - }); - }); - }); - done(); - }, { adUnits }); - }); - }); -}); diff --git a/test/spec/modules/zetaBidAdapter_spec.js b/test/spec/modules/zetaBidAdapter_spec.js deleted file mode 100644 index ccdd5f43cb0..00000000000 --- a/test/spec/modules/zetaBidAdapter_spec.js +++ /dev/null @@ -1,84 +0,0 @@ -import { spec } from '../../../modules/zetaBidAdapter.js' - -describe('Zeta Bid Adapter', function() { - const bannerRequest = [{ - bidId: 12345, - auctionId: 67890, - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - refererInfo: { - referer: 'testprebid.com' - }, - params: { - placement: 12345, - user: { - uid: 12345, - buyeruid: 12345 - }, - device: { - ip: '111.222.33.44', - geo: { - country: 'USA' - } - }, - definerId: '0', - test: 1 - } - }]; - - it('Test the bid validation function', function() { - const validBid = spec.isBidRequestValid(bannerRequest[0]); - const invalidBid = spec.isBidRequestValid(null); - - expect(validBid).to.be.true; - expect(invalidBid).to.be.false; - }); - - it('Test the request processing function', function () { - const request = spec.buildRequests(bannerRequest, bannerRequest[0]); - expect(request).to.not.be.empty; - - const payload = request.data; - expect(payload).to.not.be.empty; - }); - - const responseBody = { - id: '12345', - seatbid: [ - { - bid: [ - { - id: 'auctionId', - impid: 'impId', - price: 0.0, - adm: 'adMarkup', - crid: 'creativeId', - h: 250, - w: 300 - } - ] - } - ], - cur: 'USD' - }; - - it('Test the response parsing function', function () { - const receivedBid = responseBody.seatbid[0].bid[0]; - const response = {}; - response.body = responseBody; - - const bidResponse = spec.interpretResponse(response, null); - expect(bidResponse).to.not.be.empty; - - const bid = bidResponse[0]; - expect(bid).to.not.be.empty; - expect(bid.ad).to.equal(receivedBid.adm); - expect(bid.cpm).to.equal(receivedBid.price); - expect(bid.height).to.equal(receivedBid.h); - expect(bid.width).to.equal(receivedBid.w); - expect(bid.requestId).to.equal(receivedBid.impid); - }); -}); diff --git a/test/spec/modules/zetaSspBidAdapter_spec.js b/test/spec/modules/zetaSspBidAdapter_spec.js deleted file mode 100644 index bdfc64c3234..00000000000 --- a/test/spec/modules/zetaSspBidAdapter_spec.js +++ /dev/null @@ -1,85 +0,0 @@ -import { spec } from '../../../modules/zetaSspBidAdapter.js' - -describe('Zeta Ssp Bid Adapter', function() { - const bannerRequest = [{ - bidId: 12345, - auctionId: 67890, - mediaTypes: { - banner: { - sizes: [[300, 250]], - } - }, - refererInfo: { - referer: 'zetaglobal.com' - }, - params: { - placement: 12345, - user: { - uid: 12345, - buyeruid: 12345 - }, - tags: { - someTag: 123, - sid: 'publisherId' - }, - test: 1 - } - }]; - - it('Test the bid validation function', function() { - const validBid = spec.isBidRequestValid(bannerRequest[0]); - const invalidBid = spec.isBidRequestValid(null); - - expect(validBid).to.be.true; - expect(invalidBid).to.be.false; - }); - - it('Test the request processing function', function () { - const request = spec.buildRequests(bannerRequest, bannerRequest[0]); - expect(request).to.not.be.empty; - - const payload = request.data; - expect(payload).to.not.be.empty; - }); - - const responseBody = { - id: '12345', - seatbid: [ - { - bid: [ - { - id: 'auctionId', - impid: 'impId', - price: 0.0, - adm: 'adMarkup', - crid: 'creativeId', - adomain: [ - 'https://example.com' - ], - h: 250, - w: 300 - } - ] - } - ], - cur: 'USD' - }; - - it('Test the response parsing function', function () { - const receivedBid = responseBody.seatbid[0].bid[0]; - const response = {}; - response.body = responseBody; - - const bidResponse = spec.interpretResponse(response, null); - expect(bidResponse).to.not.be.empty; - - const bid = bidResponse[0]; - expect(bid).to.not.be.empty; - expect(bid.ad).to.equal(receivedBid.adm); - expect(bid.cpm).to.equal(receivedBid.price); - expect(bid.height).to.equal(receivedBid.h); - expect(bid.width).to.equal(receivedBid.w); - expect(bid.requestId).to.equal(receivedBid.impid); - expect(bid.meta.advertiserDomains).to.equal(receivedBid.adomain); - }); -}); diff --git a/test/spec/native_spec.js b/test/spec/native_spec.js deleted file mode 100644 index 0ffef30965b..00000000000 --- a/test/spec/native_spec.js +++ /dev/null @@ -1,482 +0,0 @@ -import { expect } from 'chai'; -import { fireNativeTrackers, getNativeTargeting, nativeBidIsValid, getAssetMessage, getAllAssetsMessage } from 'src/native.js'; -import CONSTANTS from 'src/constants.json'; -const utils = require('src/utils'); - -const bid = { - adId: '123', - native: { - title: 'Native Creative', - body: 'Cool description great stuff', - cta: 'Do it', - image: { - url: 'http://cdn.example.com/p/creative-image/image.png', - height: 83, - width: 127 - }, - icon: { - url: 'http://cdn.example.com/p/creative-image/icon.jpg', - height: 742, - width: 989 - }, - sponsoredBy: 'AppNexus', - clickUrl: 'https://www.link.example', - clickTrackers: ['https://tracker.example'], - impressionTrackers: ['https://impression.example'], - javascriptTrackers: '', - ext: { - foo: 'foo-value', - baz: 'baz-value' - } - } -}; - -const bidWithUndefinedFields = { - native: { - title: 'Native Creative', - body: undefined, - cta: undefined, - sponsoredBy: 'AppNexus', - clickUrl: 'https://www.link.example', - clickTrackers: ['https://tracker.example'], - impressionTrackers: ['https://impression.example'], - javascriptTrackers: '', - ext: { - foo: 'foo-value', - baz: undefined - } - } -}; - -describe('native.js', function () { - let triggerPixelStub; - let insertHtmlIntoIframeStub; - - beforeEach(function () { - triggerPixelStub = sinon.stub(utils, 'triggerPixel'); - insertHtmlIntoIframeStub = sinon.stub(utils, 'insertHtmlIntoIframe'); - }); - - afterEach(function () { - utils.triggerPixel.restore(); - utils.insertHtmlIntoIframe.restore(); - }); - - it('gets native targeting keys', function () { - const targeting = getNativeTargeting(bid); - expect(targeting[CONSTANTS.NATIVE_KEYS.title]).to.equal(bid.native.title); - expect(targeting[CONSTANTS.NATIVE_KEYS.body]).to.equal(bid.native.body); - expect(targeting[CONSTANTS.NATIVE_KEYS.clickUrl]).to.equal(bid.native.clickUrl); - expect(targeting.hb_native_foo).to.equal(bid.native.foo); - }); - - it('sends placeholders for configured assets', function () { - const bidRequest = { - nativeParams: { - body: { sendId: true }, - clickUrl: { sendId: true }, - ext: { - foo: { - sendId: false - }, - baz: { - sendId: true - } - } - } - }; - const targeting = getNativeTargeting(bid, bidRequest); - - expect(targeting[CONSTANTS.NATIVE_KEYS.title]).to.equal(bid.native.title); - expect(targeting[CONSTANTS.NATIVE_KEYS.body]).to.equal('hb_native_body:123'); - expect(targeting[CONSTANTS.NATIVE_KEYS.clickUrl]).to.equal('hb_native_linkurl:123'); - expect(targeting.hb_native_foo).to.equal(bid.native.ext.foo); - expect(targeting.hb_native_baz).to.equal('hb_native_baz:123'); - }); - - it('should only include native targeting keys with values', function () { - const bidRequest = { - nativeParams: { - body: { sendId: true }, - clickUrl: { sendId: true }, - ext: { - foo: { - required: false - }, - baz: { - required: false - } - } - } - }; - - const targeting = getNativeTargeting(bidWithUndefinedFields, bidRequest); - - expect(Object.keys(targeting)).to.deep.equal([ - CONSTANTS.NATIVE_KEYS.title, - CONSTANTS.NATIVE_KEYS.sponsoredBy, - CONSTANTS.NATIVE_KEYS.clickUrl, - 'hb_native_foo' - ]); - }); - - it('should only include targeting that has sendTargetingKeys set to true', function () { - const bidRequest = { - nativeParams: { - image: { - required: true, - sizes: [150, 50] - }, - title: { - required: true, - len: 80, - sendTargetingKeys: true - }, - sendTargetingKeys: false, - } - - }; - const targeting = getNativeTargeting(bid, bidRequest); - - expect(Object.keys(targeting)).to.deep.equal([ - CONSTANTS.NATIVE_KEYS.title - ]); - }); - - it('should only include targeting if sendTargetingKeys not set to false', function () { - const bidRequest = { - nativeParams: { - image: { - required: true, - sizes: [150, 50] - }, - title: { - required: true, - len: 80 - }, - body: { - required: true - }, - clickUrl: { - required: true - }, - icon: { - required: false, - sendTargetingKeys: false - }, - cta: { - required: false, - sendTargetingKeys: false - }, - sponsoredBy: { - required: false, - sendTargetingKeys: false - }, - ext: { - foo: { - required: false, - sendTargetingKeys: true - } - } - } - - }; - const targeting = getNativeTargeting(bid, bidRequest); - - expect(Object.keys(targeting)).to.deep.equal([ - CONSTANTS.NATIVE_KEYS.title, - CONSTANTS.NATIVE_KEYS.body, - CONSTANTS.NATIVE_KEYS.image, - CONSTANTS.NATIVE_KEYS.clickUrl, - 'hb_native_foo' - ]); - }); - - it('should copy over rendererUrl to bid object and include it in targeting', function () { - const bidRequest = { - nativeParams: { - image: { - required: true, - sizes: [150, 50] - }, - title: { - required: true, - len: 80, - }, - rendererUrl: { - url: 'https://www.renderer.com/' - } - } - - }; - const targeting = getNativeTargeting(bid, bidRequest); - - expect(Object.keys(targeting)).to.deep.equal([ - CONSTANTS.NATIVE_KEYS.title, - CONSTANTS.NATIVE_KEYS.body, - CONSTANTS.NATIVE_KEYS.cta, - CONSTANTS.NATIVE_KEYS.image, - CONSTANTS.NATIVE_KEYS.icon, - CONSTANTS.NATIVE_KEYS.sponsoredBy, - CONSTANTS.NATIVE_KEYS.clickUrl, - CONSTANTS.NATIVE_KEYS.rendererUrl - ]); - - expect(bid.native.rendererUrl).to.deep.equal('https://www.renderer.com/'); - delete bid.native.rendererUrl; - }); - - it('should copy over adTemplate to bid object and include it in targeting', function () { - const bidRequest = { - nativeParams: { - image: { - required: true, - sizes: [150, 50] - }, - title: { - required: true, - len: 80, - }, - adTemplate: '

##hb_native_body##<\/p><\/div>' - } - - }; - const targeting = getNativeTargeting(bid, bidRequest); - - expect(Object.keys(targeting)).to.deep.equal([ - CONSTANTS.NATIVE_KEYS.title, - CONSTANTS.NATIVE_KEYS.body, - CONSTANTS.NATIVE_KEYS.cta, - CONSTANTS.NATIVE_KEYS.image, - CONSTANTS.NATIVE_KEYS.icon, - CONSTANTS.NATIVE_KEYS.sponsoredBy, - CONSTANTS.NATIVE_KEYS.clickUrl - ]); - - expect(bid.native.adTemplate).to.deep.equal('

##hb_native_body##<\/p><\/div>'); - delete bid.native.adTemplate; - }); - - it('fires impression trackers', function () { - fireNativeTrackers({}, bid); - sinon.assert.calledOnce(triggerPixelStub); - sinon.assert.calledWith(triggerPixelStub, bid.native.impressionTrackers[0]); - sinon.assert.calledWith(insertHtmlIntoIframeStub, bid.native.javascriptTrackers); - }); - - it('fires click trackers', function () { - const trackerType = fireNativeTrackers({ action: 'click' }, bid); - expect(trackerType).to.equal('click'); - sinon.assert.calledOnce(triggerPixelStub); - sinon.assert.calledWith(triggerPixelStub, bid.native.clickTrackers[0]); - }); - - it('creates native asset message', function() { - const messageRequest = { - message: 'Prebid Native', - action: 'assetRequest', - adId: '123', - assets: ['hb_native_body', 'hb_native_image', 'hb_native_linkurl'], - }; - - const message = getAssetMessage(messageRequest, bid); - - expect(message.assets.length).to.equal(3); - expect(message.assets).to.deep.include({ - key: 'body', - value: bid.native.body - }); - expect(message.assets).to.deep.include({ - key: 'image', - value: bid.native.image.url - }); - expect(message.assets).to.deep.include({ - key: 'clickUrl', - value: bid.native.clickUrl - }); - }); - - it('creates native all asset message', function() { - const messageRequest = { - message: 'Prebid Native', - action: 'allAssetRequest', - adId: '123', - }; - - const message = getAllAssetsMessage(messageRequest, bid); - - expect(message.assets.length).to.equal(9); - expect(message.assets).to.deep.include({ - key: 'body', - value: bid.native.body - }); - expect(message.assets).to.deep.include({ - key: 'image', - value: bid.native.image.url - }); - expect(message.assets).to.deep.include({ - key: 'clickUrl', - value: bid.native.clickUrl - }); - expect(message.assets).to.deep.include({ - key: 'title', - value: bid.native.title - }); - expect(message.assets).to.deep.include({ - key: 'icon', - value: bid.native.icon.url - }); - expect(message.assets).to.deep.include({ - key: 'cta', - value: bid.native.cta - }); - expect(message.assets).to.deep.include({ - key: 'sponsoredBy', - value: bid.native.sponsoredBy - }); - expect(message.assets).to.deep.include({ - key: 'foo', - value: bid.native.ext.foo - }); - expect(message.assets).to.deep.include({ - key: 'baz', - value: bid.native.ext.baz - }); - }); - - it('creates native all asset message with only defined fields', function() { - const messageRequest = { - message: 'Prebid Native', - action: 'allAssetRequest', - adId: '123', - }; - - const message = getAllAssetsMessage(messageRequest, bidWithUndefinedFields); - - expect(message.assets.length).to.equal(4); - expect(message.assets).to.deep.include({ - key: 'clickUrl', - value: bid.native.clickUrl - }); - expect(message.assets).to.deep.include({ - key: 'title', - value: bid.native.title - }); - expect(message.assets).to.deep.include({ - key: 'sponsoredBy', - value: bid.native.sponsoredBy - }); - expect(message.assets).to.deep.include({ - key: 'foo', - value: bid.native.ext.foo - }); - }); -}); - -describe('validate native', function () { - let bidReq = [{ - bids: [{ - bidderCode: 'test_bidder', - bidId: 'test_bid_id', - mediaTypes: { - native: { - title: { - required: true, - }, - body: { - required: true, - }, - image: { - required: true, - sizes: [150, 50], - aspect_ratios: [150, 50] - }, - icon: { - required: true, - sizes: [50, 50] - }, - } - } - }] - }]; - - let validBid = { - adId: 'abc123', - requestId: 'test_bid_id', - adUnitCode: '123/prebid_native_adunit', - bidder: 'test_bidder', - native: { - body: 'This is a Prebid Native Creative. There are many like it, but this one is mine.', - clickTrackers: ['http://my.click.tracker/url'], - icon: { - url: 'http://my.image.file/ad_image.jpg', - height: 75, - width: 75 - }, - image: { - url: 'http://my.icon.file/ad_icon.jpg', - height: 2250, - width: 3000 - }, - clickUrl: 'http://prebid.org/dev-docs/show-native-ads.html', - impressionTrackers: ['http://my.imp.tracker/url'], - javascriptTrackers: '', - title: 'This is an example Prebid Native creative' - } - }; - - let noIconDimBid = { - adId: 'abc234', - requestId: 'test_bid_id', - adUnitCode: '123/prebid_native_adunit', - bidder: 'test_bidder', - native: { - body: 'This is a Prebid Native Creative. There are many like it, but this one is mine.', - clickTrackers: ['http://my.click.tracker/url'], - icon: 'http://my.image.file/ad_image.jpg', - image: { - url: 'http://my.icon.file/ad_icon.jpg', - height: 2250, - width: 3000 - }, - clickUrl: 'http://prebid.org/dev-docs/show-native-ads.html', - impressionTrackers: ['http://my.imp.tracker/url'], - javascriptTrackers: '', - title: 'This is an example Prebid Native creative' - } - }; - - let noImgDimBid = { - adId: 'abc345', - requestId: 'test_bid_id', - adUnitCode: '123/prebid_native_adunit', - bidder: 'test_bidder', - native: { - body: 'This is a Prebid Native Creative. There are many like it, but this one is mine.', - clickTrackers: ['http://my.click.tracker/url'], - icon: { - url: 'http://my.image.file/ad_image.jpg', - height: 75, - width: 75 - }, - image: 'http://my.icon.file/ad_icon.jpg', - clickUrl: 'http://prebid.org/dev-docs/show-native-ads.html', - impressionTrackers: ['http://my.imp.tracker/url'], - javascriptTrackers: '', - title: 'This is an example Prebid Native creative' - } - }; - - beforeEach(function () {}); - - afterEach(function () {}); - - it('should accept bid if no image sizes are defined', function () { - let result = nativeBidIsValid(validBid, bidReq); - expect(result).to.be.true; - result = nativeBidIsValid(noIconDimBid, bidReq); - expect(result).to.be.true; - result = nativeBidIsValid(noImgDimBid, bidReq); - expect(result).to.be.true; - }); -}); diff --git a/test/spec/refererDetection_spec.js b/test/spec/refererDetection_spec.js deleted file mode 100644 index 46990ae841f..00000000000 --- a/test/spec/refererDetection_spec.js +++ /dev/null @@ -1,357 +0,0 @@ -import { detectReferer } from 'src/refererDetection.js'; -import { expect } from 'chai'; - -/** - * Build a walkable linked list of window-like objects for testing. - * - * @param {Array} urls Array of URL strings starting from the top window. - * @param {string} [topReferrer] - * @param {string} [canonicalUrl] - * @param {boolean} [ancestorOrigins] - * @returns {Object} - */ -function buildWindowTree(urls, topReferrer = '', canonicalUrl = null, ancestorOrigins = false) { - /** - * Find the origin from a given fully-qualified URL. - * - * @param {string} url The fully qualified URL - * @returns {string|null} - */ - function getOrigin(url) { - const originRegex = new RegExp('^(https?://[^/]+/?)'); - - const result = originRegex.exec(url); - - if (result && result[0]) { - return result[0]; - } - - return null; - } - - let previousWindow; - const myOrigin = getOrigin(urls[urls.length - 1]); - - const windowList = urls.map((url, index) => { - const theirOrigin = getOrigin(url), - sameOrigin = (myOrigin === theirOrigin); - - const win = {}; - - if (sameOrigin) { - win.location = { - href: url - }; - - if (ancestorOrigins) { - win.location.ancestorOrigins = urls.slice(0, index).reverse().map(getOrigin); - } - - if (index === 0) { - win.document = { - referrer: topReferrer - }; - - if (canonicalUrl) { - win.document.querySelector = function(selector) { - if (selector === "link[rel='canonical']") { - return { - href: canonicalUrl - }; - } - - return null; - }; - } - } else { - win.document = { - referrer: urls[index - 1] - }; - } - } - - previousWindow = win; - - return win; - }); - - const topWindow = windowList[0]; - - previousWindow = null; - - windowList.forEach((win) => { - win.top = topWindow; - win.parent = previousWindow || topWindow; - previousWindow = win; - }); - - return windowList[windowList.length - 1]; -} - -describe('Referer detection', () => { - describe('Non cross-origin scenarios', () => { - describe('No iframes', () => { - it('Should return the current window location and no canonical URL', () => { - const testWindow = buildWindowTree(['https://example.com/some/page'], 'https://othersite.com/'), - result = detectReferer(testWindow)(); - - expect(result).to.deep.equal({ - referer: 'https://example.com/some/page', - reachedTop: true, - isAmp: false, - numIframes: 0, - stack: ['https://example.com/some/page'], - canonicalUrl: null - }); - }); - - it('Should return the current window location and a canonical URL', () => { - const testWindow = buildWindowTree(['https://example.com/some/page'], 'https://othersite.com/', 'https://example.com/canonical/page'), - result = detectReferer(testWindow)(); - - expect(result).to.deep.equal({ - referer: 'https://example.com/some/page', - reachedTop: true, - isAmp: false, - numIframes: 0, - stack: ['https://example.com/some/page'], - canonicalUrl: 'https://example.com/canonical/page' - }); - }); - }); - - describe('Friendly iframes', () => { - it('Should return the top window location and no canonical URL', () => { - const testWindow = buildWindowTree(['https://example.com/some/page', 'https://example.com/other/page', 'https://example.com/third/page'], 'https://othersite.com/'), - result = detectReferer(testWindow)(); - - expect(result).to.deep.equal({ - referer: 'https://example.com/some/page', - reachedTop: true, - isAmp: false, - numIframes: 2, - stack: [ - 'https://example.com/some/page', - 'https://example.com/other/page', - 'https://example.com/third/page' - ], - canonicalUrl: null - }); - }); - - it('Should return the top window location and a canonical URL', () => { - const testWindow = buildWindowTree(['https://example.com/some/page', 'https://example.com/other/page', 'https://example.com/third/page'], 'https://othersite.com/', 'https://example.com/canonical/page'), - result = detectReferer(testWindow)(); - - expect(result).to.deep.equal({ - referer: 'https://example.com/some/page', - reachedTop: true, - isAmp: false, - numIframes: 2, - stack: [ - 'https://example.com/some/page', - 'https://example.com/other/page', - 'https://example.com/third/page' - ], - canonicalUrl: 'https://example.com/canonical/page' - }); - }); - }); - }); - - describe('Cross-origin scenarios', () => { - it('Should return the top URL and no canonical URL with one cross-origin iframe', () => { - const testWindow = buildWindowTree(['https://example.com/some/page', 'https://safe.frame/ad'], 'https://othersite.com/', 'https://canonical.example.com/'), - result = detectReferer(testWindow)(); - - expect(result).to.deep.equal({ - referer: 'https://example.com/some/page', - reachedTop: true, - isAmp: false, - numIframes: 1, - stack: [ - 'https://example.com/some/page', - 'https://safe.frame/ad' - ], - canonicalUrl: null - }); - }); - - it('Should return the top URL and no canonical URL with one cross-origin iframe and one friendly iframe', () => { - const testWindow = buildWindowTree(['https://example.com/some/page', 'https://safe.frame/ad', 'https://safe.frame/ad'], 'https://othersite.com/', 'https://canonical.example.com/'), - result = detectReferer(testWindow)(); - - expect(result).to.deep.equal({ - referer: 'https://example.com/some/page', - reachedTop: true, - isAmp: false, - numIframes: 2, - stack: [ - 'https://example.com/some/page', - 'https://safe.frame/ad', - 'https://safe.frame/ad' - ], - canonicalUrl: null - }); - }); - - it('Should return the second iframe location with three cross-origin windows and no ancessorOrigins', () => { - const testWindow = buildWindowTree(['https://example.com/some/page', 'https://safe.frame/ad', 'https://otherfr.ame/ad'], 'https://othersite.com/', 'https://canonical.example.com/'), - result = detectReferer(testWindow)(); - - expect(result).to.deep.equal({ - referer: 'https://safe.frame/ad', - reachedTop: false, - isAmp: false, - numIframes: 2, - stack: [ - null, - 'https://safe.frame/ad', - 'https://otherfr.ame/ad' - ], - canonicalUrl: null - }); - }); - - it('Should return the top window origin with three cross-origin windows with ancessorOrigins', () => { - const testWindow = buildWindowTree(['https://example.com/some/page', 'https://safe.frame/ad', 'https://otherfr.ame/ad'], 'https://othersite.com/', 'https://canonical.example.com/', true), - result = detectReferer(testWindow)(); - - expect(result).to.deep.equal({ - referer: 'https://example.com/', - reachedTop: false, - isAmp: false, - numIframes: 2, - stack: [ - 'https://example.com/', - 'https://safe.frame/ad', - 'https://otherfr.ame/ad' - ], - canonicalUrl: null - }); - }); - }); - - describe('Cross-origin AMP page scenarios', () => { - it('Should return the AMP page source and canonical URLs in an amp-ad iframe for a non-cached AMP page', () => { - const testWindow = buildWindowTree(['https://example.com/some/page/amp/', 'https://ad-iframe.ampproject.org/ad']); - - testWindow.context = { - sourceUrl: 'https://example.com/some/page/amp/', - canonicalUrl: 'https://example.com/some/page/' - }; - - const result = detectReferer(testWindow)(); - - expect(result).to.deep.equal({ - referer: 'https://example.com/some/page/amp/', - reachedTop: true, - isAmp: true, - numIframes: 1, - stack: [ - 'https://example.com/some/page/amp/', - 'https://ad-iframe.ampproject.org/ad' - ], - canonicalUrl: 'https://example.com/some/page/' - }); - }); - - it('Should return the AMP page source and canonical URLs in an amp-ad iframe for a cached AMP page on top', () => { - const testWindow = buildWindowTree(['https://example-com.amp-cache.example.com/some/page/amp/', 'https://ad-iframe.ampproject.org/ad']); - - testWindow.context = { - sourceUrl: 'https://example.com/some/page/amp/', - canonicalUrl: 'https://example.com/some/page/' - }; - - const result = detectReferer(testWindow)(); - - expect(result).to.deep.equal({ - referer: 'https://example.com/some/page/amp/', - reachedTop: true, - isAmp: true, - numIframes: 1, - stack: [ - 'https://example.com/some/page/amp/', - 'https://ad-iframe.ampproject.org/ad' - ], - canonicalUrl: 'https://example.com/some/page/' - }); - }); - - describe('Cached AMP page in iframed search result', () => { - it('Should return the AMP source and canonical URLs but with a null top-level stack location Without ancesorOrigins', () => { - const testWindow = buildWindowTree(['https://google.com/amp/example-com/some/page/amp/', 'https://example-com.amp-cache.example.com/some/page/amp/', 'https://ad-iframe.ampproject.org/ad']); - - testWindow.context = { - sourceUrl: 'https://example.com/some/page/amp/', - canonicalUrl: 'https://example.com/some/page/' - }; - - const result = detectReferer(testWindow)(); - - expect(result).to.deep.equal({ - referer: 'https://example.com/some/page/amp/', - reachedTop: false, - isAmp: true, - numIframes: 2, - stack: [ - null, - 'https://example.com/some/page/amp/', - 'https://ad-iframe.ampproject.org/ad' - ], - canonicalUrl: 'https://example.com/some/page/' - }); - }); - - it('Should return the AMP source and canonical URLs and include the top window origin in the stack with ancesorOrigins', () => { - const testWindow = buildWindowTree(['https://google.com/amp/example-com/some/page/amp/', 'https://example-com.amp-cache.example.com/some/page/amp/', 'https://ad-iframe.ampproject.org/ad'], null, null, true); - - testWindow.context = { - sourceUrl: 'https://example.com/some/page/amp/', - canonicalUrl: 'https://example.com/some/page/' - }; - - const result = detectReferer(testWindow)(); - - expect(result).to.deep.equal({ - referer: 'https://example.com/some/page/amp/', - reachedTop: false, - isAmp: true, - numIframes: 2, - stack: [ - 'https://google.com/', - 'https://example.com/some/page/amp/', - 'https://ad-iframe.ampproject.org/ad' - ], - canonicalUrl: 'https://example.com/some/page/' - }); - }); - - it('Should return the AMP source and canonical URLs and include the top window origin in the stack with ancesorOrigins and a friendly iframe under the amp-ad iframe', () => { - const testWindow = buildWindowTree(['https://google.com/amp/example-com/some/page/amp/', 'https://example-com.amp-cache.example.com/some/page/amp/', 'https://ad-iframe.ampproject.org/ad', 'https://ad-iframe.ampproject.org/ad'], null, null, true); - - testWindow.parent.context = { - sourceUrl: 'https://example.com/some/page/amp/', - canonicalUrl: 'https://example.com/some/page/' - }; - - const result = detectReferer(testWindow)(); - - expect(result).to.deep.equal({ - referer: 'https://example.com/some/page/amp/', - reachedTop: false, - isAmp: true, - numIframes: 3, - stack: [ - 'https://google.com/', - 'https://example.com/some/page/amp/', - 'https://ad-iframe.ampproject.org/ad', - 'https://ad-iframe.ampproject.org/ad' - ], - canonicalUrl: 'https://example.com/some/page/' - }); - }); - }); - }); -}); diff --git a/test/spec/renderer_spec.js b/test/spec/renderer_spec.js deleted file mode 100644 index dcca94396cd..00000000000 --- a/test/spec/renderer_spec.js +++ /dev/null @@ -1,208 +0,0 @@ -import { expect } from 'chai'; -import { Renderer } from 'src/Renderer.js'; -import * as utils from 'src/utils.js'; -import { loadExternalScript } from 'src/adloader.js'; - -describe('Renderer', function () { - describe('Renderer: A renderer installed on a bid response', function () { - let testRenderer1; - let testRenderer2; - let spyRenderFn; - let spyEventHandler; - - beforeEach(function () { - testRenderer1 = Renderer.install({ - url: 'https://httpbin.org/post', - config: { test: 'config1' }, - id: 1 - }); - testRenderer2 = Renderer.install({ - url: 'https://httpbin.org/post', - config: { test: 'config2' }, - id: 2 - }); - - spyRenderFn = sinon.spy(); - spyEventHandler = sinon.spy(); - }); - - it('is an instance of Renderer', function () { - expect(testRenderer1 instanceof Renderer).to.equal(true); - }); - - it('has expected properties ', function () { - expect(testRenderer1.url).to.equal('https://httpbin.org/post'); - expect(testRenderer1.config).to.deep.equal({ test: 'config1' }); - expect(testRenderer1.id).to.equal(1); - }); - - it('returns config from getConfig method', function () { - expect(testRenderer1.getConfig()).to.deep.equal({ test: 'config1' }); - expect(testRenderer2.getConfig()).to.deep.equal({ test: 'config2' }); - }); - - it('sets a render function with setRender method', function () { - testRenderer1.setRender(spyRenderFn); - expect(typeof testRenderer1.render).to.equal('function'); - testRenderer1.render(); - expect(spyRenderFn.called).to.equal(true); - }); - - it('sets event handlers with setEventHandlers method and handles events with installed handlers', function () { - testRenderer1.setEventHandlers({ - testEvent: spyEventHandler - }); - - expect(testRenderer1.handlers).to.deep.equal({ - testEvent: spyEventHandler - }); - - testRenderer1.handleVideoEvent({ id: 1, eventName: 'testEvent' }); - expect(spyEventHandler.called).to.equal(true); - }); - - it('pushes commands to queue if renderer is not loaded', function () { - testRenderer1.loaded = false; - testRenderer1.push(spyRenderFn); - expect(testRenderer1.cmd.length).to.equal(1); - - // clear queue for next tests - testRenderer1.cmd = []; - }); - - it('fires commands immediately if the renderer is loaded', function () { - const func = sinon.spy(); - - testRenderer1.loaded = true; - testRenderer1.push(func); - - expect(testRenderer1.cmd.length).to.equal(0); - - sinon.assert.calledOnce(func); - }); - - it('processes queue by calling each function in queue', function () { - testRenderer1.loaded = false; - const func1 = sinon.spy(); - const func2 = sinon.spy(); - - testRenderer1.push(func1); - testRenderer1.push(func2); - expect(testRenderer1.cmd.length).to.equal(2); - - testRenderer1.process(); - - sinon.assert.calledOnce(func1); - sinon.assert.calledOnce(func2); - expect(testRenderer1.cmd.length).to.equal(0); - }); - }); - - describe('3rd party renderer', function () { - let adUnitsOld; - let utilsSpy; - before(function () { - adUnitsOld = $$PREBID_GLOBAL$$.adUnits; - utilsSpy = sinon.spy(utils, 'logWarn'); - }); - - after(function() { - $$PREBID_GLOBAL$$.adUnits = adUnitsOld; - utilsSpy.restore(); - }); - - it('should not load renderer and log warn message', function() { - $$PREBID_GLOBAL$$.adUnits = [{ - code: 'video1', - renderer: { - url: 'http://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', - render: sinon.spy() - } - }] - - let testRenderer = Renderer.install({ - url: 'https://httpbin.org/post', - config: { test: 'config1' }, - id: 1, - adUnitCode: 'video1' - }); - testRenderer.setRender(() => {}) - - testRenderer.render() - expect(utilsSpy.callCount).to.equal(1); - }); - - it('should load renderer adunit renderer when backupOnly', function() { - $$PREBID_GLOBAL$$.adUnits = [{ - code: 'video1', - renderer: { - url: 'http://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', - backupOnly: true, - render: sinon.spy() - } - }] - - let testRenderer = Renderer.install({ - url: 'https://httpbin.org/post', - config: { test: 'config1' }, - id: 1, - adUnitCode: 'video1' - - }); - testRenderer.setRender(() => {}) - - testRenderer.render() - expect(loadExternalScript.called).to.be.true; - }); - - it('should load external script instead of publisher-defined one when backupOnly option is true in mediaTypes.video options', function() { - $$PREBID_GLOBAL$$.adUnits = [{ - code: 'video1', - mediaTypes: { - video: { - context: 'outstream', - mimes: ['video/mp4'], - playerSize: [[400, 300]], - renderer: { - url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js', - backupOnly: true, - render: sinon.spy() - }, - } - } - }] - - let testRenderer = Renderer.install({ - url: 'https://httpbin.org/post', - config: { test: 'config1' }, - id: 1, - adUnitCode: 'video1' - - }); - testRenderer.setRender(() => {}) - - testRenderer.render() - expect(loadExternalScript.called).to.be.true; - }); - - it('should call loadExternalScript() for script not defined on adUnit, only when .render() is called', function() { - $$PREBID_GLOBAL$$.adUnits = [{ - code: 'video1', - renderer: { - url: 'http://cdn.adnxs.com/renderer/video/ANOutstreamVideo.js', - render: sinon.spy() - } - }]; - let testRenderer = Renderer.install({ - url: 'https://httpbin.org/post', - config: { test: 'config1' }, - id: 1, - adUnitCode: undefined - }); - expect(loadExternalScript.called).to.be.false; - - testRenderer.render() - expect(loadExternalScript.called).to.be.true; - }); - }); -}); diff --git a/test/spec/sizeMapping_spec.js b/test/spec/sizeMapping_spec.js deleted file mode 100644 index 78dd9797c36..00000000000 --- a/test/spec/sizeMapping_spec.js +++ /dev/null @@ -1,332 +0,0 @@ -import { expect } from 'chai'; -import { resolveStatus, setSizeConfig, sizeSupported } from 'src/sizeMapping.js'; -import includes from 'core-js-pure/features/array/includes.js'; - -let utils = require('src/utils'); -let deepClone = utils.deepClone; - -describe('sizeMapping', function () { - var testSizes = { - banner: { - sizes: [[970, 90], [728, 90], [300, 250], [300, 100], [80, 80]] - } - }; - - var sizeConfig = [{ - 'mediaQuery': '(min-width: 1200px)', - 'sizesSupported': [ - [970, 90], - [728, 90], - [300, 250] - ] - }, { - 'mediaQuery': '(min-width: 768px) and (max-width: 1199px)', - 'sizesSupported': [ - [728, 90], - [300, 250], - [300, 100] - ] - }, { - 'mediaQuery': '(min-width: 0px) and (max-width: 767px)', - 'sizesSupported': [] - }]; - - var sizeConfigWithLabels = [{ - 'mediaQuery': '(min-width: 1200px)', - 'labels': ['desktop'] - }, { - 'mediaQuery': '(min-width: 768px) and (max-width: 1199px)', - 'sizesSupported': [ - [728, 90], - [300, 250] - ], - 'labels': ['tablet', 'phone'] - }, { - 'mediaQuery': '(min-width: 0px) and (max-width: 767px)', - 'sizesSupported': [ - [300, 250], - [300, 100] - ], - 'labels': ['phone'] - }]; - - let sandbox, - matchMediaOverride; - - beforeEach(function () { - setSizeConfig(sizeConfig); - - sandbox = sinon.sandbox.create(); - - matchMediaOverride = {matches: false}; - - sandbox.stub(utils.getWindowTop(), 'matchMedia').callsFake((...args) => { - if (typeof matchMediaOverride === 'function') { - return matchMediaOverride.apply(utils.getWindowTop(), args); - } - return matchMediaOverride; - }); - }); - - afterEach(function () { - setSizeConfig([]); - - sandbox.restore(); - }); - - describe('when handling sizes', function () { - it('should allow us to validate a single size', function() { - matchMediaOverride = (str) => str === '(min-width: 1200px)' ? {matches: true} : {matches: false}; - - expect(sizeSupported([300, 250])).to.equal(true); - expect(sizeSupported([80, 80])).to.equal(false); - }); - - it('should log a warning when mediaQuery property missing from sizeConfig', function () { - let errorConfig = deepClone(sizeConfig); - - delete errorConfig[0].mediaQuery; - - sandbox.stub(utils, 'logWarn'); - - resolveStatus(undefined, testSizes, undefined, errorConfig); - expect(utils.logWarn.firstCall.args[0]).to.match(/missing.+?mediaQuery/); - }); - - it('should allow deprecated adUnit.sizes', function() { - matchMediaOverride = (str) => str === '(min-width: 1200px)' ? {matches: true} : {matches: false}; - - let status = resolveStatus(undefined, undefined, testSizes.banner.sizes, sizeConfig); - - expect(status.active).to.equal(true); - expect(status.mediaTypes).to.deep.equal({ - banner: { - sizes: [[970, 90], [728, 90], [300, 250]] - } - }); - }); - - 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}; - - let status = resolveStatus(undefined, testSizes, undefined, sizeConfig); - - expect(status.active).to.equal(true); - expect(status.mediaTypes).to.deep.equal({ - banner: { - sizes: [[970, 90], [728, 90], [300, 250]] - } - }); - }); - - it('when multiple mediaQuery block matches, it should filter a union of the matched sizesSupported', function () { - matchMediaOverride = (str) => includes([ - '(min-width: 1200px)', - '(min-width: 768px) and (max-width: 1199px)' - ], str) ? {matches: true} : {matches: false}; - - let status = resolveStatus(undefined, testSizes, undefined, sizeConfig); - expect(status.active).to.equal(true); - expect(status.mediaTypes).to.deep.equal({ - banner: { - sizes: [[970, 90], [728, 90], [300, 250], [300, 100]] - } - }); - }); - - it('if no mediaQueries match, it should allow all sizes specified', function () { - matchMediaOverride = () => ({matches: false}); - - let status = resolveStatus(undefined, testSizes, undefined, sizeConfig); - expect(status.active).to.equal(true); - expect(status.mediaTypes).to.deep.equal(testSizes); - }); - - 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}; - - let status = resolveStatus(undefined, testSizes, undefined, sizeConfig); - expect(status.active).to.equal(false); - expect(status.mediaTypes).to.deep.equal({ - banner: { - sizes: [] - } - }); - }); - - 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}; - let status = resolveStatus(undefined, Object.assign({}, testSizes, { - native: { - type: 'image' - } - }), undefined, sizeConfig); - expect(status.active).to.equal(false); - expect(status.mediaTypes).to.deep.equal({ - banner: { - sizes: [] - }, - native: { - type: 'image' - } - }); - }); - - 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}; - - let status = resolveStatus(undefined, testSizes, undefined, sizeConfigWithLabels); - expect(status.active).to.equal(true); - expect(status.mediaTypes).to.deep.equal(testSizes); - }); - }); - - 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}; - - let status = resolveStatus({ - labels: ['desktop'] - }, testSizes, undefined, sizeConfigWithLabels); - - expect(status).to.deep.equal({ - active: true, - mediaTypes: testSizes - }); - - status = resolveStatus({ - labels: ['tablet'] - }, testSizes, undefined, sizeConfigWithLabels); - - expect(status.active).to.equal(false); - expect(status.mediaTypes).to.deep.equal(testSizes); - }); - - 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}; - - let multiFormatSizes = { - banner: { - sizes: [[728, 90], [300, 300]] - }, - native: { - type: 'image' - }, - video: { - context: 'outstream', - playerSize: [300, 300] - } - }; - - let status = resolveStatus({ - labels: ['tablet', 'test'], - labelAll: true - }, multiFormatSizes, undefined, sizeConfigWithLabels); - - expect(status.active).to.equal(false); - expect(status.mediaTypes).to.deep.equal({ - banner: { - sizes: [[728, 90]] - }, - native: { - type: 'image' - }, - video: { - context: 'outstream', - playerSize: [300, 300] - } - }); - - status = resolveStatus({ - labels: ['tablet'] - }, multiFormatSizes, undefined, sizeConfigWithLabels); - - expect(status.active).to.equal(true); - expect(status.mediaTypes).to.deep.equal({ - banner: { - sizes: [[728, 90]] - }, - native: { - type: 'image' - }, - video: { - context: 'outstream', - playerSize: [300, 300] - } - }); - - multiFormatSizes.banner.sizes.splice(0, 1, [728, 80]); - status = resolveStatus({ - labels: ['tablet'] - }, multiFormatSizes, undefined, sizeConfigWithLabels); - - expect(status.active).to.equal(false); - expect(status.mediaTypes).to.deep.equal({ - banner: { - sizes: [] - }, - native: { - type: 'image' - }, - video: { - context: 'outstream', - playerSize: [300, 300] - } - }); - - delete multiFormatSizes.banner; - status = resolveStatus({ - labels: ['tablet'] - }, multiFormatSizes, undefined, sizeConfigWithLabels); - - expect(status.active).to.equal(true); - expect(status.mediaTypes).to.deep.equal({ - native: { - type: 'image' - }, - video: { - context: 'outstream', - playerSize: [300, 300] - } - }); - }); - - it('should active/deactivate adUnits/bidders based on requestBids labels', function () { - let activeLabels = ['us-visitor', 'desktop', 'smart']; - - let status = resolveStatus({ - labels: ['uk-visitor'], // from adunit - activeLabels // from requestBids.labels - }, testSizes, undefined, sizeConfigWithLabels); - - expect(status.active).to.equal(false); - expect(status.mediaTypes).to.deep.equal(testSizes); - - status = resolveStatus({ - labels: ['us-visitor'], - activeLabels - }, testSizes, undefined, sizeConfigWithLabels); - - expect(status.active).to.equal(true); - expect(status.mediaTypes).to.deep.equal(testSizes); - - status = resolveStatus({ - labels: ['us-visitor', 'tablet'], - labelAll: true, - activeLabels - }, testSizes, undefined, sizeConfigWithLabels); - - expect(status.active).to.equal(false); - expect(status.mediaTypes).to.deep.equal(testSizes); - - status = resolveStatus({ - labels: ['us-visitor', 'desktop'], - labelAll: true, - activeLabels - }, testSizes, undefined, sizeConfigWithLabels); - - expect(status.active).to.equal(true); - expect(status.mediaTypes).to.deep.equal(testSizes); - }); - }); -}); diff --git a/test/spec/unit/adServerManager_spec.js b/test/spec/unit/adServerManager_spec.js deleted file mode 100644 index ec58ff7f5b3..00000000000 --- a/test/spec/unit/adServerManager_spec.js +++ /dev/null @@ -1,43 +0,0 @@ -import { expect } from 'chai'; -import { getGlobal } from 'src/prebidGlobal.js'; -import { registerVideoSupport } from 'src/adServerManager.js'; - -const prebid = getGlobal(); - -describe('The ad server manager', function () { - before(function () { - delete prebid.adServers; - }); - - afterEach(function () { - delete prebid.adServers; - }); - - it('should register video support to the proper place on the API', function () { - function videoSupport() { } - registerVideoSupport('dfp', { buildVideoUrl: videoSupport }); - - expect(prebid).to.have.property('adServers'); - expect(prebid.adServers).to.have.property('dfp'); - expect(prebid.adServers.dfp).to.have.property('buildVideoUrl', videoSupport); - }); - - it('should keep the first function when we try to add a second', function () { - function videoSupport() { } - registerVideoSupport('dfp', { buildVideoUrl: videoSupport }); - registerVideoSupport('dfp', { buildVideoUrl: function noop() { } }); - - expect(prebid).to.have.property('adServers'); - expect(prebid.adServers).to.have.property('dfp'); - expect(prebid.adServers.dfp).to.have.property('buildVideoUrl', videoSupport); - }); - - it('should support any custom named property in the public API', function () { - function getTestAdServerTargetingKeys() { }; - registerVideoSupport('testAdServer', { getTargetingKeys: getTestAdServerTargetingKeys }); - - expect(prebid).to.have.property('adServers'); - expect(prebid.adServers).to.have.property('testAdServer'); - expect(prebid.adServers.testAdServer).to.have.property('getTargetingKeys', getTestAdServerTargetingKeys); - }); -}); diff --git a/test/spec/unit/adUnits_spec.js b/test/spec/unit/adUnits_spec.js deleted file mode 100644 index a8443d36522..00000000000 --- a/test/spec/unit/adUnits_spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import { expect } from 'chai'; -import { adunitCounter } from 'src/adUnits.js'; - -describe('Adunit Counter', function () { - const ADUNIT_ID_1 = 'test1'; - const ADUNIT_ID_2 = 'test2'; - const BIDDER_ID_1 = 'bidder1'; - const BIDDER_ID_2 = 'bidder2'; - - it('increments and checks requests counter of adunit 1', function () { - adunitCounter.incrementRequestsCounter(ADUNIT_ID_1); - expect(adunitCounter.getRequestsCounter(ADUNIT_ID_1)).to.be.equal(1); - }); - it('checks requests counter of adunit 2', function () { - expect(adunitCounter.getRequestsCounter(ADUNIT_ID_2)).to.be.equal(0); - }); - it('increments and checks requests counter of adunit 1', function () { - adunitCounter.incrementRequestsCounter(ADUNIT_ID_1); - expect(adunitCounter.getRequestsCounter(ADUNIT_ID_1)).to.be.equal(2); - }); - it('increments and checks requests counter of adunit 2', function () { - adunitCounter.incrementRequestsCounter(ADUNIT_ID_2); - expect(adunitCounter.getRequestsCounter(ADUNIT_ID_2)).to.be.equal(1); - }); - it('increments and checks requests counter of adunit 1 for bidder 1', function () { - adunitCounter.incrementBidderRequestsCounter(ADUNIT_ID_1, BIDDER_ID_1); - expect(adunitCounter.getBidderRequestsCounter(ADUNIT_ID_1, BIDDER_ID_1)).to.be.equal(1); - }); - it('increments and checks requests counter of adunit 1 for bidder 2', function () { - adunitCounter.incrementBidderRequestsCounter(ADUNIT_ID_1, BIDDER_ID_2); - expect(adunitCounter.getBidderRequestsCounter(ADUNIT_ID_1, BIDDER_ID_2)).to.be.equal(1); - }); - it('increments and checks requests counter of adunit 1 for bidder 1', function () { - adunitCounter.incrementBidderRequestsCounter(ADUNIT_ID_1, BIDDER_ID_1); - expect(adunitCounter.getBidderRequestsCounter(ADUNIT_ID_1, BIDDER_ID_1)).to.be.equal(2); - }); - it('increments and checks wins counter of adunit 1 for bidder 1', function () { - adunitCounter.incrementBidderWinsCounter(ADUNIT_ID_1, BIDDER_ID_1); - expect(adunitCounter.getBidderWinsCounter(ADUNIT_ID_1, BIDDER_ID_1)).to.be.equal(1); - }); - it('increments and checks wins counter of adunit 2 for bidder 1', function () { - adunitCounter.incrementBidderWinsCounter(ADUNIT_ID_2, BIDDER_ID_1); - expect(adunitCounter.getBidderWinsCounter(ADUNIT_ID_2, BIDDER_ID_1)).to.be.equal(1); - }); - it('increments and checks wins counter of adunit 1 for bidder 2', function () { - adunitCounter.incrementBidderWinsCounter(ADUNIT_ID_1, BIDDER_ID_2); - expect(adunitCounter.getBidderWinsCounter(ADUNIT_ID_1, BIDDER_ID_2)).to.be.equal(1); - }); -}); diff --git a/test/spec/unit/core/adapterManager_spec.js b/test/spec/unit/core/adapterManager_spec.js deleted file mode 100644 index f33c9139e5f..00000000000 --- a/test/spec/unit/core/adapterManager_spec.js +++ /dev/null @@ -1,2240 +0,0 @@ -import { expect } from 'chai'; -import adapterManager, { allS2SBidders, clientTestAdapters, gdprDataHandler, coppaDataHandler } from 'src/adapterManager.js'; -import { - getAdUnits, - getServerTestingConfig, - getServerTestingsAds, - getBidRequests -} from 'test/fixtures/fixtures.js'; -import CONSTANTS from 'src/constants.json'; -import * as utils from 'src/utils.js'; -import { config } from 'src/config.js'; -import { registerBidder } from 'src/adapters/bidderFactory.js'; -import { setSizeConfig } from 'src/sizeMapping.js'; -import find from 'core-js-pure/features/array/find.js'; -import includes from 'core-js-pure/features/array/includes.js'; -import s2sTesting from 'modules/s2sTesting.js'; -var events = require('../../../../src/events'); - -const CONFIG = { - enabled: true, - endpoint: CONSTANTS.S2S.DEFAULT_ENDPOINT, - timeout: 1000, - maxBids: 1, - adapter: 'prebidServer', - bidders: ['appnexus'], - accountId: 'abc' -}; - -const CONFIG2 = { - enabled: true, - endpoint: 'https://prebid-server.rubiconproject.com/openrtb2/auction', - timeout: 1000, - maxBids: 1, - adapter: 'prebidServer', - bidders: ['pubmatic'], - accountId: 'def' -} - -var prebidServerAdapterMock = { - bidder: 'prebidServer', - callBids: sinon.stub() -}; -var adequantAdapterMock = { - bidder: 'adequant', - callBids: sinon.stub() -}; -var appnexusAdapterMock = { - bidder: 'appnexus', - callBids: sinon.stub() -}; - -var rubiconAdapterMock = { - bidder: 'rubicon', - callBids: sinon.stub() -}; - -var pubmaticAdapterMock = { - bidder: 'rubicon', - callBids: sinon.stub() -}; - -var badAdapterMock = { - bidder: 'badBidder', - callBids: sinon.stub().throws(Error('some fake error')) -}; - -describe('adapterManager tests', function () { - let orgAppnexusAdapter; - let orgAdequantAdapter; - let orgPrebidServerAdapter; - let orgRubiconAdapter; - let orgBadBidderAdapter; - before(function () { - orgAppnexusAdapter = adapterManager.bidderRegistry['appnexus']; - orgAdequantAdapter = adapterManager.bidderRegistry['adequant']; - orgPrebidServerAdapter = adapterManager.bidderRegistry['prebidServer']; - orgRubiconAdapter = adapterManager.bidderRegistry['rubicon']; - orgBadBidderAdapter = adapterManager.bidderRegistry['badBidder']; - }); - - after(function () { - adapterManager.bidderRegistry['appnexus'] = orgAppnexusAdapter; - adapterManager.bidderRegistry['adequant'] = orgAdequantAdapter; - adapterManager.bidderRegistry['prebidServer'] = orgPrebidServerAdapter; - adapterManager.bidderRegistry['rubicon'] = orgRubiconAdapter; - adapterManager.bidderRegistry['badBidder'] = orgBadBidderAdapter; - config.setConfig({s2sConfig: { enabled: false }}); - }); - - describe('callBids', function () { - before(function () { - config.setConfig({s2sConfig: { enabled: false }}); - }); - - beforeEach(function () { - sinon.stub(utils, 'logError'); - appnexusAdapterMock.callBids.reset(); - adapterManager.bidderRegistry['appnexus'] = appnexusAdapterMock; - adapterManager.bidderRegistry['rubicon'] = rubiconAdapterMock; - adapterManager.bidderRegistry['badBidder'] = badAdapterMock; - adapterManager.bidderRegistry['badBidder'] = badAdapterMock; - }); - - afterEach(function () { - utils.logError.restore(); - delete adapterManager.bidderRegistry['appnexus']; - delete adapterManager.bidderRegistry['rubicon']; - delete adapterManager.bidderRegistry['badBidder']; - config.resetConfig(); - }); - - it('should log an error if a bidder is used that does not exist', function () { - const adUnits = [{ - code: 'adUnit-code', - sizes: [[728, 90]], - bids: [ - {bidder: 'appnexus', params: {placementId: 'id'}}, - {bidder: 'fakeBidder', params: {placementId: 'id'}} - ] - }]; - - let bidRequests = adapterManager.makeBidRequests(adUnits, 1111, 2222, 1000); - expect(bidRequests.length).to.equal(1); - expect(bidRequests[0].bidderCode).to.equal('appnexus'); - sinon.assert.called(utils.logError); - }); - - it('should catch a bidder adapter thrown error and continue with other bidders', function () { - const adUnits = [{ - code: 'adUnit-code', - sizes: [[728, 90]], - bids: [ - {bidder: 'appnexus', params: {placementId: 'id'}}, - {bidder: 'badBidder', params: {placementId: 'id'}}, - {bidder: 'rubicon', params: {account: 1111, site: 2222, zone: 3333}} - ] - }]; - let bidRequests = adapterManager.makeBidRequests(adUnits, 1111, 2222, 1000); - - let doneBidders = []; - function mockDoneCB() { - doneBidders.push(this.bidderCode) - } - adapterManager.callBids(adUnits, bidRequests, () => {}, mockDoneCB); - sinon.assert.calledOnce(appnexusAdapterMock.callBids); - sinon.assert.calledOnce(badAdapterMock.callBids); - sinon.assert.calledOnce(rubiconAdapterMock.callBids); - - expect(utils.logError.calledOnce).to.be.true; - expect(utils.logError.calledWith( - 'badBidder Bid Adapter emitted an uncaught error when parsing their bidRequest' - )).to.be.true; - // done should be called for our bidder! - expect(doneBidders.indexOf('badBidder') === -1).to.be.false; - }); - it('should emit BID_REQUESTED event', function () { - // function to count BID_REQUESTED events - let cnt = 0; - let count = () => cnt++; - events.on(CONSTANTS.EVENTS.BID_REQUESTED, count); - let bidRequests = [{ - 'bidderCode': 'appnexus', - 'auctionId': '1863e370099523', - 'bidderRequestId': '2946b569352ef2', - 'tid': '34566b569352ef2', - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': '4799418', - 'test': 'me' - }, - 'adUnitCode': '/19968336/header-bid-tag1', - 'sizes': [[728, 90], [970, 70]], - 'bidId': '392b5a6b05d648', - 'bidderRequestId': '2946b569352ef2', - 'auctionId': '1863e370099523', - 'startTime': 1462918897462, - 'status': 1, - 'transactionId': 'fsafsa' - }, - ], - 'start': 1462918897460 - }]; - - let adUnits = [{ - code: 'adUnit-code', - bids: [ - {bidder: 'appnexus', params: {placementId: 'id'}}, - ] - }]; - adapterManager.callBids(adUnits, bidRequests, () => {}, () => {}); - expect(cnt).to.equal(1); - sinon.assert.calledOnce(appnexusAdapterMock.callBids); - events.off(CONSTANTS.EVENTS.BID_REQUESTED, count); - }); - - it('should give bidders access to bidder-specific config', function(done) { - let mockBidders = ['rubicon', 'appnexus', 'pubmatic']; - let bidderRequest = getBidRequests().filter(bidRequest => includes(mockBidders, bidRequest.bidderCode)); - let adUnits = getAdUnits(); - - let bidders = {}; - let results = {}; - let cbCount = 0; - - function mock(bidder) { - bidders[bidder] = adapterManager.bidderRegistry[bidder]; - adapterManager.bidderRegistry[bidder] = { - callBids: function(bidRequest, addBidResponse, done, ajax, timeout, configCallback) { - let myResults = results[bidRequest.bidderCode] = []; - myResults.push(config.getConfig('buildRequests')); - myResults.push(config.getConfig('test1')); - myResults.push(config.getConfig('test2')); - // emulate ajax callback that would register bids - setTimeout(configCallback(() => { - myResults.push(config.getConfig('interpretResponse')); - myResults.push(config.getConfig('afterInterpretResponse')); - if (++cbCount === Object.keys(bidders).length) { - assertions(); - } - }), 1); - done(); - } - } - } - - mockBidders.forEach(bidder => { - mock(bidder); - }); - - config.setConfig({ - buildRequests: { - data: 1 - }, - test1: { speedy: true, fun: { test: true } }, - interpretResponse: 'baseInterpret', - afterInterpretResponse: 'anotherBaseInterpret' - }); - config.setBidderConfig({ - bidders: [ 'appnexus' ], - config: { - buildRequests: { - test: 2 - }, - test1: { fun: { safe: true, cheap: false } }, - interpretResponse: 'appnexusInterpret' - } - }); - config.setBidderConfig({ - bidders: [ 'rubicon' ], - config: { - buildRequests: 'rubiconBuild', - interpretResponse: null - } - }); - config.setBidderConfig({ - bidders: [ 'appnexus', 'rubicon' ], - config: { - test2: { amazing: true } - } - }); - - adapterManager.callBids(adUnits, bidderRequest, () => {}, () => {}); - - function assertions() { - expect(results).to.deep.equal({ - 'appnexus': [ - { - data: 1, - test: 2 - }, - { fun: { safe: true, cheap: false, test: true }, speedy: true }, - { amazing: true }, - 'appnexusInterpret', - 'anotherBaseInterpret' - ], - 'pubmatic': [ - { - data: 1 - }, - { fun: { test: true }, speedy: true }, - undefined, - 'baseInterpret', - 'anotherBaseInterpret' - ], - 'rubicon': [ - 'rubiconBuild', - { fun: { test: true }, speedy: true }, - { amazing: true }, - null, - 'anotherBaseInterpret' - ] - }); - - // restore bid adapters - Object.keys(bidders).forEach(bidder => { - adapterManager.bidderRegistry[bidder] = bidders[bidder]; - }); - done(); - } - }); - }); - - describe('callTimedOutBidders', function () { - var criteoSpec = { onTimeout: sinon.stub() } - var criteoAdapter = { - bidder: 'criteo', - getSpec: function() { return criteoSpec; } - } - before(function () { - config.setConfig({s2sConfig: { enabled: false }}); - }); - - beforeEach(function () { - adapterManager.bidderRegistry['criteo'] = criteoAdapter; - }); - - afterEach(function () { - delete adapterManager.bidderRegistry['criteo']; - }); - - it('should call spec\'s onTimeout callback when callTimedOutBidders is called', function () { - const adUnits = [{ - code: 'adUnit-code', - sizes: [[728, 90]], - bids: [ - {bidder: 'criteo', params: {placementId: 'id'}}, - ] - }]; - const timedOutBidders = [{ - bidId: 'bidId', - bidder: 'criteo', - adUnitCode: adUnits[0].code, - auctionId: 'auctionId', - }]; - adapterManager.callTimedOutBidders(adUnits, timedOutBidders, CONFIG.timeout); - sinon.assert.called(criteoSpec.onTimeout); - }); - }); // end callTimedOutBidders - - describe('onBidWon', function () { - var criteoSpec = { onBidWon: sinon.stub() } - var criteoAdapter = { - bidder: 'criteo', - getSpec: function() { return criteoSpec; } - } - before(function () { - config.setConfig({s2sConfig: { enabled: false }}); - }); - - beforeEach(function () { - adapterManager.bidderRegistry['criteo'] = criteoAdapter; - }); - - afterEach(function () { - delete adapterManager.bidderRegistry['criteo']; - }); - - it('should call spec\'s onBidWon callback when a bid is won', function () { - const bids = [ - {bidder: 'criteo', params: {placementId: 'id'}}, - ]; - const adUnits = [{ - code: 'adUnit-code', - sizes: [[728, 90]], - bids - }]; - - adapterManager.callBidWonBidder(bids[0].bidder, bids[0], adUnits); - sinon.assert.called(criteoSpec.onBidWon); - }); - }); // end onBidWon - - describe('onSetTargeting', function () { - var criteoSpec = { onSetTargeting: sinon.stub() } - var criteoAdapter = { - bidder: 'criteo', - getSpec: function() { return criteoSpec; } - } - before(function () { - config.setConfig({s2sConfig: { enabled: false }}); - }); - - beforeEach(function () { - adapterManager.bidderRegistry['criteo'] = criteoAdapter; - }); - - afterEach(function () { - delete adapterManager.bidderRegistry['criteo']; - }); - - it('should call spec\'s onSetTargeting callback when setTargeting is called', function () { - const bids = [ - {bidder: 'criteo', params: {placementId: 'id'}}, - ]; - const adUnits = [{ - code: 'adUnit-code', - sizes: [[728, 90]], - bids - }]; - adapterManager.callSetTargetingBidder(bids[0].bidder, bids[0], adUnits); - sinon.assert.called(criteoSpec.onSetTargeting); - }); - }); // end onSetTargeting - - describe('onBidViewable', function () { - var criteoSpec = { onBidViewable: sinon.stub() } - var criteoAdapter = { - bidder: 'criteo', - getSpec: function() { return criteoSpec; } - } - before(function () { - config.setConfig({s2sConfig: { enabled: false }}); - }); - - beforeEach(function () { - adapterManager.bidderRegistry['criteo'] = criteoAdapter; - }); - - afterEach(function () { - delete adapterManager.bidderRegistry['criteo']; - }); - - it('should call spec\'s onBidViewable callback when callBidViewableBidder is called', function () { - const bids = [ - {bidder: 'criteo', params: {placementId: 'id'}}, - ]; - const adUnits = [{ - code: 'adUnit-code', - sizes: [[728, 90]], - bids - }]; - adapterManager.callBidViewableBidder(bids[0].bidder, bids[0]); - sinon.assert.called(criteoSpec.onBidViewable); - }); - }); // end onBidViewable - - describe('S2S tests', function () { - beforeEach(function () { - config.setConfig({s2sConfig: CONFIG}); - adapterManager.bidderRegistry['prebidServer'] = prebidServerAdapterMock; - prebidServerAdapterMock.callBids.reset(); - }); - - const bidRequests = [{ - 'bidderCode': 'appnexus', - 'auctionId': '1863e370099523', - 'bidderRequestId': '2946b569352ef2', - 'tid': '34566b569352ef2', - 'timeout': 1000, - 'src': 's2s', - 'adUnitsS2SCopy': [ - { - 'code': '/19968336/header-bid-tag1', - 'sizes': [ - { - 'w': 728, - 'h': 90 - }, - { - 'w': 970, - 'h': 90 - } - ], - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': '543221', - 'test': 'me' - }, - 'adUnitCode': '/19968336/header-bid-tag1', - 'sizes': [ - [ - 728, - 90 - ], - [ - 970, - 90 - ] - ], - 'bidId': '68136e1c47023d', - 'bidderRequestId': '55e24a66bed717', - 'auctionId': '1ff753bd4ae5cb', - 'startTime': 1463510220995, - 'status': 1, - 'bid_id': '68136e1c47023d' - } - ] - }, - { - 'code': '/19968336/header-bid-tag-0', - 'sizes': [ - { - 'w': 300, - 'h': 250 - }, - { - 'w': 300, - 'h': 600 - } - ], - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': '5324321' - }, - 'adUnitCode': '/19968336/header-bid-tag-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '7e5d6af25ed188', - 'bidderRequestId': '55e24a66bed717', - 'auctionId': '1ff753bd4ae5cb', - 'startTime': 1463510220996, - 'bid_id': '7e5d6af25ed188' - } - ] - } - ], - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': '4799418', - 'test': 'me' - }, - 'adUnitCode': '/19968336/header-bid-tag1', - 'sizes': [ - [ - 728, - 90 - ], - [ - 970, - 90 - ] - ], - 'bidId': '392b5a6b05d648', - 'bidderRequestId': '2946b569352ef2', - 'auctionId': '1863e370099523', - 'startTime': 1462918897462, - 'status': 1, - 'transactionId': 'fsafsa' - }, - { - 'bidder': 'appnexus', - 'params': { - 'placementId': '4799418' - }, - 'adUnitCode': '/19968336/header-bid-tag-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '4dccdc37746135', - 'bidderRequestId': '2946b569352ef2', - 'auctionId': '1863e370099523', - 'startTime': 1462918897463, - 'status': 1, - 'transactionId': 'fsafsa' - } - ], - 'start': 1462918897460 - }]; - - it('invokes callBids on the S2S adapter', function () { - adapterManager.callBids( - getAdUnits(), - bidRequests, - () => {}, - () => () => {} - ); - sinon.assert.calledOnce(prebidServerAdapterMock.callBids); - }); - - // Enable this test when prebidServer adapter is made 1.0 compliant - it('invokes callBids with only s2s bids', function () { - const adUnits = getAdUnits(); - // adUnit without appnexus bidder - adUnits.push({ - 'code': '123', - 'sizes': [300, 250], - 'bids': [ - { - 'bidder': 'adequant', - 'params': { - 'publisher_id': '1234567', - 'bidfloor': 0.01 - } - } - ] - }); - - adapterManager.callBids( - adUnits, - bidRequests, - () => {}, - () => () => {} - ); - const requestObj = prebidServerAdapterMock.callBids.firstCall.args[0]; - expect(requestObj.ad_units.length).to.equal(2); - sinon.assert.calledOnce(prebidServerAdapterMock.callBids); - }); - - describe('BID_REQUESTED event', function () { - // function to count BID_REQUESTED events - let cnt, count = () => cnt++; - - beforeEach(function () { - prebidServerAdapterMock.callBids.reset(); - cnt = 0; - events.on(CONSTANTS.EVENTS.BID_REQUESTED, count); - }); - - afterEach(function () { - events.off(CONSTANTS.EVENTS.BID_REQUESTED, count); - }); - - it('should fire for s2s requests', function () { - let adUnits = utils.deepClone(getAdUnits()).map(adUnit => { - adUnit.bids = adUnit.bids.filter(bid => includes(['appnexus'], bid.bidder)); - return adUnit; - }) - let bidRequests = adapterManager.makeBidRequests(adUnits, 1111, 2222, 1000); - adapterManager.callBids(adUnits, bidRequests, () => {}, () => {}); - expect(cnt).to.equal(1); - sinon.assert.calledOnce(prebidServerAdapterMock.callBids); - }); - - it('should fire for simultaneous s2s and client requests', function () { - adapterManager.bidderRegistry['adequant'] = adequantAdapterMock; - let adUnits = utils.deepClone(getAdUnits()).map(adUnit => { - adUnit.bids = adUnit.bids.filter(bid => includes(['adequant', 'appnexus'], bid.bidder)); - return adUnit; - }) - let bidRequests = adapterManager.makeBidRequests(adUnits, 1111, 2222, 1000); - adapterManager.callBids(adUnits, bidRequests, () => {}, () => {}); - expect(cnt).to.equal(2); - sinon.assert.calledOnce(prebidServerAdapterMock.callBids); - sinon.assert.calledOnce(adequantAdapterMock.callBids); - adequantAdapterMock.callBids.reset(); - delete adapterManager.bidderRegistry['adequant']; - }); - }); - }); // end s2s tests - - describe('Multiple S2S tests', function () { - beforeEach(function () { - config.setConfig({s2sConfig: [CONFIG, CONFIG2]}); - adapterManager.bidderRegistry['prebidServer'] = prebidServerAdapterMock; - prebidServerAdapterMock.callBids.reset(); - }); - - afterEach(function () { - allS2SBidders.length = 0; - }); - - const bidRequests = [{ - 'bidderCode': 'appnexus', - 'auctionId': '1863e370099523', - 'bidderRequestId': '2946b569352ef2', - 'tid': '34566b569352ef2', - 'timeout': 1000, - 'src': 's2s', - 'adUnitsS2SCopy': [ - { - 'code': '/19968336/header-bid-tag1', - 'sizes': [ - { - 'w': 728, - 'h': 90 - }, - { - 'w': 970, - 'h': 90 - } - ], - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': '543221', - 'test': 'me' - }, - 'adUnitCode': '/19968336/header-bid-tag1', - 'sizes': [ - [ - 728, - 90 - ], - [ - 970, - 90 - ] - ], - 'bidId': '68136e1c47023d', - 'bidderRequestId': '55e24a66bed717', - 'auctionId': '1ff753bd4ae5cb', - 'startTime': 1463510220995, - 'status': 1, - 'bid_id': '68136e1c47023d' - } - ] - }, - { - 'code': '/19968336/header-bid-tag-0', - 'sizes': [ - { - 'w': 300, - 'h': 250 - }, - { - 'w': 300, - 'h': 600 - } - ], - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': '5324321' - }, - 'adUnitCode': '/19968336/header-bid-tag-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '7e5d6af25ed188', - 'bidderRequestId': '55e24a66bed717', - 'auctionId': '1ff753bd4ae5cb', - 'startTime': 1463510220996, - 'bid_id': '7e5d6af25ed188' - } - ] - } - ], - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': '4799418', - 'test': 'me' - }, - 'adUnitCode': '/19968336/header-bid-tag1', - 'sizes': [ - [ - 728, - 90 - ], - [ - 970, - 90 - ] - ], - 'bidId': '392b5a6b05d648', - 'bidderRequestId': '2946b569352ef2', - 'auctionId': '1863e370099523', - 'startTime': 1462918897462, - 'status': 1, - 'transactionId': 'fsafsa' - }, - { - 'bidder': 'appnexus', - 'params': { - 'placementId': '4799418' - }, - 'adUnitCode': '/19968336/header-bid-tag-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '4dccdc37746135', - 'bidderRequestId': '2946b569352ef2', - 'auctionId': '1863e370099523', - 'startTime': 1462918897463, - 'status': 1, - 'transactionId': 'fsafsa' - } - ], - 'start': 1462918897460 - }, - { - 'bidderCode': 'pubmatic', - 'auctionId': '1863e370099523', - 'bidderRequestId': '2946b569352ef2', - 'tid': '2342342342lfi23', - 'timeout': 1000, - 'src': 's2s', - 'adUnitsS2SCopy': [ - { - 'code': '/19968336/header-bid-tag1', - 'sizes': [ - { - 'w': 728, - 'h': 90 - }, - { - 'w': 970, - 'h': 90 - } - ], - 'bids': [ - { - 'bidder': 'pubmatic', - 'params': { - 'placementId': '543221', - 'test': 'me' - }, - 'adUnitCode': '/19968336/header-bid-tag1', - 'sizes': [ - [ - 728, - 90 - ], - [ - 970, - 90 - ] - ], - 'bidId': '68136e1c47023d', - 'bidderRequestId': '55e24a66bed717', - 'auctionId': '1ff753bd4ae5cb', - 'startTime': 1463510220995, - 'status': 1, - 'bid_id': '68136e1c47023d' - } - ] - }, - { - 'code': '/19968336/header-bid-tag-0', - 'sizes': [ - { - 'w': 300, - 'h': 250 - }, - { - 'w': 300, - 'h': 600 - } - ], - 'bids': [ - { - 'bidder': 'pubmatic', - 'params': { - 'placementId': '5324321' - }, - 'adUnitCode': '/19968336/header-bid-tag-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '7e5d6af25ed188', - 'bidderRequestId': '55e24a66bed717', - 'auctionId': '1ff753bd4ae5cb', - 'startTime': 1463510220996, - 'bid_id': '7e5d6af25ed188' - } - ] - } - ], - 'bids': [ - { - 'bidder': 'pubmatic', - 'params': { - 'placementId': '4799418', - 'test': 'me' - }, - 'adUnitCode': '/19968336/header-bid-tag1', - 'sizes': [ - [ - 728, - 90 - ], - [ - 970, - 90 - ] - ], - 'bidId': '392b5a6b05d648', - 'bidderRequestId': '2946b569352ef2', - 'auctionId': '1863e370099523', - 'startTime': 1462918897462, - 'status': 1, - 'transactionId': '4r42r23r23' - }, - { - 'bidder': 'pubmatic', - 'params': { - 'placementId': '4799418' - }, - 'adUnitCode': '/19968336/header-bid-tag-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '4dccdc37746135', - 'bidderRequestId': '2946b569352ef2', - 'auctionId': '1863e370099523', - 'startTime': 1462918897463, - 'status': 1, - 'transactionId': '4r42r23r23' - } - ], - 'start': 1462918897460 - }]; - - it('invokes callBids on the S2S adapter', function () { - adapterManager.callBids( - getAdUnits(), - bidRequests, - () => {}, - () => () => {} - ); - sinon.assert.calledTwice(prebidServerAdapterMock.callBids); - }); - - // Enable this test when prebidServer adapter is made 1.0 compliant - it('invokes callBids with only s2s bids', function () { - const adUnits = getAdUnits(); - // adUnit without appnexus bidder - adUnits.push({ - 'code': '123', - 'sizes': [300, 250], - 'bids': [ - { - 'bidder': 'adequant', - 'params': { - 'publisher_id': '1234567', - 'bidfloor': 0.01 - } - } - ] - }); - - adapterManager.callBids( - adUnits, - bidRequests, - () => {}, - () => () => {} - ); - const requestObj = prebidServerAdapterMock.callBids.firstCall.args[0]; - expect(requestObj.ad_units.length).to.equal(2); - sinon.assert.calledTwice(prebidServerAdapterMock.callBids); - }); - - describe('BID_REQUESTED event', function () { - // function to count BID_REQUESTED events - let cnt, count = () => cnt++; - - beforeEach(function () { - prebidServerAdapterMock.callBids.reset(); - cnt = 0; - events.on(CONSTANTS.EVENTS.BID_REQUESTED, count); - }); - - afterEach(function () { - events.off(CONSTANTS.EVENTS.BID_REQUESTED, count); - }); - - it('should fire for s2s requests', function () { - let adUnits = utils.deepClone(getAdUnits()).map(adUnit => { - adUnit.bids = adUnit.bids.filter(bid => includes(['appnexus', 'pubmatic'], bid.bidder)); - return adUnit; - }) - let bidRequests = adapterManager.makeBidRequests(adUnits, 1111, 2222, 1000); - adapterManager.callBids(adUnits, bidRequests, () => {}, () => {}); - expect(cnt).to.equal(2); - sinon.assert.calledTwice(prebidServerAdapterMock.callBids); - }); - - it('should fire for simultaneous s2s and client requests', function () { - adapterManager.bidderRegistry['adequant'] = adequantAdapterMock; - let adUnits = utils.deepClone(getAdUnits()).map(adUnit => { - adUnit.bids = adUnit.bids.filter(bid => includes(['adequant', 'appnexus', 'pubmatic'], bid.bidder)); - return adUnit; - }) - let bidRequests = adapterManager.makeBidRequests(adUnits, 1111, 2222, 1000); - adapterManager.callBids(adUnits, bidRequests, () => {}, () => {}); - expect(cnt).to.equal(3); - sinon.assert.calledTwice(prebidServerAdapterMock.callBids); - sinon.assert.calledOnce(adequantAdapterMock.callBids); - adequantAdapterMock.callBids.reset(); - delete adapterManager.bidderRegistry['adequant']; - }); - }); - }); // end multiple s2s tests - - describe('s2sTesting', function () { - let doneStub = sinon.stub(); - let ajaxStub = sinon.stub(); - - function getTestAdUnits() { - // copy adUnits - // return JSON.parse(JSON.stringify(getAdUnits())); - return utils.deepClone(getAdUnits()).map(adUnit => { - adUnit.bids = adUnit.bids.filter(bid => includes(['adequant', 'appnexus', 'rubicon'], bid.bidder)); - return adUnit; - }) - } - - function callBids(adUnits = getTestAdUnits()) { - let bidRequests = adapterManager.makeBidRequests(adUnits, 1111, 2222, 1000); - adapterManager.callBids(adUnits, bidRequests, doneStub, ajaxStub); - } - - function checkServerCalled(numAdUnits, numBids) { - sinon.assert.calledOnce(prebidServerAdapterMock.callBids); - let requestObj = prebidServerAdapterMock.callBids.firstCall.args[0]; - expect(requestObj.ad_units.length).to.equal(numAdUnits); - for (let i = 0; i < numAdUnits; i++) { - expect(requestObj.ad_units[i].bids.filter((bid) => { - return bid.bidder === 'appnexus' || bid.bidder === 'adequant'; - }).length).to.equal(numBids); - } - } - - function checkClientCalled(adapter, numBids) { - sinon.assert.calledOnce(adapter.callBids); - expect(adapter.callBids.firstCall.args[0].bids.length).to.equal(numBids); - } - - let TESTING_CONFIG = utils.deepClone(CONFIG); - Object.assign(TESTING_CONFIG, { - bidders: ['appnexus', 'adequant'], - testing: true - }); - let stubGetSourceBidderMap; - - beforeEach(function () { - config.setConfig({s2sConfig: TESTING_CONFIG}); - adapterManager.bidderRegistry['prebidServer'] = prebidServerAdapterMock; - adapterManager.bidderRegistry['adequant'] = adequantAdapterMock; - adapterManager.bidderRegistry['appnexus'] = appnexusAdapterMock; - adapterManager.bidderRegistry['rubicon'] = rubiconAdapterMock; - - stubGetSourceBidderMap = sinon.stub(s2sTesting, 'getSourceBidderMap'); - - prebidServerAdapterMock.callBids.reset(); - adequantAdapterMock.callBids.reset(); - appnexusAdapterMock.callBids.reset(); - rubiconAdapterMock.callBids.reset(); - }); - - afterEach(function () { - s2sTesting.getSourceBidderMap.restore(); - }); - - it('calls server adapter if no sources defined', function () { - stubGetSourceBidderMap.returns({[s2sTesting.CLIENT]: [], [s2sTesting.SERVER]: []}); - callBids(); - - // server adapter - checkServerCalled(2, 2); - - // appnexus - sinon.assert.notCalled(appnexusAdapterMock.callBids); - - // adequant - sinon.assert.notCalled(adequantAdapterMock.callBids); - }); - - it('calls client adapter if one client source defined', function () { - stubGetSourceBidderMap.returns({[s2sTesting.CLIENT]: ['appnexus'], [s2sTesting.SERVER]: []}); - callBids(); - - // server adapter - checkServerCalled(2, 2); - - // appnexus - checkClientCalled(appnexusAdapterMock, 2); - - // adequant - sinon.assert.notCalled(adequantAdapterMock.callBids); - }); - - it('calls client adapters if client sources defined', function () { - stubGetSourceBidderMap.returns({[s2sTesting.CLIENT]: ['appnexus', 'adequant'], [s2sTesting.SERVER]: []}); - callBids(); - - // server adapter - checkServerCalled(2, 2); - - // appnexus - checkClientCalled(appnexusAdapterMock, 2); - - // adequant - checkClientCalled(adequantAdapterMock, 2); - }); - - it('does not call server adapter for bidders that go to client', function () { - stubGetSourceBidderMap.returns({[s2sTesting.CLIENT]: ['appnexus', 'adequant'], [s2sTesting.SERVER]: []}); - var adUnits = getTestAdUnits(); - adUnits[0].bids[0].finalSource = s2sTesting.CLIENT; - adUnits[0].bids[1].finalSource = s2sTesting.CLIENT; - adUnits[1].bids[0].finalSource = s2sTesting.CLIENT; - adUnits[1].bids[1].finalSource = s2sTesting.CLIENT; - callBids(adUnits); - - // server adapter - sinon.assert.notCalled(prebidServerAdapterMock.callBids); - - // appnexus - checkClientCalled(appnexusAdapterMock, 2); - - // adequant - checkClientCalled(adequantAdapterMock, 2); - }); - - it('does not call client adapters for bidders that go to server', function () { - stubGetSourceBidderMap.returns({[s2sTesting.CLIENT]: ['appnexus', 'adequant'], [s2sTesting.SERVER]: []}); - var adUnits = getTestAdUnits(); - adUnits[0].bids[0].finalSource = s2sTesting.SERVER; - adUnits[0].bids[1].finalSource = s2sTesting.SERVER; - adUnits[1].bids[0].finalSource = s2sTesting.SERVER; - adUnits[1].bids[1].finalSource = s2sTesting.SERVER; - callBids(adUnits); - - // server adapter - checkServerCalled(2, 2); - - // appnexus - sinon.assert.notCalled(appnexusAdapterMock.callBids); - - // adequant - sinon.assert.notCalled(adequantAdapterMock.callBids); - }); - - it('calls client and server adapters for bidders that go to both', function () { - stubGetSourceBidderMap.returns({[s2sTesting.CLIENT]: ['appnexus', 'adequant'], [s2sTesting.SERVER]: []}); - var adUnits = getTestAdUnits(); - // adUnits[0].bids[0].finalSource = s2sTesting.BOTH; - // adUnits[0].bids[1].finalSource = s2sTesting.BOTH; - // adUnits[1].bids[0].finalSource = s2sTesting.BOTH; - // adUnits[1].bids[1].finalSource = s2sTesting.BOTH; - callBids(adUnits); - - // server adapter - checkServerCalled(2, 2); - - // appnexus - checkClientCalled(appnexusAdapterMock, 2); - - // adequant - checkClientCalled(adequantAdapterMock, 2); - }); - - it('makes mixed client/server adapter calls for mixed bidder sources', function () { - stubGetSourceBidderMap.returns({[s2sTesting.CLIENT]: ['appnexus', 'adequant'], [s2sTesting.SERVER]: []}); - var adUnits = getTestAdUnits(); - adUnits[0].bids[0].finalSource = s2sTesting.CLIENT; - adUnits[0].bids[1].finalSource = s2sTesting.CLIENT; - adUnits[1].bids[0].finalSource = s2sTesting.SERVER; - adUnits[1].bids[1].finalSource = s2sTesting.SERVER; - callBids(adUnits); - - // server adapter - checkServerCalled(1, 2); - - // appnexus - checkClientCalled(appnexusAdapterMock, 1); - - // adequant - checkClientCalled(adequantAdapterMock, 1); - }); - }); - - describe('Multiple Server s2sTesting', function () { - let doneStub = sinon.stub(); - let ajaxStub = sinon.stub(); - - function getTestAdUnits() { - // copy adUnits - return utils.deepClone(getAdUnits()).map(adUnit => { - adUnit.bids = adUnit.bids.filter(bid => { - return includes(['adequant', 'appnexus', 'pubmatic', 'rubicon'], - bid.bidder); - }); - return adUnit; - }) - } - - function callBids(adUnits = getTestAdUnits()) { - let bidRequests = adapterManager.makeBidRequests(adUnits, 1111, 2222, 1000); - adapterManager.callBids(adUnits, bidRequests, doneStub, ajaxStub); - } - - function checkServerCalled(numAdUnits, firstConfigNumBids, secondConfigNumBids) { - let requestObjects = []; - let configBids; - if (firstConfigNumBids === 0 || secondConfigNumBids === 0) { - configBids = Math.max(firstConfigNumBids, secondConfigNumBids) - sinon.assert.calledOnce(prebidServerAdapterMock.callBids); - let requestObj1 = prebidServerAdapterMock.callBids.firstCall.args[0]; - requestObjects.push(requestObj1) - } else { - sinon.assert.calledTwice(prebidServerAdapterMock.callBids); - let requestObj1 = prebidServerAdapterMock.callBids.firstCall.args[0]; - let requestObj2 = prebidServerAdapterMock.callBids.secondCall.args[0]; - requestObjects.push(requestObj1, requestObj2); - } - - requestObjects.forEach((requestObj, index) => { - const numBids = configBids !== undefined ? configBids : index === 0 ? firstConfigNumBids : secondConfigNumBids - expect(requestObj.ad_units.length).to.equal(numAdUnits); - for (let i = 0; i < numAdUnits; i++) { - expect(requestObj.ad_units[i].bids.filter((bid) => { - return bid.bidder === 'appnexus' || bid.bidder === 'adequant' || bid.bidder === 'pubmatic'; - }).length).to.equal(numBids); - } - }) - } - - function checkClientCalled(adapter, numBids) { - sinon.assert.calledOnce(adapter.callBids); - expect(adapter.callBids.firstCall.args[0].bids.length).to.equal(numBids); - } - - beforeEach(function () { - allS2SBidders.length = 0; - clientTestAdapters.length = 0 - - adapterManager.bidderRegistry['prebidServer'] = prebidServerAdapterMock; - adapterManager.bidderRegistry['adequant'] = adequantAdapterMock; - adapterManager.bidderRegistry['appnexus'] = appnexusAdapterMock; - adapterManager.bidderRegistry['rubicon'] = rubiconAdapterMock; - adapterManager.bidderRegistry['pubmatic'] = pubmaticAdapterMock; - - prebidServerAdapterMock.callBids.reset(); - adequantAdapterMock.callBids.reset(); - appnexusAdapterMock.callBids.reset(); - rubiconAdapterMock.callBids.reset(); - pubmaticAdapterMock.callBids.reset(); - }); - - it('calls server adapter if no sources defined for config where testing is true, ' + - 'calls client adapter for second config where testing is false', function () { - let TEST_CONFIG = utils.deepClone(CONFIG); - Object.assign(TEST_CONFIG, { - bidders: ['appnexus', 'adequant'], - testing: true, - }); - let TEST_CONFIG2 = utils.deepClone(CONFIG2); - Object.assign(TEST_CONFIG2, { - bidders: ['pubmatic'], - testing: true - }); - - config.setConfig({s2sConfig: [TEST_CONFIG, TEST_CONFIG2]}); - - callBids(); - - // server adapter - checkServerCalled(2, 2, 1); - - // appnexus - sinon.assert.notCalled(appnexusAdapterMock.callBids); - - // adequant - sinon.assert.notCalled(adequantAdapterMock.callBids); - - // pubmatic - sinon.assert.notCalled(pubmaticAdapterMock.callBids); - - // rubicon - sinon.assert.called(rubiconAdapterMock.callBids); - }); - - it('calls client adapter if one client source defined for config where testing is true, ' + - 'calls client adapter for second config where testing is false', function () { - let TEST_CONFIG = utils.deepClone(CONFIG); - Object.assign(TEST_CONFIG, { - bidders: ['appnexus', 'adequant'], - bidderControl: { - appnexus: { - bidSource: { server: 0, client: 100 }, - includeSourceKvp: true, - }, - }, - testing: true, - }); - let TEST_CONFIG2 = utils.deepClone(CONFIG2); - Object.assign(TEST_CONFIG2, { - bidders: ['pubmatic'], - testing: true - }); - - config.setConfig({s2sConfig: [TEST_CONFIG, TEST_CONFIG2]}); - callBids(); - - // server adapter - checkServerCalled(2, 1, 1); - - // appnexus - checkClientCalled(appnexusAdapterMock, 2); - - // adequant - sinon.assert.notCalled(adequantAdapterMock.callBids); - - // pubmatic - sinon.assert.notCalled(pubmaticAdapterMock.callBids); - - // rubicon - checkClientCalled(rubiconAdapterMock, 1); - }); - - it('calls client adapters if client sources defined in first config and server in second config', function () { - let TEST_CONFIG = utils.deepClone(CONFIG); - Object.assign(TEST_CONFIG, { - bidders: ['appnexus', 'adequant'], - bidderControl: { - appnexus: { - bidSource: { server: 0, client: 100 }, - includeSourceKvp: true, - }, - adequant: { - bidSource: { server: 0, client: 100 }, - includeSourceKvp: true, - }, - }, - testing: true, - }); - - let TEST_CONFIG2 = utils.deepClone(CONFIG2); - Object.assign(TEST_CONFIG2, { - bidders: ['pubmatic'], - testing: true - }); - - config.setConfig({s2sConfig: [TEST_CONFIG, TEST_CONFIG2]}); - - callBids(); - - // server adapter - checkServerCalled(2, 0, 1); - - // appnexus - checkClientCalled(appnexusAdapterMock, 2); - - // adequant - checkClientCalled(adequantAdapterMock, 2); - - // pubmatic - sinon.assert.notCalled(pubmaticAdapterMock.callBids); - - // rubicon - checkClientCalled(rubiconAdapterMock, 1); - }); - - it('does not call server adapter for bidders that go to client when both configs are set to client', function () { - let TEST_CONFIG = utils.deepClone(CONFIG); - Object.assign(TEST_CONFIG, { - bidders: ['appnexus', 'adequant'], - bidderControl: { - appnexus: { - bidSource: { server: 0, client: 100 }, - includeSourceKvp: true, - }, - adequant: { - bidSource: { server: 0, client: 100 }, - includeSourceKvp: true, - }, - }, - testing: true, - }); - - let TEST_CONFIG2 = utils.deepClone(CONFIG2); - Object.assign(TEST_CONFIG2, { - bidders: ['pubmatic'], - bidderControl: { - pubmatic: { - bidSource: { server: 0, client: 100 }, - includeSourceKvp: true, - }, - }, - testing: true - }); - - config.setConfig({s2sConfig: [TEST_CONFIG, TEST_CONFIG2]}); - callBids(); - - sinon.assert.notCalled(prebidServerAdapterMock.callBids); - - // appnexus - checkClientCalled(appnexusAdapterMock, 2); - - // adequant - checkClientCalled(adequantAdapterMock, 2); - - // pubmatic - checkClientCalled(pubmaticAdapterMock, 2); - - // rubicon - checkClientCalled(rubiconAdapterMock, 1); - }); - - it('does not call client adapters for bidders in either config when testServerOnly if true in first config', function () { - let TEST_CONFIG = utils.deepClone(CONFIG); - Object.assign(TEST_CONFIG, { - bidders: ['appnexus', 'adequant'], - testServerOnly: true, - bidderControl: { - appnexus: { - bidSource: { server: 0, client: 100 }, - includeSourceKvp: true, - }, - adequant: { - bidSource: { server: 100, client: 0 }, - includeSourceKvp: true, - }, - }, - testing: true, - }); - - let TEST_CONFIG2 = utils.deepClone(CONFIG2); - Object.assign(TEST_CONFIG2, { - bidders: ['pubmatic'], - bidderControl: { - pubmatic: { - bidSource: { server: 0, client: 100 }, - includeSourceKvp: true, - } - }, - testing: true - }); - - config.setConfig({s2sConfig: [TEST_CONFIG, TEST_CONFIG2]}); - callBids(); - - // server adapter - checkServerCalled(2, 1, 0); - - // appnexus - sinon.assert.notCalled(appnexusAdapterMock.callBids); - - // adequant - sinon.assert.notCalled(adequantAdapterMock.callBids); - - // pubmatic - sinon.assert.notCalled(pubmaticAdapterMock.callBids); - - // rubicon - sinon.assert.notCalled(rubiconAdapterMock.callBids); - }); - - it('does not call client adapters for bidders in either config when testServerOnly if true in second config', function () { - let TEST_CONFIG = utils.deepClone(CONFIG); - Object.assign(TEST_CONFIG, { - bidders: ['appnexus', 'adequant'], - bidderControl: { - appnexus: { - bidSource: { server: 0, client: 100 }, - includeSourceKvp: true, - }, - adequant: { - bidSource: { server: 100, client: 0 }, - includeSourceKvp: true, - }, - }, - testing: true, - }); - - let TEST_CONFIG2 = utils.deepClone(CONFIG2); - Object.assign(TEST_CONFIG2, { - bidders: ['pubmatic'], - testServerOnly: true, - bidderControl: { - pubmatic: { - bidSource: { server: 100, client: 0 }, - includeSourceKvp: true, - } - }, - testing: true - }); - - config.setConfig({s2sConfig: [TEST_CONFIG, TEST_CONFIG2]}); - callBids(); - - // server adapter - checkServerCalled(2, 1, 1); - - // appnexus - sinon.assert.notCalled(appnexusAdapterMock.callBids); - - // adequant - sinon.assert.notCalled(adequantAdapterMock.callBids); - - // pubmatic - sinon.assert.notCalled(pubmaticAdapterMock.callBids); - - // rubicon - sinon.assert.notCalled(rubiconAdapterMock.callBids); - }); - }); - - describe('aliasBidderAdaptor', function() { - const CODE = 'sampleBidder'; - - describe('using bidderFactory', function() { - let spec; - - beforeEach(function () { - spec = { - code: CODE, - isBidRequestValid: () => {}, - buildRequests: () => {}, - interpretResponse: () => {}, - getUserSyncs: () => {} - }; - }); - - it('should add alias to registry when original adapter is using bidderFactory', function() { - let thisSpec = Object.assign(spec, { supportedMediaTypes: ['video'] }); - registerBidder(thisSpec); - const alias = 'aliasBidder'; - adapterManager.aliasBidAdapter(CODE, alias); - expect(adapterManager.bidderRegistry).to.have.property(alias); - expect(adapterManager.videoAdapters).to.include(alias); - }); - }); - - describe('special case for s2s-only bidders', function () { - beforeEach(function () { - sinon.stub(utils, 'logError'); - }); - - afterEach(function () { - config.resetConfig(); - utils.logError.restore(); - }); - - it('should allow an alias if alias is part of s2sConfig.bidders', function () { - let testS2sConfig = utils.deepClone(CONFIG); - testS2sConfig.bidders = ['s2sAlias']; - config.setConfig({s2sConfig: testS2sConfig}); - - adapterManager.aliasBidAdapter('s2sBidder', 's2sAlias'); - expect(adapterManager.aliasRegistry).to.have.property('s2sAlias'); - }); - - it('should allow an alias if alias is part of s2sConfig.bidders for multiple s2sConfigs', function () { - let testS2sConfig = utils.deepClone(CONFIG); - testS2sConfig.bidders = ['s2sAlias']; - config.setConfig({s2sConfig: [ - testS2sConfig, { - enabled: true, - endpoint: 'rp-pbs-endpoint-test.com', - timeout: 500, - maxBids: 1, - adapter: 'prebidServer', - bidders: ['s2sRpAlias'], - accountId: 'def' - } - ]}); - - adapterManager.aliasBidAdapter('s2sBidder', 's2sAlias'); - expect(adapterManager.aliasRegistry).to.have.property('s2sAlias'); - adapterManager.aliasBidAdapter('s2sBidder', 's2sRpAlias'); - expect(adapterManager.aliasRegistry).to.have.property('s2sRpAlias'); - }); - - it('should throw an error if alias + bidder are unknown and not part of s2sConfig.bidders', function () { - let testS2sConfig = utils.deepClone(CONFIG); - testS2sConfig.bidders = ['s2sAlias']; - config.setConfig({s2sConfig: testS2sConfig}); - - adapterManager.aliasBidAdapter('s2sBidder1', 's2sAlias1'); - sinon.assert.calledOnce(utils.logError); - expect(adapterManager.aliasRegistry).to.not.have.property('s2sAlias1'); - }); - }); - }); - - describe('makeBidRequests', function () { - let adUnits; - beforeEach(function () { - allS2SBidders.length = 0 - adUnits = utils.deepClone(getAdUnits()).map(adUnit => { - adUnit.bids = adUnit.bids.filter(bid => includes(['appnexus', 'rubicon'], bid.bidder)); - return adUnit; - }) - }); - - it('should make separate bidder request objects for each bidder', () => { - adUnits = [utils.deepClone(getAdUnits()[0])]; - - let bidRequests = adapterManager.makeBidRequests( - adUnits, - Date.now(), - utils.getUniqueIdentifierStr(), - function callback() {}, - [] - ); - - let sizes1 = bidRequests[1].bids[0].sizes; - let sizes2 = bidRequests[0].bids[0].sizes; - - // mutate array - sizes1.splice(0, 1); - - expect(sizes1).not.to.deep.equal(sizes2); - }); - - describe('setBidderSequence', function () { - beforeEach(function () { - sinon.spy(utils, 'shuffle'); - }); - - afterEach(function () { - config.resetConfig(); - utils.shuffle.restore(); - }); - - it('setting to `random` uses shuffled order of adUnits', function () { - config.setConfig({ bidderSequence: 'random' }); - let bidRequests = adapterManager.makeBidRequests( - adUnits, - Date.now(), - utils.getUniqueIdentifierStr(), - function callback() {}, - [] - ); - sinon.assert.calledOnce(utils.shuffle); - }); - }); - - describe('sizeMapping', function () { - beforeEach(function () { - allS2SBidders.length = 0; - clientTestAdapters.length = 0; - sinon.stub(window, 'matchMedia').callsFake(() => ({matches: true})); - }); - - afterEach(function () { - matchMedia.restore(); - config.resetConfig(); - setSizeConfig([]); - }); - - it('should not filter banner bids w/ no labels', function () { - let bidRequests = adapterManager.makeBidRequests( - adUnits, - Date.now(), - utils.getUniqueIdentifierStr(), - function callback() {}, - [] - ); - - expect(bidRequests.length).to.equal(2); - let rubiconBidRequests = find(bidRequests, bidRequest => bidRequest.bidderCode === 'rubicon'); - expect(rubiconBidRequests.bids.length).to.equal(1); - expect(rubiconBidRequests.bids[0].mediaTypes).to.deep.equal(find(adUnits, adUnit => adUnit.code === rubiconBidRequests.bids[0].adUnitCode).mediaTypes); - - let appnexusBidRequests = find(bidRequests, bidRequest => bidRequest.bidderCode === 'appnexus'); - expect(appnexusBidRequests.bids.length).to.equal(2); - expect(appnexusBidRequests.bids[0].mediaTypes).to.deep.equal(find(adUnits, adUnit => adUnit.code === appnexusBidRequests.bids[0].adUnitCode).mediaTypes); - expect(appnexusBidRequests.bids[1].mediaTypes).to.deep.equal(find(adUnits, adUnit => adUnit.code === appnexusBidRequests.bids[1].adUnitCode).mediaTypes); - }); - - it('should not filter video bids', function () { - setSizeConfig([{ - 'mediaQuery': '(min-width: 768px) and (max-width: 1199px)', - 'sizesSupported': [ - [728, 90], - [300, 250] - ], - 'labels': ['tablet', 'phone'] - }]); - - let videoAdUnits = [{ - code: 'test_video', - mediaTypes: { - video: { - playerSize: [300, 300], - context: 'outstream' - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13232385, - video: { - skippable: true, - playback_method: ['auto_play_sound_off'] - } - } - }] - }]; - let bidRequests = adapterManager.makeBidRequests( - videoAdUnits, - Date.now(), - utils.getUniqueIdentifierStr(), - function callback() {}, - [] - ); - expect(bidRequests[0].bids[0].sizes).to.deep.equal([300, 300]); - }); - - it('should not filter native bids', function () { - setSizeConfig([{ - 'mediaQuery': '(min-width: 768px) and (max-width: 1199px)', - 'sizesSupported': [ - [728, 90], - [300, 250] - ], - 'labels': ['tablet', 'phone'] - }]); - - let nativeAdUnits = [{ - code: 'test_native', - sizes: [[1, 1]], - mediaTypes: { - native: { - title: { required: true }, - body: { required: false }, - image: { required: true }, - icon: { required: false }, - sponsoredBy: { required: true }, - clickUrl: { required: true }, - }, - }, - bids: [ - { - bidder: 'appnexus', - params: { placementId: 13232354 } - }, - ] - }]; - let bidRequests = adapterManager.makeBidRequests( - nativeAdUnits, - Date.now(), - utils.getUniqueIdentifierStr(), - function callback() {}, - [] - ); - expect(bidRequests[0].bids[0].sizes).to.deep.equal([]); - }); - - it('should filter sizes using size config', function () { - let validSizes = [ - [728, 90], - [300, 250] - ]; - - let validSizeMap = validSizes.map(size => size.toString()).reduce((map, size) => { - map[size] = true; - return map; - }, {}); - - setSizeConfig([{ - 'mediaQuery': '(min-width: 768px) and (max-width: 1199px)', - 'sizesSupported': validSizes, - 'labels': ['tablet', 'phone'] - }]); - - let bidRequests = adapterManager.makeBidRequests( - adUnits, - Date.now(), - utils.getUniqueIdentifierStr(), - function callback() {}, - [] - ); - - // only valid sizes as specified in size config should show up in bidRequests - bidRequests.forEach(bidRequest => { - bidRequest.bids.forEach(bid => { - bid.sizes.forEach(size => { - expect(validSizeMap[size]).to.equal(true); - }); - }); - }); - - setSizeConfig([{ - 'mediaQuery': '(min-width: 768px) and (max-width: 1199px)', - 'sizesSupported': [], - 'labels': ['tablet', 'phone'] - }]); - - bidRequests = adapterManager.makeBidRequests( - adUnits, - Date.now(), - utils.getUniqueIdentifierStr(), - function callback() {}, - [] - ); - - // if no valid sizes, all bidders should be filtered out - expect(bidRequests.length).to.equal(0); - }); - - it('should filter adUnits/bidders based on applied labels', function () { - adUnits[0].labelAll = ['visitor-uk', 'mobile']; - adUnits[1].labelAny = ['visitor-uk', 'desktop']; - adUnits[1].bids[0].labelAny = ['mobile']; - adUnits[1].bids[1].labelAll = ['desktop']; - - let bidRequests = adapterManager.makeBidRequests( - adUnits, - Date.now(), - utils.getUniqueIdentifierStr(), - function callback() {}, - ['visitor-uk', 'desktop'] - ); - - // only one adUnit and one bid from that adUnit should make it through the applied labels above - expect(bidRequests.length).to.equal(1); - expect(bidRequests[0].bidderCode).to.equal('rubicon'); - expect(bidRequests[0].bids.length).to.equal(1); - expect(bidRequests[0].bids[0].adUnitCode).to.equal(adUnits[1].code); - }); - - it('should filter adUnits/bidders based on applid labels for s2s requests', function () { - adUnits[0].labelAll = ['visitor-uk', 'mobile']; - adUnits[1].labelAny = ['visitor-uk', 'desktop']; - adUnits[1].bids[0].labelAny = ['mobile']; - adUnits[1].bids[1].labelAll = ['desktop']; - - let TESTING_CONFIG = utils.deepClone(CONFIG); - TESTING_CONFIG.bidders = ['appnexus', 'rubicon']; - config.setConfig({ s2sConfig: TESTING_CONFIG }); - - let bidRequests = adapterManager.makeBidRequests( - adUnits, - Date.now(), - utils.getUniqueIdentifierStr(), - function callback() {}, - ['visitor-uk', 'desktop'] - ); - - expect(bidRequests.length).to.equal(1); - expect(bidRequests[0].adUnitsS2SCopy.length).to.equal(1); - expect(bidRequests[0].adUnitsS2SCopy[0].bids.length).to.equal(1); - expect(bidRequests[0].adUnitsS2SCopy[0].bids[0].bidder).to.equal('rubicon'); - expect(bidRequests[0].adUnitsS2SCopy[0].labelAny).to.deep.equal(['visitor-uk', 'desktop']); - }); - }); - - describe('gdpr consent module', function () { - it('inserts gdprConsent object to bidRequest only when module was enabled', function () { - gdprDataHandler.setConsentData({ - consentString: 'abc123def456', - consentRequired: true - }); - - let bidRequests = adapterManager.makeBidRequests( - adUnits, - Date.now(), - utils.getUniqueIdentifierStr(), - function callback() {}, - [] - ); - expect(bidRequests[0].gdprConsent.consentString).to.equal('abc123def456'); - expect(bidRequests[0].gdprConsent.consentRequired).to.be.true; - - gdprDataHandler.setConsentData(null); - - bidRequests = adapterManager.makeBidRequests( - adUnits, - Date.now(), - utils.getUniqueIdentifierStr(), - function callback() {}, - [] - ); - expect(bidRequests[0].gdprConsent).to.be.undefined; - }); - }); - describe('coppa consent module', function () { - afterEach(() => { - config.resetConfig(); - }); - it('test coppa configuration with value false', function () { - config.setConfig({ coppa: 0 }); - const coppa = coppaDataHandler.getCoppa(); - expect(coppa).to.be.false; - }); - it('test coppa configuration with value true', function () { - config.setConfig({ coppa: 1 }); - const coppa = coppaDataHandler.getCoppa(); - expect(coppa).to.be.true; - }); - it('test coppa configuration', function () { - const coppa = coppaDataHandler.getCoppa(); - expect(coppa).to.be.false; - }); - }); - describe('s2sTesting - testServerOnly', () => { - beforeEach(() => { - config.setConfig({ s2sConfig: getServerTestingConfig(CONFIG) }); - allS2SBidders.length = 0 - s2sTesting.bidSource = {}; - }); - - afterEach(() => { - config.resetConfig(); - }); - - const makeBidRequests = ads => { - let bidRequests = adapterManager.makeBidRequests( - ads, 1111, 2222, 1000 - ); - - bidRequests.sort((a, b) => { - if (a.bidderCode < b.bidderCode) return -1; - if (a.bidderCode > b.bidderCode) return 1; - return 0; - }); - - return bidRequests; - }; - - const removeAdUnitsBidSource = adUnits => adUnits.map(adUnit => { - const newAdUnit = { ...adUnit }; - newAdUnit.bids = newAdUnit.bids.map(bid => { - if (bid.bidSource) delete bid.bidSource; - return bid; - }); - return newAdUnit; - }); - - it('suppresses all client bids if there are server bids resulting from bidSource at the adUnit Level', () => { - const bidRequests = makeBidRequests(getServerTestingsAds()); - - expect(bidRequests).lengthOf(2); - - expect(bidRequests[0].bids).lengthOf(1); - expect(bidRequests[0].bids[0].bidder).equals('openx'); - expect(bidRequests[0].bids[0].finalSource).equals('server'); - - expect(bidRequests[0].bids).lengthOf(1); - expect(bidRequests[1].bids[0].bidder).equals('rubicon'); - expect(bidRequests[1].bids[0].finalSource).equals('server'); - }); - - // todo: update description - it('suppresses all, and only, client bids if there are bids resulting from bidSource at the adUnit Level', () => { - const ads = getServerTestingsAds(); - - // change this adUnit to be server based - ads[1].bids[1].bidSource.client = 0; - ads[1].bids[1].bidSource.server = 100; - - const bidRequests = makeBidRequests(ads); - - expect(bidRequests).lengthOf(3); - - expect(bidRequests[0].bids).lengthOf(1); - expect(bidRequests[0].bids[0].bidder).equals('appnexus'); - expect(bidRequests[0].bids[0].finalSource).equals('server'); - - expect(bidRequests[1].bids).lengthOf(1); - expect(bidRequests[1].bids[0].bidder).equals('openx'); - expect(bidRequests[1].bids[0].finalSource).equals('server'); - - expect(bidRequests[2].bids).lengthOf(1); - expect(bidRequests[2].bids[0].bidder).equals('rubicon'); - expect(bidRequests[2].bids[0].finalSource).equals('server'); - }); - - // we have a server call now - it('does not suppress client bids if no "test case" bids result in a server bid', () => { - const ads = getServerTestingsAds(); - - // change this adUnit to be client based - ads[0].bids[0].bidSource.client = 100; - ads[0].bids[0].bidSource.server = 0; - - const bidRequests = makeBidRequests(ads); - - expect(bidRequests).lengthOf(4); - - expect(bidRequests[0].bids).lengthOf(1); - expect(bidRequests[0].bids[0].bidder).equals('adequant'); - expect(bidRequests[0].bids[0].finalSource).equals('client'); - - expect(bidRequests[1].bids).lengthOf(2); - expect(bidRequests[1].bids[0].bidder).equals('appnexus'); - expect(bidRequests[1].bids[0].finalSource).equals('client'); - expect(bidRequests[1].bids[1].bidder).equals('appnexus'); - expect(bidRequests[1].bids[1].finalSource).equals('client'); - - expect(bidRequests[2].bids).lengthOf(1); - expect(bidRequests[2].bids[0].bidder).equals('openx'); - expect(bidRequests[2].bids[0].finalSource).equals('server'); - - expect(bidRequests[3].bids).lengthOf(2); - expect(bidRequests[3].bids[0].bidder).equals('rubicon'); - expect(bidRequests[3].bids[0].finalSource).equals('client'); - expect(bidRequests[3].bids[1].bidder).equals('rubicon'); - expect(bidRequests[3].bids[1].finalSource).equals('client'); - }); - - it( - 'should surpress client side bids if no ad unit bidSources are set, ' + - 'but bidderControl resolves to server', - () => { - const ads = removeAdUnitsBidSource(getServerTestingsAds()); - - const bidRequests = makeBidRequests(ads); - - expect(bidRequests).lengthOf(2); - - expect(bidRequests[0].bids).lengthOf(1); - expect(bidRequests[0].bids[0].bidder).equals('openx'); - expect(bidRequests[0].bids[0].finalSource).equals('server'); - - expect(bidRequests[1].bids).lengthOf(2); - expect(bidRequests[1].bids[0].bidder).equals('rubicon'); - expect(bidRequests[1].bids[0].finalSource).equals('server'); - } - ); - }); - - describe('Multiple s2sTesting - testServerOnly', () => { - beforeEach(() => { - config.setConfig({s2sConfig: [getServerTestingConfig(CONFIG), CONFIG2]}); - }); - - afterEach(() => { - config.resetConfig() - allS2SBidders.length = 0; - s2sTesting.bidSource = {}; - }); - - const makeBidRequests = ads => { - let bidRequests = adapterManager.makeBidRequests( - ads, 1111, 2222, 1000 - ); - - bidRequests.sort((a, b) => { - if (a.bidderCode < b.bidderCode) return -1; - if (a.bidderCode > b.bidderCode) return 1; - return 0; - }); - - return bidRequests; - }; - - const removeAdUnitsBidSource = adUnits => adUnits.map(adUnit => { - const newAdUnit = { ...adUnit }; - newAdUnit.bids = newAdUnit.bids.map(bid => { - if (bid.bidSource) delete bid.bidSource; - return bid; - }); - return newAdUnit; - }); - - it('suppresses all client bids if there are server bids resulting from bidSource at the adUnit Level', () => { - let ads = getServerTestingsAds(); - ads.push({ - code: 'test_div_5', - sizes: [[300, 250]], - bids: [{ bidder: 'pubmatic' }] - }) - const bidRequests = makeBidRequests(ads); - - expect(bidRequests).lengthOf(3); - - expect(bidRequests[0].bids).lengthOf(1); - expect(bidRequests[0].bids[0].bidder).equals('openx'); - expect(bidRequests[0].bids[0].finalSource).equals('server'); - - expect(bidRequests[0].bids).lengthOf(1); - expect(bidRequests[1].bids[0].bidder).equals('pubmatic'); - expect(bidRequests[1].bids[0].finalSource).equals('server'); - - expect(bidRequests[0].bids).lengthOf(1); - expect(bidRequests[2].bids[0].bidder).equals('rubicon'); - expect(bidRequests[2].bids[0].finalSource).equals('server'); - }); - - it('should not surpress client side bids if testServerOnly is true in one config, ' + - ',bidderControl resolves to server in another config' + - 'and there are no bid with bidSource at the adUnit Level', () => { - let testConfig1 = utils.deepClone(getServerTestingConfig(CONFIG)); - let testConfig2 = utils.deepClone(CONFIG2); - testConfig1.testServerOnly = false; - testConfig2.testServerOnly = true; - testConfig2.testing = true; - testConfig2.bidderControl = { - 'pubmatic': { - bidSource: { server: 0, client: 100 }, - includeSourceKvp: true, - }, - }; - config.setConfig({s2sConfig: [testConfig1, testConfig2]}); - - let ads = [ - { - code: 'test_div_1', - sizes: [[300, 250]], - bids: [{ bidder: 'adequant' }] - }, - { - code: 'test_div_2', - sizes: [[300, 250]], - bids: [{ bidder: 'openx' }] - }, - { - code: 'test_div_3', - sizes: [[300, 250]], - bids: [{ bidder: 'pubmatic' }] - }, - ]; - const bidRequests = makeBidRequests(ads); - - expect(bidRequests).lengthOf(3); - - expect(bidRequests[0].bids).lengthOf(1); - expect(bidRequests[0].bids[0].bidder).equals('adequant'); - expect(bidRequests[0].bids[0].finalSource).equals('client'); - - expect(bidRequests[1].bids).lengthOf(1); - expect(bidRequests[1].bids[0].bidder).equals('openx'); - expect(bidRequests[1].bids[0].finalSource).equals('server'); - - expect(bidRequests[2].bids).lengthOf(1); - expect(bidRequests[2].bids[0].bidder).equals('pubmatic'); - expect(bidRequests[2].bids[0].finalSource).equals('client'); - }); - - // todo: update description - it('suppresses all, and only, client bids if there are bids resulting from bidSource at the adUnit Level', () => { - const ads = getServerTestingsAds(); - - // change this adUnit to be server based - ads[1].bids[1].bidSource.client = 0; - ads[1].bids[1].bidSource.server = 100; - - const bidRequests = makeBidRequests(ads); - - expect(bidRequests).lengthOf(3); - - expect(bidRequests[0].bids).lengthOf(1); - expect(bidRequests[0].bids[0].bidder).equals('appnexus'); - expect(bidRequests[0].bids[0].finalSource).equals('server'); - - expect(bidRequests[1].bids).lengthOf(1); - expect(bidRequests[1].bids[0].bidder).equals('openx'); - expect(bidRequests[1].bids[0].finalSource).equals('server'); - - expect(bidRequests[2].bids).lengthOf(1); - expect(bidRequests[2].bids[0].bidder).equals('rubicon'); - expect(bidRequests[2].bids[0].finalSource).equals('server'); - }); - - // we have a server call now - it('does not suppress client bids if no "test case" bids result in a server bid', () => { - const ads = getServerTestingsAds(); - - // change this adUnit to be client based - ads[0].bids[0].bidSource.client = 100; - ads[0].bids[0].bidSource.server = 0; - - const bidRequests = makeBidRequests(ads); - - expect(bidRequests).lengthOf(4); - - expect(bidRequests[0].bids).lengthOf(1); - expect(bidRequests[0].bids[0].bidder).equals('adequant'); - expect(bidRequests[0].bids[0].finalSource).equals('client'); - - expect(bidRequests[1].bids).lengthOf(2); - expect(bidRequests[1].bids[0].bidder).equals('appnexus'); - expect(bidRequests[1].bids[0].finalSource).equals('client'); - expect(bidRequests[1].bids[1].bidder).equals('appnexus'); - expect(bidRequests[1].bids[1].finalSource).equals('client'); - - expect(bidRequests[2].bids).lengthOf(1); - expect(bidRequests[2].bids[0].bidder).equals('openx'); - expect(bidRequests[2].bids[0].finalSource).equals('server'); - - expect(bidRequests[3].bids).lengthOf(2); - expect(bidRequests[3].bids[0].bidder).equals('rubicon'); - expect(bidRequests[3].bids[0].finalSource).equals('client'); - expect(bidRequests[3].bids[1].bidder).equals('rubicon'); - expect(bidRequests[3].bids[1].finalSource).equals('client'); - }); - - it( - 'should surpress client side bids if no ad unit bidSources are set, ' + - 'but bidderControl resolves to server', - () => { - const ads = removeAdUnitsBidSource(getServerTestingsAds()); - - const bidRequests = makeBidRequests(ads); - - expect(bidRequests).lengthOf(2); - - expect(bidRequests[0].bids).lengthOf(1); - expect(bidRequests[0].bids[0].bidder).equals('openx'); - expect(bidRequests[0].bids[0].finalSource).equals('server'); - - expect(bidRequests[1].bids).lengthOf(2); - expect(bidRequests[1].bids[0].bidder).equals('rubicon'); - expect(bidRequests[1].bids[0].finalSource).equals('server'); - } - ); - }); - }); -}); diff --git a/test/spec/unit/core/bidderFactory_spec.js b/test/spec/unit/core/bidderFactory_spec.js deleted file mode 100644 index a7e8a0d7871..00000000000 --- a/test/spec/unit/core/bidderFactory_spec.js +++ /dev/null @@ -1,1021 +0,0 @@ -import { newBidder, registerBidder, preloadBidderMappingFile, storage } from 'src/adapters/bidderFactory.js'; -import adapterManager from 'src/adapterManager.js'; -import * as ajax from 'src/ajax.js'; -import { expect } from 'chai'; -import { userSync } from 'src/userSync.js' -import * as utils from 'src/utils.js'; -import { config } from 'src/config.js'; -import { server } from 'test/mocks/xhr.js'; - -const CODE = 'sampleBidder'; -const MOCK_BIDS_REQUEST = { - bids: [ - { - bidId: 1, - auctionId: 'first-bid-id', - adUnitCode: 'mock/placement', - params: { - param: 5 - } - }, - { - bidId: 2, - auctionId: 'second-bid-id', - adUnitCode: 'mock/placement2', - params: { - badParam: 6 - } - } - ] -} - -function onTimelyResponseStub() { - -} - -let wrappedCallback = config.callbackWithBidder(CODE); - -describe('bidders created by newBidder', function () { - let spec; - let bidder; - let addBidResponseStub; - let doneStub; - - beforeEach(function () { - spec = { - code: CODE, - isBidRequestValid: sinon.stub(), - buildRequests: sinon.stub(), - interpretResponse: sinon.stub(), - getUserSyncs: sinon.stub() - }; - - addBidResponseStub = sinon.stub(); - doneStub = sinon.stub(); - }); - - describe('when the ajax response is irrelevant', function () { - let ajaxStub; - let getConfigSpy; - - beforeEach(function () { - ajaxStub = sinon.stub(ajax, 'ajax'); - addBidResponseStub.reset(); - getConfigSpy = sinon.spy(config, 'getConfig'); - doneStub.reset(); - }); - - afterEach(function () { - ajaxStub.restore(); - getConfigSpy.restore(); - }); - - it('should let registerSyncs run with invalid alias and aliasSync enabled', function () { - config.setConfig({ - userSync: { - aliasSyncEnabled: true - } - }); - spec.code = 'fakeBidder'; - const bidder = newBidder(spec); - bidder.callBids({ bids: [] }, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - expect(getConfigSpy.withArgs('userSync.filterSettings').calledOnce).to.equal(true); - }); - - it('should let registerSyncs run with valid alias and aliasSync enabled', function () { - config.setConfig({ - userSync: { - aliasSyncEnabled: true - } - }); - spec.code = 'aliasBidder'; - const bidder = newBidder(spec); - bidder.callBids({ bids: [] }, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - expect(getConfigSpy.withArgs('userSync.filterSettings').calledOnce).to.equal(true); - }); - - it('should let registerSyncs run with invalid alias and aliasSync disabled', function () { - config.setConfig({ - userSync: { - aliasSyncEnabled: false - } - }); - spec.code = 'fakeBidder'; - const bidder = newBidder(spec); - bidder.callBids({ bids: [] }, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - expect(getConfigSpy.withArgs('userSync.filterSettings').calledOnce).to.equal(true); - }); - - it('should not let registerSyncs run with valid alias and aliasSync disabled', function () { - config.setConfig({ - userSync: { - aliasSyncEnabled: false - } - }); - spec.code = 'aliasBidder'; - const bidder = newBidder(spec); - bidder.callBids({ bids: [] }, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - expect(getConfigSpy.withArgs('userSync.filterSettings').calledOnce).to.equal(false); - }); - - it('should handle bad bid requests gracefully', function () { - const bidder = newBidder(spec); - - spec.getUserSyncs.returns([]); - - bidder.callBids({}); - bidder.callBids({ bids: 'nothing useful' }, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(ajaxStub.called).to.equal(false); - expect(spec.isBidRequestValid.called).to.equal(false); - expect(spec.buildRequests.called).to.equal(false); - expect(spec.interpretResponse.called).to.equal(false); - }); - - it('should call buildRequests(bidRequest) the params are valid', function () { - const bidder = newBidder(spec); - - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns([]); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(ajaxStub.called).to.equal(false); - expect(spec.isBidRequestValid.calledTwice).to.equal(true); - expect(spec.buildRequests.calledOnce).to.equal(true); - expect(spec.buildRequests.firstCall.args[0]).to.deep.equal(MOCK_BIDS_REQUEST.bids); - }); - - it('should not call buildRequests the params are invalid', function () { - const bidder = newBidder(spec); - - spec.isBidRequestValid.returns(false); - spec.buildRequests.returns([]); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(ajaxStub.called).to.equal(false); - expect(spec.isBidRequestValid.calledTwice).to.equal(true); - expect(spec.buildRequests.called).to.equal(false); - }); - - it('should filter out invalid bids before calling buildRequests', function () { - const bidder = newBidder(spec); - - spec.isBidRequestValid.onFirstCall().returns(true); - spec.isBidRequestValid.onSecondCall().returns(false); - spec.buildRequests.returns([]); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(ajaxStub.called).to.equal(false); - expect(spec.isBidRequestValid.calledTwice).to.equal(true); - expect(spec.buildRequests.calledOnce).to.equal(true); - expect(spec.buildRequests.firstCall.args[0]).to.deep.equal([MOCK_BIDS_REQUEST.bids[0]]); - }); - - it('should make no server requests if the spec doesn\'t return any', function () { - const bidder = newBidder(spec); - - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns([]); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(ajaxStub.called).to.equal(false); - }); - - it('should make the appropriate POST request', function () { - const bidder = newBidder(spec); - const url = 'test.url.com'; - const data = { arg: 2 }; - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns({ - method: 'POST', - url: url, - data: data - }); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(ajaxStub.calledOnce).to.equal(true); - expect(ajaxStub.firstCall.args[0]).to.equal(url); - expect(ajaxStub.firstCall.args[2]).to.equal(JSON.stringify(data)); - expect(ajaxStub.firstCall.args[3]).to.deep.equal({ - method: 'POST', - contentType: 'text/plain', - withCredentials: true - }); - }); - - it('should make the appropriate POST request when options are passed', function () { - const bidder = newBidder(spec); - const url = 'test.url.com'; - const data = { arg: 2 }; - const options = { contentType: 'application/json' }; - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns({ - method: 'POST', - url: url, - data: data, - options: options - }); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(ajaxStub.calledOnce).to.equal(true); - expect(ajaxStub.firstCall.args[0]).to.equal(url); - expect(ajaxStub.firstCall.args[2]).to.equal(JSON.stringify(data)); - expect(ajaxStub.firstCall.args[3]).to.deep.equal({ - method: 'POST', - contentType: 'application/json', - withCredentials: true - }); - }); - - it('should make the appropriate GET request', function () { - const bidder = newBidder(spec); - const url = 'test.url.com'; - const data = { arg: 2 }; - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns({ - method: 'GET', - url: url, - data: data - }); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(ajaxStub.calledOnce).to.equal(true); - expect(ajaxStub.firstCall.args[0]).to.equal(`${url}?arg=2`); - expect(ajaxStub.firstCall.args[2]).to.be.undefined; - expect(ajaxStub.firstCall.args[3]).to.deep.equal({ - method: 'GET', - withCredentials: true - }); - }); - - it('should make the appropriate GET request when options are passed', function () { - const bidder = newBidder(spec); - const url = 'test.url.com'; - const data = { arg: 2 }; - const opt = { withCredentials: false } - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns({ - method: 'GET', - url: url, - data: data, - options: opt - }); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(ajaxStub.calledOnce).to.equal(true); - expect(ajaxStub.firstCall.args[0]).to.equal(`${url}?arg=2`); - expect(ajaxStub.firstCall.args[2]).to.be.undefined; - expect(ajaxStub.firstCall.args[3]).to.deep.equal({ - method: 'GET', - withCredentials: false - }); - }); - - it('should make multiple calls if the spec returns them', function () { - const bidder = newBidder(spec); - const url = 'test.url.com'; - const data = { arg: 2 }; - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns([ - { - method: 'POST', - url: url, - data: data - }, - { - method: 'GET', - url: url, - data: data - } - ]); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(ajaxStub.calledTwice).to.equal(true); - }); - - it('should not add bids for each placement code if no requests are given', function () { - const bidder = newBidder(spec); - - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns([]); - spec.interpretResponse.returns([]); - spec.getUserSyncs.returns([]); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(addBidResponseStub.callCount).to.equal(0); - }); - }); - - describe('when the ajax call succeeds', function () { - let ajaxStub; - let userSyncStub; - let logErrorSpy; - - beforeEach(function () { - ajaxStub = sinon.stub(ajax, 'ajax').callsFake(function(url, callbacks) { - const fakeResponse = sinon.stub(); - fakeResponse.returns('headerContent'); - callbacks.success('response body', { getResponseHeader: fakeResponse }); - }); - addBidResponseStub.reset(); - doneStub.resetBehavior(); - userSyncStub = sinon.stub(userSync, 'registerSync') - logErrorSpy = sinon.spy(utils, 'logError'); - }); - - afterEach(function () { - ajaxStub.restore(); - userSyncStub.restore(); - utils.logError.restore(); - }); - - it('should call spec.interpretResponse() with the response content', function () { - const bidder = newBidder(spec); - - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns({ - method: 'POST', - url: 'test.url.com', - data: {} - }); - spec.getUserSyncs.returns([]); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(spec.interpretResponse.calledOnce).to.equal(true); - const response = spec.interpretResponse.firstCall.args[0] - expect(response.body).to.equal('response body') - expect(response.headers.get('some-header')).to.equal('headerContent'); - expect(spec.interpretResponse.firstCall.args[1]).to.deep.equal({ - method: 'POST', - url: 'test.url.com', - data: {} - }); - expect(doneStub.calledOnce).to.equal(true); - }); - - it('should call spec.interpretResponse() once for each request made', function () { - const bidder = newBidder(spec); - - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns([ - { - method: 'POST', - url: 'test.url.com', - data: {} - }, - { - method: 'POST', - url: 'test.url.com', - data: {} - }, - ]); - spec.getUserSyncs.returns([]); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(spec.interpretResponse.calledTwice).to.equal(true); - expect(doneStub.calledOnce).to.equal(true); - }); - - it('should only add bids for valid adUnit code into the auction, even if the bidder doesn\'t bid on all of them', function () { - const bidder = newBidder(spec); - - const bid = { - creativeId: 'creative-id', - requestId: '1', - ad: 'ad-url.com', - cpm: 0.5, - height: 200, - width: 300, - adUnitCode: 'mock/placement', - currency: 'USD', - netRevenue: true, - ttl: 300, - bidderCode: 'sampleBidder', - sampleBidder: {advertiserId: '12345', networkId: '111222'} - }; - const bidderRequest = Object.assign({}, MOCK_BIDS_REQUEST); - bidderRequest.bids[0].bidder = 'sampleBidder'; - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns({ - method: 'POST', - url: 'test.url.com', - data: {} - }); - spec.getUserSyncs.returns([]); - - spec.interpretResponse.returns(bid); - - bidder.callBids(bidderRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(addBidResponseStub.calledOnce).to.equal(true); - expect(addBidResponseStub.firstCall.args[0]).to.equal('mock/placement'); - let bidObject = addBidResponseStub.firstCall.args[1]; - // checking the fields added by our code - expect(bidObject.originalCpm).to.equal(bid.cpm); - expect(bidObject.originalCurrency).to.equal(bid.currency); - expect(doneStub.calledOnce).to.equal(true); - expect(logErrorSpy.callCount).to.equal(0); - expect(bidObject.meta).to.exist; - expect(bidObject.meta).to.deep.equal({advertiserId: '12345', networkId: '111222'}); - }); - - it('should call spec.getUserSyncs() with the response', function () { - const bidder = newBidder(spec); - - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns({ - method: 'POST', - url: 'test.url.com', - data: {} - }); - spec.getUserSyncs.returns([]); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(spec.getUserSyncs.calledOnce).to.equal(true); - expect(spec.getUserSyncs.firstCall.args[1].length).to.equal(1); - expect(spec.getUserSyncs.firstCall.args[1][0].body).to.equal('response body'); - expect(spec.getUserSyncs.firstCall.args[1][0].headers).to.have.property('get'); - expect(spec.getUserSyncs.firstCall.args[1][0].headers.get).to.be.a('function'); - }); - - it('should register usersync pixels', function () { - const bidder = newBidder(spec); - - spec.isBidRequestValid.returns(false); - spec.buildRequests.returns([]); - spec.getUserSyncs.returns([{ - type: 'iframe', - url: 'usersync.com' - }]); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(userSyncStub.called).to.equal(true); - expect(userSyncStub.firstCall.args[0]).to.equal('iframe'); - expect(userSyncStub.firstCall.args[1]).to.equal(spec.code); - expect(userSyncStub.firstCall.args[2]).to.equal('usersync.com'); - }); - - it('should logError when required bid response params are missing', function () { - const bidder = newBidder(spec); - - const bid = { - requestId: '1', - ad: 'ad-url.com', - cpm: 0.5, - height: 200, - width: 300, - placementCode: 'mock/placement' - }; - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns({ - method: 'POST', - url: 'test.url.com', - data: {} - }); - spec.getUserSyncs.returns([]); - - spec.interpretResponse.returns(bid); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(logErrorSpy.calledOnce).to.equal(true); - }); - - it('should logError when required bid response params are undefined', function () { - const bidder = newBidder(spec); - - const bid = { - 'ad': 'creative', - 'cpm': '1.99', - 'width': 300, - 'height': 250, - 'requestId': '1', - 'creativeId': 'some-id', - 'currency': undefined, - 'netRevenue': true, - 'ttl': 360 - }; - - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns({ - method: 'POST', - url: 'test.url.com', - data: {} - }); - spec.getUserSyncs.returns([]); - - spec.interpretResponse.returns(bid); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(logErrorSpy.calledOnce).to.equal(true); - }); - }); - - describe('when the ajax call fails', function () { - let ajaxStub; - - beforeEach(function () { - ajaxStub = sinon.stub(ajax, 'ajax').callsFake(function(url, callbacks) { - callbacks.error('ajax call failed.'); - }); - addBidResponseStub.reset(); - doneStub.reset(); - }); - - afterEach(function () { - ajaxStub.restore(); - }); - - it('should not spec.interpretResponse()', function () { - const bidder = newBidder(spec); - - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns({ - method: 'POST', - url: 'test.url.com', - data: {} - }); - spec.getUserSyncs.returns([]); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(spec.interpretResponse.called).to.equal(false); - expect(doneStub.calledOnce).to.equal(true); - }); - - it('should not add bids for each adunit code into the auction', function () { - const bidder = newBidder(spec); - - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns({ - method: 'POST', - url: 'test.url.com', - data: {} - }); - spec.interpretResponse.returns([]); - spec.getUserSyncs.returns([]); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(addBidResponseStub.callCount).to.equal(0); - expect(doneStub.calledOnce).to.equal(true); - }); - - it('should call spec.getUserSyncs() with no responses', function () { - const bidder = newBidder(spec); - - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns({ - method: 'POST', - url: 'test.url.com', - data: {} - }); - spec.getUserSyncs.returns([]); - - bidder.callBids(MOCK_BIDS_REQUEST, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(spec.getUserSyncs.calledOnce).to.equal(true); - expect(spec.getUserSyncs.firstCall.args[1]).to.deep.equal([]); - expect(doneStub.calledOnce).to.equal(true); - }); - }); -}); - -describe('registerBidder', function () { - let registerBidAdapterStub; - let aliasBidAdapterStub; - - beforeEach(function () { - registerBidAdapterStub = sinon.stub(adapterManager, 'registerBidAdapter'); - aliasBidAdapterStub = sinon.stub(adapterManager, 'aliasBidAdapter'); - }); - - afterEach(function () { - registerBidAdapterStub.restore(); - aliasBidAdapterStub.restore(); - }); - - function newEmptySpec() { - return { - code: CODE, - isBidRequestValid: function() { }, - buildRequests: function() { }, - interpretResponse: function() { }, - }; - } - - it('should register a bidder with the adapterManager', function () { - registerBidder(newEmptySpec()); - expect(registerBidAdapterStub.calledOnce).to.equal(true); - expect(registerBidAdapterStub.firstCall.args[0]).to.have.property('callBids'); - expect(registerBidAdapterStub.firstCall.args[0].callBids).to.be.a('function'); - - expect(registerBidAdapterStub.firstCall.args[1]).to.equal(CODE); - expect(registerBidAdapterStub.firstCall.args[2]).to.be.undefined; - }); - - it('should register a bidder with the appropriate mediaTypes', function () { - const thisSpec = Object.assign(newEmptySpec(), { supportedMediaTypes: ['video'] }); - registerBidder(thisSpec); - expect(registerBidAdapterStub.calledOnce).to.equal(true); - expect(registerBidAdapterStub.firstCall.args[2]).to.deep.equal({supportedMediaTypes: ['video']}); - }); - - it('should register bidders with the appropriate aliases', function () { - const thisSpec = Object.assign(newEmptySpec(), { aliases: ['foo', 'bar'] }); - registerBidder(thisSpec); - - expect(registerBidAdapterStub.calledThrice).to.equal(true); - - // Make sure our later calls don't override the bidder code from previous calls. - expect(registerBidAdapterStub.firstCall.args[0].getBidderCode()).to.equal(CODE); - expect(registerBidAdapterStub.secondCall.args[0].getBidderCode()).to.equal('foo') - expect(registerBidAdapterStub.thirdCall.args[0].getBidderCode()).to.equal('bar') - - expect(registerBidAdapterStub.firstCall.args[1]).to.equal(CODE); - expect(registerBidAdapterStub.secondCall.args[1]).to.equal('foo') - expect(registerBidAdapterStub.thirdCall.args[1]).to.equal('bar') - }); - - it('should register alias with their gvlid', function() { - const aliases = [ - { - code: 'foo', - gvlid: 1 - }, - { - code: 'bar', - gvlid: 2 - }, - { - code: 'baz' - } - ] - const thisSpec = Object.assign(newEmptySpec(), { aliases: aliases }); - registerBidder(thisSpec); - - expect(registerBidAdapterStub.getCall(1).args[0].getSpec().gvlid).to.equal(1); - expect(registerBidAdapterStub.getCall(2).args[0].getSpec().gvlid).to.equal(2); - expect(registerBidAdapterStub.getCall(3).args[0].getSpec().gvlid).to.equal(undefined); - }) - - it('should register alias with skipPbsAliasing', function() { - const aliases = [ - { - code: 'foo', - skipPbsAliasing: true - }, - { - code: 'bar', - skipPbsAliasing: false - }, - { - code: 'baz' - } - ] - const thisSpec = Object.assign(newEmptySpec(), { aliases: aliases }); - registerBidder(thisSpec); - - expect(registerBidAdapterStub.getCall(1).args[0].getSpec().skipPbsAliasing).to.equal(true); - expect(registerBidAdapterStub.getCall(2).args[0].getSpec().skipPbsAliasing).to.equal(false); - expect(registerBidAdapterStub.getCall(3).args[0].getSpec().skipPbsAliasing).to.equal(undefined); - }) -}) - -describe('validate bid response: ', function () { - let spec; - let bidder; - let addBidResponseStub; - let doneStub; - let ajaxStub; - let logErrorSpy; - - let bids = [{ - 'ad': 'creative', - 'cpm': '1.99', - 'width': 300, - 'height': 250, - 'requestId': '1', - 'creativeId': 'some-id', - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 360 - }]; - - beforeEach(function () { - spec = { - code: CODE, - isBidRequestValid: sinon.stub(), - buildRequests: sinon.stub(), - interpretResponse: sinon.stub(), - }; - - spec.isBidRequestValid.returns(true); - spec.buildRequests.returns({ - method: 'POST', - url: 'test.url.com', - data: {} - }); - - addBidResponseStub = sinon.stub(); - doneStub = sinon.stub(); - ajaxStub = sinon.stub(ajax, 'ajax').callsFake(function(url, callbacks) { - const fakeResponse = sinon.stub(); - fakeResponse.returns('headerContent'); - callbacks.success('response body', { getResponseHeader: fakeResponse }); - }); - logErrorSpy = sinon.spy(utils, 'logError'); - }); - - afterEach(function () { - ajaxStub.restore(); - logErrorSpy.restore(); - }); - - it('should add native bids that do have required assets', function () { - let bidRequest = { - bids: [{ - bidId: '1', - auctionId: 'first-bid-id', - adUnitCode: 'mock/placement', - params: { - param: 5 - }, - nativeParams: { - title: {'required': true}, - }, - mediaType: 'native', - }] - }; - - let bids1 = Object.assign({}, - bids[0], - { - 'mediaType': 'native', - 'native': { - 'title': 'Native Creative', - 'clickUrl': 'https://www.link.example', - } - } - ); - - const bidder = newBidder(spec); - - spec.interpretResponse.returns(bids1); - bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(addBidResponseStub.calledOnce).to.equal(true); - expect(addBidResponseStub.firstCall.args[0]).to.equal('mock/placement'); - expect(logErrorSpy.callCount).to.equal(0); - }); - - it('should not add native bids that do not have required assets', function () { - let bidRequest = { - bids: [{ - bidId: '1', - auctionId: 'first-bid-id', - adUnitCode: 'mock/placement', - params: { - param: 5 - }, - nativeParams: { - title: {'required': true}, - }, - mediaType: 'native', - }] - }; - - let bids1 = Object.assign({}, - bids[0], - { - bidderCode: CODE, - mediaType: 'native', - native: { - title: undefined, - clickUrl: 'https://www.link.example', - } - } - ); - - const bidder = newBidder(spec); - spec.interpretResponse.returns(bids1); - bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(addBidResponseStub.calledOnce).to.equal(false); - expect(logErrorSpy.callCount).to.equal(1); - }); - - it('should add bid when renderer is present on outstream bids', function () { - let bidRequest = { - bids: [{ - bidId: '1', - auctionId: 'first-bid-id', - adUnitCode: 'mock/placement', - params: { - param: 5 - }, - mediaTypes: { - video: {context: 'outstream'} - } - }] - }; - - let bids1 = Object.assign({}, - bids[0], - { - bidderCode: CODE, - mediaType: 'video', - renderer: {render: () => true, url: 'render.js'}, - } - ); - - const bidder = newBidder(spec); - - spec.interpretResponse.returns(bids1); - bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(addBidResponseStub.calledOnce).to.equal(true); - expect(addBidResponseStub.firstCall.args[0]).to.equal('mock/placement'); - expect(logErrorSpy.callCount).to.equal(0); - }); - - it('should add banner bids that have no width or height but single adunit size', function () { - let bidRequest = { - bids: [{ - bidder: CODE, - bidId: '1', - auctionId: 'first-bid-id', - adUnitCode: 'mock/placement', - params: { - param: 5 - }, - sizes: [[300, 250]], - }] - }; - - let bids1 = Object.assign({}, - bids[0], - { - width: undefined, - height: undefined - } - ); - - const bidder = newBidder(spec); - - spec.interpretResponse.returns(bids1); - bidder.callBids(bidRequest, addBidResponseStub, doneStub, ajaxStub, onTimelyResponseStub, wrappedCallback); - - expect(addBidResponseStub.calledOnce).to.equal(true); - expect(addBidResponseStub.firstCall.args[0]).to.equal('mock/placement'); - expect(logErrorSpy.callCount).to.equal(0); - }); -}); - -describe('preload mapping url hook', function() { - let fakeTranslationServer; - let getLocalStorageStub; - let adapterManagerStub; - let adUnits = [{ - code: 'midroll_1', - mediaTypes: { - video: { - context: 'adpod' - } - }, - bids: [ - { - bidder: 'sampleBidder1', - params: { - placementId: 14542875, - } - } - ] - }]; - - beforeEach(function () { - fakeTranslationServer = server; - getLocalStorageStub = sinon.stub(storage, 'getDataFromLocalStorage'); - adapterManagerStub = sinon.stub(adapterManager, 'getBidAdapter'); - config.setConfig({ - 'adpod': { - 'brandCategoryExclusion': true - } - }); - adapterManagerStub.withArgs('sampleBidder1').returns({ - getSpec: function() { - return { - 'getMappingFileInfo': function() { - return { - url: 'http://sample.com', - refreshInDays: 7, - key: `sampleBidder1MappingFile` - } - } - } - } - }); - }); - - afterEach(function() { - getLocalStorageStub.restore(); - adapterManagerStub.restore(); - config.resetConfig(); - }); - - it('should preload mapping url file', function() { - getLocalStorageStub.returns(null); - preloadBidderMappingFile(sinon.spy(), adUnits); - expect(fakeTranslationServer.requests.length).to.equal(1); - }); - - it('should preload mapping url file for all bidders', function() { - let adUnits = [{ - code: 'midroll_1', - mediaTypes: { - video: { - context: 'adpod' - } - }, - bids: [ - { - bidder: 'sampleBidder1', - params: { - placementId: 14542875, - } - }, - { - bidder: 'sampleBidder2', - params: { - placementId: 123456, - } - } - ] - }]; - getLocalStorageStub.returns(null); - adapterManagerStub.withArgs('sampleBidder2').returns({ - getSpec: function() { - return { - 'getMappingFileInfo': function() { - return { - url: 'http://sample.com', - refreshInDays: 7, - key: `sampleBidder2MappingFile` - } - } - } - } - }); - preloadBidderMappingFile(sinon.spy(), adUnits); - expect(fakeTranslationServer.requests.length).to.equal(2); - - config.setConfig({ - 'adpod': { - 'brandCategoryExclusion': false - } - }); - preloadBidderMappingFile(sinon.spy(), adUnits); - expect(fakeTranslationServer.requests.length).to.equal(2); - }); - - it('should make ajax call to update mapping file if data found in localstorage is expired', function() { - let clock = sinon.useFakeTimers(utils.timestamp()); - getLocalStorageStub.returns(JSON.stringify({ - lastUpdated: utils.timestamp() - 8 * 24 * 60 * 60 * 1000, - mapping: { - 'iab-1': '1' - } - })); - preloadBidderMappingFile(sinon.spy(), adUnits); - expect(fakeTranslationServer.requests.length).to.equal(1); - clock.restore(); - }); - - it('should not make ajax call to update mapping file if data found in localstorage and is not expired', function () { - let clock = sinon.useFakeTimers(utils.timestamp()); - getLocalStorageStub.returns(JSON.stringify({ - lastUpdated: utils.timestamp(), - mapping: { - 'iab-1': '1' - } - })); - preloadBidderMappingFile(sinon.spy(), adUnits); - expect(fakeTranslationServer.requests.length).to.equal(0); - clock.restore(); - }); -}); diff --git a/test/spec/unit/core/storageManager_spec.js b/test/spec/unit/core/storageManager_spec.js deleted file mode 100644 index 5bb766217f5..00000000000 --- a/test/spec/unit/core/storageManager_spec.js +++ /dev/null @@ -1,98 +0,0 @@ -import { resetData, getCoreStorageManager, storageCallbacks, getStorageManager } from 'src/storageManager.js'; -import { config } from 'src/config.js'; -import * as utils from 'src/utils.js'; - -describe('storage manager', function() { - beforeEach(function() { - resetData(); - }); - - afterEach(function() { - config.resetConfig(); - }) - - it('should allow to set cookie for core modules without checking gdpr enforcements', function() { - const coreStorage = getCoreStorageManager(); - let date = new Date(); - date.setTime(date.getTime() + (24 * 60 * 60 * 1000)); - let expires = date.toUTCString(); - coreStorage.setCookie('hello', 'world', expires); - expect(coreStorage.getCookie('hello')).to.equal('world'); - }); - - it('should add done callbacks to storageCallbacks array', function() { - let noop = sinon.spy(); - const coreStorage = getStorageManager(); - - coreStorage.setCookie('foo', 'bar', null, null, null, noop); - coreStorage.getCookie('foo', noop); - coreStorage.localStorageIsEnabled(noop); - coreStorage.cookiesAreEnabled(noop); - coreStorage.setDataInLocalStorage('foo', 'bar', noop); - coreStorage.getDataFromLocalStorage('foo', noop); - coreStorage.removeDataFromLocalStorage('foo', noop); - coreStorage.hasLocalStorage(noop); - - expect(storageCallbacks.length).to.equal(8); - }); - - it('should allow bidder to access device if gdpr enforcement module is not included', function() { - let deviceAccessSpy = sinon.spy(utils, 'hasDeviceAccess'); - const storage = getStorageManager(); - storage.setCookie('foo1', 'baz1'); - expect(deviceAccessSpy.calledOnce).to.equal(true); - deviceAccessSpy.restore(); - }); - - describe('localstorage forbidden access in 3rd-party context', function() { - let errorLogSpy; - let originalLocalStorage; - const localStorageMock = { get: () => { throw Error } }; - - beforeEach(function() { - originalLocalStorage = window.localStorage; - Object.defineProperty(window, 'localStorage', localStorageMock); - errorLogSpy = sinon.spy(utils, 'logError'); - }); - - afterEach(function() { - Object.defineProperty(window, 'localStorage', { get: () => originalLocalStorage }); - errorLogSpy.restore(); - }) - - it('should not throw if the localstorage is not accessible when setting/getting/removing from localstorage', function() { - const coreStorage = getStorageManager(); - - coreStorage.setDataInLocalStorage('key', 'value'); - const val = coreStorage.getDataFromLocalStorage('key'); - coreStorage.removeDataFromLocalStorage('key'); - - expect(val).to.be.null; - sinon.assert.calledThrice(errorLogSpy); - }) - }) - - describe('localstorage is enabled', function() { - let localStorage; - - beforeEach(function() { - localStorage = window.localStorage; - localStorage.clear(); - }); - - afterEach(function() { - localStorage.clear(); - }) - - it('should remove side-effect after checking', function () { - const storage = getStorageManager(); - - localStorage.setItem('unrelated', 'dummy'); - const val = storage.localStorageIsEnabled(); - - expect(val).to.be.true; - expect(localStorage.length).to.be.eq(1); - expect(localStorage.getItem('unrelated')).to.be.eq('dummy'); - }); - }); -}); diff --git a/test/spec/unit/core/targeting_spec.js b/test/spec/unit/core/targeting_spec.js deleted file mode 100644 index 5d43ed48266..00000000000 --- a/test/spec/unit/core/targeting_spec.js +++ /dev/null @@ -1,973 +0,0 @@ -import { expect } from 'chai'; -import { targeting as targetingInstance, filters, getHighestCpmBidsFromBidPool, sortByDealAndPriceBucketOrCpm } from 'src/targeting.js'; -import { config } from 'src/config.js'; -import { getAdUnits, createBidReceived } from 'test/fixtures/fixtures.js'; -import CONSTANTS from 'src/constants.json'; -import { auctionManager } from 'src/auctionManager.js'; -import * as utils from 'src/utils.js'; - -const bid1 = { - 'bidderCode': 'rubicon', - 'width': '300', - 'height': '250', - 'statusMessage': 'Bid available', - 'adId': '148018fe5e', - 'cpm': 0.537234, - 'ad': 'markup', - 'ad_id': '3163950', - 'sizeId': '15', - 'requestTimestamp': 1454535718610, - 'responseTimestamp': 1454535724863, - 'timeToRespond': 123, - 'pbLg': '0.50', - 'pbMg': '0.50', - 'pbHg': '0.53', - 'adUnitCode': '/123456/header-bid-tag-0', - 'bidder': 'rubicon', - 'size': '300x250', - 'adserverTargeting': { - 'foobar': '300x250', - [CONSTANTS.TARGETING_KEYS.BIDDER]: 'rubicon', - [CONSTANTS.TARGETING_KEYS.AD_ID]: '148018fe5e', - [CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]: '0.53', - [CONSTANTS.TARGETING_KEYS.DEAL]: '1234' - }, - 'dealId': '1234', - 'netRevenue': true, - 'currency': 'USD', - 'ttl': 300 -}; - -const bid2 = { - 'bidderCode': 'rubicon', - 'width': '300', - 'height': '250', - 'statusMessage': 'Bid available', - 'adId': '5454545', - 'cpm': 0.25, - 'ad': 'markup', - 'ad_id': '3163950', - 'sizeId': '15', - 'requestTimestamp': 1454535718610, - 'responseTimestamp': 1454535724863, - 'timeToRespond': 123, - 'pbLg': '0.25', - 'pbMg': '0.25', - 'pbHg': '0.25', - 'adUnitCode': '/123456/header-bid-tag-0', - 'bidder': 'rubicon', - 'size': '300x250', - 'adserverTargeting': { - 'foobar': '300x250', - [CONSTANTS.TARGETING_KEYS.BIDDER]: 'rubicon', - [CONSTANTS.TARGETING_KEYS.AD_ID]: '5454545', - [CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]: '0.25' - }, - 'netRevenue': true, - 'currency': 'USD', - 'ttl': 300 -}; - -const bid3 = { - 'bidderCode': 'rubicon', - 'width': '300', - 'height': '600', - 'statusMessage': 'Bid available', - 'adId': '48747745', - 'cpm': 0.75, - 'ad': 'markup', - 'ad_id': '3163950', - 'sizeId': '15', - 'requestTimestamp': 1454535718610, - 'responseTimestamp': 1454535724863, - 'timeToRespond': 123, - 'pbLg': '0.75', - 'pbMg': '0.75', - 'pbHg': '0.75', - 'adUnitCode': '/123456/header-bid-tag-1', - 'bidder': 'rubicon', - 'size': '300x600', - 'adserverTargeting': { - 'foobar': '300x600', - [CONSTANTS.TARGETING_KEYS.BIDDER]: 'rubicon', - [CONSTANTS.TARGETING_KEYS.AD_ID]: '48747745', - [CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]: '0.75' - }, - 'netRevenue': true, - 'currency': 'USD', - 'ttl': 300 -}; - -const nativeBid1 = { - 'bidderCode': 'appnexus', - 'width': 0, - 'height': 0, - 'statusMessage': 'Bid available', - 'adId': '591e7c9354b633', - 'requestId': '24aae81e32d6f6', - 'mediaType': 'native', - 'source': 'client', - 'cpm': 10, - 'creativeId': 97494403, - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 300, - 'adUnitCode': '/19968336/prebid_native_example_1', - 'appnexus': { - 'buyerMemberId': 9325 - }, - 'meta': { - 'advertiserId': 2529885 - }, - 'native': { - 'title': 'This is a Prebid Native Creative', - 'body': 'This is a Prebid Native Creative. There are many like it, but this one is mine.', - 'sponsoredBy': 'Prebid.org', - 'clickUrl': 'http://prebid.org/dev-docs/show-native-ads.html', - 'clickTrackers': ['http://www.clickUrl.com/404'], - 'impressionTrackers': ['http://imp.trackerUrl.com/it1'], - 'javascriptTrackers': '', - 'image': { - 'url': 'http://vcdn.adnxs.com/p/creative-image/94/22/cd/0f/9422cd0f-f400-45d3-80f5-2b92629d9257.jpg', - 'height': 2250, - 'width': 3000 - }, - 'icon': { - 'url': 'http://vcdn.adnxs.com/p/creative-image/bd/59/a6/c6/bd59a6c6-0851-411d-a16d-031475a51312.png', - 'height': 83, - 'width': 127 - } - }, - 'auctionId': '72138a4a-b747-4192-9192-dcc41d675de8', - 'responseTimestamp': 1565785219461, - 'requestTimestamp': 1565785219405, - 'bidder': 'appnexus', - 'timeToRespond': 56, - 'pbLg': '5.00', - 'pbMg': '10.00', - 'pbHg': '10.00', - 'pbAg': '10.00', - 'pbDg': '10.00', - 'pbCg': '', - 'size': '0x0', - 'adserverTargeting': { - [CONSTANTS.TARGETING_KEYS.BIDDER]: 'appnexus', - [CONSTANTS.TARGETING_KEYS.AD_ID]: '591e7c9354b633', - [CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]: '10.00', - [CONSTANTS.TARGETING_KEYS.SIZE]: '0x0', - [CONSTANTS.TARGETING_KEYS.SOURCE]: 'client', - [CONSTANTS.TARGETING_KEYS.FORMAT]: 'native', - [CONSTANTS.NATIVE_KEYS.title]: 'This is a Prebid Native Creative', - [CONSTANTS.NATIVE_KEYS.body]: 'This is a Prebid Native Creative. There are many like it, but this one is mine.', - [CONSTANTS.NATIVE_KEYS.sponsoredBy]: 'Prebid.org', - [CONSTANTS.NATIVE_KEYS.clickUrl]: 'http://prebid.org/dev-docs/show-native-ads.html', - [CONSTANTS.NATIVE_KEYS.image]: 'http://vcdn.adnxs.com/p/creative-image/94/22/cd/0f/9422cd0f-f400-45d3-80f5-2b92629d9257.jpg', - [CONSTANTS.NATIVE_KEYS.icon]: 'http://vcdn.adnxs.com/p/creative-image/bd/59/a6/c6/bd59a6c6-0851-411d-a16d-031475a51312.png' - } -}; -const nativeBid2 = { - 'bidderCode': 'dgads', - 'width': 0, - 'height': 0, - 'statusMessage': 'Bid available', - 'adId': '6e0aba55ed54e5', - 'requestId': '4de26ec83d9661', - 'mediaType': 'native', - 'source': 'client', - 'cpm': 1.90909091, - 'creativeId': 'xuidx6c901261b0x2b2', - 'currency': 'JPY', - 'netRevenue': true, - 'ttl': 60, - 'referrer': 'http://test.localhost:9999/integrationExamples/gpt/demo_native.html?pbjs_debug=true', - 'native': { - 'image': { - 'url': 'https://ads-tr.bigmining.com/img/300x250.png', - 'width': 300, - 'height': 250 - }, - 'title': 'Test Title', - 'body': 'Test Description', - 'sponsoredBy': 'test.com', - 'clickUrl': 'http://prebid.org/', - 'clickTrackers': ['https://www.clickUrl.com/404'], - 'impressionTrackers': [ - 'http://imp.trackerUrl.com/it2' - ] - }, - 'auctionId': '72138a4a-b747-4192-9192-dcc41d675de8', - 'responseTimestamp': 1565785219607, - 'requestTimestamp': 1565785219409, - 'bidder': 'dgads', - 'adUnitCode': '/19968336/prebid_native_example_1', - 'timeToRespond': 198, - 'pbLg': '1.50', - 'pbMg': '1.90', - 'pbHg': '1.90', - 'pbAg': '1.90', - 'pbDg': '1.90', - 'pbCg': '', - 'size': '0x0', - 'adserverTargeting': { - [CONSTANTS.TARGETING_KEYS.BIDDER]: 'dgads', - [CONSTANTS.TARGETING_KEYS.AD_ID]: '6e0aba55ed54e5', - [CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]: '1.90', - [CONSTANTS.TARGETING_KEYS.SIZE]: '0x0', - [CONSTANTS.TARGETING_KEYS.SOURCE]: 'client', - [CONSTANTS.TARGETING_KEYS.FORMAT]: 'native', - [CONSTANTS.NATIVE_KEYS.image]: 'https://ads-tr.bigmining.com/img/300x250.png', - [CONSTANTS.NATIVE_KEYS.title]: 'Test Title', - [CONSTANTS.NATIVE_KEYS.body]: 'Test Description', - [CONSTANTS.NATIVE_KEYS.sponsoredBy]: 'test.com', - [CONSTANTS.NATIVE_KEYS.clickUrl]: 'http://prebid.org/' - } -}; - -describe('targeting tests', function () { - let sandbox; - let enableSendAllBids = false; - let useBidCache; - - beforeEach(function() { - sandbox = sinon.sandbox.create(); - - useBidCache = true; - - let origGetConfig = config.getConfig; - sandbox.stub(config, 'getConfig').callsFake(function (key) { - if (key === 'enableSendAllBids') { - return enableSendAllBids; - } - if (key === 'useBidCache') { - return useBidCache; - } - return origGetConfig.apply(config, arguments); - }); - }); - - afterEach(function () { - sandbox.restore(); - }); - - describe('getAllTargeting', function () { - let amBidsReceivedStub; - let amGetAdUnitsStub; - let bidExpiryStub; - let logWarnStub; - let logErrorStub; - let bidsReceived; - - beforeEach(function () { - bidsReceived = [bid1, bid2, bid3]; - - amBidsReceivedStub = sandbox.stub(auctionManager, 'getBidsReceived').callsFake(function() { - return bidsReceived; - }); - amGetAdUnitsStub = sandbox.stub(auctionManager, 'getAdUnitCodes').callsFake(function() { - return ['/123456/header-bid-tag-0']; - }); - bidExpiryStub = sandbox.stub(filters, 'isBidNotExpired').returns(true); - logWarnStub = sinon.stub(utils, 'logWarn'); - logErrorStub = sinon.stub(utils, 'logError'); - }); - - afterEach(function() { - config.resetConfig(); - logWarnStub.restore(); - logErrorStub.restore(); - amBidsReceivedStub.restore(); - amGetAdUnitsStub.restore(); - bidExpiryStub.restore(); - }); - - describe('when hb_deal is present in bid.adserverTargeting', function () { - let bid4; - - beforeEach(function() { - bid4 = utils.deepClone(bid1); - bid4.adserverTargeting['hb_bidder'] = bid4.bidder = bid4.bidderCode = 'appnexus'; - bid4.cpm = 0; - enableSendAllBids = true; - - bidsReceived.push(bid4); - }); - - it('returns targeting with both hb_deal and hb_deal_{bidder_code}', function () { - const targeting = targetingInstance.getAllTargeting(['/123456/header-bid-tag-0']); - - // We should add both keys rather than one or the other - expect(targeting['/123456/header-bid-tag-0']).to.contain.keys('hb_deal', `hb_deal_${bid1.bidderCode}`, `hb_deal_${bid4.bidderCode}`); - - // We should assign both keys the same value - expect(targeting['/123456/header-bid-tag-0']['hb_deal']).to.deep.equal(targeting['/123456/header-bid-tag-0'][`hb_deal_${bid1.bidderCode}`]); - }); - }); - - it('will enforce a limit on the number of auction keys when auctionKeyMaxChars setting is active', function () { - config.setConfig({ - targetingControls: { - auctionKeyMaxChars: 150 - } - }); - - const targeting = targetingInstance.getAllTargeting(['/123456/header-bid-tag-0', '/123456/header-bid-tag-1']); - expect(targeting['/123456/header-bid-tag-1']).to.deep.equal({}); - expect(targeting['/123456/header-bid-tag-0']).to.contain.keys('hb_pb', 'hb_adid', 'hb_bidder', 'hb_deal'); - expect(targeting['/123456/header-bid-tag-0']['hb_adid']).to.equal(bid1.adId); - expect(logWarnStub.calledOnce).to.be.true; - }); - - it('will return an error when auctionKeyMaxChars setting is set too low for any auction keys to be allowed', function () { - config.setConfig({ - targetingControls: { - auctionKeyMaxChars: 50 - } - }); - - const targeting = targetingInstance.getAllTargeting(['/123456/header-bid-tag-0', '/123456/header-bid-tag-1']); - expect(targeting['/123456/header-bid-tag-1']).to.deep.equal({}); - expect(targeting['/123456/header-bid-tag-0']).to.deep.equal({}); - expect(logWarnStub.calledTwice).to.be.true; - expect(logErrorStub.calledOnce).to.be.true; - }); - - describe('when bidLimit is present in setConfig', function () { - let bid4; - - beforeEach(function() { - bid4 = utils.deepClone(bid1); - bid4.adserverTargeting['hb_bidder'] = bid4.bidder = bid4.bidderCode = 'appnexus'; - bid4.cpm = 2.25; - bid4.adId = '8383838'; - enableSendAllBids = true; - - bidsReceived.push(bid4); - }); - - it('when sendBidsControl.bidLimit is set greater than 0 in getHighestCpmBidsFromBidPool', function () { - config.setConfig({ - sendBidsControl: { - bidLimit: 2, - dealPrioritization: true - } - }); - - const bids = getHighestCpmBidsFromBidPool(bidsReceived, utils.getHighestCpm, 2); - - expect(bids.length).to.equal(3); - expect(bids[0].adId).to.equal('8383838'); - expect(bids[1].adId).to.equal('148018fe5e'); - expect(bids[2].adId).to.equal('48747745'); - }); - - it('when sendBidsControl.bidLimit is set greater than 0 and deal priortization is false in getHighestCpmBidsFromBidPool', function () { - config.setConfig({ - sendBidsControl: { - bidLimit: 2, - dealPrioritization: false - } - }); - - const bids = getHighestCpmBidsFromBidPool(bidsReceived, utils.getHighestCpm, 2); - - expect(bids.length).to.equal(3); - expect(bids[0].adId).to.equal('8383838'); - expect(bids[1].adId).to.equal('148018fe5e'); - expect(bids[2].adId).to.equal('48747745'); - }); - - it('selects the top n number of bids when enableSendAllBids is true and and bitLimit is set', function () { - config.setConfig({ - sendBidsControl: { - bidLimit: 1 - } - }); - - const targeting = targetingInstance.getAllTargeting(['/123456/header-bid-tag-0']); - let limitedBids = Object.keys(targeting['/123456/header-bid-tag-0']).filter(key => key.indexOf(CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_') != -1) - - expect(limitedBids.length).to.equal(1); - }); - - it('sends all bids when enableSendAllBids is true and and bitLimit is above total number of bids received', function () { - config.setConfig({ - sendBidsControl: { - bidLimit: 50 - } - }); - - const targeting = targetingInstance.getAllTargeting(['/123456/header-bid-tag-0']); - let limitedBids = Object.keys(targeting['/123456/header-bid-tag-0']).filter(key => key.indexOf(CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_') != -1) - - expect(limitedBids.length).to.equal(2); - }); - - it('Sends all bids when enableSendAllBids is true and and bidLimit is set to 0', function () { - config.setConfig({ - sendBidsControl: { - bidLimit: 0 - } - }); - - const targeting = targetingInstance.getAllTargeting(['/123456/header-bid-tag-0']); - let limitedBids = Object.keys(targeting['/123456/header-bid-tag-0']).filter(key => key.indexOf(CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_') != -1) - - expect(limitedBids.length).to.equal(2); - }); - }); - - describe('targetingControls.allowTargetingKeys', function () { - let bid4; - - beforeEach(function() { - bid4 = utils.deepClone(bid1); - bid4.adserverTargeting = { - hb_deal: '4321', - hb_pb: '0.1', - hb_adid: '567891011', - hb_bidder: 'appnexus', - }; - bid4.bidder = bid4.bidderCode = 'appnexus'; - bid4.cpm = 0.1; // losing bid so not included if enableSendAllBids === false - bid4.dealId = '4321'; - enableSendAllBids = true; - config.setConfig({ - targetingControls: { - allowTargetingKeys: ['BIDDER', 'AD_ID', 'PRICE_BUCKET'] - } - }); - bidsReceived.push(bid4); - }); - - it('targeting should include custom keys', function () { - const targeting = targetingInstance.getAllTargeting(['/123456/header-bid-tag-0']); - expect(targeting['/123456/header-bid-tag-0']).to.include.all.keys('foobar'); - }); - - it('targeting should include keys prefixed by allowed default targeting keys', function () { - const targeting = targetingInstance.getAllTargeting(['/123456/header-bid-tag-0']); - expect(targeting['/123456/header-bid-tag-0']).to.include.all.keys('hb_bidder_rubicon', 'hb_adid_rubicon', 'hb_pb_rubicon'); - expect(targeting['/123456/header-bid-tag-0']).to.include.all.keys('hb_bidder_appnexus', 'hb_adid_appnexus', 'hb_pb_appnexus'); - }); - - it('targeting should not include keys prefixed by disallowed default targeting keys', function () { - const targeting = targetingInstance.getAllTargeting(['/123456/header-bid-tag-0']); - expect(targeting['/123456/header-bid-tag-0']).to.not.have.all.keys(['hb_deal_appnexus', 'hb_deal_rubicon']); - }); - }); - - describe('targetingControls.alwaysIncludeDeals', function () { - let bid4; - - beforeEach(function() { - bid4 = utils.deepClone(bid1); - bid4.adserverTargeting = { - hb_deal: '4321', - hb_pb: '0.1', - hb_adid: '567891011', - hb_bidder: 'appnexus', - }; - bid4.bidder = bid4.bidderCode = 'appnexus'; - bid4.cpm = 0.1; // losing bid so not included if enableSendAllBids === false - bid4.dealId = '4321'; - enableSendAllBids = false; - - bidsReceived.push(bid4); - }); - - it('does not include losing deals when alwaysIncludeDeals not set', function () { - const targeting = targetingInstance.getAllTargeting(['/123456/header-bid-tag-0']); - - // Rubicon wins bid and has deal, but alwaysIncludeDeals is false, so only top bid plus deal_id - // appnexus does not get sent since alwaysIncludeDeals is not defined - expect(targeting['/123456/header-bid-tag-0']).to.deep.equal({ - 'hb_deal_rubicon': '1234', - 'hb_deal': '1234', - 'hb_pb': '0.53', - 'hb_adid': '148018fe5e', - 'hb_bidder': 'rubicon', - 'foobar': '300x250' - }); - }); - - it('does not include losing deals when alwaysIncludeDeals set to false', function () { - config.setConfig({ - targetingControls: { - alwaysIncludeDeals: false - } - }); - - const targeting = targetingInstance.getAllTargeting(['/123456/header-bid-tag-0']); - - // Rubicon wins bid and has deal, but alwaysIncludeDeals is false, so only top bid plus deal_id - // appnexus does not get sent since alwaysIncludeDeals is false - expect(targeting['/123456/header-bid-tag-0']).to.deep.equal({ - 'hb_deal_rubicon': '1234', // This is just how it works before this PR, always added no matter what for winner if they have deal - 'hb_deal': '1234', - 'hb_pb': '0.53', - 'hb_adid': '148018fe5e', - 'hb_bidder': 'rubicon', - 'foobar': '300x250' - }); - }); - - it('includes losing deals when alwaysIncludeDeals set to true and also winning deals bidder KVPs', function () { - config.setConfig({ - targetingControls: { - alwaysIncludeDeals: true - } - }); - const targeting = targetingInstance.getAllTargeting(['/123456/header-bid-tag-0']); - - // Rubicon wins bid and has a deal, so all KVPs for them are passed (top plus bidder specific) - // Appnexus had deal so passed through - expect(targeting['/123456/header-bid-tag-0']).to.deep.equal({ - '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' - }); - }); - - it('includes winning bid even when it is not a deal, plus other deal KVPs', function () { - config.setConfig({ - targetingControls: { - alwaysIncludeDeals: true - } - }); - let bid5 = utils.deepClone(bid4); - bid5.adserverTargeting = { - hb_pb: '3.0', - hb_adid: '111111', - hb_bidder: 'pubmatic', - }; - bid5.bidder = bid5.bidderCode = 'pubmatic'; - bid5.cpm = 3.0; // winning bid! - delete bid5.dealId; // no deal with winner - bidsReceived.push(bid5); - - const targeting = targetingInstance.getAllTargeting(['/123456/header-bid-tag-0']); - - // Pubmatic wins but no deal. So only top bid KVPs for them is sent - // Rubicon has a dealId so passed through - // Appnexus has a dealId so passed through - expect(targeting['/123456/header-bid-tag-0']).to.deep.equal({ - 'hb_bidder': 'pubmatic', - 'hb_adid': '111111', - 'hb_pb': '3.0', - 'foobar': '300x250', - 'hb_deal_rubicon': '1234', - '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' - }); - }); - }); - - it('selects the top bid when enableSendAllBids true', function () { - enableSendAllBids = true; - let targeting = targetingInstance.getAllTargeting(['/123456/header-bid-tag-0']); - - // we should only get the targeting data for the one requested adunit - expect(Object.keys(targeting).length).to.equal(1); - - let sendAllBidCpm = Object.keys(targeting['/123456/header-bid-tag-0']).filter(key => key.indexOf(CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_') != -1) - // we shouldn't get more than 1 key for hb_pb_${bidder} - expect(sendAllBidCpm.length).to.equal(1); - - // expect the winning CPM to be equal to the sendAllBidCPM - expect(targeting['/123456/header-bid-tag-0'][CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_rubicon']).to.deep.equal(targeting['/123456/header-bid-tag-0'][CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]); - }); - - it('ensures keys are properly generated when enableSendAllBids is true and multiple bidders use native', function() { - const nativeAdUnitCode = '/19968336/prebid_native_example_1'; - enableSendAllBids = true; - - // update mocks for this test to return native bids - amBidsReceivedStub.callsFake(function() { - return [nativeBid1, nativeBid2]; - }); - amGetAdUnitsStub.callsFake(function() { - return [nativeAdUnitCode]; - }); - - let targeting = targetingInstance.getAllTargeting([nativeAdUnitCode]); - expect(targeting[nativeAdUnitCode].hb_native_image).to.equal(nativeBid1.native.image.url); - expect(targeting[nativeAdUnitCode].hb_native_linkurl).to.equal(nativeBid1.native.clickUrl); - expect(targeting[nativeAdUnitCode].hb_native_title).to.equal(nativeBid1.native.title); - expect(targeting[nativeAdUnitCode].hb_native_image_dgad).to.exist.and.to.equal(nativeBid2.native.image.url); - expect(targeting[nativeAdUnitCode].hb_pb_dgads).to.exist.and.to.equal(nativeBid2.pbMg); - expect(targeting[nativeAdUnitCode].hb_native_body_appne).to.exist.and.to.equal(nativeBid1.native.body); - }); - - it('does not include adpod type bids in the getBidsReceived results', function () { - let adpodBid = utils.deepClone(bid1); - adpodBid.video = { context: 'adpod', durationSeconds: 15, durationBucket: 15 }; - adpodBid.cpm = 5; - bidsReceived.push(adpodBid); - - const targeting = targetingInstance.getAllTargeting(['/123456/header-bid-tag-0']); - expect(targeting['/123456/header-bid-tag-0']).to.contain.keys('hb_deal', 'hb_adid', 'hb_bidder'); - expect(targeting['/123456/header-bid-tag-0']['hb_adid']).to.equal(bid1.adId); - }); - }); // end getAllTargeting tests - - describe('getAllTargeting without bids return empty object', function () { - let amBidsReceivedStub; - let amGetAdUnitsStub; - let bidExpiryStub; - - beforeEach(function () { - amBidsReceivedStub = sandbox.stub(auctionManager, 'getBidsReceived').callsFake(function() { - return []; - }); - amGetAdUnitsStub = sandbox.stub(auctionManager, 'getAdUnitCodes').callsFake(function() { - return ['/123456/header-bid-tag-0']; - }); - bidExpiryStub = sandbox.stub(filters, 'isBidNotExpired').returns(true); - }); - - it('returns targetingSet correctly', function () { - let targeting = targetingInstance.getAllTargeting(['/123456/header-bid-tag-0']); - - // we should only get the targeting data for the one requested adunit to at least exist even though it has no keys to set - expect(Object.keys(targeting).length).to.equal(1); - }); - }); // end getAllTargeting without bids return empty object - - describe('Targeting in concurrent auctions', function () { - describe('check getOldestBid', function () { - let bidExpiryStub; - let auctionManagerStub; - beforeEach(function () { - bidExpiryStub = sandbox.stub(filters, 'isBidNotExpired').returns(true); - auctionManagerStub = sandbox.stub(auctionManager, 'getBidsReceived'); - }); - - it('should use bids from pool to get Winning Bid', function () { - let bidsReceived = [ - createBidReceived({bidder: 'appnexus', cpm: 7, auctionId: 1, responseTimestamp: 100, adUnitCode: 'code-0', adId: 'adid-1'}), - createBidReceived({bidder: 'rubicon', cpm: 6, auctionId: 1, responseTimestamp: 101, adUnitCode: 'code-1', adId: 'adid-2'}), - createBidReceived({bidder: 'appnexus', cpm: 6, auctionId: 2, responseTimestamp: 102, adUnitCode: 'code-0', adId: 'adid-3'}), - createBidReceived({bidder: 'rubicon', cpm: 6, auctionId: 2, responseTimestamp: 103, adUnitCode: 'code-1', adId: 'adid-4'}), - ]; - let adUnitCodes = ['code-0', 'code-1']; - - let bids = targetingInstance.getWinningBids(adUnitCodes, bidsReceived); - - expect(bids.length).to.equal(2); - expect(bids[0].adId).to.equal('adid-1'); - expect(bids[1].adId).to.equal('adid-2'); - }); - - it('should honor useBidCache', function() { - useBidCache = true; - - auctionManagerStub.returns([ - createBidReceived({bidder: 'appnexus', cpm: 7, auctionId: 1, responseTimestamp: 100, adUnitCode: 'code-0', adId: 'adid-1'}), - createBidReceived({bidder: 'appnexus', cpm: 5, auctionId: 2, responseTimestamp: 102, adUnitCode: 'code-0', adId: 'adid-2'}), - ]); - - let adUnitCodes = ['code-0']; - targetingInstance.setLatestAuctionForAdUnit('code-0', 2); - - let bids = targetingInstance.getWinningBids(adUnitCodes); - - expect(bids.length).to.equal(1); - expect(bids[0].adId).to.equal('adid-1'); - - useBidCache = false; - - bids = targetingInstance.getWinningBids(adUnitCodes); - - expect(bids.length).to.equal(1); - expect(bids[0].adId).to.equal('adid-2'); - }); - - it('should not use rendered bid to get winning bid', function () { - let bidsReceived = [ - createBidReceived({bidder: 'appnexus', cpm: 8, auctionId: 1, responseTimestamp: 100, adUnitCode: 'code-0', adId: 'adid-1', status: 'rendered'}), - createBidReceived({bidder: 'rubicon', cpm: 6, auctionId: 1, responseTimestamp: 101, adUnitCode: 'code-1', adId: 'adid-2'}), - createBidReceived({bidder: 'appnexus', cpm: 7, auctionId: 2, responseTimestamp: 102, adUnitCode: 'code-0', adId: 'adid-3'}), - createBidReceived({bidder: 'rubicon', cpm: 6, auctionId: 2, responseTimestamp: 103, adUnitCode: 'code-1', adId: 'adid-4'}), - ]; - auctionManagerStub.returns(bidsReceived); - - let adUnitCodes = ['code-0', 'code-1']; - let bids = targetingInstance.getWinningBids(adUnitCodes); - - expect(bids.length).to.equal(2); - expect(bids[0].adId).to.equal('adid-2'); - expect(bids[1].adId).to.equal('adid-3'); - }); - - it('should use highest cpm bid from bid pool to get winning bid', function () { - // Pool is having 4 bids from 2 auctions. There are 2 bids from rubicon, #2 which is highest cpm bid will be selected to take part in auction. - let bidsReceived = [ - createBidReceived({bidder: 'appnexus', cpm: 8, auctionId: 1, responseTimestamp: 100, adUnitCode: 'code-0', adId: 'adid-1'}), - createBidReceived({bidder: 'rubicon', cpm: 9, auctionId: 1, responseTimestamp: 101, adUnitCode: 'code-0', adId: 'adid-2'}), - createBidReceived({bidder: 'appnexus', cpm: 7, auctionId: 2, responseTimestamp: 102, adUnitCode: 'code-0', adId: 'adid-3'}), - createBidReceived({bidder: 'rubicon', cpm: 8, auctionId: 2, responseTimestamp: 103, adUnitCode: 'code-0', adId: 'adid-4'}), - ]; - auctionManagerStub.returns(bidsReceived); - - let adUnitCodes = ['code-0']; - let bids = targetingInstance.getWinningBids(adUnitCodes); - - expect(bids.length).to.equal(1); - expect(bids[0].adId).to.equal('adid-2'); - }); - }); - - describe('check bidExpiry', function () { - let auctionManagerStub; - let timestampStub; - beforeEach(function () { - auctionManagerStub = sandbox.stub(auctionManager, 'getBidsReceived'); - timestampStub = sandbox.stub(utils, 'timestamp'); - }); - - it('should not include expired bids in the auction', function () { - timestampStub.returns(200000); - // Pool is having 4 bids from 2 auctions. All the bids are expired and only bid #3 is passing the bidExpiry check. - let bidsReceived = [ - createBidReceived({bidder: 'appnexus', cpm: 18, auctionId: 1, responseTimestamp: 100, adUnitCode: 'code-0', adId: 'adid-1', ttl: 150}), - createBidReceived({bidder: 'sampleBidder', cpm: 16, auctionId: 1, responseTimestamp: 101, adUnitCode: 'code-0', adId: 'adid-2', ttl: 100}), - createBidReceived({bidder: 'appnexus', cpm: 7, auctionId: 2, responseTimestamp: 102, adUnitCode: 'code-0', adId: 'adid-3', ttl: 300}), - createBidReceived({bidder: 'rubicon', cpm: 6, auctionId: 2, responseTimestamp: 103, adUnitCode: 'code-0', adId: 'adid-4', ttl: 50}), - ]; - auctionManagerStub.returns(bidsReceived); - - let adUnitCodes = ['code-0', 'code-1']; - let bids = targetingInstance.getWinningBids(adUnitCodes); - - expect(bids.length).to.equal(1); - expect(bids[0].adId).to.equal('adid-3'); - }); - }); - }); - - describe('sortByDealAndPriceBucketOrCpm', function() { - it('will properly sort bids when some bids have deals and some do not', function () { - let bids = [{ - adserverTargeting: { - hb_adid: 'abc', - hb_pb: '1.00', - hb_deal: '1234' - } - }, { - adserverTargeting: { - hb_adid: 'def', - hb_pb: '0.50', - } - }, { - adserverTargeting: { - hb_adid: 'ghi', - hb_pb: '20.00', - hb_deal: '4532' - } - }, { - adserverTargeting: { - hb_adid: 'jkl', - hb_pb: '9.00', - hb_deal: '9864' - } - }, { - adserverTargeting: { - hb_adid: 'mno', - hb_pb: '50.00', - } - }, { - adserverTargeting: { - hb_adid: 'pqr', - hb_pb: '100.00', - } - }]; - bids.sort(sortByDealAndPriceBucketOrCpm()); - expect(bids[0].adserverTargeting.hb_adid).to.equal('ghi'); - expect(bids[1].adserverTargeting.hb_adid).to.equal('jkl'); - expect(bids[2].adserverTargeting.hb_adid).to.equal('abc'); - expect(bids[3].adserverTargeting.hb_adid).to.equal('pqr'); - expect(bids[4].adserverTargeting.hb_adid).to.equal('mno'); - expect(bids[5].adserverTargeting.hb_adid).to.equal('def'); - }); - - it('will properly sort bids when all bids have deals', function () { - let bids = [{ - adserverTargeting: { - hb_adid: 'abc', - hb_pb: '1.00', - hb_deal: '1234' - } - }, { - adserverTargeting: { - hb_adid: 'def', - hb_pb: '0.50', - hb_deal: '4321' - } - }, { - adserverTargeting: { - hb_adid: 'ghi', - hb_pb: '2.50', - hb_deal: '4532' - } - }, { - adserverTargeting: { - hb_adid: 'jkl', - hb_pb: '2.00', - hb_deal: '9864' - } - }]; - bids.sort(sortByDealAndPriceBucketOrCpm()); - expect(bids[0].adserverTargeting.hb_adid).to.equal('ghi'); - expect(bids[1].adserverTargeting.hb_adid).to.equal('jkl'); - expect(bids[2].adserverTargeting.hb_adid).to.equal('abc'); - expect(bids[3].adserverTargeting.hb_adid).to.equal('def'); - }); - - it('will properly sort bids when no bids have deals', function () { - let bids = [{ - adserverTargeting: { - hb_adid: 'abc', - hb_pb: '1.00' - } - }, { - adserverTargeting: { - hb_adid: 'def', - hb_pb: '0.10' - } - }, { - adserverTargeting: { - hb_adid: 'ghi', - hb_pb: '10.00' - } - }, { - adserverTargeting: { - hb_adid: 'jkl', - hb_pb: '10.01' - } - }, { - adserverTargeting: { - hb_adid: 'mno', - hb_pb: '1.00' - } - }, { - adserverTargeting: { - hb_adid: 'pqr', - hb_pb: '100.00' - } - }]; - bids.sort(sortByDealAndPriceBucketOrCpm()); - expect(bids[0].adserverTargeting.hb_adid).to.equal('pqr'); - expect(bids[1].adserverTargeting.hb_adid).to.equal('jkl'); - expect(bids[2].adserverTargeting.hb_adid).to.equal('ghi'); - expect(bids[3].adserverTargeting.hb_adid).to.equal('abc'); - expect(bids[4].adserverTargeting.hb_adid).to.equal('mno'); - expect(bids[5].adserverTargeting.hb_adid).to.equal('def'); - }); - - it('will properly sort bids when some bids have deals and some do not and by cpm when flag is set to true', function () { - let bids = [{ - cpm: 1.04, - adserverTargeting: { - hb_adid: 'abc', - hb_pb: '1.00', - hb_deal: '1234' - } - }, { - cpm: 0.50, - adserverTargeting: { - hb_adid: 'def', - hb_pb: '0.50', - hb_deal: '4532' - } - }, { - cpm: 0.53, - adserverTargeting: { - hb_adid: 'ghi', - hb_pb: '0.50', - hb_deal: '4532' - } - }, { - cpm: 9.04, - adserverTargeting: { - hb_adid: 'jkl', - hb_pb: '9.00', - hb_deal: '9864' - } - }, { - cpm: 50.00, - adserverTargeting: { - hb_adid: 'mno', - hb_pb: '50.00', - } - }, { - cpm: 100.00, - adserverTargeting: { - hb_adid: 'pqr', - hb_pb: '100.00', - } - }]; - bids.sort(sortByDealAndPriceBucketOrCpm(true)); - expect(bids[0].adserverTargeting.hb_adid).to.equal('jkl'); - expect(bids[1].adserverTargeting.hb_adid).to.equal('abc'); - expect(bids[2].adserverTargeting.hb_adid).to.equal('ghi'); - expect(bids[3].adserverTargeting.hb_adid).to.equal('def'); - expect(bids[4].adserverTargeting.hb_adid).to.equal('pqr'); - expect(bids[5].adserverTargeting.hb_adid).to.equal('mno'); - }); - }); - - describe('setTargetingForAst', function () { - let sandbox, - apnTagStub; - beforeEach(function() { - sandbox = sinon.createSandbox(); - sandbox.stub(targetingInstance, 'resetPresetTargetingAST'); - apnTagStub = sandbox.stub(window.apntag, 'setKeywords'); - }); - afterEach(function () { - sandbox.restore(); - }); - - it('should set single addUnit code', function() { - let adUnitCode = 'testdiv-abc-ad-123456-0'; - sandbox.stub(targetingInstance, 'getAllTargeting').returns({ - 'testdiv1-abc-ad-123456-0': {hb_bidder: 'appnexus'} - }); - targetingInstance.setTargetingForAst(adUnitCode); - expect(targetingInstance.getAllTargeting.called).to.equal(true); - expect(targetingInstance.resetPresetTargetingAST.called).to.equal(true); - expect(apnTagStub.callCount).to.equal(1); - expect(apnTagStub.getCall(0).args[0]).to.deep.equal('testdiv1-abc-ad-123456-0'); - expect(apnTagStub.getCall(0).args[1]).to.deep.equal({HB_BIDDER: 'appnexus'}); - }); - - it('should set array of addUnit codes', function() { - let adUnitCodes = ['testdiv1-abc-ad-123456-0', 'testdiv2-abc-ad-123456-0'] - sandbox.stub(targetingInstance, 'getAllTargeting').returns({ - 'testdiv1-abc-ad-123456-0': {hb_bidder: 'appnexus'}, - 'testdiv2-abc-ad-123456-0': {hb_bidder: 'appnexus'} - }); - targetingInstance.setTargetingForAst(adUnitCodes); - expect(targetingInstance.getAllTargeting.called).to.equal(true); - expect(targetingInstance.resetPresetTargetingAST.called).to.equal(true); - expect(apnTagStub.callCount).to.equal(2); - expect(apnTagStub.getCall(1).args[0]).to.deep.equal('testdiv2-abc-ad-123456-0'); - expect(apnTagStub.getCall(1).args[1]).to.deep.equal({HB_BIDDER: 'appnexus'}); - }); - }); -}); diff --git a/test/spec/unit/pbjs_api_spec.js b/test/spec/unit/pbjs_api_spec.js deleted file mode 100644 index 805eae9e3bc..00000000000 --- a/test/spec/unit/pbjs_api_spec.js +++ /dev/null @@ -1,2868 +0,0 @@ -import { - getAdServerTargeting, - getBidRequests, - getBidResponses, - getBidResponsesFromAPI, - getTargetingKeys, - getTargetingKeysBidLandscape, - getAdUnits, - createBidReceived -} from 'test/fixtures/fixtures.js'; -import { auctionManager, newAuctionManager } from 'src/auctionManager.js'; -import { targeting, newTargeting, filters } from 'src/targeting.js'; -import { config as configObj } from 'src/config.js'; -import * as ajaxLib from 'src/ajax.js'; -import * as auctionModule from 'src/auction.js'; -import { registerBidder } from 'src/adapters/bidderFactory.js'; -import { _sendAdToCreative } from 'src/secureCreatives.js'; -import find from 'core-js-pure/features/array/find.js'; - -var assert = require('chai').assert; -var expect = require('chai').expect; - -var utils = require('src/utils'); -var adapterManager = require('src/adapterManager').default; -var events = require('src/events'); -var CONSTANTS = require('src/constants.json'); - -// These bid adapters are required to be loaded for the following tests to work -require('modules/appnexusBidAdapter'); - -var config = require('test/fixtures/config.json'); - -$$PREBID_GLOBAL$$ = $$PREBID_GLOBAL$$ || {}; -var adUnits = getAdUnits(); -var adUnitCodes = getAdUnits().map(unit => unit.code); -var bidsBackHandler = function() {}; -const timeout = 2000; -var auction = auctionManager.createAuction({adUnits, adUnitCodes, callback: bidsBackHandler, cbTimeout: timeout}); -auction.getBidRequests = getBidRequests; -auction.getBidsReceived = getBidResponses; -auction.getAdUnits = getAdUnits; -auction.getAuctionStatus = function() { return auctionModule.AUCTION_COMPLETED } - -function resetAuction() { - $$PREBID_GLOBAL$$.setConfig({ enableSendAllBids: false }); - auction.getBidRequests = getBidRequests; - auction.getBidsReceived = getBidResponses; - auction.getAdUnits = getAdUnits; - auction.getAuctionStatus = function() { return auctionModule.AUCTION_COMPLETED } -} - -var Slot = function Slot(elementId, pathId) { - var slot = { - targeting: {}, - getSlotElementId: function getSlotElementId() { - return elementId; - }, - - getAdUnitPath: function getAdUnitPath() { - return pathId; - }, - - setTargeting: function setTargeting(key, value) { - this.targeting[key] = Array.isArray(value) ? value : [value]; - }, - - getTargeting: function getTargeting(key) { - return this.targeting[key] || []; - }, - - getTargetingKeys: function getTargetingKeys() { - return Object.getOwnPropertyNames(this.targeting); - }, - - clearTargeting: function clearTargeting() { - this.targeting = {}; - return this; - } - }; - slot.spySetTargeting = sinon.spy(slot, 'setTargeting'); - slot.spyGetSlotElementId = sinon.spy(slot, 'getSlotElementId'); - return slot; -}; - -var createSlotArray = function createSlotArray() { - return [ - new Slot(config.adUnitElementIDs[0], config.adUnitCodes[0]), - new Slot(config.adUnitElementIDs[1], config.adUnitCodes[1]), - new Slot(config.adUnitElementIDs[2], config.adUnitCodes[2]) - ]; -}; - -var createSlotArrayScenario2 = function createSlotArrayScenario2() { - var slot1 = new Slot(config.adUnitElementIDs[0], config.adUnitCodes[0]); - slot1.setTargeting('pos1', '750x350'); - var slot2 = new Slot(config.adUnitElementIDs[1], config.adUnitCodes[0]); - slot2.setTargeting('gender', ['male', 'female']); - return [ - slot1, - slot2 - ]; -}; - -window.googletag = { - _slots: [], - _targeting: {}, - pubads: function () { - var self = this; - return { - getSlots: function () { - return self._slots; - }, - - setSlots: function (slots) { - self._slots = slots; - }, - - setTargeting: function(key, arrayOfValues) { - self._targeting[key] = Array.isArray(arrayOfValues) ? arrayOfValues : [arrayOfValues]; - }, - - getTargeting: function(key) { - return self._targeting[key] || []; - }, - - getTargetingKeys: function() { - return Object.getOwnPropertyNames(self._targeting); - }, - - clearTargeting: function() { - self._targeting = {}; - } - }; - } -}; - -var createTagAST = function() { - var tags = {}; - tags[config.adUnitCodes[0]] = { - keywords: {} - }; - return tags; -}; - -window.apntag = { - keywords: [], - tags: createTagAST(), - setKeywords: function(key, params, options) { - var self = this; - if (!self.tags.hasOwnProperty(key)) { - return; - } - self.tags[key].keywords = this.tags[key].keywords || {}; - - if (typeof options === 'object' && options !== null && options.overrideKeyValue === true) { - utils._each(params, function(param, id) { - self.tags[key].keywords[id] = param; - }); - } else { - utils._each(params, function (param, id) { - if (!self.tags[key].keywords.hasOwnProperty(id)) { - self.tags[key].keywords[id] = param; - } else if (!utils.isArray(self.tags[key].keywords[id])) { - self.tags[key].keywords[id] = [self.tags[key].keywords[id]].concat(param); - } else { - self.tags[key].keywords[id] = self.tags[key].keywords[id].concat(param); - } - }) - } - }, - getTag: function(tagId) { - return this.tags[tagId]; - }, - modifyTag: function(tagId, params) { - var output = {}; - - utils._each(this.tags[tagId], function(tag, id) { - output[id] = tag; - }); - - utils._each(params, function(param, id) { - output[id] = param; - }); - - this.tags[tagId] = output; - } -} - -describe('Unit: Prebid Module', function () { - let bidExpiryStub; - beforeEach(function () { - bidExpiryStub = sinon.stub(filters, 'isBidNotExpired').callsFake(() => true); - configObj.setConfig({ useBidCache: true }); - }); - - afterEach(function() { - $$PREBID_GLOBAL$$.adUnits = []; - bidExpiryStub.restore(); - configObj.setConfig({ useBidCache: false }); - }); - - describe('getAdserverTargetingForAdUnitCodeStr', function () { - beforeEach(function () { - resetAuction(); - }); - - it('should return targeting info as a string', function () { - const adUnitCode = config.adUnitCodes[0]; - $$PREBID_GLOBAL$$.setConfig({ enableSendAllBids: true }); - var expected = 'foobar=0x0%2C300x250%2C300x600&' + CONSTANTS.TARGETING_KEYS.SIZE + '=300x250&' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '=10.00&' + CONSTANTS.TARGETING_KEYS.AD_ID + '=233bcbee889d46d&' + CONSTANTS.TARGETING_KEYS.BIDDER + '=appnexus&' + CONSTANTS.TARGETING_KEYS.SIZE + '_triplelift=0x0&' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_triplelift=10.00&' + CONSTANTS.TARGETING_KEYS.AD_ID + '_triplelift=222bb26f9e8bd&' + CONSTANTS.TARGETING_KEYS.BIDDER + '_triplelift=triplelift&' + CONSTANTS.TARGETING_KEYS.SIZE + '_appnexus=300x250&' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_appnexus=10.00&' + CONSTANTS.TARGETING_KEYS.AD_ID + '_appnexus=233bcbee889d46d&' + CONSTANTS.TARGETING_KEYS.BIDDER + '_appnexus=appnexus&' + CONSTANTS.TARGETING_KEYS.SIZE + '_pagescience=300x250&' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_pagescience=10.00&' + CONSTANTS.TARGETING_KEYS.AD_ID + '_pagescience=25bedd4813632d7&' + CONSTANTS.TARGETING_KEYS.BIDDER + '_pagescienc=pagescience&' + CONSTANTS.TARGETING_KEYS.SIZE + '_brightcom=300x250&' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_brightcom=10.00&' + CONSTANTS.TARGETING_KEYS.AD_ID + '_brightcom=26e0795ab963896&' + CONSTANTS.TARGETING_KEYS.BIDDER + '_brightcom=brightcom&' + CONSTANTS.TARGETING_KEYS.SIZE + '_brealtime=300x250&' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_brealtime=10.00&' + CONSTANTS.TARGETING_KEYS.AD_ID + '_brealtime=275bd666f5a5a5d&' + CONSTANTS.TARGETING_KEYS.BIDDER + '_brealtime=brealtime&' + CONSTANTS.TARGETING_KEYS.SIZE + '_pubmatic=300x250&' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_pubmatic=10.00&' + CONSTANTS.TARGETING_KEYS.AD_ID + '_pubmatic=28f4039c636b6a7&' + CONSTANTS.TARGETING_KEYS.BIDDER + '_pubmatic=pubmatic&' + CONSTANTS.TARGETING_KEYS.SIZE + '_rubicon=300x600&' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_rubicon=10.00&' + CONSTANTS.TARGETING_KEYS.AD_ID + '_rubicon=29019e2ab586a5a&' + CONSTANTS.TARGETING_KEYS.BIDDER + '_rubicon=rubicon'; - var result = $$PREBID_GLOBAL$$.getAdserverTargetingForAdUnitCodeStr(adUnitCode); - assert.equal(expected, result, 'returns expected string of ad targeting info'); - }); - - it('should log message if adunitCode param is falsey', function () { - var spyLogMessage = sinon.spy(utils, 'logMessage'); - var result = $$PREBID_GLOBAL$$.getAdserverTargetingForAdUnitCodeStr(); - assert.ok(spyLogMessage.calledWith('Need to call getAdserverTargetingForAdUnitCodeStr with adunitCode'), 'expected message was logged'); - assert.equal(result, undefined, 'result is undefined'); - utils.logMessage.restore(); - }); - }); - - describe('getAdserverTargetingForAdUnitCode', function () { - it('should return targeting info as an object', function () { - const adUnitCode = config.adUnitCodes[0]; - $$PREBID_GLOBAL$$.setConfig({ enableSendAllBids: true }); - var result = $$PREBID_GLOBAL$$.getAdserverTargetingForAdUnitCode(adUnitCode); - const expected = getAdServerTargeting()[adUnitCode]; - assert.deepEqual(result, expected, 'returns expected' + - ' targeting info object'); - }); - }); - - describe('getAdServerTargeting', function () { - beforeEach(function () { - resetAuction(); - }); - - afterEach(function () { - resetAuction(); - }); - - it('should return current targeting data for slots', function () { - $$PREBID_GLOBAL$$.setConfig({ enableSendAllBids: true }); - const targeting = $$PREBID_GLOBAL$$.getAdserverTargeting(['/19968336/header-bid-tag-0', '/19968336/header-bid-tag1']); - const expected = getAdServerTargeting(['/19968336/header-bid-tag-0, /19968336/header-bid-tag1']); - assert.deepEqual(targeting, expected, 'targeting ok'); - }); - - it('should return correct targeting with default settings', function () { - var targeting = $$PREBID_GLOBAL$$.getAdserverTargeting(['/19968336/header-bid-tag-0', '/19968336/header-bid-tag1']); - var expected = { - '/19968336/header-bid-tag-0': { - foobar: '0x0,300x250,300x600', - [CONSTANTS.TARGETING_KEYS.SIZE]: '300x250', - [CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]: '10.00', - [CONSTANTS.TARGETING_KEYS.AD_ID]: '233bcbee889d46d', - [CONSTANTS.TARGETING_KEYS.BIDDER]: 'appnexus' - }, - '/19968336/header-bid-tag1': { - foobar: '728x90', - [CONSTANTS.TARGETING_KEYS.SIZE]: '728x90', - [CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]: '10.00', - [CONSTANTS.TARGETING_KEYS.AD_ID]: '24bd938435ec3fc', - [CONSTANTS.TARGETING_KEYS.BIDDER]: 'appnexus' - } - }; - assert.deepEqual(targeting, expected); - }); - - it('should return correct targeting with bid landscape targeting on', function () { - $$PREBID_GLOBAL$$.setConfig({ enableSendAllBids: true }); - var targeting = $$PREBID_GLOBAL$$.getAdserverTargeting(['/19968336/header-bid-tag-0', '/19968336/header-bid-tag1']); - var expected = getAdServerTargeting(['/19968336/header-bid-tag-0', '/19968336/header-bid-tag1']); - assert.deepEqual(targeting, expected); - }); - - it("should include a losing bid's custom ad targeting key", function () { - // Let's make sure we're getting the expected losing bid. - assert.equal(auction.getBidsReceived()[0]['bidderCode'], 'triplelift'); - assert.equal(auction.getBidsReceived()[0]['cpm'], 0.112256); - - // Modify the losing bid to have `alwaysUseBid=true` and a custom `adserverTargeting` key. - let _bidsReceived = getBidResponses(); - _bidsReceived[0]['adserverTargeting'] = { - always_use_me: 'abc', - }; - - auction.getBidsReceived = function() { return _bidsReceived }; - - var targeting = $$PREBID_GLOBAL$$.getAdserverTargeting(['/19968336/header-bid-tag-0', '/19968336/header-bid-tag1']); - - // Ensure targeting for both ad placements includes the custom key. - assert.equal( - targeting['/19968336/header-bid-tag-0'].hasOwnProperty('always_use_me'), - true - ); - - var expected = { - '/19968336/header-bid-tag-0': { - foobar: '300x250,300x600', - always_use_me: 'abc', - [CONSTANTS.TARGETING_KEYS.SIZE]: '300x250', - [CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]: '10.00', - [CONSTANTS.TARGETING_KEYS.AD_ID]: '233bcbee889d46d', - [CONSTANTS.TARGETING_KEYS.BIDDER]: 'appnexus' - }, - '/19968336/header-bid-tag1': { - foobar: '728x90', - [CONSTANTS.TARGETING_KEYS.SIZE]: '728x90', - [CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]: '10.00', - [CONSTANTS.TARGETING_KEYS.AD_ID]: '24bd938435ec3fc', - [CONSTANTS.TARGETING_KEYS.BIDDER]: 'appnexus' - } - }; - assert.deepEqual(targeting, expected); - }); - - it('should not overwrite winning bids custom keys targeting key', function () { - resetAuction(); - // mimic a bidderSetting.standard key here for each bid and alwaysUseBid true for every bid - let _bidsReceived = getBidResponses(); - _bidsReceived.forEach(bid => { - bid.adserverTargeting.custom_ad_id = bid.adId; - }); - - auction.getBidsReceived = function() { return _bidsReceived }; - - $$PREBID_GLOBAL$$.bidderSettings = { - 'standard': { - adserverTargeting: [{ - key: CONSTANTS.TARGETING_KEYS.BIDDER, - val: function(bidResponse) { - return bidResponse.bidderCode; - } - }, { - key: 'custom_ad_id', - val: function(bidResponse) { - return bidResponse.adId; - } - }, { - key: CONSTANTS.TARGETING_KEYS.PRICE_BUCKET, - val: function(bidResponse) { - return bidResponse.pbMg; - } - }, { - key: 'foobar', - val: function(bidResponse) { - return bidResponse.size; - } - }] - } - }; - - var targeting = $$PREBID_GLOBAL$$.getAdserverTargeting(['/19968336/header-bid-tag-0', '/19968336/header-bid-tag1']); - - var expected = { - '/19968336/header-bid-tag-0': { - foobar: '300x250', - custom_ad_id: '233bcbee889d46d', - [CONSTANTS.TARGETING_KEYS.SIZE]: '300x250', - [CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]: '10.00', - [CONSTANTS.TARGETING_KEYS.AD_ID]: '233bcbee889d46d', - [CONSTANTS.TARGETING_KEYS.BIDDER]: 'appnexus' - }, - '/19968336/header-bid-tag1': { - foobar: '728x90', - [CONSTANTS.TARGETING_KEYS.SIZE]: '728x90', - [CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]: '10.00', - [CONSTANTS.TARGETING_KEYS.AD_ID]: '24bd938435ec3fc', - [CONSTANTS.TARGETING_KEYS.BIDDER]: 'appnexus', - custom_ad_id: '24bd938435ec3fc' - } - }; - assert.deepEqual(targeting, expected); - $$PREBID_GLOBAL$$.bidderSettings = {}; - }); - - it('should not send standard targeting keys when the bid has `sendStandardTargeting` set to `false`', function () { - let _bidsReceived = getBidResponses(); - _bidsReceived.forEach(bid => { - bid.adserverTargeting.custom_ad_id = bid.adId; - bid.sendStandardTargeting = false; - }); - - auction.getBidsReceived = function() { return _bidsReceived }; - - var targeting = $$PREBID_GLOBAL$$.getAdserverTargeting(['/19968336/header-bid-tag-0', '/19968336/header-bid-tag1']); - - var expected = { - '/19968336/header-bid-tag-0': { - foobar: '0x0,300x250,300x600', - custom_ad_id: '222bb26f9e8bd,233bcbee889d46d,25bedd4813632d7,26e0795ab963896,275bd666f5a5a5d,28f4039c636b6a7,29019e2ab586a5a' - }, - '/19968336/header-bid-tag1': { - foobar: '728x90', - custom_ad_id: '24bd938435ec3fc' - } - }; - assert.deepEqual(targeting, expected); - }); - }); - - describe('getAdserverTargeting', function() { - const customConfigObject = { - 'buckets': [ - { 'precision': 2, 'max': 5, 'increment': 0.01 }, - { 'precision': 2, 'max': 8, 'increment': 0.05 }, - { 'precision': 2, 'max': 20, 'increment': 0.5 }, - { 'precision': 2, 'max': 25, 'increment': 1 } - ] - }; - let currentPriceBucket; - let bid; - let auction; - let ajaxStub; - let cbTimeout = 3000; - let targeting; - - let RESPONSE = { - 'version': '0.0.1', - 'tags': [{ - 'uuid': '4d0a6829338a07', - 'tag_id': 4799418, - 'auction_id': '2256922143947979797', - 'no_ad_url': 'http://lax1-ib.adnxs.com/no-ad', - 'timeout_ms': 2500, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'banner', - 'buyer_member_id': 958, - 'creative_id': 33989846, - 'media_type_id': 1, - 'media_subtype_id': 1, - 'cpm': 1.99, - 'cpm_publisher_currency': 0.500000, - 'publisher_currency_code': '$', - 'client_initiated_ad_counting': true, - 'rtb': { - 'banner': { - 'width': 728, - 'height': 90, - 'content': '' - }, - 'trackers': [{ - 'impression_urls': ['http://lax1-ib.adnxs.com/impression'] - }] - }, - 'viewability': { - 'config': ''} - }] - }] - }; - - before(function () { - $$PREBID_GLOBAL$$.bidderSettings = {}; - currentPriceBucket = configObj.getConfig('priceGranularity'); - configObj.setConfig({ priceGranularity: customConfigObject }); - sinon.stub(adapterManager, 'makeBidRequests').callsFake(() => ([{ - 'bidderCode': 'appnexus', - 'auctionId': '20882439e3238c', - 'bidderRequestId': '331f3cf3f1d9c8', - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': '10433394' - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '4d0a6829338a07', - 'bidderRequestId': '331f3cf3f1d9c8', - 'auctionId': '20882439e3238c' - } - ], - 'auctionStart': 1505250713622, - 'timeout': 3000 - }] - )); - }); - - after(function () { - configObj.setConfig({ priceGranularity: currentPriceBucket }); - adapterManager.makeBidRequests.restore(); - }) - - beforeEach(function () { - let auctionManagerInstance = newAuctionManager(); - targeting = newTargeting(auctionManagerInstance); - let adUnits = [{ - code: 'div-gpt-ad-1460505748561-0', - sizes: [[300, 250], [300, 600]], - bids: [{ - bidder: 'appnexus', - params: { - placementId: '10433394' - } - }] - }]; - let adUnitCodes = ['div-gpt-ad-1460505748561-0']; - auction = auctionManagerInstance.createAuction({adUnits, adUnitCodes}); - ajaxStub = sinon.stub(ajaxLib, 'ajaxBuilder').callsFake(function() { - return function(url, callback) { - const fakeResponse = sinon.stub(); - fakeResponse.returns('headerContent'); - callback.success(JSON.stringify(RESPONSE), { getResponseHeader: fakeResponse }); - } - }); - }); - - afterEach(function () { - ajaxStub.restore(); - }); - - it('should get correct ' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + ' when using bid.cpm is between 0 to 5', function() { - RESPONSE.tags[0].ads[0].cpm = 2.1234; - auction.callBids(cbTimeout); - let bidTargeting = targeting.getAllTargeting(); - expect(bidTargeting['div-gpt-ad-1460505748561-0'][CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]).to.equal('2.12'); - }); - - it('should get correct ' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + ' when using bid.cpm is between 5 to 8', function() { - RESPONSE.tags[0].ads[0].cpm = 6.78; - auction.callBids(cbTimeout); - let bidTargeting = targeting.getAllTargeting(); - expect(bidTargeting['div-gpt-ad-1460505748561-0'][CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]).to.equal('6.75'); - }); - - it('should get correct ' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + ' when using bid.cpm is between 8 to 20', function() { - RESPONSE.tags[0].ads[0].cpm = 19.5234; - auction.callBids(cbTimeout); - let bidTargeting = targeting.getAllTargeting(); - expect(bidTargeting['div-gpt-ad-1460505748561-0'][CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]).to.equal('19.50'); - }); - - it('should get correct ' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + ' when using bid.cpm is between 20 to 25', function() { - RESPONSE.tags[0].ads[0].cpm = 21.5234; - auction.callBids(cbTimeout); - let bidTargeting = targeting.getAllTargeting(); - expect(bidTargeting['div-gpt-ad-1460505748561-0'][CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]).to.equal('21.00'); - }); - }); - - describe('getAdserverTargeting with `mediaTypePriceGranularity` set for media type', function() { - let currentPriceBucket; - let auction; - let ajaxStub; - let response; - let cbTimeout = 3000; - let auctionManagerInstance; - let targeting; - - const bannerResponse = { - 'version': '0.0.1', - 'tags': [{ - 'uuid': '4d0a6829338a07', - 'tag_id': 4799418, - 'auction_id': '2256922143947979797', - 'no_ad_url': 'http://lax1-ib.adnxs.com/no-ad', - 'timeout_ms': 2500, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'banner', - 'buyer_member_id': 958, - 'creative_id': 33989846, - 'media_type_id': 1, - 'media_subtype_id': 1, - 'cpm': 1.99, - 'cpm_publisher_currency': 0.500000, - 'publisher_currency_code': '$', - 'client_initiated_ad_counting': true, - 'rtb': { - 'banner': { - 'width': 300, - 'height': 250, - 'content': '' - }, - 'trackers': [{ - 'impression_urls': ['http://lax1-ib.adnxs.com/impression'] - }] - }, - 'viewability': { - 'config': ''} - }] - }] - }; - const videoResponse = { - 'version': '0.0.1', - 'tags': [{ - 'uuid': '4d0a6829338a07', - 'tag_id': 4799418, - 'auction_id': '2256922143947979797', - 'no_ad_url': 'http://lax1-ib.adnxs.com/no-ad', - 'timeout_ms': 2500, - 'ads': [{ - 'content_source': 'rtb', - 'ad_type': 'video', - 'buyer_member_id': 958, - 'creative_id': 33989846, - 'media_type_id': 1, - 'media_subtype_id': 1, - 'cpm': 1.99, - 'cpm_publisher_currency': 0.500000, - 'publisher_currency_code': '$', - 'client_initiated_ad_counting': true, - 'rtb': { - 'video': { - 'width': 300, - 'height': 250, - 'content': '' - }, - 'trackers': [{ - 'impression_urls': ['http://lax1-ib.adnxs.com/impression'] - }] - }, - 'viewability': { - 'config': ''} - }] - }] - }; - - const createAdUnit = (code, mediaTypes) => { - if (!mediaTypes) { - mediaTypes = ['banner']; - } else if (typeof mediaTypes === 'string') { - mediaTypes = [mediaTypes]; - } - - const adUnit = { - code: code, - sizes: [[300, 250], [300, 600]], - bids: [{ - bidder: 'appnexus', - params: { - placementId: '10433394' - } - }] - }; - - let _mediaTypes = {}; - if (mediaTypes.indexOf('banner') !== -1) { - _mediaTypes['banner'] = { - 'banner': {} - }; - } - if (mediaTypes.indexOf('video') !== -1) { - _mediaTypes['video'] = { - 'video': { - context: 'instream', - playerSize: [300, 250] - } - }; - } - if (mediaTypes.indexOf('native') !== -1) { - _mediaTypes['native'] = { - 'native': {} - }; - } - - if (Object.keys(_mediaTypes).length > 0) { - adUnit['mediaTypes'] = _mediaTypes; - // if video type, add video to every bid.param object - if (_mediaTypes.video) { - adUnit.bids.forEach(bid => { - bid.params['video'] = { - width: 300, - height: 250, - vastUrl: '', - ttl: 3600 - }; - }); - } - } - return adUnit; - } - const initTestConfig = (data) => { - $$PREBID_GLOBAL$$.bidderSettings = {}; - - ajaxStub = sinon.stub(ajaxLib, 'ajaxBuilder').callsFake(function() { - return function(url, callback) { - const fakeResponse = sinon.stub(); - fakeResponse.returns('headerContent'); - callback.success(JSON.stringify(response), { getResponseHeader: fakeResponse }); - } - }); - auctionManagerInstance = newAuctionManager(); - targeting = newTargeting(auctionManagerInstance) - - configObj.setConfig({ - 'priceGranularity': { - 'buckets': [ - { 'precision': 2, 'max': 5, 'increment': 0.01 }, - { 'precision': 2, 'max': 8, 'increment': 0.05 }, - { 'precision': 2, 'max': 20, 'increment': 0.5 }, - { 'precision': 2, 'max': 25, 'increment': 1 } - ] - }, - 'mediaTypePriceGranularity': { - 'banner': { - 'buckets': [ - { 'precision': 2, 'max': 5, 'increment': 0.25 }, - { 'precision': 2, 'max': 20, 'increment': 0.5 }, - { 'precision': 2, 'max': 100, 'increment': 1 } - ] - }, - 'video': 'low', - 'native': 'high' - } - }); - - auction = auctionManagerInstance.createAuction({ - adUnits: data.adUnits, - adUnitCodes: data.adUnitCodes - }); - }; - - before(function () { - currentPriceBucket = configObj.getConfig('priceGranularity'); - sinon.stub(adapterManager, 'makeBidRequests').callsFake(() => ([{ - 'bidderCode': 'appnexus', - 'auctionId': '20882439e3238c', - 'bidderRequestId': '331f3cf3f1d9c8', - 'bids': [ - { - 'bidder': 'appnexus', - 'params': { - 'placementId': '10433394' - }, - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'sizes': [ - [ - 300, - 250 - ], - [ - 300, - 600 - ] - ], - 'bidId': '4d0a6829338a07', - 'bidderRequestId': '331f3cf3f1d9c8', - 'auctionId': '20882439e3238c' - } - ], - 'auctionStart': 1505250713622, - 'timeout': 3000 - }])); - }); - - after(function () { - configObj.setConfig({ priceGranularity: currentPriceBucket }); - adapterManager.makeBidRequests.restore(); - }) - - afterEach(function () { - ajaxStub.restore(); - }); - - it('should get correct ' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + ' with cpm between 0 - 5', function() { - initTestConfig({ - adUnits: [createAdUnit('div-gpt-ad-1460505748561-0')], - adUnitCodes: ['div-gpt-ad-1460505748561-0'] - }); - - response = bannerResponse; - response.tags[0].ads[0].cpm = 3.4288; - - auction.callBids(cbTimeout); - let bidTargeting = targeting.getAllTargeting(); - expect(bidTargeting['div-gpt-ad-1460505748561-0'][CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]).to.equal('3.25'); - }); - - it('should get correct ' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + ' with cpm between 21 - 100', function() { - initTestConfig({ - adUnits: [createAdUnit('div-gpt-ad-1460505748561-0')], - adUnitCodes: ['div-gpt-ad-1460505748561-0'] - }); - - response = bannerResponse; - response.tags[0].ads[0].cpm = 43.4288; - - auction.callBids(cbTimeout); - let bidTargeting = targeting.getAllTargeting(); - expect(bidTargeting['div-gpt-ad-1460505748561-0'][CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]).to.equal('43.00'); - }); - - it('should only apply price granularity if bid media type matches', function () { - initTestConfig({ - adUnits: [ createAdUnit('div-gpt-ad-1460505748561-0', 'video') ], - adUnitCodes: ['div-gpt-ad-1460505748561-0'] - }); - - response = videoResponse; - response.tags[0].ads[0].cpm = 3.4288; - - auction.callBids(cbTimeout); - let bidTargeting = targeting.getAllTargeting(); - expect(bidTargeting['div-gpt-ad-1460505748561-0'][CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]).to.equal('3.00'); - }); - }); - - describe('getBidResponses', function () { - it('should return empty obj when last auction Id had no responses', function () { - auctionManager.getLastAuctionId = () => 999994; - var result = $$PREBID_GLOBAL$$.getBidResponses(); - assert.deepEqual(result, {}, 'expected bid responses are returned'); - }); - - it('should return expected bid responses when not passed an adunitCode', function () { - auctionManager.getLastAuctionId = () => 654321; - var result = $$PREBID_GLOBAL$$.getBidResponses(); - var compare = getBidResponsesFromAPI(); - assert.deepEqual(result, compare, 'expected bid responses are returned'); - }); - - it('should return bid responses for most recent auctionId only', function () { - const responses = $$PREBID_GLOBAL$$.getBidResponses(); - assert.equal(responses[Object.keys(responses)[0]].bids.length, 4); - }); - }); - - describe('getBidResponsesForAdUnitCode', function () { - it('should return bid responses as expected', function () { - const adUnitCode = '/19968336/header-bid-tag-0'; - const result = $$PREBID_GLOBAL$$.getBidResponsesForAdUnitCode(adUnitCode); - const bids = getBidResponses().filter(bid => bid.adUnitCode === adUnitCode); - const compare = { bids: bids }; - assert.deepEqual(result, compare, 'expected id responses for ad unit code are returned'); - }); - }); - - describe('setTargetingForGPTAsync', function () { - let logErrorSpy; - - beforeEach(function () { - logErrorSpy = sinon.spy(utils, 'logError'); - resetAuction(); - }); - - afterEach(function () { - utils.logError.restore(); - resetAuction(); - }); - - it('should set googletag targeting keys after calling setTargetingForGPTAsync function', function () { - var slots = createSlotArrayScenario2(); - window.googletag.pubads().setSlots(slots); - $$PREBID_GLOBAL$$.setTargetingForGPTAsync([config.adUnitCodes[0]]); - - // we need to transform the spySetTargeting into something that looks like - // googletag's targeting structure - // googletag setTargeting will override old value if invoked with same key - - const targeting = []; - slots[1].getTargetingKeys().map(function (key) { - const value = slots[1].getTargeting(key); - targeting.push([key, value]); - }); - - var invokedTargetingMap = {}; - slots[1].spySetTargeting.args.map(function (entry) { - invokedTargetingMap[entry[0]] = entry[1]; - }); - - var invokedTargeting = []; - - Object.getOwnPropertyNames(invokedTargetingMap).map(function (key) { - const value = Array.isArray(invokedTargetingMap[key]) ? invokedTargetingMap[key] : [invokedTargetingMap[key]]; // values are always returned as array in googletag - invokedTargeting.push([key, value]); - }); - assert.deepEqual(targeting, invokedTargeting, 'google tag targeting options not matching'); - }); - - it('should set googletag targeting keys to specific slot with customSlotMatching', function () { - // same ad unit code but two differnt divs - // we make sure we can set targeting for a specific one with customSlotMatching - - $$PREBID_GLOBAL$$.setConfig({ enableSendAllBids: false }); - - var slots = [ - new Slot('div-id-one', config.adUnitCodes[0]), - new Slot('div-id-two', config.adUnitCodes[0]), - new Slot(config.adUnitElementIDs[2], config.adUnitCodes[2]) - ]; - - slots[0].spySetTargeting.resetHistory(); - slots[1].spySetTargeting.resetHistory(); - window.googletag.pubads().setSlots(slots); - - $$PREBID_GLOBAL$$.setTargetingForGPTAsync([config.adUnitCodes[0]], (slot) => { - return (adUnitCode) => { - return slots[0].getSlotElementId() === slot.getSlotElementId(); - }; - }); - - var expected = getTargetingKeys(); - expect(slots[0].spySetTargeting.args).to.deep.contain.members(expected); - expect(slots[1].spySetTargeting.args).to.not.deep.contain.members(expected); - }); - - it('should set targeting when passed a string ad unit code with enableSendAllBids', function () { - var slots = createSlotArray(); - window.googletag.pubads().setSlots(slots); - $$PREBID_GLOBAL$$.setConfig({ enableSendAllBids: true }); - - $$PREBID_GLOBAL$$.setTargetingForGPTAsync('/19968336/header-bid-tag-0'); - expect(slots[0].spySetTargeting.args).to.deep.contain.members([[CONSTANTS.TARGETING_KEYS.BIDDER, 'appnexus'], [CONSTANTS.TARGETING_KEYS.AD_ID + '_appnexus', '233bcbee889d46d'], [CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_appnexus', '10.00']]); - }); - - it('should set targeting when passed an array of ad unit codes with enableSendAllBids', function () { - var slots = createSlotArray(); - window.googletag.pubads().setSlots(slots); - $$PREBID_GLOBAL$$.setConfig({ enableSendAllBids: true }); - - $$PREBID_GLOBAL$$.setTargetingForGPTAsync(['/19968336/header-bid-tag-0']); - expect(slots[0].spySetTargeting.args).to.deep.contain.members([[CONSTANTS.TARGETING_KEYS.BIDDER, 'appnexus'], [CONSTANTS.TARGETING_KEYS.AD_ID + '_appnexus', '233bcbee889d46d'], [CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_appnexus', '10.00']]); - }); - - it('should set targeting from googletag data', function () { - var slots = createSlotArray(); - slots[0].spySetTargeting.resetHistory(); - window.googletag.pubads().setSlots(slots); - - $$PREBID_GLOBAL$$.setTargetingForGPTAsync(); - - var expected = getTargetingKeys(); - expect(slots[0].spySetTargeting.args).to.deep.contain.members(expected); - }); - - it('should find correct gpt slot based on ad id rather than ad unit code when resizing secure creative', function () { - var slots = [ - new Slot('div-not-matching-adunit-code-1', config.adUnitCodes[0]), - new Slot('div-not-matching-adunit-code-2', config.adUnitCodes[0]), - new Slot('div-not-matching-adunit-code-3', config.adUnitCodes[0]) - ]; - - slots[1].setTargeting('hb_adid', ['someAdId']); - slots[1].spyGetSlotElementId.resetHistory(); - window.googletag.pubads().setSlots(slots); - - const mockAdObject = { - adId: 'someAdId', - ad: '', - adUrl: 'http://creative.prebid.org/${AUCTION_PRICE}', - width: 300, - height: 250, - renderer: null, - cpm: '1.00', - adUnitCode: config.adUnitCodes[0], - }; - - const event = { - source: { postMessage: sinon.stub() }, - origin: 'origin.sf.com' - }; - - _sendAdToCreative(mockAdObject, event); - - expect(slots[0].spyGetSlotElementId.called).to.equal(false); - expect(slots[1].spyGetSlotElementId.called).to.equal(true); - expect(slots[2].spyGetSlotElementId.called).to.equal(false); - }); - - it('Calling enableSendAllBids should set targeting to include standard keys with bidder' + - ' append to key name', function () { - var slots = createSlotArray(); - window.googletag.pubads().setSlots(slots); - - $$PREBID_GLOBAL$$.setConfig({ enableSendAllBids: true }); - $$PREBID_GLOBAL$$.setTargetingForGPTAsync(); - - var expected = getTargetingKeysBidLandscape(); - expect(slots[0].spySetTargeting.args).to.deep.contain.members(expected); - }); - - it('should set targeting for bids', function () { - // Make sure we're getting the expected losing bid. - assert.equal(auctionManager.getBidsReceived()[0]['bidderCode'], 'triplelift'); - assert.equal(auctionManager.getBidsReceived()[0]['cpm'], 0.112256); - - resetAuction(); - // Modify the losing bid to have `alwaysUseBid=true` and a custom `adserverTargeting` key. - let _bidsReceived = getBidResponses(); - _bidsReceived[0]['adserverTargeting'] = { - always_use_me: 'abc', - }; - - auction.getBidsReceived = function() { return _bidsReceived }; - - var slots = createSlotArray(); - window.googletag.pubads().setSlots(slots); - - $$PREBID_GLOBAL$$.setTargetingForGPTAsync(); - - var expected = [ - [ - CONSTANTS.TARGETING_KEYS.BIDDER, - 'appnexus' - ], - [ - CONSTANTS.TARGETING_KEYS.AD_ID, - '233bcbee889d46d' - ], - [ - CONSTANTS.TARGETING_KEYS.PRICE_BUCKET, - '10.00' - ], - [ - CONSTANTS.TARGETING_KEYS.SIZE, - '300x250' - ], - [ - 'foobar', - ['300x250', '300x600'] - ], - [ - 'always_use_me', - 'abc' - ] - ]; - - expect(slots[0].spySetTargeting.args).to.deep.contain.members(expected); - }); - - it('should log error when googletag is not defined on page', function () { - const error = 'window.googletag is not defined on the page'; - const windowGoogletagBackup = window.googletag; - window.googletag = {}; - - $$PREBID_GLOBAL$$.setTargetingForGPTAsync(); - assert.ok(logErrorSpy.calledWith(error), 'expected error was logged'); - window.googletag = windowGoogletagBackup; - }); - - it('should emit SET_TARGETING event when successfully invoked', function() { - var slots = createSlotArray(); - window.googletag.pubads().setSlots(slots); - - var callback = sinon.spy(); - - $$PREBID_GLOBAL$$.onEvent('setTargeting', callback); - $$PREBID_GLOBAL$$.setTargetingForGPTAsync(config.adUnitCodes); - - sinon.assert.calledOnce(callback); - }); - }); - - describe('renderAd', function () { - var bidId = 1; - var doc = {}; - var elStub = {}; - var adResponse = {}; - var spyLogError = null; - var spyLogMessage = null; - var inIframe = true; - var triggerPixelStub; - - function pushBidResponseToAuction(obj) { - adResponse = Object.assign({ - auctionId: 1, - adId: bidId, - width: 300, - height: 250, - }, obj); - auction.getBidsReceived = function() { - let bidsReceived = getBidResponses(); - bidsReceived.push(adResponse); - return bidsReceived; - } - auction.getAuctionId = () => 1; - } - - beforeEach(function () { - doc = { - write: sinon.spy(), - close: sinon.spy(), - defaultView: { - frameElement: { - width: 0, - height: 0 - } - }, - getElementsByTagName: sinon.stub() - }; - - elStub = { - insertBefore: sinon.stub() - }; - doc.getElementsByTagName.returns([elStub]); - - spyLogError = sinon.spy(utils, 'logError'); - spyLogMessage = sinon.spy(utils, 'logMessage'); - - inIframe = true; - sinon.stub(utils, 'inIframe').callsFake(() => inIframe); - triggerPixelStub = sinon.stub(utils.internal, 'triggerPixel'); - }); - - afterEach(function () { - auction.getBidsReceived = getBidResponses; - utils.logError.restore(); - utils.logMessage.restore(); - utils.inIframe.restore(); - triggerPixelStub.restore(); - }); - - it('should require doc and id params', function () { - $$PREBID_GLOBAL$$.renderAd(); - var error = 'Error trying to write ad Id :undefined to the page. Missing document or adId'; - assert.ok(spyLogError.calledWith(error), 'expected param error was logged'); - }); - - it('should log message with bid id', function () { - $$PREBID_GLOBAL$$.renderAd(doc, bidId); - var message = 'Calling renderAd with adId :' + bidId; - assert.ok(spyLogMessage.calledWith(message), 'expected message was logged'); - }); - - it('should write the ad to the doc', function () { - pushBidResponseToAuction({ - ad: "" - }); - adResponse.ad = ""; - $$PREBID_GLOBAL$$.renderAd(doc, bidId); - assert.ok(doc.write.calledWith(adResponse.ad), 'ad was written to doc'); - assert.ok(doc.close.called, 'close method called'); - }); - - it('should place the url inside an iframe on the doc', function () { - pushBidResponseToAuction({ - adUrl: 'http://server.example.com/ad/ad.js' - }); - $$PREBID_GLOBAL$$.renderAd(doc, bidId); - assert.ok(elStub.insertBefore.called, 'url was written to iframe in doc'); - }); - - it('should log an error when no ad or url', function () { - pushBidResponseToAuction({}); - $$PREBID_GLOBAL$$.renderAd(doc, bidId); - var error = 'Error trying to write ad. No ad for bid response id: ' + bidId; - assert.ok(spyLogError.calledWith(error), 'expected error was logged'); - }); - - it('should log an error when not in an iFrame', function () { - pushBidResponseToAuction({ - ad: "" - }); - inIframe = false; - $$PREBID_GLOBAL$$.renderAd(document, bidId); - const error = 'Error trying to write ad. Ad render call ad id ' + bidId + ' was prevented from writing to the main document.'; - assert.ok(spyLogError.calledWith(error), 'expected error was logged'); - }); - - it('should not render videos', function () { - pushBidResponseToAuction({ - mediatype: 'video' - }); - $$PREBID_GLOBAL$$.renderAd(doc, bidId); - sinon.assert.notCalled(doc.write); - }); - - it('should catch errors thrown when trying to write ads to the page', function () { - pushBidResponseToAuction({ - ad: "" - }); - - var error = { message: 'doc write error' }; - doc.write = sinon.stub().throws(error); - $$PREBID_GLOBAL$$.renderAd(doc, bidId); - - var errorMessage = 'Error trying to write ad Id :' + bidId + ' to the page:' + error.message; - assert.ok(spyLogError.calledWith(errorMessage), 'expected error was logged'); - }); - - it('should log an error when ad not found', function () { - var fakeId = 99; - $$PREBID_GLOBAL$$.renderAd(doc, fakeId); - var error = 'Error trying to write ad. Cannot find ad by given id : ' + fakeId; - assert.ok(spyLogError.calledWith(error), 'expected error was logged'); - }); - - it('should save bid displayed to winning bid', function () { - pushBidResponseToAuction({ - ad: "" - }); - $$PREBID_GLOBAL$$.renderAd(doc, bidId); - assert.deepEqual($$PREBID_GLOBAL$$.getAllWinningBids()[0], adResponse); - }); - - it('should replace ${CLICKTHROUGH} macro in winning bids response', function () { - pushBidResponseToAuction({ - ad: "" - }); - $$PREBID_GLOBAL$$.renderAd(doc, bidId, {clickThrough: 'https://someadserverclickurl.com'}); - expect(adResponse).to.have.property('ad').and.to.match(/https:\/\/someadserverclickurl\.com/i); - }); - - it('fires billing url if present on s2s bid', function () { - const burl = 'http://www.example.com/burl'; - pushBidResponseToAuction({ - ad: '

ad
', - source: 's2s', - burl - }); - - $$PREBID_GLOBAL$$.renderAd(doc, bidId); - - sinon.assert.calledOnce(triggerPixelStub); - sinon.assert.calledWith(triggerPixelStub, burl); - }); - }); - - describe('requestBids', function () { - let logMessageSpy; - let makeRequestsStub; - let adUnits; - let clock; - before(function () { - clock = sinon.useFakeTimers(); - }); - after(function () { - clock.restore(); - }); - let bidsBackHandlerStub = sinon.stub(); - - const BIDDER_CODE = 'sampleBidder'; - let bids = [{ - 'ad': 'creative', - 'cpm': '1.99', - 'width': 300, - 'height': 250, - 'bidderCode': BIDDER_CODE, - 'requestId': '4d0a6829338a07', - 'creativeId': 'id', - 'currency': 'USD', - 'netRevenue': true, - 'ttl': 360 - }]; - let bidRequests = [{ - 'bidderCode': BIDDER_CODE, - 'auctionId': '20882439e3238c', - 'bidderRequestId': '331f3cf3f1d9c8', - 'bids': [ - { - 'bidder': BIDDER_CODE, - 'params': { - 'placementId': 'id' - }, - 'adUnitCode': 'adUnit-code', - 'sizes': [[300, 250], [300, 600]], - 'bidId': '4d0a6829338a07', - 'bidderRequestId': '331f3cf3f1d9c8', - 'auctionId': '20882439e3238c' - } - ], - 'auctionStart': 1505250713622, - 'timeout': 3000, - 'start': 1000 - }]; - - beforeEach(function () { - logMessageSpy = sinon.spy(utils, 'logMessage'); - makeRequestsStub = sinon.stub(adapterManager, 'makeBidRequests'); - makeRequestsStub.returns(bidRequests); - - adUnits = [{ - code: 'adUnit-code', - mediaTypes: { - banner: { - sizes: [[300, 250]] - } - }, - bids: [ - {bidder: BIDDER_CODE, params: {placementId: 'id'}}, - ] - }]; - let adUnitCodes = ['adUnit-code']; - let auction = auctionModule.newAuction({ - adUnits, - adUnitCodes, - callback: bidsBackHandlerStub, - cbTimeout: 2000 - }); - let createAuctionStub = sinon.stub(auctionModule, 'newAuction'); - createAuctionStub.returns(auction); - }); - - afterEach(function () { - clock.restore(); - adapterManager.makeBidRequests.restore(); - auctionModule.newAuction.restore(); - utils.logMessage.restore(); - }); - - it('should execute callback after timeout', function () { - let spec = { - code: BIDDER_CODE, - isBidRequestValid: sinon.stub(), - buildRequests: sinon.stub(), - interpretResponse: sinon.stub(), - getUserSyncs: sinon.stub(), - onTimeout: sinon.stub() - }; - - registerBidder(spec); - spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); - spec.isBidRequestValid.returns(true); - spec.interpretResponse.returns(bids); - - let requestObj = { - bidsBackHandler: null, // does not need to be defined because of newAuction mock in beforeEach - timeout: 2000, - adUnits: adUnits - }; - - $$PREBID_GLOBAL$$.requestBids(requestObj); - let re = new RegExp('^Auction [a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12} timedOut$'); - clock.tick(requestObj.timeout - 1); - assert.ok(logMessageSpy.neverCalledWith(sinon.match(re)), 'executeCallback not called'); - - clock.tick(1); - assert.ok(logMessageSpy.calledWith(sinon.match(re)), 'executeCallback called'); - - expect(bidsBackHandlerStub.getCall(0).args[1]).to.equal(true, - 'bidsBackHandler should be called with timedOut=true'); - - sinon.assert.called(spec.onTimeout); - }); - - it('should execute callback after setTargeting', function () { - let spec = { - code: BIDDER_CODE, - isBidRequestValid: sinon.stub(), - buildRequests: sinon.stub(), - interpretResponse: sinon.stub(), - onSetTargeting: sinon.stub() - }; - - registerBidder(spec); - spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); - spec.isBidRequestValid.returns(true); - spec.interpretResponse.returns(bids); - - const bidId = 1; - const auctionId = 1; - let adResponse = Object.assign({ - auctionId: auctionId, - adId: String(bidId), - width: 300, - height: 250, - adUnitCode: bidRequests[0].bids[0].adUnitCode, - adserverTargeting: { - 'hb_bidder': BIDDER_CODE, - 'hb_adid': bidId, - 'hb_pb': bids[0].cpm, - 'hb_size': '300x250', - }, - bidder: bids[0].bidderCode, - }, bids[0]); - auction.getBidsReceived = function() { return [adResponse]; } - auction.getAuctionId = () => auctionId; - - let requestObj = { - bidsBackHandler: null, // does not need to be defined because of newAuction mock in beforeEach - timeout: 2000, - adUnits: adUnits - }; - - $$PREBID_GLOBAL$$.requestBids(requestObj); - $$PREBID_GLOBAL$$.setTargetingForGPTAsync(); - - sinon.assert.called(spec.onSetTargeting); - }); - }) - - describe('requestBids', function () { - let sandbox; - beforeEach(function () { - sandbox = sinon.sandbox.create(); - }); - afterEach(function () { - sandbox.restore(); - }); - describe('bidRequests is empty', function () { - it('should log warning message and execute callback if bidRequests is empty', function () { - let bidsBackHandler = function bidsBackHandlerCallback() {}; - let spyExecuteCallback = sinon.spy(bidsBackHandler); - let logWarnSpy = sandbox.spy(utils, 'logWarn'); - - $$PREBID_GLOBAL$$.requestBids({ - adUnits: [ - { - code: 'test1', - mediaTypes: { banner: { sizes: [] } }, - bids: [], - }, { - code: 'test2', - mediaTypes: { banner: { sizes: [] } }, - bids: [], - } - ], - bidsBackHandler: spyExecuteCallback - }); - - assert.ok(logWarnSpy.calledWith('No valid bid requests returned for auction'), 'expected warning message was logged'); - assert.ok(spyExecuteCallback.calledOnce, 'callback executed when bidRequests is empty'); - }); - }); - }); - - describe('requestBids', function () { - var adUnitsBackup; - var auctionManagerStub; - let logMessageSpy; - let logInfoSpy; - let logErrorSpy; - - let spec = { - code: 'sampleBidder', - isBidRequestValid: () => {}, - buildRequests: () => {}, - interpretResponse: () => {}, - getUserSyncs: () => {} - }; - registerBidder(spec); - - describe('part 1', function () { - let auctionArgs; - - beforeEach(function () { - adUnitsBackup = auction.getAdUnits - auctionManagerStub = sinon.stub(auctionManager, 'createAuction').callsFake(function() { - auctionArgs = arguments[0]; - return auction; - }); - logMessageSpy = sinon.spy(utils, 'logMessage'); - logInfoSpy = sinon.spy(utils, 'logInfo'); - logErrorSpy = sinon.spy(utils, 'logError'); - }); - - afterEach(function () { - auction.getAdUnits = adUnitsBackup; - auctionManager.createAuction.restore(); - utils.logMessage.restore(); - utils.logInfo.restore(); - utils.logError.restore(); - resetAuction(); - }); - - it('should log message when adUnits not configured', function () { - $$PREBID_GLOBAL$$.adUnits = []; - try { - $$PREBID_GLOBAL$$.requestBids({}); - } catch (e) { - console.log(e); // eslint-disable-line - } - assert.ok(logMessageSpy.calledWith('No adUnits configured. No bids requested.'), 'expected message was logged'); - }); - - it('should always attach new transactionIds to adUnits passed to requestBids', function () { - $$PREBID_GLOBAL$$.requestBids({ - adUnits: [ - { - code: 'test1', - transactionId: 'd0676a3c-ff32-45a5-af65-8175a8e7ddca', - mediaTypes: { banner: { sizes: [] } }, - bids: [] - }, { - code: 'test2', - mediaTypes: { banner: { sizes: [] } }, - bids: [] - } - ] - }); - - expect(auctionArgs.adUnits[0]).to.have.property('transactionId') - .and.to.match(/[a-f0-9\-]{36}/i) - .and.not.to.equal('d0676a3c-ff32-45a5-af65-8175a8e7ddca'); - expect(auctionArgs.adUnits[1]).to.have.property('transactionId') - .and.to.match(/[a-f0-9\-]{36}/i); - }); - - it('should notify targeting of the latest auction for each adUnit', function () { - let latestStub = sinon.stub(targeting, 'setLatestAuctionForAdUnit'); - let getAuctionStub = sinon.stub(auction, 'getAuctionId').returns(2); - - $$PREBID_GLOBAL$$.requestBids({ - adUnits: [ - { - code: 'test1', - mediaTypes: { banner: { sizes: [] } }, - bids: [] - }, { - code: 'test2', - mediaTypes: { banner: { sizes: [] } }, - bids: [] - } - ] - }); - - expect(latestStub.firstCall.calledWith('test1', 2)).to.equal(true); - expect(latestStub.secondCall.calledWith('test2', 2)).to.equal(true); - - latestStub.restore(); - getAuctionStub.restore(); - }); - - it('should execute callback immediately if adUnits is empty', function () { - var bidsBackHandler = function bidsBackHandlerCallback() {}; - var spyExecuteCallback = sinon.spy(bidsBackHandler); - - $$PREBID_GLOBAL$$.adUnits = []; - $$PREBID_GLOBAL$$.requestBids({ - bidsBackHandler: spyExecuteCallback - }); - - assert.ok(spyExecuteCallback.calledOnce, 'callback executed immediately when adUnits is' + - ' empty'); - }); - - it('should not propagate exceptions from bidsBackHandler', function () { - $$PREBID_GLOBAL$$.adUnits = []; - - var requestObj = { - bidsBackHandler: function bidsBackHandlerCallback() { - var test; - return test.test; - } - }; - - expect(() => { - $$PREBID_GLOBAL$$.requestBids(requestObj); - }).not.to.throw(); - }); - - describe('checkAdUnitSetup', function() { - describe('positive tests for validating adUnits', function() { - it('should maintain adUnit structure and adUnit.sizes is replaced', function () { - let fullAdUnit = [{ - code: 'test1', - sizes: [[300, 250], [300, 600]], - mediaTypes: { - banner: { - sizes: [[300, 250]] - }, - video: { - playerSize: [[640, 480]] - }, - native: { - image: { - sizes: [150, 150], - aspect_ratios: [140, 140] - }, - icon: { - sizes: [75, 75] - } - } - }, - bids: [] - }]; - $$PREBID_GLOBAL$$.requestBids({ - adUnits: fullAdUnit - }); - expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[640, 480]]); - expect(auctionArgs.adUnits[0].mediaTypes.video.playerSize).to.deep.equal([[640, 480]]); - expect(auctionArgs.adUnits[0].mediaTypes.native.image.sizes).to.deep.equal([150, 150]); - expect(auctionArgs.adUnits[0].mediaTypes.native.icon.sizes).to.deep.equal([75, 75]); - expect(auctionArgs.adUnits[0].mediaTypes.native.image.aspect_ratios).to.deep.equal([140, 140]); - - let noOptnlFieldAdUnit = [{ - code: 'test2', - bids: [], - sizes: [[300, 250], [300, 600]], - mediaTypes: { - banner: { - sizes: [[300, 250]] - }, - video: { - context: 'outstream' - }, - native: { - image: { - required: true - }, - icon: { - required: true - } - } - } - }]; - $$PREBID_GLOBAL$$.requestBids({ - adUnits: noOptnlFieldAdUnit - }); - expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[300, 250]]); - expect(auctionArgs.adUnits[0].mediaTypes.video).to.exist; - - let mixedAdUnit = [{ - code: 'test3', - bids: [], - sizes: [[300, 250], [300, 600]], - mediaTypes: { - video: { - context: 'outstream', - playerSize: [[400, 350]] - }, - native: { - image: { - aspect_ratios: [200, 150], - required: true - } - } - } - }]; - $$PREBID_GLOBAL$$.requestBids({ - adUnits: mixedAdUnit - }); - expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[400, 350]]); - expect(auctionArgs.adUnits[0].mediaTypes.video).to.exist; - - let altVideoPlayerSize = [{ - code: 'test4', - bids: [], - sizes: [[600, 600]], - mediaTypes: { - video: { - playerSize: [640, 480] - } - } - }]; - $$PREBID_GLOBAL$$.requestBids({ - adUnits: altVideoPlayerSize - }); - expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[640, 480]]); - expect(auctionArgs.adUnits[0].mediaTypes.video.playerSize).to.deep.equal([[640, 480]]); - expect(auctionArgs.adUnits[0].mediaTypes.video).to.exist; - }); - - it('should normalize adUnit.sizes and adUnit.mediaTypes.banner.sizes', function () { - let normalizeAdUnit = [{ - code: 'test5', - bids: [], - sizes: [300, 250], - mediaTypes: { - banner: { - sizes: [300, 250] - } - } - }]; - $$PREBID_GLOBAL$$.requestBids({ - adUnits: normalizeAdUnit - }); - expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[300, 250]]); - expect(auctionArgs.adUnits[0].mediaTypes.banner.sizes).to.deep.equal([[300, 250]]); - }); - }); - - describe('negative tests for validating adUnits', function() { - it('should throw error message and delete an object/property', function () { - let badBanner = [{ - code: 'testb1', - bids: [], - sizes: [[300, 250], [300, 600]], - mediaTypes: { - banner: { - name: 'test' - } - } - }]; - $$PREBID_GLOBAL$$.requestBids({ - adUnits: badBanner - }); - expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[300, 250], [300, 600]]); - expect(auctionArgs.adUnits[0].mediaTypes.banner).to.be.undefined; - assert.ok(logErrorSpy.calledWith('Detected a mediaTypes.banner object without a proper sizes field. Please ensure the sizes are listed like: [[300, 250], ...]. Removing invalid mediaTypes.banner object from request.')); - - let badVideo1 = [{ - code: 'testb2', - bids: [], - sizes: [[600, 600]], - mediaTypes: { - video: { - playerSize: ['600x400'] - } - } - }]; - $$PREBID_GLOBAL$$.requestBids({ - adUnits: badVideo1 - }); - expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[600, 600]]); - expect(auctionArgs.adUnits[0].mediaTypes.video.playerSize).to.be.undefined; - expect(auctionArgs.adUnits[0].mediaTypes.video).to.exist; - assert.ok(logErrorSpy.calledWith('Detected incorrect configuration of mediaTypes.video.playerSize. Please specify only one set of dimensions in a format like: [[640, 480]]. Removing invalid mediaTypes.video.playerSize property from request.')); - - let badVideo2 = [{ - code: 'testb3', - bids: [], - sizes: [[600, 600]], - mediaTypes: { - video: { - playerSize: [['300', '200']] - } - } - }]; - $$PREBID_GLOBAL$$.requestBids({ - adUnits: badVideo2 - }); - expect(auctionArgs.adUnits[0].sizes).to.deep.equal([[600, 600]]); - expect(auctionArgs.adUnits[0].mediaTypes.video.playerSize).to.be.undefined; - expect(auctionArgs.adUnits[0].mediaTypes.video).to.exist; - assert.ok(logErrorSpy.calledWith('Detected incorrect configuration of mediaTypes.video.playerSize. Please specify only one set of dimensions in a format like: [[640, 480]]. Removing invalid mediaTypes.video.playerSize property from request.')); - - let badNativeImgSize = [{ - code: 'testb4', - bids: [], - mediaTypes: { - native: { - image: { - sizes: '300x250' - } - } - } - }]; - $$PREBID_GLOBAL$$.requestBids({ - adUnits: badNativeImgSize - }); - expect(auctionArgs.adUnits[0].mediaTypes.native.image.sizes).to.be.undefined; - expect(auctionArgs.adUnits[0].mediaTypes.native.image).to.exist; - assert.ok(logErrorSpy.calledWith('Please use an array of sizes for native.image.sizes field. Removing invalid mediaTypes.native.image.sizes property from request.')); - - let badNativeImgAspRat = [{ - code: 'testb5', - bids: [], - mediaTypes: { - native: { - image: { - aspect_ratios: '300x250' - } - } - } - }]; - $$PREBID_GLOBAL$$.requestBids({ - adUnits: badNativeImgAspRat - }); - expect(auctionArgs.adUnits[0].mediaTypes.native.image.aspect_ratios).to.be.undefined; - expect(auctionArgs.adUnits[0].mediaTypes.native.image).to.exist; - assert.ok(logErrorSpy.calledWith('Please use an array of sizes for native.image.aspect_ratios field. Removing invalid mediaTypes.native.image.aspect_ratios property from request.')); - - let badNativeIcon = [{ - code: 'testb6', - bids: [], - mediaTypes: { - native: { - icon: { - sizes: '300x250' - } - } - } - }]; - $$PREBID_GLOBAL$$.requestBids({ - adUnits: badNativeIcon - }); - expect(auctionArgs.adUnits[0].mediaTypes.native.icon.sizes).to.be.undefined; - expect(auctionArgs.adUnits[0].mediaTypes.native.icon).to.exist; - assert.ok(logErrorSpy.calledWith('Please use an array of sizes for native.icon.sizes field. Removing invalid mediaTypes.native.icon.sizes property from request.')); - }); - - it('should throw error message and remove adUnit if adUnit.bids is not defined correctly', function () { - const adUnits = [{ - code: 'ad-unit-1', - mediaTypes: { - banner: { - sizes: [300, 400] - } - }, - bids: [{code: 'appnexus', params: 1234}] - }, { - code: 'bad-ad-unit-2', - mediaTypes: { - banner: { - sizes: [300, 400] - } - } - }]; - - $$PREBID_GLOBAL$$.requestBids({ - adUnits: adUnits - }); - expect(auctionArgs.adUnits.length).to.equal(1); - expect(auctionArgs.adUnits[1]).to.not.exist; - assert.ok(logErrorSpy.calledWith("Detected adUnit.code 'bad-ad-unit-2' did not have 'adUnit.bids' defined or 'adUnit.bids' is not an array. Removing adUnit from auction.")); - }); - }); - }); - }); - - describe('multiformat requests', function () { - let adUnits; - - beforeEach(function () { - adUnits = [{ - code: 'adUnit-code', - mediaTypes: { - banner: { - sizes: [[300, 250]] - }, - native: {}, - }, - sizes: [[300, 250], [300, 600]], - bids: [ - {bidder: 'appnexus', params: {placementId: 'id'}}, - {bidder: 'sampleBidder', params: {placementId: 'banner-only-bidder'}} - ] - }]; - adUnitCodes = ['adUnit-code']; - configObj.setConfig({maxRequestsPerOrigin: Number.MAX_SAFE_INTEGER || 99999999}); - sinon.spy(adapterManager, 'callBids'); - }) - - afterEach(function () { - adapterManager.callBids.restore(); - }); - - it('bidders that support one of the declared formats are allowed to participate', function () { - $$PREBID_GLOBAL$$.requestBids({adUnits}); - sinon.assert.calledOnce(adapterManager.callBids); - - const spyArgs = adapterManager.callBids.getCall(0); - const biddersCalled = spyArgs.args[0][0].bids; - - // appnexus and sampleBidder both support banner - expect(biddersCalled.length).to.equal(2); - }); - - it('bidders that do not support one of the declared formats are dropped', function () { - delete adUnits[0].mediaTypes.banner; - - $$PREBID_GLOBAL$$.requestBids({adUnits}); - sinon.assert.calledOnce(adapterManager.callBids); - - const spyArgs = adapterManager.callBids.getCall(0); - const biddersCalled = spyArgs.args[0][0].bids; - // only appnexus supports native - expect(biddersCalled.length).to.equal(1); - }); - }); - - describe('part 2', function () { - let spyCallBids; - let createAuctionStub; - let adUnits; - - before(function () { - adUnits = [{ - code: 'adUnit-code', - mediaTypes: { banner: { sizes: [[300, 250], [300, 600]] } }, - bids: [ - {bidder: 'appnexus', params: {placementId: '10433394'}} - ] - }]; - let adUnitCodes = ['adUnit-code']; - let auction = auctionModule.newAuction({adUnits, adUnitCodes, callback: function() {}, cbTimeout: timeout}); - - adUnits[0]['mediaTypes'] = { native: {} }; - adUnitCodes = ['adUnit-code']; - let auction1 = auctionModule.newAuction({adUnits, adUnitCodes, callback: function() {}, cbTimeout: timeout}); - - adUnits = [{ - code: 'adUnit-code', - mediaTypes: { native: { type: 'image' } }, - sizes: [[300, 250], [300, 600]], - bids: [ - {bidder: 'appnexus', params: {placementId: 'id'}} - ] - }]; - let auction3 = auctionModule.newAuction({adUnits, adUnitCodes, callback: function() {}, cbTimeout: timeout}); - - let createAuctionStub = sinon.stub(auctionModule, 'newAuction'); - createAuctionStub.onCall(0).returns(auction1); - createAuctionStub.onCall(2).returns(auction3); - createAuctionStub.returns(auction); - }); - - after(function () { - auctionModule.newAuction.restore(); - }); - - beforeEach(function () { - spyCallBids = sinon.spy(adapterManager, 'callBids'); - }) - - afterEach(function () { - adapterManager.callBids.restore(); - }) - - it('should callBids if a native adUnit has all native bidders', function () { - $$PREBID_GLOBAL$$.requestBids({adUnits}); - sinon.assert.calledOnce(adapterManager.callBids); - }); - - it('should call callBids function on adapterManager', function () { - let adUnits = [{ - code: 'adUnit-code', - mediaTypes: { banner: { sizes: [[300, 250], [300, 600]] } }, - bids: [ - {bidder: 'appnexus', params: {placementId: '10433394'}} - ] - }]; - $$PREBID_GLOBAL$$.requestBids({adUnits}); - assert.ok(spyCallBids.called, 'called adapterManager.callBids'); - }); - - it('splits native type to individual native assets', function () { - let adUnits = [{ - code: 'adUnit-code', - mediaTypes: { native: { type: 'image' } }, - bids: [ - {bidder: 'appnexus', params: {placementId: 'id'}} - ] - }]; - $$PREBID_GLOBAL$$.requestBids({adUnits}); - const spyArgs = adapterManager.callBids.getCall(0); - const nativeRequest = spyArgs.args[1][0].bids[0].nativeParams; - expect(nativeRequest).to.deep.equal({ - image: {required: true}, - title: {required: true}, - sponsoredBy: {required: true}, - clickUrl: {required: true}, - body: {required: false}, - icon: {required: false}, - }); - resetAuction(); - }); - }); - - describe('part-3', function () { - let auctionManagerInstance = newAuctionManager(); - let auctionManagerStub; - let adUnits1 = getAdUnits().filter((adUnit) => { - return adUnit.code === '/19968336/header-bid-tag1'; - }); - let adUnitCodes1 = getAdUnits().map(unit => unit.code); - let auction1 = auctionManagerInstance.createAuction({adUnits: adUnits1, adUnitCodes: adUnitCodes1}); - - let adUnits2 = getAdUnits().filter((adUnit) => { - return adUnit.code === '/19968336/header-bid-tag-0'; - }); - let adUnitCodes2 = getAdUnits().map(unit => unit.code); - let auction2 = auctionManagerInstance.createAuction({adUnits: adUnits2, adUnitCodes: adUnitCodes2}); - let spyCallBids; - - auction1.getBidRequests = function() { - return getBidRequests().map((req) => { - req.bids = req.bids.filter((bid) => { - return bid.adUnitCode === '/19968336/header-bid-tag1'; - }); - return (req.bids.length > 0) ? req : undefined; - }).filter((item) => { - return item != undefined; - }); - }; - auction1.getBidsReceived = function() { - return getBidResponses().filter((bid) => { - return bid.adUnitCode === '/19968336/header-bid-tag1'; - }); - }; - - auction2.getBidRequests = function() { - return getBidRequests().map((req) => { - req.bids = req.bids.filter((bid) => { - return bid.adUnitCode === '/19968336/header-bid-tag-0'; - }); - return (req.bids.length > 0) ? req : undefined; - }).filter((item) => { - return item != undefined; - }); - }; - auction2.getBidsReceived = function() { - return getBidResponses().filter((bid) => { - return bid.adUnitCode === '/19968336/header-bid-tag-0'; - }); - }; - - beforeEach(function() { - spyCallBids = sinon.spy(adapterManager, 'callBids'); - auctionManagerStub = sinon.stub(auctionManager, 'createAuction'); - auctionManagerStub.onCall(0).returns(auction1); - auctionManagerStub.onCall(1).returns(auction2); - }); - - afterEach(function() { - auctionManager.createAuction.restore(); - adapterManager.callBids.restore(); - }); - - it('should not queue bid requests when a previous bid request is in process', function () { - var requestObj1 = { - bidsBackHandler: function bidsBackHandlerCallback() {}, - timeout: 2000, - adUnits: auction1.getAdUnits() - }; - - var requestObj2 = { - bidsBackHandler: function bidsBackHandlerCallback() {}, - timeout: 2000, - adUnits: auction2.getAdUnits() - }; - - assert.equal(auctionManager.getBidsReceived().length, 8, '_bidsReceived contains 8 bids'); - - $$PREBID_GLOBAL$$.requestBids(requestObj1); - $$PREBID_GLOBAL$$.requestBids(requestObj2); - - assert.ok(spyCallBids.calledTwice, 'When two requests for bids are made both should be' + - ' callBids immediately'); - - let result = targeting.getAllTargeting(['/19968336/header-bid-tag-0', '/19968336/header-bid-tag1']); // $$PREBID_GLOBAL$$.getAdserverTargeting(); - let expected = { - '/19968336/header-bid-tag-0': { - 'foobar': '0x0,300x250,300x600', - [CONSTANTS.TARGETING_KEYS.SIZE]: '300x250', - [CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]: '10.00', - [CONSTANTS.TARGETING_KEYS.AD_ID]: '233bcbee889d46d', - [CONSTANTS.TARGETING_KEYS.BIDDER]: 'appnexus' - }, - '/19968336/header-bid-tag1': { - [CONSTANTS.TARGETING_KEYS.BIDDER]: 'appnexus', - [CONSTANTS.TARGETING_KEYS.AD_ID]: '24bd938435ec3fc', - [CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]: '10.00', - [CONSTANTS.TARGETING_KEYS.SIZE]: '728x90', - 'foobar': '728x90' - } - } - assert.deepEqual(result, expected, 'targeting info returned for current placements'); - }); - }); - }); - - describe('onEvent', function () { - it('should log an error when handler is not a function', function () { - var spyLogError = sinon.spy(utils, 'logError'); - var event = 'testEvent'; - $$PREBID_GLOBAL$$.onEvent(event); - assert.ok(spyLogError.calledWith('The event handler provided is not a function and was not set on event "' + event + '".'), - 'expected error was logged'); - utils.logError.restore(); - }); - - it('should log an error when id provided is not valid for event', function () { - var spyLogError = sinon.spy(utils, 'logError'); - var event = 'bidWon'; - $$PREBID_GLOBAL$$.onEvent(event, Function, 'testId'); - assert.ok(spyLogError.calledWith('The id provided is not valid for event "' + event + '" and no handler was set.'), - 'expected error was logged'); - utils.logError.restore(); - }); - - it('should call events.on with valid parameters', function () { - var spyEventsOn = sinon.spy(events, 'on'); - $$PREBID_GLOBAL$$.onEvent('bidWon', Function); - assert.ok(spyEventsOn.calledWith('bidWon', Function)); - events.on.restore(); - }); - - describe('beforeRequestBids', function () { - let bidRequestedHandler; - let beforeRequestBidsHandler; - let bidsBackHandler = function bidsBackHandler() {}; - - let bidsBackSpy; - let bidRequestedSpy; - let beforeRequestBidsSpy; - - beforeEach(function () { - resetAuction(); - bidsBackSpy = sinon.spy(bidsBackHandler); - googletag.pubads().setSlots(createSlotArrayScenario2()); - }); - - afterEach(function () { - bidsBackSpy.resetHistory(); - - if (bidRequestedSpy) { - $$PREBID_GLOBAL$$.offEvent('bidRequested', bidRequestedSpy); - bidRequestedSpy.resetHistory(); - } - - if (beforeRequestBidsSpy) { - $$PREBID_GLOBAL$$.offEvent('beforeRequestBids', beforeRequestBidsSpy); - beforeRequestBidsSpy.resetHistory(); - } - }); - - it('should allow creation of a fpd.context.pbAdSlot property on adUnits from inside the event handler', function () { - // verify adUnits passed to handler then alter the adUnits - beforeRequestBidsHandler = function beforeRequestBidsHandler(beforeRequestBidsAdUnits) { - expect(beforeRequestBidsAdUnits).to.be.a('array'); - expect(beforeRequestBidsAdUnits).to.have.lengthOf(1); - expect(beforeRequestBidsAdUnits[0]).to.be.a('object'); - // adUnit should not contain a context property yet - expect(beforeRequestBidsAdUnits[0]).to.not.have.property('fpd') - // alter the adUnit by adding the property for context.pbAdSlot - beforeRequestBidsAdUnits[0].fpd = { - context: { - pbAdSlot: '/19968336/header-bid-tag-pbadslot-0' - } - }; - }; - beforeRequestBidsSpy = sinon.spy(beforeRequestBidsHandler); - - // use this handler to verify if the adUnits alterations were applied successfully by the beforeRequestBids handler - bidRequestedHandler = function bidRequestedHandler(bidRequest) { - expect(bidRequest).to.be.a('object'); - expect(bidRequest).to.have.property('bids'); - expect(bidRequest.bids).to.be.a('array'); - expect(bidRequest.bids).to.have.lengthOf(1); - const bid = bidRequest['bids'][0]; - expect(bid).to.be.a('object'); - expect(bid).to.have.property('fpd'); - expect(bid.fpd).to.be.a('object'); - expect(bid.fpd).to.have.property('context'); - expect(bid.fpd.context).to.be.a('object'); - expect(bid.fpd.context).to.have.property('pbAdSlot'); - expect(bid.fpd.context.pbAdSlot).to.equal('/19968336/header-bid-tag-pbadslot-0'); - }; - bidRequestedSpy = sinon.spy(bidRequestedHandler); - - $$PREBID_GLOBAL$$.onEvent('beforeRequestBids', beforeRequestBidsSpy); - $$PREBID_GLOBAL$$.onEvent('bidRequested', bidRequestedSpy); - $$PREBID_GLOBAL$$.requestBids({ - adUnits: [{ - code: '/19968336/header-bid-tag-0', - mediaTypes: { - banner: { - sizes: [[750, 350]] - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13122370 - } - }] - }], - bidsBackHandler: bidsBackSpy - }); - - sinon.assert.calledOnce(beforeRequestBidsSpy); - sinon.assert.calledOnce(bidRequestedSpy); - }); - - it('should allow creation of a fpd.context.pbAdSlot property on adUnits from inside the event handler', function () { - // verify adUnits passed to handler then alter the adUnits - beforeRequestBidsHandler = function beforeRequestBidsHandler(beforeRequestBidsAdUnits) { - expect(beforeRequestBidsAdUnits).to.be.a('array'); - expect(beforeRequestBidsAdUnits).to.have.lengthOf(2); - expect(beforeRequestBidsAdUnits[0]).to.be.a('object'); - expect(beforeRequestBidsAdUnits[1]).to.be.a('object'); - // adUnit should not contain a context property yet - expect(beforeRequestBidsAdUnits[0]).to.not.have.property('fpd'); - expect(beforeRequestBidsAdUnits[1]).to.not.have.property('fpd'); - // alter the adUnit by adding the property for context.pbAdSlot - beforeRequestBidsAdUnits[0].fpd = { - context: { - pbAdSlot: '/19968336/header-bid-tag-pbadslot-0' - } - }; - beforeRequestBidsAdUnits[1].fpd = { - context: { - pbAdSlot: '/19968336/header-bid-tag-pbadslot-1' - } - }; - }; - beforeRequestBidsSpy = sinon.spy(beforeRequestBidsHandler); - - // use this handler to verify if the adUnits alterations were applied successfully by the beforeRequestBids handler - bidRequestedHandler = function bidRequestedHandler(bidRequest) { - expect(bidRequest).to.be.a('object'); - expect(bidRequest).to.have.property('bids'); - expect(bidRequest.bids).to.be.a('array'); - expect(bidRequest.bids).to.have.lengthOf(2); - const bid0 = bidRequest['bids'][0]; - expect(bid0).to.be.a('object'); - expect(bid0).to.have.property('fpd'); - expect(bid0.fpd).to.be.a('object'); - expect(bid0.fpd).to.have.property('context'); - expect(bid0.fpd.context).to.be.a('object'); - expect(bid0.fpd.context).to.have.property('pbAdSlot'); - expect(bid0.fpd.context.pbAdSlot).to.equal('/19968336/header-bid-tag-pbadslot-0'); - - const bid1 = bidRequest['bids'][1]; - expect(bid1).to.be.a('object'); - expect(bid1).to.have.property('fpd'); - expect(bid1.fpd).to.be.a('object'); - expect(bid1.fpd).to.have.property('context'); - expect(bid1.fpd.context).to.be.a('object'); - expect(bid1.fpd.context).to.have.property('pbAdSlot'); - expect(bid1.fpd.context.pbAdSlot).to.equal('/19968336/header-bid-tag-pbadslot-1'); - }; - bidRequestedSpy = sinon.spy(bidRequestedHandler); - - $$PREBID_GLOBAL$$.onEvent('beforeRequestBids', beforeRequestBidsSpy); - $$PREBID_GLOBAL$$.onEvent('bidRequested', bidRequestedSpy); - $$PREBID_GLOBAL$$.requestBids({ - adUnits: [{ - code: '/19968336/header-bid-tag-0', - mediaTypes: { - banner: { - sizes: [[750, 350]] - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13122370 - } - }] - }, { - code: '/19968336/header-bid-tag-1', - mediaTypes: { - banner: { - sizes: [[750, 350]] - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 14122380 - } - }] - }], - bidsBackHandler: bidsBackSpy - }); - - sinon.assert.calledOnce(beforeRequestBidsSpy); - sinon.assert.calledOnce(bidRequestedSpy); - }); - - it('should not create a context property on adUnits if not added by handler', function () { - // verify adUnits passed to handler then alter the adUnits - beforeRequestBidsHandler = function beforeRequestBidsHandler(beforeRequestBidsAdUnits) { - expect(beforeRequestBidsAdUnits).to.be.a('array'); - expect(beforeRequestBidsAdUnits).to.have.lengthOf(1); - expect(beforeRequestBidsAdUnits[0]).to.be.a('object'); - // adUnit should not contain a context property yet - expect(beforeRequestBidsAdUnits[0]).to.not.have.property('context') - }; - beforeRequestBidsSpy = sinon.spy(beforeRequestBidsHandler); - - // use this handler to verify if the adUnits alterations were applied successfully by the beforeRequestBids handler - bidRequestedHandler = function bidRequestedHandler(bidRequest) { - expect(bidRequest).to.be.a('object'); - expect(bidRequest).to.have.property('bids'); - expect(bidRequest.bids).to.be.a('array'); - expect(bidRequest.bids).to.have.lengthOf(1); - const bid = bidRequest['bids'][0]; - expect(bid).to.be.a('object'); - expect(bid).to.not.have.property('context'); - }; - bidRequestedSpy = sinon.spy(bidRequestedHandler); - - $$PREBID_GLOBAL$$.onEvent('beforeRequestBids', beforeRequestBidsSpy); - $$PREBID_GLOBAL$$.onEvent('bidRequested', bidRequestedSpy); - $$PREBID_GLOBAL$$.requestBids({ - adUnits: [{ - code: '/19968336/header-bid-tag-0', - mediaTypes: { - banner: { - sizes: [[750, 350]] - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13122370 - } - }] - }], - bidsBackHandler: bidsBackSpy - }); - - sinon.assert.calledOnce(beforeRequestBidsSpy); - sinon.assert.calledOnce(bidRequestedSpy); - }); - }); - }); - - describe('offEvent', function () { - it('should return when id provided is not valid for event', function () { - var spyEventsOff = sinon.spy(events, 'off'); - $$PREBID_GLOBAL$$.offEvent('bidWon', Function, 'testId'); - assert.ok(spyEventsOff.notCalled); - events.off.restore(); - }); - - it('should call events.off with valid parameters', function () { - var spyEventsOff = sinon.spy(events, 'off'); - $$PREBID_GLOBAL$$.offEvent('bidWon', Function); - assert.ok(spyEventsOff.calledWith('bidWon', Function)); - events.off.restore(); - }); - }); - - describe('emit', function () { - it('should be able to emit event without arguments', function () { - var spyEventsEmit = sinon.spy(events, 'emit'); - events.emit(CONSTANTS.EVENTS.REQUEST_BIDS); - assert.ok(spyEventsEmit.calledWith('requestBids')); - events.emit.restore(); - }); - }); - - describe('registerBidAdapter', function () { - it('should register bidAdaptor with adapterManager', function () { - var registerBidAdapterSpy = sinon.spy(adapterManager, 'registerBidAdapter'); - $$PREBID_GLOBAL$$.registerBidAdapter(Function, 'biddercode'); - assert.ok(registerBidAdapterSpy.called, 'called adapterManager.registerBidAdapter'); - adapterManager.registerBidAdapter.restore(); - }); - - it('should catch thrown errors', function () { - var spyLogError = sinon.spy(utils, 'logError'); - var errorObject = { message: 'bidderAdaptor error' }; - var bidderAdaptor = sinon.stub().throws(errorObject); - - $$PREBID_GLOBAL$$.registerBidAdapter(bidderAdaptor, 'biddercode'); - - var errorMessage = 'Error registering bidder adapter : ' + errorObject.message; - assert.ok(spyLogError.calledWith(errorMessage), 'expected error was caught'); - utils.logError.restore(); - }); - }); - - describe('createBid', function () { - it('should return a bid object', function () { - const statusCode = 1; - const bid = $$PREBID_GLOBAL$$.createBid(statusCode); - assert.isObject(bid, 'bid is an object'); - assert.equal(bid.getStatusCode(), statusCode, 'bid has correct status'); - - const defaultStatusBid = $$PREBID_GLOBAL$$.createBid(); - assert.isObject(defaultStatusBid, 'bid is an object'); - assert.equal(defaultStatusBid.getStatusCode(), 0, 'bid has correct status'); - }); - }); - - describe('aliasBidder', function () { - it('should call adapterManager.aliasBidder', function () { - const aliasBidAdapterSpy = sinon.spy(adapterManager, 'aliasBidAdapter'); - const bidderCode = 'testcode'; - const alias = 'testalias'; - - $$PREBID_GLOBAL$$.aliasBidder(bidderCode, alias); - assert.ok(aliasBidAdapterSpy.calledWith(bidderCode, alias), 'called adapterManager.aliasBidAdapterSpy'); - adapterManager.aliasBidAdapter(); - }); - - it('should log error when not passed correct arguments', function () { - const logErrorSpy = sinon.spy(utils, 'logError'); - const error = 'bidderCode and alias must be passed as arguments'; - - $$PREBID_GLOBAL$$.aliasBidder(); - assert.ok(logErrorSpy.calledWith(error), 'expected error was logged'); - utils.logError.restore(); - }); - }); - - describe('setPriceGranularity', function () { - it('should log error when not passed granularity', function () { - const logErrorSpy = sinon.spy(utils, 'logError'); - const error = 'Prebid Error: no value passed to `setPriceGranularity()`'; - - $$PREBID_GLOBAL$$.setConfig({ priceGranularity: null }); - assert.ok(logErrorSpy.calledWith(error), 'expected error was logged'); - utils.logError.restore(); - }); - - it('should log error when not passed a valid config object', function () { - const logErrorSpy = sinon.spy(utils, 'logError'); - const error = 'Invalid custom price value passed to `setPriceGranularity()`'; - const badConfig = { - 'buckets': [{ - 'max': 3, - 'increment': 0.01, - }, - { - 'max': 18, - // missing increment prop - 'cap': true - } - ] - }; - - $$PREBID_GLOBAL$$.setConfig({ priceGranularity: badConfig }); - assert.ok(logErrorSpy.calledWith(error), 'expected error was logged'); - utils.logError.restore(); - }); - - it('should set customPriceBucket with custom config buckets', function () { - let customPriceBucket = configObj.getConfig('customPriceBucket'); - const goodConfig = { - 'buckets': [{ - 'max': 3, - 'increment': 0.01, - 'cap': true - } - ] - }; - configObj.setConfig({ priceGranularity: goodConfig }); - let priceGranularity = configObj.getConfig('priceGranularity'); - let newCustomPriceBucket = configObj.getConfig('customPriceBucket'); - expect(goodConfig).to.deep.equal(newCustomPriceBucket); - expect(priceGranularity).to.equal(CONSTANTS.GRANULARITY_OPTIONS.CUSTOM); - }); - }); - - describe('emit event', function () { - let auctionManagerStub; - beforeEach(function () { - auctionManagerStub = sinon.stub(auctionManager, 'createAuction').callsFake(function() { - return auction; - }); - }); - - afterEach(function () { - auctionManager.createAuction.restore(); - }); - }); - - describe('removeAdUnit', function () { - it('should remove given adUnit in adUnits array', function () { - const adUnit1 = { - code: 'adUnit1', - bids: [{ - bidder: 'appnexus', - params: { placementId: '123' } - }] - }; - const adUnit2 = { - code: 'adUnit2', - bids: [{ - bidder: 'rubicon', - params: { - accountId: '1234', - siteId: '1234', - zoneId: '1234' - } - }] - }; - const adUnits = [adUnit1, adUnit2]; - $$PREBID_GLOBAL$$.adUnits = adUnits; - $$PREBID_GLOBAL$$.removeAdUnit('foobar'); - assert.deepEqual($$PREBID_GLOBAL$$.adUnits, adUnits); - $$PREBID_GLOBAL$$.removeAdUnit('adUnit1'); - assert.deepEqual($$PREBID_GLOBAL$$.adUnits, [adUnit2]); - }); - it('should remove all adUnits in adUnits array if no adUnits are given', function () { - const adUnit1 = { - code: 'adUnit1', - bids: [{ - bidder: 'appnexus', - params: { placementId: '123' } - }] - }; - const adUnit2 = { - code: 'adUnit2', - bids: [{ - bidder: 'rubicon', - params: { - accountId: '1234', - siteId: '1234', - zoneId: '1234' - } - }] - }; - const adUnits = [adUnit1, adUnit2]; - $$PREBID_GLOBAL$$.adUnits = adUnits; - $$PREBID_GLOBAL$$.removeAdUnit(); - assert.deepEqual($$PREBID_GLOBAL$$.adUnits, []); - }); - it('should remove adUnits which match addUnitCodes in adUnit array argument', function () { - const adUnit1 = { - code: 'adUnit1', - bids: [{ - bidder: 'appnexus', - params: { placementId: '123' } - }] - }; - const adUnit2 = { - code: 'adUnit2', - bids: [{ - bidder: 'rubicon', - params: { - accountId: '1234', - siteId: '1234', - zoneId: '1234' - } - }] - }; - const adUnit3 = { - code: 'adUnit3', - bids: [{ - bidder: 'rubicon3', - params: { - accountId: '12345', - siteId: '12345', - zoneId: '12345' - } - }] - }; - const adUnits = [adUnit1, adUnit2, adUnit3]; - $$PREBID_GLOBAL$$.adUnits = adUnits; - $$PREBID_GLOBAL$$.removeAdUnit([adUnit1.code, adUnit2.code]); - assert.deepEqual($$PREBID_GLOBAL$$.adUnits, [adUnit3]); - }); - }); - - describe('getDealTargeting', function () { - beforeEach(function () { - resetAuction(); - }); - - afterEach(function () { - resetAuction(); - }); - - it('should truncate deal keys', function () { - $$PREBID_GLOBAL$$._bidsReceived = [ - { - 'bidderCode': 'appnexusDummyName', - 'dealId': '1234', - 'width': 300, - 'height': 250, - 'statusMessage': 'Bid available', - 'adId': '233bcbee889d46d', - 'creative_id': 29681110, - 'cpm': 10, - 'adUrl': 'http://lax1-ib.adnxs.com/ab?e=wqT_3QL8BKh8AgAAAwDWAAUBCMjAybkFEMLLiJWTu9PsVxjL84KE1tzG-kkgASotCQAAAQII4D8RAQcQAADgPxkJCQjwPyEJCQjgPykRCaAwuvekAji-B0C-B0gCUNbLkw5YweAnYABokUB4190DgAEBigEDVVNEkgUG8FKYAawCoAH6AagBAbABALgBAcABA8gBANABANgBAOABAPABAIoCOnVmKCdhJywgNDk0NDcyLCAxNDYyOTE5MjQwKTt1ZigncicsIDI5NjgxMTEwLDIeAPBskgLZASFmU21rZ0FpNjBJY0VFTmJMa3c0WUFDREI0Q2N3QURnQVFBUkl2Z2RRdXZla0FsZ0FZSk1IYUFCd0EzZ0RnQUVEaUFFRGtBRUJtQUVCb0FFQnFBRURzQUVBdVFFQUFBQUFBQURnUDhFQgkMTEFBNERfSkFRMkxMcEVUMU93XzJRFSggd1AtQUJBUFVCBSxASmdDaW9EVTJnV2dBZ0MxQWcBFgRDOQkIqERBQWdQSUFnUFFBZ1BZQWdQZ0FnRG9BZ0Q0QWdDQUF3RS6aAiUhV1FrbmI63AAcd2VBbklBUW8JXPCVVS7YAugH4ALH0wHqAh9odHRwOi8vcHJlYmlkLm9yZzo5OTk5L2dwdC5odG1sgAMAiAMBkAMAmAMFoAMBqgMAsAMAuAMAwAOsAsgDANgDAOADAOgDAPgDA4AEAJIEBC9qcHSYBACiBAoxMC4xLjEzLjM3qAQAsgQICAAQABgAIAC4BADABADIBADSBAoxMC4wLjg1Ljkx&s=1bf15e8cdc7c0c8c119614c6386ab1496560da39&referrer=http%3A%2F%2Fprebid.org%3A9999%2Fgpt.html', - 'responseTimestamp': 1462919239340, - 'requestTimestamp': 1462919238919, - 'bidder': 'appnexus', - 'adUnitCode': '/19968336/header-bid-tag-0', - 'timeToRespond': 421, - 'pbLg': '5.00', - 'pbMg': '10.00', - 'pbHg': '10.00', - 'pbAg': '10.00', - 'size': '300x250', - 'alwaysUseBid': true, - 'auctionId': 123456, - 'adserverTargeting': { - 'foobar': '300x250', - [CONSTANTS.TARGETING_KEYS.BIDDER]: 'appnexus', - [CONSTANTS.TARGETING_KEYS.AD_ID]: '233bcbee889d46d', - [CONSTANTS.TARGETING_KEYS.PRICE_BUCKET]: '10.00', - [CONSTANTS.TARGETING_KEYS.SIZE]: '300x250', - [CONSTANTS.TARGETING_KEYS.DEAL + '_appnexusDummyName']: '1234' - } - } - ]; - - var result = $$PREBID_GLOBAL$$.getAdserverTargeting(); - Object.keys(result['/19968336/header-bid-tag-0']).forEach(value => { - expect(value).to.have.length.of.at.most(20); - }); - }); - }); - - describe('getHighestUnusedBidResponseForAdUnitCode', () => { - afterEach(() => { - resetAuction(); - }) - - it('returns an empty object if there is no bid for the given adUnitCode', () => { - const highestBid = $$PREBID_GLOBAL$$.getHighestUnusedBidResponseForAdUnitCode('stallone'); - expect(highestBid).to.deep.equal({}); - }) - - it('returns undefined if adUnitCode is provided', () => { - const highestBid = $$PREBID_GLOBAL$$.getHighestUnusedBidResponseForAdUnitCode(); - expect(highestBid).to.be.undefined; - }) - - it('should ignore bids that have already been used (\'rendered\')', () => { - const _bidsReceived = getBidResponses().slice(0, 3); - _bidsReceived[0].cpm = 11 - _bidsReceived[1].cpm = 13 - _bidsReceived[2].cpm = 12 - - _bidsReceived.forEach((bid) => { - bid.adUnitCode = '/19968336/header-bid-tag-0'; - }); - - auction.getBidsReceived = function() { return _bidsReceived }; - const highestBid1 = $$PREBID_GLOBAL$$.getHighestUnusedBidResponseForAdUnitCode('/19968336/header-bid-tag-0'); - expect(highestBid1).to.deep.equal(_bidsReceived[1]) - _bidsReceived[1].status = CONSTANTS.BID_STATUS.RENDERED - const highestBid2 = $$PREBID_GLOBAL$$.getHighestUnusedBidResponseForAdUnitCode('/19968336/header-bid-tag-0'); - expect(highestBid2).to.deep.equal(_bidsReceived[2]) - }) - - it('should ignore expired bids', () => { - const _bidsReceived = getBidResponses().slice(0, 3); - _bidsReceived[0].cpm = 11 - _bidsReceived[1].cpm = 13 - _bidsReceived[2].cpm = 12 - - _bidsReceived.forEach((bid) => { - bid.adUnitCode = '/19968336/header-bid-tag-0'; - }); - - auction.getBidsReceived = function() { return _bidsReceived }; - - bidExpiryStub.restore(); - bidExpiryStub = sinon.stub(filters, 'isBidNotExpired').callsFake((bid) => bid.cpm !== 13); - const highestBid = $$PREBID_GLOBAL$$.getHighestUnusedBidResponseForAdUnitCode('/19968336/header-bid-tag-0'); - expect(highestBid).to.deep.equal(_bidsReceived[2]) - }) - }) - - describe('getHighestCpm', () => { - after(() => { - resetAuction(); - }); - it('returns an array containing the highest bid object for the given adUnitCode', function () { - const highestCpmBids = $$PREBID_GLOBAL$$.getHighestCpmBids('/19968336/header-bid-tag-0'); - expect(highestCpmBids.length).to.equal(1); - expect(highestCpmBids[0]).to.deep.equal(auctionManager.getBidsReceived()[1]); - }); - - it('returns an empty array when the given adUnit is not found', function () { - const highestCpmBids = $$PREBID_GLOBAL$$.getHighestCpmBids('/stallone'); - expect(highestCpmBids.length).to.equal(0); - }); - - it('returns an empty array when the given adUnit has no bids', function () { - let _bidsReceived = getBidResponses()[0]; - _bidsReceived.cpm = 0; - auction.getBidsReceived = function() { return _bidsReceived }; - - const highestCpmBids = $$PREBID_GLOBAL$$.getHighestCpmBids('/19968336/header-bid-tag-0'); - expect(highestCpmBids.length).to.equal(0); - }); - - it('should not return rendered bid', function() { - let _bidsReceived = getBidResponses().slice(0, 3); - _bidsReceived[0].cpm = 12; - _bidsReceived[0].status = 'rendered'; - _bidsReceived[1].cpm = 9; - _bidsReceived[2].cpm = 11; - - _bidsReceived.forEach((bid) => { - bid.adUnitCode = '/19968336/header-bid-tag-0'; - }); - - auction.getBidsReceived = function() { return _bidsReceived }; - - const highestCpmBids = $$PREBID_GLOBAL$$.getHighestCpmBids('/19968336/header-bid-tag-0'); - expect(highestCpmBids[0]).to.deep.equal(auctionManager.getBidsReceived()[2]); - }); - }); - - describe('markWinningBidAsUsed', function () { - it('marks the bid object as used for the given adUnitCode/adId combination', function () { - // make sure the auction has "state" and does not reload the fixtures - const adUnitCode = '/19968336/header-bid-tag-0'; - const bidsReceived = $$PREBID_GLOBAL$$.getBidResponsesForAdUnitCode(adUnitCode); - auction.getBidsReceived = function() { return bidsReceived.bids }; - - // mark the bid and verify the state has changed to RENDERED - const winningBid = targeting.getWinningBids(adUnitCode)[0]; - $$PREBID_GLOBAL$$.markWinningBidAsUsed({ adUnitCode, adId: winningBid.adId }); - const markedBid = find($$PREBID_GLOBAL$$.getBidResponsesForAdUnitCode(adUnitCode).bids, - bid => bid.adId === winningBid.adId); - - expect(markedBid.status).to.equal(CONSTANTS.BID_STATUS.RENDERED); - resetAuction(); - }); - - it('try and mark the bid object, but fail because we supplied the wrong adId', function () { - const adUnitCode = '/19968336/header-bid-tag-0'; - const bidsReceived = $$PREBID_GLOBAL$$.getBidResponsesForAdUnitCode(adUnitCode); - auction.getBidsReceived = function() { return bidsReceived.bids }; - - const winningBid = targeting.getWinningBids(adUnitCode)[0]; - $$PREBID_GLOBAL$$.markWinningBidAsUsed({ adUnitCode, adId: 'miss' }); - const markedBid = find($$PREBID_GLOBAL$$.getBidResponsesForAdUnitCode(adUnitCode).bids, - bid => bid.adId === winningBid.adId); - - expect(markedBid.status).to.not.equal(CONSTANTS.BID_STATUS.RENDERED); - resetAuction(); - }); - - it('marks the winning bid object as used for the given adUnitCode', function () { - // make sure the auction has "state" and does not reload the fixtures - const adUnitCode = '/19968336/header-bid-tag-0'; - const bidsReceived = $$PREBID_GLOBAL$$.getBidResponsesForAdUnitCode(adUnitCode); - auction.getBidsReceived = function() { return bidsReceived.bids }; - - // mark the bid and verify the state has changed to RENDERED - const winningBid = targeting.getWinningBids(adUnitCode)[0]; - $$PREBID_GLOBAL$$.markWinningBidAsUsed({ adUnitCode }); - const markedBid = find($$PREBID_GLOBAL$$.getBidResponsesForAdUnitCode(adUnitCode).bids, - bid => bid.adId === winningBid.adId); - - expect(markedBid.status).to.equal(CONSTANTS.BID_STATUS.RENDERED); - resetAuction(); - }); - - it('marks a bid object as used for the given adId', function () { - // make sure the auction has "state" and does not reload the fixtures - const adUnitCode = '/19968336/header-bid-tag-0'; - const bidsReceived = $$PREBID_GLOBAL$$.getBidResponsesForAdUnitCode(adUnitCode); - auction.getBidsReceived = function() { return bidsReceived.bids }; - - // mark the bid and verify the state has changed to RENDERED - const winningBid = targeting.getWinningBids(adUnitCode)[0]; - $$PREBID_GLOBAL$$.markWinningBidAsUsed({ adId: winningBid.adId }); - const markedBid = find($$PREBID_GLOBAL$$.getBidResponsesForAdUnitCode(adUnitCode).bids, - bid => bid.adId === winningBid.adId); - - expect(markedBid.status).to.equal(CONSTANTS.BID_STATUS.RENDERED); - resetAuction(); - }); - }); - - describe('setTargetingForAst', function () { - let targeting; - let auctionManagerInstance; - - beforeEach(function () { - resetAuction(); - auctionManagerInstance = newAuctionManager(); - sinon.stub(auctionManagerInstance, 'getBidsReceived').callsFake(function() { - let bidResponse = getBidResponses()[1]; - // add a pt0 value for special case. - bidResponse.adserverTargeting.pt0 = 'someVal'; - return [bidResponse]; - }); - sinon.stub(auctionManagerInstance, 'getAdUnitCodes').callsFake(function() { - return ['/19968336/header-bid-tag-0']; - }); - targeting = newTargeting(auctionManagerInstance); - }); - - afterEach(function () { - auctionManagerInstance.getBidsReceived.restore(); - auctionManagerInstance.getAdUnitCodes.restore(); - resetAuction(); - }); - - it('should set targeting for appnexus apntag object', function () { - const bids = auctionManagerInstance.getBidsReceived(); - const adUnitCode = '/19968336/header-bid-tag-0'; - - var expectedAdserverTargeting = bids[0].adserverTargeting; - var newAdserverTargeting = {}; - let regex = /pt[0-9]/; - - for (var key in expectedAdserverTargeting) { - if (key.search(regex) < 0) { - newAdserverTargeting[key.toUpperCase()] = expectedAdserverTargeting[key]; - } else { - newAdserverTargeting[key] = expectedAdserverTargeting[key]; - } - } - targeting.setTargetingForAst(); - expect(newAdserverTargeting).to.deep.equal(window.apntag.tags[adUnitCode].keywords); - }); - - it('should reset targeting for appnexus apntag object', function () { - const bids = auctionManagerInstance.getBidsReceived(); - const adUnitCode = '/19968336/header-bid-tag-0'; - - var expectedAdserverTargeting = bids[0].adserverTargeting; - var newAdserverTargeting = {}; - let regex = /pt[0-9]/; - - for (var key in expectedAdserverTargeting) { - if (key.search(regex) < 0) { - newAdserverTargeting[key.toUpperCase()] = expectedAdserverTargeting[key]; - } else { - newAdserverTargeting[key] = expectedAdserverTargeting[key]; - } - } - targeting.setTargetingForAst(); - expect(newAdserverTargeting).to.deep.equal(window.apntag.tags[adUnitCode].keywords); - targeting.resetPresetTargetingAST(); - expect(window.apntag.tags[adUnitCode].keywords).to.deep.equal({}); - }); - - it('should not find ' + CONSTANTS.TARGETING_KEYS.AD_ID + ' key in lowercase for all bidders', function() { - const adUnitCode = '/19968336/header-bid-tag-0'; - $$PREBID_GLOBAL$$.setConfig({ enableSendAllBids: true }); - targeting.setTargetingForAst(); - const keywords = Object.keys(window.apntag.tags[adUnitCode].keywords).filter(keyword => (keyword.substring(0, CONSTANTS.TARGETING_KEYS.AD_ID.length) === CONSTANTS.TARGETING_KEYS.AD_ID)); - expect(keywords.length).to.equal(0); - }); - }); - - describe('The monkey-patched queue.push function', function() { - beforeEach(function initializeSpies() { - sinon.spy(utils, 'logError'); - }); - - afterEach(function resetSpies() { - utils.logError.restore(); - }); - - it('should run commands which are pushed into it', function() { - let cmd = sinon.spy(); - $$PREBID_GLOBAL$$.cmd.push(cmd); - assert.isTrue(cmd.called); - }); - - it('should log an error when given non-functions', function() { - $$PREBID_GLOBAL$$.cmd.push(5); - assert.isTrue(utils.logError.calledOnce); - }); - - it('should log an error if the command passed into it fails', function() { - $$PREBID_GLOBAL$$.cmd.push(function() { - throw new Error('Failed function.'); - }); - assert.isTrue(utils.logError.calledOnce); - }); - }); - - describe('The monkey-patched que.push function', function() { - it('should be the same as the cmd.push function', function() { - assert.equal($$PREBID_GLOBAL$$.que.push, $$PREBID_GLOBAL$$.cmd.push); - }); - }); - - describe('getAllPrebidWinningBids', function () { - let auctionManagerStub; - beforeEach(function () { - auctionManagerStub = sinon.stub(auctionManager, 'getBidsReceived'); - }); - - afterEach(function () { - auctionManagerStub.restore(); - }); - - it('should return prebid auction winning bids', function () { - let bidsReceived = [ - createBidReceived({bidder: 'appnexus', cpm: 7, auctionId: 1, responseTimestamp: 100, adUnitCode: 'code-0', adId: 'adid-1', status: 'targetingSet', requestId: 'reqid-1'}), - createBidReceived({bidder: 'rubicon', cpm: 6, auctionId: 1, responseTimestamp: 101, adUnitCode: 'code-1', adId: 'adid-2', requestId: 'reqid-2'}), - createBidReceived({bidder: 'appnexus', cpm: 6, auctionId: 2, responseTimestamp: 102, adUnitCode: 'code-0', adId: 'adid-3', requestId: 'reqid-3'}), - createBidReceived({bidder: 'rubicon', cpm: 6, auctionId: 2, responseTimestamp: 103, adUnitCode: 'code-1', adId: 'adid-4', requestId: 'reqid-4'}), - ]; - auctionManagerStub.returns(bidsReceived) - let bids = $$PREBID_GLOBAL$$.getAllPrebidWinningBids(); - - expect(bids.length).to.equal(1); - expect(bids[0].adId).to.equal('adid-1'); - }); - }); -}); diff --git a/test/spec/unit/secureCreatives_spec.js b/test/spec/unit/secureCreatives_spec.js deleted file mode 100644 index 566154f0003..00000000000 --- a/test/spec/unit/secureCreatives_spec.js +++ /dev/null @@ -1,45 +0,0 @@ -import { - _sendAdToCreative -} from '../../../src/secureCreatives.js'; -import { expect } from 'chai'; -import * as utils from 'src/utils.js'; - -describe('secureCreatives', () => { - describe('_sendAdToCreative', () => { - beforeEach(function () { - sinon.stub(utils, 'logError'); - sinon.stub(utils, 'logWarn'); - }); - - afterEach(function () { - utils.logError.restore(); - utils.logWarn.restore(); - }); - it('should macro replace ${AUCTION_PRICE} with the winning bid for ad and adUrl', () => { - const oldVal = window.googletag; - const oldapntag = window.apntag; - window.apntag = null - window.googletag = null; - const mockAdObject = { - adId: 'someAdId', - ad: '', - adUrl: 'http://creative.prebid.org/${AUCTION_PRICE}', - width: 300, - height: 250, - renderer: null, - cpm: '1.00', - adUnitCode: 'some_dom_id' - }; - const event = { - source: { postMessage: sinon.stub() }, - origin: 'origin.sf.com' - }; - - _sendAdToCreative(mockAdObject, event); - expect(JSON.parse(event.source.postMessage.args[0][0]).ad).to.equal(''); - expect(JSON.parse(event.source.postMessage.args[0][0]).adUrl).to.equal('http://creative.prebid.org/1.00'); - window.googletag = oldVal; - window.apntag = oldapntag; - }); - }); -}); diff --git a/test/spec/userSync_spec.js b/test/spec/userSync_spec.js deleted file mode 100644 index 55b613ce929..00000000000 --- a/test/spec/userSync_spec.js +++ /dev/null @@ -1,589 +0,0 @@ -import { expect } from 'chai'; -import { config } from 'src/config.js'; -// Use require since we need to be able to write to these vars -const utils = require('../../src/utils'); -let { newUserSync, USERSYNC_DEFAULT_CONFIG } = require('../../src/userSync'); - -describe('user sync', function () { - let triggerPixelStub; - let logWarnStub; - let timeoutStub; - let shuffleStub; - let getUniqueIdentifierStrStub; - let insertUserSyncIframeStub; - let idPrefix = 'test-generated-id-'; - let lastId = 0; - let defaultUserSyncConfig = config.getConfig('userSync'); - function getUserSyncConfig(userSyncConfig) { - return Object.assign({}, defaultUserSyncConfig, userSyncConfig); - } - function newTestUserSync(configOverrides, disableBrowserCookies) { - const thisConfig = Object.assign({}, defaultUserSyncConfig, configOverrides); - return newUserSync({ - config: thisConfig, - browserSupportsCookies: !disableBrowserCookies, - }) - } - let clock; - before(function () { - clock = sinon.useFakeTimers(); - }); - - after(function () { - clock.restore(); - }); - - beforeEach(function () { - config.setConfig({ userSync: USERSYNC_DEFAULT_CONFIG }); - triggerPixelStub = sinon.stub(utils, 'triggerPixel'); - logWarnStub = sinon.stub(utils, 'logWarn'); - shuffleStub = sinon.stub(utils, 'shuffle').callsFake((array) => array.reverse()); - getUniqueIdentifierStrStub = sinon.stub(utils, 'getUniqueIdentifierStr').callsFake(() => idPrefix + (lastId += 1)); - insertUserSyncIframeStub = sinon.stub(utils, 'insertUserSyncIframe'); - }); - - afterEach(function () { - triggerPixelStub.restore(); - logWarnStub.restore(); - shuffleStub.restore(); - getUniqueIdentifierStrStub.restore(); - insertUserSyncIframeStub.restore(); - config.resetConfig(); - }); - - it('should register and fire a pixel URL', function () { - const userSync = newTestUserSync(); - userSync.registerSync('image', 'testBidder', 'http://example.com'); - userSync.syncUsers(); - expect(triggerPixelStub.getCall(0)).to.not.be.null; - expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.equal('http://example.com'); - }); - - it('should clear queue after sync', function () { - const userSync = newTestUserSync(); - userSync.syncUsers(); - expect(triggerPixelStub.callCount).to.equal(0); - }); - - it('should delay firing a pixel by the expected amount', function () { - const userSync = newTestUserSync(); - userSync.registerSync('image', 'testBidder', 'http://example.com'); - // This implicitly tests cookie and browser support - userSync.syncUsers(999); - clock.tick(1000); - expect(triggerPixelStub.getCall(0)).to.not.be.null; - }); - - it('should register and fires multiple pixel URLs', function () { - const userSync = newTestUserSync(); - userSync.registerSync('image', 'testBidder', 'http://example.com/1'); - userSync.registerSync('image', 'testBidder', 'http://example.com/2'); - userSync.syncUsers(); - expect(triggerPixelStub.getCall(0)).to.not.be.null; - expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.include('http://example.com/'); - expect(triggerPixelStub.getCall(1)).to.not.be.null; - expect(triggerPixelStub.getCall(1).args[0]).to.exist.and.to.include('http://example.com/'); - expect(triggerPixelStub.getCall(2)).to.be.null; - }); - - it('should not register pixel URL since it is not supported', function () { - const userSync = newTestUserSync({filterSettings: { - image: { - bidders: '*', - filter: 'exclude' - } - }}); - userSync.registerSync('image', 'testBidder', 'http://example.com'); - userSync.syncUsers(); - expect(triggerPixelStub.getCall(0)).to.be.null; - }); - - it('should register and load an iframe', function () { - const userSync = newTestUserSync({filterSettings: { - iframe: { - bidders: '*', - filter: 'include' - } - }}); - userSync.registerSync('iframe', 'testBidder', 'http://example.com/iframe'); - userSync.syncUsers(); - expect(insertUserSyncIframeStub.getCall(0).args[0]).to.equal('http://example.com/iframe'); - }); - - it('should only trigger syncs once per page per bidder', function () { - const userSync = newTestUserSync({ pixelEnabled: true }); - userSync.registerSync('image', 'testBidder', 'http://example.com/1'); - userSync.syncUsers(); - userSync.registerSync('image', 'testBidder', 'http://example.com/2'); - userSync.registerSync('image', 'testBidder2', 'http://example.com/3'); - userSync.syncUsers(); - expect(triggerPixelStub.callCount).to.equal(2); - expect(triggerPixelStub.getCall(0)).to.not.be.null; - expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.equal('http://example.com/1'); - expect(triggerPixelStub.getCall(1)).to.not.be.null; - expect(triggerPixelStub.getCall(1).args[0]).to.exist.and.to.equal('http://example.com/3'); - }); - - it('should not fire syncs if cookies are not supported', function () { - const userSync = newTestUserSync({ pixelEnabled: true }, true); - userSync.registerSync('image', 'testBidder', 'http://example.com'); - userSync.syncUsers(); - expect(triggerPixelStub.getCall(0)).to.be.null; - }); - - it('should prevent registering invalid type', function () { - const userSync = newTestUserSync(); - userSync.registerSync('invalid', 'testBidder', 'http://example.com'); - expect(logWarnStub.getCall(0).args[0]).to.exist; - }); - - it('should expose the syncUsers method for the publisher to manually trigger syncs', function () { - // triggerUserSyncs should do nothing by default - let userSync = newTestUserSync(); - let syncUsersSpy = sinon.spy(userSync, 'syncUsers'); - userSync.triggerUserSyncs(); - expect(syncUsersSpy.notCalled).to.be.true; - // triggerUserSyncs should trigger syncUsers if enableOverride is on - userSync = newTestUserSync({ enableOverride: true }); - syncUsersSpy = sinon.spy(userSync, 'syncUsers'); - userSync.triggerUserSyncs(); - expect(syncUsersSpy.called).to.be.true; - }); - - it('should limit the number of syncs per bidder', function () { - const userSync = newTestUserSync({ syncsPerBidder: 2 }); - userSync.registerSync('image', 'testBidder', 'http://example.com/1'); - userSync.registerSync('image', 'testBidder', 'http://example.com/2'); - userSync.registerSync('image', 'testBidder', 'http://example.com/3'); - userSync.syncUsers(); - expect(triggerPixelStub.getCall(0)).to.not.be.null; - expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.match(/^http:\/\/example\.com\/[1|2]/); - expect(triggerPixelStub.getCall(1)).to.not.be.null; - expect(triggerPixelStub.getCall(1).args[0]).to.exist.and.to.match(/^http:\/\/example\.com\/[1|2]/); - expect(triggerPixelStub.getCall(2)).to.be.null; - }); - - it('should not limit the number of syncs per bidder when set to 0', function () { - const userSync = newTestUserSync({ syncsPerBidder: 0 }); - userSync.registerSync('image', 'testBidder', 'http://example.com/1'); - userSync.registerSync('image', 'testBidder', 'http://example.com/2'); - userSync.registerSync('image', 'testBidder', 'http://example.com/3'); - userSync.syncUsers(); - expect(triggerPixelStub.getCall(0)).to.not.be.null; - expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.match(/^http:\/\/example\.com\/[1|2|3]/); - expect(triggerPixelStub.getCall(1)).to.not.be.null; - expect(triggerPixelStub.getCall(1).args[0]).to.exist.and.to.match(/^http:\/\/example\.com\/[1|2|3]/); - expect(triggerPixelStub.getCall(2)).to.not.be.null; - expect(triggerPixelStub.getCall(2).args[0]).to.exist.and.to.match(/^http:\/\/example\.com\/[1|2|3]/); - }); - - it('should balance out bidder requests', function () { - const userSync = newTestUserSync(); - userSync.registerSync('image', 'atestBidder', 'http://example.com/1'); - userSync.registerSync('image', 'atestBidder', 'http://example.com/3'); - userSync.registerSync('image', 'btestBidder', 'http://example.com/2'); - userSync.syncUsers(); - // The stubbed shuffle function should just reverse the order - expect(triggerPixelStub.getCall(0)).to.not.be.null; - expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.equal('http://example.com/2'); - expect(triggerPixelStub.getCall(1)).to.not.be.null; - expect(triggerPixelStub.getCall(1).args[0]).to.exist.and.to.equal('http://example.com/3'); - expect(triggerPixelStub.getCall(2)).to.not.be.null; - expect(triggerPixelStub.getCall(2).args[0]).to.exist.and.to.equal('http://example.com/1'); - expect(triggerPixelStub.getCall(3)).to.be.null; - }); - - it('should disable user sync', function () { - const userSync = newTestUserSync({ syncEnabled: false }); - userSync.registerSync('pixel', 'testBidder', 'http://example.com'); - expect(logWarnStub.getCall(0).args[0]).to.exist; - userSync.syncUsers(); - expect(triggerPixelStub.getCall(0)).to.be.null; - }); - - it('should only sync enabled bidders', function () { - const userSync = newTestUserSync({filterSettings: { - image: { - bidders: ['testBidderA'], - filter: 'include' - } - }}); - userSync.registerSync('image', 'testBidderA', 'http://example.com/1'); - userSync.registerSync('image', 'testBidderB', 'http://example.com/2'); - userSync.syncUsers(); - expect(triggerPixelStub.getCall(0)).to.not.be.null; - expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.include('http://example.com/'); - expect(triggerPixelStub.getCall(1)).to.be.null; - }); - - it('should register config set after instantiation', function () { - // start with userSync off - const userSync = newTestUserSync({ syncEnabled: false }); - // turn it on with setConfig() - config.setConfig({ userSync: { syncEnabled: true } }); - userSync.registerSync('image', 'testBidder', 'http://example.com'); - userSync.syncUsers(); - expect(triggerPixelStub.getCall(0)).to.not.be.null; - expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.equal('http://example.com'); - }); - - it('should register both image and iframe pixels with filterSettings.all config', function () { - const userSync = newTestUserSync({ - filterSettings: { - all: { - bidders: ['atestBidder', 'testBidder'], - filter: 'include' - }, - } - }); - userSync.registerSync('image', 'atestBidder', 'http://example.com/1'); - userSync.registerSync('iframe', 'testBidder', 'http://example.com/iframe'); - userSync.syncUsers(); - expect(triggerPixelStub.getCall(0)).to.not.be.null; - expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.equal('http://example.com/1'); - expect(insertUserSyncIframeStub.getCall(0)).to.not.be.null; - expect(insertUserSyncIframeStub.getCall(0).args[0]).to.equal('http://example.com/iframe'); - }); - - it('should register iframe and not register image pixels based on filterSettings config', function () { - const userSync = newTestUserSync({ - filterSettings: { - image: { - bidders: '*', - filter: 'exclude' - }, - iframe: { - bidders: ['testBidder'] - } - } - }); - userSync.registerSync('image', 'atestBidder', 'http://example.com/1'); - userSync.registerSync('iframe', 'testBidder', 'http://example.com/iframe'); - userSync.syncUsers(); - expect(triggerPixelStub.getCall(0)).to.be.null; - expect(insertUserSyncIframeStub.getCall(0)).to.not.be.null; - expect(insertUserSyncIframeStub.getCall(0).args[0]).to.equal('http://example.com/iframe'); - }); - - it('should throw a warning and default to basic resgistration rules when filterSettings config is invalid', function () { - // invalid config - passed invalid filter option - const userSync1 = newTestUserSync({ - filterSettings: { - iframe: { - bidders: ['testBidder'], - filter: 'includes' - } - } - }); - userSync1.registerSync('image', 'atestBidder', 'http://example.com/1'); - userSync1.registerSync('iframe', 'testBidder', 'http://example.com/iframe'); - userSync1.syncUsers(); - expect(logWarnStub.getCall(0).args[0]).to.exist; - expect(triggerPixelStub.getCall(0)).to.not.be.null; - expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.equal('http://example.com/1'); - expect(insertUserSyncIframeStub.getCall(0)).to.be.null; - - // invalid config - bidders is not an array of strings - const userSync2 = newTestUserSync({ - filterSettings: { - iframe: { - bidders: ['testBidder', 0], - filter: 'include' - } - } - }); - userSync2.registerSync('image', 'atestBidder', 'http://example.com/1'); - userSync2.registerSync('iframe', 'testBidder', 'http://example.com/iframe'); - userSync2.syncUsers(); - expect(logWarnStub.getCall(1).args[0]).to.exist; - expect(triggerPixelStub.getCall(1)).to.not.be.null; - expect(triggerPixelStub.getCall(1).args[0]).to.exist.and.to.equal('http://example.com/1'); - expect(insertUserSyncIframeStub.getCall(0)).to.be.null; - - // invalid config - bidders list includes wildcard - const userSync3 = newTestUserSync({ - filterSettings: { - iframe: { - bidders: ['testBidder', '*'], - filter: 'include' - } - } - }); - userSync3.registerSync('image', 'atestBidder', 'http://example.com/1'); - userSync3.registerSync('iframe', 'testBidder', 'http://example.com/iframe'); - userSync3.syncUsers(); - expect(logWarnStub.getCall(2).args[0]).to.exist; - expect(triggerPixelStub.getCall(2)).to.not.be.null; - expect(triggerPixelStub.getCall(2).args[0]).to.exist.and.to.equal('http://example.com/1'); - expect(insertUserSyncIframeStub.getCall(0)).to.be.null; - - // invalid config - incorrect wildcard - const userSync4 = newTestUserSync({ - filterSettings: { - iframe: { - bidders: '***', - filter: 'include' - } - } - }); - userSync4.registerSync('image', 'atestBidder', 'http://example.com/1'); - userSync4.registerSync('iframe', 'testBidder', 'http://example.com/iframe'); - userSync4.syncUsers(); - expect(logWarnStub.getCall(3).args[0]).to.exist; - expect(triggerPixelStub.getCall(3)).to.not.be.null; - expect(triggerPixelStub.getCall(3).args[0]).to.exist.and.to.equal('http://example.com/1'); - expect(insertUserSyncIframeStub.getCall(0)).to.be.null; - - // invalid config - missing bidders field - const userSync5 = newTestUserSync({ - filterSettings: { - iframe: { - filter: 'include' - } - } - }); - userSync5.registerSync('image', 'atestBidder', 'http://example.com/1'); - userSync5.registerSync('iframe', 'testBidder', 'http://example.com/iframe'); - userSync5.syncUsers(); - expect(logWarnStub.getCall(4).args[0]).to.exist; - expect(triggerPixelStub.getCall(4)).to.not.be.null; - expect(triggerPixelStub.getCall(4).args[0]).to.exist.and.to.equal('http://example.com/1'); - expect(insertUserSyncIframeStub.getCall(0)).to.be.null; - }); - - it('should overwrite logic of deprecated fields when filterSettings is defined', function () { - const userSync = newTestUserSync({ - pixelsEnabled: false, - iframeEnabled: true, - enabledBidders: ['ctestBidder'], - filterSettings: { - image: { - bidders: '*', - filter: 'include' - }, - iframe: { - bidders: ['testBidder'], - filter: 'exclude' - } - } - }); - userSync.registerSync('image', 'atestBidder', 'http://example.com/1'); - userSync.registerSync('iframe', 'testBidder', 'http://example.com/iframe'); - userSync.syncUsers(); - expect(logWarnStub.getCall(0).args[0]).to.exist; - expect(triggerPixelStub.getCall(0)).to.not.be.null; - expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.equal('http://example.com/1'); - expect(insertUserSyncIframeStub.getCall(0)).to.be.null; - }); - - it('should still allow default image syncs if setConfig only defined iframe', function () { - const userSync = newUserSync({ - config: config.getConfig('userSync'), - browserSupportsCookies: true - }); - - config.setConfig({ - userSync: { - filterSettings: { - iframe: { - bidders: ['bidderXYZ'], - filter: 'include' - } - } - } - }); - - userSync.registerSync('image', 'testBidder', 'http://example.com'); - userSync.registerSync('iframe', 'bidderXYZ', 'http://example.com/iframe'); - userSync.syncUsers(); - expect(triggerPixelStub.getCall(0)).to.not.be.null; - expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.equal('http://example.com'); - expect(insertUserSyncIframeStub.getCall(0).args[0]).to.equal('http://example.com/iframe'); - }); - - it('should override default image syncs if setConfig used image filter', function () { - const userSync = newUserSync({ - config: config.getConfig('userSync'), - browserSupportsCookies: true - }); - - config.setConfig({ - userSync: { - filterSettings: { - image: { - bidders: ['bidderXYZ'], - filter: 'exclude' - } - } - } - }); - - userSync.registerSync('image', 'testBidder', 'http://example.com'); - userSync.registerSync('image', 'bidderXYZ', 'http://example.com/image-blocked'); - userSync.syncUsers(); - expect(triggerPixelStub.getCall(0)).to.not.be.null; - expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.equal('http://example.com'); - expect(triggerPixelStub.getCall(1)).to.be.null; - }); - - it('should override default image syncs if setConfig used all filter', function() { - const userSync = newUserSync({ - config: config.getConfig('userSync'), - browserSupportsCookies: true - }); - - config.setConfig({ - userSync: { - filterSettings: { - all: { - bidders: ['bidderXYZ'], - filter: 'exclude' - } - } - } - }); - - userSync.registerSync('image', 'testBidder', 'http://example.com'); - userSync.registerSync('image', 'bidderXYZ', 'http://example.com/image-blocked'); - userSync.registerSync('iframe', 'testBidder', 'http://example.com/iframe'); - userSync.registerSync('iframe', 'bidderXYZ', 'http://example.com/iframe-blocked'); - userSync.syncUsers(); - expect(triggerPixelStub.getCall(0)).to.not.be.null; - expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.equal('http://example.com'); - expect(triggerPixelStub.getCall(1)).to.be.null; - expect(insertUserSyncIframeStub.getCall(0).args[0]).to.equal('http://example.com/iframe'); - expect(insertUserSyncIframeStub.getCall(1)).to.be.null; - }); - - describe('publicAPI', function () { - describe('canBidderRegisterSync', function () { - describe('with filterSettings', function () { - it('should return false if filter settings does not allow it', function () { - const userSync = newUserSync({ - config: { - filterSettings: { - image: { - bidders: '*', - filter: 'include' - }, - iframe: { - bidders: ['testBidder'], - filter: 'include' - } - } - } - }); - expect(userSync.canBidderRegisterSync('iframe', 'otherTestBidder')).to.equal(false); - }); - it('should return false for iframe if there is no iframe filterSettings', function () { - const userSync = newUserSync({ - config: { - syncEnabled: true, - filterSettings: { - image: { - bidders: '*', - filter: 'include' - } - }, - syncsPerBidder: 5, - syncDelay: 3000, - auctionDelay: 0 - } - }); - - expect(userSync.canBidderRegisterSync('iframe', 'otherTestBidder')).to.equal(false); - }); - it('should return true if filter settings does allow it', function () { - const userSync = newUserSync({ - config: { - filterSettings: { - image: { - bidders: '*', - filter: 'include' - }, - iframe: { - bidders: ['testBidder'], - filter: 'include' - } - } - } - }); - expect(userSync.canBidderRegisterSync('iframe', 'testBidder')).to.equal(true); - }); - }); - describe('almost deprecated - without filterSettings', function () { - describe('enabledBidders contains testBidder', function () { - it('should return false if type is iframe and iframeEnabled is false', function () { - const userSync = newUserSync({ - config: { - filterSettings: { - iframe: { - bidders: ['testBidder'], - filter: 'exclude' - } - } - } - }); - expect(userSync.canBidderRegisterSync('iframe', 'testBidder')).to.equal(false); - }); - - it('should return true if type is iframe and iframeEnabled is true', function () { - const userSync = newUserSync({ - config: { - pixelEnabled: true, - iframeEnabled: true, - enabledBidders: ['testBidder'], - } - }); - expect(userSync.canBidderRegisterSync('iframe', 'testBidder')).to.equal(true); - }); - - it('should return false if type is image and pixelEnabled is false', function () { - const userSync = newUserSync({ - config: { - filterSettings: { - image: { - bidders: ['testBidder'], - filter: 'exclude' - } - } - } - }); - expect(userSync.canBidderRegisterSync('image', 'testBidder')).to.equal(false); - }); - - it('should return true if type is image and pixelEnabled is true', function () { - const userSync = newUserSync({ - config: { - pixelEnabled: true, - iframeEnabled: true, - enabledBidders: ['testBidder'], - } - }); - expect(userSync.canBidderRegisterSync('image', 'testBidder')).to.equal(true); - }); - }); - - describe('enabledBidders does not container testBidder', function () { - it('should return false since testBidder is not in enabledBidders', function () { - const userSync = newUserSync({ - config: { - filterSettings: { - image: { - bidders: ['otherTestBidder'], - filter: 'include' - }, - iframe: { - bidders: ['otherTestBidder'], - filter: 'include' - } - } - } - }); - expect(userSync.canBidderRegisterSync('iframe', 'testBidder')).to.equal(false); - }); - }); - }); - }); - }); -}); diff --git a/test/spec/utils_spec.js b/test/spec/utils_spec.js deleted file mode 100644 index 6494ead78e7..00000000000 --- a/test/spec/utils_spec.js +++ /dev/null @@ -1,1201 +0,0 @@ -import { getAdServerTargeting } from 'test/fixtures/fixtures.js'; -import { expect } from 'chai'; -import CONSTANTS from 'src/constants.json'; -import * as utils from 'src/utils.js'; - -var assert = require('assert'); - -describe('Utils', function () { - var obj_string = 's', - obj_number = 1, - obj_object = {}, - obj_array = [], - obj_function = function () {}; - - var type_string = 'String', - type_number = 'Number', - type_object = 'Object', - type_array = 'Array', - type_function = 'Function'; - - describe('getBidIdParameter', function () { - it('should return value of the key in input object', function () { - var obj = { - a: 'valueA', - b: 'valueB' - }; - var output = utils.getBidIdParameter('a', obj); - assert.equal(output, 'valueA'); - }); - - it('should return empty string, if the key is not existsed in the object', function () { - var obj = { - a: 'valueA', - b: 'valueB' - }; - var output = utils.getBidIdParameter('c', obj); - assert.equal(output, ''); - }); - }); - - describe('tryAppendQueryString', function () { - it('should append query string to existing url', function () { - var url = 'www.a.com?'; - var key = 'b'; - var value = 'c'; - - var output = utils.tryAppendQueryString(url, key, value); - - var expectedResult = url + key + '=' + encodeURIComponent(value) + '&'; - assert.equal(output, expectedResult); - }); - - it('should return existing url, if the value is empty', function () { - var url = 'www.a.com?'; - var key = 'b'; - var value = ''; - - var output = utils.tryAppendQueryString(url, key, value); - assert.equal(output, url); - }); - }); - - describe('parseQueryStringParameters', function () { - it('should append query string to existing using the input obj', function () { - var obj = { - a: 'http://example.com/?foo=bar&bar=foo', - b: 'abc["def"]' - }; - - var output = utils.parseQueryStringParameters(obj); - var expectedResult = 'a=' + encodeURIComponent('http://example.com/?foo=bar&bar=foo') + '&b=' + encodeURIComponent('abc["def"]'); - assert.equal(output, expectedResult); - }); - - it('should return an empty string, if input obj is empty', function () { - var obj = {}; - var output = utils.parseQueryStringParameters(obj); - assert.equal(output, ''); - }); - }); - - describe('transformAdServerTargetingObj', function () { - it('should append query string to existing using the input obj', function () { - var obj = getAdServerTargeting(); - - var output = utils.transformAdServerTargetingObj(obj[Object.keys(obj)[0]]); - var expected = 'foobar=0x0%2C300x250%2C300x600&' + CONSTANTS.TARGETING_KEYS.SIZE + '=300x250&' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '=10.00&' + CONSTANTS.TARGETING_KEYS.AD_ID + '=233bcbee889d46d&' + CONSTANTS.TARGETING_KEYS.BIDDER + '=appnexus&' + CONSTANTS.TARGETING_KEYS.SIZE + '_triplelift=0x0&' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_triplelift=10.00&' + CONSTANTS.TARGETING_KEYS.AD_ID + '_triplelift=222bb26f9e8bd&' + CONSTANTS.TARGETING_KEYS.BIDDER + '_triplelift=triplelift&' + CONSTANTS.TARGETING_KEYS.SIZE + '_appnexus=300x250&' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_appnexus=10.00&' + CONSTANTS.TARGETING_KEYS.AD_ID + '_appnexus=233bcbee889d46d&' + CONSTANTS.TARGETING_KEYS.BIDDER + '_appnexus=appnexus&' + CONSTANTS.TARGETING_KEYS.SIZE + '_pagescience=300x250&' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_pagescience=10.00&' + CONSTANTS.TARGETING_KEYS.AD_ID + '_pagescience=25bedd4813632d7&' + CONSTANTS.TARGETING_KEYS.BIDDER + '_pagescienc=pagescience&' + CONSTANTS.TARGETING_KEYS.SIZE + '_brightcom=300x250&' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_brightcom=10.00&' + CONSTANTS.TARGETING_KEYS.AD_ID + '_brightcom=26e0795ab963896&' + CONSTANTS.TARGETING_KEYS.BIDDER + '_brightcom=brightcom&' + CONSTANTS.TARGETING_KEYS.SIZE + '_brealtime=300x250&' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_brealtime=10.00&' + CONSTANTS.TARGETING_KEYS.AD_ID + '_brealtime=275bd666f5a5a5d&' + CONSTANTS.TARGETING_KEYS.BIDDER + '_brealtime=brealtime&' + CONSTANTS.TARGETING_KEYS.SIZE + '_pubmatic=300x250&' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_pubmatic=10.00&' + CONSTANTS.TARGETING_KEYS.AD_ID + '_pubmatic=28f4039c636b6a7&' + CONSTANTS.TARGETING_KEYS.BIDDER + '_pubmatic=pubmatic&' + CONSTANTS.TARGETING_KEYS.SIZE + '_rubicon=300x600&' + CONSTANTS.TARGETING_KEYS.PRICE_BUCKET + '_rubicon=10.00&' + CONSTANTS.TARGETING_KEYS.AD_ID + '_rubicon=29019e2ab586a5a&' + CONSTANTS.TARGETING_KEYS.BIDDER + '_rubicon=rubicon'; - assert.equal(output, expected); - }); - - it('should return an empty string, if input obj is empty', function () { - var obj = {}; - var output = utils.transformAdServerTargetingObj(obj); - assert.equal(output, ''); - }); - }); - - describe('extend', function () { - it('should merge two input object', function () { - var target = { - a: '1', - b: '2' - }; - - var source = { - c: '3' - }; - - var expectedResult = { - a: '1', - b: '2', - c: '3' - }; - - var output = Object.assign(target, source); - assert.deepEqual(output, expectedResult); - }); - - it('should merge two input object even though target object is empty', function () { - var target = {}; - var source = { - c: '3' - }; - - var output = Object.assign(target, source); - assert.deepEqual(output, source); - }); - - it('just return target object, if the source object is empty', function () { - var target = { - a: '1', - b: '2' - }; - var source = {}; - - var output = Object.assign(target, source); - assert.deepEqual(output, target); - }); - }); - - describe('parseSizesInput', function () { - it('should return query string using multi size array', function () { - var sizes = [[728, 90], [970, 90]]; - var output = utils.parseSizesInput(sizes); - assert.deepEqual(output, ['728x90', '970x90']); - }); - - it('should return query string using single size array', function () { - var sizes = [728, 90]; - var output = utils.parseSizesInput(sizes); - assert.deepEqual(output, ['728x90']); - }); - - it('should return query string using string input', function () { - var sizes = '300x250,970x90'; - var output = utils.parseSizesInput(sizes); - assert.deepEqual(output, ['300x250', '970x90']); - }); - - it('return undefined if input array is empty', function () { - var sizes = []; - var output = utils.parseSizesInput(sizes); - assert.deepEqual(output, []); - }); - }); - - describe('parseGPTSingleSizeArray', function () { - it('should return size string with input single size array', function () { - var size = [300, 250]; - var output = utils.parseGPTSingleSizeArray(size); - assert.equal(output, '300x250'); - }); - - it('should return size string with input single size array', function () { - var size = ['300', '250']; - var output = utils.parseGPTSingleSizeArray(size); - assert.equal(output, '300x250'); - }); - - it('return undefined using string input', function () { - var size = '1'; - var output = utils.parseGPTSingleSizeArray(size); - assert.equal(output, undefined); - }); - - it('return undefined using number input', function () { - var size = 1; - var output = utils.parseGPTSingleSizeArray(size); - assert.equal(output, undefined); - }); - - it('return undefined using one length single array', function () { - var size = [300]; - var output = utils.parseGPTSingleSizeArray(size); - assert.equal(output, undefined); - }); - - it('return undefined if the input is empty', function () { - var size = ''; - var output = utils.parseGPTSingleSizeArray(size); - assert.equal(output, undefined); - }); - - it('return undefined if the input is not a number', function () { - var size = ['foo', 'bar']; - var output = utils.parseGPTSingleSizeArray(size); - assert.equal(output, undefined); - }); - - it('return undefined if the input is not a number 2', function () { - var size = ['foo', 300]; - var output = utils.parseGPTSingleSizeArray(size); - assert.equal(output, undefined); - }); - }); - - describe('parseGPTSingleSizeArrayToRtbSize', function () { - it('should return size string with input single size array', function () { - var size = [300, 250]; - var output = utils.parseGPTSingleSizeArrayToRtbSize(size); - assert.deepEqual(output, {w: 300, h: 250}); - }); - - it('should return size string with input single size array', function () { - var size = ['300', '250']; - var output = utils.parseGPTSingleSizeArrayToRtbSize(size); - assert.deepEqual(output, {w: 300, h: 250}); - }); - - it('return undefined using string input', function () { - var size = '1'; - var output = utils.parseGPTSingleSizeArrayToRtbSize(size); - assert.equal(output, undefined); - }); - - it('return undefined using number input', function () { - var size = 1; - var output = utils.parseGPTSingleSizeArrayToRtbSize(size); - assert.equal(output, undefined); - }); - - it('return undefined using one length single array', function () { - var size = [300]; - var output = utils.parseGPTSingleSizeArrayToRtbSize(size); - assert.equal(output, undefined); - }); - - it('return undefined if the input is empty', function () { - var size = ''; - var output = utils.parseGPTSingleSizeArrayToRtbSize(size); - assert.equal(output, undefined); - }); - - it('return undefined if the input is not a number', function () { - var size = ['foo', 'bar']; - var output = utils.parseGPTSingleSizeArrayToRtbSize(size); - assert.equal(output, undefined); - }); - - it('return undefined if the input is not a number 2', function () { - var size = [300, 'foo']; - var output = utils.parseGPTSingleSizeArrayToRtbSize(size); - assert.equal(output, undefined); - }); - }); - - describe('isA', function () { - it('should return true with string object', function () { - var output = utils.isA(obj_string, type_string); - assert.deepEqual(output, true); - }); - - it('should return false with object', function () { - var output = utils.isA(obj_object, type_string); - assert.deepEqual(output, false); - }); - - it('should return true with object', function () { - var output = utils.isA(obj_object, type_object); - assert.deepEqual(output, true); - }); - - it('should return false with array object', function () { - var output = utils.isA(obj_array, type_object); - assert.deepEqual(output, false); - }); - - it('should return true with array object', function () { - var output = utils.isA(obj_array, type_array); - assert.deepEqual(output, true); - }); - - it('should return false with array object', function () { - var output = utils.isA(obj_array, type_function); - assert.deepEqual(output, false); - }); - - it('should return true with function', function () { - var output = utils.isA(obj_function, type_function); - assert.deepEqual(output, true); - }); - - it('should return false with number', function () { - var output = utils.isA(obj_function, type_number); - assert.deepEqual(output, false); - }); - - it('should return true with number', function () { - var output = utils.isA(obj_number, type_number); - assert.deepEqual(output, true); - }); - }); - - describe('isFn', function () { - it('should return true with input function', function () { - var output = utils.isFn(obj_function); - assert.deepEqual(output, true); - }); - - it('should return false with input string', function () { - var output = utils.isFn(obj_string); - assert.deepEqual(output, false); - }); - - it('should return false with input number', function () { - var output = utils.isFn(obj_number); - assert.deepEqual(output, false); - }); - - it('should return false with input Array', function () { - var output = utils.isFn(obj_array); - assert.deepEqual(output, false); - }); - - it('should return false with input object', function () { - var output = utils.isFn(obj_object); - assert.deepEqual(output, false); - }); - }); - - describe('isStr', function () { - it('should return true with input string', function () { - var output = utils.isStr(obj_string); - assert.deepEqual(output, true); - }); - - it('should return false with input number', function () { - var output = utils.isStr(obj_number); - assert.deepEqual(output, false); - }); - - it('should return false with input object', function () { - var output = utils.isStr(obj_object); - assert.deepEqual(output, false); - }); - - it('should return false with input array', function () { - var output = utils.isStr(obj_array); - assert.deepEqual(output, false); - }); - - it('should return false with input function', function () { - var output = utils.isStr(obj_function); - assert.deepEqual(output, false); - }); - }); - - describe('isArray', function () { - it('should return false with input string', function () { - var output = utils.isArray(obj_string); - assert.deepEqual(output, false); - }); - - it('should return false with input number', function () { - var output = utils.isArray(obj_number); - assert.deepEqual(output, false); - }); - - it('should return false with input object', function () { - var output = utils.isArray(obj_object); - assert.deepEqual(output, false); - }); - - it('should return true with input array', function () { - var output = utils.isArray(obj_array); - assert.deepEqual(output, true); - }); - - it('should return false with input function', function () { - var output = utils.isArray(obj_function); - assert.deepEqual(output, false); - }); - }); - - describe('isPlainObject', function () { - it('should return false with input string', function () { - var output = utils.isPlainObject(obj_string); - assert.deepEqual(output, false); - }); - - it('should return false with input number', function () { - var output = utils.isPlainObject(obj_number); - assert.deepEqual(output, false); - }); - - it('should return true with input object', function () { - var output = utils.isPlainObject(obj_object); - assert.deepEqual(output, true); - }); - - it('should return false with input array', function () { - var output = utils.isPlainObject(obj_array); - assert.deepEqual(output, false); - }); - - it('should return false with input function', function () { - var output = utils.isPlainObject(obj_function); - assert.deepEqual(output, false); - }); - }); - - describe('isEmpty', function () { - it('should return true with empty object', function () { - var output = utils.isEmpty(obj_object); - assert.deepEqual(output, true); - }); - - it('should return false with non-empty object', function () { - var obj = { a: 'b' }; - var output = utils.isEmpty(obj); - assert.deepEqual(output, false); - }); - - it('should return false with null', function () { - var obj = null; - var output = utils.isEmpty(obj); - assert.deepEqual(output, true); - }); - }); - - describe('contains', function () { - it('should return true if the input string contains in the input obj', function () { - var output = utils.contains('123', '1'); - assert.deepEqual(output, true); - }); - - it('should return false if the input string do not contain in the input obj', function () { - var output = utils.contains('234', '1'); - assert.deepEqual(output, false); - }); - - it('should return false if the input string is empty', function () { - var output = utils.contains(); - assert.ok(!output, 'an empty string returns false'); - }); - }); - - describe('_map', function () { - it('return empty array when input object is empty', function () { - var input = {}; - var callback = function () {}; - - var output = utils._map(input, callback); - assert.deepEqual(output, []); - }); - - it('return value array with vaild input object', function () { - var input = { a: 'A', b: 'B' }; - var callback = function (v) { return v; }; - - var output = utils._map(input, callback); - assert.deepEqual(output, ['A', 'B']); - }); - - it('return value array with vaild input object_callback func changed 1', function () { - var input = { a: 'A', b: 'B' }; - var callback = function (v, k) { return v + k; }; - - var output = utils._map(input, callback); - assert.deepEqual(output, ['Aa', 'Bb']); - }); - - it('return value array with vaild input object_callback func changed 2', function () { - var input = { a: 'A', b: 'B' }; - var callback = function (v, k, o) { return o; }; - - var output = utils._map(input, callback); - assert.deepEqual(output, [input, input]); - }); - }); - - describe('createInvisibleIframe', function () { - var output = utils.createInvisibleIframe(); - - it('return iframe - id', function () { - assert.ok(output.id); - }); - - it('return iframe - height', function () { - assert.deepEqual(output.height, 0); - }); - - it('return iframe - width', function () { - assert.deepEqual(output.width, 0); - }); - - it('return iframe - hspace', function () { - assert.deepEqual(output.hspace, '0'); - }); - - it('return iframe - vspace', function () { - assert.deepEqual(output.vspace, '0'); - }); - - it('return iframe - marginWidth', function () { - assert.deepEqual(output.marginWidth, '0'); - }); - - it('return iframe - marginHeight', function () { - assert.deepEqual(output.marginHeight, '0'); - }); - - it('return iframe - scrolling', function () { - assert.deepEqual(output.scrolling, 'no'); - }); - - it('return iframe - frameBorder', function () { - assert.deepEqual(output.frameBorder, '0'); - }); - - it('return iframe - src', function () { - assert.deepEqual(output.src, 'about:blank'); - }); - - it('return iframe - style', function () { - assert.ok(output.style); - }); - }); - - describe('getHighestCpm', function () { - it('should pick the existing highest cpm', function () { - let previous = { - cpm: 2, - timeToRespond: 100 - }; - let current = { - cpm: 1, - timeToRespond: 100 - }; - assert.equal(utils.getHighestCpm(previous, current), previous); - }); - - it('should pick the new highest cpm', function () { - let previous = { - cpm: 1, - timeToRespond: 100 - }; - let current = { - cpm: 2, - timeToRespond: 100 - }; - assert.equal(utils.getHighestCpm(previous, current), current); - }); - - it('should pick the fastest cpm in case of tie', function () { - let previous = { - cpm: 1, - timeToRespond: 100 - }; - let current = { - cpm: 1, - timeToRespond: 50 - }; - assert.equal(utils.getHighestCpm(previous, current), current); - }); - - it('should pick the oldest in case of tie using responseTimeStamp', function () { - let previous = { - cpm: 1, - timeToRespond: 100, - responseTimestamp: 1000 - }; - let current = { - cpm: 1, - timeToRespond: 50, - responseTimestamp: 2000 - }; - assert.equal(utils.getOldestHighestCpmBid(previous, current), previous); - }); - - it('should pick the latest in case of tie using responseTimeStamp', function () { - let previous = { - cpm: 1, - timeToRespond: 100, - responseTimestamp: 1000 - }; - let current = { - cpm: 1, - timeToRespond: 50, - responseTimestamp: 2000 - }; - assert.equal(utils.getLatestHighestCpmBid(previous, current), current); - }); - }); - - describe('polyfill test', function () { - it('should not add polyfill to array', function() { - var arr = ['hello', 'world']; - var count = 0; - for (var key in arr) { - count++; - } - assert.equal(arr.length, count, 'Polyfill test fails'); - }); - }); - - describe('delayExecution', function () { - it('should execute the core function after the correct number of calls', function () { - const callback = sinon.spy(); - const delayed = utils.delayExecution(callback, 5); - for (let i = 0; i < 4; i++) { - delayed(); - } - assert(callback.notCalled); - delayed(3); - assert(callback.called) - assert.equal(callback.firstCall.args[0], 3); - }); - }); - - describe('deepAccess', function() { - var obj = { - 1: 2, - test: { - first: 11 - } - }; - - it('should allow deep access of object properties', function() { - var value1 = utils.deepAccess(obj, 'test'); - assert.deepEqual(value1, obj.test); - - var value2 = utils.deepAccess(obj, 'test.first'); - assert.equal(value2, 11); - - var value3 = utils.deepAccess(obj, '1'); - assert.equal(value3, 2); - }); - - it('should allow safe access (returning undefined for missing properties and not throwing exceptions)', function() { - var value; - - assert.doesNotThrow(function() { - value = utils.deepAccess(obj, 'test.second.third'); - }); - - assert.equal(value, undefined); - }); - }); - - describe('deepSetValue', function() { - it('should set existing properties at various depths', function() { - const testObj = { - prop: 'value', - nestedObj: { - nestedProp: 'nestedValue' - } - }; - utils.deepSetValue(testObj, 'prop', 'newValue'); - assert.equal(testObj.prop, 'newValue'); - utils.deepSetValue(testObj, 'nestedObj.nestedProp', 'newNestedValue'); - assert.equal(testObj.nestedObj.nestedProp, 'newNestedValue'); - }); - - it('should create object levels between top and bottom of given path if they do not exist', function() { - const testObj = {}; - utils.deepSetValue(testObj, 'level1.level2', 'value'); - assert.notEqual(testObj.level1, undefined); - assert.notEqual(testObj.level1.level2, undefined); - assert.equal(testObj.level1.level2, 'value'); - }); - }); - - describe('getDefinedParams', function () { - it('builds an object consisting of defined params', function () { - const adUnit = { - mediaType: 'video', - comeWithMe: 'ifuwant2live', - notNeeded: 'do not include', - }; - - const builtObject = utils.getDefinedParams(adUnit, [ - 'mediaType', 'comeWithMe' - ]); - - assert.deepEqual(builtObject, { - mediaType: 'video', - comeWithMe: 'ifuwant2live', - }); - }); - }); - - describe('deepClone', function () { - it('deep copies objects', function () { - const adUnit = [{ - code: 'swan', - mediaTypes: {video: {context: 'outstream'}}, - renderer: { - render: bid => player.render(bid), - url: '/video/renderer.js' - }, - bids: [{ - bidder: 'dharmaInitiative', - params: { placementId: '481516', } - }], - }]; - - const adUnitCopy = utils.deepClone(adUnit); - expect(adUnitCopy[0].renderer.url).to.be.a('string'); - expect(adUnitCopy[0].renderer.render).to.be.a('function'); - }); - }); - - describe('getUserConfiguredParams', function () { - const adUnits = [{ - code: 'adUnit1', - bids: [{ - bidder: 'bidder1', - params: { - key1: 'value1' - } - }, { - bidder: 'bidder2' - }] - }]; - - it('should return params configured', function () { - const output = utils.getUserConfiguredParams(adUnits, 'adUnit1', 'bidder1'); - const expected = [{ - key1: 'value1' - }]; - assert.deepEqual(output, expected); - }); - - it('should return array containting empty object, if bidder present and no params are configured', function () { - const output = utils.getUserConfiguredParams(adUnits, 'adUnit1', 'bidder2'); - const expected = [{}]; - assert.deepEqual(output, expected); - }); - - it('should return empty array, if bidder is not present', function () { - const output = utils.getUserConfiguredParams(adUnits, 'adUnit1', 'bidder3'); - const expected = []; - assert.deepEqual(output, expected); - }); - - it('should return empty array, if adUnit is not present', function () { - const output = utils.getUserConfiguredParams(adUnits, 'adUnit2', 'bidder3'); - const expected = []; - assert.deepEqual(output, expected); - }); - }); - - describe('convertCamelToUnderscore', function () { - it('returns converted string value using underscore syntax instead of camelCase', function () { - let var1 = 'placementIdTest'; - let test1 = utils.convertCamelToUnderscore(var1); - expect(test1).to.equal('placement_id_test'); - - let var2 = 'my_test_value'; - let test2 = utils.convertCamelToUnderscore(var2); - expect(test2).to.equal(var2); - }); - }); - - describe('getAdUnitSizes', function () { - it('returns an empty response when adUnits is undefined', function () { - let sizes = utils.getAdUnitSizes(); - expect(sizes).to.be.undefined; - }); - - it('returns an empty array when invalid data is present in adUnit object', function () { - let sizes = utils.getAdUnitSizes({ sizes: 300 }); - expect(sizes).to.deep.equal([]); - }); - - it('retuns an array of arrays when reading from adUnit.sizes', function () { - let sizes = utils.getAdUnitSizes({ sizes: [300, 250] }); - expect(sizes).to.deep.equal([[300, 250]]); - - sizes = utils.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 = utils.getAdUnitSizes({ mediaTypes: { banner: { sizes: [300, 250] } } }); - expect(sizes).to.deep.equal([[300, 250]]); - - sizes = utils.getAdUnitSizes({ mediaTypes: { banner: { sizes: [[300, 250], [300, 600]] } } }); - expect(sizes).to.deep.equal([[300, 250], [300, 600]]); - }); - }); - - describe('URL helpers', function () { - describe('parseUrl()', function () { - let parsed; - - beforeEach(function () { - parsed = utils.parseUrl('http://example.com:3000/pathname/?search=test&foo=bar&bar=foo%26foo%3Dxxx#hash'); - }); - - it('extracts the protocol', function () { - expect(parsed).to.have.property('protocol', 'http'); - }); - - it('extracts the hostname', function () { - expect(parsed).to.have.property('hostname', 'example.com'); - }); - - it('extracts the port', function () { - expect(parsed).to.have.property('port', 3000); - }); - - it('extracts the pathname', function () { - expect(parsed).to.have.property('pathname', '/pathname/'); - }); - - it('extracts the search query', function () { - expect(parsed).to.have.property('search'); - expect(parsed.search).to.eql({ - foo: 'xxx', - search: 'test', - bar: 'foo', - }); - }); - - it('extracts the hash', function () { - expect(parsed).to.have.property('hash', 'hash'); - }); - - it('extracts the host', function () { - expect(parsed).to.have.property('host', 'example.com:3000'); - }); - }); - - describe('parseUrl(url, {noDecodeWholeURL: true})', function () { - let parsed; - - beforeEach(function () { - parsed = utils.parseUrl('http://example.com:3000/pathname/?search=test&foo=bar&bar=foo%26foo%3Dxxx#hash', {noDecodeWholeURL: true}); - }); - - it('extracts the search query', function () { - expect(parsed).to.have.property('search'); - expect(parsed.search).to.eql({ - foo: 'bar', - search: 'test', - bar: 'foo%26foo%3Dxxx', - }); - }); - }); - - describe('buildUrl()', function () { - it('formats an object in to a URL', function () { - expect(utils.buildUrl({ - protocol: 'http', - hostname: 'example.com', - port: 3000, - pathname: '/pathname/', - search: {foo: 'bar', search: 'test', bar: 'foo%26foo%3Dxxx'}, - hash: 'hash' - })).to.equal('http://example.com:3000/pathname/?foo=bar&search=test&bar=foo%26foo%3Dxxx#hash'); - }); - - it('will use defaults for missing properties', function () { - expect(utils.buildUrl({ - hostname: 'example.com' - })).to.equal('http://example.com'); - }); - }); - - describe('parseUrl(url, {decodeSearchAsString: true})', function () { - let parsed; - - beforeEach(function () { - parsed = utils.parseUrl('http://example.com:3000/pathname/?search=test&foo=bar&bar=foo%26foo%3Dxxx#hash', {decodeSearchAsString: true}); - }); - - it('extracts the search query', function () { - expect(parsed).to.have.property('search'); - expect(parsed.search).to.equal('?search=test&foo=bar&bar=foo&foo=xxx'); - }); - }); - }); - - describe('transformBidderParamKeywords', function () { - it('returns an array of objects when keyvalue is an array', function () { - let keywords = { - genre: ['rock', 'pop'] - }; - let result = utils.transformBidderParamKeywords(keywords); - expect(result).to.deep.equal([{ - key: 'genre', - value: ['rock', 'pop'] - }]); - }); - - it('returns an array of objects when keyvalue is a string', function () { - let keywords = { - genre: 'opera' - }; - let result = utils.transformBidderParamKeywords(keywords); - expect(result).to.deep.equal([{ - key: 'genre', - value: ['opera'] - }]); - }); - - it('returns an array of objects when keyvalue is a number', function () { - let keywords = { - age: 15 - }; - let result = utils.transformBidderParamKeywords(keywords); - expect(result).to.deep.equal([{ - key: 'age', - value: ['15'] - }]); - }); - - it('returns an array of objects when using multiple keys with values of differing types', function () { - let keywords = { - genre: 'classical', - mix: ['1', 2, '3', 4], - age: 10 - }; - let result = utils.transformBidderParamKeywords(keywords); - expect(result).to.deep.equal([{ - key: 'genre', - value: ['classical'] - }, { - key: 'mix', - value: ['1', '2', '3', '4'] - }, { - key: 'age', - value: ['10'] - }]); - }); - - it('returns an array of objects when the keyvalue uses an empty string', function() { - let keywords = { - test: [''], - test2: '' - }; - let result = utils.transformBidderParamKeywords(keywords); - expect(result).to.deep.equal([{ - key: 'test', - value: [''] - }, { - key: 'test2', - value: [''] - }]); - }); - - describe('insertElement', function () { - it('returns a node at the top of the target by default', function () { - const toInsert = document.createElement('div'); - const target = document.getElementsByTagName('body')[0]; - const inserted = utils.insertElement(toInsert, document, 'body'); - expect(inserted).to.equal(target.firstChild); - }); - it('returns a node at bottom of target if 4th argument is true', function () { - const toInsert = document.createElement('div'); - const target = document.getElementsByTagName('html')[0]; - const inserted = utils.insertElement(toInsert, document, 'html', true); - expect(inserted).to.equal(target.lastChild); - }); - it('returns a node at top of the head if no target is given', function () { - const toInsert = document.createElement('div'); - const target = document.getElementsByTagName('head')[0]; - const inserted = utils.insertElement(toInsert); - expect(inserted).to.equal(target.firstChild); - }); - }); - }); - - describe('isSafariBrowser', function () { - let userAgentStub; - let userAgent; - - before(function () { - userAgentStub = sinon.stub(navigator, 'userAgent').get(function () { - return userAgent; - }); - }); - - after(function () { - userAgentStub.restore(); - }); - - it('properly detects safari', function () { - userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/536.25 (KHTML, like Gecko) Version/6.0 Safari/536.25'; - expect(utils.isSafariBrowser()).to.equal(true); - }); - it('does not flag Chrome on MacOS', function () { - userAgent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36'; - expect(utils.isSafariBrowser()).to.equal(false); - }); - it('does not flag Chrome iOS', function () { - userAgent = 'Mozilla/5.0 (iPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/80.0.3987.95 Mobile/15E148 Safari/604.1'; - expect(utils.isSafariBrowser()).to.equal(false); - }); - it('does not flag Firefox iOS', function () { - userAgent = 'Mozilla/5.0 (iPhone; CPU OS 13_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/23.0 Mobile/15E148 Safari/605.1.15'; - expect(utils.isSafariBrowser()).to.equal(false); - }); - it('does not flag Windows Edge', function () { - userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.74 Safari/537.36 Edg/79.0.309.43'; - expect(utils.isSafariBrowser()).to.equal(false); - }); - }); - - describe('mergeDeep', function() { - it('properly merge objects that share same property names', function() { - const object1 = { - propA: { - subPropA: 'abc' - } - }; - const object2 = { - propA: { - subPropB: 'def' - } - }; - - const resultWithoutMergeDeep = Object.assign({}, object1, object2); - expect(resultWithoutMergeDeep).to.deep.equal({ - propA: { - subPropB: 'def' - } - }); - - const resultWithMergeDeep = utils.mergeDeep({}, object1, object2); - expect(resultWithMergeDeep).to.deep.equal({ - propA: { - subPropA: 'abc', - subPropB: 'def' - } - }); - }); - - it('properly merge objects that have different depths', function() { - const object1 = { - depth0_A: { - depth1_A: { - depth2_A: 123 - } - } - }; - const object2 = { - depth0_A: { - depth1_A: { - depth2_B: { - depth3_A: { - depth4_A: 'def' - } - } - }, - depth1_B: 'abc' - } - }; - const object3 = { - depth0_B: 456 - }; - - const result = utils.mergeDeep({}, object1, object2, object3); - expect(result).to.deep.equal({ - depth0_A: { - depth1_A: { - depth2_A: 123, - depth2_B: { - depth3_A: { - depth4_A: 'def' - } - } - }, - depth1_B: 'abc' - }, - depth0_B: 456 - }); - }); - - it('properly merge objects with various property types', function() { - const object1 = { - depth0_A: { - depth1_A: ['a', 'b', 'c'], - depth1_B: 'abc', - depth1_C: 123 - } - }; - const object2 = { - depth0_A: { - depth1_A: ['d', 'e', 'f'], - depth1_D: true, - } - }; - - const result = utils.mergeDeep({}, object1, object2); - expect(result).to.deep.equal({ - depth0_A: { - depth1_A: ['a', 'b', 'c', 'd', 'e', 'f'], - depth1_B: 'abc', - depth1_C: 123, - depth1_D: true, - } - }); - }); - }); - - describe('deepEqual', function() { - it('should return "true" if comparing the same object', function() { - const obj1 = { - banner: { - sizeConfig: [ - { minViewPort: [0, 0], sizes: [] }, - { minViewPort: [1000, 0], sizes: [[1000, 300], [1000, 90], [970, 250], [970, 90], [728, 90]] }, - ], - }, - }; - const obj2 = obj1; - expect(utils.deepEqual(obj1, obj2)).to.equal(true); - }); - it('should return "true" if two deeply nested objects are equal', function() { - const obj1 = { - banner: { - sizeConfig: [ - { minViewPort: [0, 0], sizes: [] }, - { minViewPort: [1000, 0], sizes: [[1000, 300], [1000, 90], [970, 250], [970, 90], [728, 90]] }, - ], - }, - }; - const obj2 = { - banner: { - sizeConfig: [ - { minViewPort: [0, 0], sizes: [] }, - { minViewPort: [1000, 0], sizes: [[1000, 300], [1000, 90], [970, 250], [970, 90], [728, 90]] }, - ], - }, - }; - expect(utils.deepEqual(obj1, obj2)).to.equal(true); - }); - it('should return "true" if comparting the same primitive values', function() { - const primitive1 = 'Prebid.js'; - const primitive2 = 'Prebid.js'; - expect(utils.deepEqual(primitive1, primitive2)).to.equal(true); - }); - it('should return "false" if comparing two different primitive values', function() { - const primitive1 = 12; - const primitive2 = 123; - expect(utils.deepEqual(primitive1, primitive2)).to.equal(false); - }); - it('should return "false" if comparing two different deeply nested objects', function() { - const obj1 = { - banner: { - sizeConfig: [ - { minViewPort: [0, 0], sizes: [] }, - { minViewPort: [1000, 0], sizes: [[1000, 300], [1000, 90], [970, 250], [970, 90], [728, 90]] }, - ], - }, - }; - const obj2 = { - banner: { - sizeConfig: [ - { minViewPort: [0, 0], sizes: [] }, - { minViewPort: [1000, 0], sizes: [[1000, 300], [728, 90]] }, - ], - }, - } - expect(utils.deepEqual(obj1, obj2)).to.equal(false); - }); - - describe('cyrb53Hash', function() { - it('should return the same hash for the same string', function() { - const stringOne = 'string1'; - expect(utils.cyrb53Hash(stringOne)).to.equal(utils.cyrb53Hash(stringOne)); - }); - it('should return a different hash for the same string with different seeds', function() { - const stringOne = 'string1'; - expect(utils.cyrb53Hash(stringOne, 1)).to.not.equal(utils.cyrb53Hash(stringOne, 2)); - }); - it('should return a different hash for different strings with the same seed', function() { - const stringOne = 'string1'; - const stringTwo = 'string2'; - expect(utils.cyrb53Hash(stringOne)).to.not.equal(utils.cyrb53Hash(stringTwo)); - }); - it('should return a string value, not a number', function() { - const stringOne = 'string1'; - expect(typeof utils.cyrb53Hash(stringOne)).to.equal('string'); - }); - }); - }); -}); diff --git a/test/spec/videoCache_spec.js b/test/spec/videoCache_spec.js deleted file mode 100644 index 554db3ebe4e..00000000000 --- a/test/spec/videoCache_spec.js +++ /dev/null @@ -1,351 +0,0 @@ -import chai from 'chai'; -import { getCacheUrl, store } from 'src/videoCache.js'; -import { config } from 'src/config.js'; -import { server } from 'test/mocks/xhr.js'; - -const should = chai.should(); - -function getMockBid(bidder, auctionId, bidderRequestId) { - return { - 'bidder': bidder, - 'params': { - 'placementId': '10433394', - 'member': 123, - 'keywords': { - 'foo': ['bar', 'baz'], - 'fizz': ['buzz'] - } - }, - 'bid_id': '12345abc', - 'adUnitCode': 'div-gpt-ad-1460505748561-0', - 'mediaTypes': { - 'banner': { - 'sizes': [[300, 250]] - } - }, - 'transactionId': '4ef956ad-fd83-406d-bd35-e4bb786ab86c', - 'sizes': [300, 250], - 'bidId': '123', - 'bidderRequestId': bidderRequestId, - 'auctionId': auctionId, - 'storedAuctionResponse': 11111 - }; -} - -function getMockBidRequest(bidder = 'appnexus', auctionId = '173afb6d132ba3', bidderRequestId = '3d1063078dfcc8') { - return { - 'bidderCode': bidder, - 'auctionId': auctionId, - 'bidderRequestId': bidderRequestId, - 'tid': '437fbbf5-33f5-487a-8e16-a7112903cfe5', - 'bids': [getMockBid(bidder, auctionId, bidderRequestId)], - 'auctionStart': 1510852447530, - 'timeout': 5000, - 'src': 's2s', - 'doneCbCallCount': 0, - 'refererInfo': { - 'referer': 'http://mytestpage.com' - } - } -} - -describe('The video cache', function () { - function assertError(callbackSpy) { - callbackSpy.calledOnce.should.equal(true); - callbackSpy.firstCall.args[0].should.be.an('error'); - } - - function assertSuccess(callbackSpy) { - callbackSpy.calledOnce.should.equal(true); - should.not.exist(callbackSpy.firstCall.args[0]); - } - - describe('when the cache server is unreachable', function () { - it('should execute the callback with an error when store() is called', function () { - const callback = sinon.spy(); - store([{ vastUrl: 'my-mock-url.com' }], callback); - - server.requests[0].respond(503, { - 'Content-Type': 'plain/text', - }, 'The server could not save anything at the moment.'); - - assertError(callback); - callback.firstCall.args[1].should.deep.equal([]); - }); - }); - - describe('when the cache server is available', function () { - beforeEach(function () { - config.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }) - }); - - afterEach(function () { - config.resetConfig(); - }); - - it('should execute the callback with a successful result when store() is called', function () { - const uuid = 'c488b101-af3e-4a99-b538-00423e5a3371'; - const callback = fakeServerCall( - { vastUrl: 'my-mock-url.com' }, - `{"responses":[{"uuid":"${uuid}"}]}`); - - assertSuccess(callback); - callback.firstCall.args[1].should.deep.equal([{ uuid: uuid }]); - }); - - it('should execute the callback with an error if the cache server response has no responses property', function () { - const callback = fakeServerCall( - { vastUrl: 'my-mock-url.com' }, - '{"broken":[{"uuid":"c488b101-af3e-4a99-b538-00423e5a3371"}]}'); - assertError(callback); - callback.firstCall.args[1].should.deep.equal([]); - }); - - it('should execute the callback with an error if the cache server responds with malformed JSON', function () { - const callback = fakeServerCall( - { vastUrl: 'my-mock-url.com' }, - 'Not JSON here'); - assertError(callback); - callback.firstCall.args[1].should.deep.equal([]); - }); - - it('should make the expected request when store() is called on an ad with a vastUrl', function () { - const expectedValue = ` - - - prebid.org wrapper - - - - - - `; - assertRequestMade({ vastUrl: 'my-mock-url.com', ttl: 25 }, expectedValue) - }); - - it('should make the expected request when store() is called on an ad with a vastUrl and a vastImpUrl', function () { - const expectedValue = ` - - - prebid.org wrapper - - - - - - `; - assertRequestMade({ vastUrl: 'my-mock-url.com', vastImpUrl: 'imptracker.com', ttl: 25 }, expectedValue) - }); - - it('should make the expected request when store() is called on an ad with vastXml', function () { - const vastXml = ''; - assertRequestMade({ vastXml: vastXml, ttl: 25 }, vastXml); - }); - - it('should make the expected request when store() is called while supplying a custom key param', function () { - const customKey1 = 'keyword_abc_123'; - const customKey2 = 'other_xyz_789'; - const vastXml1 = 'test1'; - const vastXml2 = 'test2'; - - const bids = [{ - vastXml: vastXml1, - ttl: 25, - customCacheKey: customKey1 - }, { - vastXml: vastXml2, - ttl: 25, - customCacheKey: customKey2 - }]; - - store(bids, function () { }); - const request = server.requests[0]; - request.method.should.equal('POST'); - request.url.should.equal('https://prebid.adnxs.com/pbc/v1/cache'); - request.requestHeaders['Content-Type'].should.equal('text/plain;charset=utf-8'); - let payload = { - puts: [{ - type: 'xml', - value: vastXml1, - ttlseconds: 25, - key: customKey1 - }, { - type: 'xml', - value: vastXml2, - ttlseconds: 25, - key: customKey2 - }] - }; - JSON.parse(request.requestBody).should.deep.equal(payload); - }); - - it('should include additional params in request payload should config.cache.vasttrack be true', () => { - config.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache', - vasttrack: true - } - }); - - const customKey1 = 'vasttrack_123'; - const customKey2 = 'vasttrack_abc'; - const vastXml1 = 'testvast1'; - const vastXml2 = 'testvast2'; - - const bids = [{ - vastXml: vastXml1, - ttl: 25, - customCacheKey: customKey1, - requestId: '12345abc', - bidder: 'appnexus', - auctionId: '1234-56789-abcde' - }, { - vastXml: vastXml2, - ttl: 25, - customCacheKey: customKey2, - requestId: 'cba54321', - bidder: 'rubicon', - auctionId: '1234-56789-abcde' - }]; - - store(bids, function () { }); - const request = server.requests[0]; - request.method.should.equal('POST'); - request.url.should.equal('https://prebid.adnxs.com/pbc/v1/cache'); - request.requestHeaders['Content-Type'].should.equal('text/plain;charset=utf-8'); - let payload = { - puts: [{ - type: 'xml', - value: vastXml1, - ttlseconds: 25, - key: customKey1, - bidid: '12345abc', - aid: '1234-56789-abcde', - bidder: 'appnexus' - }, { - type: 'xml', - value: vastXml2, - ttlseconds: 25, - key: customKey2, - bidid: 'cba54321', - aid: '1234-56789-abcde', - bidder: 'rubicon' - }] - }; - - JSON.parse(request.requestBody).should.deep.equal(payload); - }); - - it('should include additional params in request payload should config.cache.vasttrack be true and bidderRequest argument was defined', () => { - config.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache', - vasttrack: true - } - }); - - const customKey1 = 'vasttrack_123'; - const customKey2 = 'vasttrack_abc'; - const vastXml1 = 'testvast1'; - const vastXml2 = 'testvast2'; - - const bids = [{ - vastXml: vastXml1, - ttl: 25, - customCacheKey: customKey1, - requestId: '12345abc', - bidder: 'appnexus', - auctionId: '1234-56789-abcde' - }, { - vastXml: vastXml2, - ttl: 25, - customCacheKey: customKey2, - requestId: 'cba54321', - bidder: 'rubicon', - auctionId: '1234-56789-abcde' - }]; - - store(bids, function () { }, getMockBidRequest()); - const request = server.requests[0]; - request.method.should.equal('POST'); - request.url.should.equal('https://prebid.adnxs.com/pbc/v1/cache'); - request.requestHeaders['Content-Type'].should.equal('text/plain;charset=utf-8'); - let payload = { - puts: [{ - type: 'xml', - value: vastXml1, - ttlseconds: 25, - key: customKey1, - bidid: '12345abc', - bidder: 'appnexus', - aid: '1234-56789-abcde', - timestamp: 1510852447530 - }, { - type: 'xml', - value: vastXml2, - ttlseconds: 25, - key: customKey2, - bidid: 'cba54321', - bidder: 'rubicon', - aid: '1234-56789-abcde', - timestamp: 1510852447530 - }] - }; - - JSON.parse(request.requestBody).should.deep.equal(payload); - }); - - function assertRequestMade(bid, expectedValue) { - store([bid], function () { }); - - const request = server.requests[0]; - request.method.should.equal('POST'); - request.url.should.equal('https://prebid.adnxs.com/pbc/v1/cache'); - request.requestHeaders['Content-Type'].should.equal('text/plain;charset=utf-8'); - - JSON.parse(request.requestBody).should.deep.equal({ - puts: [{ - type: 'xml', - value: expectedValue, - ttlseconds: 25 - }], - }); - } - - function fakeServerCall(bid, responseBody) { - const callback = sinon.spy(); - store([bid], callback); - server.requests[0].respond( - 200, - { - 'Content-Type': 'application/json', - }, - responseBody); - return callback; - } - }); -}); - -describe('The getCache function', function () { - beforeEach(function () { - config.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }) - }); - - afterEach(function () { - config.resetConfig(); - }); - - it('should return the expected URL', function () { - const uuid = 'c488b101-af3e-4a99-b538-00423e5a3371'; - const url = getCacheUrl(uuid); - url.should.equal(`https://prebid.adnxs.com/pbc/v1/cache?uuid=${uuid}`); - }); -}) diff --git a/test/spec/video_spec.js b/test/spec/video_spec.js deleted file mode 100644 index 3ce8ba081da..00000000000 --- a/test/spec/video_spec.js +++ /dev/null @@ -1,113 +0,0 @@ -import { isValidVideoBid } from 'src/video.js'; - -describe('video.js', function () { - it('validates valid instream bids', function () { - const bid = { - adId: '456xyz', - vastUrl: 'http://www.example.com/vastUrl', - requestId: '123abc' - }; - const bidRequests = [{ - bids: [{ - bidId: '123abc', - bidder: 'appnexus', - mediaTypes: { - video: { context: 'instream' } - } - }] - }]; - const valid = isValidVideoBid(bid, bidRequests); - expect(valid).to.equal(true); - }); - - it('catches invalid instream bids', function () { - const bid = { - requestId: '123abc' - }; - const bidRequests = [{ - bids: [{ - bidId: '123abc', - bidder: 'appnexus', - mediaTypes: { - video: { context: 'instream' } - } - }] - }]; - const valid = isValidVideoBid(bid, bidRequests); - expect(valid).to.equal(false); - }); - - it('catches invalid bids when prebid-cache is disabled', function () { - const bidRequests = [{ - bids: [{ - bidder: 'vastOnlyVideoBidder', - mediaTypes: { video: {} }, - }] - }]; - - const valid = isValidVideoBid({ vastXml: 'vast' }, bidRequests); - - expect(valid).to.equal(false); - }); - - it('validates valid outstream bids', function () { - const bid = { - requestId: '123abc', - renderer: { - url: 'render.url', - render: () => true, - } - }; - const bidRequests = [{ - bids: [{ - bidId: '123abc', - bidder: 'appnexus', - mediaTypes: { - video: { context: 'outstream' } - } - }] - }]; - const valid = isValidVideoBid(bid, bidRequests); - expect(valid).to.equal(true); - }); - - it('validates valid outstream bids with a publisher defined renderer', function () { - const bid = { - requestId: '123abc', - }; - const bidRequests = [{ - bids: [{ - bidId: '123abc', - bidder: 'appnexus', - mediaTypes: { - video: { - context: 'outstream', - renderer: { - url: 'render.url', - render: () => true, - } - } - } - }] - }]; - const valid = isValidVideoBid(bid, bidRequests); - expect(valid).to.equal(true); - }); - - it('catches invalid outstream bids', function () { - const bid = { - requestId: '123abc' - }; - const bidRequests = [{ - bids: [{ - bidId: '123abc', - bidder: 'appnexus', - mediaTypes: { - video: { context: 'outstream' } - } - }] - }]; - const valid = isValidVideoBid(bid, bidRequests); - expect(valid).to.equal(false); - }); -}); diff --git a/test/test_index.js b/test/test_index.js deleted file mode 100644 index 53d75e36176..00000000000 --- a/test/test_index.js +++ /dev/null @@ -1,8 +0,0 @@ -require('test/helpers/prebidGlobal.js'); -require('test/mocks/adloaderStub.js'); -require('test/mocks/xhr.js'); - -var testsContext = require.context('.', true, /_spec$/); -testsContext.keys().forEach(testsContext); - -window.$$PREBID_GLOBAL$$.processQueue();